• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 
8 #ifndef ToolUtils_DEFINED
9 #define ToolUtils_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkEncodedImageFormat.h"
14 #include "include/core/SkFont.h"
15 #include "include/core/SkFontStyle.h"
16 #include "include/core/SkFontTypes.h"
17 #include "include/core/SkImageEncoder.h"
18 #include "include/core/SkImageInfo.h"
19 #include "include/core/SkPixmap.h"
20 #include "include/core/SkRect.h"
21 #include "include/core/SkRefCnt.h"
22 #include "include/core/SkScalar.h"
23 #include "include/core/SkStream.h"
24 #include "include/core/SkSurface.h"
25 #include "include/core/SkTypeface.h"
26 #include "include/core/SkTypes.h"
27 #include "include/private/SkTArray.h"
28 #include "include/private/SkTDArray.h"
29 #include "include/utils/SkRandom.h"
30 
31 class SkBitmap;
32 class SkCanvas;
33 class SkFontStyle;
34 class SkImage;
35 class SkPath;
36 class SkPixmap;
37 class SkRRect;
38 class SkShader;
39 class SkSurface;
40 class SkSurfaceProps;
41 class SkTextBlobBuilder;
42 class SkTypeface;
43 
44 namespace ToolUtils {
45 
46 const char* alphatype_name (SkAlphaType);
47 const char* colortype_name (SkColorType);
48 const char* colortype_depth(SkColorType);  // like colortype_name, but channel order agnostic
49 const char* tilemode_name(SkTileMode);
50 
51 /**
52  * Map opaque colors from 8888 to 565.
53  */
54 SkColor color_to_565(SkColor color);
55 
56 /* Return a color emoji typeface with planets to scale if available. */
57 sk_sp<SkTypeface> planet_typeface();
58 
59 /** Return a color emoji typeface if available. */
60 sk_sp<SkTypeface> emoji_typeface();
61 
62 /** Sample text for the emoji_typeface font. */
63 const char* emoji_sample_text();
64 
65 /**
66  * Returns a platform-independent text renderer.
67  */
68 sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style);
69 
create_portable_typeface()70 static inline sk_sp<SkTypeface> create_portable_typeface() {
71     return create_portable_typeface(nullptr, SkFontStyle());
72 }
73 
74 /**
75  *  Turn on portable (--nonativeFonts) or GDI font rendering (--gdi).
76  */
77 void SetDefaultFontMgr();
78 
79 
80 void get_text_path(const SkFont&,
81                    const void* text,
82                    size_t      length,
83                    SkTextEncoding,
84                    SkPath*,
85                    const SkPoint* positions = nullptr);
86 
87 /**
88  *  Returns true iff all of the pixels between the two images are identical.
89  *
90  *  If the configs differ, return false.
91  */
92 bool equal_pixels(const SkPixmap&, const SkPixmap&);
93 bool equal_pixels(const SkBitmap&, const SkBitmap&);
94 bool equal_pixels(const SkImage* a, const SkImage* b);
95 
96 /** Returns a newly created CheckerboardShader. */
97 sk_sp<SkShader> create_checkerboard_shader(SkColor c1, SkColor c2, int size);
98 
99 /** Draw a checkerboard pattern in the current canvas, restricted to
100     the current clip, using SkXfermode::kSrc_Mode. */
101 void draw_checkerboard(SkCanvas* canvas, SkColor color1, SkColor color2, int checkSize);
102 
103 /** Make it easier to create a bitmap-based checkerboard */
104 SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize);
105 
106 /** A default checkerboard. */
draw_checkerboard(SkCanvas * canvas)107 inline void draw_checkerboard(SkCanvas* canvas) {
108     ToolUtils::draw_checkerboard(canvas, 0xFF999999, 0xFF666666, 8);
109 }
110 
111 SkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y, int textSize, const char* str);
112 
113 // If the canvas does't make a surface (e.g. recording), make a raster surface
114 sk_sp<SkSurface> makeSurface(SkCanvas*, const SkImageInfo&, const SkSurfaceProps* = nullptr);
115 
116 // A helper for inserting a drawtext call into a SkTextBlobBuilder
117 void add_to_text_blob_w_len(SkTextBlobBuilder*,
118                             const char* text,
119                             size_t      len,
120                             SkTextEncoding,
121                             const SkFont&,
122                             SkScalar x,
123                             SkScalar y);
124 
125 void add_to_text_blob(SkTextBlobBuilder*, const char* text, const SkFont&, SkScalar x, SkScalar y);
126 
127 // Constructs a star by walking a 'numPts'-sided regular polygon with even/odd fill:
128 //
129 //   moveTo(pts[0]);
130 //   lineTo(pts[step % numPts]);
131 //   ...
132 //   lineTo(pts[(step * (N - 1)) % numPts]);
133 //
134 // numPts=5, step=2 will produce a classic five-point star.
135 //
136 // numPts and step must be co-prime.
137 SkPath make_star(const SkRect& bounds, int numPts = 5, int step = 2);
138 
139 void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst);
140 
141 void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst);
142 
143 void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst);
144 
145 void make_big_path(SkPath& path);
146 
147 void set_path_pt(int index, const SkPoint&, SkPath* path);
148 
149 // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
150 class TopoTestNode : public SkRefCnt {
151 public:
TopoTestNode(int id)152     TopoTestNode(int id) : fID(id), fOutputPos(-1), fTempMark(false) {}
153 
dependsOn(TopoTestNode * src)154     void dependsOn(TopoTestNode* src) { *fDependencies.append() = src; }
155 
id()156     int  id() const { return fID; }
reset()157     void reset() { fOutputPos = -1; }
158 
outputPos()159     int outputPos() const { return fOutputPos; }
160 
161     // check that the topological sort is valid for this node
check()162     bool check() {
163         if (-1 == fOutputPos) {
164             return false;
165         }
166 
167         for (int i = 0; i < fDependencies.count(); ++i) {
168             if (-1 == fDependencies[i]->outputPos()) {
169                 return false;
170             }
171             // This node should've been output after all the nodes on which it depends
172             if (fOutputPos < fDependencies[i]->outputPos()) {
173                 return false;
174             }
175         }
176 
177         return true;
178     }
179 
180     // The following 7 methods are needed by the topological sort
SetTempMark(TopoTestNode * node)181     static void SetTempMark(TopoTestNode* node) { node->fTempMark = true; }
ResetTempMark(TopoTestNode * node)182     static void ResetTempMark(TopoTestNode* node) { node->fTempMark = false; }
IsTempMarked(TopoTestNode * node)183     static bool IsTempMarked(TopoTestNode* node) { return node->fTempMark; }
Output(TopoTestNode * node,int outputPos)184     static void Output(TopoTestNode* node, int outputPos) {
185         SkASSERT(-1 != outputPos);
186         node->fOutputPos = outputPos;
187     }
WasOutput(TopoTestNode * node)188     static bool          WasOutput(TopoTestNode* node) { return (-1 != node->fOutputPos); }
NumDependencies(TopoTestNode * node)189     static int           NumDependencies(TopoTestNode* node) { return node->fDependencies.count(); }
Dependency(TopoTestNode * node,int index)190     static TopoTestNode* Dependency(TopoTestNode* node, int index) {
191         return node->fDependencies[index];
192     }
193 
194     // Helper functions for TopoSortBench & TopoSortTest
AllocNodes(SkTArray<sk_sp<ToolUtils::TopoTestNode>> * graph,int num)195     static void AllocNodes(SkTArray<sk_sp<ToolUtils::TopoTestNode>>* graph, int num) {
196         graph->reserve(num);
197 
198         for (int i = 0; i < num; ++i) {
199             graph->push_back(sk_sp<TopoTestNode>(new TopoTestNode(i)));
200         }
201     }
202 
203 #ifdef SK_DEBUG
Print(const SkTArray<TopoTestNode * > & graph)204     static void Print(const SkTArray<TopoTestNode*>& graph) {
205         for (int i = 0; i < graph.count(); ++i) {
206             SkDebugf("%d, ", graph[i]->id());
207         }
208         SkDebugf("\n");
209     }
210 #endif
211 
212     // randomize the array
Shuffle(SkTArray<sk_sp<TopoTestNode>> * graph,SkRandom * rand)213     static void Shuffle(SkTArray<sk_sp<TopoTestNode>>* graph, SkRandom* rand) {
214         for (int i = graph->count() - 1; i > 0; --i) {
215             int swap = rand->nextU() % (i + 1);
216 
217             (*graph)[i].swap((*graph)[swap]);
218         }
219     }
220 
221 private:
222     int  fID;
223     int  fOutputPos;
224     bool fTempMark;
225 
226     SkTDArray<TopoTestNode*> fDependencies;
227 };
228 
229 template <typename T>
EncodeImageToFile(const char * path,const T & src,SkEncodedImageFormat f,int q)230 inline bool EncodeImageToFile(const char* path, const T& src, SkEncodedImageFormat f, int q) {
231     SkFILEWStream file(path);
232     return file.isValid() && SkEncodeImage(&file, src, f, q);
233 }
234 
235 bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
236 void copy_to_g8(SkBitmap* dst, const SkBitmap& src);
237 
238 class PixelIter {
239 public:
240     PixelIter();
PixelIter(SkSurface * surf)241     PixelIter(SkSurface* surf) {
242         SkPixmap pm;
243         if (!surf->peekPixels(&pm)) {
244             pm.reset();
245         }
246         this->reset(pm);
247     }
248 
reset(const SkPixmap & pm)249     void reset(const SkPixmap& pm) {
250         fPM  = pm;
251         fLoc = {-1, 0};
252     }
253 
254     void* next(SkIPoint* loc = nullptr) {
255         if (!fPM.addr()) {
256             return nullptr;
257         }
258         fLoc.fX += 1;
259         if (fLoc.fX >= fPM.width()) {
260             fLoc.fX = 0;
261             if (++fLoc.fY >= fPM.height()) {
262                 this->setDone();
263                 return nullptr;
264             }
265         }
266         if (loc) {
267             *loc = fLoc;
268         }
269         return fPM.writable_addr(fLoc.fX, fLoc.fY);
270     }
271 
setDone()272     void setDone() { fPM.reset(); }
273 
274 private:
275     SkPixmap fPM;
276     SkIPoint fLoc;
277 };
278 
279 }  // namespace ToolUtils
280 
281 #endif  // ToolUtils_DEFINED
282