aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2011-03-14 11:20:24 -0400
committerDerek Sollenberger <djsollen@google.com>2011-03-14 16:33:36 -0400
commit05b6b4d746867a9fb02e14edfe1bf3685abeb813 (patch)
tree34b121f598d1693c014df48ee70bffa382b0cc23 /tests
parent6210a7c68844602ee390bcce61dbb637910a3c6b (diff)
downloadexternal_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.zip
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.gz
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.bz2
Skia Merge (revision 922)
Change-Id: I7ed57d10905d8bad6486a4d7410165eec1cc2b4f
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk44
-rw-r--r--tests/BitmapCopyTest.cpp415
-rw-r--r--tests/BitmapGetColorTest.cpp36
-rw-r--r--tests/BlitRowTest.cpp3
-rw-r--r--tests/ClipCubicTest.cpp18
-rw-r--r--tests/ClipStackTest.cpp49
-rw-r--r--tests/DequeTest.cpp96
-rw-r--r--tests/FillPathTest.cpp60
-rw-r--r--tests/FlateTest.cpp107
-rw-r--r--tests/InfRectTest.cpp44
-rw-r--r--tests/MathTest.cpp47
-rw-r--r--tests/MatrixTest.cpp4
-rw-r--r--tests/PDFPrimitivesTest.cpp210
-rw-r--r--tests/PaintTest.cpp12
-rw-r--r--tests/PathTest.cpp18
-rw-r--r--tests/RefDictTest.cpp66
-rw-r--r--tests/RegionTest.cpp63
-rw-r--r--tests/StringTest.cpp37
-rw-r--r--tests/TestSize.cpp2
-rw-r--r--tests/UtilsTest.cpp66
-rw-r--r--tests/XfermodeTest.cpp30
21 files changed, 1386 insertions, 41 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index e1c03ec..a5611ee 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -3,24 +3,40 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- BlitRowTest.cpp \
- GeometryTest.cpp \
- MathTest.cpp \
- MatrixTest.cpp \
- PackBitsTest.cpp \
- Sk64Test.cpp \
- StringTest.cpp \
- Test.cpp UtilsTest.cpp \
- PathTest.cpp \
- SrcOverTest.cpp \
- StreamTest.cpp \
- SortTest.cpp \
- PathMeasureTest.cpp
+ BitmapCopyTest.cpp \
+ BitmapGetColorTest.cpp \
+ BlitRowTest.cpp \
+ ClipCubicTest.cpp \
+ ClipStackTest.cpp \
+ ClipperTest.cpp \
+ DequeTest.cpp \
+ FillPathTest.cpp \
+ FlateTest.cpp \
+ GeometryTest.cpp \
+ InfRectTest.cpp \
+ MathTest.cpp \
+ MatrixTest.cpp \
+ PackBitsTest.cpp \
+ PaintTest.cpp \
+ ParsePathTest.cpp \
+ PathMeasureTest.cpp \
+ PathTest.cpp \
+ RefDictTest.cpp \
+ RegionTest.cpp \
+ Sk64Test.cpp \
+ SortTest.cpp \
+ SrcOverTest.cpp \
+ StreamTest.cpp \
+ StringTest.cpp \
+ Test.cpp \
+ TestSize.cpp \
+ UtilsTest.cpp \
+ XfermodeTest.cpp
# The name of the file with a main function must
# match native test's naming rule: xxx_test.cpp.
LOCAL_SRC_FILES += \
- skia_test.cpp
+ skia_test.cpp
LOCAL_MODULE:= skia_test
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index be3850e..1878dfa 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -62,10 +62,14 @@ static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src,
}
}
-static void init_src(const SkBitmap& bitmap) {
+static void init_src(const SkBitmap& bitmap, const SkColorTable* ct) {
SkAutoLockPixels lock(bitmap);
if (bitmap.getPixels()) {
- memset(bitmap.getPixels(), 4, bitmap.getSize());
+ if (ct) {
+ sk_bzero(bitmap.getPixels(), bitmap.getSize());
+ } else {
+ bitmap.eraseColor(SK_ColorWHITE);
+ }
}
}
@@ -81,6 +85,151 @@ struct Pair {
const char* fValid;
};
+// Utility functions for copyPixelsTo()/copyPixelsFrom() tests.
+// getPixel()
+// setPixel()
+// getSkConfigName()
+// struct Coordinates
+// reportCopyVerification()
+// writeCoordPixels()
+
+// Utility function to read the value of a given pixel in bm. All
+// values converted to uint32_t for simplification of comparisons.
+uint32_t getPixel(int x, int y, const SkBitmap& bm) {
+ uint32_t val = 0;
+ uint16_t val16;
+ uint8_t val8, shift;
+ SkAutoLockPixels lock(bm);
+ const void* rawAddr = bm.getAddr(x,y);
+
+ switch (bm.getConfig()) {
+ case SkBitmap::kARGB_8888_Config:
+ memcpy(&val, rawAddr, sizeof(uint32_t));
+ break;
+ case SkBitmap::kARGB_4444_Config:
+ case SkBitmap::kRGB_565_Config:
+ memcpy(&val16, rawAddr, sizeof(uint16_t));
+ val = val16;
+ break;
+ case SkBitmap::kA8_Config:
+ case SkBitmap::kIndex8_Config:
+ memcpy(&val8, rawAddr, sizeof(uint8_t));
+ val = val8;
+ break;
+ case SkBitmap::kA1_Config:
+ memcpy(&val8, rawAddr, sizeof(uint8_t));
+ shift = x % 8;
+ val = (val8 >> shift) & 0x1 ;
+ break;
+ default:
+ break;
+ }
+ return val;
+}
+
+// Utility function to set value of any pixel in bm.
+// bm.getConfig() specifies what format 'val' must be
+// converted to, but at present uint32_t can handle all formats.
+void setPixel(int x, int y, uint32_t val, SkBitmap& bm) {
+ uint16_t val16;
+ uint8_t val8, shift;
+ SkAutoLockPixels lock(bm);
+ void* rawAddr = bm.getAddr(x,y);
+
+ switch (bm.getConfig()) {
+ case SkBitmap::kARGB_8888_Config:
+ memcpy(rawAddr, &val, sizeof(uint32_t));
+ break;
+ case SkBitmap::kARGB_4444_Config:
+ case SkBitmap::kRGB_565_Config:
+ val16 = val & 0xFFFF;
+ memcpy(rawAddr, &val16, sizeof(uint16_t));
+ break;
+ case SkBitmap::kA8_Config:
+ case SkBitmap::kIndex8_Config:
+ val8 = val & 0xFF;
+ memcpy(rawAddr, &val8, sizeof(uint8_t));
+ break;
+ case SkBitmap::kA1_Config:
+ shift = x % 8; // We assume we're in the right byte.
+ memcpy(&val8, rawAddr, sizeof(uint8_t));
+ if (val & 0x1) // Turn bit on.
+ val8 |= (0x1 << shift);
+ else // Turn bit off.
+ val8 &= ~(0x1 << shift);
+ memcpy(rawAddr, &val8, sizeof(uint8_t));
+ break;
+ default:
+ // Ignore.
+ break;
+ }
+}
+
+// Utility to return string containing name of each format, to
+// simplify diagnostic output.
+const char* getSkConfigName(const SkBitmap& bm) {
+ switch (bm.getConfig()) {
+ case SkBitmap::kNo_Config: return "SkBitmap::kNo_Config";
+ case SkBitmap::kA1_Config: return "SkBitmap::kA1_Config";
+ case SkBitmap::kA8_Config: return "SkBitmap::kA8_Config";
+ case SkBitmap::kIndex8_Config: return "SkBitmap::kIndex8_Config";
+ case SkBitmap::kRGB_565_Config: return "SkBitmap::kRGB_565_Config";
+ case SkBitmap::kARGB_4444_Config: return "SkBitmap::kARGB_4444_Config";
+ case SkBitmap::kARGB_8888_Config: return "SkBitmap::kARGB_8888_Config";
+ case SkBitmap::kRLE_Index8_Config:
+ return "SkBitmap::kRLE_Index8_Config,";
+ default: return "Unknown SkBitmap configuration.";
+ }
+}
+
+// Helper struct to contain pixel locations, while avoiding need for STL.
+struct Coordinates {
+
+ const int length;
+ SkIPoint* const data;
+
+ explicit Coordinates(int _length): length(_length)
+ , data(new SkIPoint[length]) { }
+
+ ~Coordinates(){
+ delete [] data;
+ }
+
+ SkIPoint* operator[](int i) const {
+ // Use with care, no bounds checking.
+ return data + i;
+ }
+};
+
+// A function to verify that two bitmaps contain the same pixel values
+// at all coordinates indicated by coords. Simplifies verification of
+// copied bitmaps.
+void reportCopyVerification(const SkBitmap& bm1, const SkBitmap& bm2,
+ Coordinates& coords,
+ const char* msg,
+ skiatest::Reporter* reporter){
+ bool success = true;
+
+ // Confirm all pixels in the list match.
+ for (int i = 0; i < coords.length; ++i)
+ success = success &&
+ (getPixel(coords[i]->fX, coords[i]->fY, bm1) ==
+ getPixel(coords[i]->fX, coords[i]->fY, bm2));
+
+ if (!success) {
+ SkString str;
+ str.printf("%s [config = %s]",
+ msg, getSkConfigName(bm1));
+ reporter->reportFailed(str);
+ }
+}
+
+// Writes unique pixel values at locations specified by coords.
+void writeCoordPixels(SkBitmap& bm, const Coordinates& coords) {
+ for (int i = 0; i < coords.length; ++i)
+ setPixel(coords[i]->fX, coords[i]->fY, i, bm);
+}
+
static void TestBitmapCopy(skiatest::Reporter* reporter) {
static const Pair gPairs[] = {
{ SkBitmap::kNo_Config, "00000000" },
@@ -94,6 +243,10 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
// { SkBitmap::kRLE_Index8_Config, "00101111" }
};
+ static const bool isExtracted[] = {
+ false, true
+ };
+
const int W = 20;
const int H = 33;
@@ -110,7 +263,7 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
src.allocPixels(ct);
SkSafeUnref(ct);
- init_src(src);
+ init_src(src, ct);
bool success = src.copyTo(&dst, gPairs[j].fConfig);
bool expected = gPairs[i].fValid[j] != '0';
if (success != expected) {
@@ -120,7 +273,7 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
boolStr(success));
reporter->reportFailed(str);
}
-
+
bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
if (success != canSucceed) {
SkString str;
@@ -161,7 +314,7 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
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
@@ -176,7 +329,257 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, dst.width() == 0);
REPORTER_ASSERT(reporter, dst.height() == 0);
}
- }
+ } // for (size_t j = ...
+
+ // Tests for getSafeSize(), getSafeSize64(), copyPixelsTo(),
+ // copyPixelsFrom().
+ //
+ for (size_t copyCase = 0; copyCase < SK_ARRAY_COUNT(isExtracted);
+ ++copyCase) {
+ // Test copying to/from external buffer.
+ // Note: the tests below have hard-coded values ---
+ // Please take care if modifying.
+ if (gPairs[i].fConfig != SkBitmap::kRLE_Index8_Config) {
+
+ // Tests for getSafeSize64().
+ // Test with a very large configuration without pixel buffer
+ // attached.
+ SkBitmap tstSafeSize;
+ tstSafeSize.setConfig(gPairs[i].fConfig, 100000000U,
+ 100000000U);
+ Sk64 safeSize = tstSafeSize.getSafeSize64();
+ if (safeSize.isNeg()) {
+ SkString str;
+ str.printf("getSafeSize64() negative: %s",
+ getSkConfigName(tstSafeSize));
+ reporter->reportFailed(str);
+ }
+ bool sizeFail = false;
+ // Compare against hand-computed values.
+ switch (gPairs[i].fConfig) {
+ case SkBitmap::kNo_Config:
+ break;
+
+ case SkBitmap::kA1_Config:
+ if (safeSize.fHi != 0x470DE ||
+ safeSize.fLo != 0x4DF82000)
+ sizeFail = true;
+ break;
+
+ case SkBitmap::kA8_Config:
+ case SkBitmap::kIndex8_Config:
+ if (safeSize.fHi != 0x2386F2 ||
+ safeSize.fLo != 0x6FC10000)
+ sizeFail = true;
+ break;
+
+ case SkBitmap::kRGB_565_Config:
+ case SkBitmap::kARGB_4444_Config:
+ if (safeSize.fHi != 0x470DE4 ||
+ safeSize.fLo != 0xDF820000)
+ sizeFail = true;
+ break;
+
+ case SkBitmap::kARGB_8888_Config:
+ if (safeSize.fHi != 0x8E1BC9 ||
+ safeSize.fLo != 0xBF040000)
+ sizeFail = true;
+ break;
+
+ case SkBitmap::kRLE_Index8_Config:
+ break;
+
+ default:
+ break;
+ }
+ if (sizeFail) {
+ SkString str;
+ str.printf("getSafeSize64() wrong size: %s",
+ getSkConfigName(tstSafeSize));
+ reporter->reportFailed(str);
+ }
+
+ size_t subW, subH;
+ // Set sizes to be height = 2 to force the last row of the
+ // source to be used, thus verifying correct operation if
+ // the bitmap is an extracted subset.
+ if (gPairs[i].fConfig == SkBitmap::kA1_Config) {
+ // If one-bit per pixel, use 9 pixels to force more than
+ // one byte per row.
+ subW = 9;
+ subH = 2;
+ } else {
+ // All other configurations are at least one byte per pixel,
+ // and different configs will test copying different numbers
+ // of bytes.
+ subW = subH = 2;
+ }
+
+ // Create bitmap to act as source for copies and subsets.
+ SkBitmap src, subset;
+ SkColorTable* ct = NULL;
+ if (isExtracted[copyCase]) { // A larger image to extract from.
+ src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH);
+ } else // Tests expect a 2x2 bitmap, so make smaller.
+ src.setConfig(gPairs[i].fConfig, subW, subH);
+ if (SkBitmap::kIndex8_Config == src.config() ||
+ SkBitmap::kRLE_Index8_Config == src.config()) {
+ ct = init_ctable();
+ }
+
+ src.allocPixels(ct);
+ SkSafeUnref(ct);
+
+ // Either copy src or extract into 'subset', which is used
+ // for subsequent calls to copyPixelsTo/From.
+ bool srcReady = false;
+ if (isExtracted[copyCase]) {
+ // The extractedSubset() test case allows us to test copy-
+ // ing when src and dst mave possibly different strides.
+ SkIRect r;
+ if (gPairs[i].fConfig == SkBitmap::kA1_Config)
+ // This config seems to need byte-alignment of
+ // extracted subset bits.
+ r.set(0, 0, subW, subH);
+ else
+ r.set(1, 0, 1 + subW, subH); // 2x2 extracted bitmap
+
+ srcReady = src.extractSubset(&subset, r);
+ } else {
+ srcReady = src.copyTo(&subset, src.getConfig());
+ }
+
+ // Not all configurations will generate a valid 'subset'.
+ if (srcReady) {
+
+ // Allocate our target buffer 'buf' for all copies.
+ // To simplify verifying correctness of copies attach
+ // buf to a SkBitmap, but copies are done using the
+ // raw buffer pointer.
+ const uint32_t bufSize = subH *
+ SkBitmap::ComputeRowBytes(src.getConfig(), subW) * 2;
+ uint8_t* buf = new uint8_t[bufSize];
+
+ SkBitmap bufBm; // Attach buf to this bitmap.
+ bool successExpected;
+
+ // Set up values for each pixel being copied.
+ Coordinates coords(subW * subH);
+ for (size_t x = 0; x < subW; ++x)
+ for (size_t y = 0; y < subH; ++y)
+ {
+ int index = y * subW + x;
+ SkASSERT(index < coords.length);
+ coords[index]->fX = x;
+ coords[index]->fY = y;
+ }
+
+ writeCoordPixels(subset, coords);
+
+ // Test #1 ////////////////////////////////////////////
+
+ // Before/after comparisons easier if we attach buf
+ // to an appropriately configured SkBitmap.
+ memset(buf, 0xFF, bufSize);
+ // Config with stride greater than src but that fits in buf.
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+ SkBitmap::ComputeRowBytes(subset.getConfig(), subW)
+ * 2);
+ bufBm.setPixels(buf);
+ successExpected = false;
+ // Then attempt to copy with a stride that is too large
+ // to fit in the buffer.
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes() * 3)
+ == successExpected);
+
+ if (successExpected)
+ reportCopyVerification(subset, bufBm, coords,
+ "copyPixelsTo(buf, bufSize, 1.5*maxRowBytes)",
+ reporter);
+
+ // Test #2 ////////////////////////////////////////////
+ // This test should always succeed, but in the case
+ // of extracted bitmaps only because we handle the
+ // issue of getSafeSize(). Without getSafeSize()
+ // buffer overrun/read would occur.
+ memset(buf, 0xFF, bufSize);
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+ subset.rowBytes());
+ bufBm.setPixels(buf);
+ successExpected = subset.getSafeSize() <= bufSize;
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsTo(buf, bufSize) ==
+ successExpected);
+ if (successExpected)
+ reportCopyVerification(subset, bufBm, coords,
+ "copyPixelsTo(buf, bufSize)", reporter);
+
+ // Test #3 ////////////////////////////////////////////
+ // Copy with different stride between src and dst.
+ memset(buf, 0xFF, bufSize);
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+ subset.rowBytes()+1);
+ bufBm.setPixels(buf);
+ successExpected = true; // Should always work.
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsTo(buf, bufSize,
+ subset.rowBytes()+1) == successExpected);
+ if (successExpected)
+ reportCopyVerification(subset, bufBm, coords,
+ "copyPixelsTo(buf, bufSize, rowBytes+1)", reporter);
+
+ // Test #4 ////////////////////////////////////////////
+ // Test copy with stride too small.
+ memset(buf, 0xFF, bufSize);
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+ bufBm.setPixels(buf);
+ successExpected = false;
+ // Request copy with stride too small.
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes()-1)
+ == successExpected);
+ if (successExpected)
+ reportCopyVerification(subset, bufBm, coords,
+ "copyPixelsTo(buf, bufSize, rowBytes()-1)", reporter);
+
+ // Test #5 ////////////////////////////////////////////
+ // Tests the case where the source stride is too small
+ // for the source configuration.
+ memset(buf, 0xFF, bufSize);
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+ bufBm.setPixels(buf);
+ writeCoordPixels(bufBm, coords);
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsFrom(buf, bufSize, 1) == false);
+
+ // Test #6 ////////////////////////////////////////////
+ // Tests basic copy from an external buffer to the bitmap.
+ // If the bitmap is "extracted", this also tests the case
+ // where the source stride is different from the dest.
+ // stride.
+ // We've made the buffer large enough to always succeed.
+ bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+ bufBm.setPixels(buf);
+ writeCoordPixels(bufBm, coords);
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsFrom(buf, bufSize, bufBm.rowBytes()) ==
+ true);
+ reportCopyVerification(bufBm, subset, coords,
+ "copyPixelsFrom(buf, bufSize)",
+ reporter);
+
+ // Test #7 ////////////////////////////////////////////
+ // Tests the case where the source buffer is too small
+ // for the transfer.
+ REPORTER_ASSERT(reporter,
+ subset.copyPixelsFrom(buf, 1, subset.rowBytes()) ==
+ false);
+
+ delete [] buf;
+ }
+ }
+ } // for (size_t copyCase ...
}
}
diff --git a/tests/BitmapGetColorTest.cpp b/tests/BitmapGetColorTest.cpp
new file mode 100644
index 0000000..81cf412
--- /dev/null
+++ b/tests/BitmapGetColorTest.cpp
@@ -0,0 +1,36 @@
+#include "Test.h"
+#include "SkBitmap.h"
+
+static void TestGetColor(skiatest::Reporter* reporter) {
+ static const struct Rec {
+ SkBitmap::Config fConfig;
+ SkColor fInColor;
+ SkColor fOutColor;
+ } gRec[] = {
+ // todo: add some tests that involve alpha, so we exercise the
+ // unpremultiply aspect of getColor()
+ { SkBitmap::kA8_Config, 0xFF000000, 0xFF000000 },
+ { SkBitmap::kA8_Config, 0, 0 },
+ { SkBitmap::kARGB_4444_Config, 0xFF224466, 0xFF224466 },
+ { SkBitmap::kARGB_4444_Config, 0, 0 },
+ { SkBitmap::kRGB_565_Config, 0xFF00FF00, 0xFF00FF00 },
+ { SkBitmap::kRGB_565_Config, 0xFFFF00FF, 0xFFFF00FF },
+ { SkBitmap::kARGB_8888_Config, 0xFFFFFFFF, 0xFFFFFFFF },
+ { SkBitmap::kARGB_8888_Config, 0, 0 },
+ { SkBitmap::kARGB_8888_Config, 0xFF224466, 0xFF224466 },
+ };
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
+ SkBitmap bm;
+ uint32_t storage[1];
+ bm.setConfig(gRec[i].fConfig, 1, 1);
+ bm.setPixels(storage);
+ bm.eraseColor(gRec[i].fInColor);
+
+ SkColor c = bm.getColor(0, 0);
+ REPORTER_ASSERT(reporter, c == gRec[i].fOutColor);
+ }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("GetColor", TestGetColorClass, TestGetColor)
diff --git a/tests/BlitRowTest.cpp b/tests/BlitRowTest.cpp
index 91d6b94..d18cb8a 100644
--- a/tests/BlitRowTest.cpp
+++ b/tests/BlitRowTest.cpp
@@ -207,7 +207,8 @@ static void test_diagonal(skiatest::Reporter* reporter) {
SkBitmap srcBM;
srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, H);
srcBM.allocPixels();
- SkRect srcR = { 0, 0, srcBM.width(), srcBM.height() };
+ SkRect srcR = {
+ 0, 0, SkIntToScalar(srcBM.width()), SkIntToScalar(srcBM.height()) };
// cons up a mesh to draw the bitmap with
Mesh mesh(srcBM, &paint);
diff --git a/tests/ClipCubicTest.cpp b/tests/ClipCubicTest.cpp
index 905b733..e38a22f 100644
--- a/tests/ClipCubicTest.cpp
+++ b/tests/ClipCubicTest.cpp
@@ -7,10 +7,10 @@
static void PrintCurve(const char *name, const SkPoint crv[4]) {
printf("%s: %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g\n",
name,
- crv[0].fX, crv[0].fY,
- crv[1].fX, crv[1].fY,
- crv[2].fX, crv[2].fY,
- crv[3].fX, crv[3].fY);
+ (float)crv[0].fX, (float)crv[0].fY,
+ (float)crv[1].fX, (float)crv[1].fY,
+ (float)crv[2].fX, (float)crv[2].fY,
+ (float)crv[3].fX, (float)crv[3].fY);
}
@@ -46,17 +46,17 @@ static SkPoint* SetCurve(float x0, float y0,
static void TestCubicClipping(skiatest::Reporter* reporter) {
static SkPoint crv[4] = {
- { SkFloatToScalar(0), SkFloatToScalar(0) },
- { SkFloatToScalar(2), SkFloatToScalar(3) },
- { SkFloatToScalar(1), SkFloatToScalar(10) },
- { SkFloatToScalar(4), SkFloatToScalar(12) }
+ { SkIntToScalar(0), SkIntToScalar(0) },
+ { SkIntToScalar(2), SkIntToScalar(3) },
+ { SkIntToScalar(1), SkIntToScalar(10) },
+ { SkIntToScalar(4), SkIntToScalar(12) }
};
SkCubicClipper clipper;
SkPoint clipped[4], shouldbe[4];
SkIRect clipRect;
bool success;
- const float tol = 1e-4;
+ const float tol = SkFloatToScalar(1e-4);
// Test no clip, with plenty of room.
clipRect.set(-2, -2, 6, 14);
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
new file mode 100644
index 0000000..e3c95b4
--- /dev/null
+++ b/tests/ClipStackTest.cpp
@@ -0,0 +1,49 @@
+#include "Test.h"
+#include "SkClipStack.h"
+
+static void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack,
+ int count) {
+ REPORTER_ASSERT(reporter, count == stack.getSaveCount());
+
+ SkClipStack::B2FIter iter(stack);
+ int counter = 0;
+ while (iter.next()) {
+ counter += 1;
+ }
+ REPORTER_ASSERT(reporter, count == counter);
+}
+
+static void TestClipStack(skiatest::Reporter* reporter) {
+ SkClipStack stack;
+
+ assert_count(reporter, stack, 0);
+
+ static const SkIRect gRects[] = {
+ { 0, 0, 100, 100 },
+ { 25, 25, 125, 125 },
+ { 0, 0, 1000, 1000 },
+ { 0, 0, 75, 75 }
+ };
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) {
+ stack.clipDevRect(gRects[i]);
+ }
+
+ // all of the above rects should have been intersected, leaving only 1 rect
+ SkClipStack::B2FIter iter(stack);
+ const SkClipStack::B2FIter::Clip* clip = iter.next();
+ const SkRect answer = { 25, 25, 75, 75 };
+
+ REPORTER_ASSERT(reporter, clip);
+ REPORTER_ASSERT(reporter, clip->fRect);
+ REPORTER_ASSERT(reporter, !clip->fPath);
+ REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == clip->fOp);
+ REPORTER_ASSERT(reporter, *clip->fRect == answer);
+ // now check that we only had one in our iterator
+ REPORTER_ASSERT(reporter, !iter.next());
+
+ stack.reset();
+ assert_count(reporter, stack, 0);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack)
diff --git a/tests/DequeTest.cpp b/tests/DequeTest.cpp
new file mode 100644
index 0000000..e74fd28
--- /dev/null
+++ b/tests/DequeTest.cpp
@@ -0,0 +1,96 @@
+#include "Test.h"
+#include "SkDeque.h"
+
+static void assert_count(skiatest::Reporter* reporter, const SkDeque& deq, int count) {
+ if (0 == count) {
+ REPORTER_ASSERT(reporter, deq.empty());
+ REPORTER_ASSERT(reporter, 0 == deq.count());
+ REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize());
+ REPORTER_ASSERT(reporter, NULL == deq.front());
+ REPORTER_ASSERT(reporter, NULL == deq.back());
+ } else {
+ REPORTER_ASSERT(reporter, !deq.empty());
+ REPORTER_ASSERT(reporter, count == deq.count());
+ REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize());
+ REPORTER_ASSERT(reporter, NULL != deq.front());
+ REPORTER_ASSERT(reporter, NULL != deq.back());
+ if (1 == count) {
+ REPORTER_ASSERT(reporter, deq.back() == deq.front());
+ } else {
+ REPORTER_ASSERT(reporter, deq.back() != deq.front());
+ }
+ }
+}
+
+static void assert_f2biter(skiatest::Reporter* reporter, const SkDeque& deq,
+ int max, int min) {
+ SkDeque::F2BIter iter(deq);
+ void* ptr;
+
+ int value = max;
+ while ((ptr = iter.next()) != NULL) {
+ REPORTER_ASSERT(reporter, value == *(int*)ptr);
+ value -= 1;
+ }
+ REPORTER_ASSERT(reporter, value+1 == min);
+}
+
+static void TestDeque(skiatest::Reporter* reporter) {
+ SkDeque deq(sizeof(int));
+ int i;
+
+ // test pushing on the front
+
+ assert_count(reporter, deq, 0);
+ for (i = 1; i <= 10; i++) {
+ *(int*)deq.push_front() = i;
+ }
+ assert_count(reporter, deq, 10);
+ assert_f2biter(reporter, deq, 10, 1);
+
+ for (i = 0; i < 5; i++) {
+ deq.pop_front();
+ }
+ assert_count(reporter, deq, 5);
+ assert_f2biter(reporter, deq, 5, 1);
+
+ for (i = 0; i < 5; i++) {
+ deq.pop_front();
+ }
+ assert_count(reporter, deq, 0);
+
+ // now test pushing on the back
+
+ for (i = 10; i >= 1; --i) {
+ *(int*)deq.push_back() = i;
+ }
+ assert_count(reporter, deq, 10);
+ assert_f2biter(reporter, deq, 10, 1);
+
+ for (i = 0; i < 5; i++) {
+ deq.pop_back();
+ }
+ assert_count(reporter, deq, 5);
+ assert_f2biter(reporter, deq, 10, 6);
+
+ for (i = 0; i < 5; i++) {
+ deq.pop_back();
+ }
+ assert_count(reporter, deq, 0);
+
+ // now tests pushing/poping on both ends
+
+ *(int*)deq.push_front() = 5;
+ *(int*)deq.push_back() = 4;
+ *(int*)deq.push_front() = 6;
+ *(int*)deq.push_back() = 3;
+ *(int*)deq.push_front() = 7;
+ *(int*)deq.push_back() = 2;
+ *(int*)deq.push_front() = 8;
+ *(int*)deq.push_back() = 1;
+ assert_count(reporter, deq, 8);
+ assert_f2biter(reporter, deq, 8, 1);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Deque", TestDequeClass, TestDeque)
diff --git a/tests/FillPathTest.cpp b/tests/FillPathTest.cpp
new file mode 100644
index 0000000..ffc9f8e
--- /dev/null
+++ b/tests/FillPathTest.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Chromium Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Test.h"
+#include "SkRegion.h"
+#include "SkPath.h"
+#include "SkScan.h"
+#include "SkBlitter.h"
+
+namespace {
+
+struct FakeBlitter : public SkBlitter {
+ FakeBlitter()
+ : m_blitCount(0)
+ {}
+
+ virtual void blitH(int x, int y, int width) {
+ m_blitCount++;
+ }
+
+ int m_blitCount;
+};
+
+}
+
+// http://code.google.com/p/skia/issues/detail?id=87
+// Lines which is not clipped by boundary based clipping,
+// but skipped after tessellation, should be cleared by the blitter.
+static void TestFillPathInverse(skiatest::Reporter* reporter) {
+ FakeBlitter blitter;
+ SkRegion clip;
+ SkPath path;
+ int height = 100;
+ int width = 200;
+ int expected_lines = 5;
+ clip.setRect(0, height - expected_lines, width, height);
+ path.moveTo(0.0, 0.0);
+ path.quadTo(width/2, height, width, 0.0);
+ path.close();
+ path.setFillType(SkPath::kInverseWinding_FillType);
+ SkScan::FillPath(path, clip, &blitter);
+
+ REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("FillPath", FillPathTestClass, TestFillPathInverse)
diff --git a/tests/FlateTest.cpp b/tests/FlateTest.cpp
new file mode 100644
index 0000000..f8e0921
--- /dev/null
+++ b/tests/FlateTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Test.h"
+#include "SkFlate.h"
+#include "SkStream.h"
+
+// A memory stream that reports zero size with the standard call, like
+// an unseekable file stream would.
+class SkZeroSizeMemStream : public SkMemoryStream {
+public:
+ virtual size_t read(void* buffer, size_t size) {
+ if (buffer == NULL && size == 0)
+ return 0;
+ if (buffer == NULL && size == kGetSizeKey)
+ size = 0;
+ return SkMemoryStream::read(buffer, size);
+ }
+
+ static const size_t kGetSizeKey = 0xDEADBEEF;
+};
+
+static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
+ size_t dataSize) {
+ if (testStream == NULL)
+ return;
+
+ SkMemoryStream testData(dataSize);
+ uint8_t* data = (uint8_t*)testData.getMemoryBase();
+ srand(0); // Make data deterministic.
+ for (size_t i = 0; i < dataSize; i++)
+ data[i] = rand() & 0xFF;
+
+ testStream->setMemory(testData.getMemoryBase(), dataSize, true);
+ SkDynamicMemoryWStream compressed;
+ bool status = SkFlate::Deflate(testStream, &compressed);
+ REPORTER_ASSERT(reporter, status);
+
+ // Check that the input data wasn't changed.
+ size_t inputSize = testStream->getLength();
+ if (inputSize == 0)
+ inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
+ REPORTER_ASSERT(reporter, testData.getLength() == inputSize);
+ REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
+ testStream->getMemoryBase(),
+ testData.getLength()) == 0);
+
+ // Assume there are two test sizes, big and small.
+ if (dataSize < 1024)
+ REPORTER_ASSERT(reporter, compressed.getOffset() < 1024);
+ else
+ REPORTER_ASSERT(reporter, compressed.getOffset() > 1024);
+
+ testStream->setMemory(compressed.getStream(), compressed.getOffset(), true);
+ SkDynamicMemoryWStream uncompressed;
+ status = SkFlate::Inflate(testStream, &uncompressed);
+ REPORTER_ASSERT(reporter, status);
+
+ // Check that the input data wasn't changed.
+ inputSize = testStream->getLength();
+ if (inputSize == 0)
+ inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
+ REPORTER_ASSERT(reporter, compressed.getOffset() == inputSize);
+ REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
+ compressed.getStream(),
+ compressed.getOffset()) == 0);
+
+ // Check that the uncompressed data matches the source data.
+ REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset());
+ REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
+ uncompressed.getStream(),
+ testData.getLength()) == 0);
+}
+
+static void TestFlateCompression(skiatest::Reporter* reporter) {
+ TestFlate(reporter, NULL, 0);
+#ifdef SK_ZLIB_INCLUDE
+ REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
+
+ SkMemoryStream memStream;
+ TestFlate(reporter, &memStream, 512);
+ TestFlate(reporter, &memStream, 10240);
+
+ SkZeroSizeMemStream fileStream;
+ TestFlate(reporter, &fileStream, 512);
+ TestFlate(reporter, &fileStream, 10240);
+#endif
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Flate", FlateTestClass, TestFlateCompression)
diff --git a/tests/InfRectTest.cpp b/tests/InfRectTest.cpp
new file mode 100644
index 0000000..1e15023
--- /dev/null
+++ b/tests/InfRectTest.cpp
@@ -0,0 +1,44 @@
+#include "Test.h"
+#include "SkRect.h"
+
+#ifdef SK_SCALAR_IS_FLOAT
+static float make_zero() {
+ return sk_float_sin(0);
+}
+#endif
+
+static void check_invalid(skiatest::Reporter* reporter,
+ SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
+ SkRect rect;
+ rect.set(l, t, r, b);
+ REPORTER_ASSERT(reporter, !rect.hasValidCoordinates());
+}
+
+// Tests that hasValidCoordinates() will reject any rect with +/-inf values
+// as one of its coordinates.
+static void TestInfRect(skiatest::Reporter* reporter) {
+#ifdef SK_SCALAR_IS_FLOAT
+ float invalid = 1 / make_zero(); // infinity
+#else
+ SkFixed invalid = SK_FixedNaN;
+#endif
+ SkScalar small = SkIntToScalar(10);
+ SkScalar big = SkIntToScalar(100);
+
+ SkRect rect = SkRect::MakeXYWH(small, small, big, big);
+ REPORTER_ASSERT(reporter, rect.hasValidCoordinates());
+
+ check_invalid(reporter, small, small, big, invalid);
+ check_invalid(reporter, small, small, invalid, big);
+ check_invalid(reporter, small, invalid, big, big);
+ check_invalid(reporter, invalid, small, big, big);
+ check_invalid(reporter, small, small, big, -invalid);
+ check_invalid(reporter, small, small, -invalid, big);
+ check_invalid(reporter, small, -invalid, big, big);
+ check_invalid(reporter, -invalid, small, big, big);
+}
+
+// need tests for SkStrSearch
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("InfRect", InfRectTestClass, TestInfRect)
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 4bfbd94..493691e 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -146,6 +146,38 @@ static void unittest_fastfloat(skiatest::Reporter* reporter) {
}
}
+#ifdef SK_SCALAR_IS_FLOAT
+static float make_zero() {
+ return sk_float_sin(0);
+}
+#endif
+
+static void unittest_isfinite(skiatest::Reporter* reporter) {
+#ifdef SK_SCALAR_IS_FLOAT
+ float nan = ::asin(2);
+ float inf = 1.0 / make_zero();
+ float big = 3.40282e+038;
+
+ REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
+ REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
+ REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
+ REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
+#else
+ SkFixed nan = SK_FixedNaN;
+ SkFixed big = SK_FixedMax;
+#endif
+
+ REPORTER_ASSERT(reporter, SkScalarIsNaN(nan));
+ REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
+ REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
+ REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
+
+ REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
+ REPORTER_ASSERT(reporter, SkScalarIsFinite(big));
+ REPORTER_ASSERT(reporter, SkScalarIsFinite(-big));
+ REPORTER_ASSERT(reporter, SkScalarIsFinite(0));
+}
+
#endif
static void test_muldiv255(skiatest::Reporter* reporter) {
@@ -171,6 +203,19 @@ static void test_muldiv255(skiatest::Reporter* reporter) {
#endif
}
+static void test_muldiv255ceiling(skiatest::Reporter* reporter) {
+ for (int c = 0; c <= 255; c++) {
+ for (int a = 0; a <= 255; a++) {
+ int product = (c * a + 255);
+ int expected_ceiling = (product + (product >> 8)) >> 8;
+ int webkit_ceiling = (c * a + 254) / 255;
+ REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
+ int skia_ceiling = SkMulDiv255Ceiling(c, a);
+ REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
+ }
+ }
+}
+
static void test_copysign(skiatest::Reporter* reporter) {
static const int32_t gTriples[] = {
// x, y, expected result
@@ -237,6 +282,7 @@ static void TestMath(skiatest::Reporter* reporter) {
#endif
test_muldiv255(reporter);
+ test_muldiv255ceiling(reporter);
test_copysign(reporter);
{
@@ -295,6 +341,7 @@ static void TestMath(skiatest::Reporter* reporter) {
#ifdef SK_CAN_USE_FLOAT
unittest_fastfloat(reporter);
+ unittest_isfinite(reporter);
#endif
#ifdef SkLONGLONG
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
index 052687d..49a98c2 100644
--- a/tests/MatrixTest.cpp
+++ b/tests/MatrixTest.cpp
@@ -5,7 +5,7 @@ static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
#ifdef SK_SCALAR_IS_FLOAT
const float tolerance = 0.000005f;
#else
- const int32_t tolerance = 3;
+ const int32_t tolerance = 8;
#endif
return SkScalarAbs(a - b) <= tolerance;
@@ -14,7 +14,7 @@ static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
for (int i = 0; i < 9; i++) {
if (!nearly_equal_scalar(a[i], b[i])) {
- printf("not equal %g %g\n", a[i], b[i]);
+ printf("not equal %g %g\n", (float)a[i], (float)b[i]);
return false;
}
}
diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp
new file mode 100644
index 0000000..6feab51
--- /dev/null
+++ b/tests/PDFPrimitivesTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include "Test.h"
+#include "SkPDFCatalog.h"
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkScalar.h"
+#include "SkStream.h"
+
+static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj,
+ const std::string& representation,
+ bool indirect) {
+ size_t directSize = obj->getOutputSize(NULL, false);
+ REPORTER_ASSERT(reporter, directSize == representation.size());
+
+ SkDynamicMemoryWStream buffer;
+ obj->emitObject(&buffer, NULL, false);
+ REPORTER_ASSERT(reporter, directSize == buffer.getOffset());
+ REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), representation.c_str(),
+ directSize) == 0);
+
+ if (indirect) {
+ // Indirect output.
+ static char header[] = "1 0 obj\n";
+ static size_t headerLen = strlen(header);
+ static char footer[] = "\nendobj\n";
+ static size_t footerLen = strlen(footer);
+
+ SkPDFCatalog catalog;
+ catalog.addObject(obj, false);
+
+ size_t indirectSize = obj->getOutputSize(&catalog, true);
+ REPORTER_ASSERT(reporter,
+ indirectSize == directSize + headerLen + footerLen);
+
+ buffer.reset();
+ obj->emitObject(&buffer, &catalog, true);
+ REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset());
+ REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), header,
+ headerLen) == 0);
+ REPORTER_ASSERT(reporter,
+ memcmp(buffer.getStream() + headerLen,
+ representation.c_str(), directSize) == 0);
+ REPORTER_ASSERT(reporter,
+ memcmp(buffer.getStream() + headerLen + directSize,
+ footer, footerLen) == 0);
+ }
+}
+
+static void TestCatalog(skiatest::Reporter* reporter) {
+ SkPDFCatalog catalog;
+ SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+ int1->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
+ int2->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFInt> int3 = new SkPDFInt(3);
+ int3->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFInt> int1Again(int1.get());
+
+ catalog.addObject(int1.get(), false);
+ catalog.addObject(int2.get(), false);
+ catalog.addObject(int3.get(), false);
+
+ REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
+ REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
+ REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int3.get()) == 3);
+
+ SkDynamicMemoryWStream buffer;
+ catalog.emitObjectNumber(&buffer, int1.get());
+ catalog.emitObjectNumber(&buffer, int2.get());
+ catalog.emitObjectNumber(&buffer, int3.get());
+ catalog.emitObjectNumber(&buffer, int1Again.get());
+ char expectedResult[] = "1 02 03 01 0";
+ REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
+ strlen(expectedResult)) == 0);
+}
+
+static void TestObjectRef(skiatest::Reporter* reporter) {
+ SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+ int1->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
+ int2->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFObjRef> int2ref = new SkPDFObjRef(int2.get());
+ int2ref->unref(); // SkRefPtr and new both took a reference.
+
+ SkPDFCatalog catalog;
+ catalog.addObject(int1.get(), false);
+ catalog.addObject(int2.get(), false);
+ REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
+ REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
+
+ char expectedResult[] = "2 0 R";
+ SkDynamicMemoryWStream buffer;
+ int2ref->emitObject(&buffer, &catalog, false);
+ REPORTER_ASSERT(reporter, buffer.getOffset() == strlen(expectedResult));
+ REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
+ buffer.getOffset()) == 0);
+}
+
+static void TestPDFPrimitives(skiatest::Reporter* reporter) {
+ SkRefPtr<SkPDFInt> int42 = new SkPDFInt(42);
+ int42->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, int42.get(), "42", true);
+
+ SkRefPtr<SkPDFScalar> realHalf = new SkPDFScalar(SK_ScalarHalf);
+ realHalf->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, realHalf.get(), "0.5", true);
+
+ SkRefPtr<SkPDFScalar> bigScalar = new SkPDFScalar(110999.75);
+ bigScalar->unref(); // SkRefPtr and new both took a reference.
+#if defined(SK_SCALAR_IS_FIXED) || !defined(SK_ALLOW_LARGE_PDF_SCALARS)
+ CheckObjectOutput(reporter, bigScalar.get(), "111000", true);
+#else
+ CheckObjectOutput(reporter, bigScalar.get(), "110999.75", true);
+#endif
+
+#if defined(SK_SCALAR_IS_FLOAT) && defined(SK_ALLOW_LARGE_PDF_SCALARS)
+ SkRefPtr<SkPDFScalar> biggerScalar = new SkPDFScalar(50000000.1);
+ biggerScalar->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, biggerScalar.get(), "50000000", true);
+
+ SkRefPtr<SkPDFScalar> smallestScalar = new SkPDFScalar(1.0/65536);
+ smallestScalar->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, smallestScalar.get(), "0.00001526", true);
+#endif
+
+ SkRefPtr<SkPDFString> stringSimple = new SkPDFString("test ) string ( foo");
+ stringSimple->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, stringSimple.get(), "(test \\) string \\( foo)",
+ true);
+ SkRefPtr<SkPDFString> stringComplex =
+ new SkPDFString("\ttest ) string ( foo");
+ stringComplex->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, stringComplex.get(),
+ "<0974657374202920737472696E67202820666F6F>", true);
+
+ SkRefPtr<SkPDFName> name = new SkPDFName("Test name\twith#tab");
+ name->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, name.get(), "/Test#20name#09with#23tab", false);
+
+ SkRefPtr<SkPDFArray> array = new SkPDFArray;
+ array->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, array.get(), "[]", true);
+ array->append(int42.get());
+ CheckObjectOutput(reporter, array.get(), "[42]", true);
+ array->append(realHalf.get());
+ CheckObjectOutput(reporter, array.get(), "[42 0.5]", true);
+ SkRefPtr<SkPDFInt> int0 = new SkPDFInt(0);
+ int0->unref(); // SkRefPtr and new both took a reference.
+ array->append(int0.get());
+ CheckObjectOutput(reporter, array.get(), "[42 0.5 0]", true);
+ SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+ int1->unref(); // SkRefPtr and new both took a reference.
+ array->setAt(0, int1.get());
+ CheckObjectOutput(reporter, array.get(), "[1 0.5 0]", true);
+
+ SkRefPtr<SkPDFDict> dict = new SkPDFDict;
+ dict->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, dict.get(), "<<>>", true);
+ SkRefPtr<SkPDFName> n1 = new SkPDFName("n1");
+ n1->unref(); // SkRefPtr and new both took a reference.
+ dict->insert(n1.get(), int42.get());
+ CheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>", true);
+ SkRefPtr<SkPDFName> n2 = new SkPDFName("n2");
+ n2->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFName> n3 = new SkPDFName("n3");
+ n3->unref(); // SkRefPtr and new both took a reference.
+ dict->insert(n2.get(), realHalf.get());
+ dict->insert(n3.get(), array.get());
+ CheckObjectOutput(reporter, dict.get(),
+ "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>", true);
+
+ char streamBytes[] = "Test\nFoo\tBar";
+ SkRefPtr<SkMemoryStream> streamData = new SkMemoryStream(
+ streamBytes, strlen(streamBytes), true);
+ streamData->unref(); // SkRefPtr and new both took a reference.
+ SkRefPtr<SkPDFStream> stream = new SkPDFStream(streamData.get());
+ stream->unref(); // SkRefPtr and new both took a reference.
+ CheckObjectOutput(reporter, stream.get(),
+ "<</Length 12\n>> stream\nTest\nFoo\tBar\nendstream",
+ true);
+ stream->insert(n1.get(), int42.get());
+ CheckObjectOutput(reporter, stream.get(),
+ "<</Length 12\n/n1 42\n>> stream\nTest\nFoo\tBar"
+ "\nendstream",
+ true);
+
+ TestCatalog(reporter);
+
+ TestObjectRef(reporter);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PDFPrimitives", PDFPrimitivesTestClass, TestPDFPrimitives)
diff --git a/tests/PaintTest.cpp b/tests/PaintTest.cpp
index 4e6c8b9..5b19090 100644
--- a/tests/PaintTest.cpp
+++ b/tests/PaintTest.cpp
@@ -8,10 +8,14 @@ static void regression_cubic(skiatest::Reporter* reporter) {
SkPath path, stroke;
SkPaint paint;
- path.moveTo(460.2881309415525, 303.250847066498);
- path.cubicTo(463.36378422175284, 302.1169735073363,
- 456.32239330810046, 304.720354932878,
- 453.15255460013304, 305.788586869862);
+ path.moveTo(SkFloatToFixed(460.2881309415525f),
+ SkFloatToFixed(303.250847066498));
+ path.cubicTo(SkFloatToFixed(463.36378422175284),
+ SkFloatToFixed(302.1169735073363),
+ SkFloatToFixed(456.32239330810046),
+ SkFloatToFixed(304.720354932878),
+ SkFloatToFixed(453.15255460013304),
+ SkFloatToFixed(305.788586869862));
SkRect fillR, strokeR;
fillR = path.getBounds();
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 9f26d01..b4b6317 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -6,7 +6,7 @@ static void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,
const SkRect& bounds) {
REPORTER_ASSERT(reporter, p.isConvex());
REPORTER_ASSERT(reporter, p.getBounds() == bounds);
-
+
SkPath p2(p);
REPORTER_ASSERT(reporter, p2.isConvex());
REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
@@ -45,12 +45,12 @@ static void TestPath(skiatest::Reporter* reporter) {
p.setIsConvex(false);
p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
check_convex_bounds(reporter, p, bounds);
-
+
p.reset();
p.setIsConvex(false);
p.addOval(bounds);
check_convex_bounds(reporter, p, bounds);
-
+
p.reset();
p.setIsConvex(false);
p.addRect(bounds);
@@ -88,6 +88,18 @@ static void TestPath(skiatest::Reporter* reporter) {
p.moveTo(SK_Scalar1, 0);
p.getLastPt(&pt);
REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1);
+
+ // check that reset and rewind clear the convex hint back to false
+ p.setIsConvex(false);
+ REPORTER_ASSERT(reporter, !p.isConvex());
+ p.setIsConvex(true);
+ REPORTER_ASSERT(reporter, p.isConvex());
+ p.reset();
+ REPORTER_ASSERT(reporter, !p.isConvex());
+ p.setIsConvex(true);
+ REPORTER_ASSERT(reporter, p.isConvex());
+ p.rewind();
+ REPORTER_ASSERT(reporter, !p.isConvex());
}
#include "TestClassDef.h"
diff --git a/tests/RefDictTest.cpp b/tests/RefDictTest.cpp
new file mode 100644
index 0000000..f52541b
--- /dev/null
+++ b/tests/RefDictTest.cpp
@@ -0,0 +1,66 @@
+#include "Test.h"
+#include "SkRefDict.h"
+
+class TestRC : public SkRefCnt {
+};
+
+static void TestRefDict(skiatest::Reporter* reporter) {
+ TestRC data0, data1;
+ SkRefDict dict;
+
+ REPORTER_ASSERT(reporter, NULL == dict.find(NULL));
+ REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+ REPORTER_ASSERT(reporter, NULL == dict.find("bar"));
+
+ dict.set("foo", &data0);
+ REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+ REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+
+ dict.set("foo", &data0);
+ REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+ REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+
+ dict.set("foo", &data1);
+ REPORTER_ASSERT(reporter, &data1 == dict.find("foo"));
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+ REPORTER_ASSERT(reporter, 2 == data1.getRefCnt());
+
+ dict.set("foo", NULL);
+ REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+ REPORTER_ASSERT(reporter, 1 == data1.getRefCnt());
+
+ dict.set("foo", &data0);
+ dict.set("bar", &data1);
+ REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+ REPORTER_ASSERT(reporter, &data1 == dict.find("bar"));
+ REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+ REPORTER_ASSERT(reporter, 2 == data1.getRefCnt());
+
+ dict.set("foo", &data1);
+ REPORTER_ASSERT(reporter, &data1 == dict.find("foo"));
+ REPORTER_ASSERT(reporter, &data1 == dict.find("bar"));
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+ REPORTER_ASSERT(reporter, 3 == data1.getRefCnt());
+
+ dict.removeAll();
+ REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+ REPORTER_ASSERT(reporter, NULL == dict.find("bar"));
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+ REPORTER_ASSERT(reporter, 1 == data1.getRefCnt());
+
+ {
+ SkRefDict d;
+ REPORTER_ASSERT(reporter, NULL == d.find("foo"));
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+ d.set("foo", &data0);
+ REPORTER_ASSERT(reporter, &data0 == d.find("foo"));
+ REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+ // let d go out of scope still with a ref on data0
+ }
+ // be sure d's destructor lowered data0's owner count back to 1
+ REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("RefDict", RefDictTestClass, TestRefDict)
diff --git a/tests/RegionTest.cpp b/tests/RegionTest.cpp
new file mode 100644
index 0000000..ee34d8b
--- /dev/null
+++ b/tests/RegionTest.cpp
@@ -0,0 +1,63 @@
+#include "Test.h"
+#include "SkRegion.h"
+#include "SkRandom.h"
+
+static void rand_rect(SkIRect* rect, SkRandom& rand) {
+ int bits = 6;
+ int shift = 32 - bits;
+ rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
+ rand.nextU() >> shift, rand.nextU() >> shift);
+ rect->sort();
+}
+
+static bool test_rects(const SkIRect rect[], int count) {
+ SkRegion rgn0, rgn1;
+
+ for (int i = 0; i < count; i++) {
+ rgn0.op(rect[i], SkRegion::kUnion_Op);
+ }
+ rgn1.setRects(rect, count);
+
+ if (rgn0 != rgn1) {
+ SkDebugf("\n");
+ for (int i = 0; i < count; i++) {
+ SkDebugf(" { %d, %d, %d, %d },\n",
+ rect[i].fLeft, rect[i].fTop,
+ rect[i].fRight, rect[i].fBottom);
+ }
+ SkDebugf("\n");
+ return false;
+ }
+ return true;
+}
+
+static void TestRegion(skiatest::Reporter* reporter) {
+ const SkIRect r2[] = {
+ { 0, 0, 1, 1 },
+ { 2, 2, 3, 3 },
+ };
+ REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
+
+ const SkIRect rects[] = {
+ { 0, 0, 1, 2 },
+ { 2, 1, 3, 3 },
+ { 4, 0, 5, 1 },
+ { 6, 0, 7, 4 },
+ };
+ REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
+
+ SkRandom rand;
+ for (int i = 0; i < 1000; i++) {
+ SkRegion rgn0, rgn1;
+
+ const int N = 8;
+ SkIRect rect[N];
+ for (int j = 0; j < N; j++) {
+ rand_rect(&rect[j], rand);
+ }
+ REPORTER_ASSERT(reporter, test_rects(rect, N));
+ }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Region", RegionTestClass, TestRegion)
diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp
index 344c752..270ccfd 100644
--- a/tests/StringTest.cpp
+++ b/tests/StringTest.cpp
@@ -48,6 +48,43 @@ static void TestString(skiatest::Reporter* reporter) {
a.set("ab");
a.set("abc");
a.set("abcd");
+
+ a.set("");
+ a.appendS64(72036854775808LL, 0);
+ REPORTER_ASSERT(reporter, a.equals("72036854775808"));
+
+ a.set("");
+ a.appendS64(-1844674407370LL, 0);
+ REPORTER_ASSERT(reporter, a.equals("-1844674407370"));
+
+ a.set("");
+ a.appendS64(73709551616LL, 15);
+ REPORTER_ASSERT(reporter, a.equals("000073709551616"));
+
+ a.set("");
+ a.appendS64(-429496729612LL, 15);
+ REPORTER_ASSERT(reporter, a.equals("-000429496729612"));
+
+ static const struct {
+ SkScalar fValue;
+ const char* fString;
+ } gRec[] = {
+ { 0, "0" },
+ { SK_Scalar1, "1" },
+ { -SK_Scalar1, "-1" },
+ { SK_Scalar1/2, "0.5" },
+#ifdef SK_SCALAR_IS_FLOAT
+ { 3.4028234e38f, "3.4028235e+38" },
+ { -3.4028234e38f, "-3.4028235e+38" },
+#endif
+ };
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
+ a.reset();
+ a.appendScalar(gRec[i].fValue);
+ REPORTER_ASSERT(reporter, a.size() <= SkStrAppendScalar_MaxSize);
+// SkDebugf(" received <%s> expected <%s>\n", a.c_str(), gRec[i].fString);
+ REPORTER_ASSERT(reporter, a.equals(gRec[i].fString));
+ }
}
#include "TestClassDef.h"
diff --git a/tests/TestSize.cpp b/tests/TestSize.cpp
index 6551509..9e0aaaa 100644
--- a/tests/TestSize.cpp
+++ b/tests/TestSize.cpp
@@ -53,7 +53,7 @@ static void TestSize(skiatest::Reporter* reporter) {
SkISize ia;
ia.set(ix, iy);
a.set(x, y);
- REPORTER_ASSERT(reporter, a.round() == ia);
+ REPORTER_ASSERT(reporter, a.toRound() == ia);
};
#include "TestClassDef.h"
diff --git a/tests/UtilsTest.cpp b/tests/UtilsTest.cpp
index 8a8319c..2019a77 100644
--- a/tests/UtilsTest.cpp
+++ b/tests/UtilsTest.cpp
@@ -1,9 +1,71 @@
#include "Test.h"
#include "SkRandom.h"
+#include "SkRefCnt.h"
#include "SkTSearch.h"
#include "SkTSort.h"
#include "SkUtils.h"
+class RefClass : public SkRefCnt {
+public:
+ RefClass(int n) : fN(n) {}
+ int get() const { return fN; }
+
+private:
+ int fN;
+};
+
+static void test_refptr(skiatest::Reporter* reporter) {
+ RefClass* r0 = new RefClass(0);
+
+ SkRefPtr<RefClass> rc0;
+ REPORTER_ASSERT(reporter, rc0.get() == NULL);
+ REPORTER_ASSERT(reporter, !rc0);
+
+ SkRefPtr<RefClass> rc1;
+ REPORTER_ASSERT(reporter, rc0 == rc1);
+ REPORTER_ASSERT(reporter, rc0.get() != r0);
+
+ rc0 = r0;
+ REPORTER_ASSERT(reporter, rc0);
+ REPORTER_ASSERT(reporter, rc0 != rc1);
+ REPORTER_ASSERT(reporter, rc0.get() == r0);
+
+ rc1 = rc0;
+ REPORTER_ASSERT(reporter, rc1);
+ REPORTER_ASSERT(reporter, rc0 == rc1);
+ REPORTER_ASSERT(reporter, rc0.get() == r0);
+
+ rc0 = NULL;
+ REPORTER_ASSERT(reporter, rc0.get() == NULL);
+ REPORTER_ASSERT(reporter, !rc0);
+ REPORTER_ASSERT(reporter, rc0 != rc1);
+
+ r0->unref();
+}
+
+static void test_autounref(skiatest::Reporter* reporter) {
+ RefClass obj(0);
+ REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+
+ SkAutoTUnref<RefClass> tmp(&obj);
+ REPORTER_ASSERT(reporter, &obj == tmp.get());
+ REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+
+ REPORTER_ASSERT(reporter, &obj == tmp.detach());
+ REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+ REPORTER_ASSERT(reporter, NULL == tmp.detach());
+ REPORTER_ASSERT(reporter, NULL == tmp.get());
+
+ obj.ref();
+ REPORTER_ASSERT(reporter, 2 == obj.getRefCnt());
+ {
+ SkAutoTUnref<RefClass> tmp2(&obj);
+ }
+ REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
#define kSEARCH_COUNT 91
static void test_search(skiatest::Reporter* reporter) {
@@ -103,7 +165,9 @@ static void TestUTF(skiatest::Reporter* reporter) {
test_utf16(reporter);
test_search(reporter);
+ test_refptr(reporter);
+ test_autounref(reporter);
}
#include "TestClassDef.h"
-DEFINE_TESTCLASS("UTF", UtfTestClass, TestUTF)
+DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF)
diff --git a/tests/XfermodeTest.cpp b/tests/XfermodeTest.cpp
new file mode 100644
index 0000000..6ab6cd7
--- /dev/null
+++ b/tests/XfermodeTest.cpp
@@ -0,0 +1,30 @@
+#include "Test.h"
+#include "SkColor.h"
+#include "SkXfermode.h"
+
+SkPMColor bogusXfermodeProc(SkPMColor src, SkPMColor dst) {
+ return 42;
+}
+
+static void test_asMode(skiatest::Reporter* reporter) {
+ for (int mode = 0; mode <= SkXfermode::kLastMode; mode++) {
+ SkXfermode* xfer = SkXfermode::Create((SkXfermode::Mode) mode);
+ SkXfermode::Mode reportedMode = (SkXfermode::Mode) -1;
+ REPORTER_ASSERT(reporter,
+ xfer != NULL || mode == SkXfermode::kSrcOver_Mode);
+ if (xfer) {
+ REPORTER_ASSERT(reporter, xfer->asMode(&reportedMode));
+ REPORTER_ASSERT(reporter, reportedMode == mode);
+ xfer->unref();
+ }
+ }
+
+ SkXfermode* bogusXfer = new SkProcXfermode(bogusXfermodeProc);
+ SkXfermode::Mode reportedMode = (SkXfermode::Mode) -1;
+ REPORTER_ASSERT(reporter, !bogusXfer->asMode(&reportedMode));
+ REPORTER_ASSERT(reporter, reportedMode == -1);
+ bogusXfer->unref();
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Xfermode", XfermodeTestClass, test_asMode)