11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "Test.h" 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkAAClip.h" 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkCanvas.h" 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMask.h" 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkPath.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkRandom.h" 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool operator==(const SkMask& a, const SkMask& b) { 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (a.fFormat != b.fFormat || a.fBounds != b.fBounds) { 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!a.fImage && !b.fImage) { 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!a.fImage || !b.fImage) { 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t wbytes = a.fBounds.width(); 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (a.fFormat) { 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kBW_Format: 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger wbytes = (wbytes + 7) >> 3; 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kA8_Format: 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::k3D_Format: 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD16_Format: 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger wbytes <<= 1; 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kLCD32_Format: 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkMask::kARGB32_Format: 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger wbytes <<= 2; 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(!"unknown mask format"); 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int h = a.fBounds.height(); 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* aptr = (const char*)a.fImage; 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* bptr = (const char*)b.fImage; 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int y = 0; y < h; ++y) { 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (memcmp(aptr, bptr, wbytes)) { 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger aptr += wbytes; 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bptr += wbytes; 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void copyToMask(const SkRegion& rgn, SkMask* mask) { 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fFormat = SkMask::kA8_Format; 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (rgn.isEmpty()) { 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fBounds.setEmpty(); 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fRowBytes = 0; 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fImage = NULL; 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fBounds = rgn.getBounds(); 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fRowBytes = mask->fBounds.width(); 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fImage = SkMask::AllocImage(mask->computeImageSize()); 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sk_bzero(mask->fImage, mask->computeImageSize()); 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap bitmap; 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask->fBounds.height(), mask->fRowBytes); 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap.setPixels(mask->fImage); 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // canvas expects its coordinate system to always be 0,0 in the top/left 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // so we translate the rgn to match that before drawing into the mask. 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion tmpRgn(rgn); 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmpRgn.translate(-rgn.getBounds().fLeft, -rgn.getBounds().fTop); 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas canvas(bitmap); 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas.clipRegion(tmpRgn); 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas.drawColor(SK_ColorBLACK); 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkIRect rand_rect(SkRandom& rand, int n) { 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int x = rand.nextS() % n; 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int y = rand.nextS() % n; 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int w = rand.nextU() % n; 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int h = rand.nextU() % n; 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkIRect::MakeXYWH(x, y, w, h); 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void make_rand_rgn(SkRegion* rgn, SkRandom& rand) { 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int count = rand.nextU() % 20; 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn->op(rand_rect(rand, 100), SkRegion::kXOR_Op); 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool operator==(const SkRegion& rgn, const SkAAClip& aaclip) { 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask mask0, mask1; 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger copyToMask(rgn, &mask0); 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger aaclip.copyToMask(&mask1); 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool eq = (mask0 == mask1); 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::FreeImage(mask0.fImage); 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::FreeImage(mask1.fImage); 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return eq; 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool equalsAAClip(const SkRegion& rgn) { 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAAClip aaclip; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger aaclip.setRegion(rgn); 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return rgn == aaclip; 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void setRgnToPath(SkRegion* rgn, const SkPath& path) { 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect ir; 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.getBounds().round(&ir); 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn->setPath(path, SkRegion(ir)); 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// aaclip.setRegion should create idential masks to the region 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_rgn(skiatest::Reporter* reporter) { 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRandom rand; 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 1000; i++) { 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion rgn; 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger make_rand_rgn(&rgn, rand); 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, equalsAAClip(rgn)); 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion rgn; 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPath path; 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.addCircle(0, 0, SkIntToScalar(30)); 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setRgnToPath(&rgn, path); 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, equalsAAClip(rgn)); 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.reset(); 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.moveTo(0, 0); 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.lineTo(SkIntToScalar(100), 0); 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.lineTo(SkIntToScalar(100 - 20), SkIntToScalar(20)); 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.lineTo(SkIntToScalar(20), SkIntToScalar(20)); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setRgnToPath(&rgn, path); 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, equalsAAClip(rgn)); 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const SkRegion::Op gRgnOps[] = { 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kDifference_Op, 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kIntersect_Op, 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kUnion_Op, 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kXOR_Op, 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kReverseDifference_Op, 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::kReplace_Op 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const char* gRgnOpNames[] = { 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "DIFF", "INTERSECT", "UNION", "XOR", "REVERSE_DIFF", "REPLACE" 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void imoveTo(SkPath& path, int x, int y) { 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.moveTo(SkIntToScalar(x), SkIntToScalar(y)); 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void icubicTo(SkPath& path, int x0, int y0, int x1, int y1, int x2, int y2) { 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.cubicTo(SkIntToScalar(x0), SkIntToScalar(y0), 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(x1), SkIntToScalar(y1), 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(x2), SkIntToScalar(y2)); 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_path_bounds(skiatest::Reporter* reporter) { 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPath path; 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAAClip clip; 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int height = 40; 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkScalar sheight = SkIntToScalar(height); 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.addOval(SkRect::MakeWH(sheight, sheight)); 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, sheight == path.getBounds().height()); 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip.setPath(path, NULL, true); 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, height == clip.getBounds().height()); 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // this is the trimmed height of this cubic (with aa). The critical thing 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // for this test is that it is less than height, which represents just 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the bounds of the path's control-points. 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // This used to fail until we tracked the MinY in the BuilderBlitter. 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int teardrop_height = 12; 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger path.reset(); 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger imoveTo(path, 0, 20); 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger icubicTo(path, 40, 40, 40, 0, 0, 20); 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, sheight == path.getBounds().height()); 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip.setPath(path, NULL, true); 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, teardrop_height == clip.getBounds().height()); 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_empty(skiatest::Reporter* reporter) { 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAAClip clip0, clip1; 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.isEmpty()); 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty()); 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip1 == clip0); 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip0.translate(10, 10); // should have no effect on empty 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.isEmpty()); 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty()); 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip1 == clip0); 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect r = { 10, 10, 40, 50 }; 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip0.setRect(r); 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, !clip0.isEmpty()); 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, !clip0.getBounds().isEmpty()); 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0 != clip1); 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.getBounds() == r); 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip0.setEmpty(); 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.isEmpty()); 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty()); 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip1 == clip0); 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask mask; 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mask.fImage = NULL; 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip0.copyToMask(&mask); 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, NULL == mask.fImage); 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, mask.fBounds.isEmpty()); 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void rand_irect(SkIRect* r, int N, SkRandom& rand) { 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r->setXYWH(0, 0, rand.nextU() % N, rand.nextU() % N); 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dx = rand.nextU() % (2*N); 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dy = rand.nextU() % (2*N); 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // use int dx,dy to make the subtract be signed 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r->offset(N - dx, N - dy); 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_irect(skiatest::Reporter* reporter) { 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRandom rand; 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 10000; i++) { 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAAClip clip0, clip1; 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion rgn0, rgn1; 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect r0, r1; 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rand_irect(&r0, 10, rand); 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rand_irect(&r1, 10, rand); 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip0.setRect(r0); 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip1.setRect(r1); 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn0.setRect(r0); 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn1.setRect(r1); 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t j = 0; j < SK_ARRAY_COUNT(gRgnOps); ++j) { 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::Op op = gRgnOps[j]; 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAAClip clip2; 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion rgn2; 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool nonEmptyAA = clip2.op(clip0, clip1, op); 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool nonEmptyBW = rgn2.op(rgn0, rgn1, op); 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (nonEmptyAA != nonEmptyBW || clip2.getBounds() != rgn2.getBounds()) { 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("[%d %d %d %d] %s [%d %d %d %d] = BW:[%d %d %d %d] AA:[%d %d %d %d]\n", 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r0.fLeft, r0.fTop, r0.right(), r0.bottom(), 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gRgnOpNames[j], 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r1.fLeft, r1.fTop, r1.right(), r1.bottom(), 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn2.getBounds().fLeft, rgn2.getBounds().fTop, 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rgn2.getBounds().right(), rgn2.getBounds().bottom(), 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip2.getBounds().fLeft, clip2.getBounds().fTop, 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip2.getBounds().right(), clip2.getBounds().bottom()); 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, nonEmptyAA == nonEmptyBW); 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, clip2.getBounds() == rgn2.getBounds()); 2754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkMask maskBW, maskAA; 2774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger copyToMask(rgn2, &maskBW); 2784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clip2.copyToMask(&maskAA); 2794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger REPORTER_ASSERT(reporter, maskBW == maskAA); 2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void test_path_with_hole(skiatest::Reporter* reporter) { 2854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger static const uint8_t gExpectedImage[] = { 2864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0xFF, 0xFF, 0xFF, 0xFF, 2874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0xFF, 0xFF, 0xFF, 0xFF, 2884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0x00, 0x00, 0x00, 0x00, 2894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0x00, 0x00, 0x00, 0x00, 2904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0xFF, 0xFF, 0xFF, 0xFF, 2914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0xFF, 0xFF, 0xFF, 0xFF, 2924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 2934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkMask expected; 2944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger expected.fBounds.set(0, 0, 4, 6); 2954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger expected.fRowBytes = 4; 2964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger expected.fFormat = SkMask::kA8_Format; 2974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger expected.fImage = (uint8_t*)gExpectedImage; 2984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPath path; 3004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger path.addRect(SkRect::MakeXYWH(0, 0, 3014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(4), SkIntToScalar(2))); 3024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger path.addRect(SkRect::MakeXYWH(0, SkIntToScalar(4), 3034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(4), SkIntToScalar(2))); 3044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger for (int i = 0; i < 2; ++i) { 3064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkAAClip clip; 3074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clip.setPath(path, NULL, 1 == i); 3084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkMask mask; 3104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clip.copyToMask(&mask); 3114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger REPORTER_ASSERT(reporter, expected == mask); 3134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void test_regressions(skiatest::Reporter* reporter) { 3174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // these should not assert in the debug build 3184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // bug was introduced in rev. 3209 3194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger { 3204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkAAClip clip; 3214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRect r; 3224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger r.fLeft = SkFloatToScalar(129.892181); 3234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger r.fTop = SkFloatToScalar(10.3999996); 3244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger r.fRight = SkFloatToScalar(130.892181); 3254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger r.fBottom = SkFloatToScalar(20.3999996); 3264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clip.setRect(r, true); 3274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void TestAAClip(skiatest::Reporter* reporter) { 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_empty(reporter); 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_path_bounds(reporter); 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_irect(reporter); 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_rgn(reporter); 3354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger test_path_with_hole(reporter); 3364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger test_regressions(reporter); 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "TestClassDef.h" 3401cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerDEFINE_TESTCLASS("AAClip", AAClipTestClass, TestAAClip) 341