diff options
-rw-r--r-- | include/core/SkColorPriv.h | 15 | ||||
-rw-r--r-- | include/core/SkTDArray.h | 11 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 41 | ||||
-rw-r--r-- | src/core/SkScan_Path.cpp | 6 |
4 files changed, 70 insertions, 3 deletions
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h index 7658d5b..5129ac6 100644 --- a/include/core/SkColorPriv.h +++ b/include/core/SkColorPriv.h @@ -393,6 +393,21 @@ inline SkPMColor SkPixel16ToPixel32(U16CPU src) return SkPackARGB32(0xFF, r, g, b); } +// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor +static inline SkColor SkPixel16ToColor(U16CPU src) { + SkASSERT(src == SkToU16(src)); + + unsigned r = SkPacked16ToR32(src); + unsigned g = SkPacked16ToG32(src); + unsigned b = SkPacked16ToB32(src); + + SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); + SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); + SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); + + return SkColorSetRGB(r, g, b); +} + /////////////////////////////////////////////////////////////////////////////// typedef uint16_t SkPMColor16; diff --git a/include/core/SkTDArray.h b/include/core/SkTDArray.h index 5f6bbd8..954bcf8 100644 --- a/include/core/SkTDArray.h +++ b/include/core/SkTDArray.h @@ -86,6 +86,17 @@ public: SkTSwap(fCount, other.fCount); } + /** Return a ptr to the array of data, to be freed with sk_free. This also + resets the SkTDArray to be empty. + */ + T* detach() { + T* array = fArray; + fArray = NULL; + fReserve = fCount = 0; + SkDEBUGCODE(fData = NULL;) + return array; + } + bool isEmpty() const { return fCount == 0; } int count() const { return fCount; } T* begin() const { return fArray; } diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 353388b..cb4d129 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -207,14 +207,51 @@ void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { /////////////////////////////////////////////////////////////////////////////// +#include "SkUnPreMultiply.h" +#include "SkColorShader.h" + +// returns true and set color if the bitmap can be drawn as a single color +// (for efficiency) +static bool canUseColorShader(const SkBitmap& bm, SkColor* color) { + if (1 != bm.width() || 1 != bm.height()) { + return false; + } + + SkAutoLockPixels alp(bm); + if (!bm.readyToDraw()) { + return false; + } + + switch (bm.config()) { + case SkBitmap::kARGB_8888_Config: + *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0)); + return true; + case SkBitmap::kRGB_565_Config: + *color = SkPixel16ToColor(*bm.getAddr16(0, 0)); + return true; + case SkBitmap::kIndex8_Config: + *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0)); + return true; + default: // just skip the other configs for now + break; + } + return false; +} + #include "SkTemplatesPriv.h" SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, void* storage, size_t storageSize) { SkShader* shader; - SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, - storageSize, (src, tmx, tmy)); + SkColor color; + if (canUseColorShader(src, &color)) { + SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize, + (color)); + } else { + SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, + storageSize, (src, tmx, tmy)); + } return shader; } diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index 211259f..636478d 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -383,7 +383,11 @@ extern "C" { valuea = edgea->fX; valueb = edgeb->fX; } - return valuea - valueb; + + // this overflows if valuea >>> valueb or vice-versa + // return valuea - valueb; + // do perform the slower but safe compares + return (valuea < valueb) ? -1 : (valuea > valueb); } } |