1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SampleCode.h" 9 #include "SkView.h" 10 #include "SkCanvas.h" 11 #include "Sk64.h" 12 #include "SkGradientShader.h" 13 #include "SkGraphics.h" 14 #include "SkImageDecoder.h" 15 #include "SkKernel33MaskFilter.h" 16 #include "SkPath.h" 17 #include "SkRandom.h" 18 #include "SkRegion.h" 19 #include "SkShader.h" 20 #include "SkUtils.h" 21 #include "SkColorPriv.h" 22 #include "SkColorFilter.h" 23 #include "SkTime.h" 24 #include "SkTypeface.h" 25 #include "SkXfermode.h" 26 27 static void lettersToBitmap(SkBitmap* dst, const char chars[], 28 const SkPaint& original, SkBitmap::Config config) { 29 SkPath path; 30 SkScalar x = 0; 31 SkScalar width; 32 SkPath p; 33 for (size_t i = 0; i < strlen(chars); i++) { 34 original.getTextPath(&chars[i], 1, x, 0, &p); 35 path.addPath(p); 36 original.getTextWidths(&chars[i], 1, &width); 37 x += width; 38 } 39 SkRect bounds = path.getBounds(); 40 SkScalar sw = -original.getStrokeWidth(); 41 bounds.inset(sw, sw); 42 path.offset(-bounds.fLeft, -bounds.fTop); 43 bounds.offset(-bounds.fLeft, -bounds.fTop); 44 45 int w = SkScalarRound(bounds.width()); 46 int h = SkScalarRound(bounds.height()); 47 SkPaint paint(original); 48 SkBitmap src; 49 src.setConfig(config, w, h); 50 src.allocPixels(); 51 src.eraseColor(0); 52 { 53 SkCanvas canvas(src); 54 paint.setAntiAlias(true); 55 paint.setColor(SK_ColorBLACK); 56 paint.setStyle(SkPaint::kFill_Style); 57 canvas.drawPath(path, paint); 58 } 59 60 dst->setConfig(config, w, h); 61 dst->allocPixels(); 62 dst->eraseColor(SK_ColorWHITE); 63 { 64 SkCanvas canvas(*dst); 65 paint.setXfermodeMode(SkXfermode::kDstATop_Mode); 66 canvas.drawBitmap(src, 0, 0, &paint); 67 paint.setColor(original.getColor()); 68 paint.setStyle(SkPaint::kStroke_Style); 69 canvas.drawPath(path, paint); 70 } 71 } 72 73 static void lettersToBitmap2(SkBitmap* dst, const char chars[], 74 const SkPaint& original, SkBitmap::Config config) { 75 SkPath path; 76 SkScalar x = 0; 77 SkScalar width; 78 SkPath p; 79 for (size_t i = 0; i < strlen(chars); i++) { 80 original.getTextPath(&chars[i], 1, x, 0, &p); 81 path.addPath(p); 82 original.getTextWidths(&chars[i], 1, &width); 83 x += width; 84 } 85 SkRect bounds = path.getBounds(); 86 SkScalar sw = -original.getStrokeWidth(); 87 bounds.inset(sw, sw); 88 path.offset(-bounds.fLeft, -bounds.fTop); 89 bounds.offset(-bounds.fLeft, -bounds.fTop); 90 91 int w = SkScalarRound(bounds.width()); 92 int h = SkScalarRound(bounds.height()); 93 SkPaint paint(original); 94 95 paint.setAntiAlias(true); 96 paint.setXfermodeMode(SkXfermode::kDstATop_Mode); 97 paint.setColor(original.getColor()); 98 paint.setStyle(SkPaint::kStroke_Style); 99 100 dst->setConfig(config, w, h); 101 dst->allocPixels(); 102 dst->eraseColor(SK_ColorWHITE); 103 104 SkCanvas canvas(*dst); 105 canvas.drawPath(path, paint); 106 } 107 108 class StrokeTextView : public SampleView { 109 bool fAA; 110 public: 111 StrokeTextView() : fAA(false) { 112 this->setBGColor(0xFFCC8844); 113 } 114 115 protected: 116 // overrides from SkEventSink 117 virtual bool onQuery(SkEvent* evt) { 118 if (SampleCode::TitleQ(*evt)) { 119 SampleCode::TitleR(evt, "StrokeText"); 120 return true; 121 } 122 return this->INHERITED::onQuery(evt); 123 } 124 125 virtual void onDrawContent(SkCanvas* canvas) { 126 SkBitmap bm; 127 SkPaint paint; 128 129 paint.setStrokeWidth(SkIntToScalar(6)); 130 paint.setTextSize(SkIntToScalar(80)); 131 // paint.setTypeface(Typeface.DEFAULT_BOLD); 132 133 lettersToBitmap(&bm, "Test Case", paint, SkBitmap::kARGB_4444_Config); 134 135 canvas->drawBitmap(bm, 0, 0); 136 } 137 138 private: 139 140 typedef SampleView INHERITED; 141 }; 142 143 ////////////////////////////////////////////////////////////////////////////// 144 145 static SkView* MyFactory() { return new StrokeTextView; } 146 static SkViewRegister reg(MyFactory); 147 148