xref: /aosp_15_r20/external/skia/tools/ToolUtils.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2014 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef ToolUtils_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define ToolUtils_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontArguments.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontParameters.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPixmap.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"  // IWYU pragma: keep
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTInternalLList.h"
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
32*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
33*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
34*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
35*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker class SkBitmap;
38*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas;
39*c8dee2aaSAndroid Build Coastguard Worker class SkFont;
40*c8dee2aaSAndroid Build Coastguard Worker class SkImage;
41*c8dee2aaSAndroid Build Coastguard Worker class SkMatrix;
42*c8dee2aaSAndroid Build Coastguard Worker class SkMetaData;
43*c8dee2aaSAndroid Build Coastguard Worker class SkPaint;
44*c8dee2aaSAndroid Build Coastguard Worker class SkPath;
45*c8dee2aaSAndroid Build Coastguard Worker class SkShader;
46*c8dee2aaSAndroid Build Coastguard Worker class SkSurfaceProps;
47*c8dee2aaSAndroid Build Coastguard Worker class SkTextBlobBuilder;
48*c8dee2aaSAndroid Build Coastguard Worker enum SkAlphaType : int;
49*c8dee2aaSAndroid Build Coastguard Worker enum SkColorType : int;
50*c8dee2aaSAndroid Build Coastguard Worker enum class SkTextEncoding;
51*c8dee2aaSAndroid Build Coastguard Worker enum class SkTileMode;
52*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo;
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker namespace ToolUtils {
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker const char* alphatype_name (SkAlphaType);
57*c8dee2aaSAndroid Build Coastguard Worker const char* colortype_name (SkColorType);
58*c8dee2aaSAndroid Build Coastguard Worker const char* colortype_depth(SkColorType);  // like colortype_name, but channel order agnostic
59*c8dee2aaSAndroid Build Coastguard Worker const char* tilemode_name(SkTileMode);
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker /**
62*c8dee2aaSAndroid Build Coastguard Worker  * Map opaque colors from 8888 to 565.
63*c8dee2aaSAndroid Build Coastguard Worker  */
64*c8dee2aaSAndroid Build Coastguard Worker SkColor color_to_565(SkColor color);
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker void get_text_path(const SkFont&,
67*c8dee2aaSAndroid Build Coastguard Worker                    const void* text,
68*c8dee2aaSAndroid Build Coastguard Worker                    size_t      length,
69*c8dee2aaSAndroid Build Coastguard Worker                    SkTextEncoding,
70*c8dee2aaSAndroid Build Coastguard Worker                    SkPath*,
71*c8dee2aaSAndroid Build Coastguard Worker                    const SkPoint* positions = nullptr);
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker /**
74*c8dee2aaSAndroid Build Coastguard Worker  *  Returns true iff all of the pixels between the two images are identical.
75*c8dee2aaSAndroid Build Coastguard Worker  *
76*c8dee2aaSAndroid Build Coastguard Worker  *  If the configs differ, return false.
77*c8dee2aaSAndroid Build Coastguard Worker  */
78*c8dee2aaSAndroid Build Coastguard Worker bool equal_pixels(const SkPixmap&, const SkPixmap&);
79*c8dee2aaSAndroid Build Coastguard Worker bool equal_pixels(const SkBitmap&, const SkBitmap&);
80*c8dee2aaSAndroid Build Coastguard Worker bool equal_pixels(const SkImage* a, const SkImage* b);
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker /** Returns a newly created CheckerboardShader. */
83*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> create_checkerboard_shader(SkColor c1, SkColor c2, int size);
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker /** Draw a checkerboard pattern in the current canvas, restricted to
86*c8dee2aaSAndroid Build Coastguard Worker     the current clip, using SkBlendMode::kSrc. */
87*c8dee2aaSAndroid Build Coastguard Worker void draw_checkerboard(SkCanvas* canvas, SkColor color1, SkColor color2, int checkSize);
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker /** Make it easier to create a bitmap-based checkerboard */
90*c8dee2aaSAndroid Build Coastguard Worker SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize);
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize);
93*c8dee2aaSAndroid Build Coastguard Worker 
94*c8dee2aaSAndroid Build Coastguard Worker /** A default checkerboard. */
draw_checkerboard(SkCanvas * canvas)95*c8dee2aaSAndroid Build Coastguard Worker inline void draw_checkerboard(SkCanvas* canvas) {
96*c8dee2aaSAndroid Build Coastguard Worker     ToolUtils::draw_checkerboard(canvas, 0xFF999999, 0xFF666666, 8);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker class HilbertGenerator {
100*c8dee2aaSAndroid Build Coastguard Worker public:
101*c8dee2aaSAndroid Build Coastguard Worker     HilbertGenerator(float desiredSize, float desiredLineWidth, int desiredDepth);
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker     // Draw a Hilbert curve into the canvas w/ a gradient along its length
104*c8dee2aaSAndroid Build Coastguard Worker     void draw(SkCanvas* canvas);
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker private:
107*c8dee2aaSAndroid Build Coastguard Worker     void turn90(bool turnLeft);
108*c8dee2aaSAndroid Build Coastguard Worker     void line(SkCanvas* canvas);
109*c8dee2aaSAndroid Build Coastguard Worker     void recursiveDraw(SkCanvas* canvas, int curDepth, bool turnLeft);
110*c8dee2aaSAndroid Build Coastguard Worker     SkColor4f getColor(float curLen);
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     const float fDesiredSize;
113*c8dee2aaSAndroid Build Coastguard Worker     const int fDesiredDepth;
114*c8dee2aaSAndroid Build Coastguard Worker     const float fSegmentLength;            // length of a line segment
115*c8dee2aaSAndroid Build Coastguard Worker     const float fDesiredLineWidth;
116*c8dee2aaSAndroid Build Coastguard Worker 
117*c8dee2aaSAndroid Build Coastguard Worker     SkRect fActualBounds;
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker     // The "turtle" state
120*c8dee2aaSAndroid Build Coastguard Worker     SkPoint fCurPos;
121*c8dee2aaSAndroid Build Coastguard Worker     int fCurDir;
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker     const float fExpectedLen;
124*c8dee2aaSAndroid Build Coastguard Worker     float fCurLen;
125*c8dee2aaSAndroid Build Coastguard Worker };
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker /** Create pixmaps to initialize a 32x32 image w/ or w/o mipmaps.
128*c8dee2aaSAndroid Build Coastguard Worker  *  Returns the number of levels (either 1 or 6). The mipmap levels will be colored as
129*c8dee2aaSAndroid Build Coastguard Worker  *  specified in 'colors'
130*c8dee2aaSAndroid Build Coastguard Worker  */
131*c8dee2aaSAndroid Build Coastguard Worker int make_pixmaps(SkColorType,
132*c8dee2aaSAndroid Build Coastguard Worker                  SkAlphaType,
133*c8dee2aaSAndroid Build Coastguard Worker                  bool withMips,
134*c8dee2aaSAndroid Build Coastguard Worker                  const SkColor4f colors[6],
135*c8dee2aaSAndroid Build Coastguard Worker                  SkPixmap pixmaps[6],
136*c8dee2aaSAndroid Build Coastguard Worker                  std::unique_ptr<char[]>* mem);
137*c8dee2aaSAndroid Build Coastguard Worker 
138*c8dee2aaSAndroid Build Coastguard Worker // If the canvas doesn't make a surface (e.g. recording), make a raster surface
139*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> makeSurface(SkCanvas*, const SkImageInfo&, const SkSurfaceProps* = nullptr);
140*c8dee2aaSAndroid Build Coastguard Worker 
141*c8dee2aaSAndroid Build Coastguard Worker // A helper for inserting a drawtext call into a SkTextBlobBuilder
142*c8dee2aaSAndroid Build Coastguard Worker void add_to_text_blob_w_len(SkTextBlobBuilder*,
143*c8dee2aaSAndroid Build Coastguard Worker                             const char* text,
144*c8dee2aaSAndroid Build Coastguard Worker                             size_t      len,
145*c8dee2aaSAndroid Build Coastguard Worker                             SkTextEncoding,
146*c8dee2aaSAndroid Build Coastguard Worker                             const SkFont&,
147*c8dee2aaSAndroid Build Coastguard Worker                             SkScalar x,
148*c8dee2aaSAndroid Build Coastguard Worker                             SkScalar y);
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker void add_to_text_blob(SkTextBlobBuilder*, const char* text, const SkFont&, SkScalar x, SkScalar y);
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker // Constructs a star by walking a 'numPts'-sided regular polygon with even/odd fill:
153*c8dee2aaSAndroid Build Coastguard Worker //
154*c8dee2aaSAndroid Build Coastguard Worker //   moveTo(pts[0]);
155*c8dee2aaSAndroid Build Coastguard Worker //   lineTo(pts[step % numPts]);
156*c8dee2aaSAndroid Build Coastguard Worker //   ...
157*c8dee2aaSAndroid Build Coastguard Worker //   lineTo(pts[(step * (N - 1)) % numPts]);
158*c8dee2aaSAndroid Build Coastguard Worker //
159*c8dee2aaSAndroid Build Coastguard Worker // numPts=5, step=2 will produce a classic five-point star.
160*c8dee2aaSAndroid Build Coastguard Worker //
161*c8dee2aaSAndroid Build Coastguard Worker // numPts and step must be co-prime.
162*c8dee2aaSAndroid Build Coastguard Worker SkPath make_star(const SkRect& bounds, int numPts = 5, int step = 2);
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst);
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst);
167*c8dee2aaSAndroid Build Coastguard Worker 
168*c8dee2aaSAndroid Build Coastguard Worker void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst);
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
171*c8dee2aaSAndroid Build Coastguard Worker class TopoTestNode : public SkRefCnt {
172*c8dee2aaSAndroid Build Coastguard Worker public:
TopoTestNode(int id)173*c8dee2aaSAndroid Build Coastguard Worker     TopoTestNode(int id) : fID(id) {}
174*c8dee2aaSAndroid Build Coastguard Worker 
dependsOn(TopoTestNode * src)175*c8dee2aaSAndroid Build Coastguard Worker     void dependsOn(TopoTestNode* src) { *fDependencies.append() = src; }
targets(uint32_t target)176*c8dee2aaSAndroid Build Coastguard Worker     void targets(uint32_t target) { *fTargets.append() = target; }
177*c8dee2aaSAndroid Build Coastguard Worker 
id()178*c8dee2aaSAndroid Build Coastguard Worker     int  id() const { return fID; }
reset()179*c8dee2aaSAndroid Build Coastguard Worker     void reset() {
180*c8dee2aaSAndroid Build Coastguard Worker         fOutputPos = 0;
181*c8dee2aaSAndroid Build Coastguard Worker         fTempMark = false;
182*c8dee2aaSAndroid Build Coastguard Worker         fWasOutput = false;
183*c8dee2aaSAndroid Build Coastguard Worker     }
184*c8dee2aaSAndroid Build Coastguard Worker 
outputPos()185*c8dee2aaSAndroid Build Coastguard Worker     uint32_t outputPos() const {
186*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fWasOutput);
187*c8dee2aaSAndroid Build Coastguard Worker         return fOutputPos;
188*c8dee2aaSAndroid Build Coastguard Worker     }
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker     // check that the topological sort is valid for this node
check()191*c8dee2aaSAndroid Build Coastguard Worker     bool check() {
192*c8dee2aaSAndroid Build Coastguard Worker         if (!fWasOutput) {
193*c8dee2aaSAndroid Build Coastguard Worker             return false;
194*c8dee2aaSAndroid Build Coastguard Worker         }
195*c8dee2aaSAndroid Build Coastguard Worker 
196*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < fDependencies.size(); ++i) {
197*c8dee2aaSAndroid Build Coastguard Worker             if (!fDependencies[i]->fWasOutput) {
198*c8dee2aaSAndroid Build Coastguard Worker                 return false;
199*c8dee2aaSAndroid Build Coastguard Worker             }
200*c8dee2aaSAndroid Build Coastguard Worker             // This node should've been output after all the nodes on which it depends
201*c8dee2aaSAndroid Build Coastguard Worker             if (fOutputPos < fDependencies[i]->outputPos()) {
202*c8dee2aaSAndroid Build Coastguard Worker                 return false;
203*c8dee2aaSAndroid Build Coastguard Worker             }
204*c8dee2aaSAndroid Build Coastguard Worker         }
205*c8dee2aaSAndroid Build Coastguard Worker 
206*c8dee2aaSAndroid Build Coastguard Worker         return true;
207*c8dee2aaSAndroid Build Coastguard Worker     }
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker     // The following 7 methods are needed by the topological sort
SetTempMark(TopoTestNode * node)210*c8dee2aaSAndroid Build Coastguard Worker     static void SetTempMark(TopoTestNode* node) { node->fTempMark = true; }
ResetTempMark(TopoTestNode * node)211*c8dee2aaSAndroid Build Coastguard Worker     static void ResetTempMark(TopoTestNode* node) { node->fTempMark = false; }
IsTempMarked(TopoTestNode * node)212*c8dee2aaSAndroid Build Coastguard Worker     static bool IsTempMarked(TopoTestNode* node) { return node->fTempMark; }
Output(TopoTestNode * node,uint32_t outputPos)213*c8dee2aaSAndroid Build Coastguard Worker     static void Output(TopoTestNode* node, uint32_t outputPos) {
214*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!node->fWasOutput);
215*c8dee2aaSAndroid Build Coastguard Worker         node->fOutputPos = outputPos;
216*c8dee2aaSAndroid Build Coastguard Worker         node->fWasOutput = true;
217*c8dee2aaSAndroid Build Coastguard Worker     }
WasOutput(TopoTestNode * node)218*c8dee2aaSAndroid Build Coastguard Worker     static bool          WasOutput(TopoTestNode* node) { return node->fWasOutput; }
GetIndex(TopoTestNode * node)219*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t      GetIndex(TopoTestNode* node) { return node->outputPos(); }
NumDependencies(TopoTestNode * node)220*c8dee2aaSAndroid Build Coastguard Worker     static int           NumDependencies(TopoTestNode* node) { return node->fDependencies.size(); }
Dependency(TopoTestNode * node,int index)221*c8dee2aaSAndroid Build Coastguard Worker     static TopoTestNode* Dependency(TopoTestNode* node, int index) {
222*c8dee2aaSAndroid Build Coastguard Worker         return node->fDependencies[index];
223*c8dee2aaSAndroid Build Coastguard Worker     }
NumTargets(TopoTestNode * node)224*c8dee2aaSAndroid Build Coastguard Worker     static int           NumTargets(TopoTestNode* node) { return node->fTargets.size(); }
GetTarget(TopoTestNode * node,int i)225*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t      GetTarget(TopoTestNode* node, int i) { return node->fTargets[i]; }
GetID(TopoTestNode * node)226*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t      GetID(TopoTestNode* node) { return node->id(); }
227*c8dee2aaSAndroid Build Coastguard Worker 
228*c8dee2aaSAndroid Build Coastguard Worker     // Helper functions for TopoSortBench & TopoSortTest
AllocNodes(skia_private::TArray<sk_sp<ToolUtils::TopoTestNode>> * graph,int num)229*c8dee2aaSAndroid Build Coastguard Worker     static void AllocNodes(skia_private::TArray<sk_sp<ToolUtils::TopoTestNode>>* graph, int num) {
230*c8dee2aaSAndroid Build Coastguard Worker         graph->reserve_exact(graph->size() + num);
231*c8dee2aaSAndroid Build Coastguard Worker 
232*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < num; ++i) {
233*c8dee2aaSAndroid Build Coastguard Worker             graph->push_back(sk_sp<TopoTestNode>(new TopoTestNode(i)));
234*c8dee2aaSAndroid Build Coastguard Worker         }
235*c8dee2aaSAndroid Build Coastguard Worker     }
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
Print(const skia_private::TArray<TopoTestNode * > & graph)238*c8dee2aaSAndroid Build Coastguard Worker     static void Print(const skia_private::TArray<TopoTestNode*>& graph) {
239*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < graph.size(); ++i) {
240*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("%d, ", graph[i]->id());
241*c8dee2aaSAndroid Build Coastguard Worker         }
242*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("\n");
243*c8dee2aaSAndroid Build Coastguard Worker     }
244*c8dee2aaSAndroid Build Coastguard Worker #endif
245*c8dee2aaSAndroid Build Coastguard Worker 
246*c8dee2aaSAndroid Build Coastguard Worker     // randomize the array
Shuffle(SkSpan<sk_sp<TopoTestNode>> graph,SkRandom * rand)247*c8dee2aaSAndroid Build Coastguard Worker     static void Shuffle(SkSpan<sk_sp<TopoTestNode>> graph, SkRandom* rand) {
248*c8dee2aaSAndroid Build Coastguard Worker         for (size_t i = graph.size() - 1; i > 0; --i) {
249*c8dee2aaSAndroid Build Coastguard Worker             int swap = rand->nextU() % (i + 1);
250*c8dee2aaSAndroid Build Coastguard Worker 
251*c8dee2aaSAndroid Build Coastguard Worker             graph[i].swap(graph[swap]);
252*c8dee2aaSAndroid Build Coastguard Worker         }
253*c8dee2aaSAndroid Build Coastguard Worker     }
254*c8dee2aaSAndroid Build Coastguard Worker 
255*c8dee2aaSAndroid Build Coastguard Worker     SK_DECLARE_INTERNAL_LLIST_INTERFACE(TopoTestNode);
256*c8dee2aaSAndroid Build Coastguard Worker 
257*c8dee2aaSAndroid Build Coastguard Worker private:
258*c8dee2aaSAndroid Build Coastguard Worker     int      fID;
259*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fOutputPos = 0;
260*c8dee2aaSAndroid Build Coastguard Worker     bool     fTempMark = false;
261*c8dee2aaSAndroid Build Coastguard Worker     bool     fWasOutput = false;
262*c8dee2aaSAndroid Build Coastguard Worker 
263*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<TopoTestNode*> fDependencies;
264*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<uint32_t>      fTargets;
265*c8dee2aaSAndroid Build Coastguard Worker };
266*c8dee2aaSAndroid Build Coastguard Worker 
267*c8dee2aaSAndroid Build Coastguard Worker bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
268*c8dee2aaSAndroid Build Coastguard Worker void copy_to_g8(SkBitmap* dst, const SkBitmap& src);
269*c8dee2aaSAndroid Build Coastguard Worker 
270*c8dee2aaSAndroid Build Coastguard Worker class PixelIter {
271*c8dee2aaSAndroid Build Coastguard Worker public:
272*c8dee2aaSAndroid Build Coastguard Worker     PixelIter();
PixelIter(SkSurface * surf)273*c8dee2aaSAndroid Build Coastguard Worker     PixelIter(SkSurface* surf) {
274*c8dee2aaSAndroid Build Coastguard Worker         SkPixmap pm;
275*c8dee2aaSAndroid Build Coastguard Worker         if (!surf->peekPixels(&pm)) {
276*c8dee2aaSAndroid Build Coastguard Worker             pm.reset();
277*c8dee2aaSAndroid Build Coastguard Worker         }
278*c8dee2aaSAndroid Build Coastguard Worker         this->reset(pm);
279*c8dee2aaSAndroid Build Coastguard Worker     }
280*c8dee2aaSAndroid Build Coastguard Worker 
reset(const SkPixmap & pm)281*c8dee2aaSAndroid Build Coastguard Worker     void reset(const SkPixmap& pm) {
282*c8dee2aaSAndroid Build Coastguard Worker         fPM  = pm;
283*c8dee2aaSAndroid Build Coastguard Worker         fLoc = {-1, 0};
284*c8dee2aaSAndroid Build Coastguard Worker     }
285*c8dee2aaSAndroid Build Coastguard Worker 
286*c8dee2aaSAndroid Build Coastguard Worker     void* next(SkIPoint* loc = nullptr) {
287*c8dee2aaSAndroid Build Coastguard Worker         if (!fPM.addr()) {
288*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
289*c8dee2aaSAndroid Build Coastguard Worker         }
290*c8dee2aaSAndroid Build Coastguard Worker         fLoc.fX += 1;
291*c8dee2aaSAndroid Build Coastguard Worker         if (fLoc.fX >= fPM.width()) {
292*c8dee2aaSAndroid Build Coastguard Worker             fLoc.fX = 0;
293*c8dee2aaSAndroid Build Coastguard Worker             if (++fLoc.fY >= fPM.height()) {
294*c8dee2aaSAndroid Build Coastguard Worker                 this->setDone();
295*c8dee2aaSAndroid Build Coastguard Worker                 return nullptr;
296*c8dee2aaSAndroid Build Coastguard Worker             }
297*c8dee2aaSAndroid Build Coastguard Worker         }
298*c8dee2aaSAndroid Build Coastguard Worker         if (loc) {
299*c8dee2aaSAndroid Build Coastguard Worker             *loc = fLoc;
300*c8dee2aaSAndroid Build Coastguard Worker         }
301*c8dee2aaSAndroid Build Coastguard Worker         return fPM.writable_addr(fLoc.fX, fLoc.fY);
302*c8dee2aaSAndroid Build Coastguard Worker     }
303*c8dee2aaSAndroid Build Coastguard Worker 
setDone()304*c8dee2aaSAndroid Build Coastguard Worker     void setDone() { fPM.reset(); }
305*c8dee2aaSAndroid Build Coastguard Worker 
306*c8dee2aaSAndroid Build Coastguard Worker private:
307*c8dee2aaSAndroid Build Coastguard Worker     SkPixmap fPM;
308*c8dee2aaSAndroid Build Coastguard Worker     SkIPoint fLoc;
309*c8dee2aaSAndroid Build Coastguard Worker };
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker using PathSniffCallback = void(const SkMatrix&, const SkPath&, const SkPaint&);
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker // Calls the provided PathSniffCallback for each path in the given file.
314*c8dee2aaSAndroid Build Coastguard Worker // Supported file formats .skp. (See SvgPathExtractor for .svg)
315*c8dee2aaSAndroid Build Coastguard Worker void ExtractPathsFromSKP(const char filepath[], std::function<PathSniffCallback>);
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker // Initialised with a font, this class can be called to setup GM UI with sliders for font
318*c8dee2aaSAndroid Build Coastguard Worker // variations, and returns a set of variation coordinates that matches what the sliders in the UI
319*c8dee2aaSAndroid Build Coastguard Worker // are set to. Useful for testing variable font properties, see colrv1.cpp.
320*c8dee2aaSAndroid Build Coastguard Worker class VariationSliders {
321*c8dee2aaSAndroid Build Coastguard Worker public:
VariationSliders()322*c8dee2aaSAndroid Build Coastguard Worker     VariationSliders() {}
323*c8dee2aaSAndroid Build Coastguard Worker 
324*c8dee2aaSAndroid Build Coastguard Worker     VariationSliders(SkTypeface*,
325*c8dee2aaSAndroid Build Coastguard Worker                      SkFontArguments::VariationPosition variationPosition = {nullptr, 0});
326*c8dee2aaSAndroid Build Coastguard Worker 
327*c8dee2aaSAndroid Build Coastguard Worker     bool writeControls(SkMetaData* controls);
328*c8dee2aaSAndroid Build Coastguard Worker 
329*c8dee2aaSAndroid Build Coastguard Worker     /* Scans controls for information about the variation axes that the user may have configured.
330*c8dee2aaSAndroid Build Coastguard Worker      * Optionally pass in a boolean to receive information on whether the axes were updated. */
331*c8dee2aaSAndroid Build Coastguard Worker     void readControls(const SkMetaData& controls, bool* changed = nullptr);
332*c8dee2aaSAndroid Build Coastguard Worker 
333*c8dee2aaSAndroid Build Coastguard Worker     SkSpan<const SkFontArguments::VariationPosition::Coordinate> getCoordinates();
334*c8dee2aaSAndroid Build Coastguard Worker 
335*c8dee2aaSAndroid Build Coastguard Worker     static SkString tagToString(SkFourByteTag tag);
336*c8dee2aaSAndroid Build Coastguard Worker 
337*c8dee2aaSAndroid Build Coastguard Worker private:
338*c8dee2aaSAndroid Build Coastguard Worker     struct AxisSlider {
339*c8dee2aaSAndroid Build Coastguard Worker         SkScalar current;
340*c8dee2aaSAndroid Build Coastguard Worker         SkFontParameters::Variation::Axis axis;
341*c8dee2aaSAndroid Build Coastguard Worker         SkString name;
342*c8dee2aaSAndroid Build Coastguard Worker     };
343*c8dee2aaSAndroid Build Coastguard Worker 
344*c8dee2aaSAndroid Build Coastguard Worker     std::vector<AxisSlider> fAxisSliders;
345*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> fCoords;
346*c8dee2aaSAndroid Build Coastguard Worker     static constexpr size_t kAxisVarsSize = 3;
347*c8dee2aaSAndroid Build Coastguard Worker };
348*c8dee2aaSAndroid Build Coastguard Worker 
349*c8dee2aaSAndroid Build Coastguard Worker }  // namespace ToolUtils
350*c8dee2aaSAndroid Build Coastguard Worker 
351*c8dee2aaSAndroid Build Coastguard Worker #endif  // ToolUtils_DEFINED
352