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 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "gen/sky/platform/RuntimeEnabledFeatures.h" | 27 #include "gen/sky/platform/RuntimeEnabledFeatures.h" |
28 #include "sky/engine/platform/LayoutUnit.h" | 28 #include "sky/engine/platform/LayoutUnit.h" |
29 #include "sky/engine/platform/fonts/Character.h" | 29 #include "sky/engine/platform/fonts/Character.h" |
30 #include "sky/engine/platform/fonts/FontCache.h" | 30 #include "sky/engine/platform/fonts/FontCache.h" |
31 #include "sky/engine/platform/fonts/FontFallbackList.h" | 31 #include "sky/engine/platform/fonts/FontFallbackList.h" |
32 #include "sky/engine/platform/fonts/FontPlatformFeatures.h" | 32 #include "sky/engine/platform/fonts/FontPlatformFeatures.h" |
33 #include "sky/engine/platform/fonts/GlyphBuffer.h" | 33 #include "sky/engine/platform/fonts/GlyphBuffer.h" |
34 #include "sky/engine/platform/fonts/GlyphPageTreeNode.h" | 34 #include "sky/engine/platform/fonts/GlyphPageTreeNode.h" |
35 #include "sky/engine/platform/fonts/SimpleFontData.h" | 35 #include "sky/engine/platform/fonts/SimpleFontData.h" |
36 #include "sky/engine/platform/fonts/WidthIterator.h" | 36 #include "sky/engine/platform/fonts/WidthIterator.h" |
| 37 #include "sky/engine/platform/fonts/harfbuzz/HarfBuzzShaper.h" |
37 #include "sky/engine/platform/geometry/FloatRect.h" | 38 #include "sky/engine/platform/geometry/FloatRect.h" |
38 #include "sky/engine/platform/graphics/GraphicsContext.h" | 39 #include "sky/engine/platform/graphics/GraphicsContext.h" |
39 #include "sky/engine/platform/text/TextRun.h" | 40 #include "sky/engine/platform/text/TextRun.h" |
40 #include "sky/engine/wtf/MainThread.h" | 41 #include "sky/engine/wtf/MainThread.h" |
41 #include "sky/engine/wtf/StdLibExtras.h" | 42 #include "sky/engine/wtf/StdLibExtras.h" |
42 #include "sky/engine/wtf/unicode/CharacterNames.h" | 43 #include "sky/engine/wtf/unicode/CharacterNames.h" |
43 #include "sky/engine/wtf/unicode/Unicode.h" | 44 #include "sky/engine/wtf/unicode/Unicode.h" |
44 | 45 |
45 using namespace WTF; | 46 using namespace WTF; |
46 using namespace Unicode; | 47 using namespace Unicode; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
but it ends up | 97 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
but it ends up |
97 // being reasonably safe (because inherited fonts in the render tree pick up
the new | 98 // being reasonably safe (because inherited fonts in the render tree pick up
the new |
98 // style anyway. Other copies are transient, e.g., the state in the Graphics
Context, and | 99 // style anyway. Other copies are transient, e.g., the state in the Graphics
Context, and |
99 // won't stick around long enough to get you in trouble). Still, this is pre
tty disgusting, | 100 // won't stick around long enough to get you in trouble). Still, this is pre
tty disgusting, |
100 // and could eventually be rectified by using RefPtrs for Fonts themselves. | 101 // and could eventually be rectified by using RefPtrs for Fonts themselves. |
101 if (!m_fontFallbackList) | 102 if (!m_fontFallbackList) |
102 m_fontFallbackList = FontFallbackList::create(); | 103 m_fontFallbackList = FontFallbackList::create(); |
103 m_fontFallbackList->invalidate(fontSelector); | 104 m_fontFallbackList->invalidate(fontSelector); |
104 } | 105 } |
105 | 106 |
106 void Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, c
onst FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) const | 107 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph
Buffer, |
| 108 ForTextEmphasisOrNot forTextEmphasis) const |
| 109 { |
| 110 if (codePath(runInfo.run) == ComplexPath) { |
| 111 HarfBuzzShaper shaper(this, runInfo.run, (forTextEmphasis == ForTextEmph
asis) |
| 112 ? HarfBuzzShaper::ForTextEmphasis : HarfBuzzShaper::NotForTextEmphas
is); |
| 113 shaper.setDrawRange(runInfo.from, runInfo.to); |
| 114 shaper.shape(&glyphBuffer); |
| 115 |
| 116 return 0; |
| 117 } |
| 118 |
| 119 WidthIterator it(this, runInfo.run, nullptr, false, forTextEmphasis); |
| 120 it.advance(runInfo.from); |
| 121 float beforeWidth = it.runWidthSoFar(); |
| 122 it.advance(runInfo.to, &glyphBuffer); |
| 123 |
| 124 if (runInfo.run.ltr()) |
| 125 return beforeWidth; |
| 126 |
| 127 // RTL |
| 128 float afterWidth = it.runWidthSoFar(); |
| 129 it.advance(runInfo.run.length()); |
| 130 glyphBuffer.reverse(); |
| 131 |
| 132 return it.runWidthSoFar() - afterWidth; |
| 133 } |
| 134 |
| 135 void Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, |
| 136 const FloatPoint& point) const |
| 137 { |
| 138 // Don't draw anything while we are using custom fonts that are in the proce
ss of loading. |
| 139 if (shouldSkipDrawing()) |
| 140 return; |
| 141 |
| 142 TextDrawingModeFlags textMode = context->textDrawingMode(); |
| 143 if (!(textMode & TextModeFill) && !((textMode & TextModeStroke) && context->
hasStroke())) |
| 144 return; |
| 145 |
| 146 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
| 147 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
| 148 // we have a pre-cached blob -- happy joy! |
| 149 drawTextBlob(context, runInfo.cachedTextBlob->get(), point.data()); |
| 150 return; |
| 151 } |
| 152 |
| 153 GlyphBuffer glyphBuffer; |
| 154 float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer); |
| 155 |
| 156 if (glyphBuffer.isEmpty()) |
| 157 return; |
| 158 |
| 159 if (RuntimeEnabledFeatures::textBlobEnabled()) { |
| 160 // Enabling text-blobs forces the blob rendering path even for uncacheab
le blobs. |
| 161 TextBlobPtr uncacheableTextBlob; |
| 162 TextBlobPtr& textBlob = runInfo.cachedTextBlob ? *runInfo.cachedTextBlob
: uncacheableTextBlob; |
| 163 FloatRect blobBounds = runInfo.bounds; |
| 164 blobBounds.moveBy(-point); |
| 165 |
| 166 textBlob = buildTextBlob(glyphBuffer, initialAdvance, blobBounds); |
| 167 if (textBlob) { |
| 168 drawTextBlob(context, textBlob.get(), point.data()); |
| 169 return; |
| 170 } |
| 171 } |
| 172 |
| 173 drawGlyphBuffer(context, runInfo, glyphBuffer, FloatPoint(point.x() + initia
lAdvance, point.y())); |
| 174 } |
| 175 |
| 176 float Font::drawUncachedText(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, |
| 177 const FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction)
const |
107 { | 178 { |
108 // Don't draw anything while we are using custom fonts that are in the proce
ss of loading, | 179 // Don't draw anything while we are using custom fonts that are in the proce
ss of loading, |
109 // except if the 'force' argument is set to true (in which case it will use
a fallback | 180 // except if the 'force' argument is set to true (in which case it will use
a fallback |
110 // font). | 181 // font). |
111 if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotRe
ady) | 182 if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotRe
ady) |
112 return; | 183 return 0; |
113 | 184 |
114 CodePath codePathToUse = codePath(runInfo.run); | 185 TextDrawingModeFlags textMode = context->textDrawingMode(); |
115 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 | 186 if (!(textMode & TextModeFill) && !((textMode & TextModeStroke) && context->
hasStroke())) |
116 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) | 187 return 0; |
117 codePathToUse = ComplexPath; | |
118 | 188 |
119 if (codePathToUse != ComplexPath) { | 189 GlyphBuffer glyphBuffer; |
120 drawSimpleText(context, runInfo, point); | 190 float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer); |
121 } else { | 191 |
122 drawComplexText(context, runInfo, point); | 192 if (glyphBuffer.isEmpty()) |
123 } | 193 return 0; |
| 194 |
| 195 return drawGlyphBuffer(context, runInfo, glyphBuffer, FloatPoint(point.x() +
initialAdvance, point.y())); |
124 } | 196 } |
125 | 197 |
126 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const AtomicString& mark, const FloatPoint& point) const | 198 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const AtomicString& mark, const FloatPoint& point) const |
127 { | 199 { |
128 if (shouldSkipDrawing()) | 200 if (shouldSkipDrawing()) |
129 return; | 201 return; |
130 | 202 |
131 CodePath codePathToUse = codePath(runInfo.run); | 203 GlyphBuffer glyphBuffer; |
132 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 | 204 float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer, ForTextEmphasi
s); |
133 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) | |
134 codePathToUse = ComplexPath; | |
135 | 205 |
136 if (codePathToUse != ComplexPath) | 206 if (glyphBuffer.isEmpty()) |
137 drawEmphasisMarksForSimpleText(context, runInfo, mark, point); | 207 return; |
138 else | 208 |
139 drawEmphasisMarksForComplexText(context, runInfo, mark, point); | 209 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x()
+ initialAdvance, point.y())); |
140 } | 210 } |
141 | 211 |
142 static inline void updateGlyphOverflowFromBounds(const IntRectExtent& glyphBound
s, | 212 static inline void updateGlyphOverflowFromBounds(const IntRectExtent& glyphBound
s, |
143 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) | 213 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) |
144 { | 214 { |
145 glyphOverflow->top = std::max<int>(glyphOverflow->top, | 215 glyphOverflow->top = std::max<int>(glyphOverflow->top, |
146 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce
nt())); | 216 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce
nt())); |
147 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, | 217 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, |
148 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d
escent())); | 218 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d
escent())); |
149 glyphOverflow->left = glyphBounds.left(); | 219 glyphOverflow->left = glyphBounds.left(); |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 return 0; | 672 return 0; |
603 | 673 |
604 const SimpleFontData* markFontData = markGlyphData.fontData; | 674 const SimpleFontData* markFontData = markGlyphData.fontData; |
605 ASSERT(markFontData); | 675 ASSERT(markFontData); |
606 if (!markFontData) | 676 if (!markFontData) |
607 return 0; | 677 return 0; |
608 | 678 |
609 return markFontData->fontMetrics().height(); | 679 return markFontData->fontMetrics().height(); |
610 } | 680 } |
611 | 681 |
612 float Font::getGlyphsAndAdvancesForSimpleText(const TextRunPaintInfo& runInfo, G
lyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const | 682 float Font::drawGlyphBuffer(GraphicsContext* context, const TextRunPaintInfo& ru
nInfo, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const |
613 { | |
614 float initialAdvance; | |
615 | |
616 WidthIterator it(this, runInfo.run, 0, false, forTextEmphasis); | |
617 it.advance(runInfo.from); | |
618 float beforeWidth = it.m_runWidthSoFar; | |
619 it.advance(runInfo.to, &glyphBuffer); | |
620 | |
621 if (glyphBuffer.isEmpty()) | |
622 return 0; | |
623 | |
624 float afterWidth = it.m_runWidthSoFar; | |
625 | |
626 if (runInfo.run.rtl()) { | |
627 it.advance(runInfo.run.length()); | |
628 initialAdvance = it.m_runWidthSoFar - afterWidth; | |
629 glyphBuffer.reverse(); | |
630 } else { | |
631 initialAdvance = beforeWidth; | |
632 } | |
633 | |
634 return initialAdvance; | |
635 } | |
636 | |
637 void Font::drawSimpleText(GraphicsContext* context, const TextRunPaintInfo& runI
nfo, const FloatPoint& point) const | |
638 { | |
639 // This glyph buffer holds our glyphs+advances+font data for each glyph. | |
640 GlyphBuffer glyphBuffer; | |
641 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r); | |
642 ASSERT(!glyphBuffer.hasVerticalAdvances()); | |
643 | |
644 if (glyphBuffer.isEmpty()) | |
645 return; | |
646 | |
647 TextBlobPtr textBlob; | |
648 if (RuntimeEnabledFeatures::textBlobEnabled()) { | |
649 // Using text blob causes a small difference in how gradients and | |
650 // patterns are rendered. | |
651 // FIXME: Fix this, most likely in Skia. | |
652 if (!context->strokeGradient() && !context->strokePattern() && !context-
>fillGradient() && !context->fillPattern()) { | |
653 FloatRect blobBounds = runInfo.bounds; | |
654 blobBounds.moveBy(-point); | |
655 textBlob = buildTextBlob(glyphBuffer, initialAdvance, blobBounds); | |
656 } | |
657 } | |
658 | |
659 if (textBlob) { | |
660 drawTextBlob(context, textBlob.get(), point.data()); | |
661 } else { | |
662 FloatPoint startPoint(point.x() + initialAdvance, point.y()); | |
663 drawGlyphBuffer(context, runInfo, glyphBuffer, startPoint); | |
664 } | |
665 } | |
666 | |
667 void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRu
nPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const | |
668 { | |
669 GlyphBuffer glyphBuffer; | |
670 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r, ForTextEmphasis); | |
671 | |
672 if (glyphBuffer.isEmpty()) | |
673 return; | |
674 | |
675 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x()
+ initialAdvance, point.y())); | |
676 } | |
677 | |
678 void Font::drawGlyphBuffer(GraphicsContext* context, const TextRunPaintInfo& run
Info, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const | |
679 { | 683 { |
680 // Draw each contiguous run of glyphs that use the same font data. | 684 // Draw each contiguous run of glyphs that use the same font data. |
681 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); | 685 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); |
682 FloatPoint startPoint(point); | 686 FloatPoint startPoint(point); |
683 FloatPoint nextPoint = startPoint + glyphBuffer.advanceAt(0); | 687 float advanceSoFar = 0; |
684 unsigned lastFrom = 0; | 688 unsigned lastFrom = 0; |
685 unsigned nextGlyph = 1; | 689 unsigned nextGlyph = 0; |
686 while (nextGlyph < glyphBuffer.size()) { | 690 while (nextGlyph < glyphBuffer.size()) { |
687 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); | 691 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); |
688 | |
689 if (nextFontData != fontData) { | 692 if (nextFontData != fontData) { |
690 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las
tFrom, startPoint, runInfo.bounds); | 693 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las
tFrom, startPoint, runInfo.bounds); |
691 | |
692 lastFrom = nextGlyph; | 694 lastFrom = nextGlyph; |
693 fontData = nextFontData; | 695 fontData = nextFontData; |
694 startPoint = nextPoint; | 696 startPoint += FloatSize(advanceSoFar, 0); |
| 697 advanceSoFar = 0; |
695 } | 698 } |
696 nextPoint += glyphBuffer.advanceAt(nextGlyph); | 699 advanceSoFar += glyphBuffer.advanceAt(nextGlyph); |
697 nextGlyph++; | 700 nextGlyph++; |
698 } | 701 } |
| 702 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, s
tartPoint, runInfo.bounds); |
| 703 startPoint += FloatSize(advanceSoFar, 0); |
| 704 return startPoint.x() - point.x(); |
| 705 } |
699 | 706 |
700 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, s
tartPoint, runInfo.bounds); | |
701 } | |
702 | 707 |
703 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph
glyph) | 708 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph
glyph) |
704 { | 709 { |
705 if (fontData->platformData().orientation() == Horizontal) { | 710 if (fontData->platformData().orientation() == Horizontal) { |
706 FloatRect bounds = fontData->boundsForGlyph(glyph); | 711 FloatRect bounds = fontData->boundsForGlyph(glyph); |
707 return bounds.x() + bounds.width() / 2; | 712 return bounds.x() + bounds.width() / 2; |
708 } | 713 } |
709 // FIXME: Use glyph bounds once they make sense for vertical fonts. | 714 // FIXME: Use glyph bounds once they make sense for vertical fonts. |
710 return fontData->widthForGlyph(glyph) / 2; | 715 return fontData->widthForGlyph(glyph) / 2; |
711 } | 716 } |
712 | 717 |
713 inline static float offsetToMiddleOfAdvanceAtIndex(const GlyphBuffer& glyphBuffe
r, size_t i) | 718 inline static float offsetToMiddleOfAdvanceAtIndex(const GlyphBuffer& glyphBuffe
r, size_t i) |
714 { | 719 { |
715 return glyphBuffer.advanceAt(i).width() / 2; | 720 return glyphBuffer.advanceAt(i) / 2; |
716 } | 721 } |
717 | 722 |
718 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi
nt& point) const | 723 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi
nt& point) const |
719 { | 724 { |
720 FontCachePurgePreventer purgePreventer; | 725 FontCachePurgePreventer purgePreventer; |
721 | 726 |
722 GlyphData markGlyphData; | 727 GlyphData markGlyphData; |
723 if (!getEmphasisMarkGlyphData(mark, markGlyphData)) | 728 if (!getEmphasisMarkGlyphData(mark, markGlyphData)) |
724 return; | 729 return; |
725 | 730 |
726 const SimpleFontData* markFontData = markGlyphData.fontData; | 731 const SimpleFontData* markFontData = markGlyphData.fontData; |
727 ASSERT(markFontData); | 732 ASSERT(markFontData); |
728 if (!markFontData) | 733 if (!markFontData) |
729 return; | 734 return; |
730 | 735 |
731 Glyph markGlyph = markGlyphData.glyph; | 736 Glyph markGlyph = markGlyphData.glyph; |
732 Glyph spaceGlyph = markFontData->spaceGlyph(); | 737 Glyph spaceGlyph = markFontData->spaceGlyph(); |
733 | 738 |
734 float middleOfLastGlyph = offsetToMiddleOfAdvanceAtIndex(glyphBuffer, 0); | 739 float middleOfLastGlyph = offsetToMiddleOfAdvanceAtIndex(glyphBuffer, 0); |
735 FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(
markFontData, markGlyph), point.y()); | 740 FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(
markFontData, markGlyph), point.y()); |
736 | 741 |
737 GlyphBuffer markBuffer; | 742 GlyphBuffer markBuffer; |
738 for (unsigned i = 0; i + 1 < glyphBuffer.size(); ++i) { | 743 for (unsigned i = 0; i + 1 < glyphBuffer.size(); ++i) { |
739 float middleOfNextGlyph = offsetToMiddleOfAdvanceAtIndex(glyphBuffer, i
+ 1); | 744 float middleOfNextGlyph = offsetToMiddleOfAdvanceAtIndex(glyphBuffer, i
+ 1); |
740 float advance = glyphBuffer.advanceAt(i).width() - middleOfLastGlyph + m
iddleOfNextGlyph; | 745 float advance = glyphBuffer.advanceAt(i) - middleOfLastGlyph + middleOfN
extGlyph; |
741 markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFont
Data, advance); | 746 markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFont
Data, advance); |
742 middleOfLastGlyph = middleOfNextGlyph; | 747 middleOfLastGlyph = middleOfNextGlyph; |
743 } | 748 } |
744 markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spa
ceGlyph, markFontData, 0); | 749 markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spa
ceGlyph, markFontData, 0); |
745 | 750 |
746 drawGlyphBuffer(context, runInfo, markBuffer, startPoint); | 751 drawGlyphBuffer(context, runInfo, markBuffer, startPoint); |
747 } | 752 } |
748 | 753 |
749 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont
Data*>* fallbackFonts, IntRectExtent* glyphBounds) const | 754 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont
Data*>* fallbackFonts, IntRectExtent* glyphBounds) const |
750 { | 755 { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 if (delta <= 0) | 832 if (delta <= 0) |
828 break; | 833 break; |
829 } | 834 } |
830 } | 835 } |
831 } | 836 } |
832 | 837 |
833 return offset; | 838 return offset; |
834 } | 839 } |
835 | 840 |
836 } // namespace blink | 841 } // namespace blink |
OLD | NEW |