[svg] Text object bounding box support
Implement onObjectBoundingBox() for SkSVGText.
Enables use of objectBoundingBox filters effects on text.
Bug: skia:10840
Change-Id: I84ab3df04683cb23073ba9ddc531abe4e5788e5e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/358476
Commit-Queue: Florin Malita <fmalita@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
diff --git a/modules/svg/src/SkSVGText.cpp b/modules/svg/src/SkSVGText.cpp
index f81eb7c..a5f1609 100644
--- a/modules/svg/src/SkSVGText.cpp
+++ b/modules/svg/src/SkSVGText.cpp
@@ -20,6 +20,7 @@
#include "modules/svg/include/SkSVGRenderContext.h"
#include "modules/svg/include/SkSVGValue.h"
#include "modules/svg/src/SkSVGTextPriv.h"
+#include "src/core/SkTextBlobPriv.h"
#include "src/utils/SkUTF.h"
namespace {
@@ -558,6 +559,41 @@
this->onShapeText(ctx, &tctx, this->getXmlSpace());
}
+SkRect SkSVGText::onObjectBoundingBox(const SkSVGRenderContext& ctx) const {
+ SkRect bounds = SkRect::MakeEmpty();
+
+ const SkSVGTextContext::ShapedTextCallback compute_bounds =
+ [&bounds](const SkSVGRenderContext& ctx, const sk_sp<SkTextBlob>& blob, const SkPaint*,
+ const SkPaint*) {
+ if (!blob) {
+ return;
+ }
+
+ SkAutoSTArray<64, SkRect> glyphBounds;
+
+ SkTextBlobRunIterator it(blob.get());
+
+ for (SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) {
+ glyphBounds.reset(SkToInt(it.glyphCount()));
+ it.font().getBounds(it.glyphs(), it.glyphCount(), glyphBounds.get(), nullptr);
+
+ SkASSERT(it.positioning() == SkTextBlobRunIterator::kRSXform_Positioning);
+ SkMatrix m;
+ for (uint32_t i = 0; i < it.glyphCount(); ++i) {
+ m.setRSXform(it.xforms()[i]);
+ bounds.join(m.mapRect(glyphBounds[i]));
+ }
+ }
+ };
+
+ {
+ SkSVGTextContext tctx(ctx, compute_bounds);
+ this->onShapeText(ctx, &tctx, this->getXmlSpace());
+ }
+
+ return bounds;
+}
+
void SkSVGTextPath::onShapeText(const SkSVGRenderContext& ctx, SkSVGTextContext* parent_tctx,
SkSVGXmlSpace xs) const {
SkASSERT(parent_tctx);