Chromium Code Reviews| 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 |