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