1
2/*
3 * Copyright 2006 The Android Open Source Project
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
9
10#include "SkGraphics.h"
11
12#include "Sk64.h"
13#include "SkBlitter.h"
14#include "SkCanvas.h"
15#include "SkFloat.h"
16#include "SkGeometry.h"
17#include "SkMath.h"
18#include "SkMatrix.h"
19#include "SkPath.h"
20#include "SkPathEffect.h"
21#include "SkPixelRef.h"
22#include "SkRandom.h"
23#include "SkRefCnt.h"
24#include "SkScalerContext.h"
25#include "SkShader.h"
26#include "SkStream.h"
27#include "SkTSearch.h"
28#include "SkTime.h"
29#include "SkUtils.h"
30#include "SkXfermode.h"
31
32void SkGraphics::GetVersion(int32_t* major, int32_t* minor, int32_t* patch) {
33    if (major) {
34        *major = SKIA_VERSION_MAJOR;
35    }
36    if (minor) {
37        *minor = SKIA_VERSION_MINOR;
38    }
39    if (patch) {
40        *patch = SKIA_VERSION_PATCH;
41    }
42}
43
44#define typesizeline(type)  { #type , sizeof(type) }
45
46#ifdef BUILD_EMBOSS_TABLE
47    extern void SkEmbossMask_BuildTable();
48#endif
49
50#ifdef BUILD_RADIALGRADIENT_TABLE
51    extern void SkRadialGradient_BuildTable();
52#endif
53
54void SkGraphics::Init() {
55#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
56    SkFlattenable::InitializeFlattenables();
57    SkPixelRef::InitializeFlattenables();
58#endif
59#ifdef BUILD_EMBOSS_TABLE
60    SkEmbossMask_BuildTable();
61#endif
62#ifdef BUILD_RADIALGRADIENT_TABLE
63    SkRadialGradient_BuildTable();
64#endif
65
66#ifdef SK_DEBUGx
67    int i;
68
69    static const struct {
70        const char* fTypeName;
71        size_t      fSizeOf;
72    } gTypeSize[] = {
73        typesizeline(char),
74        typesizeline(short),
75        typesizeline(int),
76        typesizeline(long),
77        typesizeline(size_t),
78        typesizeline(void*),
79
80        typesizeline(S8CPU),
81        typesizeline(U8CPU),
82        typesizeline(S16CPU),
83        typesizeline(U16CPU),
84
85        typesizeline(SkPoint),
86        typesizeline(SkRect),
87        typesizeline(SkMatrix),
88        typesizeline(SkPath),
89        typesizeline(SkGlyph),
90        typesizeline(SkRefCnt),
91
92        typesizeline(SkPaint),
93        typesizeline(SkCanvas),
94        typesizeline(SkBlitter),
95        typesizeline(SkShader),
96        typesizeline(SkXfermode),
97        typesizeline(SkPathEffect)
98    };
99
100#ifdef SK_CPU_BENDIAN
101    SkDebugf("SkGraphics: big-endian\n");
102#else
103    SkDebugf("SkGraphics: little-endian\n");
104#endif
105
106    {
107        char    test = 0xFF;
108        int     itest = test;   // promote to int, see if it sign-extended
109        if (itest < 0)
110            SkDebugf("SkGraphics: char is signed\n");
111        else
112            SkDebugf("SkGraphics: char is unsigned\n");
113    }
114    for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) {
115        SkDebugf("SkGraphics: sizeof(%s) = %d\n",
116                 gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf);
117    }
118    SkDebugf("SkGraphics: font cache limit %dK\n",
119             GetFontCacheLimit() >> 10);
120
121#endif
122}
123
124///////////////////////////////////////////////////////////////////////////////
125
126#include "SkGlyphCache.h"
127#include "SkTypefaceCache.h"
128
129void SkGraphics::Term() {
130    PurgeFontCache();
131}
132
133#ifndef SK_DEFAULT_FONT_CACHE_LIMIT
134    #define SK_DEFAULT_FONT_CACHE_LIMIT (2 * 1024 * 1024)
135#endif
136
137#define SK_MIN_FONT_CACHE_LIMIT    (256 * 1024)
138
139static size_t gFontCacheLimit = SK_DEFAULT_FONT_CACHE_LIMIT;
140
141size_t SkGraphics::GetFontCacheLimit() {
142    return gFontCacheLimit;
143}
144
145size_t SkGraphics::SetFontCacheLimit(size_t bytes) {
146    size_t prev = gFontCacheLimit;
147
148    if (bytes < SK_MIN_FONT_CACHE_LIMIT) {
149        bytes = SK_MIN_FONT_CACHE_LIMIT;
150    }
151    gFontCacheLimit = bytes;
152
153    // trigger a purge if the new size is smaller that our currently used amount
154    if (bytes < SkGlyphCache::GetCacheUsed()) {
155        SkGlyphCache::SetCacheUsed(bytes);
156    }
157    return prev;
158}
159
160void SkGraphics::PurgeFontCache() {
161    SkGlyphCache::SetCacheUsed(0);
162    SkTypefaceCache::PurgeAll();
163}
164
165///////////////////////////////////////////////////////////////////////////////
166
167static const char kFontCacheLimitStr[] = "font-cache-limit";
168static const size_t kFontCacheLimitLen = sizeof(kFontCacheLimitStr) - 1;
169
170static const struct {
171    const char* fStr;
172    size_t fLen;
173    size_t (*fFunc)(size_t);
174} gFlags[] = {
175    {kFontCacheLimitStr, kFontCacheLimitLen, SkGraphics::SetFontCacheLimit}
176};
177
178/* flags are of the form param; or param=value; */
179void SkGraphics::SetFlags(const char* flags) {
180    if (!flags) {
181        return;
182    }
183    const char* nextSemi;
184    do {
185        size_t len = strlen(flags);
186        const char* paramEnd = flags + len;
187        const char* nextEqual = strchr(flags, '=');
188        if (nextEqual && paramEnd > nextEqual) {
189            paramEnd = nextEqual;
190        }
191        nextSemi = strchr(flags, ';');
192        if (nextSemi && paramEnd > nextSemi) {
193            paramEnd = nextSemi;
194        }
195        size_t paramLen = paramEnd - flags;
196        for (int i = 0; i < (int)SK_ARRAY_COUNT(gFlags); ++i) {
197            if (paramLen != gFlags[i].fLen) {
198                continue;
199            }
200            if (strncmp(flags, gFlags[i].fStr, paramLen) == 0) {
201                size_t val = 0;
202                if (nextEqual) {
203                    val = (size_t) atoi(nextEqual + 1);
204                }
205                (gFlags[i].fFunc)(val);
206                break;
207            }
208        }
209        flags = nextSemi + 1;
210    } while (nextSemi);
211}
212