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

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

Issue 986493002: Simplify text emphasis painting (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 9 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
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 // being reasonably safe (because inherited fonts in the render tree pick up the new 90 // being reasonably safe (because inherited fonts in the render tree pick up the new
91 // style anyway. Other copies are transient, e.g., the state in the Graphics Context, and 91 // style anyway. Other copies are transient, e.g., the state in the Graphics Context, and
92 // won't stick around long enough to get you in trouble). Still, this is pre tty disgusting, 92 // won't stick around long enough to get you in trouble). Still, this is pre tty disgusting,
93 // and could eventually be rectified by using RefPtrs for Fonts themselves. 93 // and could eventually be rectified by using RefPtrs for Fonts themselves.
94 if (!m_fontFallbackList) 94 if (!m_fontFallbackList)
95 m_fontFallbackList = FontFallbackList::create(); 95 m_fontFallbackList = FontFallbackList::create();
96 m_fontFallbackList->invalidate(fontSelector); 96 m_fontFallbackList->invalidate(fontSelector);
97 } 97 }
98 98
99 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph Buffer, 99 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph Buffer,
100 ForTextEmphasisOrNot forTextEmphasis) const 100 const GlyphData* emphasisData) const
101 { 101 {
102 if (codePath(runInfo) == ComplexPath) { 102 if (codePath(runInfo) == ComplexPath) {
103 HarfBuzzShaper shaper(this, runInfo.run, (forTextEmphasis == ForTextEmph asis) 103 HarfBuzzShaper shaper(this, runInfo.run, emphasisData);
104 ? HarfBuzzShaper::ForTextEmphasis : HarfBuzzShaper::NotForTextEmphas is);
105 shaper.setDrawRange(runInfo.from, runInfo.to); 104 shaper.setDrawRange(runInfo.from, runInfo.to);
106 shaper.shape(&glyphBuffer); 105 shaper.shape(&glyphBuffer);
107 return shaper.totalWidth(); 106 return shaper.totalWidth();
108 } 107 }
109 108
110 SimpleShaper shaper(this, runInfo.run, nullptr /* fallbackFonts */, 109 SimpleShaper shaper(this, runInfo.run, emphasisData, nullptr /* fallbackFont s */, nullptr);
111 nullptr, forTextEmphasis);
112 shaper.advance(runInfo.from); 110 shaper.advance(runInfo.from);
113 shaper.advance(runInfo.to, &glyphBuffer); 111 shaper.advance(runInfo.to, &glyphBuffer);
114 float width = shaper.runWidthSoFar(); 112 float width = shaper.runWidthSoFar();
115 113
116 if (runInfo.run.rtl()) { 114 if (runInfo.run.rtl()) {
117 // Glyphs are shaped & stored in RTL advance order - reverse them for LT R drawing. 115 // Glyphs are shaped & stored in RTL advance order - reverse them for LT R drawing.
118 shaper.advance(runInfo.run.length()); 116 shaper.advance(runInfo.run.length());
119 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar()); 117 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar());
120 } 118 }
121 119
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 drawGlyphBuffer(context, runInfo, glyphBuffer, point); 181 drawGlyphBuffer(context, runInfo, glyphBuffer, point);
184 182
185 return totalAdvance; 183 return totalAdvance;
186 } 184 }
187 185
188 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const AtomicString& mark, const FloatPoint& point) const 186 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const AtomicString& mark, const FloatPoint& point) const
189 { 187 {
190 if (shouldSkipDrawing()) 188 if (shouldSkipDrawing())
191 return; 189 return;
192 190
191 FontCachePurgePreventer purgePreventer;
192
193 GlyphData emphasisGlyphData;
194 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData))
195 return;
196
197 ASSERT(emphasisGlyphData.fontData);
198 if (!emphasisGlyphData.fontData)
199 return;
200
193 GlyphBuffer glyphBuffer; 201 GlyphBuffer glyphBuffer;
194 buildGlyphBuffer(runInfo, glyphBuffer, ForTextEmphasis); 202 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);
195 203
196 if (glyphBuffer.isEmpty()) 204 if (glyphBuffer.isEmpty())
197 return; 205 return;
198 206
199 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, point); 207 drawGlyphBuffer(context, runInfo, glyphBuffer, point);
200 } 208 }
201 209
202 static inline void updateGlyphOverflowFromBounds(const IntRectOutsets& glyphBoun ds, 210 static inline void updateGlyphOverflowFromBounds(const IntRectOutsets& glyphBoun ds,
203 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) 211 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow)
204 { 212 {
205 glyphOverflow->top = std::max<int>(glyphOverflow->top, 213 glyphOverflow->top = std::max<int>(glyphOverflow->top,
206 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt())); 214 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt()));
207 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, 215 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom,
208 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent())); 216 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent()));
209 glyphOverflow->left = glyphBounds.left(); 217 glyphOverflow->left = glyphBounds.left();
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 SkPaint paint = gc->strokePaint(); 768 SkPaint paint = gc->strokePaint();
761 if (textMode & TextModeFill) 769 if (textMode & TextModeFill)
762 paint.setLooper(0); 770 paint.setLooper(0);
763 gc->drawTextBlob(blob, origin, paint); 771 gc->drawTextBlob(blob, origin, paint);
764 } 772 }
765 } 773 }
766 774
767 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, IntRectOutsets* glyphBounds) const 775 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, IntRectOutsets* glyphBounds) const
768 { 776 {
769 FloatRect bounds; 777 FloatRect bounds;
770 HarfBuzzShaper shaper(this, run, HarfBuzzShaper::NotForTextEmphasis, fallbac kFonts, glyphBounds ? &bounds : 0); 778 HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &boun ds : 0);
771 if (!shaper.shape()) 779 if (!shaper.shape())
772 return 0; 780 return 0;
773 781
774 glyphBounds->setTop(ceilf(-bounds.y())); 782 glyphBounds->setTop(ceilf(-bounds.y()));
775 glyphBounds->setBottom(ceilf(bounds.maxY())); 783 glyphBounds->setBottom(ceilf(bounds.maxY()));
776 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x()))); 784 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x())));
777 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - shaper.totalWid th()))); 785 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - shaper.totalWid th())));
778 786
779 return shaper.totalWidth(); 787 return shaper.totalWidth();
780 } 788 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 828
821 lastFrom = nextGlyph; 829 lastFrom = nextGlyph;
822 fontData = nextFontData; 830 fontData = nextFontData;
823 } 831 }
824 } 832 }
825 833
826 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint, 834 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint,
827 runInfo.bounds); 835 runInfo.bounds);
828 } 836 }
829 837
830 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph, FontOrientation orientation = Horizontal)
831 {
832 FloatRect bounds = fontData->boundsForGlyph(glyph);
833 if (orientation == Horizontal)
834 return bounds.x() + bounds.width() / 2;
835 return bounds.y() + bounds.height() / 2;
836 }
837
838 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const
839 {
840 FontCachePurgePreventer purgePreventer;
841
842 GlyphData markGlyphData;
843 if (!getEmphasisMarkGlyphData(mark, markGlyphData))
844 return;
845
846 const SimpleFontData* markFontData = markGlyphData.fontData;
847 ASSERT(markFontData);
848 if (!markFontData)
849 return;
850
851 GlyphBuffer markBuffer;
852 bool drawVertically = markFontData->platformData().orientation() == Vertical && markFontData->verticalData();
853 for (unsigned i = 0; i < glyphBuffer.size(); ++i) {
854 // Skip marks for suppressed glyphs.
855 if (!glyphBuffer.glyphAt(i))
856 continue;
857
858 // We want the middle of the emphasis mark aligned with the middle of th e glyph.
859 // The input offsets are already adjusted to point to the middle of the glyph, so all
860 // is left to do is adjust for 1/2 mark width.
861 // FIXME: we could avoid this by passing some additional info to the sha per,
862 // and perform all adjustments at buffer build time.
863 if (!drawVertically) {
864 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffse tAt(i) - offsetToMiddleOfGlyph(markFontData, markGlyphData.glyph));
865 } else {
866 markBuffer.add(markGlyphData.glyph, markFontData, FloatPoint(- offse tToMiddleOfGlyph(markFontData, markGlyphData.glyph),
867 glyphBuffer.xOffsetAt(i) - offsetToMiddleOfGlyph(markFontData, m arkGlyphData.glyph, Vertical)));
868 }
869 }
870
871 drawGlyphBuffer(context, runInfo, markBuffer, point);
872 }
873
874 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectOutsets* glyphBounds) const 838 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectOutsets* glyphBounds) const
875 { 839 {
876 FloatRect bounds; 840 FloatRect bounds;
877 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0); 841 SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &bounds : 0);
878 shaper.advance(run.length()); 842 shaper.advance(run.length());
879 float runWidth = shaper.runWidthSoFar(); 843 float runWidth = shaper.runWidthSoFar();
880 844
881 if (glyphBounds) { 845 if (glyphBounds) {
882 glyphBounds->setTop(ceilf(-bounds.y())); 846 glyphBounds->setTop(ceilf(-bounds.y()));
883 glyphBounds->setBottom(ceilf(bounds.maxY())); 847 glyphBounds->setBottom(ceilf(bounds.maxY()));
884 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x()))); 848 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x())));
885 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - runWidth))) ; 849 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - runWidth))) ;
886 } 850 }
887 return runWidth; 851 return runWidth;
888 } 852 }
889 853
890 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const 854 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const
891 { 855 {
892 FloatRect bounds; 856 FloatRect bounds;
893 SimpleShaper shaper(this, run, 0, accountForGlyphBounds ? &bounds : 0); 857 SimpleShaper shaper(this, run, nullptr, nullptr, accountForGlyphBounds ? &bo unds : nullptr);
894 shaper.advance(from); 858 shaper.advance(from);
895 float fromX = shaper.runWidthSoFar(); 859 float fromX = shaper.runWidthSoFar();
896 shaper.advance(to); 860 shaper.advance(to);
897 float toX = shaper.runWidthSoFar(); 861 float toX = shaper.runWidthSoFar();
898 862
899 if (run.rtl()) { 863 if (run.rtl()) {
900 shaper.advance(run.length()); 864 shaper.advance(run.length());
901 float totalWidth = shaper.runWidthSoFar(); 865 float totalWidth = shaper.runWidthSoFar();
902 float beforeWidth = fromX; 866 float beforeWidth = fromX;
903 float afterWidth = toX; 867 float afterWidth = toX;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 if (delta <= 0) 911 if (delta <= 0)
948 break; 912 break;
949 } 913 }
950 } 914 }
951 } 915 }
952 916
953 return offset; 917 return offset;
954 } 918 }
955 919
956 } // namespace blink 920 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698