OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 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 "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 if (!bm.requestLock(&result)) { | 659 if (!bm.requestLock(&result)) { |
660 return false; | 660 return false; |
661 } | 661 } |
662 return compute_is_opaque(result.pixmap()); | 662 return compute_is_opaque(result.pixmap()); |
663 } | 663 } |
664 | 664 |
665 | 665 |
666 /////////////////////////////////////////////////////////////////////////////// | 666 /////////////////////////////////////////////////////////////////////////////// |
667 /////////////////////////////////////////////////////////////////////////////// | 667 /////////////////////////////////////////////////////////////////////////////// |
668 | 668 |
669 static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b
) { | 669 void SkBitmap::erase(SkColor c, const SkIRect& area) const { |
670 unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) | | |
671 (SkR32To4444(r) << SK_R4444_SHIFT) | | |
672 (SkG32To4444(g) << SK_G4444_SHIFT) | | |
673 (SkB32To4444(b) << SK_B4444_SHIFT); | |
674 return SkToU16(pixel); | |
675 } | |
676 | |
677 static bool internal_erase(const SkPixmap& pmap, const SkIRect& area, | |
678 U8CPU a, U8CPU r, U8CPU g, U8CPU b) { | |
679 int height = area.height(); | |
680 const int width = area.width(); | |
681 const int rowBytes = pmap.rowBytes(); | |
682 | |
683 switch (pmap.colorType()) { | |
684 case kGray_8_SkColorType: { | |
685 if (255 != a) { | |
686 r = SkMulDiv255Round(r, a); | |
687 g = SkMulDiv255Round(g, a); | |
688 b = SkMulDiv255Round(b, a); | |
689 } | |
690 int gray = SkComputeLuminance(r, g, b); | |
691 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop); | |
692 while (--height >= 0) { | |
693 memset(p, gray, width); | |
694 p += rowBytes; | |
695 } | |
696 break; | |
697 } | |
698 case kAlpha_8_SkColorType: { | |
699 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop); | |
700 while (--height >= 0) { | |
701 memset(p, a, width); | |
702 p += rowBytes; | |
703 } | |
704 break; | |
705 } | |
706 case kARGB_4444_SkColorType: | |
707 case kRGB_565_SkColorType: { | |
708 uint16_t* p = pmap.writable_addr16(area.fLeft, area.fTop); | |
709 uint16_t v; | |
710 | |
711 // make rgb premultiplied | |
712 if (255 != a) { | |
713 r = SkAlphaMul(r, a); | |
714 g = SkAlphaMul(g, a); | |
715 b = SkAlphaMul(b, a); | |
716 } | |
717 | |
718 if (kARGB_4444_SkColorType == pmap.colorType()) { | |
719 v = pack_8888_to_4444(a, r, g, b); | |
720 } else { | |
721 v = SkPackRGB16(r >> (8 - SK_R16_BITS), | |
722 g >> (8 - SK_G16_BITS), | |
723 b >> (8 - SK_B16_BITS)); | |
724 } | |
725 while (--height >= 0) { | |
726 sk_memset16(p, v, width); | |
727 p = (uint16_t*)((char*)p + rowBytes); | |
728 } | |
729 break; | |
730 } | |
731 case kBGRA_8888_SkColorType: | |
732 case kRGBA_8888_SkColorType: { | |
733 uint32_t* p = pmap.writable_addr32(area.fLeft, area.fTop); | |
734 | |
735 if (255 != a && kPremul_SkAlphaType == pmap.alphaType()) { | |
736 r = SkAlphaMul(r, a); | |
737 g = SkAlphaMul(g, a); | |
738 b = SkAlphaMul(b, a); | |
739 } | |
740 uint32_t v = kRGBA_8888_SkColorType == pmap.colorType() ? | |
741 SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b); | |
742 | |
743 while (--height >= 0) { | |
744 sk_memset32(p, v, width); | |
745 p = (uint32_t*)((char*)p + rowBytes); | |
746 } | |
747 break; | |
748 } | |
749 default: | |
750 return false; // no change, so don't call notifyPixelsChanged() | |
751 } | |
752 return true; | |
753 } | |
754 | |
755 void SkBitmap::internalErase(const SkIRect& area, U8CPU a, U8CPU r, U8CPU g, U8C
PU b) const { | |
756 #ifdef SK_DEBUG | |
757 SkDEBUGCODE(this->validate();) | 670 SkDEBUGCODE(this->validate();) |
758 SkASSERT(!area.isEmpty()); | |
759 { | |
760 SkIRect total = { 0, 0, this->width(), this->height() }; | |
761 SkASSERT(total.contains(area)); | |
762 } | |
763 #endif | |
764 | 671 |
765 switch (fInfo.colorType()) { | 672 switch (fInfo.colorType()) { |
766 case kUnknown_SkColorType: | 673 case kUnknown_SkColorType: |
767 case kIndex_8_SkColorType: | 674 case kIndex_8_SkColorType: |
768 // TODO: can we ASSERT that we never get here? | 675 // TODO: can we ASSERT that we never get here? |
769 return; // can't erase. Should we bzero so the memory is not uniniti
alized? | 676 return; // can't erase. Should we bzero so the memory is not uniniti
alized? |
770 default: | 677 default: |
771 break; | 678 break; |
772 } | 679 } |
773 | 680 |
774 SkAutoPixmapUnlock result; | 681 SkAutoPixmapUnlock result; |
775 if (!this->requestLock(&result)) { | 682 if (!this->requestLock(&result)) { |
776 return; | 683 return; |
777 } | 684 } |
778 | 685 |
779 if (internal_erase(result.pixmap(), area, a, r, g, b)) { | 686 if (result.pixmap().erase(c, area)) { |
780 this->notifyPixelsChanged(); | 687 this->notifyPixelsChanged(); |
781 } | 688 } |
782 } | 689 } |
783 | 690 |
784 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { | 691 void SkBitmap::eraseColor(SkColor c) const { |
785 SkIRect area = { 0, 0, this->width(), this->height() }; | 692 this->erase(c, SkIRect::MakeWH(this->width(), this->height())); |
786 if (!area.isEmpty()) { | |
787 this->internalErase(area, a, r, g, b); | |
788 } | |
789 } | |
790 | |
791 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { | |
792 SkIRect area = { 0, 0, this->width(), this->height() }; | |
793 if (area.intersect(rect)) { | |
794 this->internalErase(area, SkColorGetA(c), SkColorGetR(c), | |
795 SkColorGetG(c), SkColorGetB(c)); | |
796 } | |
797 } | 693 } |
798 | 694 |
799 ////////////////////////////////////////////////////////////////////////////////
////// | 695 ////////////////////////////////////////////////////////////////////////////////
////// |
800 ////////////////////////////////////////////////////////////////////////////////
////// | 696 ////////////////////////////////////////////////////////////////////////////////
////// |
801 | 697 |
802 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { | 698 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { |
803 SkDEBUGCODE(this->validate();) | 699 SkDEBUGCODE(this->validate();) |
804 | 700 |
805 if (NULL == result || NULL == fPixelRef) { | 701 if (NULL == result || NULL == fPixelRef) { |
806 return false; // no src pixels | 702 return false; // no src pixels |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 /////////////////////////////////////////////////////////////////////////////// | 1297 /////////////////////////////////////////////////////////////////////////////// |
1402 | 1298 |
1403 #ifdef SK_DEBUG | 1299 #ifdef SK_DEBUG |
1404 void SkImageInfo::validate() const { | 1300 void SkImageInfo::validate() const { |
1405 SkASSERT(fWidth >= 0); | 1301 SkASSERT(fWidth >= 0); |
1406 SkASSERT(fHeight >= 0); | 1302 SkASSERT(fHeight >= 0); |
1407 SkASSERT(SkColorTypeIsValid(fColorType)); | 1303 SkASSERT(SkColorTypeIsValid(fColorType)); |
1408 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | 1304 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
1409 } | 1305 } |
1410 #endif | 1306 #endif |
OLD | NEW |