OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrAtlasTextBlob.h" | 8 #include "GrAtlasTextBlob.h" |
9 | 9 |
| 10 #include "GrBlurUtils.h" |
| 11 #include "GrContext.h" |
| 12 #include "GrDrawContext.h" |
| 13 #include "SkColorFilter.h" |
| 14 #include "SkDrawFilter.h" |
| 15 #include "SkTextBlobRunIterator.h" |
| 16 #include "batches/GrAtlasTextBatch.h" |
| 17 |
10 void GrAtlasTextBlob::appendGlyph(int runIndex, | 18 void GrAtlasTextBlob::appendGlyph(int runIndex, |
11 const SkRect& positions, | 19 const SkRect& positions, |
12 GrColor color, | 20 GrColor color, |
13 GrBatchTextStrike* strike, | 21 GrBatchTextStrike* strike, |
14 GrGlyph* glyph, | 22 GrGlyph* glyph, |
15 GrFontScaler* scaler, const SkGlyph& skGlyph, | 23 GrFontScaler* scaler, const SkGlyph& skGlyph, |
16 SkScalar x, SkScalar y, SkScalar scale, bool a
pplyVM) { | 24 SkScalar x, SkScalar y, SkScalar scale, bool a
pplyVM) { |
17 | 25 |
18 // If the glyph is too large we fall back to paths | 26 // If the glyph is too large we fall back to paths |
19 if (glyph->fTooLargeForAtlas) { | 27 if (glyph->fTooLargeForAtlas) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 fViewMatrix = viewMatrix; | 208 fViewMatrix = viewMatrix; |
201 fX = x; | 209 fX = x; |
202 fY = y; | 210 fY = y; |
203 | 211 |
204 // It is possible that a blob has neither distanceField nor bitmaptext. Thi
s is in the case | 212 // It is possible that a blob has neither distanceField nor bitmaptext. Thi
s is in the case |
205 // when all of the runs inside the blob are drawn as paths. In this case, w
e always regenerate | 213 // when all of the runs inside the blob are drawn as paths. In this case, w
e always regenerate |
206 // the blob anyways at flush time, so no need to regenerate explicitly | 214 // the blob anyways at flush time, so no need to regenerate explicitly |
207 return false; | 215 return false; |
208 } | 216 } |
209 | 217 |
| 218 GrDrawBatch* GrAtlasTextBlob::createBatch(const Run::SubRunInfo& info, |
| 219 int glyphCount, int run, int subRun, |
| 220 GrColor color, SkScalar transX, SkScal
ar transY, |
| 221 const SkPaint& skPaint, const SkSurfac
eProps& props, |
| 222 const GrDistanceFieldAdjustTable* dist
anceAdjustTable, |
| 223 GrBatchFontCache* cache) { |
| 224 GrMaskFormat format = info.maskFormat(); |
| 225 GrColor subRunColor; |
| 226 if (kARGB_GrMaskFormat == format) { |
| 227 uint8_t paintAlpha = skPaint.getAlpha(); |
| 228 subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAl
pha); |
| 229 } else { |
| 230 subRunColor = color; |
| 231 } |
| 232 |
| 233 GrAtlasTextBatch* batch; |
| 234 if (info.drawAsDistanceFields()) { |
| 235 SkColor filteredColor; |
| 236 SkColorFilter* colorFilter = skPaint.getColorFilter(); |
| 237 if (colorFilter) { |
| 238 filteredColor = colorFilter->filterColor(skPaint.getColor()); |
| 239 } else { |
| 240 filteredColor = skPaint.getColor(); |
| 241 } |
| 242 bool useBGR = SkPixelGeometryIsBGR(props.pixelGeometry()); |
| 243 batch = GrAtlasTextBatch::CreateDistanceField(glyphCount, cache, |
| 244 distanceAdjustTable, filte
redColor, |
| 245 info.hasUseLCDText(), useB
GR); |
| 246 } else { |
| 247 batch = GrAtlasTextBatch::CreateBitmap(format, glyphCount, cache); |
| 248 } |
| 249 GrAtlasTextBatch::Geometry& geometry = batch->geometry(); |
| 250 geometry.fBlob = SkRef(this); |
| 251 geometry.fRun = run; |
| 252 geometry.fSubRun = subRun; |
| 253 geometry.fColor = subRunColor; |
| 254 geometry.fTransX = transX; |
| 255 geometry.fTransY = transY; |
| 256 batch->init(); |
| 257 |
| 258 return batch; |
| 259 } |
| 260 |
| 261 inline |
| 262 void GrAtlasTextBlob::flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBui
lder, |
| 263 int run, GrColor color, |
| 264 SkScalar transX, SkScalar transY, |
| 265 const SkPaint& skPaint, const SkSurfaceProps& pro
ps, |
| 266 const GrDistanceFieldAdjustTable* distanceAdjustT
able, |
| 267 GrBatchFontCache* cache) { |
| 268 for (int subRun = 0; subRun < fRuns[run].fSubRunInfo.count(); subRun++) { |
| 269 const Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun]; |
| 270 int glyphCount = info.glyphCount(); |
| 271 if (0 == glyphCount) { |
| 272 continue; |
| 273 } |
| 274 |
| 275 SkAutoTUnref<GrDrawBatch> batch(this->createBatch(info, glyphCount, run, |
| 276 subRun, color, transX,
transY, |
| 277 skPaint, props, |
| 278 distanceAdjustTable, c
ache)); |
| 279 dc->drawBatch(pipelineBuilder, batch); |
| 280 } |
| 281 } |
| 282 |
| 283 void GrAtlasTextBlob::flushBigGlyphs(GrContext* context, GrDrawContext* dc, |
| 284 const GrClip& clip, const SkPaint& skPaint, |
| 285 SkScalar transX, SkScalar transY, |
| 286 const SkIRect& clipBounds) { |
| 287 for (int i = 0; i < fBigGlyphs.count(); i++) { |
| 288 GrAtlasTextBlob::BigGlyph& bigGlyph = fBigGlyphs[i]; |
| 289 bigGlyph.fVx += transX; |
| 290 bigGlyph.fVy += transY; |
| 291 SkMatrix ctm; |
| 292 ctm.setScale(bigGlyph.fScale, bigGlyph.fScale); |
| 293 ctm.postTranslate(bigGlyph.fVx, bigGlyph.fVy); |
| 294 if (bigGlyph.fApplyVM) { |
| 295 ctm.postConcat(fViewMatrix); |
| 296 } |
| 297 |
| 298 GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, bigGlyph.fPath, |
| 299 skPaint, ctm, nullptr, clipBounds, f
alse); |
| 300 } |
| 301 } |
| 302 |
| 303 void GrAtlasTextBlob::flushRunAsPaths(GrDrawContext* dc, |
| 304 GrTextContext* textContext, |
| 305 const SkSurfaceProps& props, |
| 306 const SkTextBlobRunIterator& it, |
| 307 const GrClip& clip, const SkPaint& skPaint
, |
| 308 SkDrawFilter* drawFilter, const SkMatrix&
viewMatrix, |
| 309 const SkIRect& clipBounds, SkScalar x, SkS
calar y) { |
| 310 SkPaint runPaint = skPaint; |
| 311 |
| 312 size_t textLen = it.glyphCount() * sizeof(uint16_t); |
| 313 const SkPoint& offset = it.offset(); |
| 314 |
| 315 it.applyFontToPaint(&runPaint); |
| 316 |
| 317 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type))
{ |
| 318 return; |
| 319 } |
| 320 |
| 321 runPaint.setFlags(GrTextContext::FilterTextFlags(props, runPaint)); |
| 322 |
| 323 switch (it.positioning()) { |
| 324 case SkTextBlob::kDefault_Positioning: |
| 325 textContext->drawTextAsPath(dc, clip, runPaint, viewMatrix, |
| 326 (const char *)it.glyphs(), |
| 327 textLen, x + offset.x(), y + offset.y(),
clipBounds); |
| 328 break; |
| 329 case SkTextBlob::kHorizontal_Positioning: |
| 330 textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, |
| 331 (const char*)it.glyphs(), |
| 332 textLen, it.pos(), 1, SkPoint::Make(x
, y + offset.y()), |
| 333 clipBounds); |
| 334 break; |
| 335 case SkTextBlob::kFull_Positioning: |
| 336 textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, |
| 337 (const char*)it.glyphs(), |
| 338 textLen, it.pos(), 2, SkPoint::Make(x
, y), clipBounds); |
| 339 break; |
| 340 } |
| 341 } |
| 342 |
| 343 void GrAtlasTextBlob::flushCached(const SkTextBlob* blob, |
| 344 GrContext* context, |
| 345 GrDrawContext* dc, |
| 346 GrTextContext* textContext, |
| 347 const SkSurfaceProps& props, |
| 348 const GrDistanceFieldAdjustTable* distanceAdju
stTable, |
| 349 const SkPaint& skPaint, |
| 350 const GrPaint& grPaint, |
| 351 SkDrawFilter* drawFilter, |
| 352 const GrClip& clip, |
| 353 const SkMatrix& viewMatrix, |
| 354 const SkIRect& clipBounds, |
| 355 SkScalar x, SkScalar y, |
| 356 SkScalar transX, SkScalar transY) { |
| 357 // We loop through the runs of the blob, flushing each. If any run is too l
arge, then we flush |
| 358 // it as paths |
| 359 GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip); |
| 360 |
| 361 GrColor color = grPaint.getColor(); |
| 362 |
| 363 SkTextBlobRunIterator it(blob); |
| 364 for (int run = 0; !it.done(); it.next(), run++) { |
| 365 if (fRuns[run].fDrawAsPaths) { |
| 366 this->flushRunAsPaths(dc, textContext, props, it, clip, skPaint, |
| 367 drawFilter, viewMatrix, clipBounds, x, y); |
| 368 continue; |
| 369 } |
| 370 fRuns[run].fVertexBounds.offset(transX, transY); |
| 371 this->flushRun(dc, &pipelineBuilder, run, color, |
| 372 transX, transY, skPaint, props, |
| 373 distanceAdjustTable, context->getBatchFontCache()); |
| 374 } |
| 375 |
| 376 // Now flush big glyphs |
| 377 this->flushBigGlyphs(context, dc, clip, skPaint, transX, transY, clipBounds)
; |
| 378 } |
| 379 |
| 380 void GrAtlasTextBlob::flushThrowaway(GrContext* context, |
| 381 GrDrawContext* dc, |
| 382 const SkSurfaceProps& props, |
| 383 const GrDistanceFieldAdjustTable* distanceA
djustTable, |
| 384 const SkPaint& skPaint, |
| 385 const GrPaint& grPaint, |
| 386 const GrClip& clip, |
| 387 const SkIRect& clipBounds) { |
| 388 GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip); |
| 389 |
| 390 GrColor color = grPaint.getColor(); |
| 391 for (int run = 0; run < fRunCount; run++) { |
| 392 this->flushRun(dc, &pipelineBuilder, run, color, 0, 0, skPaint, props, |
| 393 distanceAdjustTable, context->getBatchFontCache()); |
| 394 } |
| 395 |
| 396 // Now flush big glyphs |
| 397 this->flushBigGlyphs(context, dc, clip, skPaint, 0, 0, clipBounds); |
| 398 } |
| 399 |
| 400 |
210 // TODO get this code building again | 401 // TODO get this code building again |
211 #ifdef CACHE_SANITY_CHECK | 402 #ifdef CACHE_SANITY_CHECK |
212 void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlo
b& r) { | 403 void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlo
b& r) { |
213 SkASSERT(l.fSize == r.fSize); | 404 SkASSERT(l.fSize == r.fSize); |
214 SkASSERT(l.fPool == r.fPool); | 405 SkASSERT(l.fPool == r.fPool); |
215 | 406 |
216 SkASSERT(l.fBlurRec.fSigma == r.fBlurRec.fSigma); | 407 SkASSERT(l.fBlurRec.fSigma == r.fBlurRec.fSigma); |
217 SkASSERT(l.fBlurRec.fStyle == r.fBlurRec.fStyle); | 408 SkASSERT(l.fBlurRec.fStyle == r.fBlurRec.fStyle); |
218 SkASSERT(l.fBlurRec.fQuality == r.fBlurRec.fQuality); | 409 SkASSERT(l.fBlurRec.fQuality == r.fBlurRec.fQuality); |
219 | 410 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 rSubRun.fBulkUseToken.fPlotAlreadyUpdated); | 492 rSubRun.fBulkUseToken.fPlotAlreadyUpdated); |
302 for (int k = 0; k < lSubRun.fBulkUseToken.fPlotsToUpdate.count(); k+
+) { | 493 for (int k = 0; k < lSubRun.fBulkUseToken.fPlotsToUpdate.count(); k+
+) { |
303 SkASSERT(lSubRun.fBulkUseToken.fPlotsToUpdate[k] == | 494 SkASSERT(lSubRun.fBulkUseToken.fPlotsToUpdate[k] == |
304 rSubRun.fBulkUseToken.fPlotsToUpdate[k]); | 495 rSubRun.fBulkUseToken.fPlotsToUpdate[k]); |
305 }*/ | 496 }*/ |
306 } | 497 } |
307 } | 498 } |
308 } | 499 } |
309 | 500 |
310 #endif | 501 #endif |
OLD | NEW |