Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2012 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 
      8 #include "SkPaint.h"
      9 #include "SkPath.h"
     10 #include "SkRect.h"
     11 #include "SkStroke.h"
     12 #include "SkStrokeRec.h"
     13 #include "Test.h"
     14 
     15 static bool equal(const SkRect& a, const SkRect& b) {
     16     return  SkScalarNearlyEqual(a.left(), b.left()) &&
     17             SkScalarNearlyEqual(a.top(), b.top()) &&
     18             SkScalarNearlyEqual(a.right(), b.right()) &&
     19             SkScalarNearlyEqual(a.bottom(), b.bottom());
     20 }
     21 
     22 static void test_strokecubic(skiatest::Reporter* reporter) {
     23     uint32_t hexCubicVals[] = {
     24         0x424c1086, 0x44bcf0cb,  // fX=51.0161362 fY=1511.52478
     25         0x424c107c, 0x44bcf0cb,  // fX=51.0160980 fY=1511.52478
     26         0x424c10c2, 0x44bcf0cb,  // fX=51.0163651 fY=1511.52478
     27         0x424c1119, 0x44bcf0ca,  // fX=51.0166969 fY=1511.52466
     28     };
     29     SkPoint cubicVals[] = {
     30         {51.0161362f, 1511.52478f },
     31         {51.0160980f, 1511.52478f },
     32         {51.0163651f, 1511.52478f },
     33         {51.0166969f, 1511.52466f },
     34     };
     35     SkPaint paint;
     36 
     37     paint.setStyle(SkPaint::kStroke_Style);
     38     paint.setStrokeWidth(0.394537568f);
     39     SkPath path, fillPath;
     40     path.moveTo(cubicVals[0]);
     41     path.cubicTo(cubicVals[1], cubicVals[2], cubicVals[3]);
     42     paint.getFillPath(path, &fillPath);
     43     path.reset();
     44     path.moveTo(SkBits2Float(hexCubicVals[0]), SkBits2Float(hexCubicVals[1]));
     45     path.cubicTo(SkBits2Float(hexCubicVals[2]), SkBits2Float(hexCubicVals[3]),
     46             SkBits2Float(hexCubicVals[4]), SkBits2Float(hexCubicVals[5]),
     47             SkBits2Float(hexCubicVals[6]), SkBits2Float(hexCubicVals[7]));
     48     paint.getFillPath(path, &fillPath);
     49 }
     50 
     51 static void test_strokerect(skiatest::Reporter* reporter) {
     52     const SkScalar width = SkIntToScalar(10);
     53     SkPaint paint;
     54 
     55     paint.setStyle(SkPaint::kStroke_Style);
     56     paint.setStrokeWidth(width);
     57 
     58     SkRect r = { 0, 0, SkIntToScalar(200), SkIntToScalar(100) };
     59 
     60     SkRect outer(r);
     61     outer.outset(width/2, width/2);
     62 
     63     static const SkPaint::Join joins[] = {
     64         SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join
     65     };
     66 
     67     for (size_t i = 0; i < SK_ARRAY_COUNT(joins); ++i) {
     68         paint.setStrokeJoin(joins[i]);
     69 
     70         SkPath path, fillPath;
     71         path.addRect(r);
     72         paint.getFillPath(path, &fillPath);
     73 
     74         REPORTER_ASSERT(reporter, equal(outer, fillPath.getBounds()));
     75 
     76         bool isMiter = SkPaint::kMiter_Join == joins[i];
     77         SkRect nested[2];
     78         REPORTER_ASSERT(reporter, fillPath.isNestedFillRects(nested) == isMiter);
     79         if (isMiter) {
     80             SkRect inner(r);
     81             inner.inset(width/2, width/2);
     82             REPORTER_ASSERT(reporter, equal(nested[0], outer));
     83             REPORTER_ASSERT(reporter, equal(nested[1], inner));
     84         }
     85     }
     86 }
     87 
     88 static void test_strokerec_equality(skiatest::Reporter* reporter) {
     89     {
     90         SkStrokeRec s1(SkStrokeRec::kFill_InitStyle);
     91         SkStrokeRec s2(SkStrokeRec::kFill_InitStyle);
     92         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
     93 
     94         // Test that style mismatch is detected.
     95         s2.setHairlineStyle();
     96         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
     97 
     98         s1.setHairlineStyle();
     99         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    100 
    101         // ResScale is not part of equality.
    102         s1.setResScale(2.1f);
    103         s2.setResScale(1.2f);
    104         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    105         s1.setFillStyle();
    106         s2.setFillStyle();
    107         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    108         s1.setStrokeStyle(1.0f, false);
    109         s2.setStrokeStyle(1.0f, false);
    110         s1.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.9f);
    111         s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.9f);
    112         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    113     }
    114 
    115     // Stroke parameters on fill or hairline style are not part of equality.
    116     {
    117         SkStrokeRec s1(SkStrokeRec::kFill_InitStyle);
    118         SkStrokeRec s2(SkStrokeRec::kFill_InitStyle);
    119         for (int i = 0; i < 2; ++i) {
    120             s1.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.9f);
    121             s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.1f);
    122             REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    123             s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBevel_Join, 2.9f);
    124             REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    125             s2.setStrokeParams(SkPaint::kRound_Cap, SkPaint::kRound_Join, 2.9f);
    126             REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    127             s1.setHairlineStyle();
    128             s2.setHairlineStyle();
    129         }
    130     }
    131 
    132     // Stroke parameters on stroke style are part of equality.
    133     {
    134         SkStrokeRec s1(SkStrokeRec::kFill_InitStyle);
    135         SkStrokeRec s2(SkStrokeRec::kFill_InitStyle);
    136         s1.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.9f);
    137         s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.9f);
    138         s1.setStrokeStyle(1.0f, false);
    139 
    140         s2.setStrokeStyle(1.0f, true);
    141         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
    142 
    143         s2.setStrokeStyle(2.1f, false);
    144         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
    145 
    146         s2.setStrokeStyle(1.0f, false);
    147         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    148 
    149         s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kRound_Join, 2.1f);
    150         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
    151         s2.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBevel_Join, 2.9f);
    152         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
    153         s2.setStrokeParams(SkPaint::kRound_Cap, SkPaint::kRound_Join, 2.9f);
    154         REPORTER_ASSERT(reporter, !s1.hasEqualEffect(s2));
    155 
    156         // Sets fill.
    157         s1.setStrokeStyle(0.0f, true);
    158         s2.setStrokeStyle(0.0f, true);
    159         REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2));
    160     }
    161 }
    162 
    163 DEF_TEST(Stroke, reporter) {
    164     test_strokecubic(reporter);
    165     test_strokerect(reporter);
    166     test_strokerec_equality(reporter);
    167 }
    168