Notify when SkFontMetrics bounds are bogus.
OpenType and many other font formats have the concept of pre-computed
metrics for the union of all glyph bounding boxes. This allows for fast
though course quick rejecting of bounds, since the glyphs themselves may
potentially be quite a bit larger than the EM. With the introduction of
variable fonts OpenType does not vary these bounds, so the bounds are
only valid for the default non-varied font.
As a result the fTop, fBottom, fXMax, and fXMin reported in
SkFontMetrics may be bogus. Since simply always setting them to empty
zeros may be disruptive, provide a way forward for new users to check if
the bounds are valid.
This exposed an issue where SkTextBlobBuilder::TightRunBounds does not
handle SkTextBlob::kRSXform_Positioning, so add a test for that.
Change-Id: I872729e0f16e2a196229f9902addf4b07b461590
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301455
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/gm/drawatlas.cpp b/gm/drawatlas.cpp
index d447c69..1c70e7e 100644
--- a/gm/drawatlas.cpp
+++ b/gm/drawatlas.cpp
@@ -12,6 +12,7 @@
#include "include/core/SkColorFilter.h"
#include "include/core/SkFilterQuality.h"
#include "include/core/SkFont.h"
+#include "include/core/SkFontMgr.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
@@ -259,6 +260,44 @@
canvas->drawTextBlob(blob, offset.fX, offset.fY, paint);
}
+// Exercise xform blob and its tight bounds
+DEF_SIMPLE_GM(blob_rsxform_distortable, canvas, 500, 100) {
+ sk_sp<SkTypeface> typeface;
+ std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
+ if (distortable) {
+ sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
+ const SkFontArguments::VariationPosition::Coordinate position[] = {
+ { SkSetFourByteTag('w','g','h','t'), 1.618033988749895f }
+ };
+ SkFontArguments params;
+ params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)});
+ typeface = fm->makeFromStream(std::move(distortable), params);
+ }
+
+ SkFont font(typeface, 50);
+
+ const char text[] = "abcabcabc";
+ constexpr size_t len = sizeof(text) - 1;
+
+ SkRSXform xforms[len];
+ SkScalar scale = 1;
+ SkScalar x = 0, y = 0;
+ for (size_t i = 0; i < len; ++i) {
+ scale = SkScalarSin(i * SK_ScalarPI / (len-1)) * 0.75f + 0.5f;
+ xforms[i] = SkRSXform::Make(scale, 0, x, y);
+ x += 50 * scale;
+ }
+
+ auto blob = SkTextBlob::MakeFromRSXform(text, len, xforms, font);
+
+ SkPoint offset = { 20, 70 };
+ SkPaint paint;
+ paint.setColor(0xFFCCCCCC);
+ canvas->drawRect(blob->bounds().makeOffset(offset.fX, offset.fY), paint);
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawTextBlob(blob, offset.fX, offset.fY, paint);
+}
+
static sk_sp<SkVertices> make_vertices(sk_sp<SkImage> image, const SkRect& r,
SkColor color) {
SkPoint pos[4];