Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2013 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 | |
| 10 #include "Resources.h" | |
| 11 #include "SkCanvas.h" | |
| 12 #include "SkGradientShader.h" | |
| 13 #include "SkStream.h" | |
| 14 #include "SkTextBlob.h" | |
| 15 #include "SkTypeface.h" | |
| 16 | |
| 17 namespace skiagm { | |
| 18 | |
| 19 static void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint, | |
| 20 SkScalar x, SkScalar y) { | |
| 21 SkPaint paint(origPaint); | |
| 22 SkTDArray<uint16_t> glyphs; | |
| 23 | |
| 24 size_t len = strlen(text); | |
| 25 glyphs.append(paint.textToGlyphs(text, len, NULL)); | |
| 26 paint.textToGlyphs(text, len, glyphs.begin()); | |
| 27 | |
| 28 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
| 29 const SkTextBlobBuilder::RunBuffer& run = builder->allocRun(paint, glyphs.co unt(), x, y, | |
| 30 NULL); | |
| 31 memcpy(run.glyphs, glyphs.begin(), glyphs.count() * sizeof(uint16_t)); | |
| 32 } | |
| 33 | |
| 34 static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& s kPaint, | |
| 35 const SkRect& clipRect) { | |
| 36 SkPaint clipHairline; | |
| 37 clipHairline.setColor(SK_ColorWHITE); | |
| 38 clipHairline.setStyle(SkPaint::kStroke_Style); | |
| 39 | |
| 40 SkPaint paint(skPaint); | |
| 41 canvas->save(); | |
| 42 canvas->drawRect(clipRect, clipHairline); | |
| 43 paint.setAlpha(0x20); | |
| 44 canvas->drawTextBlob(blob, 0, 0, paint); | |
| 45 canvas->clipRect(clipRect); | |
| 46 paint.setAlpha(0xFF); | |
| 47 canvas->drawTextBlob(blob, 0, 0, paint); | |
| 48 canvas->restore(); | |
| 49 } | |
| 50 | |
| 51 class MixedTextBlobsGM : public GM { | |
| 52 public: | |
| 53 MixedTextBlobsGM() { } | |
| 54 | |
| 55 protected: | |
| 56 virtual void onOnceBeforeDraw() override { | |
|
bsalomon
2015/04/03 14:33:43
-virtual
| |
| 57 SkAutoTDelete<SkFILEStream> stream; | |
| 58 SkString filename; | |
| 59 #ifndef SK_BUILD_FOR_MAC | |
| 60 filename = GetResourcePath("/Funkster.ttf"); | |
| 61 stream.reset(new SkFILEStream(filename.c_str())); | |
| 62 if (stream->isValid()) { | |
| 63 fEmojiTypeface.reset(SkTypeface::CreateFromStream(stream.detach())); | |
| 64 } else { | |
| 65 SkDebugf("Could not find Funkster.ttf, please set --resourcePath cor rectly.\n"); | |
| 66 } | |
| 67 fEmojiText = "Emoji!!!"; | |
| 68 #else | |
| 69 fEmojiTypeface.reset(SkTypeface::CreateFromName("Apple Color Emoji", SkT ypeface::kNormal)); | |
| 70 fEmojiText = "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85" // 💰🏡🎅 | |
| 71 "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80"; / / 🍪🍕🚀 | |
| 72 #endif | |
| 73 | |
| 74 filename = GetResourcePath("/ReallyBigA.ttf"); | |
| 75 | |
| 76 stream.reset(new SkFILEStream(filename.c_str())); | |
| 77 if (stream->isValid()) { | |
| 78 fReallyBigATypeface.reset(SkTypeface::CreateFromStream(stream.detach ())); | |
| 79 } | |
| 80 | |
| 81 SkTextBlobBuilder builder; | |
| 82 | |
| 83 // make textblob | |
| 84 // Text so large we draw as paths | |
| 85 SkPaint paint; | |
| 86 paint.setTextSize(384); | |
| 87 const char* text = "O"; | |
| 88 sk_tool_utils::set_portable_typeface(&paint); | |
| 89 | |
| 90 SkRect bounds; | |
| 91 paint.measureText(text, strlen(text), &bounds); | |
| 92 | |
| 93 size_t yOffset = bounds.height(); | |
| 94 add_to_text_blob(&builder, text, paint, 10, yOffset); | |
| 95 size_t corruptedAx = bounds.width(); | |
| 96 size_t corruptedAy = yOffset; | |
| 97 | |
| 98 const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; | |
| 99 const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; | |
| 100 | |
| 101 size_t xOffset = boundsHalfWidth; | |
| 102 yOffset = boundsHalfHeight; | |
| 103 | |
| 104 // LCD | |
| 105 paint.setTextSize(32); | |
| 106 text = "LCD!!!!!"; | |
| 107 paint.setSubpixelText(true); | |
| 108 paint.setLCDRenderText(true); | |
| 109 paint.measureText(text, strlen(text), &bounds); | |
| 110 add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.25f , | |
| 111 yOffset - bounds.height() * 0.5f ); | |
| 112 yOffset += bounds.height(); | |
| 113 | |
| 114 // color emoji | |
| 115 paint.setSubpixelText(false); | |
| 116 paint.setLCDRenderText(false); | |
| 117 paint.setTypeface(fEmojiTypeface); | |
| 118 text = fEmojiText; | |
| 119 paint.measureText(text, strlen(text), &bounds); | |
| 120 add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.3f, yOffset); | |
| 121 | |
| 122 // Corrupted font | |
| 123 paint.setTextSize(12); | |
| 124 text = "aA"; | |
| 125 paint.setTypeface(fReallyBigATypeface); | |
| 126 add_to_text_blob(&builder, text, paint, corruptedAx, corruptedAy); | |
| 127 fBlob.reset(builder.build()); | |
| 128 } | |
| 129 | |
| 130 SkString onShortName() override { | |
| 131 return SkString("mixedtextblobs"); | |
| 132 } | |
| 133 | |
| 134 SkISize onISize() override { | |
| 135 return SkISize::Make(kWidth, kHeight); | |
| 136 } | |
| 137 | |
| 138 void onDraw(SkCanvas* canvas) override { | |
| 139 | |
| 140 canvas->drawColor(SK_ColorGRAY); | |
| 141 | |
| 142 SkPaint paint; | |
| 143 | |
| 144 // setup work needed to draw text with different clips | |
| 145 paint.setColor(SK_ColorBLACK); | |
| 146 canvas->translate(10, 40); | |
| 147 | |
| 148 paint.setTextSize(40); | |
| 149 | |
| 150 // compute the bounds of the text and setup some clips | |
| 151 SkRect bounds = fBlob->bounds(); | |
| 152 | |
| 153 const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; | |
| 154 const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; | |
| 155 const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf; | |
| 156 const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf; | |
| 157 | |
| 158 SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(), | |
| 159 boundsHalfWidth, boundsHalfHeigh t); | |
| 160 SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.center Y(), | |
| 161 boundsHalfWidth, boundsHalfHeig ht); | |
| 162 SkRect interiorClip = bounds; | |
| 163 interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight); | |
| 164 | |
| 165 const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, inte riorClip}; | |
| 166 | |
| 167 size_t count = sizeof(clipRects) / sizeof(SkRect); | |
| 168 for (size_t x = 0; x < count; ++x) { | |
| 169 draw_blob(canvas, fBlob, paint, clipRects[x]); | |
| 170 if (x == (count >> 1) - 1) { | |
| 171 canvas->translate(SkScalarFloorToScalar(bounds.width() + SkIntTo Scalar(25)), | |
| 172 -(x * SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25)))); | |
|
bsalomon
2015/04/03 14:33:43
line wrap
| |
| 173 } else { | |
| 174 canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkI ntToScalar(25))); | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 private: | |
| 180 SkAutoTUnref<SkTypeface> fEmojiTypeface; | |
| 181 SkAutoTUnref<SkTypeface> fReallyBigATypeface; | |
| 182 const char* fEmojiText; | |
| 183 SkAutoTUnref<const SkTextBlob> fBlob; | |
| 184 | |
| 185 static const int kWidth = 1250; | |
| 186 static const int kHeight = 700; | |
| 187 | |
| 188 typedef GM INHERITED; | |
| 189 }; | |
| 190 | |
| 191 ////////////////////////////////////////////////////////////////////////////// | |
| 192 | |
| 193 static GM* MyFactory(void*) { return new MixedTextBlobsGM; } | |
|
bsalomon
2015/04/03 14:33:43
use DEF_GM?
| |
| 194 static GMRegistry reg(MyFactory); | |
| 195 | |
| 196 } | |
| OLD | NEW |