| 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 |