Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/core/SkScalerContext.cpp

Issue 14637007: Detect color masks, and divert to draw-sprite instead of maskblitters (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/core/SkDrawProcs.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkDrawProcs.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698