1c3dcb67f07173af1c17771965ab7254910d52ef3caryclark/*
22010891425f10257363ae6eb0da70453746dc087tfarina * Copyright 2014 Google Inc.
32010891425f10257363ae6eb0da70453746dc087tfarina *
42010891425f10257363ae6eb0da70453746dc087tfarina * Use of this source code is governed by a BSD-style license that can be
52010891425f10257363ae6eb0da70453746dc087tfarina * found in the LICENSE file.
62010891425f10257363ae6eb0da70453746dc087tfarina */
72010891425f10257363ae6eb0da70453746dc087tfarina
84cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org#include "sk_tool_utils.h"
9992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "sk_tool_utils_flags.h"
104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
11c3dcb67f07173af1c17771965ab7254910d52ef3caryclark#include "Resources.h"
122010891425f10257363ae6eb0da70453746dc087tfarina#include "SkBitmap.h"
132010891425f10257363ae6eb0da70453746dc087tfarina#include "SkCanvas.h"
146531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark#include "SkCommonFlags.h"
152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkPoint3.h"
16b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary#include "SkShader.h"
17992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "SkTestScalerContext.h"
189e36c1a9306f052331550dab4728b9875127bfb5joshualitt#include "SkTextBlob.h"
192010891425f10257363ae6eb0da70453746dc087tfarina
20992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary ClarkDEFINE_bool(portableFonts, false, "Use portable fonts");
214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
22992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarknamespace sk_tool_utils {
235fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson/* these are the default fonts chosen by Chrome for serif, sans-serif, and monospace */
252880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic const char* gStandardFontNames[][3] = {
262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "Times", "Helvetica", "Courier" }, // Mac
272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "Times New Roman", "Helvetica", "Courier" }, // iOS
282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "Times New Roman", "Arial", "Courier New" }, // Win
292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "Times New Roman", "Arial", "Monospace" }, // Ubuntu
302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "serif", "sans-serif", "monospace" }, // Android
312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    { "Tinos", "Arimo", "Cousine" } // ChromeOS
322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson};
332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
342880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonconst char* platform_font_name(const char* name) {
352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkString platform = major_platform_os_name();
362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    int index;
372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (!strcmp(name, "serif")) {
382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        index = 0;
392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    } else if (!strcmp(name, "san-serif")) {
402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        index = 1;
412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    } else if (!strcmp(name, "monospace")) {
422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        index = 2;
432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    } else {
442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return name;
452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("Mac")) {
472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[0][index];
482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("iOS")) {
502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[1][index];
512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("Win")) {
532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[2][index];
542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("Ubuntu")) {
562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[3][index];
572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("Android")) {
592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[4][index];
602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (platform.equals("ChromeOS")) {
622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return gStandardFontNames[5][index];
632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return name;
652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
67c3dcb67f07173af1c17771965ab7254910d52ef3caryclarkconst char* platform_os_emoji() {
68c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    const char* osName = platform_os_name();
69e6633416056d10bc781dcfc32494f5766109ec79caryclark    if (!strcmp(osName, "Android") || !strcmp(osName, "Ubuntu")) {
70c3dcb67f07173af1c17771965ab7254910d52ef3caryclark        return "CBDT";
71c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
72c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    if (!strncmp(osName, "Mac", 3)) {
73c3dcb67f07173af1c17771965ab7254910d52ef3caryclark        return "SBIX";
74c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
75c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    return "";
76c3dcb67f07173af1c17771965ab7254910d52ef3caryclark}
77c3dcb67f07173af1c17771965ab7254910d52ef3caryclark
783b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclarkvoid emoji_typeface(SkAutoTUnref<SkTypeface>* tf) {
79c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    if (!strcmp(sk_tool_utils::platform_os_emoji(), "CBDT")) {
803b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclark        tf->reset(GetResourceAsTypeface("/fonts/Funkster.ttf"));
813b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclark        return;
82c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
83c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    if (!strcmp(sk_tool_utils::platform_os_emoji(), "SBIX")) {
843b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclark        tf->reset(SkTypeface::CreateFromName("Apple Color Emoji", SkTypeface::kNormal));
853b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclark        return;
86c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
872880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    tf->reset(nullptr);
883b0f98ee17e02aae4e1e1e9fa65d3c56104dd9c7caryclark    return;
89c3dcb67f07173af1c17771965ab7254910d52ef3caryclark}
90c3dcb67f07173af1c17771965ab7254910d52ef3caryclark
91c3dcb67f07173af1c17771965ab7254910d52ef3caryclarkconst char* emoji_sample_text() {
92c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    if (!strcmp(sk_tool_utils::platform_os_emoji(), "CBDT")) {
93c3dcb67f07173af1c17771965ab7254910d52ef3caryclark        return "Hamburgefons";
94c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
95c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    if (!strcmp(sk_tool_utils::platform_os_emoji(), "SBIX")) {
96c3dcb67f07173af1c17771965ab7254910d52ef3caryclark        return "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85"  // ������
97c3dcb67f07173af1c17771965ab7254910d52ef3caryclark               "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80"  // ������
98c3dcb67f07173af1c17771965ab7254910d52ef3caryclark               "\xF0\x9F\x9A\xBB" "\xF0\x9F\x92\xA9" "\xF0\x9F\x93\xB7" // ������
99c3dcb67f07173af1c17771965ab7254910d52ef3caryclark               "\xF0\x9F\x93\xA6" // ��
100c3dcb67f07173af1c17771965ab7254910d52ef3caryclark               "\xF0\x9F\x87\xBA" "\xF0\x9F\x87\xB8" "\xF0\x9F\x87\xA6"; // ������
101c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    }
102c3dcb67f07173af1c17771965ab7254910d52ef3caryclark    return "";
103c3dcb67f07173af1c17771965ab7254910d52ef3caryclark}
104c3dcb67f07173af1c17771965ab7254910d52ef3caryclark
1056531c3619f08cc83aad34883c5f00f6a358c9fadcaryclarkconst char* platform_os_name() {
1066531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    for (int index = 0; index < FLAGS_key.count(); index += 2) {
1076531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        if (!strcmp("os", FLAGS_key[index])) {
1086531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark            return FLAGS_key[index + 1];
1096531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        }
1106531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    }
1116531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    // when running SampleApp or dm without a --key pair, omit the platform name
1126531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    return "";
1136531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark}
1146531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark
1152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// omit version number in returned value
1162880df2609eba09b555ca37be04b6ad89290c765Tom HudsonSkString major_platform_os_name() {
1172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkString name;
1182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int index = 0; index < FLAGS_key.count(); index += 2) {
1192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        if (!strcmp("os", FLAGS_key[index])) {
1202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            const char* platform = FLAGS_key[index + 1];
1212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            const char* end = platform;
1222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            while (*end && (*end < '0' || *end > '9')) {
1232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                ++end;
1242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            }
1252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            name.append(platform, end - platform);
1262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            break;
1272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
1282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
1292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return name;
1302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
1312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1326531c3619f08cc83aad34883c5f00f6a358c9fadcaryclarkconst char* platform_extra_config(const char* config) {
1336531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    for (int index = 0; index < FLAGS_key.count(); index += 2) {
1346531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        if (!strcmp("extra_config", FLAGS_key[index]) && !strcmp(config, FLAGS_key[index + 1])) {
1356531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark            return config;
1366531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        }
1376531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    }
1386531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark    return "";
1396531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark}
1406531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark
141a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgconst char* colortype_name(SkColorType ct) {
142a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    switch (ct) {
143a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kUnknown_SkColorType:      return "Unknown";
144a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kAlpha_8_SkColorType:      return "Alpha_8";
145a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kIndex_8_SkColorType:      return "Index_8";
146a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kARGB_4444_SkColorType:    return "ARGB_4444";
147a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kRGB_565_SkColorType:      return "RGB_565";
148a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kRGBA_8888_SkColorType:    return "RGBA_8888";
149a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        case kBGRA_8888_SkColorType:    return "BGRA_8888";
150a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        default:
151a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org            SkASSERT(false);
152a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org            return "unexpected colortype";
153a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
154a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org}
155a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
15665cdba6ba78aaec0c0a4596bb5941020c789482bcaryclarkSkColor color_to_565(SkColor color) {
15765cdba6ba78aaec0c0a4596bb5941020c789482bcaryclark    SkPMColor pmColor = SkPreMultiplyColor(color);
158d85093c28fe360650c46971b00a39c6dbf991a6bcaryclark    U16CPU color16 = SkPixel32ToPixel16(pmColor);
15965cdba6ba78aaec0c0a4596bb5941020c789482bcaryclark    return SkPixel16ToColor(color16);
160d85093c28fe360650c46971b00a39c6dbf991a6bcaryclark}
161d85093c28fe360650c46971b00a39c6dbf991a6bcaryclark
162992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary ClarkSkTypeface* create_portable_typeface(const char* name, SkTypeface::Style style) {
16383ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark    return create_font(name, style);
16483ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark}
16583ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark
166992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkvoid set_portable_typeface(SkPaint* paint, const char* name, SkTypeface::Style style) {
16783ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark    SkTypeface* face = create_font(name, style);
16883ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark    SkSafeUnref(paint->setTypeface(face));
16983ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark}
17083ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark
1714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgvoid write_pixels(SkCanvas* canvas, const SkBitmap& bitmap, int x, int y,
1724cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org                  SkColorType colorType, SkAlphaType alphaType) {
1734cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    SkBitmap tmp(bitmap);
1744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    tmp.lockPixels();
175e62513fb9274b65bcd9fecf61acc418dd3949df5skia.committer@gmail.com
176e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const SkImageInfo info = SkImageInfo::Make(tmp.width(), tmp.height(), colorType, alphaType);
177e62513fb9274b65bcd9fecf61acc418dd3949df5skia.committer@gmail.com
1784cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    canvas->writePixels(info, tmp.getPixels(), tmp.rowBytes(), x, y);
1794cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}
1804cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
181b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanarySkShader* create_checkerboard_shader(SkColor c1, SkColor c2, int size) {
182b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    SkBitmap bm;
183b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    bm.allocN32Pixels(2 * size, 2 * size);
184b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    bm.eraseColor(c1);
185b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2);
186b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2);
187b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    return SkShader::CreateBitmapShader(
188b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary            bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
189b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary}
190b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary
1912880df2609eba09b555ca37be04b6ad89290c765Tom HudsonSkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize) {
1922880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkBitmap bitmap;
1932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    bitmap.allocN32Pixels(w, h);
1942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkCanvas canvas(bitmap);
1952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1962880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    sk_tool_utils::draw_checkerboard(&canvas, c1, c2, checkSize);
1972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return bitmap;
1982880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
1992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
200b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanaryvoid draw_checkerboard(SkCanvas* canvas, SkColor c1, SkColor c2, int size) {
201b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    SkPaint paint;
202b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    paint.setShader(create_checkerboard_shader(c1, c2, size))->unref();
203f77365f43e74dee617db669369a0eb86c6acc550halcanary    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
204b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary    canvas->drawPaint(paint);
205b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary}
206b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary
2072880df2609eba09b555ca37be04b6ad89290c765Tom HudsonSkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y,
2082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                              int textSize, const char* str) {
2092880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkBitmap bitmap;
2102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    bitmap.allocN32Pixels(w, h);
2112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkCanvas canvas(bitmap);
2122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkPaint paint;
2142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setAntiAlias(true);
2152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    sk_tool_utils::set_portable_typeface(&paint);
2162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setColor(c);
2172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setTextSize(SkIntToScalar(textSize));
2182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas.clear(0x00000000);
2202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas.drawText(str, strlen(str), SkIntToScalar(x), SkIntToScalar(y), paint);
2212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return bitmap;
2232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
2242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2259e36c1a9306f052331550dab4728b9875127bfb5joshualittvoid add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint,
2269e36c1a9306f052331550dab4728b9875127bfb5joshualitt                      SkScalar x, SkScalar y) {
2279e36c1a9306f052331550dab4728b9875127bfb5joshualitt    SkPaint paint(origPaint);
2289e36c1a9306f052331550dab4728b9875127bfb5joshualitt    SkTDArray<uint16_t> glyphs;
2299e36c1a9306f052331550dab4728b9875127bfb5joshualitt
2309e36c1a9306f052331550dab4728b9875127bfb5joshualitt    size_t len = strlen(text);
2312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    glyphs.append(paint.textToGlyphs(text, len, nullptr));
2329e36c1a9306f052331550dab4728b9875127bfb5joshualitt    paint.textToGlyphs(text, len, glyphs.begin());
2339e36c1a9306f052331550dab4728b9875127bfb5joshualitt
2349e36c1a9306f052331550dab4728b9875127bfb5joshualitt    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
2359e36c1a9306f052331550dab4728b9875127bfb5joshualitt    const SkTextBlobBuilder::RunBuffer& run = builder->allocRun(paint, glyphs.count(), x, y,
2362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                                                                nullptr);
2379e36c1a9306f052331550dab4728b9875127bfb5joshualitt    memcpy(run.glyphs, glyphs.begin(), glyphs.count() * sizeof(uint16_t));
2389e36c1a9306f052331550dab4728b9875127bfb5joshualitt}
2399e36c1a9306f052331550dab4728b9875127bfb5joshualitt
2402880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic inline void norm_to_rgb(SkBitmap* bm, int x, int y, const SkVector3& norm) {
2412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkASSERT(SkScalarNearlyEqual(norm.length(), 1.0f));
2422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    unsigned char r = static_cast<unsigned char>((0.5f * norm.fX + 0.5f) * 255);
2432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    unsigned char g = static_cast<unsigned char>((-0.5f * norm.fY + 0.5f) * 255);
2442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    unsigned char b = static_cast<unsigned char>((0.5f * norm.fZ + 0.5f) * 255);
2452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    *bm->getAddr32(x, y) = SkPackARGB32(0xFF, r, g, b);
2462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
2472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2482880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonvoid create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst) {
2492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f),
2502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                                         dst.fTop + (dst.height() / 2.0f));
2512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint halfSize = SkPoint::Make(dst.width() / 2.0f, dst.height() / 2.0f);
2522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkVector3 norm;
2542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int y = dst.fTop; y < dst.fBottom; ++y) {
2562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int x = dst.fLeft; x < dst.fRight; ++x) {
2572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            norm.fX = (x + 0.5f - center.fX) / halfSize.fX;
2582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            norm.fY = (y + 0.5f - center.fY) / halfSize.fY;
2592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SkScalar tmp = norm.fX * norm.fX + norm.fY * norm.fY;
2612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            if (tmp >= 1.0f) {
2622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                norm.set(0.0f, 0.0f, 1.0f);
2632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            } else {
2642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                norm.fZ = sqrtf(1.0f - tmp);
2652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            }
2662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            norm_to_rgb(bm, x, y, norm);
2682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
2692880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
2702880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
2712880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2722880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonvoid create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst) {
2732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f),
2742880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                                         dst.fTop + (dst.height() / 2.0f));
2752880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2762880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkIRect inner = dst;
2772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    inner.inset(dst.width()/4, dst.height()/4);
2782880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2792880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkPoint3 norm;
2802880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 left =  SkPoint3::Make(-SK_ScalarRoot2Over2, 0.0f, SK_ScalarRoot2Over2);
2812880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 up =    SkPoint3::Make(0.0f, -SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
2822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 right = SkPoint3::Make(SK_ScalarRoot2Over2,  0.0f, SK_ScalarRoot2Over2);
2832880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 down =  SkPoint3::Make(0.0f,  SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
2842880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2852880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int y = dst.fTop; y < dst.fBottom; ++y) {
2862880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int x = dst.fLeft; x < dst.fRight; ++x) {
2872880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            if (inner.contains(x, y)) {
2882880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                norm.set(0.0f, 0.0f, 1.0f);
2892880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            } else {
2902880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                SkScalar locX = x + 0.5f - center.fX;
2912880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                SkScalar locY = y + 0.5f - center.fY;
2922880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
2932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                if (locX >= 0.0f) {
2942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    if (locY > 0.0f) {
2952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                        norm = locX >= locY ? right : down;   // LR corner
2962880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    } else {
2972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                        norm = locX > -locY ? right : up;     // UR corner
2982880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    }
2992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                } else {
3002880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    if (locY > 0.0f) {
3012880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                        norm = -locX > locY ? left : down;    // LL corner
3022880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    } else {
3032880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                        norm = locX > locY ? up : left;       // UL corner
3042880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    }
3052880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                }
3062880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            }
3072880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            norm_to_rgb(bm, x, y, norm);
3092880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
3102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
3112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
3122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3132880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonvoid create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst) {
3142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f),
3152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                                         dst.fTop + (dst.height() / 2.0f));
3162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const SkScalar k1OverRoot3 = 0.5773502692f;
3182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkPoint3 norm;
3202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 leftUp =  SkPoint3::Make(-k1OverRoot3, -k1OverRoot3, k1OverRoot3);
3212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 rightUp = SkPoint3::Make(k1OverRoot3,  -k1OverRoot3, k1OverRoot3);
3222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const SkPoint3 down =  SkPoint3::Make(0.0f,  SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
3232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int y = dst.fTop; y < dst.fBottom; ++y) {
3252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int x = dst.fLeft; x < dst.fRight; ++x) {
3262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SkScalar locX = x + 0.5f - center.fX;
3272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SkScalar locY = y + 0.5f - center.fY;
3282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            if (locX >= 0.0f) {
3302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                if (locY > 0.0f) {
3312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    norm = locX >= locY ? rightUp : down;   // LR corner
3322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                } else {
3332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    norm = rightUp;
3342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                }
3352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            } else {
3362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                if (locY > 0.0f) {
3372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    norm = -locX > locY ? leftUp : down;    // LL corner
3382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                } else {
3392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                    norm = leftUp;
3402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                }
3412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            }
3422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            norm_to_rgb(bm, x, y, norm);
3442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
3452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
3462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
3472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3482880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonvoid make_big_path(SkPath& path) {
3492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    #include "BigPathBench.inc"
3502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
3512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3522880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic float gaussian2d_value(int x, int y, float sigma) {
3532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // don't bother with the scale term since we're just going to normalize the
3542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // kernel anyways
3552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    float temp = expf(-(x*x + y*y)/(2*sigma*sigma));
3562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return temp;
3572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
3582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3592880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic float* create_2d_kernel(float sigma, int* filterSize) {
3602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // We will actually take 2*halfFilterSize+1 samples (i.e., our filter kernel
3612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // sizes are always odd)
3622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    int halfFilterSize = SkScalarCeilToInt(6*sigma)/2;
3632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    int wh = *filterSize = 2*halfFilterSize + 1;
3642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    float* temp = new float[wh*wh];
3662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    float filterTot = 0.0f;
3682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int yOff = 0; yOff < wh; ++yOff) {
3692880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int xOff = 0; xOff < wh; ++xOff) {
3702880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            temp[yOff*wh+xOff] = gaussian2d_value(xOff-halfFilterSize, yOff-halfFilterSize, sigma);
3712880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3722880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            filterTot += temp[yOff*wh+xOff];
3732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
3742880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
3752880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3762880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // normalize the kernel
3772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int yOff = 0; yOff < wh; ++yOff) {
3782880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int xOff = 0; xOff < wh; ++xOff) {
3792880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            temp[yOff*wh+xOff] /= filterTot;
3802880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
3812880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
3822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3832880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return temp;
3842880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
3852880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3862880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic SkPMColor blur_pixel(const SkBitmap& bm, int x, int y, float* kernel, int wh) {
3872880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkASSERT(wh & 0x1);
3882880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3892880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    int halfFilterSize = (wh-1)/2;
3902880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3912880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    float r = 0.0f, g = 0.0f, b = 0.0f;
3922880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int yOff = 0; yOff < wh; ++yOff) {
3932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        int ySamp = y + yOff - halfFilterSize;
3942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
3952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        if (ySamp < 0) {
3962880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            ySamp = 0;
3972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        } else if (ySamp > bm.height()-1) {
3982880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            ySamp = bm.height()-1;
3992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
4002880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4012880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int xOff = 0; xOff < wh; ++xOff) {
4022880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            int xSamp = x + xOff - halfFilterSize;
4032880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4042880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            if (xSamp < 0) {
4052880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                xSamp = 0;
4062880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            } else if (xSamp > bm.width()-1) {
4072880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                xSamp = bm.width()-1;
4082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            }
4092880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            float filter = kernel[yOff*wh + xOff];
4112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SkPMColor c = *bm.getAddr32(xSamp, ySamp);
4132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            r += SkGetPackedR32(c) * filter;
4152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            g += SkGetPackedG32(c) * filter;
4162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            b += SkGetPackedB32(c) * filter;
4172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
4182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
4192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    U8CPU r8, g8, b8;
4212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    r8 = (U8CPU) (r+0.5f);
4232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    g8 = (U8CPU) (g+0.5f);
4242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    b8 = (U8CPU) (b+0.5f);
4252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return SkPackARGB32(255, r8, g8, b8);
4272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
4282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4292880df2609eba09b555ca37be04b6ad89290c765Tom HudsonSkBitmap slow_blur(const SkBitmap& src, float sigma) {
4302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkBitmap dst;
4312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    dst.allocN32Pixels(src.width(), src.height(), true);
4332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    int wh;
4352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkAutoTDeleteArray<float> kernel(create_2d_kernel(sigma, &wh));
4362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    for (int y = 0; y < src.height(); ++y) {
4382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int x = 0; x < src.width(); ++x) {
4392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            *dst.getAddr32(x, y) = blur_pixel(src, x, y, kernel.get(), wh);
4402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
4412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
4422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
4432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return dst;
4442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
4459c4909b50ff9d0fdf9bce2a67cd459aeb28cdc3crobertphillips
4462010891425f10257363ae6eb0da70453746dc087tfarina}  // namespace sk_tool_utils
447