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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chu nkLength, reinterpret_cast<float*>(&translations[0])); | 150 verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chu nkLength, reinterpret_cast<float*>(&translations[0])); |
151 | 151 |
152 x = verticalOriginX; | 152 x = verticalOriginX; |
153 y = SkFloatToScalar(point.y() + horizontalOffset - point.x()); | 153 y = SkFloatToScalar(point.y() + horizontalOffset - point.x()); |
154 | 154 |
155 float currentWidth = 0; | 155 float currentWidth = 0; |
156 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) { | 156 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) { |
157 pos[i].set( | 157 pos[i].set( |
158 x + SkIntToScalar(lroundf(translations[i].x())), | 158 x + SkIntToScalar(lroundf(translations[i].x())), |
159 y + -SkIntToScalar(-lroundf(currentWidth - translations[i].y ()))); | 159 y + -SkIntToScalar(-lroundf(currentWidth - translations[i].y ()))); |
160 currentWidth += glyphBuffer.advanceAt(from + glyphIndex).width() ; | 160 currentWidth += glyphBuffer.advanceAt(from + glyphIndex); |
161 } | 161 } |
162 horizontalOffset += currentWidth; | 162 horizontalOffset += currentWidth; |
163 paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect); | 163 paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect); |
164 } | 164 } |
165 | 165 |
166 gc->setCTM(savedMatrix); | 166 gc->setCTM(savedMatrix); |
167 return; | 167 return; |
168 } | 168 } |
169 | 169 |
170 if (!glyphBuffer.hasVerticalAdvances()) { | 170 if (!glyphBuffer.hasOffsets()) { |
171 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); | 171 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); |
172 SkScalar* xpos = storage.get(); | 172 SkScalar* xpos = storage.get(); |
173 const FloatSize* adv = glyphBuffer.advances(from); | 173 const float* adv = glyphBuffer.advances(from); |
174 for (unsigned i = 0; i < numGlyphs; i++) { | 174 for (unsigned i = 0; i < numGlyphs; i++) { |
175 xpos[i] = x; | 175 xpos[i] = x; |
176 x += SkFloatToScalar(adv[i].width()); | 176 x += SkFloatToScalar(adv[i]); |
177 } | 177 } |
178 const Glyph* glyphs = glyphBuffer.glyphs(from); | 178 const Glyph* glyphs = glyphBuffer.glyphs(from); |
179 paintGlyphsHorizontal(gc, font, glyphs, numGlyphs, xpos, SkFloatToScalar (y), textRect); | 179 paintGlyphsHorizontal(gc, font, glyphs, numGlyphs, xpos, SkFloatToScalar (y), textRect); |
180 return; | 180 return; |
181 } | 181 } |
182 | 182 |
183 // FIXME: text rendering speed: | 183 ASSERT(glyphBuffer.hasOffsets()); |
184 // Android has code in their WebCore fork to special case when the | 184 const GlyphBufferWithOffsets& glyphBufferWithOffsets = |
185 // GlyphBuffer has no advances other than the defaults. In that case the | 185 static_cast<const GlyphBufferWithOffsets&>(glyphBuffer); |
186 // text drawing can proceed faster. However, it's unclear when those | |
187 // patches may be upstreamed to WebKit so we always use the slower path | |
188 // here. | |
189 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); | 186 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); |
190 SkPoint* pos = storage.get(); | 187 SkPoint* pos = storage.get(); |
191 const FloatSize* adv = glyphBuffer.advances(from); | 188 const FloatSize* offsets = glyphBufferWithOffsets.offsets(from); |
189 const float* advances = glyphBufferWithOffsets.advances(from); | |
190 SkScalar advanceSoFar = SkFloatToScalar(0); | |
192 for (unsigned i = 0; i < numGlyphs; i++) { | 191 for (unsigned i = 0; i < numGlyphs; i++) { |
193 pos[i].set(x, y); | 192 pos[i].set( |
194 x += SkFloatToScalar(adv[i].width()); | 193 x + SkFloatToScalar(offsets[i].width()) + advanceSoFar, |
195 y += SkFloatToScalar(adv[i].height()); | 194 y + SkFloatToScalar(offsets[i].height())); |
195 advanceSoFar += SkFloatToScalar(advances[i]); | |
196 } | 196 } |
197 | 197 |
198 const Glyph* glyphs = glyphBuffer.glyphs(from); | 198 const Glyph* glyphs = glyphBufferWithOffsets.glyphs(from); |
199 paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect); | 199 paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect); |
200 } | 200 } |
201 | 201 |
202 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const | 202 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const |
203 { | 203 { |
204 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); | 204 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
205 | 205 |
206 // FIXME: It would be good to move this to Font.cpp, if we're sure that none | 206 // FIXME: It would be good to move this to Font.cpp, if we're sure that none |
207 // of the things in FontMac's setupPaint need to apply here. | 207 // of the things in FontMac's setupPaint need to apply here. |
208 // See also paintGlyphs. | 208 // See also paintGlyphs. |
(...skipping 15 matching lines...) Expand all Loading... | |
224 if (!runInfo.run.length()) | 224 if (!runInfo.run.length()) |
225 return 0; | 225 return 0; |
226 | 226 |
227 TextDrawingModeFlags textMode = gc->textDrawingMode(); | 227 TextDrawingModeFlags textMode = gc->textDrawingMode(); |
228 bool fill = textMode & TextModeFill; | 228 bool fill = textMode & TextModeFill; |
229 bool stroke = (textMode & TextModeStroke) && gc->hasStroke(); | 229 bool stroke = (textMode & TextModeStroke) && gc->hasStroke(); |
230 | 230 |
231 if (!fill && !stroke) | 231 if (!fill && !stroke) |
232 return 0; | 232 return 0; |
233 | 233 |
234 GlyphBuffer glyphBuffer; | 234 GlyphBufferWithOffsets glyphBuffer; |
235 HarfBuzzShaper shaper(this, runInfo.run); | 235 HarfBuzzShaper shaper(this, runInfo.run); |
236 shaper.setDrawRange(runInfo.from, runInfo.to); | 236 shaper.setDrawRange(runInfo.from, runInfo.to); |
237 if (!shaper.shape(&glyphBuffer) || glyphBuffer.isEmpty()) | 237 if (!shaper.shape(&glyphBuffer) || glyphBuffer.isEmpty()) |
238 return 0; | 238 return 0; |
239 FloatPoint adjustedPoint = shaper.adjustStartPoint(point); | 239 return drawGlyphBuffer(gc, runInfo, glyphBuffer, point); |
240 return drawGlyphBuffer(gc, runInfo, glyphBuffer, adjustedPoint); | |
241 } | 240 } |
242 | 241 |
243 void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextR unPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const | 242 void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextR unPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const |
244 { | 243 { |
245 GlyphBuffer glyphBuffer; | 244 GlyphBuffer glyphBuffer; |
246 | 245 |
247 float initialAdvance = getGlyphsAndAdvancesForComplexText(runInfo, glyphBuff er, ForTextEmphasis); | 246 float initialAdvance = getGlyphsAndAdvancesForComplexText(runInfo, glyphBuff er, ForTextEmphasis); |
248 | 247 |
249 if (glyphBuffer.isEmpty()) | 248 if (glyphBuffer.isEmpty()) |
250 return; | 249 return; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 return shaper.selectionRect(point, height, from, to); | 294 return shaper.selectionRect(point, height, from, to); |
296 } | 295 } |
297 | 296 |
298 PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer, float initia lAdvance, | 297 PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer, float initia lAdvance, |
299 const FloatRect& bounds, float& advance, bool couldUseLCD) const | 298 const FloatRect& bounds, float& advance, bool couldUseLCD) const |
300 { | 299 { |
301 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); | 300 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
302 | 301 |
303 // FIXME: Except for setupPaint, this is not specific to FontHarfBuzz. | 302 // FIXME: Except for setupPaint, this is not specific to FontHarfBuzz. |
304 // FIXME: Also implement the more general full-positioning path. | 303 // FIXME: Also implement the more general full-positioning path. |
305 ASSERT(!glyphBuffer.hasVerticalAdvances()); | |
jbroman
2014/09/26 13:02:11
Mind putting the equivalent assertion back here?
| |
306 | 304 |
307 SkTextBlobBuilder builder; | 305 SkTextBlobBuilder builder; |
308 SkScalar x = SkFloatToScalar(initialAdvance); | 306 SkScalar x = SkFloatToScalar(initialAdvance); |
309 SkRect skBounds = bounds; | 307 SkRect skBounds = bounds; |
310 | 308 |
311 unsigned i = 0; | 309 unsigned i = 0; |
312 while (i < glyphBuffer.size()) { | 310 while (i < glyphBuffer.size()) { |
313 const SimpleFontData* fontData = glyphBuffer.fontDataAt(i); | 311 const SimpleFontData* fontData = glyphBuffer.fontDataAt(i); |
314 | 312 |
315 // FIXME: Handle vertical text. | 313 // FIXME: Handle vertical text. |
(...skipping 17 matching lines...) Expand all Loading... | |
333 unsigned start = i++; | 331 unsigned start = i++; |
334 while (i < glyphBuffer.size() && glyphBuffer.fontDataAt(i) == fontData) | 332 while (i < glyphBuffer.size() && glyphBuffer.fontDataAt(i) == fontData) |
335 i++; | 333 i++; |
336 unsigned count = i - start; | 334 unsigned count = i - start; |
337 | 335 |
338 const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPosH(paint, count, 0, &skBounds); | 336 const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPosH(paint, count, 0, &skBounds); |
339 | 337 |
340 const uint16_t* glyphs = glyphBuffer.glyphs(start); | 338 const uint16_t* glyphs = glyphBuffer.glyphs(start); |
341 std::copy(glyphs, glyphs + count, buffer.glyphs); | 339 std::copy(glyphs, glyphs + count, buffer.glyphs); |
342 | 340 |
343 const FloatSize* advances = glyphBuffer.advances(start); | 341 const float* advances = glyphBuffer.advances(start); |
344 for (unsigned j = 0; j < count; j++) { | 342 for (unsigned j = 0; j < count; j++) { |
345 buffer.pos[j] = x; | 343 buffer.pos[j] = x; |
346 x += SkFloatToScalar(advances[j].width()); | 344 x += SkFloatToScalar(advances[j]); |
347 } | 345 } |
348 } | 346 } |
349 | 347 |
350 advance = x; | 348 advance = x; |
351 return adoptRef(builder.build()); | 349 return adoptRef(builder.build()); |
352 } | 350 } |
353 | 351 |
354 } // namespace blink | 352 } // namespace blink |
OLD | NEW |