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