Changeset 58585 in webkit
- Timestamp:
- Apr 30, 2010, 10:50:39 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r58584 r58585 1 2010-04-30 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Adele Peterson. 4 5 Updated results for <rdar://problem/6649734> Text repainting does not account for glyphs which draw outside the typographic bounds of the font 6 https://bugs.webkit.org/show_bug.cgi?id=6274 7 8 * platform/mac/fast/repaint/stacked-diacritics-expected.checksum: 9 * platform/mac/fast/repaint/stacked-diacritics-expected.png: 10 1 11 2010-04-30 Chris Marrin <cmarrin@apple.com> 2 12 -
trunk/LayoutTests/platform/mac/fast/repaint/stacked-diacritics-expected.checksum
r58426 r58585 1 214a62226351798b782ad9c839ab900d 1 61cab097914525fb7f7a07989330012e -
trunk/WebCore/ChangeLog
r58584 r58585 1 2010-04-30 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Adele Peterson. 4 5 Part of <rdar://problem/6649734> Text repainting does not account for glyphs which draw outside the typographic bounds of the font 6 https://bugs.webkit.org/show_bug.cgi?id=6274 7 8 Account for glyph overflow of characters in the range U+1E00..U+2000, but without sending them 9 through the complex text code path. Instead, introduce a variant of the fast path that tracks 10 glyph overflow. 11 12 * platform/graphics/Font.cpp: 13 (WebCore::Font::drawText): Use codePath(). 14 (WebCore::Font::floatWidth): Use codePath(). Pass the GlyphOverflow pointer through to 15 floatWidthForSimpleText() if the code path is SimpleWithGlyphOverflow. 16 (WebCore::Font::selectionRectForText): Use codePath(). 17 (WebCore::Font::offsetForPosition): Ditto. 18 * platform/graphics/Font.h: Replaced canUseGlyphCache() with codePath(). Added a GlyphOverflow 19 parameter to floatWidthForSimpleText(). 20 * platform/graphics/FontFastPath.cpp: 21 Removed ROMAN_AND_GREEK_DIACRITICS_CAN_USE_GLYPH_CACHE. 22 (WebCore::Font::codePath): Renamed canUseGlyphCache() to this. Where it used to return false, 23 it now returns Complex. Where it used to return true, it now returns Simple, except for 24 the range U+1E00..U+2000, where it now returns SimpleWithGlyphOverflow. 25 (WebCore::Font::floatWidthForSimpleText): Added a GlyphOverflow parameter. If not 0, have the 26 width iterator account for glyph bounds, then update the GlyphOverflow accordingly. 27 * platform/graphics/WidthIterator.cpp: 28 (WebCore::WidthIterator::WidthIterator): Added boolean parameter telling the width iterator 29 whether to account for glyph bounds. Initialize m_accountForGlyphBounds accordingly. Initialize 30 m_maxGlyphBoundingBoxY, m_minGlyphBoundingBoxY, m_firstGlyphOverflow and m_lastGlyphOverflow. 31 (WebCore::WidthIterator::advance): If accounting for glyph bounds, update the above member variables. 32 * platform/graphics/WidthIterator.h: 33 (WebCore::WidthIterator::maxGlyphBoundingBoxY): Added this accessor. 34 (WebCore::WidthIterator::minGlyphBoundingBoxY): Ditto. 35 (WebCore::WidthIterator::firstGlyphOverflow): Ditto. 36 (WebCore::WidthIterator::lastGlyphOverflow): Ditto. 37 1 38 2010-04-30 Chris Marrin <cmarrin@apple.com> 2 39 -
trunk/WebCore/platform/graphics/Font.cpp
r57215 r58585 176 176 177 177 #if USE(FONT_FAST_PATH) 178 if (c anUseGlyphCache(run))178 if (codePath(run) != Complex) 179 179 return drawSimpleText(context, run, point, from, to); 180 180 #endif … … 191 191 192 192 #if USE(FONT_FAST_PATH) 193 if (canUseGlyphCache(run)) { 193 CodePath codePathToUse = codePath(run); 194 if (codePathToUse != Complex) { 194 195 // If the complex text implementation cannot return fallback fonts, avoid 195 196 // returning them for simple text as well. 196 197 static bool returnFallbackFonts = canReturnFallbackFontsForComplexText(); 197 return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0 );198 return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow ? glyphOverflow : 0); 198 199 } 199 200 #endif … … 215 216 216 217 #if USE(FONT_FAST_PATH) 217 if (c anUseGlyphCache(run))218 if (codePath(run) != Complex) 218 219 return floatWidthForSimpleText(run, 0); 219 220 #endif … … 232 233 233 234 #if USE(FONT_FAST_PATH) 234 if (c anUseGlyphCache(run))235 if (codePath(run) != Complex) 235 236 return selectionRectForSimpleText(run, point, h, from, to); 236 237 #endif … … 247 248 248 249 #if USE(FONT_FAST_PATH) 249 if (c anUseGlyphCache(run))250 if (codePath(run) != Complex) 250 251 return offsetForPositionForSimpleText(run, x, includePartialGlyphs); 251 252 #endif -
trunk/WebCore/platform/graphics/Font.h
r58042 r58585 151 151 static bool shouldUseSmoothing(); 152 152 153 #if USE(FONT_FAST_PATH) 154 enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow }; 155 #endif 156 153 157 private: 154 158 #if ENABLE(SVG_FONTS) … … 161 165 162 166 #if USE(FONT_FAST_PATH) 163 bool canUseGlyphCache(const TextRun&) const;167 CodePath codePath(const TextRun&) const; 164 168 void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const; 165 169 void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const; 166 170 void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const TextRun&, const FloatPoint&) const; 167 float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0 ) const;171 float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; 168 172 int offsetForPositionForSimpleText(const TextRun&, int position, bool includePartialGlyphs) const; 169 173 FloatRect selectionRectForSimpleText(const TextRun&, const IntPoint&, int h, int from, int to) const; … … 182 186 // Useful for debugging the different font rendering code paths. 183 187 #if USE(FONT_FAST_PATH) 184 enum CodePath { Auto, Simple, Complex };185 188 static void setCodePath(CodePath); 186 189 static CodePath codePath(); -
trunk/WebCore/platform/graphics/FontFastPath.cpp
r58426 r58585 37 37 #include <wtf/unicode/Unicode.h> 38 38 39 #ifndef ROMAN_AND_GREEK_DIACRITICS_CAN_USE_GLYPH_CACHE40 #define ROMAN_AND_GREEK_DIACRITICS_CAN_USE_GLYPH_CACHE 141 #endif42 43 39 using namespace WTF; 44 40 using namespace Unicode; … … 195 191 } 196 192 197 bool Font::canUseGlyphCache(const TextRun& run) const 198 { 199 switch (s_codePath) { 200 case Auto: 201 break; 202 case Simple: 203 return true; 204 case Complex: 205 return false; 206 } 207 193 Font::CodePath Font::codePath(const TextRun& run) const 194 { 195 if (s_codePath != Auto) 196 return s_codePath; 197 208 198 // Start from 0 since drawing and highlighting also measure the characters before run->from 209 199 for (int i = 0; i < run.length(); i++) { … … 212 202 continue; 213 203 if (c <= 0x36F) 214 return false;204 return Complex; 215 205 216 206 if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha 217 207 continue; 218 208 if (c <= 0x05CF) 219 return false;209 return Complex; 220 210 221 211 if (c < 0x0600) // U+0600 through U+1059 Arabic, Syriac, Thaana, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar 222 212 continue; 223 213 if (c <= 0x1059) 224 return false;214 return Complex; 225 215 226 216 if (c < 0x1100) // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose; Modern Korean will be precomposed as a result of step A) 227 217 continue; 228 218 if (c <= 0x11FF) 229 return false;219 return Complex; 230 220 231 221 if (c < 0x1780) // U+1780 through U+18AF Khmer, Mongolian 232 222 continue; 233 223 if (c <= 0x18AF) 234 return false;224 return Complex; 235 225 236 226 if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0) 237 227 continue; 238 228 if (c <= 0x194F) 239 return false; 240 241 #if !ROMAN_AND_GREEK_DIACRITICS_CAN_USE_GLYPH_CACHE 242 // FIXME: we should not use complex text path for these characters. 229 return Complex; 230 243 231 if (c < 0x1E00) // U+1E00 through U+2000 characters with diacritics and stacked diacritics 244 232 continue; 245 233 if (c <= 0x2000) 246 return false; 247 #endif 234 return SimpleWithGlyphOverflow; 248 235 249 236 if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols 250 237 continue; 251 238 if (c <= 0x20FF) 252 return false;239 return Complex; 253 240 254 241 if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks 255 242 continue; 256 243 if (c <= 0xFE2F) 257 return false;244 return Complex; 258 245 } 259 246 260 247 if (typesettingFeatures()) 261 return false; 262 263 return true; 264 248 return Complex; 249 250 return Simple; 265 251 } 266 252 … … 327 313 } 328 314 329 float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts ) const330 { 331 WidthIterator it(this, run, fallbackFonts );315 float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 316 { 317 WidthIterator it(this, run, fallbackFonts, glyphOverflow); 332 318 it.advance(run.length(), glyphBuffer); 319 320 if (glyphOverflow) { 321 glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - ascent()); 322 glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - descent()); 323 glyphOverflow->left = ceilf(it.firstGlyphOverflow()); 324 glyphOverflow->right = ceilf(it.lastGlyphOverflow()); 325 } 326 333 327 return it.m_runWidthSoFar; 334 328 } -
trunk/WebCore/platform/graphics/WidthIterator.cpp
r44439 r58585 34 34 using namespace WTF; 35 35 using namespace Unicode; 36 using namespace std; 36 37 37 38 namespace WebCore { … … 40 41 static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8; 41 42 42 WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts )43 WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds) 43 44 : m_font(font) 44 45 , m_run(run) … … 48 49 , m_finalRoundingWidth(0) 49 50 , m_fallbackFonts(fallbackFonts) 51 , m_accountForGlyphBounds(accountForGlyphBounds) 52 , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) 53 , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) 54 , m_firstGlyphOverflow(0) 55 , m_lastGlyphOverflow(0) 50 56 { 51 57 // If the padding is non-zero, count the number of spaces in the run … … 80 86 float runWidthSoFar = m_runWidthSoFar; 81 87 float lastRoundingWidth = m_finalRoundingWidth; 88 FloatRect bounds; 82 89 83 90 const SimpleFontData* primaryFont = m_font->primaryFont(); … … 176 183 } 177 184 185 if (m_accountForGlyphBounds) { 186 bounds = fontData->boundsForGlyph(glyph); 187 if (!currentCharacter) 188 m_firstGlyphOverflow = max<float>(0, -bounds.x()); 189 } 190 178 191 // Advance past the character we just dealt with. 179 192 cp += clusterLength; … … 206 219 207 220 lastRoundingWidth = width - oldWidth; 221 222 if (m_accountForGlyphBounds) { 223 m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.bottom()); 224 m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, bounds.y()); 225 m_lastGlyphOverflow = max<float>(0, bounds.right() - width); 226 } 208 227 } 209 228 -
trunk/WebCore/platform/graphics/WidthIterator.h
r42379 r58585 34 34 35 35 struct WidthIterator { 36 WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0 );36 WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false); 37 37 38 38 void advance(int to, GlyphBuffer* = 0); 39 39 bool advanceOneCharacter(float& width, GlyphBuffer* = 0); 40 41 float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; } 42 float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; } 43 float firstGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_firstGlyphOverflow; } 44 float lastGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_lastGlyphOverflow; } 40 45 41 46 const Font* m_font; … … 52 57 private: 53 58 UChar32 normalizeVoicingMarks(int currentCharacter); 59 54 60 HashSet<const SimpleFontData*>* m_fallbackFonts; 61 bool m_accountForGlyphBounds; 62 float m_maxGlyphBoundingBoxY; 63 float m_minGlyphBoundingBoxY; 64 float m_firstGlyphOverflow; 65 float m_lastGlyphOverflow; 55 66 }; 56 67
Note:
See TracChangeset
for help on using the changeset viewer.