OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. | 2 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 { | 50 { |
51 return false; | 51 return false; |
52 } | 52 } |
53 | 53 |
54 bool FontPlatformFeatures::canExpandAroundIdeographsInComplexText() | 54 bool FontPlatformFeatures::canExpandAroundIdeographsInComplexText() |
55 { | 55 { |
56 return false; | 56 return false; |
57 } | 57 } |
58 | 58 |
59 static void paintGlyphs(GraphicsContext* gc, const SimpleFontData* font, | 59 static void paintGlyphs(GraphicsContext* gc, const SimpleFontData* font, |
60 const GlyphBufferGlyph* glyphs, unsigned numGlyphs, | 60 const Glyph* glyphs, unsigned numGlyphs, |
61 SkPoint* pos, const FloatRect& textRect) | 61 SkPoint* pos, const FloatRect& textRect) |
62 { | 62 { |
63 TextDrawingModeFlags textMode = gc->textDrawingMode(); | 63 TextDrawingModeFlags textMode = gc->textDrawingMode(); |
64 | 64 |
65 // We draw text up to two times (once for fill, once for stroke). | 65 // We draw text up to two times (once for fill, once for stroke). |
66 if (textMode & TextModeFill) { | 66 if (textMode & TextModeFill) { |
67 SkPaint paint = gc->fillPaint(); | 67 SkPaint paint = gc->fillPaint(); |
68 font->platformData().setupPaint(&paint, gc); | 68 font->platformData().setupPaint(&paint, gc); |
69 gc->adjustTextRenderMode(&paint); | 69 gc->adjustTextRenderMode(&paint); |
70 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 70 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
71 | 71 |
72 gc->drawPosText(glyphs, numGlyphs << 1, pos, textRect, paint); | 72 gc->drawPosText(glyphs, numGlyphs * sizeof(Glyph), pos, textRect, paint)
; |
73 } | 73 } |
74 | 74 |
75 if ((textMode & TextModeStroke) | 75 if ((textMode & TextModeStroke) |
76 && gc->strokeStyle() != NoStroke | 76 && gc->strokeStyle() != NoStroke |
77 && gc->strokeThickness() > 0) { | 77 && gc->strokeThickness() > 0) { |
78 | 78 |
79 SkPaint paint = gc->strokePaint(); | 79 SkPaint paint = gc->strokePaint(); |
80 font->platformData().setupPaint(&paint, gc); | 80 font->platformData().setupPaint(&paint, gc); |
81 gc->adjustTextRenderMode(&paint); | 81 gc->adjustTextRenderMode(&paint); |
82 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 82 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
83 | 83 |
84 if (textMode & TextModeFill) { | 84 if (textMode & TextModeFill) { |
85 // If there is a shadow and we filled above, there will already be | 85 // If there is a shadow and we filled above, there will already be |
86 // a shadow. We don't want to draw it again or it will be too dark | 86 // a shadow. We don't want to draw it again or it will be too dark |
87 // and it will go on top of the fill. | 87 // and it will go on top of the fill. |
88 // | 88 // |
89 // Note that this isn't strictly correct, since the stroke could be | 89 // Note that this isn't strictly correct, since the stroke could be |
90 // very thick and the shadow wouldn't account for this. The "right" | 90 // very thick and the shadow wouldn't account for this. The "right" |
91 // thing would be to draw to a new layer and then draw that layer | 91 // thing would be to draw to a new layer and then draw that layer |
92 // with a shadow. But this is a lot of extra work for something | 92 // with a shadow. But this is a lot of extra work for something |
93 // that isn't normally an issue. | 93 // that isn't normally an issue. |
94 paint.setLooper(0); | 94 paint.setLooper(0); |
95 } | 95 } |
96 | 96 |
97 gc->drawPosText(glyphs, numGlyphs << 1, pos, textRect, paint); | 97 gc->drawPosText(glyphs, numGlyphs * sizeof(Glyph), pos, textRect, paint)
; |
98 } | 98 } |
99 } | 99 } |
100 | 100 |
101 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, | 101 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, |
102 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, | 102 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, |
103 const FloatPoint& point, const FloatRect& textRect) const | 103 const FloatPoint& point, const FloatRect& textRect) const |
104 { | 104 { |
105 SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time asse
rt | |
106 | |
107 SkScalar x = SkFloatToScalar(point.x()); | 105 SkScalar x = SkFloatToScalar(point.x()); |
108 SkScalar y = SkFloatToScalar(point.y()); | 106 SkScalar y = SkFloatToScalar(point.y()); |
109 | 107 |
110 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); | 108 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); |
111 SkPoint* pos = storage.get(); | 109 SkPoint* pos = storage.get(); |
112 | 110 |
113 const OpenTypeVerticalData* verticalData = font->verticalData(); | 111 const OpenTypeVerticalData* verticalData = font->verticalData(); |
114 if (font->platformData().orientation() == Vertical && verticalData) { | 112 if (font->platformData().orientation() == Vertical && verticalData) { |
115 AffineTransform savedMatrix = gc->getCTM(); | 113 AffineTransform savedMatrix = gc->getCTM(); |
116 gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y())); | 114 gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y())); |
117 gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y())); | 115 gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y())); |
118 | 116 |
119 const unsigned kMaxBufferLength = 256; | 117 const unsigned kMaxBufferLength = 256; |
120 Vector<FloatPoint, kMaxBufferLength> translations; | 118 Vector<FloatPoint, kMaxBufferLength> translations; |
121 | 119 |
122 const FontMetrics& metrics = font->fontMetrics(); | 120 const FontMetrics& metrics = font->fontMetrics(); |
123 SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAsce
nt() - metrics.floatAscent(IdeographicBaseline)); | 121 SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAsce
nt() - metrics.floatAscent(IdeographicBaseline)); |
124 float horizontalOffset = point.x(); | 122 float horizontalOffset = point.x(); |
125 | 123 |
126 unsigned glyphIndex = 0; | 124 unsigned glyphIndex = 0; |
127 while (glyphIndex < numGlyphs) { | 125 while (glyphIndex < numGlyphs) { |
128 unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphI
ndex); | 126 unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphI
ndex); |
129 | 127 |
130 const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from + glyphInde
x); | 128 const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex); |
131 translations.resize(chunkLength); | 129 translations.resize(chunkLength); |
132 verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chu
nkLength, reinterpret_cast<float*>(&translations[0])); | 130 verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chu
nkLength, reinterpret_cast<float*>(&translations[0])); |
133 | 131 |
134 x = verticalOriginX; | 132 x = verticalOriginX; |
135 y = SkFloatToScalar(point.y() + horizontalOffset - point.x()); | 133 y = SkFloatToScalar(point.y() + horizontalOffset - point.x()); |
136 | 134 |
137 float currentWidth = 0; | 135 float currentWidth = 0; |
138 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) { | 136 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) { |
139 pos[i].set( | 137 pos[i].set( |
140 x + SkIntToScalar(lroundf(translations[i].x())), | 138 x + SkIntToScalar(lroundf(translations[i].x())), |
(...skipping 14 matching lines...) Expand all Loading... |
155 // text drawing can proceed faster. However, it's unclear when those | 153 // text drawing can proceed faster. However, it's unclear when those |
156 // patches may be upstreamed to WebKit so we always use the slower path | 154 // patches may be upstreamed to WebKit so we always use the slower path |
157 // here. | 155 // here. |
158 const GlyphBufferAdvance* adv = glyphBuffer.advances(from); | 156 const GlyphBufferAdvance* adv = glyphBuffer.advances(from); |
159 for (unsigned i = 0; i < numGlyphs; i++) { | 157 for (unsigned i = 0; i < numGlyphs; i++) { |
160 pos[i].set(x, y); | 158 pos[i].set(x, y); |
161 x += SkFloatToScalar(adv[i].width()); | 159 x += SkFloatToScalar(adv[i].width()); |
162 y += SkFloatToScalar(adv[i].height()); | 160 y += SkFloatToScalar(adv[i].height()); |
163 } | 161 } |
164 | 162 |
165 const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from); | 163 const Glyph* glyphs = glyphBuffer.glyphs(from); |
166 paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect); | 164 paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect); |
167 } | 165 } |
168 | 166 |
169 void Font::drawComplexText(GraphicsContext* gc, const TextRunPaintInfo& runInfo,
const FloatPoint& point) const | 167 void Font::drawComplexText(GraphicsContext* gc, const TextRunPaintInfo& runInfo,
const FloatPoint& point) const |
170 { | 168 { |
171 if (!runInfo.run.length()) | 169 if (!runInfo.run.length()) |
172 return; | 170 return; |
173 | 171 |
174 TextDrawingModeFlags textMode = gc->textDrawingMode(); | 172 TextDrawingModeFlags textMode = gc->textDrawingMode(); |
175 bool fill = textMode & TextModeFill; | 173 bool fill = textMode & TextModeFill; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 const FloatPoint& point, int height, | 236 const FloatPoint& point, int height, |
239 int from, int to) const | 237 int from, int to) const |
240 { | 238 { |
241 HarfBuzzShaper shaper(this, run); | 239 HarfBuzzShaper shaper(this, run); |
242 if (!shaper.shape()) | 240 if (!shaper.shape()) |
243 return FloatRect(); | 241 return FloatRect(); |
244 return shaper.selectionRect(point, height, from, to); | 242 return shaper.selectionRect(point, height, from, to); |
245 } | 243 } |
246 | 244 |
247 } // namespace WebCore | 245 } // namespace WebCore |
OLD | NEW |