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 "SkTypeface.h"
12 #include "SkPath.h"
13 #include "SkRegion.h"
14 #include "SkShader.h"
15 #include "SkUtils.h"
16 #include "Sk1DPathEffect.h"
17 #include "SkCornerPathEffect.h"
18 #include "SkPathMeasure.h"
19 #include "SkRandom.h"
20 #include "SkColorPriv.h"
21 #include "SkColorFilter.h"
22 #include "SkDither.h"
23 #include "SkTypefaceCache.h"
24
dither_4444(int x)25 static int dither_4444(int x) {
26 return ((x << 1) - ((x >> 4 << 4) | (x >> 4))) >> 4;
27 }
28
29 /** Ensure that the max of the original and dithered value (for alpha) is always
30 >= any other dithered value. We apply this "max" in colorpriv.h when we
31 predither down to 4444, to be sure that we stay in legal premultiplied form
32 */
test_4444_dither()33 static void test_4444_dither() {
34 int buckets[16];
35 sk_bzero(buckets, sizeof(buckets));
36
37 for (int a = 0; a <= 0xFF; a++) {
38 int da = dither_4444(a);
39 int maxa = SkMax32(a >> 4, da);
40 // SkDebugf("--- %02X %X\n", a, da);
41 buckets[da] += 1;
42 for (int c = 0; c <= a; c++) {
43 int dc = dither_4444(c);
44 if (maxa < dc) {
45 SkDebugf("------------ error a=%d da=%d c=%d dc=%d\n", a, da,
46 c, dc);
47 }
48 }
49 }
50 for (int i = 0; i < 16; i++) {
51 // SkDebugf("[%d] = %d\n", i, buckets[i]);
52 }
53 }
54
55 static const struct {
56 const char* fName;
57 SkTypeface::Style fStyle;
58 } gFaces[] = {
59 { "sans-serif", SkTypeface::kNormal },
60 { "sans-serif", SkTypeface::kBold },
61 { "sans-serif", SkTypeface::kItalic },
62 { "sans-serif", SkTypeface::kBoldItalic },
63 { "serif", SkTypeface::kNormal },
64 { "serif", SkTypeface::kBold },
65 { "serif", SkTypeface::kItalic },
66 { "serif", SkTypeface::kBoldItalic },
67 { "monospace", SkTypeface::kNormal },
68 { "monospace", SkTypeface::kBold },
69 { "monospace", SkTypeface::kItalic },
70 { "monospace", SkTypeface::kBoldItalic },
71 };
72
73 static const int gFaceCount = SK_ARRAY_COUNT(gFaces);
74
75 class TypefaceView : public SampleView {
76 SkTypeface* fFaces[gFaceCount];
77
78 public:
TypefaceView()79 TypefaceView() {
80 test_4444_dither();
81 for (int i = 0; i < gFaceCount; i++) {
82 fFaces[i] = SkTypeface::CreateFromName(gFaces[i].fName,
83 gFaces[i].fStyle);
84 }
85
86 this->setBGColor(0xFFDDDDDD);
87 }
88
~TypefaceView()89 virtual ~TypefaceView() {
90 for (int i = 0; i < gFaceCount; i++) {
91 SkSafeUnref(fFaces[i]);
92 }
93
94 SkTypefaceCache::Dump();
95 }
96
97 protected:
98 // overrides from SkEventSink
onQuery(SkEvent * evt)99 virtual bool onQuery(SkEvent* evt) {
100 if (SampleCode::TitleQ(*evt)) {
101 SampleCode::TitleR(evt, "Typefaces");
102 return true;
103 }
104 return this->INHERITED::onQuery(evt);
105 }
106
onDrawContent(SkCanvas * canvas)107 virtual void onDrawContent(SkCanvas* canvas) {
108 SkPaint paint;
109 paint.setAntiAlias(true);
110 paint.setTextSize(SkIntToScalar(30));
111
112 const char* text = "Hamburgefons";
113 const size_t textLen = strlen(text);
114
115 SkScalar x = SkIntToScalar(10);
116 SkScalar dy = paint.getFontMetrics(NULL);
117 SkScalar y = dy;
118
119 paint.setLinearText(true);
120 for (int i = 0; i < gFaceCount; i++) {
121 paint.setTypeface(fFaces[i]);
122 canvas->drawText(text, textLen, x, y, paint);
123 y += dy;
124 }
125 }
126
127 private:
128 typedef SampleView INHERITED;
129 };
130
131 //////////////////////////////////////////////////////////////////////////////
132
MyFactory()133 static SkView* MyFactory() { return new TypefaceView; }
134 static SkViewRegister reg(MyFactory);
135
136