11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SampleCode.h" 90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkView.h" 100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h" 110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkTypeface.h" 120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPath.h" 130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRegion.h" 140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkShader.h" 150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkUtils.h" 160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "Sk1DPathEffect.h" 170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCornerPathEffect.h" 180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPathMeasure.h" 190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRandom.h" 200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkColorPriv.h" 210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkColorFilter.h" 220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkDither.h" 230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkTypefaceCache.h" 240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic int dither_4444(int x) { 260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return ((x << 1) - ((x >> 4 << 4) | (x >> 4))) >> 4; 270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/** Ensure that the max of the original and dithered value (for alpha) is always 300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger >= any other dithered value. We apply this "max" in colorpriv.h when we 310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger predither down to 4444, to be sure that we stay in legal premultiplied form 320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger */ 330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test_4444_dither() { 340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int buckets[16]; 350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger sk_bzero(buckets, sizeof(buckets)); 360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int a = 0; a <= 0xFF; a++) { 380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int da = dither_4444(a); 390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int maxa = SkMax32(a >> 4, da); 400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // SkDebugf("--- %02X %X\n", a, da); 410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger buckets[da] += 1; 420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int c = 0; c <= a; c++) { 430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int dc = dither_4444(c); 440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (maxa < dc) { 450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkDebugf("------------ error a=%d da=%d c=%d dc=%d\n", a, da, 460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger c, dc); 470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < 16; i++) { 510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // SkDebugf("[%d] = %d\n", i, buckets[i]); 520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic const struct { 560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const char* fName; 570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkTypeface::Style fStyle; 580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} gFaces[] = { 590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "sans-serif", SkTypeface::kNormal }, 600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "sans-serif", SkTypeface::kBold }, 610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "sans-serif", SkTypeface::kItalic }, 620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "sans-serif", SkTypeface::kBoldItalic }, 630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "serif", SkTypeface::kNormal }, 640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "serif", SkTypeface::kBold }, 650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "serif", SkTypeface::kItalic }, 660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "serif", SkTypeface::kBoldItalic }, 670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "monospace", SkTypeface::kNormal }, 680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "monospace", SkTypeface::kBold }, 690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "monospace", SkTypeface::kItalic }, 700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { "monospace", SkTypeface::kBoldItalic }, 710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic const int gFaceCount = SK_ARRAY_COUNT(gFaces); 740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass TypefaceView : public SampleView { 760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkTypeface* fFaces[gFaceCount]; 770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic: 790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger TypefaceView() { 800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger test_4444_dither(); 810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < gFaceCount; i++) { 820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFaces[i] = SkTypeface::CreateFromName(gFaces[i].fName, 830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger gFaces[i].fStyle); 840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setBGColor(0xFFDDDDDD); 870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual ~TypefaceView() { 900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < gFaceCount; i++) { 910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkSafeUnref(fFaces[i]); 920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkTypefaceCache::Dump(); 950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected: 980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // overrides from SkEventSink 990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual bool onQuery(SkEvent* evt) { 1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SampleCode::TitleQ(*evt)) { 1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SampleCode::TitleR(evt, "Typefaces"); 1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onQuery(evt); 1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual void onDrawContent(SkCanvas* canvas) { 1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPaint paint; 1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAntiAlias(true); 1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setTextSize(SkIntToScalar(30)); 1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const char* text = "Hamburgefons"; 1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const size_t textLen = strlen(text); 1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar x = SkIntToScalar(10); 1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar dy = paint.getFontMetrics(NULL); 1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar y = dy; 1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setLinearText(true); 1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < gFaceCount; i++) { 1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setTypeface(fFaces[i]); 1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawText(text, textLen, x, y, paint); 1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger y += dy; 1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate: 1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger typedef SampleView INHERITED; 1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger////////////////////////////////////////////////////////////////////////////// 1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkView* MyFactory() { return new TypefaceView; } 1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkViewRegister reg(MyFactory); 1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 136