Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10930)

Unified Diff: chrome/renderer/print_web_view_helper_win.cc

Issue 9111042: Fix RTL and complex script title in print preview header/footer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/print_web_view_helper_win.cc
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 4ee351ba67cfc6c271a6d5aa113560abf9dac663..1128e01a5790cff22e35a0a4d04be4dbbea09320 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -4,6 +4,7 @@
#include "chrome/renderer/print_web_view_helper.h"
+#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
@@ -20,6 +21,7 @@
#include "skia/ext/vector_canvas.h"
#include "skia/ext/platform_device.h"
#include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/ports/SkTypeface_win.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/point.h"
@@ -327,3 +329,100 @@ bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
shared_mem_handle));
return true;
}
+
+#if defined(USE_SKIA)
+
+// Uniscribe generation is very time consuming so a global cache for previous
+// results are needed.
+SCRIPT_CACHE PrintWebViewHelper::g_script_cache_;
+SCRIPT_ANALYSIS PrintWebViewHelper::g_script_analysis_;
jungshik at Google 2012/01/06 22:38:45 In the past, we used to have UniscribeHelper class
xji 2012/01/07 01:21:15 Mike (msw@) implemented RenderText in Windows. The
+
+// static
+bool PrintWebViewHelper::ConvertTextToGlyphs(SkTypeface* typeface,
+ const string16& text,
+ std::vector<uint16_t>* glyphs) {
+ bool rtl = base::i18n::IsRTL() &&
+ base::i18n::StringContainsStrongRTLChars(text);
+ HRESULT hr = ScriptIsComplex(text.c_str(), text.size(), SIC_COMPLEX);
+ if (hr != S_OK && !rtl) {
+ return false; // Script is neither complex nor BiDi.
+ }
+
+ // Complex script handling started here.
+ std::vector<SCRIPT_ITEM> items;
+ int max_items = text.size();
+ int generated_items;
+ for (;;) {
+ items.resize(max_items);
+ hr = ScriptItemize(text.c_str(), text.size(), max_items - 1, NULL, NULL,
+ &items[0], &generated_items);
+ if (SUCCEEDED(hr)) {
+ items.resize(generated_items + 1);
+ break;
+ }
+ if (hr != E_OUTOFMEMORY) {
+ return false;
+ }
+ max_items *= 2;
+ }
+
+ std::vector<int> visual_to_logical(generated_items + 1);
+ std::vector<int> logical_to_visual(generated_items + 1);
+ std::vector<BYTE> directions(generated_items);
+ for (int i = 0; i < generated_items; ++i) {
+ directions[i] = items[i].a.s.uBidiLevel;
+ }
+
+ ScriptLayout(generated_items, &directions[0], &visual_to_logical[0],
+ &logical_to_visual[0]);
+ visual_to_logical.push_back(generated_items);
+ logical_to_visual.push_back(generated_items);
+
+ base::win::ScopedCreateDC dc(CreateCompatibleDC(GetDC(NULL)));
+ LOGFONT lf;
+ SkLOGFONTFromTypeface(typeface, &lf);
+ HFONT font_handle = CreateFontIndirect(&lf);
+ if (font_handle == NULL) {
+ return false;
+ }
+ SelectObject(dc.Get(), font_handle);
+
+ for (size_t i = 0; i < items.size() - 1; ++i) {
+ int index = logical_to_visual[i];
+ int input_length = items[index + 1].iCharPos - items[index].iCharPos;
+
+ // Initial size guess suggested by MSDN.
+ std::vector<WORD> logs(input_length);
+ int max_glyph_len = input_length * 3 / 2 + 16;
+ std::vector<WORD> glyph_buffer;
+ std::vector<SCRIPT_VISATTR> visattr;
+
+ for (;;) {
+ int glyphs_used;
+ glyph_buffer.resize(max_glyph_len);
+ visattr.resize(max_glyph_len);
+ items[index].a.fLogicalOrder = FALSE;
+ hr = ScriptShape(dc, &g_script_cache_, &text[items[index].iCharPos],
+ input_length, max_glyph_len, &(items[index].a),
+ &glyph_buffer[0], &logs[0], &visattr[0], &glyphs_used);
+ if (SUCCEEDED(hr)) {
+ // We are not supposed to handle Kashidas in Arabic, so reverting the
+ // glyph order shall be good enough for all RTLs.
+ glyph_buffer.resize(glyphs_used);
+ glyphs->insert(glyphs->end(), glyph_buffer.begin(),glyph_buffer.end());
+ break;
+ }
+
+ if (hr == E_PENDING) {
+ // keep waiting
+ } else if (hr != E_OUTOFMEMORY) {
+ return false;
+ }
+
jungshik at Google 2012/01/06 22:38:45 After calling ScriptShape, ScriptPlace (?) has to
+ max_glyph_len *= 2;
+ }
+ }
+
+ return true;
+}
+#endif
« chrome/renderer/print_web_view_helper.cc ('K') | « chrome/renderer/print_web_view_helper_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698