aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/3dgm.cpp3
-rw-r--r--gn/samples.gni1
-rw-r--r--samplecode/SampleGlyphTransform.cpp81
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp12
-rw-r--r--src/gpu/text/GrTextBlob.cpp3
-rw-r--r--src/gpu/text/GrTextBlob.h5
6 files changed, 97 insertions, 8 deletions
diff --git a/gm/3dgm.cpp b/gm/3dgm.cpp
index 93c6f92281..8014c246d3 100644
--- a/gm/3dgm.cpp
+++ b/gm/3dgm.cpp
@@ -173,6 +173,9 @@ protected:
SkString onShortName() override { return SkString("3dgm"); }
bool onAnimate(const SkAnimTimer& timer) override {
+ if (!fAnim) {
+ return false;
+ }
SkScalar dur = fAnim->duration();
fAnimT = fmod(timer.secs(), dur) / dur;
return true;
diff --git a/gn/samples.gni b/gn/samples.gni
index b5728b3bfd..1a4002f82c 100644
--- a/gn/samples.gni
+++ b/gn/samples.gni
@@ -50,6 +50,7 @@ samples_sources = [
"$_samplecode/SampleFlutterAnimate.cpp",
"$_samplecode/SampleFontScalerTest.cpp",
"$_samplecode/SampleFuzz.cpp",
+ "$_samplecode/SampleGlyphTransform.cpp",
"$_samplecode/SampleGradients.cpp",
"$_samplecode/SampleHairCurves.cpp",
"$_samplecode/SampleHairline.cpp",
diff --git a/samplecode/SampleGlyphTransform.cpp b/samplecode/SampleGlyphTransform.cpp
new file mode 100644
index 0000000000..b5d44f8bfc
--- /dev/null
+++ b/samplecode/SampleGlyphTransform.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "sk_tool_utils.h"
+
+#include "SkAnimTimer.h"
+#include "SkCanvas.h"
+#include "SkPath.h"
+#include "SkRandom.h"
+#include "SkRRect.h"
+#include "SkTypeface.h"
+
+// Implementation in C++ of Animated Emoji
+// See https://t.d3fc.io/status/705212795936247808
+
+class GlyphTransformView : public SampleView {
+public:
+ GlyphTransformView() {}
+
+protected:
+ void onOnceBeforeDraw() override {
+ fEmojiFont.fTypeface = sk_tool_utils::emoji_typeface();
+ fEmojiFont.fText = sk_tool_utils::emoji_sample_text();
+ }
+
+ // overrides from SkEventSink
+ bool onQuery(SkEvent* evt) override {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "Glyph Transform");
+ return true;
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ void onDrawContent(SkCanvas* canvas) override {
+ SkPaint paint;
+ paint.setTypeface(fEmojiFont.fTypeface);
+ const char* text = fEmojiFont.fText;
+
+ canvas->scale(4, 4);
+
+ canvas->drawLine(0, 200, 600, 200, paint);
+ SkMatrix ctm;
+ ctm.setRotate(SkRadiansToDegrees(fRotate));
+ ctm.postScale(fScale, fScale);
+ ctm.postTranslate(fTranslate.fX, fTranslate.fY);
+ canvas->concat(ctm);
+ canvas->drawString(text, 0, 0, paint);
+ }
+
+ bool onAnimate(const SkAnimTimer& timer) override {
+ double t = timer.secs();
+
+ fTranslate.set(99 + sin(t / 3.0e3) - t / 1024, 200 + sin(t / 999) / t);
+ fScale = 4.5 - t*t / 99;
+ fRotate = sin(t / 734);
+
+ return true;
+ }
+
+private:
+ struct EmojiFont {
+ sk_sp<SkTypeface> fTypeface;
+ const char* fText;
+ } fEmojiFont;
+
+ SkVector fTranslate;
+ SkScalar fScale;
+ SkScalar fRotate;
+
+ typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new GlyphTransformView; }
+static SkViewRegister reg(MyFactory);
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 82f4b54c10..a83e025a50 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -25,11 +25,6 @@ static const int kDistanceAdjustLumShift = 5;
void GrAtlasTextOp::init() {
const Geometry& geo = fGeoData[0];
- SkRect bounds;
- geo.fBlob->computeSubRunBounds(&bounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX, geo.fY);
- // We don't have tight bounds on the glyph paths in device space. For the purposes of bounds
- // we treat this as a set of non-AA rects rendered with a texture.
- this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
if (this->usesDistanceFields()) {
bool isLCD = this->isLCD();
@@ -51,6 +46,13 @@ void GrAtlasTextOp::init() {
fNeedsGlyphTransform = true;
}
+
+ SkRect bounds;
+ geo.fBlob->computeSubRunBounds(&bounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX, geo.fY,
+ fNeedsGlyphTransform);
+ // We don't have tight bounds on the glyph paths in device space. For the purposes of bounds
+ // we treat this as a set of non-AA rects rendered with a texture.
+ this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
}
void GrAtlasTextOp::visitProxies(const VisitProxyFunc& func) const {
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index c3d06e81fd..b6fc3ce170 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -353,7 +353,8 @@ void GrTextBlob::flush(GrTextUtils::Target* target, const SkSurfaceProps& props,
skipClip = true;
// We only need to do clipping work if the subrun isn't contained by the clip
SkRect subRunBounds;
- this->computeSubRunBounds(&subRunBounds, runIndex, subRun, viewMatrix, x, y);
+ this->computeSubRunBounds(&subRunBounds, runIndex, subRun, viewMatrix, x, y,
+ false);
if (!clipRRect.getBounds().contains(subRunBounds)) {
// If the subrun is completely outside, don't add an op for it
if (!clipRRect.getBounds().intersects(subRunBounds)) {
diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h
index 49615a92ed..e34ab88ef2 100644
--- a/src/gpu/text/GrTextBlob.h
+++ b/src/gpu/text/GrTextBlob.h
@@ -210,7 +210,8 @@ public:
SkScalar y);
void computeSubRunBounds(SkRect* outBounds, int runIndex, int subRunIndex,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
+ const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+ bool needsGlyphTransform) {
// We don't yet position distance field text on the cpu, so we have to map the vertex bounds
// into device space.
// We handle vertex bounds differently for distance field text and bitmap text because
@@ -219,7 +220,7 @@ public:
const Run& run = fRuns[runIndex];
const Run::SubRunInfo& subRun = run.fSubRunInfo[subRunIndex];
*outBounds = subRun.vertexBounds();
- if (subRun.drawAsDistanceFields()) {
+ if (needsGlyphTransform) {
// Distance field text is positioned with the (X,Y) as part of the glyph position,
// and currently the view matrix is applied on the GPU
outBounds->offset(x - fInitialX, y - fInitialY);