adding cache manager documentation (draft)
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
diff --git a/docs/cache/cache.txt b/docs/cache/cache.txt
new file mode 100644
index 0000000..4c51948
--- /dev/null
+++ b/docs/cache/cache.txt
@@ -0,0 +1,267 @@
+ The FreeType 2 cache sub-system explained
+ (c) 2000 David Turner
+
+ -----------------------------------------------
+
+Introduction :
+--------------
+
+ this document describes the caching sub-system that comes
+ with the FreeType library, version 2.0. Note that unlike
+ the rest of the library, this code is still in beta stage
+ and might still suffer slight changes in the future.
+
+ Its basic design shouldn't evolve though and is explained
+ in this paper.
+
+
+I. Requirements and Design Goals:
+---------------------------------
+
+ The FT2 cache sub-system was designed to implement caching
+ of glyph images. However, it is extremely flexible and can
+ be easily extended to cache other kind of data like metrics,
+ character maps, coverage tables, etc..
+
+
+II. Base Concepts:
+------------------
+
+ 1. The cache manager object:
+
+ at the heart of the caching sub-system is a single object
+ called the "cache manager". It is used to deal with FT_Face
+ and FT_Size objects, as well as to manager a LRU list of
+ abstract "cache nodes".
+
+ a. caching FT_Face and FT_Size objects:
+
+ each FT_Face object created by FreeType 2 can take from
+ a few hundred bytes to several tens of kilobytes, depending
+ on the original font's file format as well as its content.
+
+ there is no easy way to compute the size of a given FT_Face
+ object, so it's always a good idea to assume that it is
+ large and to want to limit the number of live face objects
+ as much as possible.
+
+ similarly, each FT_Face can have one or more FT_Size childs,
+ whose byte size depends heavily on the font format.
+
+ the first purpose of the cache manager is to provide a
+ small cache for FT_Face and FT_Size objects. Basically,
+ an application can use it as follows:
+
+ - each font face is described to the cache manager
+ through a typeless pointer, called a FTC_FaceID.
+
+ the cache manager itself doesn't interpret or use
+ the value of FTC_FaceIDs directly. Rather, it passes
+ them to a user-provided function called a
+ "face requester". see the defintion of the
+ FTC_Face_Requester type in <freetype/ftcache.h>
+ for details..
+
+ the face requester is in charge of translating a given
+ face into into a real new FT_Face object that is
+ returned to the cache manager. The latter will keep
+ the face object alive as long as it needs to.
+
+ the face requester is unique and must be passed
+ to the function named FTC_Manager_New used to
+ create/initialise a new cache manager.
+
+
+ - to lookup a given FT_Face, call the function
+ FTC_Manager_Lookup_Face as in the following code:
+
+ FTC_Manager_Lookup_Face( manager,
+ face_id,
+ &face );
+
+ if the corresponding FT_Face object is kept in
+ the cache manager's list, it will be returned
+ directly. Otherwise, this function will call
+ the user-provided face requester to create
+ a new FT_Face object, add it to the manager's
+ list to finally return it.
+
+ FT_Face objects are always destroyed by the cache
+ manager. An application that uses the cache
+ sub-system should never call FT_Done_Face !!
+
+ - to lookup a given FT_Size and FT_Face, call the
+ function FTC_Manager_Lookup_Size, as in:
+
+ FTC_Manager_Lookup_Size( manager,
+ ftc_font,
+ &face,
+ &size );
+
+ where "ftc_font" is a pointer to a FTC_Font descriptor
+ (a structure containing a FTC_FaceIDs and character
+ dimensions corresponding to the desired FT_Size).
+
+ note that the function returns both a FT_Face and
+ a FT_Size object. You don't need to call
+ FTC_Manager_Lookup_Face before it !!
+
+ also note that returned FT_Size objects are always
+ destroyed by the cache manager. A client application
+ that uses it should never call FT_Done_Size !!
+
+
+ the big advantage of using FTC_FaceIDs is that is
+ makes the caching sub-system completely independent
+ of the way font files are installed / listed / managed
+ in your application. In most implementations, a FTC_FaceID
+ is really a pointer to an application-specific structure
+ that describe the source font file + face index.
+
+
+ b - manage a MRU list of abstract "cache nodes":
+
+ the second role of the cache manager is to hold and manager
+ a list of abstract "cache nodes". The list is always sorted
+ in most-recently-used order. The manager always ensure that
+ the total size of nodes in memory doesn't over-reach a
+ certain threshold, by eliminating "old" nodes when
+ necessary.
+
+ the cache manager doesn't know much about the cache nodes:
+
+ - it knows how to move them in its list
+ - it knows how to destroy them when they're too old
+ - it knows how to "size" them (i.e. compute their byte
+ size in memory)
+
+
+ 2. Cache objects:
+
+ the cache manager doesn't create new cache nodes however, this
+ is the charge of what are called "cache objects".
+
+ Basically, each cache object is in charge of managing cache
+ nodes of a certain type. Its role is to:
+
+ - provide a simple description of its cache nodes to the
+ manager (i.e. through a FTC_CacheNode_Class structure)
+
+ - provide a high-level API that can be called by client
+ applications to lookup cache nodes of the corresponding
+ type.
+
+ this function usually creates new nodes when they're not
+ available yet.
+
+ - also, and even though this is completely transparent to
+ the applications and the cache manager, each cache object
+ manages "node sets", where each set contains cache nodes
+ usually correspond to the same font face + font size.
+
+
+ For example, the cache sub-system currently comes with two
+ distinct cache classes:
+
+ - a FTC_Image_Cache, which is used to cache FT_Glyph images
+ (with one FT_Glyph per cache node).
+
+
+ - a FTC_SBit_Cache, which is used to cache small glyph bitmaps
+ ("sbit" means "embedded bitmaps" in digital typography).
+
+
+ the small bitmaps glyph is useful because storing one glyph
+ image per cache node isn't memory efficient when the data
+ associated to each node is very small. Indeed, each cache
+ node has a minimal size of 20 bytes, which is huge when
+ your data is an 8x8 monochrome bitmap :-)
+
+ Hence, a FTC_SBit_Cache is capable of storing several
+ contiguous sbits in a single cache node, resulting in much
+ higher cached glyphs / total cache size.
+
+ an application can lookup a FT_Glyph image with a FTC_Image_Cache
+ by calling:
+
+ error = FTC_Image_Cache_Lookup( image_cache,
+ ftc_font,
+ glyph_index,
+ &ft_glyph );
+
+ or a FTC_SBit (small bitmap descriptor) by calling:
+
+ error = FTC_SBit_Cache_Lookup( sbit_cache,
+ ftc_font,
+ glyph_index,
+ &ftc_sbit );
+
+III. Extending the cache sub-system:
+
+ It is possible to extend the current cache sub-system by
+ providing your own cache class and register it in the cache
+ manager. That might be useful to cache other kind of data
+ in the sub-system, like glyph metrics (without images),
+
+ To do it, you'll need to read the cache sub-system public
+ header files rather heavily :-) Fortunately, they're pretty
+ well commented and should guide you to your goal.
+
+ Note that the cache sub-system already provides two "abstract
+ cache" classes that can be re-used by your own implementation:
+
+
+ 1. The abstract "FTC_GlyphCache" class:
+
+ this code is used to implement an abstract "glyph cache",
+ i.e. one that simply maps one glyph data per cache node.
+
+ it is sub-classed by FTC_Image_Cache, whose implementation
+ only consists in simple code to store a FT_Glyph in each
+ cache node.
+
+ you could sub-class it in your application to store glyph
+ images in a different format, for example.
+
+ see the files <freetype/cache/ftcglyph.h> and
+ "src/cache/ftcglyph.h" for details.
+
+
+ 2. The abstract "FTC_ChunkCache" class:
+
+ this code is used to implement an abstract "glyph chunk cache".
+ it's very similar to a FTC_GlyphCache, except that it is capable
+ of storing several glyph-specific elements per cache node.
+
+ it is sub-classed by FTC_SBit_Cache, whose implementation
+ only consists in code to store a FTC_SBitRec record in each
+ node element.
+
+ you could sub-class it in your application to store small
+ glyph data, like metrics, glyph names, wathever.
+
+ see the files <freetype/cache/ftcchunk.h> and
+ "src/cache/ftcchunk.h" for details..
+
+
+ Note that the two abstract caches are rather complex because
+ they use "glyph sets". Each glyph set corresponds to a single
+ font face + font size combination. both caches are also
+ glyph-specific, though it is perfectly possible to use
+ broader selection criterion, here are a few examples:
+
+ - caching language coverage maps corresponding to
+ a given font face + language combination
+
+ - caching charmaps, layout tables, and other global
+ data..
+
+ - caching (font_face + font_size) specific "latin1"
+ ascender + descender
+
+
+ as you can see, a lot is possible with this design :-)
+
+
+
+