| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |