// Test that all the SkRRect entry points correctly handle un-sorted and // zero-sized input rects static void test_empty(skiatest::Reporter* reporter) { static const SkRect oooRects[] = { // out of order { 100, 0, 0, 100 }, // ooo horizontal { 0, 100, 100, 0 }, // ooo vertical { 100, 100, 0, 0 }, // ooo both }; static const SkRect emptyRects[] = { { 100, 100, 100, 200 }, // empty horizontal { 100, 100, 200, 100 }, // empty vertical { 100, 100, 100, 100 }, // empty both { 0, 0, 0, 0 } // setEmpty-empty }; static const SkVector radii[4] = { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 } }; SkRRect r; for (size_t i = 0; i < SK_ARRAY_COUNT(oooRects); ++i) { r.setRect(oooRects[i]); REPORTER_ASSERT(reporter, !r.isEmpty()); r.setOval(oooRects[i]); REPORTER_ASSERT(reporter, !r.isEmpty()); r.setRectXY(oooRects[i], 1, 2); REPORTER_ASSERT(reporter, !r.isEmpty()); r.setNinePatch(oooRects[i], 0, 1, 2, 3); REPORTER_ASSERT(reporter, !r.isEmpty()); r.setRectRadii(oooRects[i], radii); REPORTER_ASSERT(reporter, !r.isEmpty()); } for (size_t i = 0; i < SK_ARRAY_COUNT(emptyRects); ++i) { r.setRect(emptyRects[i]); REPORTER_ASSERT(reporter, r.isEmpty()); r.setOval(emptyRects[i]); REPORTER_ASSERT(reporter, r.isEmpty()); r.setRectXY(emptyRects[i], 1, 2); REPORTER_ASSERT(reporter, r.isEmpty()); r.setNinePatch(emptyRects[i], 0, 1, 2, 3); REPORTER_ASSERT(reporter, r.isEmpty()); r.setRectRadii(emptyRects[i], radii); REPORTER_ASSERT(reporter, r.isEmpty()); } }
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> 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 draw_30_60(SkCanvas* canvas, SkRRect::Corner corner, const SkVector& v, SkScalar dist, const SkPoint& center) { SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner; constexpr int kLength = 64; constexpr int kWidth = 30; switch (corner) { case SkRRect::kUpperLeft_Corner: left = SkRRect::kUpperRight_Corner; right = SkRRect::kLowerLeft_Corner; break; case SkRRect::kUpperRight_Corner: left = SkRRect::kUpperLeft_Corner; right = SkRRect::kLowerRight_Corner; break; case SkRRect::kLowerRight_Corner: left = SkRRect::kLowerLeft_Corner; right = SkRRect::kUpperRight_Corner; break; case SkRRect::kLowerLeft_Corner: left = SkRRect::kLowerRight_Corner; right = SkRRect::kUpperLeft_Corner; break; default: SkFAIL("Invalid shape."); } SkIRect r; if (fabs(v.fX) < fabs(v.fY)) { r = SkIRect::MakeWH(kLength, kWidth); } else { r = SkIRect::MakeWH(kWidth, kLength); } // 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(SkIntToScalar(kWidth), SkIntToScalar(kWidth)); radii[right] = SkVector::Make(SkIntToScalar(kWidth), SkIntToScalar(kWidth)); SkRRect rr; rr.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii); dist -= 10.0f; SkRRect occRR; occRR.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii); draw_rrect(canvas, rr, occRR); }
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); }
// 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); }
static void test_tricky_radii(skiatest::Reporter* reporter) { { // crbug.com/458522 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); path_contains_rrect_check(reporter, rr); } { // crbug.com//463920 SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0); SkVector radii[4] = { { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f, 5.0f } }; SkRRect rr; rr.setRectRadii(r, radii); path_contains_rrect_nocheck(reporter, rr); } }
static void test_tricky_radii(skiatest::Reporter* reporter) { { // crbug.com/458522 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); } { // crbug.com//463920 SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0); SkVector radii[4] = { { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f, 5.0f } }; SkRRect rr; rr.setRectRadii(r, radii); REPORTER_ASSERT(reporter, (double) rr.radii(SkRRect::kUpperRight_Corner).fY + (double) rr.radii(SkRRect::kLowerRight_Corner).fY <= rr.height()); } }
SkRRect makeRRect() { SkRRect rrect; RandomSetRRect rrectType = makeSetRRectType(); if (fPrintName) { SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetRRectNames[rrectType]); } switch (rrectType) { case kSetEmpty: rrect.setEmpty(); break; case kSetRect: { SkRect rect = makeRect(); rrect.setRect(rect); } break; case kSetOval: { SkRect oval = makeRect(); rrect.setOval(oval); } break; case kSetRectXY: { SkRect rect = makeRect(); SkScalar xRad = makeScalar(); SkScalar yRad = makeScalar(); rrect.setRectXY(rect, xRad, yRad); } break; case kSetNinePatch: { SkRect rect = makeRect(); SkScalar leftRad = makeScalar(); SkScalar topRad = makeScalar(); SkScalar rightRad = makeScalar(); SkScalar bottomRad = makeScalar(); rrect.setNinePatch(rect, leftRad, topRad, rightRad, bottomRad); SkDebugf(""); // keep locals in scope } break; case kSetRectRadii: { SkRect rect = makeRect(); SkVector radii[4]; makeVectorArray(SK_ARRAY_COUNT(radii), radii); rrect.setRectRadii(rect, radii); } break; } return rrect; }
void draw(SkCanvas* canvas) { SkRRect rrect = SkRRect::MakeRect({6.f / 7, 2.f / 3, 6.f / 7, 2.f / 3}); rrect.dumpHex(); SkRect bounds = SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */ SkBits2Float(0x3f2aaaab), /* 0.666667 */ SkBits2Float(0x3f5b6db7), /* 0.857143 */ SkBits2Float(0x3f2aaaab) /* 0.666667 */); const SkPoint corners[] = { { SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */ { SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */ { SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */ { SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */ }; SkRRect copy; copy.setRectRadii(bounds, corners); SkDebugf("rrect is " "%s" "equal to copy\n", rrect == copy ? "" : "not "); }
static void test_round_rect_transform(skiatest::Reporter* reporter) { SkRRect rrect; { SkRect r = { 0, 0, kWidth, kHeight }; rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7)); test_transform_helper(reporter, rrect); } { SkRect r = { SkIntToScalar(5), SkIntToScalar(15), SkIntToScalar(27), SkIntToScalar(34) }; SkVector radii[4] = { { 0, SkIntToScalar(1) }, { SkIntToScalar(2), SkIntToScalar(3) }, { SkIntToScalar(4), SkIntToScalar(5) }, { SkIntToScalar(6), SkIntToScalar(7) } }; rrect.setRectRadii(r, radii); test_transform_helper(reporter, rrect); } }
void DrawRect(SkiaRenderer _r, Paint _paint, Rect _rect, Point * raddis) { Renderer * r = Renderer::fromPtr(_r); SkVector skRads[4]; for (int i=0; i<4; ++i) { skRads[i] = SkPoint::Make(raddis[i].x, raddis[i].y); } SkRect rect = toSkRect(_rect); SkPaint paint; paint.setAntiAlias(true); paint.setColor(_paint.fillColor); paint.setStyle(SkPaint::kFill_Style); SkRRect rr; rr.setRectRadii(rect, skRads); r->canvas->drawRRect(rr, paint); paint.setColor(_paint.strokeColor); paint.setStrokeWidth(_paint.strokeWidth); paint.setStyle(SkPaint::kStroke_Style); r->canvas->drawRRect(rr, paint); }
void ClipDisplayItem::appendToWebDisplayItemList(const IntRect& visualRect, WebDisplayItemList* list) const { WebVector<SkRRect> webRoundedRects(m_roundedRectClips.size()); for (size_t i = 0; i < m_roundedRectClips.size(); ++i) { FloatRoundedRect::Radii rectRadii = m_roundedRectClips[i].radii(); SkVector skRadii[4]; skRadii[SkRRect::kUpperLeft_Corner].set(SkIntToScalar(rectRadii.topLeft().width()), SkIntToScalar(rectRadii.topLeft().height())); skRadii[SkRRect::kUpperRight_Corner].set(SkIntToScalar(rectRadii.topRight().width()), SkIntToScalar(rectRadii.topRight().height())); skRadii[SkRRect::kLowerRight_Corner].set(SkIntToScalar(rectRadii.bottomRight().width()), SkIntToScalar(rectRadii.bottomRight().height())); skRadii[SkRRect::kLowerLeft_Corner].set(SkIntToScalar(rectRadii.bottomLeft().width()), SkIntToScalar(rectRadii.bottomLeft().height())); SkRRect skRoundedRect; skRoundedRect.setRectRadii(m_roundedRectClips[i].rect(), skRadii); webRoundedRects[i] = skRoundedRect; } list->appendClipItem(visualRect, m_clipRect, webRoundedRects); }
GrFragmentProcessor* EllipticalRRectEffect::TestCreate(SkRandom* random, GrContext*, const GrDrawTargetCaps& caps, GrTexture*[]) { SkScalar w = random->nextRangeScalar(20.f, 1000.f); SkScalar h = random->nextRangeScalar(20.f, 1000.f); SkVector r[4]; r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); // ensure at least one corner really is elliptical do { r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].fX); SkRRect rrect; if (random->nextBool()) { // half the time create a four-radii rrect. r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); r[SkRRect::kLowerRight_Corner].fY = random->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); } GrFragmentProcessor* fp; do { GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt); fp = GrRRectEffect::Create(et, rrect); } while (NULL == fp); return fp; }
void onDrawContent(SkCanvas* canvas) override { SkPaint paintFill; SkPaint paintStroke; SkPath path; canvas->save(); canvas->translate(150, 150); canvas->scale(0.4f, 0.4f); canvas->rotate(-180.f/2.f); paintFill.setAntiAlias(true); paintFill.setColor(SK_ColorBLACK); paintStroke.setAntiAlias(true); paintStroke.setStyle(SkPaint::kStroke_Style); paintStroke.setColor(SK_ColorBLACK); paintStroke.setStrokeWidth(8); paintStroke.setStrokeCap(SkPaint::kRound_Cap); // Hour marks SkRect rect; #ifndef USE_PATH rect = SkRect::MakeLTRB(200-4, -4, 240+4, 4); SkRRect rrect; SkVector radii[4] = {{4,4}, {4,4}, {4,4}, {4,4}}; rrect.setRectRadii(rect, radii); #endif canvas->save(); for (int i=0;i<12;i++){ canvas->rotate(180.f/6.f); #ifdef USE_PATH path.reset(); path.moveTo(200,0); path.lineTo(240,0); canvas->drawPath(path, paintStroke); #else canvas->drawRRect(rrect, paintFill); #endif } canvas->restore(); // Minute marks canvas->save(); #ifdef USE_PATH paintStroke.setStrokeWidth(5); #else rect = SkRect::MakeLTRB(231.5f, -2.5f, 242.5, 2.5f); radii[0] = SkPoint::Make(2.5f,2.5f); radii[1] = SkPoint::Make(2.5f,2.5f); radii[2] = SkPoint::Make(2.5f,2.5f); radii[3] = SkPoint::Make(2.5f,2.5f); rrect.setRectRadii(rect, radii); #endif for (int i=0;i<60;i++){ if (i%5 == 0) { canvas->rotate(180.f/30.f); continue; } #ifdef USE_PATH path.reset(); path.moveTo(234,0); path.lineTo(240,0); canvas->drawPath(path, paintStroke); #else canvas->drawRRect(rrect, paintFill); #endif canvas->rotate(180.f/30.f); } canvas->restore(); SkTime::DateTime time; SkTime::GetDateTime(&time); time.fHour = time.fHour >= 12 ? time.fHour-12 : time.fHour; paintFill.setColor(SK_ColorBLACK); // Write hours canvas->save(); canvas->rotate(time.fHour*(180.f/6.f) + time.fMinute*(180.f/360.f) + time.fSecond*(180.f/21600.f) ); #ifdef USE_PATH paintStroke.setStrokeWidth(14); path.reset(); path.moveTo(-20,0); path.lineTo(80,0); canvas->drawPath(path, paintStroke); #else rect = SkRect::MakeLTRB(-20-7, -7, 80+7, 7); radii[0] = SkPoint::Make(7,7); radii[1] = SkPoint::Make(7,7); radii[2] = SkPoint::Make(7,7); radii[3] = SkPoint::Make(7,7); rrect.setRectRadii(rect, radii); canvas->drawRRect(rrect, paintFill); #endif canvas->restore(); // Write minutes canvas->save(); canvas->rotate(time.fMinute*(180.f/30.f) + time.fSecond*(180.f/1800.f) ); #ifdef USE_PATH paintStroke.setStrokeWidth(10); path.reset(); path.moveTo(-56,0); path.lineTo(224,0); canvas->drawPath(path, paintStroke); #else rect = SkRect::MakeLTRB(-56-5, -5, 224+5, 5); radii[0] = SkPoint::Make(5,5); radii[1] = SkPoint::Make(5,5); radii[2] = SkPoint::Make(5,5); radii[3] = SkPoint::Make(5,5); rrect.setRectRadii(rect, radii); canvas->drawRRect(rrect, paintFill); #endif canvas->restore(); // Write seconds canvas->save(); canvas->rotate(time.fSecond*(180.f/30.f)); paintFill.setColor(0xffd40000); paintStroke.setColor(0xffd40000); paintStroke.setStrokeWidth(6); #ifdef USE_PATH path.reset(); path.moveTo(-60,0); path.lineTo(166,0); canvas->drawPath(path, paintStroke); #else rect = SkRect::MakeLTRB(-60-3, -3, 166+3, 3); radii[0] = SkPoint::Make(3,3); radii[1] = SkPoint::Make(3,3); radii[2] = SkPoint::Make(3,3); radii[3] = SkPoint::Make(3,3); rrect.setRectRadii(rect, radii); canvas->drawRRect(rrect, paintFill); #endif rect = SkRect::MakeLTRB(-20, -20, 20, 20); #ifdef USE_PATH path.reset(); path.arcTo(rect, 0, 0, false); path.addOval(rect, SkPath::kCCW_Direction); path.arcTo(rect, 360, 0, true); canvas->drawPath(path, paintFill); #else canvas->drawOval(rect, paintFill); #endif rect = SkRect::MakeLTRB(-20+190, -20, 20+190, 20); #ifdef USE_PATH path.reset(); path.arcTo(rect, 0, 0, false); path.addOval(rect, SkPath::kCCW_Direction); path.arcTo(rect, 360, 0, true); canvas->drawPath(path, paintStroke); #else canvas->drawOval(rect, paintStroke); #endif paintFill.setColor(0xff505050); #ifdef USE_PATH rect = SkRect::MakeLTRB(-6, -6, 6, 6); path.arcTo(rect, 0, 0, false); path.addOval(rect, SkPath::kCCW_Direction); path.arcTo(rect, 360, 0, true); canvas->drawPath(path, paintFill); #else canvas->drawOval(rect, paintFill); rect = SkRect::MakeLTRB(-6, -6, 6, 6); canvas->drawOval(rect, paintFill); #endif canvas->restore(); paintStroke.setStrokeWidth(18); paintStroke.setColor(0xff325FA2); rect = SkRect::MakeLTRB(-284, -284, 284, 284); #ifdef USE_PATH path.reset(); path.arcTo(rect, 0, 0, false); path.addOval(rect, SkPath::kCCW_Direction); path.arcTo(rect, 360, 0, true); canvas->drawPath(path, paintStroke); #else canvas->drawOval(rect, paintStroke); #endif canvas->restore(); this->inval(nullptr); }
DEF_TEST(Serialization, reporter) { // Test matrix serialization { SkMatrix matrix = SkMatrix::I(); TestObjectSerialization(&matrix, reporter); } // Test path serialization { SkPath path; TestObjectSerialization(&path, reporter); } // Test region serialization { SkRegion region; TestObjectSerialization(®ion, reporter); } // Test color filter serialization { TestColorFilterSerialization(reporter); } // Test string serialization { SkString string("string"); TestObjectSerializationNoAlign<SkString, false>(&string, reporter); TestObjectSerializationNoAlign<SkString, true>(&string, reporter); } // Test rrect serialization { // SkRRect does not initialize anything. // An uninitialized SkRRect can be serialized, // but will branch on uninitialized data when deserialized. SkRRect rrect; SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30); SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} }; rrect.setRectRadii(rect, corners); SerializationTest::TestAlignment(&rrect, reporter); } // Test readByteArray { unsigned char data[kArraySize] = { 1, 2, 3 }; TestArraySerialization(data, reporter); } // Test readColorArray { SkColor data[kArraySize] = { SK_ColorBLACK, SK_ColorWHITE, SK_ColorRED }; TestArraySerialization(data, reporter); } // Test readColor4fArray { SkColor4f data[kArraySize] = { SkColor4f::FromColor(SK_ColorBLACK), SkColor4f::FromColor(SK_ColorWHITE), SkColor4f::FromColor(SK_ColorRED), { 1.f, 2.f, 4.f, 8.f } }; TestArraySerialization(data, reporter); } // Test readIntArray { int32_t data[kArraySize] = { 1, 2, 4, 8 }; TestArraySerialization(data, reporter); } // Test readPointArray { SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; TestArraySerialization(data, reporter); } // Test readScalarArray { SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; TestArraySerialization(data, reporter); } // Test invalid deserializations { SkImageInfo info = SkImageInfo::MakeN32Premul(kBitmapSize, kBitmapSize); SkBitmap validBitmap; validBitmap.setInfo(info); // Create a bitmap with a really large height SkBitmap invalidBitmap; invalidBitmap.setInfo(info.makeWH(info.width(), 1000000000)); // The deserialization should succeed, and the rendering shouldn't crash, // even when the device fails to initialize, due to its size TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter); } // Test simple SkPicture serialization { SkPictureRecorder recorder; draw_something(recorder.beginRecording(SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize), nullptr, 0)); sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture()); // Serialize picture SkBinaryWriteBuffer writer; pict->flatten(writer); size_t size = writer.bytesWritten(); SkAutoTMalloc<unsigned char> data(size); writer.writeToMemory(static_cast<void*>(data.get())); // Deserialize picture SkReadBuffer reader(static_cast<void*>(data.get()), size); sk_sp<SkPicture> readPict(SkPicture::MakeFromBuffer(reader)); REPORTER_ASSERT(reporter, reader.isValid()); REPORTER_ASSERT(reporter, readPict.get()); } TestPictureTypefaceSerialization(reporter); }
DEF_TEST(Serialization, reporter) { // Test matrix serialization { SkMatrix matrix = SkMatrix::I(); TestObjectSerialization(&matrix, reporter); } // Test path serialization { SkPath path; TestObjectSerialization(&path, reporter); } // Test region serialization { SkRegion region; TestObjectSerialization(®ion, reporter); } // Test rrect serialization { // SkRRect does not initialize anything. // An uninitialized SkRRect can be serialized, // but will branch on uninitialized data when deserialized. SkRRect rrect; SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30); SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} }; rrect.setRectRadii(rect, corners); TestAlignment(&rrect, reporter); } // Test readByteArray { unsigned char data[kArraySize] = { 1, 2, 3 }; TestArraySerialization(data, reporter); } // Test readColorArray { SkColor data[kArraySize] = { SK_ColorBLACK, SK_ColorWHITE, SK_ColorRED }; TestArraySerialization(data, reporter); } // Test readIntArray { int32_t data[kArraySize] = { 1, 2, 4, 8 }; TestArraySerialization(data, reporter); } // Test readPointArray { SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; TestArraySerialization(data, reporter); } // Test readScalarArray { SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; TestArraySerialization(data, reporter); } // Test invalid deserializations { SkImageInfo info = SkImageInfo::MakeN32Premul(kBitmapSize, kBitmapSize); SkBitmap validBitmap; validBitmap.setConfig(info); // Create a bitmap with a really large height info.fHeight = 1000000000; SkBitmap invalidBitmap; invalidBitmap.setConfig(info); // The deserialization should succeed, and the rendering shouldn't crash, // even when the device fails to initialize, due to its size TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter); } // Test simple SkPicture serialization { SkPictureRecorder recorder; bool didDraw = drawSomething(recorder.beginRecording(kBitmapSize, kBitmapSize)); REPORTER_ASSERT(reporter, didDraw); SkAutoTUnref<SkPicture> pict(recorder.endRecording()); // Serialize picture SkWriteBuffer writer(SkWriteBuffer::kValidation_Flag); pict->flatten(writer); size_t size = writer.bytesWritten(); SkAutoTMalloc<unsigned char> data(size); writer.writeToMemory(static_cast<void*>(data.get())); // Deserialize picture SkValidatingReadBuffer reader(static_cast<void*>(data.get()), size); SkAutoTUnref<SkPicture> readPict( SkPicture::CreateFromBuffer(reader)); REPORTER_ASSERT(reporter, NULL != readPict.get()); } }
static tb_bool_t gb_device_skia_draw_hint(gb_device_impl_t* device, gb_shape_ref_t hint) { // check gb_skia_device_ref_t impl = (gb_skia_device_ref_t)device; tb_assert_and_check_return_val(impl && impl->canvas && hint, tb_false); // done tb_bool_t ok = tb_false; switch (hint->type) { case GB_SHAPE_TYPE_RECT: { gb_rect_ref_t rect = &hint->u.rect; impl->canvas->drawRect(SkRect::MakeXYWH(gb_float_to_sk(rect->x), gb_float_to_sk(rect->y), gb_float_to_sk(rect->w), gb_float_to_sk(rect->h)), *impl->paint); ok = tb_true; } break; #if 0 // for lastest version case GB_SHAPE_TYPE_ROUND_RECT: { // the round rect gb_round_rect_ref_t rect = &hint->u.round_rect; // the bounds gb_rect_ref_t bounds = &hint->u.round_rect.bounds; // make rrect SkRRect rrect; SkVector radii[4]; radii[0] = SkVector::make(gb_float_to_sk(rect->rx[0]), gb_float_to_sk(rect->ry[0])); radii[1] = SkVector::make(gb_float_to_sk(rect->rx[1]), gb_float_to_sk(rect->ry[1])); radii[2] = SkVector::make(gb_float_to_sk(rect->rx[2]), gb_float_to_sk(rect->ry[2])); radii[3] = SkVector::make(gb_float_to_sk(rect->rx[3]), gb_float_to_sk(rect->ry[3])); rrect.setRectRadii(SkRect::MakeXYWH(gb_float_to_sk(bounds->x), gb_float_to_sk(bounds->y), gb_float_to_sk(bounds->w), gb_float_to_sk(bounds->h))); // draw rrect impl->canvas->drawRRect(rrect, *impl->paint); // ok ok = tb_true; } break; #endif case GB_SHAPE_TYPE_LINE: { gb_line_ref_t line = &hint->u.line; impl->canvas->drawLine(gb_float_to_sk(line->p0.x), gb_float_to_sk(line->p0.y), gb_float_to_sk(line->p1.x), gb_float_to_sk(line->p1.y), *impl->paint); ok = tb_true; } break; case GB_SHAPE_TYPE_CIRCLE: { gb_circle_ref_t circle = &hint->u.circle; impl->canvas->drawCircle(gb_float_to_sk(circle->c.x), gb_float_to_sk(circle->c.y), gb_float_to_sk(circle->r), *impl->paint); ok = tb_true; } break; case GB_SHAPE_TYPE_ELLIPSE: { gb_ellipse_ref_t ellipse = &hint->u.ellipse; impl->canvas->drawOval(SkRect::MakeXYWH(gb_float_to_sk(ellipse->c.x - ellipse->rx), gb_float_to_sk(ellipse->c.y - ellipse->ry), gb_float_to_sk(ellipse->rx + ellipse->rx), gb_float_to_sk(ellipse->ry + ellipse->ry)), *impl->paint); ok = tb_true; } break; case GB_SHAPE_TYPE_ARC: { gb_arc_ref_t arc = &hint->u.arc; impl->canvas->drawArc(SkRect::MakeXYWH(gb_float_to_sk(arc->c.x - arc->rx), gb_float_to_sk(arc->c.y - arc->ry), SkScalarMul(gb_float_to_sk(arc->rx), SkIntToScalar(2)), SkScalarMul(gb_float_to_sk(arc->ry), SkIntToScalar(2))), gb_float_to_sk(arc->ab), gb_float_to_sk(arc->an), false, *impl->paint); ok = tb_true; } break; case GB_SHAPE_TYPE_POINT: { gb_point_ref_t point = &hint->u.point; impl->canvas->drawPoint(gb_float_to_sk(point->x), gb_float_to_sk(point->y), *impl->paint); ok = tb_true; } break; default: break; } // ok? return ok; }
static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect& r, SkVector v[4]) { SkRRect rrect; rrect.setRectRadii(r, v); path_contains_rrect_check(reporter, rrect); }
DEF_TEST(Serialization, reporter) { // Test matrix serialization { SkMatrix matrix = SkMatrix::I(); TestObjectSerialization(&matrix, reporter); } // Test path serialization { SkPath path; TestObjectSerialization(&path, reporter); } // Test region serialization { SkRegion region; TestObjectSerialization(®ion, reporter); } // Test xfermode serialization { TestXfermodeSerialization(reporter); } // Test color filter serialization { TestColorFilterSerialization(reporter); } // Test string serialization { SkString string("string"); TestObjectSerializationNoAlign<SkString, false>(&string, reporter); TestObjectSerializationNoAlign<SkString, true>(&string, reporter); } // Test rrect serialization { // SkRRect does not initialize anything. // An uninitialized SkRRect can be serialized, // but will branch on uninitialized data when deserialized. SkRRect rrect; SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30); SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} }; rrect.setRectRadii(rect, corners); TestAlignment(&rrect, reporter); } // Test readByteArray { unsigned char data[kArraySize] = { 1, 2, 3 }; TestArraySerialization(data, reporter); } // Test readColorArray { SkColor data[kArraySize] = { SK_ColorBLACK, SK_ColorWHITE, SK_ColorRED }; TestArraySerialization(data, reporter); } // Test readIntArray { int32_t data[kArraySize] = { 1, 2, 4, 8 }; TestArraySerialization(data, reporter); } // Test readPointArray { SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; TestArraySerialization(data, reporter); } // Test readScalarArray { SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; TestArraySerialization(data, reporter); } // Test invalid deserializations { SkImageInfo info = SkImageInfo::MakeN32Premul(kBitmapSize, kBitmapSize); SkBitmap validBitmap; validBitmap.setInfo(info); // Create a bitmap with a really large height SkBitmap invalidBitmap; invalidBitmap.setInfo(info.makeWH(info.width(), 1000000000)); // The deserialization should succeed, and the rendering shouldn't crash, // even when the device fails to initialize, due to its size TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter); } // Test simple SkPicture serialization { SkPictureRecorder recorder; draw_something(recorder.beginRecording(SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize), nullptr, 0)); sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture()); // Serialize picture SkBinaryWriteBuffer writer; pict->flatten(writer); size_t size = writer.bytesWritten(); SkAutoTMalloc<unsigned char> data(size); writer.writeToMemory(static_cast<void*>(data.get())); // Deserialize picture SkValidatingReadBuffer reader(static_cast<void*>(data.get()), size); sk_sp<SkPicture> readPict(SkPicture::MakeFromBuffer(reader)); REPORTER_ASSERT(reporter, readPict.get()); } TestPictureTypefaceSerialization(reporter); // Test SkLightingShader/NormalMapSource serialization { const int kTexSize = 2; SkLights::Builder builder; builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), SkVector3::Make(1.0f, 0.0f, 0.0f))); builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f))); sk_sp<SkLights> fLights = builder.finish(); SkBitmap diffuse = sk_tool_utils::create_checkerboard_bitmap( kTexSize, kTexSize, sk_tool_utils::color_to_565(0x0), sk_tool_utils::color_to_565(0xFF804020), 8); SkRect bitmapBounds = SkRect::MakeIWH(diffuse.width(), diffuse.height()); SkMatrix matrix; SkRect r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize)); matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit); SkMatrix ctm; ctm.setRotate(45); SkBitmap normals; normals.allocN32Pixels(kTexSize, kTexSize); sk_tool_utils::create_frustum_normal_map(&normals, SkIRect::MakeWH(kTexSize, kTexSize)); sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(normals, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix); sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap), ctm); sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(diffuse, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix); sk_sp<SkShader> lightingShader = SkLightingShader::Make(diffuseShader, normalSource, fLights); SkAutoTUnref<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter)); lightingShader = SkLightingShader::Make(std::move(diffuseShader), nullptr, fLights); SkAutoTUnref<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter)); lightingShader = SkLightingShader::Make(nullptr, std::move(normalSource), fLights); SkAutoTUnref<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter)); lightingShader = SkLightingShader::Make(nullptr, nullptr, fLights); SkAutoTUnref<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter)); } // Test NormalBevelSource serialization { sk_sp<SkNormalSource> bevelSource = SkNormalSource::MakeBevel( SkNormalSource::BevelType::kLinear, 2.0f, 5.0f); SkAutoTUnref<SkNormalSource>(TestFlattenableSerialization(bevelSource.get(), true, reporter)); // TODO test equality? } }
DEF_TEST(Serialization, reporter) { // Test matrix serialization { SkMatrix matrix = SkMatrix::I(); TestObjectSerialization(&matrix, reporter); } // Test path serialization { SkPath path; TestObjectSerialization(&path, reporter); } // Test region serialization { SkRegion region; TestObjectSerialization(®ion, reporter); } // Test rrect serialization { // SkRRect does not initialize anything. // An uninitialized SkRRect can be serialized, // but will branch on uninitialized data when deserialized. SkRRect rrect; SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30); SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} }; rrect.setRectRadii(rect, corners); TestAlignment(&rrect, reporter); } // Test readByteArray { unsigned char data[kArraySize] = { 1, 2, 3 }; TestArraySerialization(data, reporter); } // Test readColorArray { SkColor data[kArraySize] = { SK_ColorBLACK, SK_ColorWHITE, SK_ColorRED }; TestArraySerialization(data, reporter); } // Test readIntArray { int32_t data[kArraySize] = { 1, 2, 4, 8 }; TestArraySerialization(data, reporter); } // Test readPointArray { SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; TestArraySerialization(data, reporter); } // Test readScalarArray { SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; TestArraySerialization(data, reporter); } // Test invalid deserializations { SkBitmap validBitmap; validBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 256); // Create a bitmap with a really large height SkBitmap invalidBitmap; invalidBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 1000000000); // The deserialization should succeed, and the rendering shouldn't crash, // even when the device fails to initialize, due to its size TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter); // Create a bitmap with a pixel ref too small SkImageInfo info; info.fWidth = 256; info.fHeight = 256; info.fColorType = kPMColor_SkColorType; info.fAlphaType = kPremul_SkAlphaType; SkBitmap invalidBitmap2; invalidBitmap2.setConfig(info); // Hack to force invalid, by making the pixelref smaller than its // owning bitmap. info.fWidth = 32; info.fHeight = 1; invalidBitmap2.setPixelRef(SkMallocPixelRef::NewAllocate( info, invalidBitmap2.rowBytes(), NULL))->unref(); // The deserialization should detect the pixel ref being too small and fail TestBitmapSerialization(validBitmap, invalidBitmap2, false, reporter); } }