Example #1
0
GrFillRRectOp::GrFillRRectOp(
        GrAAType aaType, const SkRRect& rrect, Flags flags,
        const SkMatrix& totalShapeMatrix, GrPaint&& paint, const SkRect& devBounds)
        : GrDrawOp(ClassID())
        , fAAType(aaType)
        , fOriginalColor(paint.getColor4f())
        , fLocalRect(rrect.rect())
        , fFlags(flags)
        , fProcessors(std::move(paint)) {
    SkASSERT((fFlags & Flags::kHasPerspective) == totalShapeMatrix.hasPerspective());
    this->setBounds(devBounds, GrOp::HasAABloat::kYes, GrOp::IsZeroArea::kNo);

    // Write the matrix attribs.
    const SkMatrix& m = totalShapeMatrix;
    if (!(fFlags & Flags::kHasPerspective)) {
        // Affine 2D transformation (float2x2 plus float2 translate).
        SkASSERT(!m.hasPerspective());
        this->writeInstanceData(m.getScaleX(), m.getSkewX(), m.getSkewY(), m.getScaleY());
        this->writeInstanceData(m.getTranslateX(), m.getTranslateY());
    } else {
        // Perspective float3x3 transformation matrix.
        SkASSERT(m.hasPerspective());
        m.get9(this->appendInstanceData<float>(9));
    }

    // Convert the radii to [-1, -1, +1, +1] space and write their attribs.
    Sk4f radiiX, radiiY;
    Sk4f::Load2(SkRRectPriv::GetRadiiArray(rrect), &radiiX, &radiiY);
    (radiiX * (2/rrect.width())).store(this->appendInstanceData<float>(4));
    (radiiY * (2/rrect.height())).store(this->appendInstanceData<float>(4));

    // We will write the color and local rect attribs during finalize().
}
void InstancedRendering::Batch::appendRRectParams(const SkRRect& rrect) {
    SkASSERT(!fIsTracked);
    switch (rrect.getType()) {
        case SkRRect::kSimple_Type: {
            const SkVector& radii = rrect.getSimpleRadii();
            this->appendParamsTexel(radii.x(), radii.y(), rrect.width(), rrect.height());
            return;
        }
        case SkRRect::kNinePatch_Type: {
            float twoOverW = 2 / rrect.width();
            float twoOverH = 2 / rrect.height();
            const SkVector& radiiTL = rrect.radii(SkRRect::kUpperLeft_Corner);
            const SkVector& radiiBR = rrect.radii(SkRRect::kLowerRight_Corner);
            this->appendParamsTexel(radiiTL.x() * twoOverW, radiiBR.x() * twoOverW,
                                    radiiTL.y() * twoOverH, radiiBR.y() * twoOverH);
            return;
        }
        case SkRRect::kComplex_Type: {
            /**
             * The x and y radii of each arc are stored in separate vectors,
             * in the following order:
             *
             *        __x1 _ _ _ x3__
             *    y1 |               | y2
             *
             *       |               |
             *
             *    y3 |__   _ _ _   __| y4
             *          x2       x4
             *
             */
            float twoOverW = 2 / rrect.width();
            float twoOverH = 2 / rrect.height();
            const SkVector& radiiTL = rrect.radii(SkRRect::kUpperLeft_Corner);
            const SkVector& radiiTR = rrect.radii(SkRRect::kUpperRight_Corner);
            const SkVector& radiiBR = rrect.radii(SkRRect::kLowerRight_Corner);
            const SkVector& radiiBL = rrect.radii(SkRRect::kLowerLeft_Corner);
            this->appendParamsTexel(radiiTL.x() * twoOverW, radiiBL.x() * twoOverW,
                                    radiiTR.x() * twoOverW, radiiBR.x() * twoOverW);
            this->appendParamsTexel(radiiTL.y() * twoOverH, radiiTR.y() * twoOverH,
                                    radiiBL.y() * twoOverH, radiiBR.y() * twoOverH);
            return;
        }
        default: return;
    }
}
Example #3
0
        void initialize(const SkRRect& rrect, const SkPoint& p, const SkVector& s) {
            objectNode = sksg::RRect::Make(rrect);
            shadowNode = sksg::RRect::Make(rrect);

            pos = p;
            spd = s;
            size = SkSize::Make(rrect.width(), rrect.height());
        }
Example #4
0
        void initialize(const SkRRect& rrect, SkColor color,
                        const SkPoint& p, const SkVector& s) {
            objectNode = make_svg_rrect(rrect);
            objectNode->setFill(SkSVGPaint(SkSVGColorType(color)));

            shadowNode = make_svg_rrect(rrect);
            shadowNode->setFillOpacity(SkSVGNumberType(kShadowOpacity));

            pos = p;
            spd = s;
            size = SkSize::Make(rrect.width(), rrect.height());
        }
Example #5
0
// Test out the case where an oval already off in space is translated/scaled 
// further off into space - yielding numerical issues when the rect & radii
// are transformed separatly
// BUG=skia:2696
static void test_issue_2696(skiatest::Reporter* reporter) {
    SkRRect rrect;
    SkRect r = { 28443.8594f, 53.1428604f, 28446.7148f, 56.0000038f };
    rrect.setOval(r);

    SkMatrix xform;
    xform.setAll(2.44f,  0.0f, 485411.7f,
                 0.0f,  2.44f,   -438.7f,
                 0.0f,   0.0f,      1.0f);
    SkRRect dst;

    bool success = rrect.transform(xform, &dst);
    REPORTER_ASSERT(reporter, success);

    SkScalar halfWidth = SkScalarHalf(dst.width());
    SkScalar halfHeight = SkScalarHalf(dst.height());

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, 
                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fX, halfWidth));
        REPORTER_ASSERT(reporter, 
                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fY, halfHeight));
    }
}