aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/graphics/sgl/SkGlyphCache.h
blob: 20a7aced1d14c9924652d16295491a29c714a772 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef SkGlyphCache_DEFINED
#define SkGlyphCache_DEFINED

#include "SkBitmap.h"
#include "SkChunkAlloc.h"
#include "SkDescriptor.h"
#include "SkScalerContext.h"
#include "SkTemplates.h"

class SkPaint;

class SkGlyphCache {
public:
	const SkGlyph& getMetrics(SkUnichar charCode)
	{
		int		 hash = charCode & kHashMask;
		SkGlyph* glyph = fHash[hash];

		if (glyph != nil && glyph->fCharCode == charCode)
			return *glyph;
		return this->lookupMetrics(charCode);
	}


	const void*		findImage(SkUnichar);
	const SkPath*	findPath(SkUnichar);
	void			getLineHeight(SkPoint* above, SkPoint* below);

	static SkGlyphCache* DetachCache(const SkPaint&, const SkMatrix* matrix);
	static SkGlyphCache* DetachCache(const SkDescriptor*);
	static void			 AttachCache(SkGlyphCache*);
	static bool			 FreeCache(size_t bytesNeeded);

private:
	SkGlyphCache(const SkDescriptor*);
	~SkGlyphCache();

	const SkGlyph& lookupMetrics(SkUnichar charCode);

	SkGlyphCache*		fNext;
	SkDescriptor*		fDesc;
	SkScalerContext*	fScalerContext;

	enum {
		kHashBits	= 6,
		kHashCount	= 1 << kHashBits,
		kHashMask	= kHashCount - 1
	};
	SkGlyph*			fHash[kHashCount];
	SkTDArray<SkGlyph*>	fGlyphArray;
	SkChunkAlloc		fGlyphAlloc;
	SkChunkAlloc		fImageAlloc;

	SkPoint	fAbove, fBelow;
};

class SkAutoGlyphCache {
public:
	SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {}
	SkAutoGlyphCache(const SkDescriptor* desc)
	{
		fCache = SkGlyphCache::DetachCache(desc);
	}
	SkAutoGlyphCache(const SkPaint& paint, const SkMatrix* matrix)
	{
		fCache = SkGlyphCache::DetachCache(paint, matrix);
	}
	~SkAutoGlyphCache()
	{
		if (fCache)
			SkGlyphCache::AttachCache(fCache);
	}

	SkGlyphCache*	getCache() const { return fCache; }

	void release()
	{
		if (fCache)
		{
			SkGlyphCache::AttachCache(fCache);
			fCache = nil;
		}
	}
private:
	SkGlyphCache*	fCache;
};

#endif