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

Side by Side Diff: sky/engine/platform/fonts/Font.cpp

Issue 859203002: Merge Blink code to cache SkTextBlob (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: hashmap Created 5 years, 11 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
« no previous file with comments | « sky/engine/platform/fonts/Font.h ('k') | sky/engine/platform/fonts/GlyphBuffer.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 * 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
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
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
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
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
OLDNEW
« no previous file with comments | « sky/engine/platform/fonts/Font.h ('k') | sky/engine/platform/fonts/GlyphBuffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698