Index: skia/ext/vector_platform_device_emf_win.cc |
=================================================================== |
--- skia/ext/vector_platform_device_emf_win.cc (revision 167921) |
+++ skia/ext/vector_platform_device_emf_win.cc (working copy) |
@@ -2,12 +2,17 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "skia/ext/vector_platform_device_emf_win.h" |
+ |
#include <windows.h> |
-#include "skia/ext/vector_platform_device_emf_win.h" |
+#include <string> |
+#include "base/logging.h" |
+#include "content/renderer/render_thread_impl.h" |
Lei Zhang
2012/11/16 00:14:03
jam: Is skia allowed to #include content ?
Should
|
#include "skia/ext/bitmap_platform_device.h" |
#include "skia/ext/skia_utils_win.h" |
+#include "third_party/skia/include/core/SkFontHost.h" |
#include "third_party/skia/include/core/SkPathEffect.h" |
#include "third_party/skia/include/core/SkTemplates.h" |
#include "third_party/skia/include/core/SkUtils.h" |
@@ -366,6 +371,49 @@ |
} |
} |
+void SkiaPreCacheFontCharacters(const LOGFONT& logfont, |
+ const wchar_t* text, |
+ unsigned int text_length) { |
+ content::RenderThreadImpl* render_thread_impl = |
+ content::RenderThreadImpl::current(); |
+ if (render_thread_impl) { |
+ render_thread_impl->PreCacheFontCharacters(logfont, |
+ std::wstring(text, text_length)); |
+ } |
+} |
+ |
+void EnsureTypefaceCharactersAccessible( |
+ const SkTypeface& typeface, const wchar_t* text, unsigned int text_length) { |
+ LOGFONT lf; |
+ SkLOGFONTFromTypeface(&typeface, &lf); |
+ SkiaPreCacheFontCharacters(lf, text, text_length); |
+} |
+ |
+bool EnsureExtTextOut(HDC hdc, int x, int y, UINT options, const RECT * lprect, |
+ LPCWSTR text, unsigned int characters, const int * lpDx, |
+ SkTypeface* const typeface) { |
+ bool success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); |
+ if (!success) { |
+ if (typeface) { |
+ EnsureTypefaceCharactersAccessible(*typeface, |
+ text, |
+ characters); |
+ success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); |
+ if (!success) { |
+ LOGFONT lf; |
+ SkLOGFONTFromTypeface(typeface, &lf); |
+ VLOG(1) << "SkFontHost::EnsureTypefaceCharactersAccessible FAILED for " |
+ << " FaceName = " << lf.lfFaceName |
+ << " and characters: " << std::wstring(text, characters); |
+ } |
+ } else { |
+ VLOG(1) << "ExtTextOut FAILED for default FaceName " |
+ << " and characters: " << std::wstring(text, characters); |
+ } |
+ } |
+ return success; |
+} |
+ |
void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, |
const void* text, |
size_t byteLength, |
@@ -373,13 +421,19 @@ |
SkScalar y, |
const SkPaint& paint) { |
SkGDIFontSetup setup; |
+ bool useDrawPath = true; |
+ |
if (SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() |
&& setup.useGDI(hdc_, paint)) { |
UINT options = getTextOutOptions(paint); |
UINT count = byteLength >> 1; |
- ExtTextOut(hdc_, SkScalarRound(x), SkScalarRound(y + getAscent(paint)), |
- options, 0, reinterpret_cast<const wchar_t*>(text), count, NULL); |
- } else { |
+ useDrawPath = !EnsureExtTextOut(hdc_, SkScalarRound(x), |
+ SkScalarRound(y + getAscent(paint)), options, 0, |
+ reinterpret_cast<const wchar_t*>(text), count, NULL, |
+ paint.getTypeface()); |
+ } |
+ |
+ if (useDrawPath) { |
SkPath path; |
paint.getTextPath(text, byteLength, x, y, &path); |
drawPath(draw, path, paint); |
@@ -407,6 +461,8 @@ |
int scalarsPerPos, |
const SkPaint& paint) { |
SkGDIFontSetup setup; |
+ bool useDrawText = true; |
+ |
if (2 == scalarsPerPos |
&& SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() |
&& setup.useGDI(hdc_, paint)) { |
@@ -419,9 +475,12 @@ |
advances[i] = SkScalarRound(pos[2] - pos[0]); |
pos += 2; |
} |
- ExtTextOut(hdc_, startX, startY, getTextOutOptions(paint), 0, |
- reinterpret_cast<const wchar_t*>(text), count, advances); |
- } else { |
+ useDrawText = !EnsureExtTextOut(hdc_, startX, startY, |
+ getTextOutOptions(paint), 0, reinterpret_cast<const wchar_t*>(text), |
+ count, advances, paint.getTypeface()); |
+ } |
+ |
+ if (useDrawText) { |
size_t (*bytesPerCodePoint)(const char*); |
switch (paint.getTextEncoding()) { |
case SkPaint::kUTF8_TextEncoding: |