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

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: review comments 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
« no previous file with comments | « Source/platform/fonts/Font.h ('k') | Source/platform/fonts/shaping/HarfBuzzShaper.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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // being reasonably safe (because inherited fonts in the render tree pick up the new 92 // being reasonably safe (because inherited fonts in the render tree pick up the new
93 // style anyway. Other copies are transient, e.g., the state in the Graphics Context, and 93 // style anyway. Other copies are transient, e.g., the state in the Graphics Context, and
94 // won't stick around long enough to get you in trouble). Still, this is pre tty disgusting, 94 // won't stick around long enough to get you in trouble). Still, this is pre tty disgusting,
95 // and could eventually be rectified by using RefPtrs for Fonts themselves. 95 // and could eventually be rectified by using RefPtrs for Fonts themselves.
96 if (!m_fontFallbackList) 96 if (!m_fontFallbackList)
97 m_fontFallbackList = FontFallbackList::create(); 97 m_fontFallbackList = FontFallbackList::create();
98 m_fontFallbackList->invalidate(fontSelector); 98 m_fontFallbackList->invalidate(fontSelector);
99 } 99 }
100 100
101 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph Buffer, 101 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph Buffer,
102 ForTextEmphasisOrNot forTextEmphasis) const 102 const GlyphData* emphasisData) const
103 { 103 {
104 if (codePath(runInfo) == ComplexPath) { 104 if (codePath(runInfo) == ComplexPath) {
105 HarfBuzzShaper shaper(this, runInfo.run, (forTextEmphasis == ForTextEmph asis) 105 HarfBuzzShaper shaper(this, runInfo.run, emphasisData);
106 ? HarfBuzzShaper::ForTextEmphasis : HarfBuzzShaper::NotForTextEmphas is);
107 shaper.setDrawRange(runInfo.from, runInfo.to); 106 shaper.setDrawRange(runInfo.from, runInfo.to);
108 shaper.shape(&glyphBuffer); 107 shaper.shape(&glyphBuffer);
109 return shaper.totalWidth(); 108 return shaper.totalWidth();
110 } 109 }
111 110
112 SimpleShaper shaper(this, runInfo.run, nullptr /* fallbackFonts */, 111 SimpleShaper shaper(this, runInfo.run, emphasisData, nullptr /* fallbackFont s */, nullptr);
113 nullptr, forTextEmphasis);
114 shaper.advance(runInfo.from); 112 shaper.advance(runInfo.from);
115 shaper.advance(runInfo.to, &glyphBuffer); 113 shaper.advance(runInfo.to, &glyphBuffer);
116 float width = shaper.runWidthSoFar(); 114 float width = shaper.runWidthSoFar();
117 115
118 if (runInfo.run.rtl()) { 116 if (runInfo.run.rtl()) {
119 // Glyphs are shaped & stored in RTL advance order - reverse them for LT R drawing. 117 // Glyphs are shaped & stored in RTL advance order - reverse them for LT R drawing.
120 shaper.advance(runInfo.run.length()); 118 shaper.advance(runInfo.run.length());
121 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar()); 119 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar());
122 } 120 }
123 121
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 195 }
198 196
199 bidiRuns.deleteRuns(); 197 bidiRuns.deleteRuns();
200 } 198 }
201 199
202 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const AtomicString& mark, const FloatPoint& point) const 200 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const AtomicString& mark, const FloatPoint& point) const
203 { 201 {
204 if (shouldSkipDrawing()) 202 if (shouldSkipDrawing())
205 return; 203 return;
206 204
205 FontCachePurgePreventer purgePreventer;
206
207 GlyphData emphasisGlyphData;
208 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData))
209 return;
210
211 ASSERT(emphasisGlyphData.fontData);
212 if (!emphasisGlyphData.fontData)
213 return;
214
207 GlyphBuffer glyphBuffer; 215 GlyphBuffer glyphBuffer;
208 buildGlyphBuffer(runInfo, glyphBuffer, ForTextEmphasis); 216 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);
209 217
210 if (glyphBuffer.isEmpty()) 218 if (glyphBuffer.isEmpty())
211 return; 219 return;
212 220
213 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, point); 221 drawGlyphBuffer(context, runInfo, glyphBuffer, point);
214 } 222 }
215 223
216 static inline void updateGlyphOverflowFromBounds(const IntRectOutsets& glyphBoun ds, 224 static inline void updateGlyphOverflowFromBounds(const IntRectOutsets& glyphBoun ds,
217 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) 225 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow)
218 { 226 {
219 glyphOverflow->top = std::max<int>(glyphOverflow->top, 227 glyphOverflow->top = std::max<int>(glyphOverflow->top,
220 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt())); 228 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt()));
221 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, 229 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom,
222 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent())); 230 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent()));
223 glyphOverflow->left = glyphBounds.left(); 231 glyphOverflow->left = glyphBounds.left();
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 SkPaint paint = gc->strokePaint(); 782 SkPaint paint = gc->strokePaint();
775 if (textMode & TextModeFill) 783 if (textMode & TextModeFill)
776 paint.setLooper(0); 784 paint.setLooper(0);
777 gc->drawTextBlob(blob, origin, paint); 785 gc->drawTextBlob(blob, origin, paint);
778 } 786 }
779 } 787 }
780 788
781 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, IntRectOutsets* glyphBounds) const 789 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, IntRectOutsets* glyphBounds) const
782 { 790 {
783 FloatRect bounds; 791 FloatRect bounds;
784 HarfBuzzShaper shaper(this, run, HarfBuzzShaper::NotForTextEmphasis, fallbac kFonts, glyphBounds ? &bounds : 0); 792 HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &boun ds : 0);
785 if (!shaper.shape()) 793 if (!shaper.shape())
786 return 0; 794 return 0;
787 795
788 glyphBounds->setTop(ceilf(-bounds.y())); 796 glyphBounds->setTop(ceilf(-bounds.y()));
789 glyphBounds->setBottom(ceilf(bounds.maxY())); 797 glyphBounds->setBottom(ceilf(bounds.maxY()));
790 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x()))); 798 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x())));
791 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - shaper.totalWid th()))); 799 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - shaper.totalWid th())));
792 800
793 return shaper.totalWidth(); 801 return shaper.totalWidth();
794 } 802 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 854
847 lastFrom = nextGlyph; 855 lastFrom = nextGlyph;
848 fontData = nextFontData; 856 fontData = nextFontData;
849 } 857 }
850 } 858 }
851 859
852 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint, 860 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint,
853 runInfo.bounds); 861 runInfo.bounds);
854 } 862 }
855 863
856 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph, FontOrientation orientation = Horizontal)
857 {
858 FloatRect bounds = fontData->boundsForGlyph(glyph);
859 if (orientation == Horizontal)
860 return bounds.x() + bounds.width() / 2;
861 return bounds.y() + bounds.height() / 2;
862 }
863
864 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const
865 {
866 FontCachePurgePreventer purgePreventer;
867
868 GlyphData markGlyphData;
869 if (!getEmphasisMarkGlyphData(mark, markGlyphData))
870 return;
871
872 const SimpleFontData* markFontData = markGlyphData.fontData;
873 ASSERT(markFontData);
874 if (!markFontData)
875 return;
876
877 GlyphBuffer markBuffer;
878 bool drawVertically = markFontData->platformData().orientation() == Vertical && markFontData->verticalData();
879 for (unsigned i = 0; i < glyphBuffer.size(); ++i) {
880 // Skip marks for suppressed glyphs.
881 if (!glyphBuffer.glyphAt(i))
882 continue;
883
884 // We want the middle of the emphasis mark aligned with the middle of th e glyph.
885 // The input offsets are already adjusted to point to the middle of the glyph, so all
886 // is left to do is adjust for 1/2 mark width.
887 // FIXME: we could avoid this by passing some additional info to the sha per,
888 // and perform all adjustments at buffer build time.
889 if (!drawVertically) {
890 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffse tAt(i) - offsetToMiddleOfGlyph(markFontData, markGlyphData.glyph));
891 } else {
892 markBuffer.add(markGlyphData.glyph, markFontData, FloatPoint(- offse tToMiddleOfGlyph(markFontData, markGlyphData.glyph),
893 glyphBuffer.xOffsetAt(i) - offsetToMiddleOfGlyph(markFontData, m arkGlyphData.glyph, Vertical)));
894 }
895 }
896
897 drawGlyphBuffer(context, runInfo, markBuffer, point);
898 }
899
900 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectOutsets* glyphBounds) const 864 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectOutsets* glyphBounds) const
901 { 865 {
902 FloatRect bounds; 866 FloatRect bounds;
903 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0); 867 SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds ? &bounds : 0);
904 shaper.advance(run.length()); 868 shaper.advance(run.length());
905 float runWidth = shaper.runWidthSoFar(); 869 float runWidth = shaper.runWidthSoFar();
906 870
907 if (glyphBounds) { 871 if (glyphBounds) {
908 glyphBounds->setTop(ceilf(-bounds.y())); 872 glyphBounds->setTop(ceilf(-bounds.y()));
909 glyphBounds->setBottom(ceilf(bounds.maxY())); 873 glyphBounds->setBottom(ceilf(bounds.maxY()));
910 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x()))); 874 glyphBounds->setLeft(std::max<int>(0, ceilf(-bounds.x())));
911 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - runWidth))) ; 875 glyphBounds->setRight(std::max<int>(0, ceilf(bounds.maxX() - runWidth))) ;
912 } 876 }
913 return runWidth; 877 return runWidth;
914 } 878 }
915 879
916 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const 880 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to, bool accountForGlyphBounds) const
917 { 881 {
918 FloatRect bounds; 882 FloatRect bounds;
919 SimpleShaper shaper(this, run, 0, accountForGlyphBounds ? &bounds : 0); 883 SimpleShaper shaper(this, run, nullptr, nullptr, accountForGlyphBounds ? &bo unds : nullptr);
920 shaper.advance(from); 884 shaper.advance(from);
921 float fromX = shaper.runWidthSoFar(); 885 float fromX = shaper.runWidthSoFar();
922 shaper.advance(to); 886 shaper.advance(to);
923 float toX = shaper.runWidthSoFar(); 887 float toX = shaper.runWidthSoFar();
924 888
925 if (run.rtl()) { 889 if (run.rtl()) {
926 shaper.advance(run.length()); 890 shaper.advance(run.length());
927 float totalWidth = shaper.runWidthSoFar(); 891 float totalWidth = shaper.runWidthSoFar();
928 float beforeWidth = fromX; 892 float beforeWidth = fromX;
929 float afterWidth = toX; 893 float afterWidth = toX;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 if (delta <= 0) 937 if (delta <= 0)
974 break; 938 break;
975 } 939 }
976 } 940 }
977 } 941 }
978 942
979 return offset; 943 return offset;
980 } 944 }
981 945
982 } // namespace blink 946 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/fonts/Font.h ('k') | Source/platform/fonts/shaping/HarfBuzzShaper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698