OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrStencilAndCoverTextContext.h" | 8 #include "GrStencilAndCoverTextContext.h" |
9 #include "GrBitmapTextContext.h" | 9 #include "GrBitmapTextContext.h" |
10 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 227 |
228 void GrStencilAndCoverTextContext::init(const GrPaint& paint, | 228 void GrStencilAndCoverTextContext::init(const GrPaint& paint, |
229 const SkPaint& skPaint, | 229 const SkPaint& skPaint, |
230 size_t textByteLength, | 230 size_t textByteLength, |
231 RenderMode renderMode, | 231 RenderMode renderMode, |
232 const SkMatrix& viewMatrix) { | 232 const SkMatrix& viewMatrix) { |
233 GrTextContext::init(paint, skPaint); | 233 GrTextContext::init(paint, skPaint); |
234 | 234 |
235 fContextInitialMatrix = viewMatrix; | 235 fContextInitialMatrix = viewMatrix; |
236 fViewMatrix = viewMatrix; | 236 fViewMatrix = viewMatrix; |
| 237 fLocalMatrix = SkMatrix::I(); |
237 | 238 |
238 const bool otherBackendsWillDrawAsPaths = | 239 const bool otherBackendsWillDrawAsPaths = |
239 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); | 240 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); |
240 | 241 |
241 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && | 242 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && |
242 kMaxAccuracy_RenderMode == renderMode && | 243 kMaxAccuracy_RenderMode == renderMode && |
243 SkToBool(fContextInitialMatrix.getType() & | 244 SkToBool(fContextInitialMatrix.getType() & |
244 (SkMatrix::kScale_Mask | SkMatrix::kAffin
e_Mask)); | 245 (SkMatrix::kScale_Mask | SkMatrix::kAffin
e_Mask)); |
245 | 246 |
246 if (fUsingDeviceSpaceGlyphs) { | 247 if (fUsingDeviceSpaceGlyphs) { |
247 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. | 248 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. |
248 SkASSERT(!fContextInitialMatrix.hasPerspective()); | 249 SkASSERT(!fContextInitialMatrix.hasPerspective()); |
249 | 250 |
250 // The whole shape (including stroke) will be baked into the glyph outli
nes. Make | 251 // The whole shape (including stroke) will be baked into the glyph outli
nes. Make |
251 // NVPR just fill the baked shapes. | 252 // NVPR just fill the baked shapes. |
252 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle); | 253 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle); |
253 | 254 |
254 fTextRatio = fTextInverseRatio = 1.0f; | 255 fTextRatio = fTextInverseRatio = 1.0f; |
255 | 256 |
256 // Glyphs loaded by GPU path rendering have an inverted y-direction. | 257 // Glyphs loaded by GPU path rendering have an inverted y-direction. |
257 SkMatrix m; | 258 SkMatrix m; |
258 m.setScale(1, -1); | 259 m.setScale(1, -1); |
259 fViewMatrix = m; | 260 fViewMatrix = m; |
260 | 261 |
261 // Post-flip the initial matrix so we're left with just the flip after | 262 // Post-flip the initial matrix so we're left with just the flip after |
262 // the paint preConcats the inverse. | 263 // the paint preConcats the inverse. |
263 m = fContextInitialMatrix; | 264 m = fContextInitialMatrix; |
264 m.postScale(1, -1); | 265 m.postScale(1, -1); |
265 fPaint.localCoordChangeInverse(m); | 266 if (!m.invert(&fLocalMatrix)) { |
| 267 SkDebugf("Not invertible!\n"); |
| 268 return; |
| 269 } |
266 | 270 |
267 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM
atrix, | 271 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM
atrix, |
268 true /*ignoreGamma*/); | 272 true /*ignoreGamma*/); |
269 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy
peface(), | 273 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy
peface(), |
270 &fGlyphCache->getDescriptor(), fStroke); | 274 &fGlyphCache->getDescriptor(), fStroke); |
271 } else { | 275 } else { |
272 // Don't bake strokes into the glyph outlines. We will stroke the glyphs | 276 // Don't bake strokes into the glyph outlines. We will stroke the glyphs |
273 // using the GPU instead. This is the fast path. | 277 // using the GPU instead. This is the fast path. |
274 fStroke = SkStrokeRec(fSkPaint); | 278 fStroke = SkStrokeRec(fSkPaint); |
275 fSkPaint.setStyle(SkPaint::kFill_Style); | 279 fSkPaint.setStyle(SkPaint::kFill_Style); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 !fSkPaint.isFakeBoldText() && | 328 !fSkPaint.isFakeBoldText() && |
325 !fSkPaint.isVerticalText(); | 329 !fSkPaint.isVerticalText(); |
326 } else { | 330 } else { |
327 fTextRatio = fTextInverseRatio = 1.0f; | 331 fTextRatio = fTextInverseRatio = 1.0f; |
328 canUseRawPaths = false; | 332 canUseRawPaths = false; |
329 } | 333 } |
330 | 334 |
331 SkMatrix textMatrix; | 335 SkMatrix textMatrix; |
332 // Glyphs loaded by GPU path rendering have an inverted y-direction. | 336 // Glyphs loaded by GPU path rendering have an inverted y-direction. |
333 textMatrix.setScale(fTextRatio, -fTextRatio); | 337 textMatrix.setScale(fTextRatio, -fTextRatio); |
334 fPaint.localCoordChange(textMatrix); | |
335 fViewMatrix.preConcat(textMatrix); | 338 fViewMatrix.preConcat(textMatrix); |
| 339 fLocalMatrix = textMatrix; |
336 | 340 |
337 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, true /*igno
reGamma*/); | 341 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, true /*igno
reGamma*/); |
338 fGlyphs = canUseRawPaths ? | 342 fGlyphs = canUseRawPaths ? |
339 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, fStr
oke) : | 343 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, fStr
oke) : |
340 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g
etTypeface(), | 344 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g
etTypeface(), |
341 &fGlyphCache->getDescriptor(), fStroke); | 345 &fGlyphCache->getDescriptor(), fStroke); |
342 } | 346 } |
343 | 347 |
344 fStateRestore.set(&fDrawState); | 348 fStateRestore.set(&fDrawState); |
345 | 349 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 399 |
396 static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) { | 400 static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) { |
397 GR_STATIC_ASSERT(2 * sizeof(SkScalar) == sizeof(SkPoint)); | 401 GR_STATIC_ASSERT(2 * sizeof(SkScalar) == sizeof(SkPoint)); |
398 GR_STATIC_ASSERT(0 == offsetof(SkPoint, fX)); | 402 GR_STATIC_ASSERT(0 == offsetof(SkPoint, fX)); |
399 | 403 |
400 return &pointArray[0].fX; | 404 return &pointArray[0].fX; |
401 } | 405 } |
402 | 406 |
403 void GrStencilAndCoverTextContext::flush() { | 407 void GrStencilAndCoverTextContext::flush() { |
404 if (fQueuedGlyphCount > 0) { | 408 if (fQueuedGlyphCount > 0) { |
405 SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor
())); | 409 SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor
(), fLocalMatrix)); |
406 fDrawTarget->drawPaths(&fDrawState, pp, fGlyphs, | 410 fDrawTarget->drawPaths(&fDrawState, pp, fGlyphs, |
407 fGlyphIndices, GrPathRange::kU16_PathIndexType, | 411 fGlyphIndices, GrPathRange::kU16_PathIndexType, |
408 get_xy_scalar_array(fGlyphPositions), | 412 get_xy_scalar_array(fGlyphPositions), |
409 GrPathRendering::kTranslate_PathTransformType, | 413 GrPathRendering::kTranslate_PathTransformType, |
410 fQueuedGlyphCount, GrPathRendering::kWinding_Fill
Type); | 414 fQueuedGlyphCount, GrPathRendering::kWinding_Fill
Type); |
411 | 415 |
412 fQueuedGlyphCount = 0; | 416 fQueuedGlyphCount = 0; |
413 } | 417 } |
414 | 418 |
415 if (fFallbackGlyphsIdx < kGlyphBufferSize) { | 419 if (fFallbackGlyphsIdx < kGlyphBufferSize) { |
416 int fallbackGlyphCount = kGlyphBufferSize - fFallbackGlyphsIdx; | 420 int fallbackGlyphCount = kGlyphBufferSize - fFallbackGlyphsIdx; |
417 | 421 |
418 GrPaint paintFallback(fPaint); | 422 GrPaint paintFallback(fPaint); |
419 | 423 |
420 SkPaint skPaintFallback(fSkPaint); | 424 SkPaint skPaintFallback(fSkPaint); |
421 if (!fUsingDeviceSpaceGlyphs) { | 425 if (!fUsingDeviceSpaceGlyphs) { |
422 fStroke.applyToPaint(&skPaintFallback); | 426 fStroke.applyToPaint(&skPaintFallback); |
423 } | 427 } |
424 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already
been accounted for. | 428 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already
been accounted for. |
425 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 429 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
426 | 430 |
427 SkMatrix inverse; | 431 SkMatrix inverse; |
428 if (this->mapToFallbackContext(&inverse)) { | 432 if (this->mapToFallbackContext(&inverse)) { |
429 paintFallback.localCoordChangeInverse(inverse); | |
430 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp
hCount); | 433 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp
hCount); |
431 } | 434 } |
432 | 435 |
433 fFallbackTextContext->drawPosText(paintFallback, skPaintFallback, fViewM
atrix, | 436 fFallbackTextContext->drawPosText(paintFallback, skPaintFallback, fViewM
atrix, |
434 (char*)&fGlyphIndices[fFallbackGlyphsI
dx], | 437 (char*)&fGlyphIndices[fFallbackGlyphsI
dx], |
435 2 * fallbackGlyphCount, | 438 2 * fallbackGlyphCount, |
436 get_xy_scalar_array(&fGlyphPositions[f
FallbackGlyphsIdx]), | 439 get_xy_scalar_array(&fGlyphPositions[f
FallbackGlyphsIdx]), |
437 2, SkPoint::Make(0, 0)); | 440 2, SkPoint::Make(0, 0)); |
438 | 441 |
439 fFallbackGlyphsIdx = kGlyphBufferSize; | 442 fFallbackGlyphsIdx = kGlyphBufferSize; |
440 } | 443 } |
441 } | 444 } |
442 | 445 |
443 void GrStencilAndCoverTextContext::finish() { | 446 void GrStencilAndCoverTextContext::finish() { |
444 this->flush(); | 447 this->flush(); |
445 | 448 |
446 fGlyphs->unref(); | 449 fGlyphs->unref(); |
447 fGlyphs = NULL; | 450 fGlyphs = NULL; |
448 | 451 |
449 SkGlyphCache::AttachCache(fGlyphCache); | 452 SkGlyphCache::AttachCache(fGlyphCache); |
450 fGlyphCache = NULL; | 453 fGlyphCache = NULL; |
451 | 454 |
452 fDrawState.stencil()->setDisabled(); | 455 fDrawState.stencil()->setDisabled(); |
453 fStateRestore.set(NULL); | 456 fStateRestore.set(NULL); |
454 fViewMatrix = fContextInitialMatrix; | 457 fViewMatrix = fContextInitialMatrix; |
455 GrTextContext::finish(); | 458 GrTextContext::finish(); |
456 } | 459 } |
457 | 460 |
OLD | NEW |