xref: /aosp_15_r20/external/skia/tools/viewer/GlyphTransformSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "include/core/SkCanvas.h"
8 #include "include/core/SkFont.h"
9 #include "include/core/SkPath.h"
10 #include "include/core/SkRRect.h"
11 #include "include/core/SkTypeface.h"
12 #include "src/base/SkRandom.h"
13 #include "tools/ToolUtils.h"
14 #include "tools/fonts/FontToolUtils.h"
15 #include "tools/timer/TimeUtils.h"
16 #include "tools/viewer/Slide.h"
17 
18 #include <cmath>
19 
20 // Implementation in C++ of Animated Emoji
21 // See https://t.d3fc.io/status/705212795936247808
22 // See https://crbug.com/848616
23 
24 class GlyphTransformView : public Slide {
25 public:
GlyphTransformView()26     GlyphTransformView() { fName = "Glyph Transform"; }
27 
load(SkScalar w,SkScalar h)28     void load(SkScalar w, SkScalar h) override {
29         fEmojiFont = ToolUtils::EmojiSample();
30         fSize = {w, h};
31     }
32 
resize(SkScalar w,SkScalar h)33     void resize(SkScalar w, SkScalar h) override { fSize = {w, h}; }
34 
draw(SkCanvas * canvas)35     void draw(SkCanvas* canvas) override {
36         SkPaint paint;
37 
38         SkFont font(fEmojiFont.typeface);
39         const char* text = fEmojiFont.sampleText;
40 
41         double baseline = fSize.height() / 2;
42         canvas->drawLine(0, baseline, fSize.width(), baseline, paint);
43 
44         SkMatrix ctm;
45         ctm.setRotate(fRotate); // d3 rotate takes degrees
46         ctm.postScale(fScale * 4, fScale * 4);
47         ctm.postTranslate(fTranslate.fX  + fSize.width() * 0.8, fTranslate.fY + baseline);
48         canvas->concat(ctm);
49 
50         // d3 by default anchors text around the middle
51         SkRect bounds;
52         font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
53         canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, -bounds.centerX(), -bounds.centerY(),
54                                font, paint);
55     }
56 
animate(double nanos)57     bool animate(double nanos) override {
58         constexpr SkScalar maxt = 100000;
59         double t = TimeUtils::PingPong(1e-9 * nanos, 20, 0, 0, maxt); // d3 t is in milliseconds
60 
61         fTranslate.set(sin(t / 3000) - t * fSize.width() * 0.7 / maxt, sin(t / 999) / t);
62         fScale = 4.5 - std::sqrt(t) / 99;
63         fRotate = sin(t / 734);
64 
65         return true;
66     }
67 
68 private:
69     ToolUtils::EmojiTestSample fEmojiFont;
70 
71     SkVector fTranslate;
72     SkScalar fScale;
73     SkScalar fRotate;
74     SkSize fSize;
75 };
76 
77 //////////////////////////////////////////////////////////////////////////////
78 
79 DEF_SLIDE( return new GlyphTransformView(); )
80