From df3d225e80f20c0b1c35cf02ef4dd6001de2e13a Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Thu, 20 Dec 2018 17:10:27 -0500 Subject: [PATCH] use SkFont for measuring and paths Bug: skia: Change-Id: I1810edfef6e04be0380bac0eeab5450fe302e078 Reviewed-on: https://skia-review.googlesource.com/c/179728 Reviewed-by: Mike Reed Commit-Queue: Mike Reed --- gm/drawatlas.cpp | 23 +++++++++++++---------- gm/highcontrastfilter.cpp | 13 ++++++++----- tests/PathTest.cpp | 18 ++++++++++++++---- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/gm/drawatlas.cpp b/gm/drawatlas.cpp index a06668fe7b..5997bf6dd1 100644 --- a/gm/drawatlas.cpp +++ b/gm/drawatlas.cpp @@ -11,6 +11,7 @@ #include "SkCanvas.h" #include "SkRSXform.h" #include "SkSurface.h" +#include "SkTextBlob.h" #include "sk_tool_utils.h" class DrawAtlasGM : public skiagm::GM { @@ -104,12 +105,10 @@ DEF_GM( return new DrawAtlasGM; ) #include "SkPathMeasure.h" static void draw_text_on_path(SkCanvas* canvas, const void* text, size_t length, - const SkPoint xy[], const SkPath& path, const SkPaint& paint, + const SkPoint xy[], const SkPath& path, const SkFont& font, const SkPaint& paint, float baseline_offset) { SkPathMeasure meas(path, false); - SkFont font = SkFont::LEGACY_ExtractFromPaint(paint); - int count = font.countText(text, length, kUTF8_SkTextEncoding); size_t size = count * (sizeof(SkRSXform) + sizeof(SkScalar)); SkAutoSMalloc<512> storage(size); @@ -122,7 +121,9 @@ static void draw_text_on_path(SkCanvas* canvas, const void* text, size_t length, SkTMax(SkScalarAbs(fontb.fTop), SkScalarAbs(fontb.fBottom))); const SkRect bounds = path.getBounds().makeOutset(max, max); - paint.getTextWidths(text, length, widths); + SkAutoTArray glyphs(count); + font.textToGlyphs(text, length, kUTF8_SkTextEncoding, glyphs.get(), count); + font.getWidths(glyphs.get(), count, widths); for (int i = 0; i < count; ++i) { // we want to position each character on the center of its advance @@ -141,7 +142,9 @@ static void draw_text_on_path(SkCanvas* canvas, const void* text, size_t length, xform[i].fTy = pos.y() + tan.x() * xy[i].y() - tan.y() * offset; } - canvas->drawTextRSXform(text, length, &xform[0], &bounds, paint); + canvas->drawTextBlob(SkTextBlob::MakeFromRSXform(glyphs.get(), count * sizeof(SkGlyphID), + &xform[0], font, kGlyphID_SkTextEncoding), + 0, 0, paint); if (true) { SkPaint p; @@ -162,10 +165,12 @@ static void drawTextPath(SkCanvas* canvas, bool doStroke) { const int N = sizeof(text0) - 1; SkPoint pos[N]; + SkFont font; + font.setSize(100); + SkPaint paint; paint.setShader(make_shader()); paint.setAntiAlias(true); - paint.setTextSize(100); if (doStroke) { paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(2.25f); @@ -175,7 +180,7 @@ static void drawTextPath(SkCanvas* canvas, bool doStroke) { SkScalar x = 0; for (int i = 0; i < N; ++i) { pos[i].set(x, 0); - x += paint.measureText(&text0[i], 1); + x += font.measureText(&text0[i], 1, kUTF8_SkTextEncoding, nullptr, &paint); } SkPath path; @@ -187,7 +192,7 @@ static void drawTextPath(SkCanvas* canvas, bool doStroke) { for (auto d : dirs) { path.reset(); path.addOval(SkRect::MakeXYWH(160, 160, 540, 540), d); - draw_text_on_path(canvas, text0, N, pos, path, paint, baseline_offset); + draw_text_on_path(canvas, text0, N, pos, path, font, paint, baseline_offset); } paint.reset(); @@ -204,8 +209,6 @@ DEF_SIMPLE_GM(drawTextRSXform, canvas, 430, 860) { } } -#include "SkTextBlob.h" - // Exercise xform blob and its bounds DEF_SIMPLE_GM(blob_rsxform, canvas, 500, 100) { SkFont font; diff --git a/gm/highcontrastfilter.cpp b/gm/highcontrastfilter.cpp index 0c7c5e1de6..5db2203f91 100644 --- a/gm/highcontrastfilter.cpp +++ b/gm/highcontrastfilter.cpp @@ -8,6 +8,7 @@ #include "gm.h" #include "sk_tool_utils.h" #include "SkCanvas.h" +#include "SkFont.h" #include "SkGradientShader.h" #include "SkHighContrastFilter.h" @@ -30,13 +31,15 @@ static void draw_label(SkCanvas* canvas, const SkHighContrastConfig& config) { invertStr, config.fContrast); - SkPaint paint; - sk_tool_utils::set_portable_typeface(&paint); - paint.setTextSize(0.05f); + SkFont font; + font.setTypeface(sk_tool_utils::create_portable_typeface()); + font.setSize(0.05f); + font.setEdging(SkFont::Edging::kAlias); + size_t len = strlen(labelBuffer); - SkScalar width = paint.measureText(labelBuffer, len); - canvas->drawText(labelBuffer, len, 0.5f - width / 2, 0.16f, paint); + SkScalar width = font.measureText(labelBuffer, len, kUTF8_SkTextEncoding); + canvas->drawSimpleText(labelBuffer, len, kUTF8_SkTextEncoding, 0.5f - width / 2, 0.16f, font, SkPaint()); } static void draw_scene(SkCanvas* canvas, const SkHighContrastConfig& config) { diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index 11d070df97..b5ef264185 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -7,6 +7,7 @@ #include "SkAutoMalloc.h" #include "SkCanvas.h" +#include "SkFont.h" #include "SkGeometry.h" #include "SkNullCanvas.h" #include "SkPaint.h" @@ -5400,13 +5401,22 @@ DEF_TEST(path_last_move_to_index, r) { // Previously, we would leave its fLastMoveToIndex alone after the copy, but now we should // set it to path's value inside SkPath::transform() - SkPath path; - SkPath copyPath; + const char text[] = "hello"; + constexpr size_t len = sizeof(text) - 1; + SkGlyphID glyphs[len]; - SkPaint paint; - paint.getTextPath("hello", 5, 20, 80, &(copyPath)); // <== init copyPath, set fake copyPath.fLastMoveToIndex + SkFont font; + font.textToGlyphs(text, len, kUTF8_SkTextEncoding, glyphs, len); + + SkPath copyPath; + SkFont().getPaths(glyphs, len, [](const SkPath* src, const SkMatrix& mx, void* ctx) { + if (src) { + ((SkPath*)ctx)->addPath(*src, mx); + } + }, ©Path); SkScalar radii[] = { 80, 100, 0, 0, 40, 60, 0, 0 };; + SkPath path; path.addRoundRect({10, 10, 110, 110}, radii); path.offset(0, 5, &(copyPath)); // <== change buffer copyPath.fPathRef->fPoints but not reset copyPath.fLastMoveToIndex lead to out of bound