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