1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitter.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFloat.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGeometry.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMath.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathEffect.h"
209d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com#include "SkPixelRef.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRefCnt.h"
227af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkRTConf.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalerContext.h"
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTSearch.h"
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h"
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3177407ca019ca1bb98dd65f940be825d38719e983reed@google.comvoid SkGraphics::GetVersion(int32_t* major, int32_t* minor, int32_t* patch) {
3277407ca019ca1bb98dd65f940be825d38719e983reed@google.com    if (major) {
3377407ca019ca1bb98dd65f940be825d38719e983reed@google.com        *major = SKIA_VERSION_MAJOR;
3477407ca019ca1bb98dd65f940be825d38719e983reed@google.com    }
3577407ca019ca1bb98dd65f940be825d38719e983reed@google.com    if (minor) {
3677407ca019ca1bb98dd65f940be825d38719e983reed@google.com        *minor = SKIA_VERSION_MINOR;
3777407ca019ca1bb98dd65f940be825d38719e983reed@google.com    }
3877407ca019ca1bb98dd65f940be825d38719e983reed@google.com    if (patch) {
3977407ca019ca1bb98dd65f940be825d38719e983reed@google.com        *patch = SKIA_VERSION_PATCH;
4077407ca019ca1bb98dd65f940be825d38719e983reed@google.com    }
4177407ca019ca1bb98dd65f940be825d38719e983reed@google.com}
4277407ca019ca1bb98dd65f940be825d38719e983reed@google.com
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define typesizeline(type)  { #type , sizeof(type) }
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef BUILD_EMBOSS_TABLE
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    extern void SkEmbossMask_BuildTable();
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef BUILD_RADIALGRADIENT_TABLE
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    extern void SkRadialGradient_BuildTable();
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comvoid SkGraphics::Init() {
547af56bee17764a0c118c8856a035bb3d27766969humper@google.com#ifdef SK_DEVELOPER
557af56bee17764a0c118c8856a035bb3d27766969humper@google.com    skRTConfRegistry().possiblyDumpFile();
567af56bee17764a0c118c8856a035bb3d27766969humper@google.com    skRTConfRegistry().validate();
572d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    if (skRTConfRegistry().hasNonDefault()) {
582d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com        SkDebugf("Non-default runtime configuration options:\n");
592d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com        skRTConfRegistry().printNonDefault();
602d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    }
617af56bee17764a0c118c8856a035bb3d27766969humper@google.com#endif
627fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef BUILD_EMBOSS_TABLE
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEmbossMask_BuildTable();
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef BUILD_RADIALGRADIENT_TABLE
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRadialGradient_BuildTable();
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
705e5adfd12cc2cb194db971708cd7f34ff47e10b4reed@android.com#ifdef SK_DEBUGx
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int i;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static const struct {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const char* fTypeName;
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t      fSizeOf;
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } gTypeSize[] = {
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(char),
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(short),
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(int),
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(long),
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(size_t),
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(void*),
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(S8CPU),
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(U8CPU),
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(S16CPU),
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(U16CPU),
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkPoint),
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkRect),
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkMatrix),
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkPath),
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkGlyph),
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkRefCnt),
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkPaint),
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkCanvas),
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkBlitter),
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkShader),
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkXfermode),
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        typesizeline(SkPathEffect)
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("SkGraphics: big-endian\n");
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("SkGraphics: little-endian\n");
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        char    test = 0xFF;
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int     itest = test;   // promote to int, see if it sign-extended
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (itest < 0)
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkDebugf("SkGraphics: char is signed\n");
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkDebugf("SkGraphics: char is unsigned\n");
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1185e5adfd12cc2cb194db971708cd7f34ff47e10b4reed@android.com    for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) {
1195e5adfd12cc2cb194db971708cd7f34ff47e10b4reed@android.com        SkDebugf("SkGraphics: sizeof(%s) = %d\n",
1205e5adfd12cc2cb194db971708cd7f34ff47e10b4reed@android.com                 gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
122073c90769e4cc7bf14323c1cab59339463604ecdreed@google.com    SkDebugf("SkGraphics: font cache limit %dK\n",
123073c90769e4cc7bf14323c1cab59339463604ecdreed@google.com             GetFontCacheLimit() >> 10);
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1267af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkGraphics::Term() {
130f86ab8472e8bb4017f32f8e6f36a0001ceb39b46caryclark@google.com    PurgeFontCache();
131b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com    SkPaint::Term();
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13454c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com///////////////////////////////////////////////////////////////////////////////
13554c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com
13654c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.comstatic const char kFontCacheLimitStr[] = "font-cache-limit";
137fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comstatic const size_t kFontCacheLimitLen = sizeof(kFontCacheLimitStr) - 1;
13854c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com
13954c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.comstatic const struct {
14054c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    const char* fStr;
14154c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    size_t fLen;
14254c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    size_t (*fFunc)(size_t);
14354c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com} gFlags[] = {
144098370137fc9c13acf1631bcc16d9ffbb0abf45freed@google.com    { kFontCacheLimitStr, kFontCacheLimitLen, SkGraphics::SetFontCacheLimit }
14554c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com};
14654c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com
14754c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com/* flags are of the form param; or param=value; */
14854c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.comvoid SkGraphics::SetFlags(const char* flags) {
14954c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    if (!flags) {
15054c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        return;
15154c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    }
15254c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    const char* nextSemi;
15354c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    do {
15454c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        size_t len = strlen(flags);
15554c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        const char* paramEnd = flags + len;
15654c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        const char* nextEqual = strchr(flags, '=');
15754c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        if (nextEqual && paramEnd > nextEqual) {
15854c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            paramEnd = nextEqual;
15954c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        }
16054c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        nextSemi = strchr(flags, ';');
16154c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        if (nextSemi && paramEnd > nextSemi) {
16254c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            paramEnd = nextSemi;
16354c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        }
16454c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        size_t paramLen = paramEnd - flags;
16554c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        for (int i = 0; i < (int)SK_ARRAY_COUNT(gFlags); ++i) {
16654c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            if (paramLen != gFlags[i].fLen) {
16754c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                continue;
16854c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            }
16954c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            if (strncmp(flags, gFlags[i].fStr, paramLen) == 0) {
17054c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                size_t val = 0;
17154c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                if (nextEqual) {
17254c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                    val = (size_t) atoi(nextEqual + 1);
17354c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                }
17454c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                (gFlags[i].fFunc)(val);
17554c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com                break;
17654c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com            }
17754c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        }
17854c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com        flags = nextSemi + 1;
17954c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com    } while (nextSemi);
18054c782c968fa7bb9d54db4d010ebac23168c0ba6caryclark@google.com}
181