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

Side by Side Diff: Source/platform/fonts/Font.cpp

Issue 1179723002: Store glyph bounds in WordMeasurement to avoid slow path width calc (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 5 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/fonts/Font.h ('k') | Source/platform/fonts/WidthCache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. 6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 206
207 GlyphBuffer glyphBuffer; 207 GlyphBuffer glyphBuffer;
208 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData); 208 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);
209 209
210 if (glyphBuffer.isEmpty()) 210 if (glyphBuffer.isEmpty())
211 return; 211 return;
212 212
213 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, deviceScaleFacto r); 213 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, deviceScaleFacto r);
214 } 214 }
215 215
216 static inline void updateGlyphOverflowFromBounds(const FloatRectOutsets& glyphBo unds, 216 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo nts, FloatRect* glyphBounds) const
217 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow)
218 {
219 glyphOverflow->top = ceilf(glyphOverflow->computeBounds ? glyphBounds.top() : std::max(0.0f, glyphBounds.top() - fontMetrics.floatAscent()));
220 glyphOverflow->bottom = ceilf(glyphOverflow->computeBounds ? glyphBounds.bot tom() : std::max(0.0f, glyphBounds.bottom() - fontMetrics.floatDescent()));
221 glyphOverflow->left = ceilf(glyphBounds.left());
222 glyphOverflow->right = ceilf(glyphBounds.right());
223 }
224
225 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo nts, GlyphOverflow* glyphOverflow) const
226 { 217 {
227 FontCachePurgePreventer purgePreventer; 218 FontCachePurgePreventer purgePreventer;
228 219
229 CodePath codePathToUse = codePath(TextRunPaintInfo(run)); 220 if (codePath(TextRunPaintInfo(run)) == ComplexPath)
230 221 return floatWidthForComplexText(run, fallbackFonts, glyphBounds);
231 float result; 222 return floatWidthForSimpleText(run, fallbackFonts, glyphBounds);
232 FloatRectOutsets glyphBounds;
233 if (codePathToUse == ComplexPath)
234 result = floatWidthForComplexText(run, fallbackFonts, &glyphBounds);
235 else
236 result = floatWidthForSimpleText(run, fallbackFonts, glyphOverflow ? &gl yphBounds : 0);
237
238 if (glyphOverflow)
239 updateGlyphOverflowFromBounds(glyphBounds, fontMetrics(), glyphOverflow) ;
240 return result;
241 } 223 }
242 224
243 PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer) const 225 PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer) const
244 { 226 {
245 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); 227 ASSERT(RuntimeEnabledFeatures::textBlobEnabled());
246 228
247 SkTextBlobBuilder builder; 229 SkTextBlobBuilder builder;
248 bool hasVerticalOffsets = glyphBuffer.hasVerticalOffsets(); 230 bool hasVerticalOffsets = glyphBuffer.hasVerticalOffsets();
249 231
250 unsigned i = 0; 232 unsigned i = 0;
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 canvas->restoreToCount(canvasStackLevel); 663 canvas->restoreToCount(canvasStackLevel);
682 } 664 }
683 665
684 void Font::drawTextBlob(SkCanvas* canvas, const SkPaint& paint, const SkTextBlob * blob, const SkPoint& origin) const 666 void Font::drawTextBlob(SkCanvas* canvas, const SkPaint& paint, const SkTextBlob * blob, const SkPoint& origin) const
685 { 667 {
686 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); 668 ASSERT(RuntimeEnabledFeatures::textBlobEnabled());
687 669
688 canvas->drawTextBlob(blob, origin.x(), origin.y(), paint); 670 canvas->drawTextBlob(blob, origin.x(), origin.y(), paint);
689 } 671 }
690 672
691 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, FloatRectOutsets* glyphBounds) const 673 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, FloatRect* outGlyphBounds) const
692 { 674 {
693 bool hasWordSpacingOrLetterSpacing = fontDescription().wordSpacing() 675 bool hasWordSpacingOrLetterSpacing = fontDescription().wordSpacing()
694 || fontDescription().letterSpacing(); 676 || fontDescription().letterSpacing();
695 // Word spacing and letter spacing can change the width of a word. 677 // Word spacing and letter spacing can change the width of a word.
696 // If a tab occurs inside a word, the width of the word varies based on its 678 // If a tab occurs inside a word, the width of the word varies based on its
697 // position on the line. 679 // position on the line.
698 bool isCacheable = !hasWordSpacingOrLetterSpacing && !run.allowTabs(); 680 bool isCacheable = !hasWordSpacingOrLetterSpacing && !run.allowTabs();
699 681
700 WidthCacheEntry* cacheEntry = isCacheable 682 WidthCacheEntry* cacheEntry = isCacheable
701 ? m_fontFallbackList->widthCache().add(run, WidthCacheEntry()) 683 ? m_fontFallbackList->widthCache().add(run, WidthCacheEntry())
702 : 0; 684 : 0;
703 if (cacheEntry && cacheEntry->isValid()) { 685 if (cacheEntry && cacheEntry->isValid()) {
704 ASSERT(glyphBounds); 686 if (outGlyphBounds)
705 *glyphBounds = cacheEntry->glyphBounds; 687 *outGlyphBounds = cacheEntry->glyphBounds;
706 return cacheEntry->width; 688 return cacheEntry->width;
707 } 689 }
708 690
709 FloatRect bounds; 691 FloatRect glyphBounds;
710 HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &boun ds : 0); 692 HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, &glyphBounds);
711 if (!shaper.shape()) 693 if (!shaper.shape())
712 return 0; 694 return 0;
713 695
714 glyphBounds->setTop(-bounds.y()); 696 float result = shaper.totalWidth();
715 glyphBounds->setBottom(bounds.maxY());
716 glyphBounds->setLeft(std::max(0.0f, -bounds.x()));
717 glyphBounds->setRight(std::max(0.0f, bounds.maxX() - shaper.totalWidth()));
718 697
719 float result = shaper.totalWidth();
720 if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty())) { 698 if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty())) {
721 cacheEntry->glyphBounds = *glyphBounds; 699 cacheEntry->glyphBounds = glyphBounds;
722 cacheEntry->width = result; 700 cacheEntry->width = result;
723 } 701 }
724 702
703 if (outGlyphBounds)
704 *outGlyphBounds = glyphBounds;
725 return result; 705 return result;
726 } 706 }
727 707
728 // Return the code point index for the given |x| offset into the text run. 708 // Return the code point index for the given |x| offset into the text run.
729 int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, 709 int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat,
730 bool includePartialGlyphs) const 710 bool includePartialGlyphs) const
731 { 711 {
732 HarfBuzzShaper shaper(this, run); 712 HarfBuzzShaper shaper(this, run);
733 if (!shaper.shape()) 713 if (!shaper.shape())
734 return 0; 714 return 0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 if (nextFontData != fontData) { 753 if (nextFontData != fontData) {
774 drawGlyphs(canvas, paint, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, point, runInfo.bounds, deviceScaleFactor); 754 drawGlyphs(canvas, paint, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, point, runInfo.bounds, deviceScaleFactor);
775 lastFrom = nextGlyph; 755 lastFrom = nextGlyph;
776 fontData = nextFontData; 756 fontData = nextFontData;
777 } 757 }
778 } 758 }
779 759
780 drawGlyphs(canvas, paint, fontData, glyphBuffer, lastFrom, nextGlyph - lastF rom, point, runInfo.bounds, deviceScaleFactor); 760 drawGlyphs(canvas, paint, fontData, glyphBuffer, lastFrom, nextGlyph - lastF rom, point, runInfo.bounds, deviceScaleFactor);
781 } 761 }
782 762
783 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, FloatRectOutsets* glyphBounds) const 763 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, FloatRect* glyphBounds) const
784 { 764 {
785 FloatRect bounds; 765 SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds);
786 SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &bounds : 0);
787 shaper.advance(run.length()); 766 shaper.advance(run.length());
788 float runWidth = shaper.runWidthSoFar(); 767 return shaper.runWidthSoFar();
789
790 if (glyphBounds) {
791 glyphBounds->setTop(-bounds.y());
792 glyphBounds->setBottom(bounds.maxY());
793 glyphBounds->setLeft(std::max(0.0f, -bounds.x()));
794 glyphBounds->setRight(std::max(0.0f, bounds.maxX() - runWidth));
795 }
796 return runWidth;
797 } 768 }
798 769
799 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const 770 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const
800 { 771 {
801 FloatRect bounds; 772 FloatRect bounds;
802 SimpleShaper shaper(this, run, nullptr, nullptr, accountForGlyphBounds ? &bo unds : nullptr); 773 SimpleShaper shaper(this, run, nullptr, nullptr, accountForGlyphBounds ? &bo unds : nullptr);
803 shaper.advance(from); 774 shaper.advance(from);
804 float fromX = shaper.runWidthSoFar(); 775 float fromX = shaper.runWidthSoFar();
805 shaper.advance(to); 776 shaper.advance(to);
806 float toX = shaper.runWidthSoFar(); 777 float toX = shaper.runWidthSoFar();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 { 837 {
867 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); 838 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
868 } 839 }
869 840
870 bool Font::isFallbackValid() const 841 bool Font::isFallbackValid() const
871 { 842 {
872 return !m_fontFallbackList || m_fontFallbackList->isValid(); 843 return !m_fontFallbackList || m_fontFallbackList->isValid();
873 } 844 }
874 845
875 } // namespace blink 846 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/fonts/Font.h ('k') | Source/platform/fonts/WidthCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698