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 "SkImageEncoder.h" 13 #include "SkImageInfo.h" 14 #include "SkPixelSerializer.h" 15 #include "SkRandom.h" 16 #include "SkStream.h" 17 #include "SkTDArray.h" 18 #include "SkTypeface.h" 19 20 class SkBitmap; 21 class SkCanvas; 22 class SkColorFilter; 23 class SkPaint; 24 class SkPath; 25 class SkRRect; 26 class SkShader; 27 class SkTestFont; 28 class SkTextBlobBuilder; 29 30 namespace sk_tool_utils { 31 32 const char* colortype_name(SkColorType); 33 34 /** 35 * Map opaque colors from 8888 to 565. 36 */ 37 SkColor color_to_565(SkColor color); 38 39 /** 40 * Return a color emoji typeface if available. 41 */ 42 sk_sp<SkTypeface> emoji_typeface(); 43 44 /** 45 * If the platform supports color emoji, return sample text the emoji can render. 46 */ 47 const char* emoji_sample_text(); 48 49 /** 50 * If the platform supports color emoji, return the type (i.e. "CBDT", "SBIX", ""). 51 */ 52 const char* platform_os_emoji(); 53 54 /** 55 * Return the platform name with the version number ("Mac10.9", "Win8", etc.) if available. 56 */ 57 const char* platform_os_name(); 58 59 /** 60 * Return the platform name without the version number ("Mac", "Win", etc.) if available. 61 */ 62 SkString major_platform_os_name(); 63 64 /** 65 * Return the platform extra config (e.g. "GDI") if available. 66 */ 67 const char* platform_extra_config(const char* config); 68 69 /** 70 * Map serif, san-serif, and monospace to the platform-specific font name. 71 */ 72 const char* platform_font_name(const char* name); 73 74 /** 75 * Sets the paint to use a platform-independent text renderer 76 */ 77 void set_portable_typeface(SkPaint* paint, const char* name = nullptr, 78 SkFontStyle style = SkFontStyle()); 79 80 /** 81 * Returns a platform-independent text renderer. 82 */ 83 sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style); 84 85 /** Call to clean up portable font references. */ 86 void release_portable_typefaces(); 87 88 /** 89 * Call canvas->writePixels() by using the pixels from bitmap, but with an info that claims 90 * the pixels are colorType + alphaType 91 */ 92 void write_pixels(SkCanvas*, const SkBitmap&, int x, int y, SkColorType, SkAlphaType); 93 94 // private to sk_tool_utils 95 sk_sp<SkTypeface> create_font(const char* name, SkFontStyle); 96 97 /** Returns a newly created CheckerboardShader. */ 98 sk_sp<SkShader> create_checkerboard_shader(SkColor c1, SkColor c2, int size); 99 100 /** Draw a checkerboard pattern in the current canvas, restricted to 101 the current clip, using SkXfermode::kSrc_Mode. */ 102 void draw_checkerboard(SkCanvas* canvas, 103 SkColor color1, 104 SkColor color2, 105 int checkSize); 106 107 /** Make it easier to create a bitmap-based checkerboard */ 108 SkBitmap create_checkerboard_bitmap(int w, int h, 109 SkColor c1, SkColor c2, 110 int checkSize); 111 112 /** A default checkerboard. */ draw_checkerboard(SkCanvas * canvas)113 inline void draw_checkerboard(SkCanvas* canvas) { 114 sk_tool_utils::draw_checkerboard(canvas, 0xFF999999, 0xFF666666, 8); 115 } 116 117 SkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y, 118 int textSize, const char* str); 119 120 // A helper for inserting a drawtext call into a SkTextBlobBuilder 121 void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint, 122 SkScalar x, SkScalar y); 123 124 void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst); 125 126 void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst); 127 128 void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst); 129 130 void make_big_path(SkPath& path); 131 132 // Return a blurred version of 'src'. This doesn't use a separable filter 133 // so it is slow! 134 SkBitmap slow_blur(const SkBitmap& src, float sigma); 135 136 SkRect compute_central_occluder(const SkRRect& rr); 137 SkRect compute_widest_occluder(const SkRRect& rr); 138 SkRect compute_tallest_occluder(const SkRRect& rr); 139 140 // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp) 141 class TopoTestNode { 142 public: TopoTestNode(int id)143 TopoTestNode(int id) : fID(id), fOutputPos(-1), fTempMark(false) { } 144 dependsOn(TopoTestNode * src)145 void dependsOn(TopoTestNode* src) { 146 *fDependencies.append() = src; 147 } 148 id()149 int id() const { return fID; } reset()150 void reset() { fOutputPos = -1; } 151 outputPos()152 int outputPos() const { return fOutputPos; } 153 154 // check that the topological sort is valid for this node check()155 bool check() { 156 if (-1 == fOutputPos) { 157 return false; 158 } 159 160 for (int i = 0; i < fDependencies.count(); ++i) { 161 if (-1 == fDependencies[i]->outputPos()) { 162 return false; 163 } 164 // This node should've been output after all the nodes on which it depends 165 if (fOutputPos < fDependencies[i]->outputPos()) { 166 return false; 167 } 168 } 169 170 return true; 171 } 172 173 // The following 7 methods are needed by the topological sort SetTempMark(TopoTestNode * node)174 static void SetTempMark(TopoTestNode* node) { node->fTempMark = true; } ResetTempMark(TopoTestNode * node)175 static void ResetTempMark(TopoTestNode* node) { node->fTempMark = false; } IsTempMarked(TopoTestNode * node)176 static bool IsTempMarked(TopoTestNode* node) { return node->fTempMark; } Output(TopoTestNode * node,int outputPos)177 static void Output(TopoTestNode* node, int outputPos) { 178 SkASSERT(-1 != outputPos); 179 node->fOutputPos = outputPos; 180 } WasOutput(TopoTestNode * node)181 static bool WasOutput(TopoTestNode* node) { return (-1 != node->fOutputPos); } NumDependencies(TopoTestNode * node)182 static int NumDependencies(TopoTestNode* node) { return node->fDependencies.count(); } Dependency(TopoTestNode * node,int index)183 static TopoTestNode* Dependency(TopoTestNode* node, int index) { 184 return node->fDependencies[index]; 185 } 186 187 // Helper functions for TopoSortBench & TopoSortTest AllocNodes(SkTDArray<TopoTestNode * > * graph,int num)188 static void AllocNodes(SkTDArray<TopoTestNode*>* graph, int num) { 189 graph->setReserve(num); 190 191 for (int i = 0; i < num; ++i) { 192 *graph->append() = new TopoTestNode(i); 193 } 194 } 195 DeallocNodes(SkTDArray<TopoTestNode * > * graph)196 static void DeallocNodes(SkTDArray<TopoTestNode*>* graph) { 197 for (int i = 0; i < graph->count(); ++i) { 198 delete (*graph)[i]; 199 } 200 } 201 202 #ifdef SK_DEBUG Print(const SkTDArray<TopoTestNode * > & graph)203 static void Print(const SkTDArray<TopoTestNode*>& graph) { 204 for (int i = 0; i < graph.count(); ++i) { 205 SkDebugf("%d, ", graph[i]->id()); 206 } 207 SkDebugf("\n"); 208 } 209 #endif 210 211 // randomize the array Shuffle(SkTDArray<TopoTestNode * > * graph,SkRandom * rand)212 static void Shuffle(SkTDArray<TopoTestNode*>* graph, SkRandom* rand) { 213 for (int i = graph->count()-1; i > 0; --i) { 214 int swap = rand->nextU() % (i+1); 215 216 TopoTestNode* tmp = (*graph)[i]; 217 (*graph)[i] = (*graph)[swap]; 218 (*graph)[swap] = tmp; 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 template <typename T> EncodeImageToData(const T & src,SkEncodedImageFormat f,int q)237 inline sk_sp<SkData> EncodeImageToData(const T& src, SkEncodedImageFormat f, int q) { 238 SkDynamicMemoryWStream buf; 239 return SkEncodeImage(&buf, src , f, q) ? buf.detachAsData() : nullptr; 240 } 241 242 /** 243 * Uses SkEncodeImage to serialize images that are not already 244 * encoded as SkEncodedImageFormat::kPNG images. 245 */ MakePixelSerializer()246 inline sk_sp<SkPixelSerializer> MakePixelSerializer() { 247 struct EncodeImagePixelSerializer final : SkPixelSerializer { 248 bool onUseEncodedData(const void*, size_t) override { return true; } 249 SkData* onEncode(const SkPixmap& pmap) override { 250 return EncodeImageToData(pmap, SkEncodedImageFormat::kPNG, 100).release(); 251 } 252 }; 253 return sk_make_sp<EncodeImagePixelSerializer>(); 254 } 255 256 bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src); 257 void copy_to_g8(SkBitmap* dst, const SkBitmap& src); 258 259 } // namespace sk_tool_utils 260 261 #endif // sk_tool_utils_DEFINED 262