diff options
-rw-r--r-- | samplecode/SampleLayerMask.cpp | 73 | ||||
-rw-r--r-- | src/core/SkBitmap.cpp | 18 | ||||
-rw-r--r-- | tests/BitmapCopyTest.cpp | 25 | ||||
-rw-r--r-- | xcode/core/core.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj | 4 |
5 files changed, 126 insertions, 2 deletions
diff --git a/samplecode/SampleLayerMask.cpp b/samplecode/SampleLayerMask.cpp new file mode 100644 index 0000000000..8cbe76d340 --- /dev/null +++ b/samplecode/SampleLayerMask.cpp @@ -0,0 +1,73 @@ +#include "SampleCode.h" +#include "SkCanvas.h" +#include "SkPaint.h" +#include "SkPorterDuff.h" +#include "SkView.h" + +/////////////////////////////////////////////////////////////////////////////// + +class LayerMaskView : public SkView { +public: + LayerMaskView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "LayerMask"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + void drawMask(SkCanvas* canvas, const SkRect& r) { + SkPaint paint; + paint.setAntiAlias(true); + + if (true) { + SkBitmap mask; + int w = SkScalarRound(r.width()); + int h = SkScalarRound(r.height()); + mask.setConfig(SkBitmap::kARGB_8888_Config, w, h); + mask.allocPixels(); + mask.eraseColor(0); + SkCanvas c(mask); + SkRect bounds = r; + bounds.offset(-bounds.fLeft, -bounds.fTop); + c.drawOval(bounds, paint); + + paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); + canvas->drawBitmap(mask, r.fLeft, r.fTop, &paint); + } else { + SkPath p; + p.addOval(r); + p.setFillType(SkPath::kInverseWinding_FillType); + paint.setPorterDuffXfermode(SkPorterDuff::kDstOut_Mode); + canvas->drawPath(p, paint); + } + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(0xFFDDDDDD); + } + + virtual void onDraw(SkCanvas* canvas) { + this->drawBG(canvas); + + SkRect r; + r.set(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(120), SkIntToScalar(120)); + canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); + canvas->drawColor(SK_ColorRED); + drawMask(canvas, r); + canvas->restore(); + } + +private: + typedef SkView INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new LayerMaskView; } +static SkViewRegister reg(MyFactory); + diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 3debd81dc7..2765fab194 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -710,6 +710,9 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { return false; } + // we lock this now, since we may need its colortable + SkAutoLockPixels srclock(*this); + SkBitmap tmp; tmp.setConfig(dstConfig, this->width(), this->height()); @@ -721,7 +724,6 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { return false; } - SkAutoLockPixels srclock(*this); SkAutoLockPixels dstlock(tmp); if (!this->readyToDraw() || !tmp.readyToDraw()) { @@ -733,7 +735,19 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { re-draw for the !sameConfigs cases */ if (sameConfigs) { - memcpy(tmp.getPixels(), this->getPixels(), this->getSize()); + if (tmp.getSize() == this->getSize()) { + memcpy(tmp.getPixels(), this->getPixels(), this->getSize()); + } else { + const char* srcP = reinterpret_cast<const char*>(this->getPixels()); + char* dstP = reinterpret_cast<char*>(tmp.getPixels()); + // to be sure we don't read too much, only copy our logical pixels + size_t bytesToCopy = tmp.width() * tmp.bytesPerPixel(); + for (int y = 0; y < tmp.height(); y++) { + memcpy(dstP, srcP, bytesToCopy); + srcP += this->rowBytes(); + dstP += tmp.rowBytes(); + } + } } else { // if the src has alpha, we have to clear the dst first if (!this->isOpaque()) { diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp index f904859156..95b49ce4a0 100644 --- a/tests/BitmapCopyTest.cpp +++ b/tests/BitmapCopyTest.cpp @@ -1,5 +1,6 @@ #include "Test.h" #include "SkBitmap.h" +#include "SkRect.h" static const char* boolStr(bool value) { return value ? "true" : "false"; @@ -82,6 +83,30 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, !memcmp(srcP, dstP, src.getSize())); } + // test extractSubset + { + SkBitmap subset; + SkIRect r; + r.set(1, 1, 2, 2); + if (src.extractSubset(&subset, r)) { + REPORTER_ASSERT(reporter, subset.width() == 1); + REPORTER_ASSERT(reporter, subset.height() == 1); + + SkBitmap copy; + REPORTER_ASSERT(reporter, + subset.copyTo(©, subset.config())); + REPORTER_ASSERT(reporter, copy.width() == 1); + REPORTER_ASSERT(reporter, copy.height() == 1); + REPORTER_ASSERT(reporter, copy.rowBytes() <= 4); + + SkAutoLockPixels alp0(subset); + SkAutoLockPixels alp1(copy); + // they should both have, or both not-have, a colortable + bool hasCT = subset.getColorTable() != NULL; + REPORTER_ASSERT(reporter, + (copy.getColorTable() != NULL) == hasCT); + } + } } else { // dst should be unchanged from its initial state REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config); diff --git a/xcode/core/core.xcodeproj/project.pbxproj b/xcode/core/core.xcodeproj/project.pbxproj index e4d0ca93f4..c4c1630e90 100644 --- a/xcode/core/core.xcodeproj/project.pbxproj +++ b/xcode/core/core.xcodeproj/project.pbxproj @@ -262,9 +262,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 009490660FB0AC280063C792 /* opengl */ = { + isa = PBXGroup; + children = ( + ); + name = opengl; + sourceTree = "<group>"; + }; 08FB7794FE84155DC02AAC07 /* core */ = { isa = PBXGroup; children = ( + 009490660FB0AC280063C792 /* opengl */, 08FB7795FE84155DC02AAC07 /* src */, C6A0FF2B0290797F04C91782 /* Documentation */, 1AB674ADFE9D54B511CA2CBB /* Products */, diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj index 3a3a581923..bd185174b7 100644 --- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj +++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj @@ -66,6 +66,7 @@ 007A7CC10F01658C00A2D6EE /* SampleXfermodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007A7CB20F01658C00A2D6EE /* SampleXfermodes.cpp */; }; 007C785E0F3B4C230004B142 /* SamplePathClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007C785D0F3B4C230004B142 /* SamplePathClip.cpp */; }; 008C4D980F77DAEE0056981C /* SampleHairline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008C4D970F77DAEE0056981C /* SampleHairline.cpp */; }; + 009490320FB0A5B90063C792 /* SampleLayerMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009490310FB0A5B90063C792 /* SampleLayerMask.cpp */; }; 009CC9190F65918A002185BE /* SampleFontScalerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009CC9180F65918A002185BE /* SampleFontScalerTest.cpp */; }; 00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; }; 00C55DA10F8552DC000CAC09 /* SampleGradients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00C55DA00F8552DC000CAC09 /* SampleGradients.cpp */; }; @@ -183,6 +184,7 @@ 007A7CB20F01658C00A2D6EE /* SampleXfermodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleXfermodes.cpp; path = ../../samplecode/SampleXfermodes.cpp; sourceTree = SOURCE_ROOT; }; 007C785D0F3B4C230004B142 /* SamplePathClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePathClip.cpp; path = ../../samplecode/SamplePathClip.cpp; sourceTree = SOURCE_ROOT; }; 008C4D970F77DAEE0056981C /* SampleHairline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleHairline.cpp; path = ../../samplecode/SampleHairline.cpp; sourceTree = SOURCE_ROOT; }; + 009490310FB0A5B90063C792 /* SampleLayerMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleLayerMask.cpp; path = ../../samplecode/SampleLayerMask.cpp; sourceTree = SOURCE_ROOT; }; 009CC9180F65918A002185BE /* SampleFontScalerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFontScalerTest.cpp; path = ../../samplecode/SampleFontScalerTest.cpp; sourceTree = SOURCE_ROOT; }; 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleArc.cpp; path = ../../samplecode/SampleArc.cpp; sourceTree = SOURCE_ROOT; }; 00C55DA00F8552DC000CAC09 /* SampleGradients.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleGradients.cpp; path = ../../samplecode/SampleGradients.cpp; sourceTree = SOURCE_ROOT; }; @@ -222,6 +224,7 @@ 007A7CA40F01658C00A2D6EE /* SamplePicture.cpp */, 00D6B5CB0F72DC4300C466B9 /* SampleFuzz.cpp */, 00C55DA00F8552DC000CAC09 /* SampleGradients.cpp */, + 009490310FB0A5B90063C792 /* SampleLayerMask.cpp */, 009CC9180F65918A002185BE /* SampleFontScalerTest.cpp */, 007A7CA50F01658C00A2D6EE /* SamplePoints.cpp */, 007A7CA70F01658C00A2D6EE /* SampleRegion.cpp */, @@ -525,6 +528,7 @@ 0041CE440F00A12400695E8C /* SampleLines.cpp in Sources */, 008C4D980F77DAEE0056981C /* SampleHairline.cpp in Sources */, 00C55DA10F8552DC000CAC09 /* SampleGradients.cpp in Sources */, + 009490320FB0A5B90063C792 /* SampleLayerMask.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |