[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>
This commit is contained in:
parent
233de6d8cd
commit
f661ec788b
@ -29,7 +29,7 @@ protected:
|
||||
void onRender(const SkSVGRenderContext&) const override {}
|
||||
|
||||
private:
|
||||
SkPath onAsPath(const SkSVGRenderContext&) const final;
|
||||
SkPath onAsPath(const SkSVGRenderContext&) const override;
|
||||
|
||||
using INHERITED = SkSVGTransformableNode;
|
||||
};
|
||||
@ -70,6 +70,7 @@ private:
|
||||
void onRender(const SkSVGRenderContext&) const override;
|
||||
|
||||
SkRect onObjectBoundingBox(const SkSVGRenderContext&) const override;
|
||||
SkPath onAsPath(const SkSVGRenderContext&) const override;
|
||||
|
||||
using INHERITED = SkSVGTextContainer;
|
||||
};
|
||||
|
@ -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 @@ SkRect SkSVGText::onObjectBoundingBox(const SkSVGRenderContext& ctx) const {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user