std::unique_ptr<GrFragmentProcessor> EllipticalRRectEffect::TestCreate(GrProcessorTestData* d) { SkScalar w = d->fRandom->nextRangeScalar(20.f, 1000.f); SkScalar h = d->fRandom->nextRangeScalar(20.f, 1000.f); SkVector r[4]; r[SkRRect::kUpperLeft_Corner].fX = d->fRandom->nextRangeF(kRadiusMin, 9.f); // ensure at least one corner really is elliptical do { r[SkRRect::kUpperLeft_Corner].fY = d->fRandom->nextRangeF(kRadiusMin, 9.f); } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].fX); SkRRect rrect; if (d->fRandom->nextBool()) { // half the time create a four-radii rrect. r[SkRRect::kLowerRight_Corner].fX = d->fRandom->nextRangeF(kRadiusMin, 9.f); r[SkRRect::kLowerRight_Corner].fY = d->fRandom->nextRangeF(kRadiusMin, 9.f); r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; rrect.setRectRadii(SkRect::MakeWH(w, h), r); } else { rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, r[SkRRect::kUpperLeft_Corner].fY); } std::unique_ptr<GrFragmentProcessor> fp; do { GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt); fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps()); } while (nullptr == fp); return fp; }
static void test_tricky_radii_crbug_458522(skiatest::Reporter* reporter) { SkRRect rr; const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; const SkScalar rad = 12814; const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, rad } }; rr.setRectRadii(bounds, vec); }
static void emit_draw(SkCanvas* canvas, DrawOpType draw, SkTDArray<DrawType>* expected) { switch (draw) { case kNone_DrawOpType: break; case kClear_DrawOpType: canvas->clear(SK_ColorRED); *expected->append() = DRAW_CLEAR; break; case kOval_DrawOpType: { SkRect r = SkRect::MakeLTRB(10, 10, 90, 90); SkPaint p; canvas->drawOval(r, p); *expected->append() = DRAW_OVAL; break; } case kRect_DrawOpType: { SkRect r = SkRect::MakeLTRB(10, 10, 90, 90); SkPaint p; canvas->drawRect(r, p); *expected->append() = DRAW_RECT; break; } case kRRect_DrawOpType: { SkRect r = SkRect::MakeLTRB(10.0f, 10.0f, 90.0f, 90.0f); SkRRect rr; rr.setRectXY(r, 5.0f, 5.0f); SkPaint p; canvas->drawRRect(rr, p); *expected->append() = DRAW_RRECT; break; } default: SkASSERT(0); } }
void SkDeferredCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { SkRect modRect = rrect.getBounds(); this->flush_check(&modRect, &paint, kNoClip_Flag); fCanvas->drawRRect(make_offset(rrect, modRect.x() - rrect.getBounds().x(), modRect.y() - rrect.getBounds().y()), paint); }
void onDraw(SkCanvas* canvas) override { canvas->scale(1.5f, 1.5f); canvas->translate(50,50); const float blurRadii[] = { 1,5,10,20 }; const int cornerRadii[] = { 1,5,10,20 }; const SkRect r = SkRect::MakeWH(SkIntToScalar(25), SkIntToScalar(25)); for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) { SkAutoCanvasRestore autoRestore(canvas, true); canvas->translate(0, (r.height() + SkIntToScalar(50)) * i); for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) { for (int k = 0; k <= 1; k++) { SkMaskFilter* filter = SkBlurMaskFilter::Create( kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])), SkBlurMaskFilter::kHighQuality_BlurFlag); SkPaint paint; paint.setColor(SK_ColorBLACK); paint.setMaskFilter(filter)->unref(); bool useRadial = SkToBool(k); if (useRadial) { paint.setShader(MakeRadial()); } SkRRect rrect; rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), SkIntToScalar(cornerRadii[j])); canvas->drawRRect(rrect, paint); canvas->translate(r.width() + SkIntToScalar(50), 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(). }
SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { SkRRect outerRRect; outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5); SkRRect innerRRect; innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3); canvas->drawDRRect(outerRRect, innerRRect, paint); return outerRRect.getBounds(); }
static void draw_rrect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { SkScalar xRad = r.width() / 4.0f; SkScalar yRad = r.height() / 4.0f; SkRRect rr; rr.setRectXY(r, xRad, yRad); canvas->drawRRect(rr, p); }
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()); }
static void test_mix(skiatest::Reporter* reporter) { // Test out mixed degenerate and non-degenerate geometry with Conics const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } }; SkRect r = SkRect::MakeWH(100, 100); SkRRect rr; rr.setRectRadii(r, radii); path_contains_rrect_check(reporter, rr); }
void draw(SkCanvas* canvas) { SkRRect rrect; SkPaint p; p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(10); canvas->drawRRect(rrect, p); rrect.setRect({10, 10, 100, 50}); canvas->drawRRect(rrect, p); }
Json::Value SkJSONCanvas::makeRRect(const SkRRect& rrect) { Json::Value result(Json::arrayValue); result.append(this->makeRect(rrect.rect())); result.append(this->makePoint(rrect.radii(SkRRect::kUpperLeft_Corner))); result.append(this->makePoint(rrect.radii(SkRRect::kUpperRight_Corner))); result.append(this->makePoint(rrect.radii(SkRRect::kLowerRight_Corner))); result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner))); return result; }
static void draw_drrect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { SkScalar xRad = r.width() / 4.0f; SkScalar yRad = r.height() / 4.0f; SkRRect outer; outer.setRectXY(r, xRad, yRad); SkRRect inner = outer; inner.inset(xRad, yRad); canvas->drawDRRect(outer, inner, p); }
void draw(SkCanvas* canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kStroke_Style); SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100); for (int index = 0; index < 25; ++index) { canvas->drawRRect(rrect, paint); rrect.outset(3, 3); } }
void draw(SkCanvas* canvas) { canvas->clear(SK_ColorWHITE); SkPaint paint; paint.setAntiAlias(true); paint.setColor(0x8055aaff); SkRRect oval; oval.setOval({10, 20, 90, 100}); canvas->clipRRect(oval, SkClipOp::kIntersect, true); canvas->drawCircle(70, 100, 60, paint); }
// http://crbug.com/472147 // This is a simplified version from the bug. RRect radii not properly scaled. static void test_crbug_472147_simple(skiatest::Reporter* reporter) { auto surface(SkSurface::MakeRasterN32Premul(1000, 1000)); SkCanvas* canvas = surface->getCanvas(); SkPaint p; SkRect r = SkRect::MakeLTRB(-246.0f, 33.0f, 848.0f, 33554464.0f); SkVector radii[4] = { { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554430.0f }, { 120.0f, 5.0f } }; SkRRect rr; rr.setRectRadii(r, radii); canvas->drawRRect(rr, p); }
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()); }
static void test_empty_crbug_458524(skiatest::Reporter* reporter) { SkRRect rr; const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; const SkScalar rad = 40; rr.setRectXY(bounds, rad, rad); SkRRect other; SkMatrix matrix; matrix.setScale(0, 1); rr.transform(matrix, &other); REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == other.getType()); }
void draw(SkCanvas* canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(16); SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30); canvas->drawRRect(rrect, paint); canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint); rrect.setRectXY(rrect.getBounds(), 35, 25); canvas->translate(128, 0); canvas->drawRRect(rrect, paint); canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint); }
PassRefPtr<JSONObject> LoggingCanvas::objectForSkRRect(const SkRRect& rrect) { RefPtr<JSONObject> rrectItem = JSONObject::create(); rrectItem->setString("type", rrectTypeName(rrect.type())); rrectItem->setNumber("left", rrect.rect().left()); rrectItem->setNumber("top", rrect.rect().top()); rrectItem->setNumber("right", rrect.rect().right()); rrectItem->setNumber("bottom", rrect.rect().bottom()); for (int i = 0; i < 4; ++i) rrectItem->setObject(radiusName((SkRRect::Corner) i), objectForRadius(rrect, (SkRRect::Corner) i)); return rrectItem.release(); }
static void test_empty_crbug_458524(skiatest::Reporter* reporter) { SkRRect rr; const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; const SkScalar rad = 40; rr.setRectXY(bounds, rad, rad); path_contains_rrect_check(reporter, rr); SkRRect other; SkMatrix matrix; matrix.setScale(0, 1); rr.transform(matrix, &other); path_contains_rrect_check(reporter, rr); }
// Two pictures with a round rect clip on the second one static void rrect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) { canvas->drawPicture(pictures[0]); SkRect rect = pictures[0]->cullRect(); rect.inset(kInset, kInset); SkRRect rrect; rrect.setRectXY(rect, kInset, kInset); canvas->clipRRect(rrect); canvas->drawPicture(pictures[1]); }
// The tallest inset rect SkRect compute_tallest_occluder(const SkRRect& rr) { const SkRect& r = rr.getBounds(); const SkVector& ul = rr.radii(SkRRect::kUpperLeft_Corner); const SkVector& ur = rr.radii(SkRRect::kUpperRight_Corner); const SkVector& lr = rr.radii(SkRRect::kLowerRight_Corner); const SkVector& ll = rr.radii(SkRRect::kLowerLeft_Corner); SkScalar maxL = SkTMax(ul.fX, ll.fX); SkScalar maxR = SkTMax(ur.fX, lr.fX); return SkRect::MakeLTRB(r.fLeft + maxL, r.fTop, r.fRight - maxR, r.fBottom); }
DEF_TEST(CanvasState_test_soft_clips, reporter) { SkBitmap bitmap; bitmap.allocN32Pixels(10, 10); SkCanvas canvas(bitmap); SkRRect roundRect; roundRect.setOval(SkRect::MakeWH(5, 5)); canvas.clipRRect(roundRect, SkCanvas::kIntersect_Op, true); SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas); REPORTER_ASSERT(reporter, !state); }
static void draw_45(SkCanvas* canvas, SkRRect::Corner corner, SkScalar dist, const SkPoint& center) { SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner; SkVector dir = { 0, 0 }; constexpr SkScalar kSize = 64.0f / SK_ScalarSqrt2; switch (corner) { case SkRRect::kUpperLeft_Corner: left = SkRRect::kUpperRight_Corner; right = SkRRect::kLowerLeft_Corner; dir.set(-SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2); break; case SkRRect::kUpperRight_Corner: left = SkRRect::kUpperLeft_Corner; right = SkRRect::kLowerRight_Corner; dir.set(SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2); break; case SkRRect::kLowerRight_Corner: left = SkRRect::kLowerLeft_Corner; right = SkRRect::kUpperRight_Corner; dir.set(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2); break; case SkRRect::kLowerLeft_Corner: left = SkRRect::kLowerRight_Corner; right = SkRRect::kUpperLeft_Corner; dir.set(-SK_ScalarRoot2Over2, SK_ScalarRoot2Over2); break; default: SkFAIL("Invalid shape."); } SkRect r = SkRect::MakeWH(kSize, kSize); // UL, UR, LR, LL SkVector radii[4] = { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } }; radii[left] = SkVector::Make(kSize, kSize); radii[right] = SkVector::Make(kSize, kSize); SkRRect rr; rr.setRectRadii( offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY), radii); SkRRect occRR; dist -= 10.0f; occRR.setRectRadii( offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY), radii); draw_rrect(canvas, rr, occRR); }
std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::TestCreate(GrProcessorTestData* d) { SkScalar w = d->fRandom->nextRangeScalar(20.f, 1000.f); SkScalar h = d->fRandom->nextRangeScalar(20.f, 1000.f); SkScalar r = d->fRandom->nextRangeF(kRadiusMin, 9.f); SkRRect rrect; rrect.setRectXY(SkRect::MakeWH(w, h), r, r); std::unique_ptr<GrFragmentProcessor> fp; do { GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt); fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps()); } while (nullptr == fp); return fp; }
// The widest inset rect SkRect compute_widest_occluder(const SkRRect& rr) { const SkRect& r = rr.getBounds(); const SkVector& ul = rr.radii(SkRRect::kUpperLeft_Corner); const SkVector& ur = rr.radii(SkRRect::kUpperRight_Corner); const SkVector& lr = rr.radii(SkRRect::kLowerRight_Corner); const SkVector& ll = rr.radii(SkRRect::kLowerLeft_Corner); SkScalar maxT = SkTMax(ul.fY, ur.fY); SkScalar maxB = SkTMax(ll.fY, lr.fY); return SkRect::MakeLTRB(r.fLeft, r.fTop + maxT, r.fRight, r.fBottom - maxB); }
const GrFragmentProcessor* CircularRRectEffect::TestCreate(GrProcessorTestData* d) { SkScalar w = d->fRandom->nextRangeScalar(20.f, 1000.f); SkScalar h = d->fRandom->nextRangeScalar(20.f, 1000.f); SkScalar r = d->fRandom->nextRangeF(kRadiusMin, 9.f); SkRRect rrect; rrect.setRectXY(SkRect::MakeWH(w, h), r, r); GrFragmentProcessor* fp; do { GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt); fp = GrRRectEffect::Create(et, rrect); } while (nullptr == fp); return fp; }
void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { if (rrect.isRect()) { addDraw(DRAW_RECT); addPaint(paint); addRect(rrect.getBounds()); } else if (rrect.isOval()) { addDraw(DRAW_OVAL); addPaint(paint); addRect(rrect.getBounds()); } else { addDraw(DRAW_RRECT); addPaint(paint); addRRect(rrect); } validate(); }
PassRefPtr<JSONObject> LoggingCanvas::objectForRadius(const SkRRect& rrect, SkRRect::Corner corner) { RefPtr<JSONObject> radiusItem = JSONObject::create(); SkVector radius = rrect.radii(corner); radiusItem->setNumber("xRadius", radius.x()); radiusItem->setNumber("yRadius", radius.y()); return radiusItem.release(); }