• 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  // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
148  class TopoTestNode : public SkRefCnt {
149  public:
TopoTestNode(int id)150      TopoTestNode(int id) : fID(id), fOutputPos(-1), fTempMark(false) {}
151  
dependsOn(TopoTestNode * src)152      void dependsOn(TopoTestNode* src) { *fDependencies.append() = src; }
153  
id()154      int  id() const { return fID; }
reset()155      void reset() { fOutputPos = -1; }
156  
outputPos()157      int outputPos() const { return fOutputPos; }
158  
159      // check that the topological sort is valid for this node
check()160      bool check() {
161          if (-1 == fOutputPos) {
162              return false;
163          }
164  
165          for (int i = 0; i < fDependencies.count(); ++i) {
166              if (-1 == fDependencies[i]->outputPos()) {
167                  return false;
168              }
169              // This node should've been output after all the nodes on which it depends
170              if (fOutputPos < fDependencies[i]->outputPos()) {
171                  return false;
172              }
173          }
174  
175          return true;
176      }
177  
178      // The following 7 methods are needed by the topological sort
SetTempMark(TopoTestNode * node)179      static void SetTempMark(TopoTestNode* node) { node->fTempMark = true; }
ResetTempMark(TopoTestNode * node)180      static void ResetTempMark(TopoTestNode* node) { node->fTempMark = false; }
IsTempMarked(TopoTestNode * node)181      static bool IsTempMarked(TopoTestNode* node) { return node->fTempMark; }
Output(TopoTestNode * node,int outputPos)182      static void Output(TopoTestNode* node, int outputPos) {
183          SkASSERT(-1 != outputPos);
184          node->fOutputPos = outputPos;
185      }
WasOutput(TopoTestNode * node)186      static bool          WasOutput(TopoTestNode* node) { return (-1 != node->fOutputPos); }
NumDependencies(TopoTestNode * node)187      static int           NumDependencies(TopoTestNode* node) { return node->fDependencies.count(); }
Dependency(TopoTestNode * node,int index)188      static TopoTestNode* Dependency(TopoTestNode* node, int index) {
189          return node->fDependencies[index];
190      }
191  
192      // Helper functions for TopoSortBench & TopoSortTest
AllocNodes(SkTArray<sk_sp<ToolUtils::TopoTestNode>> * graph,int num)193      static void AllocNodes(SkTArray<sk_sp<ToolUtils::TopoTestNode>>* graph, int num) {
194          graph->reserve(num);
195  
196          for (int i = 0; i < num; ++i) {
197              graph->push_back(sk_sp<TopoTestNode>(new TopoTestNode(i)));
198          }
199      }
200  
201  #ifdef SK_DEBUG
Print(const SkTArray<TopoTestNode * > & graph)202      static void Print(const SkTArray<TopoTestNode*>& graph) {
203          for (int i = 0; i < graph.count(); ++i) {
204              SkDebugf("%d, ", graph[i]->id());
205          }
206          SkDebugf("\n");
207      }
208  #endif
209  
210      // randomize the array
Shuffle(SkTArray<sk_sp<TopoTestNode>> * graph,SkRandom * rand)211      static void Shuffle(SkTArray<sk_sp<TopoTestNode>>* graph, SkRandom* rand) {
212          for (int i = graph->count() - 1; i > 0; --i) {
213              int swap = rand->nextU() % (i + 1);
214  
215              (*graph)[i].swap((*graph)[swap]);
216          }
217      }
218  
219  private:
220      int  fID;
221      int  fOutputPos;
222      bool fTempMark;
223  
224      SkTDArray<TopoTestNode*> fDependencies;
225  };
226  
227  template <typename T>
EncodeImageToFile(const char * path,const T & src,SkEncodedImageFormat f,int q)228  inline bool EncodeImageToFile(const char* path, const T& src, SkEncodedImageFormat f, int q) {
229      SkFILEWStream file(path);
230      return file.isValid() && SkEncodeImage(&file, src, f, q);
231  }
232  
233  bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
234  void copy_to_g8(SkBitmap* dst, const SkBitmap& src);
235  
236  class PixelIter {
237  public:
238      PixelIter();
PixelIter(SkSurface * surf)239      PixelIter(SkSurface* surf) {
240          SkPixmap pm;
241          if (!surf->peekPixels(&pm)) {
242              pm.reset();
243          }
244          this->reset(pm);
245      }
246  
reset(const SkPixmap & pm)247      void reset(const SkPixmap& pm) {
248          fPM  = pm;
249          fLoc = {-1, 0};
250      }
251  
252      void* next(SkIPoint* loc = nullptr) {
253          if (!fPM.addr()) {
254              return nullptr;
255          }
256          fLoc.fX += 1;
257          if (fLoc.fX >= fPM.width()) {
258              fLoc.fX = 0;
259              if (++fLoc.fY >= fPM.height()) {
260                  this->setDone();
261                  return nullptr;
262              }
263          }
264          if (loc) {
265              *loc = fLoc;
266          }
267          return fPM.writable_addr(fLoc.fX, fLoc.fY);
268      }
269  
setDone()270      void setDone() { fPM.reset(); }
271  
272  private:
273      SkPixmap fPM;
274      SkIPoint fLoc;
275  };
276  
277  }  // namespace ToolUtils
278  
279  #endif  // ToolUtils_DEFINED
280