halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 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 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "gm/gm.h" |
Ben Wagner | 7fde8e1 | 2019-05-01 17:28:53 -0400 | [diff] [blame] | 9 | #include "include/core/SkBitmap.h" |
| 10 | #include "include/core/SkCanvas.h" |
| 11 | #include "include/core/SkColor.h" |
| 12 | #include "include/core/SkFont.h" |
| 13 | #include "include/core/SkFontTypes.h" |
| 14 | #include "include/core/SkMatrix.h" |
| 15 | #include "include/core/SkPaint.h" |
| 16 | #include "include/core/SkPoint.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 17 | #include "include/core/SkRRect.h" |
Ben Wagner | 7fde8e1 | 2019-05-01 17:28:53 -0400 | [diff] [blame] | 18 | #include "include/core/SkRect.h" |
| 19 | #include "include/core/SkScalar.h" |
| 20 | #include "include/core/SkShader.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 21 | #include "include/core/SkTextBlob.h" |
Ben Wagner | 7fde8e1 | 2019-05-01 17:28:53 -0400 | [diff] [blame] | 22 | #include "include/core/SkTileMode.h" |
| 23 | #include "include/core/SkTypeface.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 24 | #include "tools/ToolUtils.h" |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 25 | |
Ben Wagner | 7fde8e1 | 2019-05-01 17:28:53 -0400 | [diff] [blame] | 26 | #include <string.h> |
| 27 | |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 28 | static void rotated_checkerboard_shader(SkPaint* paint, |
| 29 | SkColor c1, |
| 30 | SkColor c2, |
| 31 | int size) { |
| 32 | SkBitmap bm; |
| 33 | bm.allocN32Pixels(2 * size, 2 * size); |
| 34 | bm.eraseColor(c1); |
| 35 | bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2); |
| 36 | bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2); |
| 37 | SkMatrix matrix; |
| 38 | matrix.setScale(0.75f, 0.75f); |
| 39 | matrix.preRotate(30.0f); |
Mike Reed | 50acf8f | 2019-04-08 13:20:23 -0400 | [diff] [blame] | 40 | paint->setShader(bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &matrix)); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | static void exercise_draw_pos_text(SkCanvas* canvas, |
| 44 | const char* text, |
| 45 | SkScalar x, SkScalar y, |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 46 | const SkFont& font, const SkPaint& paint) { |
Ben Wagner | 51e15a6 | 2019-05-07 15:38:46 -0400 | [diff] [blame] | 47 | const int count = font.countText(text, strlen(text), SkTextEncoding::kUTF8); |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 48 | SkTextBlobBuilder builder; |
| 49 | auto rec = builder.allocRunPos(font, count); |
Ben Wagner | 51e15a6 | 2019-05-07 15:38:46 -0400 | [diff] [blame] | 50 | font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, rec.glyphs, count); |
Mike Reed | 22451cc | 2019-01-01 15:40:28 -0500 | [diff] [blame] | 51 | font.getPos(rec.glyphs, count, rec.points(), {x, y}); |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 52 | canvas->drawTextBlob(builder.make(), 0, 0, paint); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | static void exercise_draw_pos_text_h(SkCanvas* canvas, |
| 56 | const char* text, |
| 57 | SkScalar x, SkScalar y, |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 58 | const SkFont& font, const SkPaint& paint) { |
Ben Wagner | 51e15a6 | 2019-05-07 15:38:46 -0400 | [diff] [blame] | 59 | const int count = font.countText(text, strlen(text), SkTextEncoding::kUTF8); |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 60 | SkTextBlobBuilder builder; |
| 61 | auto rec = builder.allocRunPosH(font, count, 0); |
Ben Wagner | 51e15a6 | 2019-05-07 15:38:46 -0400 | [diff] [blame] | 62 | font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, rec.glyphs, count); |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 63 | font.getXPos(rec.glyphs, count, rec.pos); |
| 64 | canvas->drawTextBlob(builder.make(), x, y, paint); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | static void test_text(SkCanvas* canvas, SkScalar size, |
| 68 | SkColor color, SkScalar Y) { |
Mike Klein | ea3f014 | 2019-03-20 11:12:10 -0500 | [diff] [blame] | 69 | SkFont font(ToolUtils::create_portable_typeface(), 24); |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 70 | font.setEdging(SkFont::Edging::kAlias); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 71 | SkPaint type; |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 72 | type.setColor(color); |
| 73 | const char text[] = "HELLO WORLD"; |
Ben Wagner | 51e15a6 | 2019-05-07 15:38:46 -0400 | [diff] [blame] | 74 | canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 32, size / 2 + Y, |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 75 | font, type); |
| 76 | SkScalar lineSpacing = font.getSpacing(); |
| 77 | exercise_draw_pos_text(canvas, text, 32, size / 2 + Y + lineSpacing, font, type); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 78 | exercise_draw_pos_text_h(canvas, text, 32, |
Mike Reed | 088b74e | 2018-12-24 14:52:46 -0500 | [diff] [blame] | 79 | size / 2 + Y + 2 * lineSpacing, font, type); |
halcanary | 05b48e2 | 2015-11-16 10:51:21 -0800 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | // If this GM works correctly, the cyan layer should be lined up with |
| 83 | // the objects below it. |
| 84 | DEF_SIMPLE_GM(skbug_257, canvas, 512, 512) { |
| 85 | const SkScalar size = 256; |
| 86 | SkAutoCanvasRestore autoCanvasRestore0(canvas, true); |
| 87 | const SkScalar scale = 1.00168f; |
| 88 | canvas->scale(scale, scale); |
| 89 | { |
| 90 | SkPaint checker; |
| 91 | rotated_checkerboard_shader(&checker, SK_ColorWHITE, SK_ColorBLACK, 16); |
| 92 | checker.setAntiAlias(true); |
| 93 | |
| 94 | SkAutoCanvasRestore autoCanvasRestore(canvas, true); |
| 95 | canvas->clear(0xFFCECFCE); |
| 96 | SkScalar translate = 225364.0f; |
| 97 | canvas->translate(0, -translate); |
| 98 | |
| 99 | // Test rects |
| 100 | SkRect rect = SkRect::MakeLTRB(8, 8 + translate, size - 8, |
| 101 | size - 8 + translate); |
| 102 | canvas->drawRect(rect, checker); |
| 103 | |
| 104 | // Test Paths |
| 105 | canvas->translate(size, 0); |
| 106 | SkRRect rrect; |
| 107 | SkVector radii[4] = {{40, 40}, {40, 40}, {40, 40}, {40, 40}}; |
| 108 | rrect.setRectRadii(rect, radii); |
| 109 | canvas->drawRRect(rrect, checker); |
| 110 | |
| 111 | // Test Points |
| 112 | canvas->translate(-size, size); |
| 113 | SkScalar delta = 1.0 / 64.0; |
| 114 | SkPoint points[8] = {{size / 2, 8 + translate}, |
| 115 | {size / 2, 8 + translate + delta}, |
| 116 | {8, size / 2 + translate}, |
| 117 | {8, size / 2 + translate + delta}, |
| 118 | {size / 2, size - 8 + translate}, |
| 119 | {size / 2, size - 8 + translate + delta}, |
| 120 | {size - 8, size / 2 + translate}, |
| 121 | {size - 8, size / 2 + translate + delta}}; |
| 122 | checker.setStyle(SkPaint::kStroke_Style); |
| 123 | checker.setStrokeWidth(8); |
| 124 | checker.setStrokeCap(SkPaint::kRound_Cap); |
| 125 | canvas->drawPoints(SkCanvas::kLines_PointMode, 8, points, checker); |
| 126 | |
| 127 | // Test Text |
| 128 | canvas->translate(size, 0); |
| 129 | test_text(canvas, size, SK_ColorBLACK, translate); |
| 130 | } |
| 131 | // reference points (without the huge translations). |
| 132 | SkPaint stroke; |
| 133 | stroke.setStyle(SkPaint::kStroke_Style); |
| 134 | stroke.setStrokeWidth(5); |
| 135 | stroke.setColor(SK_ColorCYAN); |
| 136 | canvas->drawCircle(size / 2, size / 2, size / 2 - 10, stroke); |
| 137 | canvas->drawCircle(3 * size / 2, size / 2, size / 2 - 10, stroke); |
| 138 | canvas->drawCircle(size / 2, 384, size / 2 - 10, stroke); |
| 139 | canvas->translate(size, size); |
| 140 | test_text(canvas, size, SK_ColorCYAN, 0.0f); |
| 141 | } |