blob: 1ba382774a636fda25b80f40c9d4d2fa90705e71 [file] [log] [blame]
reed@google.comed3ee642012-02-14 16:12:49 +00001/*
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
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkPath.h"
11#include "SkGradientShader.h"
12#include "SkTypeface.h"
13
14static SkShader* make_heatGradient(const SkPoint pts[2]) {
15 const SkColor colors[] = {
16 SK_ColorBLACK, SK_ColorBLUE, SK_ColorCYAN, SK_ColorGREEN,
17 SK_ColorYELLOW, SK_ColorRED, SK_ColorWHITE
18 };
19 const SkColor bw[] = { SK_ColorBLACK, SK_ColorWHITE };
20
21 return SkGradientShader::CreateLinear(pts, bw, NULL,
22 SK_ARRAY_COUNT(bw),
23 SkShader::kClamp_TileMode);
24}
25
26static bool setFont(SkPaint* paint, const char name[]) {
27 SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
28 if (tf) {
29 paint->setTypeface(tf)->unref();
30 return true;
31 }
reed@google.comce151d02012-03-08 16:10:57 +000032 return false;
reed@google.comed3ee642012-02-14 16:12:49 +000033}
34
35#ifdef SK_BUILD_FOR_MAC
36#import <ApplicationServices/ApplicationServices.h>
37#define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
38
39static CGContextRef makeCG(const SkBitmap& bm) {
40 if (SkBitmap::kARGB_8888_Config != bm.config() ||
41 NULL == bm.getPixels()) {
42 return NULL;
43 }
44 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
45 CGContextRef cg = CGBitmapContextCreate(bm.getPixels(), bm.width(), bm.height(),
46 8, bm.rowBytes(), space, BITMAP_INFO_RGB);
47 CFRelease(space);
48
49 CGContextSetAllowsFontSubpixelQuantization(cg, false);
50 CGContextSetShouldSubpixelQuantizeFonts(cg, false);
51
52 return cg;
53}
54
55extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face);
56
57static CGFontRef typefaceToCGFont(const SkTypeface* face) {
58 if (NULL == face) {
59 return 0;
60 }
61
62 CTFontRef ct = SkTypeface_GetCTFontRef(face);
63 return CTFontCopyGraphicsFont(ct, NULL);
64}
65
66static void cgSetPaintForText(CGContextRef cg, const SkPaint& paint) {
67 SkColor c = paint.getColor();
68 CGFloat rgba[] = {
69 SkColorGetB(c) / 255.0,
70 SkColorGetG(c) / 255.0,
71 SkColorGetR(c) / 255.0,
72 SkColorGetA(c) / 255.0,
73 };
74 CGContextSetRGBFillColor(cg, rgba[0], rgba[1], rgba[2], rgba[3]);
75
76 CGContextSetTextDrawingMode(cg, kCGTextFill);
77 CGContextSetFont(cg, typefaceToCGFont(paint.getTypeface()));
78 CGContextSetFontSize(cg, SkScalarToFloat(paint.getTextSize()));
79
80 CGContextSetAllowsFontSubpixelPositioning(cg, paint.isSubpixelText());
81 CGContextSetShouldSubpixelPositionFonts(cg, paint.isSubpixelText());
82
83 CGContextSetShouldAntialias(cg, paint.isAntiAlias());
84 CGContextSetShouldSmoothFonts(cg, paint.isLCDRenderText());
85}
86
87static void cgDrawText(CGContextRef cg, const void* text, size_t len,
88 float x, float y, const SkPaint& paint) {
89 if (cg) {
90 cgSetPaintForText(cg, paint);
91
92 uint16_t glyphs[200];
93 int count = paint.textToGlyphs(text, len, glyphs);
94
95 CGContextShowGlyphsAtPoint(cg, x, y, glyphs, count);
96 }
97}
98#endif
99
100namespace skiagm {
101
102/**
103 Test a set of clipping problems discovered while writing blitAntiRect,
104 and test all the code paths through the clipping blitters.
105 Each region should show as a blue center surrounded by a 2px green
106 border, with no red.
107*/
108
109#define HEIGHT 480
110
111class GammaTextGM : public GM {
112public:
113 GammaTextGM() {
114
115 }
116
117protected:
118 virtual SkString onShortName() {
119 return SkString("gammatext");
120 }
121
122 virtual SkISize onISize() {
123 return make_isize(1024, HEIGHT);
124 }
125
126 static void drawGrad(SkCanvas* canvas) {
vandebo@chromium.orgc39c8672012-04-17 21:46:18 +0000127 SkPoint pts[] = { { 0, 0 }, { 0, SkIntToScalar(HEIGHT) } };
reed@google.comed3ee642012-02-14 16:12:49 +0000128#if 0
129 const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
130 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
131#else
132 SkShader* s = make_heatGradient(pts);
133#endif
134
135 canvas->clear(SK_ColorRED);
136 SkPaint paint;
137 paint.setShader(s)->unref();
vandebo@chromium.orgc39c8672012-04-17 21:46:18 +0000138 SkRect r = { 0, 0, SkIntToScalar(1024), SkIntToScalar(HEIGHT) };
reed@google.comed3ee642012-02-14 16:12:49 +0000139 canvas->drawRect(r, paint);
140 }
141
142 virtual void onDraw(SkCanvas* canvas) {
143#ifdef SK_BUILD_FOR_MAC
144 CGContextRef cg = makeCG(canvas->getDevice()->accessBitmap(false));
145#endif
146
147 drawGrad(canvas);
148
149 const SkColor fg[] = {
150 0xFFFFFFFF,
151 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
152 0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
153 0xFF000000,
154 };
155
156 const char* text = "Hamburgefons";
157 size_t len = strlen(text);
158
159 SkPaint paint;
160 setFont(&paint, "Times");
161 paint.setTextSize(SkIntToScalar(16));
162 paint.setAntiAlias(true);
163 paint.setLCDRenderText(true);
164
vandebo@chromium.orgc39c8672012-04-17 21:46:18 +0000165 SkScalar x = SkIntToScalar(10);
reed@google.comed3ee642012-02-14 16:12:49 +0000166 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
167 paint.setColor(fg[i]);
168
vandebo@chromium.orgc39c8672012-04-17 21:46:18 +0000169 SkScalar y = SkIntToScalar(40);
170 SkScalar stopy = SkIntToScalar(HEIGHT);
reed@google.comed3ee642012-02-14 16:12:49 +0000171 while (y < stopy) {
172#if 1
173 canvas->drawText(text, len, x, y, paint);
174#else
vandebo@chromium.org95ead842012-04-18 17:11:19 +0000175 cgDrawText(cg, text, len, SkScalarToFloat(x),
176 static_cast<float>(HEIGHT) - SkScalarToFloat(y),
177 paint);
reed@google.comed3ee642012-02-14 16:12:49 +0000178#endif
179 y += paint.getTextSize() * 2;
180 }
181 x += SkIntToScalar(1024) / SK_ARRAY_COUNT(fg);
182 }
183 }
184
185private:
186 typedef GM INHERITED;
187};
188
189//////////////////////////////////////////////////////////////////////////////
190
191static GM* MyFactory(void*) { return new GammaTextGM; }
192static GMRegistry reg(MyFactory);
193
194}