[svg] Text asPath() support
Enables use of text as a clip path.
Bug: skia:10840
Change-Id: I9de40e23696083e8cdd7e0b82221da3f3c36ac8b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/358533
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
diff --git a/modules/svg/src/SkSVGText.cpp b/modules/svg/src/SkSVGText.cpp
index a5f1609..c571c30 100644
--- a/modules/svg/src/SkSVGText.cpp
+++ b/modules/svg/src/SkSVGText.cpp
@@ -14,6 +14,7 @@
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
+#include "include/core/SkPathBuilder.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkString.h"
#include "modules/skshaper/include/SkShaper.h"
@@ -594,6 +595,53 @@
return bounds;
}
+SkPath SkSVGText::onAsPath(const SkSVGRenderContext& ctx) const {
+ SkPathBuilder builder;
+
+ const SkSVGTextContext::ShapedTextCallback as_path =
+ [&builder](const SkSVGRenderContext& ctx, const sk_sp<SkTextBlob>& blob, const SkPaint*,
+ const SkPaint*) {
+ if (!blob) {
+ return;
+ }
+
+ SkTextBlobRunIterator it(blob.get());
+ for (SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) {
+ struct GetPathsCtx {
+ SkPathBuilder& builder;
+ const SkRSXform* xform;
+ } get_paths_ctx {builder, it.xforms()};
+
+ it.font().getPaths(it.glyphs(), it.glyphCount(), [](const SkPath* path,
+ const SkMatrix& matrix,
+ void* raw_ctx) {
+ auto* get_paths_ctx = static_cast<GetPathsCtx*>(raw_ctx);
+ const auto& glyph_rsx = *get_paths_ctx->xform++;
+
+ if (!path) {
+ return;
+ }
+
+ SkMatrix glyph_matrix;
+ glyph_matrix.setRSXform(glyph_rsx);
+ glyph_matrix.preConcat(matrix);
+
+ get_paths_ctx->builder.addPath(path->makeTransform(glyph_matrix));
+ }, &get_paths_ctx);
+ }
+ };
+
+ {
+ SkSVGTextContext tctx(ctx, as_path);
+ this->onShapeText(ctx, &tctx, this->getXmlSpace());
+ }
+
+ auto path = builder.detach();
+ this->mapToParent(&path);
+
+ return path;
+}
+
void SkSVGTextPath::onShapeText(const SkSVGRenderContext& ctx, SkSVGTextContext* parent_tctx,
SkSVGXmlSpace xs) const {
SkASSERT(parent_tctx);