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