OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrDistanceFieldTextContext.h" | 8 #include "GrDistanceFieldTextContext.h" |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBitmapTextContext.h" | 10 #include "GrBitmapTextContext.h" |
11 #include "GrDrawTarget.h" | 11 #include "GrDrawTarget.h" |
12 #include "GrDrawTargetCaps.h" | 12 #include "GrDrawTargetCaps.h" |
13 #include "GrFontScaler.h" | 13 #include "GrFontScaler.h" |
14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
16 #include "GrStrokeInfo.h" | 16 #include "GrStrokeInfo.h" |
17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
18 #include "GrTextStrike.h" | 18 #include "GrTextStrike.h" |
19 #include "GrTextStrike_impl.h" | 19 #include "GrTextStrike_impl.h" |
20 | 20 |
| 21 #include "SkAutoKern.h" |
21 #include "SkColorFilter.h" | 22 #include "SkColorFilter.h" |
22 #include "SkDistanceFieldGen.h" | 23 #include "SkDistanceFieldGen.h" |
23 #include "SkDraw.h" | 24 #include "SkDraw.h" |
24 #include "SkGlyphCache.h" | 25 #include "SkGlyphCache.h" |
25 #include "SkGpuDevice.h" | 26 #include "SkGpuDevice.h" |
26 #include "SkPath.h" | 27 #include "SkPath.h" |
27 #include "SkRTConf.h" | 28 #include "SkRTConf.h" |
28 #include "SkStrokeRec.h" | 29 #include "SkStrokeRec.h" |
29 #include "effects/GrDistanceFieldTextureEffect.h" | 30 #include "effects/GrDistanceFieldTextureEffect.h" |
30 | 31 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 (*gammaTexture)->config(), data.get(), 0, | 206 (*gammaTexture)->config(), data.get(), 0, |
206 GrContext::kDontFlush_PixelOpsFlag); | 207 GrContext::kDontFlush_PixelOpsFlag); |
207 } | 208 } |
208 } | 209 } |
209 | 210 |
210 void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint&
skPaint, | 211 void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint&
skPaint, |
211 const char text[], size_t byteLength, | 212 const char text[], size_t byteLength, |
212 SkScalar x, SkScalar y) { | 213 SkScalar x, SkScalar y) { |
213 SkASSERT(byteLength == 0 || text != NULL); | 214 SkASSERT(byteLength == 0 || text != NULL); |
214 | 215 |
215 // nothing to draw or can't draw | 216 // nothing to draw |
216 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ | 217 if (text == NULL || byteLength == 0) { |
217 || fSkPaint.getRasterizer()) { | |
218 return; | 218 return; |
219 } | 219 } |
220 | 220 |
221 this->init(paint, skPaint); | 221 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 222 SkAutoGlyphCache autoCache(skPaint, &fDeviceProperties, NULL); |
| 223 SkGlyphCache* cache = autoCache.getCache(); |
222 | 224 |
223 SkScalar sizeRatio = fTextRatio; | 225 SkTArray<SkScalar> positions; |
224 | 226 |
225 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 227 const char* textPtr = text; |
226 | 228 SkFixed stopX = 0; |
227 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 229 SkFixed stopY = 0; |
228 SkGlyphCache* cache = autoCache.getCache(); | 230 SkFixed origin; |
229 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 231 switch (skPaint.getTextAlign()) { |
230 | 232 case SkPaint::kRight_Align: origin = SK_Fixed1; break; |
231 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 233 case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; |
232 | 234 case SkPaint::kLeft_Align: origin = 0; break; |
233 // need to measure first | 235 default: SkFAIL("Invalid paint origin"); return; |
234 // TODO - generate positions and pre-load cache as well? | |
235 const char* stop = text + byteLength; | |
236 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | |
237 SkFixed stopX = 0; | |
238 SkFixed stopY = 0; | |
239 | |
240 const char* textPtr = text; | |
241 while (textPtr < stop) { | |
242 // don't need x, y here, since all subpixel variants will have the | |
243 // same advance | |
244 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); | |
245 | |
246 stopX += glyph.fAdvanceX; | |
247 stopY += glyph.fAdvanceY; | |
248 } | |
249 SkASSERT(textPtr == stop); | |
250 | |
251 SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio; | |
252 SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio; | |
253 | |
254 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { | |
255 alignX = SkScalarHalf(alignX); | |
256 alignY = SkScalarHalf(alignY); | |
257 } | |
258 | |
259 x -= alignX; | |
260 y -= alignY; | |
261 } | 236 } |
262 | 237 |
263 SkFixed fx = SkScalarToFixed(x); | 238 SkAutoKern autokern; |
264 SkFixed fy = SkScalarToFixed(y); | 239 const char* stop = text + byteLength; |
265 SkFixed fixedScale = SkScalarToFixed(sizeRatio); | 240 while (textPtr < stop) { |
266 while (text < stop) { | 241 // don't need x, y here, since all subpixel variants will have the |
267 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 242 // same advance |
| 243 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); |
268 | 244 |
269 if (glyph.fWidth) { | 245 SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); |
270 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 246 positions.push_back(SkFixedToScalar(stopX + SkFixedMul_portable(origin,
width))); |
271 glyph.getSubXFixed(), | |
272 glyph.getSubYFixed()), | |
273 fx, | |
274 fy, | |
275 fontScaler); | |
276 } | |
277 | 247 |
278 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); | 248 SkFixed height = glyph.fAdvanceY; |
279 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); | 249 positions.push_back(SkFixedToScalar(stopY + SkFixedMul_portable(origin,
height))); |
| 250 |
| 251 stopX += width; |
| 252 stopY += height; |
280 } | 253 } |
| 254 SkASSERT(textPtr == stop); |
281 | 255 |
282 this->finish(); | 256 // now adjust starting point depending on alignment |
| 257 SkScalar alignX = SkFixedToScalar(stopX); |
| 258 SkScalar alignY = SkFixedToScalar(stopY); |
| 259 if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { |
| 260 alignX = SkScalarHalf(alignX); |
| 261 alignY = SkScalarHalf(alignY); |
| 262 } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { |
| 263 alignX = 0; |
| 264 alignY = 0; |
| 265 } |
| 266 x -= alignX; |
| 267 y -= alignY; |
| 268 SkPoint offset = SkPoint::Make(x, y); |
| 269 |
| 270 this->drawPosText(paint, skPaint, text, byteLength, positions.begin(), 2, of
fset); |
283 } | 271 } |
284 | 272 |
285 void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai
nt& skPaint, | 273 void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai
nt& skPaint, |
286 const char text[], size_t byteLengt
h, | 274 const char text[], size_t byteLengt
h, |
287 const SkScalar pos[], int scalarsPe
rPosition, | 275 const SkScalar pos[], int scalarsPe
rPosition, |
288 const SkPoint& offset) { | 276 const SkPoint& offset) { |
289 | 277 |
290 SkASSERT(byteLength == 0 || text != NULL); | 278 SkASSERT(byteLength == 0 || text != NULL); |
291 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 279 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
292 | 280 |
(...skipping 26 matching lines...) Expand all Loading... |
319 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 307 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
320 glyph.getSubXFixed(), | 308 glyph.getSubXFixed(), |
321 glyph.getSubYFixed()), | 309 glyph.getSubYFixed()), |
322 SkScalarToFixed(x), | 310 SkScalarToFixed(x), |
323 SkScalarToFixed(y), | 311 SkScalarToFixed(y), |
324 fontScaler); | 312 fontScaler); |
325 } | 313 } |
326 pos += scalarsPerPosition; | 314 pos += scalarsPerPosition; |
327 } | 315 } |
328 } else { | 316 } else { |
329 int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 :
0; | 317 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ?
SK_ScalarHalf |
| 318 :
SK_Scalar1; |
330 while (text < stop) { | 319 while (text < stop) { |
331 // the last 2 parameters are ignored | 320 // the last 2 parameters are ignored |
332 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 321 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
333 | 322 |
334 if (glyph.fWidth) { | 323 if (glyph.fWidth) { |
335 SkScalar x = offset.x() + pos[0]; | 324 SkScalar x = offset.x() + pos[0]; |
336 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 325 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
337 | 326 |
| 327 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT
extRatio; |
| 328 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT
extRatio; |
| 329 |
338 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 330 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
339 glyph.getSubXFixed(), | 331 glyph.getSubXFixed(), |
340 glyph.getSubYFixed()), | 332 glyph.getSubYFixed()), |
341 SkScalarToFixed(x) - (glyph.fAdvanceX >> align
Shift), | 333 SkScalarToFixed(x - advanceX), |
342 SkScalarToFixed(y) - (glyph.fAdvanceY >> align
Shift), | 334 SkScalarToFixed(y - advanceY), |
343 fontScaler); | 335 fontScaler); |
344 } | 336 } |
345 pos += scalarsPerPosition; | 337 pos += scalarsPerPosition; |
346 } | 338 } |
347 } | 339 } |
348 | 340 |
349 this->finish(); | 341 this->finish(); |
350 } | 342 } |
351 | 343 |
352 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { | 344 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 fVertexBounds.setLargestInverted(); | 673 fVertexBounds.setLargestInverted(); |
682 } | 674 } |
683 } | 675 } |
684 | 676 |
685 inline void GrDistanceFieldTextContext::finish() { | 677 inline void GrDistanceFieldTextContext::finish() { |
686 this->flush(); | 678 this->flush(); |
687 | 679 |
688 GrTextContext::finish(); | 680 GrTextContext::finish(); |
689 } | 681 } |
690 | 682 |
OLD | NEW |