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