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
25static 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 */
33static 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
55static 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
73static const int gFaceCount = SK_ARRAY_COUNT(gFaces);
74
75class TypefaceView : public SampleView {
76    SkTypeface* fFaces[gFaceCount];
77
78public:
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
89    virtual ~TypefaceView() {
90        for (int i = 0; i < gFaceCount; i++) {
91            SkSafeUnref(fFaces[i]);
92        }
93
94        SkTypefaceCache::Dump();
95    }
96
97protected:
98    // overrides from SkEventSink
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
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
127private:
128    typedef SampleView INHERITED;
129};
130
131//////////////////////////////////////////////////////////////////////////////
132
133static SkView* MyFactory() { return new TypefaceView; }
134static SkViewRegister reg(MyFactory);
135
136