diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/platform/graphics/chromium | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/platform/graphics/chromium')
5 files changed, 74 insertions, 23 deletions
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp index 9252ae0..e8fa860 100644 --- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp @@ -261,7 +261,7 @@ static HFONT createFontIndirectAndGetWinName(const String& family, LOGFONT* winf // characters. Because it's family names rather than font faces we use // as keys, there might be edge cases where one face of a font family // has a different repertoire from another face of the same family. -typedef HashMap<const wchar_t*, UnicodeSet*> FontCmapCache; +typedef HashMap<const wchar_t*, icu::UnicodeSet*> FontCmapCache; static bool fontContainsCharacter(const FontPlatformData* fontData, const wchar_t* family, UChar32 character) @@ -277,7 +277,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData, if (!fontCmapCache) fontCmapCache = new FontCmapCache; - HashMap<const wchar_t*, UnicodeSet*>::iterator it = fontCmapCache->find(family); + HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find(family); if (it != fontCmapCache->end()) return it->second->contains(character); @@ -308,7 +308,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData, // 1) port back ICU 4.0's faster look-up code for UnicodeSet // 2) port Mozilla's CompressedCharMap or gfxSparseBitset unsigned i = 0; - UnicodeSet* cmap = new UnicodeSet; + icu::UnicodeSet* cmap = new icu::UnicodeSet; while (i < glyphset->cRanges) { WCHAR start = glyphset->ranges[i].wcLow; cmap->add(start, start + glyphset->ranges[i].cGlyphs - 1); diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp index 3d67992..229188e 100644 --- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp @@ -459,14 +459,16 @@ void Font::drawComplexText(GraphicsContext* graphicsContext, TransparencyAwareUniscribePainter painter(graphicsContext, this, run, from, to, point); HDC hdc = painter.hdc(); - if (!hdc) + if (windowsCanHandleTextDrawing(graphicsContext) && !hdc) return; // TODO(maruel): http://b/700464 SetTextColor doesn't support transparency. // Enforce non-transparent color. color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color)); - SetTextColor(hdc, skia::SkColorToCOLORREF(color)); - SetBkMode(hdc, TRANSPARENT); + if (hdc) { + SetTextColor(hdc, skia::SkColorToCOLORREF(color)); + SetBkMode(hdc, TRANSPARENT); + } // If there is a non-blur shadow and both the fill color and shadow color // are opaque, handle without skia. diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp index d4e45fb..dca0efb 100644 --- a/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -45,6 +45,11 @@ #include "SkTypeface.h" #include "SkUtils.h" +#include <unicode/normlzr.h> +#include <unicode/uchar.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/OwnPtr.h> + namespace WebCore { bool Font::canReturnFallbackFontsForComplexText() @@ -136,27 +141,29 @@ class TextRunWalker { public: TextRunWalker(const TextRun& run, unsigned startingX, const Font* font) : m_font(font) - , m_run(run) , m_startingX(startingX) , m_offsetX(m_startingX) - , m_iterateBackwards(run.rtl()) + , m_run(getTextRun(run)) + , m_iterateBackwards(m_run.rtl()) { + // Do not use |run| inside this constructor. Use |m_run| instead. + memset(&m_item, 0, sizeof(m_item)); // We cannot know, ahead of time, how many glyphs a given script run // will produce. We take a guess that script runs will not produce more // than twice as many glyphs as there are code points and fallback if // we find that we are wrong. - m_maxGlyphs = run.length() * 2; + m_maxGlyphs = m_run.length() * 2; createGlyphArrays(); - m_item.log_clusters = new unsigned short[run.length()]; + m_item.log_clusters = new unsigned short[m_run.length()]; m_item.face = 0; m_item.font = allocHarfbuzzFont(); - m_item.string = run.characters(); - m_item.stringLength = run.length(); - m_item.item.bidiLevel = run.rtl(); + m_item.string = m_run.characters(); + m_item.stringLength = m_run.length(); + m_item.item.bidiLevel = m_run.rtl(); reset(); } @@ -283,6 +290,43 @@ public: } private: + const TextRun& getTextRun(const TextRun& originalRun) + { + // Convert the |originalRun| to NFC normalized form if combining diacritical marks + // (U+0300..) are used in the run. This conversion is necessary since most OpenType + // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in + // their GSUB tables. + // + // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since + // the API returns FALSE (= not normalized) for complex runs that don't require NFC + // normalization (e.g., Arabic text). Unless the run contains the diacritical marks, + // Harfbuzz will do the same thing for us using the GSUB table. + for (unsigned i = 0; i < originalRun.length(); ++i) { + UBlockCode block = ::ublock_getCode(originalRun[i]); + if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS) { + return getNormalizedTextRun(originalRun); + } + } + return originalRun; + } + + const TextRun& getNormalizedTextRun(const TextRun& originalRun) + { + icu::UnicodeString normalizedString; + UErrorCode error = U_ZERO_ERROR; + icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), originalRun.length()), UNORM_NFC, 0 /* no options */, normalizedString, error); + if (U_FAILURE(error)) + return originalRun; + + m_normalizedBuffer.set(new UChar[normalizedString.length() + 1]); + normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error); + ASSERT(U_SUCCESS(error)); + + m_normalizedRun.set(new TextRun(originalRun)); + m_normalizedRun->setText(m_normalizedBuffer.get(), normalizedString.length()); + return *m_normalizedRun; + } + void setupFontForScriptRun() { const FontData* fontData = m_font->fontDataAt(0); @@ -379,7 +423,6 @@ private: } const Font* const m_font; - const TextRun& m_run; HB_ShaperItem m_item; uint16_t* m_glyphs16; // A vector of 16-bit glyph ids. SkScalar* m_xPositions; // A vector of x positions for each glyph. @@ -389,6 +432,10 @@ private: unsigned m_pixelWidth; // Width (in px) of the current script run. unsigned m_numCodePoints; // Code points in current script run. unsigned m_maxGlyphs; // Current size of all the Harfbuzz arrays. + + OwnPtr<TextRun> m_normalizedRun; + OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run. + const TextRun& m_run; bool m_iterateBackwards; }; diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp index 9596a4c..4e2a226 100644 --- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp @@ -100,11 +100,11 @@ void initializeScriptFontMap(ScriptToFontMap& scriptFontMap) // Initialize the locale-dependent mapping. // Since Chrome synchronizes the ICU default locale with its UI locale, // this ICU locale tells the current UI locale of Chrome. - Locale locale = Locale::getDefault(); + icu::Locale locale = icu::Locale::getDefault(); const UChar* localeFamily = 0; - if (locale == Locale::getJapanese()) + if (locale == icu::Locale::getJapanese()) localeFamily = scriptFontMap[USCRIPT_HIRAGANA]; - else if (locale == Locale::getKorean()) + else if (locale == icu::Locale::getKorean()) localeFamily = scriptFontMap[USCRIPT_HANGUL]; else { // Use Simplified Chinese font for all other locales including diff --git a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp index 39b0847..10fcdf6 100644 --- a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp +++ b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp @@ -375,11 +375,13 @@ void UniscribeHelper::draw(GraphicsContext* graphicsContext, // Pass 0 in when there is no justification. const int* justify = shaping.m_justify.size() == 0 ? 0 : &shaping.m_justify[fromGlyph]; - if (firstRun) { - oldFont = SelectObject(dc, shaping.m_hfont); - firstRun = false; - } else - SelectObject(dc, shaping.m_hfont); + if (useWindowsDrawing) { + if (firstRun) { + oldFont = SelectObject(dc, shaping.m_hfont); + firstRun = false; + } else + SelectObject(dc, shaping.m_hfont); + } // Fonts with different ascents can be used to render different // runs. 'Across-runs' y-coordinate correction needs to be @@ -401,7 +403,7 @@ void UniscribeHelper::draw(GraphicsContext* graphicsContext, } else { SkPoint origin; origin.fX = curX + + innerOffset; - origin.fY = y + m_ascent - shaping.m_ascentOffset; + origin.fY = y + m_ascent; textOutOk = paintSkiaText(graphicsContext, shaping.m_hfont, glyphCount, |