OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkScalerContext.h" | 10 #include "SkScalerContext.h" |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 glyph->fTop = ir.fTop; | 330 glyph->fTop = ir.fTop; |
331 glyph->fWidth = SkToU16(ir.width()); | 331 glyph->fWidth = SkToU16(ir.width()); |
332 glyph->fHeight = SkToU16(ir.height()); | 332 glyph->fHeight = SkToU16(ir.height()); |
333 } | 333 } |
334 } | 334 } |
335 | 335 |
336 if (SkMask::kARGB32_Format != glyph->fMaskFormat) { | 336 if (SkMask::kARGB32_Format != glyph->fMaskFormat) { |
337 glyph->fMaskFormat = fRec.fMaskFormat; | 337 glyph->fMaskFormat = fRec.fMaskFormat; |
338 } | 338 } |
339 | 339 |
| 340 // If we are going to create the mask, then we cannot keep the color |
| 341 if ((fGenerateImageFromPath || fMaskFilter) && |
| 342 SkMask::kARGB32_Format == glyph->fMaskFormat) { |
| 343 glyph->fMaskFormat = SkMask::kA8_Format; |
| 344 } |
| 345 |
340 if (fMaskFilter) { | 346 if (fMaskFilter) { |
341 SkMask src, dst; | 347 SkMask src, dst; |
342 SkMatrix matrix; | 348 SkMatrix matrix; |
343 | 349 |
344 glyph->toMask(&src); | 350 glyph->toMask(&src); |
345 fRec.getMatrixFrom2x2(&matrix); | 351 fRec.getMatrixFrom2x2(&matrix); |
346 | 352 |
347 src.fImage = NULL; // only want the bounds from the filter | 353 src.fImage = NULL; // only want the bounds from the filter |
348 if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) { | 354 if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) { |
349 if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) { | 355 if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 pack3xHToLCD32<true>(bm, mask, maskPreBlend); | 514 pack3xHToLCD32<true>(bm, mask, maskPreBlend); |
509 } else { | 515 } else { |
510 pack3xHToLCD32<false>(bm, mask, maskPreBlend); | 516 pack3xHToLCD32<false>(bm, mask, maskPreBlend); |
511 } | 517 } |
512 break; | 518 break; |
513 default: | 519 default: |
514 break; | 520 break; |
515 } | 521 } |
516 } | 522 } |
517 | 523 |
| 524 static void extract_alpha(const SkMask& dst, |
| 525 const SkPMColor* srcRow, size_t srcRB) { |
| 526 int width = dst.fBounds.width(); |
| 527 int height = dst.fBounds.height(); |
| 528 int dstRB = dst.fRowBytes; |
| 529 uint8_t* dstRow = dst.fImage; |
| 530 |
| 531 for (int y = 0; y < height; ++y) { |
| 532 for (int x = 0; x < width; ++x) { |
| 533 dstRow[x] = SkGetPackedA32(srcRow[x]); |
| 534 } |
| 535 // zero any padding on each row |
| 536 for (int x = width; x < dstRB; ++x) { |
| 537 dstRow[x] = 0; |
| 538 } |
| 539 dstRow += dstRB; |
| 540 srcRow = (const SkPMColor*)((const char*)srcRow + srcRB); |
| 541 } |
| 542 } |
| 543 |
518 void SkScalerContext::getImage(const SkGlyph& origGlyph) { | 544 void SkScalerContext::getImage(const SkGlyph& origGlyph) { |
519 const SkGlyph* glyph = &origGlyph; | 545 const SkGlyph* glyph = &origGlyph; |
520 SkGlyph tmpGlyph; | 546 SkGlyph tmpGlyph; |
521 | 547 |
| 548 // in case we need to call generateImage on a mask-format that is different |
| 549 // (i.e. larger) than what our caller allocated by looking at origGlyph. |
| 550 SkAutoMalloc tmpGlyphImageStorage; |
| 551 |
| 552 // If we are going to draw-from-path, then we cannot generate color, since |
| 553 // the path only makes a mask. This case should have been caught up in |
| 554 // generateMetrics(). |
| 555 SkASSERT(!fGenerateImageFromPath || |
| 556 SkMask::kARGB32_Format != origGlyph.fMaskFormat); |
| 557 |
522 if (fMaskFilter) { // restore the prefilter bounds | 558 if (fMaskFilter) { // restore the prefilter bounds |
523 tmpGlyph.init(origGlyph.fID); | 559 tmpGlyph.init(origGlyph.fID); |
524 | 560 |
525 // need the original bounds, sans our maskfilter | 561 // need the original bounds, sans our maskfilter |
526 SkMaskFilter* mf = fMaskFilter; | 562 SkMaskFilter* mf = fMaskFilter; |
527 fMaskFilter = NULL; // temp disable | 563 fMaskFilter = NULL; // temp disable |
528 this->getMetrics(&tmpGlyph); | 564 this->getMetrics(&tmpGlyph); |
529 fMaskFilter = mf; // restore | 565 fMaskFilter = mf; // restore |
530 | 566 |
531 tmpGlyph.fImage = origGlyph.fImage; | |
532 | |
533 // we need the prefilter bounds to be <= filter bounds | 567 // we need the prefilter bounds to be <= filter bounds |
534 SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); | 568 SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); |
535 SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); | 569 SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); |
| 570 |
| 571 if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { |
| 572 tmpGlyph.fImage = origGlyph.fImage; |
| 573 } else { |
| 574 tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); |
| 575 tmpGlyph.fImage = tmpGlyphImageStorage.get(); |
| 576 } |
536 glyph = &tmpGlyph; | 577 glyph = &tmpGlyph; |
537 } | 578 } |
538 | 579 |
539 if (fGenerateImageFromPath) { | 580 if (fGenerateImageFromPath) { |
540 SkPath devPath, fillPath; | 581 SkPath devPath, fillPath; |
541 SkMatrix fillToDevMatrix; | 582 SkMatrix fillToDevMatrix; |
542 SkMask mask; | 583 SkMask mask; |
543 | 584 |
544 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); | 585 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); |
545 glyph->toMask(&mask); | 586 glyph->toMask(&mask); |
546 | 587 |
547 if (fRasterizer) { | 588 if (fRasterizer) { |
548 mask.fFormat = SkMask::kA8_Format; | 589 mask.fFormat = SkMask::kA8_Format; |
549 sk_bzero(glyph->fImage, mask.computeImageSize()); | 590 sk_bzero(glyph->fImage, mask.computeImageSize()); |
550 | 591 |
551 if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL, | 592 if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL, |
552 fMaskFilter, &mask, | 593 fMaskFilter, &mask, |
553 SkMask::kJustRenderImage_CreateMode)) { | 594 SkMask::kJustRenderImage_CreateMode)) { |
554 return; | 595 return; |
555 } | 596 } |
556 if (fPreBlend.isApplicable()) { | 597 if (fPreBlend.isApplicable()) { |
557 applyLUTToA8Mask(mask, fPreBlend.fG); | 598 applyLUTToA8Mask(mask, fPreBlend.fG); |
558 } | 599 } |
559 } else { | 600 } else { |
| 601 SkASSERT(SkMask::kARGB32_Format != mask.fFormat); |
560 generateMask(mask, devPath, fPreBlend); | 602 generateMask(mask, devPath, fPreBlend); |
561 } | 603 } |
562 } else { | 604 } else { |
563 this->getGlyphContext(*glyph)->generateImage(*glyph); | 605 this->getGlyphContext(*glyph)->generateImage(*glyph); |
564 } | 606 } |
565 | 607 |
566 if (fMaskFilter) { | 608 if (fMaskFilter) { |
567 SkMask srcM, dstM; | 609 SkMask srcM, dstM; |
568 SkMatrix matrix; | 610 SkMatrix matrix; |
569 | 611 |
570 // the src glyph image shouldn't be 3D | 612 // the src glyph image shouldn't be 3D |
571 SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); | 613 SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); |
| 614 |
| 615 SkAutoSMalloc<32*32> a8storage; |
572 glyph->toMask(&srcM); | 616 glyph->toMask(&srcM); |
| 617 if (SkMask::kARGB32_Format == srcM.fFormat) { |
| 618 // now we need to extract the alpha-channel from the glyph's image |
| 619 // and copy it into a temp buffer, and then point srcM at that temp. |
| 620 srcM.fFormat = SkMask::kA8_Format; |
| 621 srcM.fRowBytes = SkAlign4(srcM.fBounds.width()); |
| 622 size_t size = srcM.computeImageSize(); |
| 623 a8storage.reset(size); |
| 624 srcM.fImage = (uint8_t*)a8storage.get(); |
| 625 extract_alpha(srcM, |
| 626 (const SkPMColor*)glyph->fImage, glyph->rowBytes()); |
| 627 } |
| 628 |
573 fRec.getMatrixFrom2x2(&matrix); | 629 fRec.getMatrixFrom2x2(&matrix); |
574 | 630 |
575 if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) { | 631 if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) { |
576 int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width()); | 632 int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width()); |
577 int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height()); | 633 int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height()); |
578 int dstRB = origGlyph.rowBytes(); | 634 int dstRB = origGlyph.rowBytes(); |
579 int srcRB = dstM.fRowBytes; | 635 int srcRB = dstM.fRowBytes; |
580 | 636 |
581 const uint8_t* src = (const uint8_t*)dstM.fImage; | 637 const uint8_t* src = (const uint8_t*)dstM.fImage; |
582 uint8_t* dst = (uint8_t*)origGlyph.fImage; | 638 uint8_t* dst = (uint8_t*)origGlyph.fImage; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 SkScalerContext* c = NULL; //SkCreateColorScalerContext(desc); | 841 SkScalerContext* c = NULL; //SkCreateColorScalerContext(desc); |
786 if (NULL == c) { | 842 if (NULL == c) { |
787 c = this->onCreateScalerContext(desc); | 843 c = this->onCreateScalerContext(desc); |
788 } | 844 } |
789 if (NULL == c) { | 845 if (NULL == c) { |
790 c = SkNEW_ARGS(SkScalerContext_Empty, | 846 c = SkNEW_ARGS(SkScalerContext_Empty, |
791 (const_cast<SkTypeface*>(this), desc)); | 847 (const_cast<SkTypeface*>(this), desc)); |
792 } | 848 } |
793 return c; | 849 return c; |
794 } | 850 } |
OLD | NEW |