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
9
10
11#ifndef SkTypefaceCache_DEFINED
12#define SkTypefaceCache_DEFINED
13
14#include "SkTypeface.h"
15#include "SkTDArray.h"
16
17/*  TODO
18 *  Provide std way to cache name+requestedStyle aliases to the same typeface.
19 *
20 *  The current mechanism ends up create a diff typeface for each one, even if
21 *  they map to the same internal obj (e.g. CTFontRef on the mac)
22 */
23
24class SkTypefaceCache {
25public:
26    /**
27     * Callback for FindByProc. Returns true if the given typeface is a match
28     * for the given context. The passed typeface is owned by the cache and is
29     * not additionally ref()ed.
30     */
31    typedef bool (*FindProc)(SkTypeface*, SkTypeface::Style, void* context);
32
33    /**
34     *  Helper: returns a unique fontID to pass to the constructor of
35     *  your subclass of SkTypeface
36     */
37    static SkFontID NewFontID();
38
39    /**
40     *  Add a typeface to the cache. This ref()s the typeface, so that the
41     *  cache is also an owner. Later, if we need to purge the cache, typefaces
42     *  whose refcnt is 1 (meaning only the cache is an owner) will be
43     *  unref()ed.
44     */
45    static void Add(SkTypeface*, SkTypeface::Style requested);
46
47    /**
48     *  Search the cache for a typeface with the specified fontID (uniqueID).
49     *  If one is found, return it (its reference count is unmodified). If none
50     *  is found, return NULL. The reference count is unmodified as it is
51     *  assumed that the stack will contain a ref to the typeface.
52     */
53    static SkTypeface* FindByID(SkFontID fontID);
54
55    /**
56     *  Iterate through the cache, calling proc(typeface, ctx) with each
57     *  typeface. If proc returns true, then we return that typeface (this
58     *  ref()s the typeface). If it never returns true, we return NULL.
59     */
60    static SkTypeface* FindByProcAndRef(FindProc proc, void* ctx);
61
62    /**
63     *  This will unref all of the typefaces in the cache for which the cache
64     *  is the only owner. Normally this is handled automatically as needed.
65     *  This function is exposed for clients that explicitly want to purge the
66     *  cache (e.g. to look for leaks).
67     */
68    static void PurgeAll();
69
70    /**
71     *  Debugging only: dumps the status of the typefaces in the cache
72     */
73    static void Dump();
74
75private:
76    static SkTypefaceCache& Get();
77
78    void add(SkTypeface*, SkTypeface::Style requested);
79    SkTypeface* findByID(SkFontID findID) const;
80    SkTypeface* findByProc(FindProc proc, void* ctx) const;
81    void purge(int count);
82    void purgeAll();
83
84    struct Rec {
85        SkTypeface*         fFace;
86        SkTypeface::Style   fRequestedStyle;
87    };
88    SkTDArray<Rec> fArray;
89};
90
91#endif
92