[PDF] Honor srcRect in drawBitmap.
Review URL: http://codereview.appspot.com/4083045
git-svn-id: http://skia.googlecode.com/svn/trunk@745 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp
index 2162eae..51bf8ae 100644
--- a/src/pdf/SkPDFImage.cpp
+++ b/src/pdf/SkPDFImage.cpp
@@ -22,87 +22,91 @@
#include "SkPaint.h"
#include "SkPackBits.h"
#include "SkPDFCatalog.h"
+#include "SkRect.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkUnPreMultiply.h"
namespace {
-SkMemoryStream* extractImageData(const SkBitmap& bitmap) {
+SkMemoryStream* extractImageData(const SkBitmap& bitmap,
+ const SkIRect& srcRect) {
SkMemoryStream* result = NULL;
bitmap.lockPixels();
switch (bitmap.getConfig()) {
- case SkBitmap::kIndex8_Config:
- result = new SkMemoryStream(bitmap.getPixels(), bitmap.getSize(),
- true);
+ case SkBitmap::kIndex8_Config: {
+ const int rowBytes = srcRect.width();
+ result = new SkMemoryStream(rowBytes * srcRect.height());
+ uint8_t* dst = (uint8_t*)result->getMemoryBase();
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
+ memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes);
+ dst += rowBytes;
+ }
break;
+ }
case SkBitmap::kRLE_Index8_Config: {
- result = new SkMemoryStream(bitmap.getSize());
+ const int rowBytes = srcRect.width();
+ result = new SkMemoryStream(rowBytes * srcRect.height());
+ uint8_t* dst = (uint8_t*)result->getMemoryBase();
const SkBitmap::RLEPixels* rle =
(const SkBitmap::RLEPixels*)bitmap.getPixels();
- uint8_t* dst = (uint8_t*)result->getMemoryBase();
- const int width = bitmap.width();
- for (int y = 0; y < bitmap.height(); y++) {
- SkPackBits::Unpack8(rle->packedAtY(y), width, dst);
- dst += width;
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
+ SkPackBits::Unpack8(dst, srcRect.fLeft, rowBytes,
+ rle->packedAtY(y));
+ dst += rowBytes;
}
break;
}
case SkBitmap::kARGB_4444_Config: {
- const int width = bitmap.width();
- const int rowBytes = (width * 3 + 1) / 2;
- result = new SkMemoryStream(rowBytes * bitmap.height());
+ const int rowBytes = (srcRect.width() * 3 + 1) / 2;
+ result = new SkMemoryStream(rowBytes * srcRect.height());
uint8_t* dst = (uint8_t*)result->getMemoryBase();
- for (int y = 0; y < bitmap.height(); y++) {
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
uint16_t* src = bitmap.getAddr16(0, y);
- for (int x = 0; x < width; x += 2) {
- dst[0] = (SkGetPackedR4444(src[0]) << 4) |
- SkGetPackedG4444(src[0]);
- dst[1] = (SkGetPackedB4444(src[0]) << 4) |
- SkGetPackedR4444(src[1]);
- dst[2] = (SkGetPackedG4444(src[1]) << 4) |
- SkGetPackedB4444(src[1]);
- src += 2;
+ int x;
+ for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) {
+ dst[0] = (SkGetPackedR4444(src[x]) << 4) |
+ SkGetPackedG4444(src[x]);
+ dst[1] = (SkGetPackedB4444(src[x]) << 4) |
+ SkGetPackedR4444(src[x + 1]);
+ dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) |
+ SkGetPackedB4444(src[x + 1]);
dst += 3;
}
- if (width & 1) {
- dst[0] = (SkGetPackedR4444(src[0]) << 4) |
- SkGetPackedG4444(src[0]);
- dst[1] = (SkGetPackedB4444(src[0]) << 4);
+ if (srcRect.width() & 1) {
+ dst[0] = (SkGetPackedR4444(src[x]) << 4) |
+ SkGetPackedG4444(src[x]);
+ dst[1] = (SkGetPackedB4444(src[x]) << 4);
}
}
break;
}
case SkBitmap::kRGB_565_Config: {
- const int width = bitmap.width();
- const int rowBytes = width * 3;
- result = new SkMemoryStream(rowBytes * bitmap.height());
+ const int rowBytes = srcRect.width() * 3;
+ result = new SkMemoryStream(rowBytes * srcRect.height());
uint8_t* dst = (uint8_t*)result->getMemoryBase();
- for (int y = 0; y < bitmap.height(); y++) {
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
uint16_t* src = bitmap.getAddr16(0, y);
- for (int x = 0; x < width; x++) {
- dst[0] = SkGetPackedR16(src[0]);
- dst[1] = SkGetPackedG16(src[0]);
- dst[2] = SkGetPackedB16(src[0]);
- src++;
+ for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
+ dst[0] = SkGetPackedR16(src[x]);
+ dst[1] = SkGetPackedG16(src[x]);
+ dst[2] = SkGetPackedB16(src[x]);
dst += 3;
}
}
break;
}
case SkBitmap::kARGB_8888_Config: {
- const int width = bitmap.width();
- const int rowBytes = width * 3;
- result = new SkMemoryStream(rowBytes * bitmap.height());
+ const int rowBytes = srcRect.width() * 3;
+ result = new SkMemoryStream(rowBytes * srcRect.height());
uint8_t* dst = (uint8_t*)result->getMemoryBase();
- for (int y = 0; y < bitmap.height(); y++) {
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
uint32_t* src = bitmap.getAddr32(0, y);
- for (int x = 0; x < width; x++) {
- dst[0] = SkGetPackedR32(src[0]);
- dst[1] = SkGetPackedG32(src[0]);
- dst[2] = SkGetPackedB32(src[0]);
- src++;
+ for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
+ dst[0] = SkGetPackedR32(src[x]);
+ dst[1] = SkGetPackedG32(src[x]);
+ dst[2] = SkGetPackedB32(src[x]);
dst += 3;
}
}
@@ -149,7 +153,8 @@
}; // namespace
-SkPDFImage::SkPDFImage(const SkBitmap& bitmap, const SkPaint& paint) {
+SkPDFImage::SkPDFImage(const SkBitmap& bitmap, const SkIRect& srcRect,
+ const SkPaint& paint) {
SkBitmap::Config config = bitmap.getConfig();
// TODO(vandebo) Handle alpha and alpha only images correctly.
@@ -159,7 +164,7 @@
config == SkBitmap::kIndex8_Config ||
config == SkBitmap::kRLE_Index8_Config);
- SkMemoryStream* image_data = extractImageData(bitmap);
+ SkMemoryStream* image_data = extractImageData(bitmap, srcRect);
SkAutoUnref image_data_unref(image_data);
fStream = new SkPDFStream(image_data);
fStream->unref(); // SkRefPtr and new both took a reference.
@@ -172,11 +177,11 @@
subTypeValue->unref(); // SkRefPtr and new both took a reference.
insert("Subtype", subTypeValue.get());
- SkRefPtr<SkPDFInt> widthValue = new SkPDFInt(bitmap.width());
+ SkRefPtr<SkPDFInt> widthValue = new SkPDFInt(srcRect.width());
widthValue->unref(); // SkRefPtr and new both took a reference.
insert("Width", widthValue.get());
- SkRefPtr<SkPDFInt> heightValue = new SkPDFInt(bitmap.height());
+ SkRefPtr<SkPDFInt> heightValue = new SkPDFInt(srcRect.height());
heightValue->unref(); // SkRefPtr and new both took a reference.
insert("Height", heightValue.get());