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" |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 | 287 |
288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
289 | 289 |
290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
291 SkGlyphCache* cache = autoCache.getCache(); | 291 SkGlyphCache* cache = autoCache.getCache(); |
292 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 292 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
293 | 293 |
294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
295 | 295 |
296 const char* stop = text + byteLength; | 296 const char* stop = text + byteLength; |
297 SkTArray<char> fallbackText; | |
298 size_t fallbackByteLength = 0; | |
299 SkTArray<SkScalar> fallbackPos; | |
297 | 300 |
298 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 301 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
299 while (text < stop) { | 302 while (text < stop) { |
303 const char* lastText = text; | |
300 // the last 2 parameters are ignored | 304 // the last 2 parameters are ignored |
301 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 305 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
302 | 306 |
303 if (glyph.fWidth) { | 307 if (glyph.fWidth) { |
304 SkScalar x = offset.x() + pos[0]; | 308 SkScalar x = offset.x() + pos[0]; |
305 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; | 309 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; |
306 | 310 |
307 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 311 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
308 glyph.getSubXFixed(), | 312 glyph.getSubXFixed(), |
309 glyph.getSubYFixed()), | 313 glyph.getSubYFixed()), |
310 SkScalarToFixed(x), | 314 SkScalarToFixed(x), |
311 SkScalarToFixed(y), | 315 SkScalarToFixed(y), |
312 fontScaler); | 316 fontScaler)) { |
317 // couldn't append, send to fallback | |
318 size_t newByteLength = text-lastText; | |
robertphillips
2014/10/20 18:52:11
fallbackText.push_back_n(newByteLength, lastText);
jvanverth1
2014/10/20 20:04:40
Done.
| |
319 for (size_t i = 0; i < newByteLength; ++i) { | |
320 fallbackText.push_back(*lastText); | |
321 ++lastText; | |
322 } | |
323 fallbackPos.push_back(pos[0]); | |
robertphillips
2014/10/20 18:52:11
const on left ?
jvanverth1
2014/10/20 20:04:40
Done.
| |
324 if (scalarsPerPosition == 2) { | |
325 fallbackPos.push_back(pos[1]); | |
326 } | |
robertphillips
2014/10/20 18:52:11
Doesn't fallbackText.count() already store this?
jvanverth1
2014/10/20 20:04:40
Done.
| |
327 fallbackByteLength += newByteLength; | |
328 } | |
313 } | 329 } |
314 pos += scalarsPerPosition; | 330 pos += scalarsPerPosition; |
315 } | 331 } |
316 } else { | 332 } else { |
317 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf | 333 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf |
318 : SK_Scalar1; | 334 : SK_Scalar1; |
319 while (text < stop) { | 335 while (text < stop) { |
336 const char* lastText = text; | |
320 // the last 2 parameters are ignored | 337 // the last 2 parameters are ignored |
321 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 338 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
322 | 339 |
323 if (glyph.fWidth) { | 340 if (glyph.fWidth) { |
324 SkScalar x = offset.x() + pos[0]; | 341 SkScalar x = offset.x() + pos[0]; |
325 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; | 342 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; |
326 | 343 |
327 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio; | 344 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio; |
328 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio; | 345 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio; |
329 | 346 |
330 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 347 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
331 glyph.getSubXFixed(), | 348 glyph.getSubXFixed(), |
332 glyph.getSubYFixed()), | 349 glyph.getSubYFixed()), |
333 SkScalarToFixed(x - advanceX), | 350 SkScalarToFixed(x - advanceX), |
334 SkScalarToFixed(y - advanceY), | 351 SkScalarToFixed(y - advanceY), |
335 fontScaler); | 352 fontScaler)) { |
353 // couldn't append, send to fallback | |
354 size_t newByteLength = text-lastText; | |
robertphillips
2014/10/20 18:52:11
push_back_n here too ?
jvanverth1
2014/10/20 20:04:41
Done.
| |
355 for (size_t i = 0; i < newByteLength; ++i) { | |
356 fallbackText.push_back(*lastText); | |
357 ++lastText; | |
358 } | |
359 fallbackPos.push_back(pos[0]); | |
robertphillips
2014/10/20 18:52:11
const on left ?
jvanverth1
2014/10/20 20:04:40
Done.
| |
360 if (scalarsPerPosition == 2) { | |
361 fallbackPos.push_back(pos[1]); | |
362 } | |
363 fallbackByteLength += newByteLength; | |
364 } | |
336 } | 365 } |
337 pos += scalarsPerPosition; | 366 pos += scalarsPerPosition; |
338 } | 367 } |
339 } | 368 } |
340 | 369 |
341 this->finish(); | 370 this->finish(); |
371 | |
372 if (fallbackByteLength > 0) { | |
373 fFallbackTextContext->drawPosText(paint, skPaint, fallbackText.begin(), fallbackByteLength, | |
374 fallbackPos.begin(), scalarsPerPositio n, offset); | |
375 } | |
342 } | 376 } |
343 | 377 |
344 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { | 378 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { |
345 unsigned r = SkColorGetR(c); | 379 unsigned r = SkColorGetR(c); |
346 unsigned g = SkColorGetG(c); | 380 unsigned g = SkColorGetG(c); |
347 unsigned b = SkColorGetB(c); | 381 unsigned b = SkColorGetB(c); |
348 return GrColorPackRGBA(r, g, b, 0xff); | 382 return GrColorPackRGBA(r, g, b, 0xff); |
349 } | 383 } |
350 | 384 |
351 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) { | 385 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 params, flags)); | 425 params, flags)); |
392 #endif | 426 #endif |
393 } | 427 } |
394 fEffectTextureUniqueID = textureUniqueID; | 428 fEffectTextureUniqueID = textureUniqueID; |
395 fEffectColor = filteredColor; | 429 fEffectColor = filteredColor; |
396 fEffectFlags = flags; | 430 fEffectFlags = flags; |
397 } | 431 } |
398 | 432 |
399 } | 433 } |
400 | 434 |
401 void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, | 435 // Returns true if this method handled the glyph, false if needs to be passed to fallback |
436 // | |
437 bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, | |
402 SkFixed vx, SkFixed vy, | 438 SkFixed vx, SkFixed vy, |
403 GrFontScaler* scaler) { | 439 GrFontScaler* scaler) { |
404 if (NULL == fDrawTarget) { | 440 if (NULL == fDrawTarget) { |
405 return; | 441 return true; |
406 } | 442 } |
407 | 443 |
408 if (NULL == fStrike) { | 444 if (NULL == fStrike) { |
409 fStrike = fContext->getFontCache()->getStrike(scaler, true); | 445 fStrike = fContext->getFontCache()->getStrike(scaler, true); |
410 } | 446 } |
411 | 447 |
412 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 448 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
413 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 449 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
414 return; | 450 return true; |
415 } | 451 } |
416 | 452 |
417 // TODO: support color glyphs | 453 // fallback to color glyph support |
418 if (kA8_GrMaskFormat != glyph->fMaskFormat) { | 454 if (kA8_GrMaskFormat != glyph->fMaskFormat) { |
419 return; | 455 return false; |
420 } | 456 } |
421 | 457 |
422 SkScalar sx = SkFixedToScalar(vx); | 458 SkScalar sx = SkFixedToScalar(vx); |
423 SkScalar sy = SkFixedToScalar(vy); | 459 SkScalar sy = SkFixedToScalar(vy); |
424 /* | 460 /* |
425 // not valid, need to find a different solution for this | 461 // not valid, need to find a different solution for this |
426 vx += SkIntToFixed(glyph->fBounds.fLeft); | 462 vx += SkIntToFixed(glyph->fBounds.fLeft); |
427 vy += SkIntToFixed(glyph->fBounds.fTop); | 463 vy += SkIntToFixed(glyph->fBounds.fTop); |
428 | 464 |
429 // keep them as ints until we've done the clip-test | 465 // keep them as ints until we've done the clip-test |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 fStrike->addGlyphToAtlas(glyph, scaler)) { | 503 fStrike->addGlyphToAtlas(glyph, scaler)) { |
468 goto HAS_ATLAS; | 504 goto HAS_ATLAS; |
469 } | 505 } |
470 } | 506 } |
471 | 507 |
472 if (NULL == glyph->fPath) { | 508 if (NULL == glyph->fPath) { |
473 SkPath* path = SkNEW(SkPath); | 509 SkPath* path = SkNEW(SkPath); |
474 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { | 510 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { |
475 // flag the glyph as being dead? | 511 // flag the glyph as being dead? |
476 delete path; | 512 delete path; |
477 return; | 513 return true; |
478 } | 514 } |
479 glyph->fPath = path; | 515 glyph->fPath = path; |
480 } | 516 } |
481 | 517 |
482 // flush any accumulated draws before drawing this glyph as a path. | 518 // flush any accumulated draws before drawing this glyph as a path. |
483 this->flush(); | 519 this->flush(); |
484 | 520 |
485 GrContext::AutoMatrix am; | 521 GrContext::AutoMatrix am; |
486 SkMatrix ctm; | 522 SkMatrix ctm; |
487 ctm.setScale(fTextRatio, fTextRatio); | 523 ctm.setScale(fTextRatio, fTextRatio); |
488 ctm.postTranslate(sx, sy); | 524 ctm.postTranslate(sx, sy); |
489 GrPaint tmpPaint(fPaint); | 525 GrPaint tmpPaint(fPaint); |
490 am.setPreConcat(fContext, ctm, &tmpPaint); | 526 am.setPreConcat(fContext, ctm, &tmpPaint); |
491 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 527 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
492 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); | 528 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); |
493 return; | 529 return true; |
494 } | 530 } |
495 | 531 |
496 HAS_ATLAS: | 532 HAS_ATLAS: |
497 SkASSERT(glyph->fPlot); | 533 SkASSERT(glyph->fPlot); |
498 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 534 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
499 glyph->fPlot->setDrawToken(drawToken); | 535 glyph->fPlot->setDrawToken(drawToken); |
500 | 536 |
501 GrTexture* texture = glyph->fPlot->texture(); | 537 GrTexture* texture = glyph->fPlot->texture(); |
502 SkASSERT(texture); | 538 SkASSERT(texture); |
503 | 539 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 } | 635 } |
600 // color comes after position. | 636 // color comes after position. |
601 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); | 637 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); |
602 for (int i = 0; i < 4; ++i) { | 638 for (int i = 0; i < 4; ++i) { |
603 *colors = fPaint.getColor(); | 639 *colors = fPaint.getColor(); |
604 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize); | 640 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize); |
605 } | 641 } |
606 } | 642 } |
607 | 643 |
608 fCurrVertex += 4; | 644 fCurrVertex += 4; |
645 | |
646 return true; | |
609 } | 647 } |
610 | 648 |
611 void GrDistanceFieldTextContext::flush() { | 649 void GrDistanceFieldTextContext::flush() { |
612 if (NULL == fDrawTarget) { | 650 if (NULL == fDrawTarget) { |
613 return; | 651 return; |
614 } | 652 } |
615 | 653 |
616 GrDrawState* drawState = fDrawTarget->drawState(); | 654 GrDrawState* drawState = fDrawTarget->drawState(); |
617 GrDrawState::AutoRestoreEffects are(drawState); | 655 GrDrawState::AutoRestoreEffects are(drawState); |
618 | 656 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 fVertexBounds.setLargestInverted(); | 711 fVertexBounds.setLargestInverted(); |
674 } | 712 } |
675 } | 713 } |
676 | 714 |
677 inline void GrDistanceFieldTextContext::finish() { | 715 inline void GrDistanceFieldTextContext::finish() { |
678 this->flush(); | 716 this->flush(); |
679 | 717 |
680 GrTextContext::finish(); | 718 GrTextContext::finish(); |
681 } | 719 } |
682 | 720 |
OLD | NEW |