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