1 /* 2 * Copyright 2011 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 #include "gm.h" 8 #include "sk_tool_utils.h" 9 #include "SkCanvas.h" 10 #include "SkGradientShader.h" 11 #include "SkPath.h" 12 13 static void makebm(SkBitmap* bm, int w, int h) { 14 bm->allocN32Pixels(w, h); 15 bm->eraseColor(SK_ColorTRANSPARENT); 16 17 SkCanvas canvas(*bm); 18 SkScalar s = SkIntToScalar(SkMin32(w, h)); 19 const SkPoint kPts0[] = { { 0, 0 }, { s, s } }; 20 const SkPoint kPts1[] = { { s, 0 }, { 0, s } }; 21 const SkScalar kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 22 const SkColor kColors0[] = {0x40FF00FF, 0xF0FFFF00, 0x4000FFFF }; 23 const SkColor kColors1[] = {0xF0FF00FF, 0x80FFFF00, 0xF000FFFF }; 24 25 26 SkPaint paint; 27 28 paint.setShader(SkGradientShader::MakeLinear(kPts0, kColors0, kPos, 29 SK_ARRAY_COUNT(kColors0), SkShader::kClamp_TileMode)); 30 canvas.drawPaint(paint); 31 paint.setShader(SkGradientShader::MakeLinear(kPts1, kColors1, kPos, 32 SK_ARRAY_COUNT(kColors1), SkShader::kClamp_TileMode)); 33 canvas.drawPaint(paint); 34 } 35 36 /////////////////////////////////////////////////////////////////////////////// 37 38 struct LabeledMatrix { 39 SkMatrix fMatrix; 40 const char* fLabel; 41 }; 42 43 DEF_SIMPLE_GM_BG(shadertext2, canvas, 1800, 900, 44 sk_tool_utils::color_to_565(0xFFDDDDDD)) { 45 constexpr char kText[] = "SKIA"; 46 constexpr int kTextLen = SK_ARRAY_COUNT(kText) - 1; 47 constexpr int kPointSize = 55; 48 49 SkTDArray<LabeledMatrix> matrices; 50 matrices.append()->fMatrix.reset(); 51 matrices.top().fLabel = "Identity"; 52 matrices.append()->fMatrix.setScale(1.2f, 0.8f); 53 matrices.top().fLabel = "Scale"; 54 matrices.append()->fMatrix.setRotate(10.f); 55 matrices.top().fLabel = "Rotate"; 56 matrices.append()->fMatrix.reset(); 57 matrices.top().fMatrix.setPerspX(-0.0015f); 58 matrices.top().fMatrix.setPerspY(+0.0015f); 59 matrices.top().fLabel = "Persp"; 60 61 SkTDArray<LabeledMatrix> localMatrices; 62 localMatrices.append()->fMatrix.reset(); 63 localMatrices.top().fLabel = "Identity"; 64 localMatrices.append()->fMatrix.setScale(2.5f, 0.2f); 65 localMatrices.top().fLabel = "Scale"; 66 localMatrices.append()->fMatrix.setRotate(45.f); 67 localMatrices.top().fLabel = "Rotate"; 68 localMatrices.append()->fMatrix.reset(); 69 localMatrices.top().fMatrix.setPerspX(-0.007f); 70 localMatrices.top().fMatrix.setPerspY(+0.008f); 71 localMatrices.top().fLabel = "Persp"; 72 73 static SkBitmap bmp; 74 if (bmp.isNull()) { 75 makebm(&bmp, kPointSize / 2, kPointSize / 2); 76 } 77 78 SkPaint fillPaint; 79 fillPaint.setAntiAlias(true); 80 sk_tool_utils::set_portable_typeface(&fillPaint); 81 fillPaint.setTextSize(SkIntToScalar(kPointSize)); 82 fillPaint.setFilterQuality(kLow_SkFilterQuality); 83 84 SkPaint outlinePaint; 85 outlinePaint.setAntiAlias(true); 86 sk_tool_utils::set_portable_typeface(&outlinePaint); 87 outlinePaint.setTextSize(SkIntToScalar(kPointSize)); 88 outlinePaint.setStyle(SkPaint::kStroke_Style); 89 outlinePaint.setStrokeWidth(0.f); 90 91 SkScalar w = fillPaint.measureText(kText, kTextLen); 92 static SkScalar kPadY = 0.5f * kPointSize; 93 static SkScalar kPadX = 1.5f * kPointSize; 94 95 SkPaint strokePaint(fillPaint); 96 strokePaint.setStyle(SkPaint::kStroke_Style); 97 strokePaint.setStrokeWidth(kPointSize * 0.1f); 98 99 SkPaint labelPaint; 100 labelPaint.setColor(0xff000000); 101 labelPaint.setAntiAlias(true); 102 sk_tool_utils::set_portable_typeface(&labelPaint); 103 labelPaint.setTextSize(12.f); 104 105 canvas->translate(15.f, 15.f); 106 canvas->drawBitmap(bmp, 0, 0); 107 canvas->translate(0, bmp.height() + labelPaint.getTextSize() + 15.f); 108 109 constexpr char kLabelLabel[] = "localM / canvasM"; 110 canvas->drawString(kLabelLabel, 0, 0, labelPaint); 111 canvas->translate(0, 15.f); 112 113 canvas->save(); 114 SkScalar maxLabelW = 0; 115 canvas->translate(0, kPadY / 2 + kPointSize); 116 for (int lm = 0; lm < localMatrices.count(); ++lm) { 117 canvas->drawString(matrices[lm].fLabel, 118 0, labelPaint.getTextSize() - 1, labelPaint); 119 SkScalar labelW = labelPaint.measureText(matrices[lm].fLabel, 120 strlen(matrices[lm].fLabel)); 121 maxLabelW = SkMaxScalar(maxLabelW, labelW); 122 canvas->translate(0.f, 2 * kPointSize + 2.5f * kPadY); 123 } 124 canvas->restore(); 125 126 canvas->translate(maxLabelW + kPadX / 2.f, 0.f); 127 128 for (int s = 0; s < 2; ++s) { 129 SkPaint& paint = s ? strokePaint : fillPaint; 130 131 SkScalar columnH = 0; 132 for (int m = 0; m < matrices.count(); ++m) { 133 columnH = 0; 134 canvas->save(); 135 canvas->drawString(matrices[m].fLabel, 136 0, labelPaint.getTextSize() - 1, labelPaint); 137 canvas->translate(0, kPadY / 2 + kPointSize); 138 columnH += kPadY / 2 + kPointSize; 139 for (int lm = 0; lm < localMatrices.count(); ++lm) { 140 paint.setShader(SkShader::MakeBitmapShader(bmp, SkShader::kMirror_TileMode, 141 SkShader::kRepeat_TileMode, 142 &localMatrices[lm].fMatrix)); 143 144 canvas->save(); 145 canvas->concat(matrices[m].fMatrix); 146 canvas->drawText(kText, kTextLen, 0, 0, paint); 147 canvas->drawText(kText, kTextLen, 0, 0, outlinePaint); 148 canvas->restore(); 149 150 SkPath path; 151 path.arcTo(SkRect::MakeXYWH(-0.1f * w, 0.f, 152 1.2f * w, 2.f * kPointSize), 153 225.f, 359.f, 154 false); 155 path.close(); 156 157 canvas->translate(0.f, kPointSize + kPadY); 158 columnH += kPointSize + kPadY; 159 160 canvas->save(); 161 canvas->concat(matrices[m].fMatrix); 162 canvas->drawTextOnPath(kText, kTextLen, path, nullptr, paint); 163 canvas->drawTextOnPath(kText, kTextLen, path, nullptr, outlinePaint); 164 canvas->restore(); 165 SkPaint stroke; 166 stroke.setStyle(SkPaint::kStroke_Style); 167 canvas->translate(0.f, kPointSize + kPadY); 168 columnH += kPointSize + kPadY; 169 } 170 canvas->restore(); 171 canvas->translate(w + kPadX, 0.f); 172 } 173 if (0 == s) { 174 canvas->drawLine(0.f, -kPadY, 0.f, columnH + kPadY, outlinePaint); 175 canvas->translate(kPadX / 2, 0.f); 176 constexpr char kFillLabel[] = "Filled"; 177 constexpr char kStrokeLabel[] = "Stroked"; 178 SkScalar y = columnH + kPadY / 2; 179 SkScalar fillX = -outlinePaint.measureText(kFillLabel, strlen(kFillLabel)) - kPadX; 180 SkScalar strokeX = kPadX; 181 canvas->drawString(kFillLabel, fillX, y, labelPaint); 182 canvas->drawString(kStrokeLabel, strokeX, y, labelPaint); 183 } 184 } 185 } 186