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 8 #include "gm.h" 9 #include "sk_tool_utils.h" 10 #include "SkImage.h" 11 #include "SkRRect.h" 12 13 static void rotated_checkerboard_shader(SkPaint* paint, 14 SkColor c1, 15 SkColor c2, 16 int size) { 17 SkBitmap bm; 18 bm.allocN32Pixels(2 * size, 2 * size); 19 bm.eraseColor(c1); 20 bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2); 21 bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2); 22 SkMatrix matrix; 23 matrix.setScale(0.75f, 0.75f); 24 matrix.preRotate(30.0f); 25 paint->setShader( 26 SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, 27 &matrix)); 28 } 29 30 static void exercise_draw_pos_text(SkCanvas* canvas, 31 const char* text, 32 SkScalar x, SkScalar y, 33 const SkPaint& paint) { 34 size_t textLen = strlen(text); 35 int count = paint.countText(text, textLen); 36 SkAutoTArray<SkScalar> widths(count); 37 paint.getTextWidths(text, textLen, &widths[0]); 38 SkAutoTArray<SkPoint> pos(count); 39 for (int i = 0; i < count; ++i) { 40 pos[i].set(x, y); 41 x += widths[i]; 42 } 43 canvas->drawPosText(text, textLen, &pos[0], paint); 44 } 45 46 static void exercise_draw_pos_text_h(SkCanvas* canvas, 47 const char* text, 48 SkScalar x, SkScalar y, 49 const SkPaint& paint) { 50 size_t textLen = strlen(text); 51 int count = paint.countText(text, textLen); 52 SkAutoTArray<SkScalar> widths(count); 53 paint.getTextWidths(text, textLen, &widths[0]); 54 SkAutoTArray<SkScalar> pos(count); 55 for (int i = 0; i < count; ++i) { 56 pos[i] = x; 57 x += widths[i]; 58 } 59 canvas->drawPosTextH(text, textLen, &pos[0], y, paint); 60 } 61 62 static void test_text(SkCanvas* canvas, SkScalar size, 63 SkColor color, SkScalar Y) { 64 SkPaint type; 65 type.setTextSize(24); 66 sk_tool_utils::set_portable_typeface(&type); 67 type.setColor(color); 68 const char text[] = "HELLO WORLD"; 69 canvas->drawString(text, 32, size / 2 + Y, type); 70 SkScalar lineSpacing = type.getFontSpacing(); 71 exercise_draw_pos_text(canvas, text, 32, size / 2 + Y + lineSpacing, type); 72 exercise_draw_pos_text_h(canvas, text, 32, 73 size / 2 + Y + 2 * lineSpacing, type); 74 } 75 76 // If this GM works correctly, the cyan layer should be lined up with 77 // the objects below it. 78 DEF_SIMPLE_GM(skbug_257, canvas, 512, 512) { 79 const SkScalar size = 256; 80 SkAutoCanvasRestore autoCanvasRestore0(canvas, true); 81 const SkScalar scale = 1.00168f; 82 canvas->scale(scale, scale); 83 { 84 SkPaint checker; 85 rotated_checkerboard_shader(&checker, SK_ColorWHITE, SK_ColorBLACK, 16); 86 checker.setAntiAlias(true); 87 88 SkAutoCanvasRestore autoCanvasRestore(canvas, true); 89 canvas->clear(0xFFCECFCE); 90 SkScalar translate = 225364.0f; 91 canvas->translate(0, -translate); 92 93 // Test rects 94 SkRect rect = SkRect::MakeLTRB(8, 8 + translate, size - 8, 95 size - 8 + translate); 96 canvas->drawRect(rect, checker); 97 98 // Test Paths 99 canvas->translate(size, 0); 100 SkRRect rrect; 101 SkVector radii[4] = {{40, 40}, {40, 40}, {40, 40}, {40, 40}}; 102 rrect.setRectRadii(rect, radii); 103 canvas->drawRRect(rrect, checker); 104 105 // Test Points 106 canvas->translate(-size, size); 107 SkScalar delta = 1.0 / 64.0; 108 SkPoint points[8] = {{size / 2, 8 + translate}, 109 {size / 2, 8 + translate + delta}, 110 {8, size / 2 + translate}, 111 {8, size / 2 + translate + delta}, 112 {size / 2, size - 8 + translate}, 113 {size / 2, size - 8 + translate + delta}, 114 {size - 8, size / 2 + translate}, 115 {size - 8, size / 2 + translate + delta}}; 116 checker.setStyle(SkPaint::kStroke_Style); 117 checker.setStrokeWidth(8); 118 checker.setStrokeCap(SkPaint::kRound_Cap); 119 canvas->drawPoints(SkCanvas::kLines_PointMode, 8, points, checker); 120 121 // Test Text 122 canvas->translate(size, 0); 123 test_text(canvas, size, SK_ColorBLACK, translate); 124 } 125 // reference points (without the huge translations). 126 SkPaint stroke; 127 stroke.setStyle(SkPaint::kStroke_Style); 128 stroke.setStrokeWidth(5); 129 stroke.setColor(SK_ColorCYAN); 130 canvas->drawCircle(size / 2, size / 2, size / 2 - 10, stroke); 131 canvas->drawCircle(3 * size / 2, size / 2, size / 2 - 10, stroke); 132 canvas->drawCircle(size / 2, 384, size / 2 - 10, stroke); 133 canvas->translate(size, size); 134 test_text(canvas, size, SK_ColorCYAN, 0.0f); 135 } 136