From 614257033805783be808a3329e1d85c1cc9c32c7 Mon Sep 17 00:00:00 2001 From: blakdragan7 Date: Sat, 7 Sep 2024 17:09:16 +0000 Subject: [PATCH] skia removal overstroke.cpp strokefill.cpp still needs the contour work for overstroke.cpp Diffs= 5eadf5c17 skia removal (#8088) Co-authored-by: blakdragan7 Co-authored-by: hernan --- .rive_head | 2 +- tests/gm/gmutils.cpp | 12 +++ tests/gm/gmutils.hpp | 4 + tests/gm/overstroke.cpp | 178 +++++++++++++++++----------------------- tests/gm/strokefill.cpp | 157 +++++++++++++++++++---------------- 5 files changed, 180 insertions(+), 173 deletions(-) diff --git a/.rive_head b/.rive_head index a051d516..62a30598 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -722e60461d469d4d394ab1f901cac1ee3319d372 +5eadf5c17364cdfd9d31c92ba9a2e45843d278c9 diff --git a/tests/gm/gmutils.cpp b/tests/gm/gmutils.cpp index fe25048d..4711f39b 100644 --- a/tests/gm/gmutils.cpp +++ b/tests/gm/gmutils.cpp @@ -118,6 +118,18 @@ void draw_image(rive::Renderer* ren, rive::RenderImage* img, rive::AABB dst) ren->restore(); } +rive::rcp renderPathFromRawPath(rive::RawPath& path, + const rive::FillRule fillRule) +{ + auto factory = TestingWindow::Get()->factory(); + // this causes crash paths that have a call to addQuad. + // auto renderPath = factory->makeRenderPath(path, fillRule); + // this does not crash + auto renderPath = factory->makeEmptyRenderPath(); + path.addTo(renderPath.get()); + return renderPath; +} + PathBuilder& PathBuilder::fillRule(rive::FillRule f) { m_Path->fillRule(f); diff --git a/tests/gm/gmutils.hpp b/tests/gm/gmutils.hpp index 221d6cdb..b0cb2c0a 100644 --- a/tests/gm/gmutils.hpp +++ b/tests/gm/gmutils.hpp @@ -91,6 +91,10 @@ void draw_rect(rive::Renderer* r, rive::AABB rect, rive::RenderPaint*); void draw_oval(rive::Renderer* r, rive::AABB rect, rive::RenderPaint*); void draw_image(rive::Renderer*, rive::RenderImage*, rive::AABB); +rive::rcp renderPathFromRawPath( + rive::RawPath& path, + const rive::FillRule fillRule = rive::FillRule::nonZero); + class PathBuilder { public: diff --git a/tests/gm/overstroke.cpp b/tests/gm/overstroke.cpp index 79294aa4..a43f4c32 100644 --- a/tests/gm/overstroke.cpp +++ b/tests/gm/overstroke.cpp @@ -22,17 +22,14 @@ #include "gm.hpp" #include "gmutils.hpp" #include "rive/renderer.hpp" -#include "skia/include/core/SkColor.h" -#include "skia/include/core/SkMatrix.h" -#include "skia/include/core/SkScalar.h" -#include "skia/include/core/SkPathBuilder.h" -#include "skia/include/core/SkPathMeasure.h" +#include "rive/math/vec2d.hpp" +#include "rive/math/contour_measure.hpp" using namespace rivegm; using namespace rive; -const SkScalar OVERSTROKE_WIDTH = 500.0f; -const SkScalar NORMALSTROKE_WIDTH = 3.0f; +const float OVERSTROKE_WIDTH = 500.0f; +const float NORMALSTROKE_WIDTH = 3.0f; //////// path and paint builders @@ -41,7 +38,7 @@ Paint make_normal_paint() Paint p; p->style(RenderPaintStyle::stroke); p->thickness(NORMALSTROKE_WIDTH); - p->color(SK_ColorBLUE); + p->color(0xff0000ff); return p; } @@ -55,37 +52,62 @@ Paint make_overstroke_paint() return p; } -Path quad_path(SkPath* skpath) +RawPath quad_path() { - *skpath = SkPathBuilder().moveTo(0, 0).lineTo(100, 0).quadTo(50, -40, 0, 0).close().detach(); - return PathBuilder().moveTo(0, 0).lineTo(100, 0).quadTo(50, -40, 0, 0).close().detach(); + RawPath path; + path.moveTo(0, 0); + path.lineTo(100, 0); + path.quadTo(50, -40, 0, 0); + path.close(); + return path; } -Path cubic_path(SkPath* skpath) +RawPath cubic_path() { - skpath->moveTo(0, 0); - skpath->cubicTo(25, 75, 75, -50, 100, 0); - - Path path; - path->moveTo(0, 0); - path->cubicTo(25, 75, 75, -50, 100, 0); - + RawPath path; + path.moveTo(0, 0); + path.cubicTo(25, 75, 75, -50, 100, 0); return path; } -Path oval_path(SkPath* skpath) +RawPath oval_path() { - *skpath = SkPathBuilder().arcTo({0, -25, 100, 25}, 0, 359, true).close().detach(); - return PathBuilder().addOval({0, -25, 100, 25}).close().detach(); + RawPath path; + path.addOval({0, -25, 100, 25}); + return path; } -Path ribs_path(const SkPath& skpath, SkScalar radius) +Path ribs_path(const RawPath& path, float radius) { Path ribs; - const SkScalar spacing = 5.0f; + const float spacing = 5.0f; float accum = 0.0f; + ContourMeasureIter iter(&path); + while (auto meas = iter.next()) + { + while (accum < meas->length()) + { + auto posTan = meas->getPosTan(accum); + Vec2D pos = posTan.pos; + // there appeara to be a bug somewhere that is not normalizing this when it should, + // so i am doing it here + Vec2D tan = posTan.tan.normalized(); + tan = {tan.y * radius, -tan.x * radius}; + + Vec2D start = pos + tan; + Vec2D end = pos - tan; + + ribs->moveTo(start.x, start.y); + ribs->lineTo(end.x, end.y); + + accum += spacing; + } + accum += meas->length(); + } + + /* SkPathMeasure meas(skpath, false); SkScalar length = meas.getLength(); SkPoint pos; @@ -102,16 +124,17 @@ Path ribs_path(const SkPath& skpath, SkScalar radius) } accum += spacing; } + */ return ribs; } -void draw_ribs(Renderer* canvas, const SkPath& skpath) +void draw_ribs(Renderer* canvas, const RawPath& path) { - Path ribs = ribs_path(skpath, OVERSTROKE_WIDTH / 2.0f); + Path ribs = ribs_path(path, OVERSTROKE_WIDTH / 2.0f); Paint p = make_normal_paint(); p->thickness(1); - p->color(SK_ColorGREEN); + p->color(0xff00ff00); canvas->drawPath(ribs, p); } @@ -124,45 +147,29 @@ void draw_small_quad(Renderer* canvas) // canvas->scale(8, 8); Paint p = make_normal_paint(); - SkPath skpath; - Path path = quad_path(&skpath); + RawPath path = quad_path(); - draw_ribs(canvas, skpath); - canvas->drawPath(path, p); + auto renderPath = renderPathFromRawPath(path); + + draw_ribs(canvas, path); + canvas->drawPath(renderPath.get(), p); } void draw_large_quad(Renderer* canvas) { Paint p = make_overstroke_paint(); - SkPath skpath; - Path path = quad_path(&skpath); + RawPath path = quad_path(); - canvas->drawPath(path, p); - draw_ribs(canvas, skpath); -} + auto renderPath = renderPathFromRawPath(path); -#if 0 -void draw_quad_fillpath(Renderer* canvas) { - Path path = quad_path(); - Paint p = make_overstroke_paint(); - - Paint fillp = make_normal_paint(); - fillp->color(SK_ColorMAGENTA); - - Path fillpath; - p.getFillPath(path, &fillpath); - - canvas->drawPath(fillpath, fillp); + canvas->drawPath(renderPath.get(), p); + draw_ribs(canvas, path); } -#endif void draw_stroked_quad(Renderer* canvas) { canvas->translate(400, 0); draw_large_quad(canvas); -#if 0 - draw_quad_fillpath(canvas); -#endif } ////////// cubics @@ -170,45 +177,29 @@ void draw_stroked_quad(Renderer* canvas) void draw_small_cubic(Renderer* canvas) { Paint p = make_normal_paint(); - SkPath skpath; - Path path = cubic_path(&skpath); + RawPath path = cubic_path(); + + auto renderPath = renderPathFromRawPath(path); - draw_ribs(canvas, skpath); - canvas->drawPath(path, p); + draw_ribs(canvas, path); + canvas->drawPath(renderPath.get(), p); } void draw_large_cubic(Renderer* canvas) { Paint p = make_overstroke_paint(); - SkPath skpath; - Path path = cubic_path(&skpath); - - canvas->drawPath(path, p); - draw_ribs(canvas, skpath); -} - -#if 0 -void draw_cubic_fillpath(SkCanvas* canvas) { - Path path = cubic_path(); - Paint p = make_overstroke_paint(); - - SkPaint fillp = make_normal_paint(); - fillp.setColor(SK_ColorMAGENTA); + RawPath path = cubic_path(); - SkPath fillpath; - p.getFillPath(path, &fillpath); + auto renderPath = renderPathFromRawPath(path); - canvas->drawPath(fillpath, fillp); + canvas->drawPath(renderPath.get(), p); + draw_ribs(canvas, path); } -#endif void draw_stroked_cubic(Renderer* canvas) { canvas->translate(400, 0); draw_large_cubic(canvas); -#if 0 - draw_cubic_fillpath(canvas); -#endif } ////////// ovals @@ -216,46 +207,29 @@ void draw_stroked_cubic(Renderer* canvas) void draw_small_oval(Renderer* canvas) { Paint p = make_normal_paint(); + RawPath path = oval_path(); - SkPath skpath; - Path path = oval_path(&skpath); + auto renderPath = renderPathFromRawPath(path); - draw_ribs(canvas, skpath); - canvas->drawPath(path, p); + draw_ribs(canvas, path); + canvas->drawPath(renderPath.get(), p); } void draw_large_oval(Renderer* canvas) { Paint p = make_overstroke_paint(); - SkPath skpath; - Path path = oval_path(&skpath); - - canvas->drawPath(path, p); - draw_ribs(canvas, skpath); -} - -#if 0 -void draw_oval_fillpath(SkCanvas* canvas) { - Path path = oval_path(); - Paint p = make_overstroke_paint(); - - SkPaint fillp = make_normal_paint(); - fillp.setColor(SK_ColorMAGENTA); + RawPath path = oval_path(); - SkPath fillpath; - p.getFillPath(path, &fillpath); + auto renderPath = renderPathFromRawPath(path); - canvas->drawPath(fillpath, fillp); + canvas->drawPath(renderPath.get(), p); + draw_ribs(canvas, path); } -#endif void draw_stroked_oval(Renderer* canvas) { canvas->translate(400, 0); draw_large_oval(canvas); -#if 0 - draw_oval_fillpath(canvas); -#endif } ////////// gm diff --git a/tests/gm/strokefill.cpp b/tests/gm/strokefill.cpp index 462987ce..dcc6eea0 100644 --- a/tests/gm/strokefill.cpp +++ b/tests/gm/strokefill.cpp @@ -9,26 +9,22 @@ #include "gm.hpp" #include "gmutils.hpp" #include "rive/renderer.hpp" -#include "skia/include/core/SkColor.h" -#include "skia/include/core/SkMatrix.h" -#include "skia/include/core/SkScalar.h" -#include "skia/include/core/SkPathBuilder.h" -#include "skia/include/core/SkPathMeasure.h" +#include "rive/math/math_types.hpp" using namespace rivegm; using namespace rive; -static const SkScalar kStdFakeBoldInterpKeys[] = { - SK_Scalar1 * 9, - SK_Scalar1 * 36, +static const float kStdFakeBoldInterpKeys[] = { + 1.0f * 9, + 1.0f * 36, }; -static const SkScalar kStdFakeBoldInterpValues[] = { - SK_Scalar1 / 24, - SK_Scalar1 / 32, +static const float kStdFakeBoldInterpValues[] = { + 1.0f / 24, + 1.0f / 32, }; -static_assert(SK_ARRAY_COUNT(kStdFakeBoldInterpKeys) == SK_ARRAY_COUNT(kStdFakeBoldInterpValues), +static_assert(std::size(kStdFakeBoldInterpKeys) == std::size(kStdFakeBoldInterpValues), "mismatched_array_size"); -static const int kStdFakeBoldInterpLength = SK_ARRAY_COUNT(kStdFakeBoldInterpKeys); +static const int kStdFakeBoldInterpLength = std::size(kStdFakeBoldInterpKeys); /* Generated on a Mac with: * paint.setTypeface(SkTypeface::CreateByName("Papyrus")); @@ -247,26 +243,51 @@ static Path hiragino_maru_gothic_pro_dash() return path; } -#if 0 -static void show_bold(SkCanvas* canvas, const char* text, - SkScalar x, SkScalar y, const Paint& paint, const SkFont& font) { - canvas->drawString(text, x, y, font, paint); - SkFont f(font); - f.setEmbolden(true); - canvas->drawString(text, x, y + 120, f, paint); -} +float lerp(float a, float b, float t) { return a + t * (b - a); } + +float scalarInterpFunc(float searchKey, const float keys[], const float values[], int length) +{ + assert(length > 0); + assert(keys != nullptr); + assert(values != nullptr); +#ifdef RIVE_DEBUG + for (int i = 1; i < length; i++) + { + assert(keys[i - 1] <= keys[i]); + } #endif + int right = 0; + while (right < length && keys[right] < searchKey) + { + ++right; + } + // Could use sentinel values to eliminate conditionals, but since the + // tables are taken as input, a simpler format is better. + if (right == length) + { + return values[length - 1]; + } + if (right == 0) + { + return values[0]; + } + // Otherwise, interpolate between right - 1 and right. + float leftKey = keys[right - 1]; + float rightKey = keys[right]; + float fract = (searchKey - leftKey) / (rightKey - leftKey); + return lerp(values[right - 1], values[right], fract); +} static void path_bold(Renderer* canvas, const Path& path, float textSize) { Paint p; - p->thickness(SkIntToScalar(5)); + p->thickness(static_cast(5)); canvas->drawPath(path, p); - SkScalar fakeBoldScale = SkScalarInterpFunc(textSize, - kStdFakeBoldInterpKeys, - kStdFakeBoldInterpValues, - kStdFakeBoldInterpLength); - SkScalar extra = textSize * fakeBoldScale; + float fakeBoldScale = scalarInterpFunc(textSize, + kStdFakeBoldInterpKeys, + kStdFakeBoldInterpValues, + kStdFakeBoldInterpLength); + float extra = textSize * fakeBoldScale; p->thickness(extra); canvas->save(); canvas->translate(0, 120); @@ -280,79 +301,75 @@ static AABB xywh(float x, float y, float w, float h) { return {x, y, x + w, y + DEF_SIMPLE_GM(strokefill, 640, 480, canvas) { - SkScalar x = SkIntToScalar(100); - SkScalar y = SkIntToScalar(88); + float x = static_cast(100); + float y = static_cast(88); -#if 0 - // use the portable typeface to generically test the fake bold code everywhere - // (as long as the freetype option to do the bolding itself isn't enabled) - SkFont font(ToolUtils::create_portable_typeface("serif", SkFontStyle()), 100); -#endif Paint paint; - paint->thickness(SkIntToScalar(5)); + paint->thickness(static_cast(5)); // use paths instead of text to test the path data on all platforms, since the // Mac-specific font may change or is not available everywhere path_bold(canvas, papyrus_hello(), 100); path_bold(canvas, hiragino_maru_gothic_pro_dash(), 100); -#if 0 - show_bold(canvas, "Hi There", x + SkIntToScalar(430), y, paint, font); -#endif - PathBuilder b; b.fillRule(FillRule::nonZero); - b.addCircle(x, y + SkIntToScalar(200), SkIntToScalar(50), rivegm::PathDirection::cw); - b.addCircle(x, y + SkIntToScalar(200), SkIntToScalar(40), rivegm::PathDirection::ccw); + b.addCircle(x, y + static_cast(200), static_cast(50), rivegm::PathDirection::cw); + b.addCircle(x, y + static_cast(200), static_cast(40), rivegm::PathDirection::ccw); canvas->drawPath(b.detach(), paint); - b.addCircle(x + SkIntToScalar(120), - y + SkIntToScalar(200), - SkIntToScalar(50), + b.addCircle(x + static_cast(120), + y + static_cast(200), + static_cast(50), rivegm::PathDirection::ccw); - b.addCircle(x + SkIntToScalar(120), - y + SkIntToScalar(200), - SkIntToScalar(40), + b.addCircle(x + static_cast(120), + y + static_cast(200), + static_cast(40), rivegm::PathDirection::cw); canvas->drawPath(b.detach(), paint); - b.addCircle(x + SkIntToScalar(240), - y + SkIntToScalar(200), - SkIntToScalar(50), + b.addCircle(x + static_cast(240), + y + static_cast(200), + static_cast(50), rivegm::PathDirection::ccw); canvas->drawPath(b.detach(), paint); - b.addCircle(x + SkIntToScalar(360), - y + SkIntToScalar(200), - SkIntToScalar(50), + b.addCircle(x + static_cast(360), + y + static_cast(200), + static_cast(50), rivegm::PathDirection::cw); canvas->drawPath(b.detach(), paint); - AABB r = - xywh(x - SkIntToScalar(50), y + SkIntToScalar(280), SkIntToScalar(100), SkIntToScalar(100)); + AABB r = xywh(x - static_cast(50), + y + static_cast(280), + static_cast(100), + static_cast(100)); b.addRect(r, rivegm::PathDirection::cw); - r = r.inset(SkIntToScalar(10), SkIntToScalar(10)); + r = r.inset(static_cast(10), static_cast(10)); b.addRect(r, rivegm::PathDirection::ccw); canvas->drawPath(b.detach(), paint); - r = xywh(x + SkIntToScalar(70), y + SkIntToScalar(280), SkIntToScalar(100), SkIntToScalar(100)); + r = xywh(x + static_cast(70), + y + static_cast(280), + static_cast(100), + static_cast(100)); b.addRect(r, rivegm::PathDirection::ccw); - r = r.inset(SkIntToScalar(10), SkIntToScalar(10)); + r = r.inset(static_cast(10), static_cast(10)); b.addRect(r, rivegm::PathDirection::cw); canvas->drawPath(b.detach(), paint); - r = xywh(x + SkIntToScalar(190), - y + SkIntToScalar(280), - SkIntToScalar(100), - SkIntToScalar(100)); + r = xywh(x + static_cast(190), + y + static_cast(280), + static_cast(100), + static_cast(100)); b.addRect(r, rivegm::PathDirection::ccw); b.moveTo(0, 0); // test for crbug.com/247770 canvas->drawPath(b.detach(), paint); - r = xywh(x + SkIntToScalar(310), - y + SkIntToScalar(280), - SkIntToScalar(100), - SkIntToScalar(100)); + r = xywh(x + static_cast(310), + y + static_cast(280), + static_cast(100), + static_cast(100)); b.addRect(r, rivegm::PathDirection::cw); b.moveTo(0, 0); // test for crbug.com/247770 canvas->drawPath(b.detach(), paint); @@ -374,11 +391,11 @@ DEF_SIMPLE_GM(bug339297, 640, 480, canvas) canvas->translate(258, 10365663); Paint paint; - paint->color(SK_ColorBLACK); + paint->color(0xff000000); paint->style(RenderPaintStyle::fill); canvas->drawPath(path, paint); - paint->color(SK_ColorRED); + paint->color(0xffff0000); paint->style(RenderPaintStyle::stroke); paint->thickness(1); canvas->drawPath(path, paint); @@ -402,14 +419,14 @@ DEF_SIMPLE_GM(bug339297_as_clip, 640, 480, canvas) canvas->save(); canvas->clipPath(path); Paint clearPaint; - clearPaint->color(SK_ColorBLACK); + clearPaint->color(0xff000000); const float b = 1e9f; draw_rect(canvas, {-b, -b, b, b}, clearPaint); canvas->restore(); Paint paint; paint->style(RenderPaintStyle::fill); - paint->color(SK_ColorRED); + paint->color(0xffff0000); paint->style(RenderPaintStyle::stroke); paint->thickness(1); canvas->drawPath(path, paint);