PathOpsTightBoundsTest.cpp revision 406654be7a930b484159f5bca107d3b11d8a9ede
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7#include "PathOpsExtendedTest.h" 8#include "PathOpsThreadedCommon.h" 9#include "SkCanvas.h" 10#include "SkRandom.h" 11#include "SkTArray.h" 12#include "SkTSort.h" 13#include "Test.h" 14 15static void testTightBoundsLines(PathOpsThreadState* data) { 16 SkRandom ran; 17 for (int index = 0; index < 1000; ++index) { 18 SkPath path; 19 int contourCount = ran.nextRangeU(1, 10); 20 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { 21 int lineCount = ran.nextRangeU(1, 10); 22 path.moveTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000)); 23 for (int lIndex = 0; lIndex < lineCount; ++lIndex) { 24 path.lineTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000)); 25 } 26 if (ran.nextBool()) { 27 path.close(); 28 } 29 } 30 SkRect classicBounds = path.getBounds(); 31 SkRect tightBounds; 32 REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds)); 33 REPORTER_ASSERT(data->fReporter, classicBounds == tightBounds); 34 } 35} 36 37DEF_TEST(PathOpsTightBoundsLines, reporter) { 38 initializeTests(reporter, "tightBoundsLines"); 39 PathOpsThreadedTestRunner testRunner(reporter); 40 int outerCount = reporter->allowExtendedTest() ? 100 : 1; 41 for (int index = 0; index < outerCount; ++index) { 42 for (int idx2 = 0; idx2 < 10; ++idx2) { 43 *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable, 44 (&testTightBoundsLines, 0, 0, 0, 0, &testRunner)); 45 } 46 } 47 testRunner.render(); 48} 49 50static void testTightBoundsQuads(PathOpsThreadState* data) { 51 SkRandom ran; 52 const int bitWidth = 32; 53 const int bitHeight = 32; 54 const float pathMin = 1; 55 const float pathMax = (float) (bitHeight - 2); 56 SkBitmap& bits = *data->fBitmap; 57 if (bits.width() == 0) { 58 bits.allocN32Pixels(bitWidth, bitHeight); 59 } 60 SkCanvas canvas(bits); 61 SkPaint paint; 62 for (int index = 0; index < 100; ++index) { 63 SkPath path; 64 int contourCount = ran.nextRangeU(1, 10); 65 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { 66 int lineCount = ran.nextRangeU(1, 10); 67 path.moveTo(ran.nextRangeF(1, pathMax), ran.nextRangeF(pathMin, pathMax)); 68 for (int lIndex = 0; lIndex < lineCount; ++lIndex) { 69 if (ran.nextBool()) { 70 path.lineTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax)); 71 } else { 72 path.quadTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax), 73 ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax)); 74 } 75 } 76 if (ran.nextBool()) { 77 path.close(); 78 } 79 } 80 SkRect classicBounds = path.getBounds(); 81 SkRect tightBounds; 82 REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds)); 83 REPORTER_ASSERT(data->fReporter, classicBounds.contains(tightBounds)); 84 canvas.drawColor(SK_ColorWHITE); 85 canvas.drawPath(path, paint); 86 SkIRect bitsWritten = {31, 31, 0, 0}; 87 for (int y = 0; y < bitHeight; ++y) { 88 uint32_t* addr1 = data->fBitmap->getAddr32(0, y); 89 bool lineWritten = false; 90 for (int x = 0; x < bitWidth; ++x) { 91 if (addr1[x] == (uint32_t) -1) { 92 continue; 93 } 94 lineWritten = true; 95 bitsWritten.fLeft = SkTMin(bitsWritten.fLeft, x); 96 bitsWritten.fRight = SkTMax(bitsWritten.fRight, x); 97 } 98 if (!lineWritten) { 99 continue; 100 } 101 bitsWritten.fTop = SkTMin(bitsWritten.fTop, y); 102 bitsWritten.fBottom = SkTMax(bitsWritten.fBottom, y); 103 } 104 if (!bitsWritten.isEmpty()) { 105 SkIRect tightOut; 106 tightBounds.roundOut(&tightOut); 107 REPORTER_ASSERT(data->fReporter, tightOut.contains(bitsWritten)); 108 } 109 } 110} 111 112DEF_TEST(PathOpsTightBoundsQuads, reporter) { 113 initializeTests(reporter, "tightBoundsQuads"); 114 PathOpsThreadedTestRunner testRunner(reporter); 115 int outerCount = reporter->allowExtendedTest() ? 100 : 1; 116 for (int index = 0; index < outerCount; ++index) { 117 for (int idx2 = 0; idx2 < 10; ++idx2) { 118 *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable, 119 (&testTightBoundsQuads, 0, 0, 0, 0, &testRunner)); 120 } 121 } 122 testRunner.render(); 123} 124