special case 1x1 bitmaps when drawn as a shader (treat as a solid color)

git-svn-id: http://skia.googlecode.com/svn/trunk@336 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@android.com 2009-08-25 19:15:31 +00:00
parent 593847a0e0
commit c64599649b
4 changed files with 152 additions and 2 deletions

View File

@ -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;

View File

@ -4,6 +4,22 @@
#include "SkCanvas.h"
#include "SkUtils.h"
static void test_pathregion() {
SkPath path;
SkRegion region;
path.moveTo(25071800.f, -141823808.f);
path.lineTo(25075500.f, -141824000.f);
path.lineTo(25075400.f, -141827712.f);
path.lineTo(25071810.f, -141827600.f);
path.close();
SkIRect bounds;
path.getBounds().round(&bounds);
SkRegion clip(bounds);
bool result = region.setPath(path, clip); // <-- !! DOWN !!
SkDebugf("----- result %d\n", result);
}
static SkBitmap make_bitmap() {
SkBitmap bm;
SkColorTable* ctable = new SkColorTable(256);
@ -33,6 +49,7 @@ class DitherBitmapView : public SkView {
SkBitmap fBM32;
public:
DitherBitmapView() {
test_pathregion();
fBM8 = make_bitmap();
fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config);
}

View File

@ -0,0 +1,81 @@
#include "SampleCode.h"
#include "SkColorPriv.h"
#include "SkShader.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkUtils.h"
static SkBitmap make_bitmap() {
SkBitmap bm;
const int N = 1;
SkColorTable* ctable = new SkColorTable(N);
SkPMColor* c = ctable->lockColors();
for (int i = 0; i < N; i++) {
c[i] = SkPackARGB32(0x80, 0x80, 0, 0);
}
ctable->unlockColors(true);
bm.setConfig(SkBitmap::kIndex8_Config, 1, 1);
bm.allocPixels(ctable);
ctable->unref();
bm.lockPixels();
for (int y = 0; y < bm.height(); y++) {
uint8_t* p = bm.getAddr8(0, y);
for (int x = 0; x < bm.width(); x++) {
p[x] = 0;
}
}
bm.unlockPixels();
return bm;
}
class TinyBitmapView : public SkView {
SkBitmap fBM;
public:
TinyBitmapView() {
fBM = make_bitmap();
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "TinyBitmap");
return true;
}
return this->INHERITED::onQuery(evt);
}
void drawBG(SkCanvas* canvas) {
canvas->drawColor(0xFFDDDDDD);
}
static void setBitmapOpaque(SkBitmap* bm, bool isOpaque) {
SkAutoLockPixels alp(*bm); // needed for ctable
bm->setIsOpaque(isOpaque);
SkColorTable* ctable = bm->getColorTable();
if (ctable) {
ctable->setIsOpaque(isOpaque);
}
}
virtual void onDraw(SkCanvas* canvas) {
drawBG(canvas);
SkShader* s = SkShader::CreateBitmapShader(fBM, SkShader::kRepeat_TileMode,
SkShader::kMirror_TileMode);
SkPaint paint;
paint.setShader(s)->unref();
canvas->drawPaint(paint);
}
private:
typedef SkView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new TinyBitmapView; }
static SkViewRegister reg(MyFactory);

View File

@ -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;
}