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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 return false; | 58 return false; |
59 } | 59 } |
60 | 60 |
61 // No color bitmap fonts. | 61 // No color bitmap fonts. |
62 SkScalerContext::Rec rec; | 62 SkScalerContext::Rec rec; |
63 SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec); | 63 SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec); |
64 return rec.getFormat() != SkMask::kARGB32_Format; | 64 return rec.getFormat() != SkMask::kARGB32_Format; |
65 } | 65 } |
66 | 66 |
67 void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt, | 67 void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt, |
| 68 const GrClip& clip, |
68 const GrPaint& paint, | 69 const GrPaint& paint, |
69 const SkPaint& skPaint, | 70 const SkPaint& skPaint, |
70 const SkMatrix& viewMatrix, | 71 const SkMatrix& viewMatrix, |
71 const char text[], | 72 const char text[], |
72 size_t byteLength, | 73 size_t byteLength, |
73 SkScalar x, SkScalar y) { | 74 SkScalar x, SkScalar y) { |
74 SkASSERT(byteLength == 0 || text != NULL); | 75 SkASSERT(byteLength == 0 || text != NULL); |
75 | 76 |
76 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { | 77 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { |
77 return; | 78 return; |
78 } | 79 } |
79 | 80 |
80 // This is the slow path, mainly used by Skia unit tests. The other | 81 // This is the slow path, mainly used by Skia unit tests. The other |
81 // backends (8888, gpu, ...) use device-space dependent glyph caches. In | 82 // backends (8888, gpu, ...) use device-space dependent glyph caches. In |
82 // order to match the glyph positions that the other code paths produce, we | 83 // order to match the glyph positions that the other code paths produce, we |
83 // must also use device-space dependent glyph cache. This has the | 84 // must also use device-space dependent glyph cache. This has the |
84 // side-effect that the glyph shape outline will be in device-space, | 85 // side-effect that the glyph shape outline will be in device-space, |
85 // too. This in turn has the side-effect that NVPR can not stroke the paths, | 86 // too. This in turn has the side-effect that NVPR can not stroke the paths, |
86 // as the stroke in NVPR is defined in object-space. | 87 // as the stroke in NVPR is defined in object-space. |
87 // NOTE: here we have following coincidence that works at the moment: | 88 // NOTE: here we have following coincidence that works at the moment: |
88 // - When using the device-space glyphs, the transforms we pass to NVPR | 89 // - When using the device-space glyphs, the transforms we pass to NVPR |
89 // instanced drawing are the global transforms, and the view transform is | 90 // instanced drawing are the global transforms, and the view transform is |
90 // identity. NVPR can not use non-affine transforms in the instanced | 91 // identity. NVPR can not use non-affine transforms in the instanced |
91 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it | 92 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it |
92 // will turn off the use of device-space glyphs when perspective transforms | 93 // will turn off the use of device-space glyphs when perspective transforms |
93 // are in use. | 94 // are in use. |
94 | 95 |
95 this->init(rt, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatr
ix); | 96 this->init(rt, clip, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, vi
ewMatrix); |
96 | 97 |
97 // Transform our starting point. | 98 // Transform our starting point. |
98 if (fUsingDeviceSpaceGlyphs) { | 99 if (fUsingDeviceSpaceGlyphs) { |
99 SkPoint loc; | 100 SkPoint loc; |
100 fContextInitialMatrix.mapXY(x, y, &loc); | 101 fContextInitialMatrix.mapXY(x, y, &loc); |
101 x = loc.fX; | 102 x = loc.fX; |
102 y = loc.fY; | 103 y = loc.fY; |
103 } | 104 } |
104 | 105 |
105 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 106 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 149 } |
149 | 150 |
150 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio); | 151 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio); |
151 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio); | 152 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio); |
152 } | 153 } |
153 | 154 |
154 this->finish(); | 155 this->finish(); |
155 } | 156 } |
156 | 157 |
157 void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt, | 158 void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt, |
| 159 const GrClip& clip, |
158 const GrPaint& paint, | 160 const GrPaint& paint, |
159 const SkPaint& skPaint, | 161 const SkPaint& skPaint, |
160 const SkMatrix& viewMatrix, | 162 const SkMatrix& viewMatrix, |
161 const char text[], | 163 const char text[], |
162 size_t byteLength, | 164 size_t byteLength, |
163 const SkScalar pos[], | 165 const SkScalar pos[], |
164 int scalarsPerPosition, | 166 int scalarsPerPosition, |
165 const SkPoint& offset) { | 167 const SkPoint& offset) { |
166 SkASSERT(byteLength == 0 || text != NULL); | 168 SkASSERT(byteLength == 0 || text != NULL); |
167 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 169 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
168 | 170 |
169 // nothing to draw | 171 // nothing to draw |
170 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { | 172 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { |
171 return; | 173 return; |
172 } | 174 } |
173 | 175 |
174 // This is the fast path. Here we do not bake in the device-transform to | 176 // This is the fast path. Here we do not bake in the device-transform to |
175 // the glyph outline or the advances. This is because we do not need to | 177 // the glyph outline or the advances. This is because we do not need to |
176 // position the glyphs at all, since the caller has done the positioning. | 178 // position the glyphs at all, since the caller has done the positioning. |
177 // The positioning is based on SkPaint::measureText of individual | 179 // The positioning is based on SkPaint::measureText of individual |
178 // glyphs. That already uses glyph cache without device transforms. Device | 180 // glyphs. That already uses glyph cache without device transforms. Device |
179 // transform is not part of SkPaint::measureText API, and thus we use the | 181 // transform is not part of SkPaint::measureText API, and thus we use the |
180 // same glyphs as what were measured. | 182 // same glyphs as what were measured. |
181 | 183 |
182 this->init(rt, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewM
atrix); | 184 this->init(rt, clip, paint, skPaint, byteLength, kMaxPerformance_RenderMode,
viewMatrix); |
183 | 185 |
184 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 186 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
185 | 187 |
186 const char* stop = text + byteLength; | 188 const char* stop = text + byteLength; |
187 | 189 |
188 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); | 190 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); |
189 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign()); | 191 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign()); |
190 while (text < stop) { | 192 while (text < stop) { |
191 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); | 193 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); |
192 if (glyph.fWidth) { | 194 if (glyph.fWidth) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 static_cast<GrPathRange*>(ctx->findAndRefCachedResource(key))); | 227 static_cast<GrPathRange*>(ctx->findAndRefCachedResource(key))); |
226 if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) { | 228 if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) { |
227 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc
, stroke)); | 229 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc
, stroke)); |
228 ctx->addResourceToCache(key, glyphs); | 230 ctx->addResourceToCache(key, glyphs); |
229 } | 231 } |
230 | 232 |
231 return glyphs.detach(); | 233 return glyphs.detach(); |
232 } | 234 } |
233 | 235 |
234 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, | 236 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, |
| 237 const GrClip& clip, |
235 const GrPaint& paint, | 238 const GrPaint& paint, |
236 const SkPaint& skPaint, | 239 const SkPaint& skPaint, |
237 size_t textByteLength, | 240 size_t textByteLength, |
238 RenderMode renderMode, | 241 RenderMode renderMode, |
239 const SkMatrix& viewMatrix) { | 242 const SkMatrix& viewMatrix) { |
240 GrTextContext::init(rt, paint, skPaint); | 243 GrTextContext::init(rt, clip, paint, skPaint); |
241 | 244 |
242 fContextInitialMatrix = viewMatrix; | 245 fContextInitialMatrix = viewMatrix; |
243 fViewMatrix = viewMatrix; | 246 fViewMatrix = viewMatrix; |
244 fLocalMatrix = SkMatrix::I(); | 247 fLocalMatrix = SkMatrix::I(); |
245 | 248 |
246 const bool otherBackendsWillDrawAsPaths = | 249 const bool otherBackendsWillDrawAsPaths = |
247 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); | 250 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); |
248 | 251 |
249 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && | 252 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && |
250 kMaxAccuracy_RenderMode == renderMode && | 253 kMaxAccuracy_RenderMode == renderMode && |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 fStroke.applyToPaint(&skPaintFallback); | 438 fStroke.applyToPaint(&skPaintFallback); |
436 } | 439 } |
437 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already
been accounted for. | 440 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already
been accounted for. |
438 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 441 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
439 | 442 |
440 SkMatrix inverse; | 443 SkMatrix inverse; |
441 if (this->mapToFallbackContext(&inverse)) { | 444 if (this->mapToFallbackContext(&inverse)) { |
442 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp
hCount); | 445 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp
hCount); |
443 } | 446 } |
444 | 447 |
445 fFallbackTextContext->drawPosText(fRenderTarget, paintFallback, skPaintF
allback, | 448 fFallbackTextContext->drawPosText(fRenderTarget, fClip, paintFallback, s
kPaintFallback, |
446 fViewMatrix, (char*)&fGlyphIndices[fFa
llbackGlyphsIdx], | 449 fViewMatrix, (char*)&fGlyphIndices[fFa
llbackGlyphsIdx], |
447 2 * fallbackGlyphCount, | 450 2 * fallbackGlyphCount, |
448 get_xy_scalar_array(&fGlyphPositions[f
FallbackGlyphsIdx]), | 451 get_xy_scalar_array(&fGlyphPositions[f
FallbackGlyphsIdx]), |
449 2, SkPoint::Make(0, 0)); | 452 2, SkPoint::Make(0, 0)); |
450 | 453 |
451 fFallbackGlyphsIdx = kGlyphBufferSize; | 454 fFallbackGlyphsIdx = kGlyphBufferSize; |
452 } | 455 } |
453 } | 456 } |
454 | 457 |
455 void GrStencilAndCoverTextContext::finish() { | 458 void GrStencilAndCoverTextContext::finish() { |
456 this->flush(); | 459 this->flush(); |
457 | 460 |
458 fGlyphs->unref(); | 461 fGlyphs->unref(); |
459 fGlyphs = NULL; | 462 fGlyphs = NULL; |
460 | 463 |
461 SkGlyphCache::AttachCache(fGlyphCache); | 464 SkGlyphCache::AttachCache(fGlyphCache); |
462 fGlyphCache = NULL; | 465 fGlyphCache = NULL; |
463 | 466 |
464 fPipelineBuilder.stencil()->setDisabled(); | 467 fPipelineBuilder.stencil()->setDisabled(); |
465 fStateRestore.set(NULL); | 468 fStateRestore.set(NULL); |
466 fViewMatrix = fContextInitialMatrix; | 469 fViewMatrix = fContextInitialMatrix; |
467 GrTextContext::finish(); | 470 GrTextContext::finish(); |
468 } | 471 } |
469 | 472 |
OLD | NEW |