diff options
author | edisonn@google.com <edisonn@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 01:14:56 +0000 |
---|---|---|
committer | edisonn@google.com <edisonn@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 01:14:56 +0000 |
commit | feb3237e3c328f51525f90ea41737fe6eee28eef (patch) | |
tree | 9c45f0489ca6174ad0bb253c155ecfce742393be /skia/ext | |
parent | e8a9892eefaf046b752e229d0af39ac2c855e0ae (diff) | |
download | chromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.zip chromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.tar.gz chromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.tar.bz2 |
This is a fix for http://code.google.com/p/chromium/issues/detail?id=128506 - Random Chinese/Japanese characters are missing in documents printed via the system print dialog on Windows XP SP3
The cause of the bug is that ensureFontLoaded just does not work for the printing thread because GetTextMetrics(font) is not guaranteed to load the TrueType font for an HDC build from CreateEnhMetaFile. The only way I found to force font loading is to create a dummy HDC with CreateEnhMetaFile and then print the offending character(s).
This change contains:
- wirings for foo_CacheFontCharacters similar with foo_CacheFont, but with dispatch this message in RenderMessageFilter and defined in view_messages.h
- SkFontHost::EnsureTypefaceCharactersAccessible similar with SkFontHost::EnsureTypefaceAccessible
- Small refactoring of ExtTextOut call which would
- Call ExtTextOut
- If failed, calls SkFontHost::EnsureTypefaceCharactersAccessible
- call ExtTextOutAgain and return success/failure
- the calller will default to a skia paintPath (lower quality, but correct) if above fails
Notice: No tests for now, lets's make sure the design is right, then I will add tests too.
Contributed by edisonn@google.com
Review URL: https://chromiumcodereview.appspot.com/11363008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168943 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext')
-rw-r--r-- | skia/ext/vector_platform_device_emf_win.cc | 72 | ||||
-rw-r--r-- | skia/ext/vector_platform_device_emf_win.h | 6 |
2 files changed, 70 insertions, 8 deletions
diff --git a/skia/ext/vector_platform_device_emf_win.cc b/skia/ext/vector_platform_device_emf_win.cc index 73be491..243e808 100644 --- a/skia/ext/vector_platform_device_emf_win.cc +++ b/skia/ext/vector_platform_device_emf_win.cc @@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <windows.h> - #include "skia/ext/vector_platform_device_emf_win.h" +#include <windows.h> + +#include "base/logging.h" +#include "base/string16.h" #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 +369,48 @@ static UINT getTextOutOptions(const SkPaint& paint) { } } +static SkiaEnsureTypefaceCharactersAccessible + g_skia_ensure_typeface_characters_accessible = NULL; + +SK_API void SetSkiaEnsureTypefaceCharactersAccessible( + SkiaEnsureTypefaceCharactersAccessible func) { + // This function is supposed to be called once in process life time. + SkASSERT(g_skia_ensure_typeface_characters_accessible == NULL); + g_skia_ensure_typeface_characters_accessible = func; +} + +void EnsureTypefaceCharactersAccessible( + const SkTypeface& typeface, const wchar_t* text, unsigned int text_length) { + LOGFONT lf; + SkLOGFONTFromTypeface(&typeface, &lf); + g_skia_ensure_typeface_characters_accessible(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: " << string16(text, characters); + } + } else { + VLOG(1) << "ExtTextOut FAILED for default FaceName " + << " and characters: " << string16(text, characters); + } + } + return success; +} + void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, const void* text, size_t byteLength, @@ -373,13 +418,19 @@ void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, 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 +458,8 @@ void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw, int scalarsPerPos, const SkPaint& paint) { SkGDIFontSetup setup; + bool useDrawText = true; + if (2 == scalarsPerPos && SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() && setup.useGDI(hdc_, paint)) { @@ -419,9 +472,12 @@ void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw, 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: diff --git a/skia/ext/vector_platform_device_emf_win.h b/skia/ext/vector_platform_device_emf_win.h index 6d84d3a..af0e429 100644 --- a/skia/ext/vector_platform_device_emf_win.h +++ b/skia/ext/vector_platform_device_emf_win.h @@ -127,6 +127,12 @@ class VectorPlatformDeviceEmf : public SkDevice, public PlatformDevice { DISALLOW_COPY_AND_ASSIGN(VectorPlatformDeviceEmf); }; +typedef void (*SkiaEnsureTypefaceCharactersAccessible) + (const LOGFONT& font, const wchar_t* text, unsigned int text_length); + +SK_API void SetSkiaEnsureTypefaceCharactersAccessible( + SkiaEnsureTypefaceCharactersAccessible func); + } // namespace skia #endif // SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_ |