DEF_TEST(Geometry, reporter) { SkPoint pts[3], dst[5]; pts[0].set(0, 0); pts[1].set(100, 50); pts[2].set(0, 100); int count = SkChopQuadAtMaxCurvature(pts, dst); REPORTER_ASSERT(reporter, count == 1 || count == 2); pts[0].set(0, 0); pts[1].set(3, 0); pts[2].set(3, 3); SkConvertQuadToCubic(pts, dst); const SkPoint cubic[] = { { 0, 0, }, { 2, 0, }, { 3, 1, }, { 3, 3 }, }; for (int i = 0; i < 4; ++i) { REPORTER_ASSERT(reporter, nearly_equal(cubic[i], dst[i])); } testChopCubic(reporter); test_evalquadat(reporter); test_conic(reporter); test_cubic_tangents(reporter); test_quad_tangents(reporter); test_conic_tangents(reporter); }
static void TestGeometry(skiatest::Reporter* reporter) { SkPoint pts[3], dst[5]; pts[0].set(0, 0); pts[1].set(100, 50); pts[2].set(0, 100); int count = SkChopQuadAtMaxCurvature(pts, dst); REPORTER_ASSERT(reporter, count == 1 || count == 2); pts[0].set(0, 0); pts[1].set(SkIntToScalar(3), 0); pts[2].set(SkIntToScalar(3), SkIntToScalar(3)); SkConvertQuadToCubic(pts, dst); const SkPoint cubic[] = { { 0, 0, }, { SkIntToScalar(2), 0, }, { SkIntToScalar(3), SkIntToScalar(1), }, { SkIntToScalar(3), SkIntToScalar(3) }, }; for (int i = 0; i < 4; ++i) { REPORTER_ASSERT(reporter, nearly_equal(cubic[i], dst[i])); } testChopCubic(reporter); }
// static void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle, SkWStream* content) { // Filling a path with no area results in a drawing in PDF renderers but // Chrome expects to be able to draw some such entities with no visible // result, so we detect those cases and discard the drawing for them. // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y). enum SkipFillState { kEmpty_SkipFillState = 0, kSingleLine_SkipFillState = 1, kNonSingleLine_SkipFillState = 2, }; SkipFillState fillState = kEmpty_SkipFillState; if (paintStyle != SkPaint::kFill_Style) { fillState = kNonSingleLine_SkipFillState; } SkPoint lastMovePt = SkPoint::Make(0,0); SkDynamicMemoryWStream currentSegment; SkPoint args[4]; SkPath::Iter iter(path, false); for (SkPath::Verb verb = iter.next(args); verb != SkPath::kDone_Verb; verb = iter.next(args)) { // args gets all the points, even the implicit first point. switch (verb) { case SkPath::kMove_Verb: MoveTo(args[0].fX, args[0].fY, ¤tSegment); lastMovePt = args[0]; fillState = kEmpty_SkipFillState; break; case SkPath::kLine_Verb: AppendLine(args[1].fX, args[1].fY, ¤tSegment); if (fillState == kEmpty_SkipFillState) { if (args[0] != lastMovePt) { fillState = kSingleLine_SkipFillState; } } else if (fillState == kSingleLine_SkipFillState) { fillState = kNonSingleLine_SkipFillState; } break; case SkPath::kQuad_Verb: { SkPoint cubic[4]; SkConvertQuadToCubic(args, cubic); AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, cubic[3].fX, cubic[3].fY, ¤tSegment); fillState = kNonSingleLine_SkipFillState; break; } case SkPath::kCubic_Verb: AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY, args[3].fX, args[3].fY, ¤tSegment); fillState = kNonSingleLine_SkipFillState; break; case SkPath::kClose_Verb: if (fillState != kSingleLine_SkipFillState) { ClosePath(¤tSegment); SkData* data = currentSegment.copyToData(); content->write(data->data(), data->size()); data->unref(); } currentSegment.reset(); break; default: SkASSERT(false); break; } } if (currentSegment.bytesWritten() > 0) { SkData* data = currentSegment.copyToData(); content->write(data->data(), data->size()); data->unref(); } }