1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftcglyph.c                                                             */
4 /*                                                                         */
5 /*    FreeType Glyph Image (FT_Glyph) cache (body).                        */
6 /*                                                                         */
7 /*  Copyright 2000-2015 by                                                 */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_OBJECTS_H
21 #include FT_CACHE_H
22 #include "ftcglyph.h"
23 #include FT_ERRORS_H
24 
25 #include "ftccback.h"
26 #include "ftcerror.h"
27 
28 
29   /* create a new chunk node, setting its cache index and ref count */
30   FT_LOCAL_DEF( void )
FTC_GNode_Init(FTC_GNode gnode,FT_UInt gindex,FTC_Family family)31   FTC_GNode_Init( FTC_GNode   gnode,
32                   FT_UInt     gindex,
33                   FTC_Family  family )
34   {
35     gnode->family = family;
36     gnode->gindex = gindex;
37     family->num_nodes++;
38   }
39 
40 
41   FT_LOCAL_DEF( void )
FTC_GNode_UnselectFamily(FTC_GNode gnode,FTC_Cache cache)42   FTC_GNode_UnselectFamily( FTC_GNode  gnode,
43                             FTC_Cache  cache )
44   {
45     FTC_Family  family = gnode->family;
46 
47 
48     gnode->family = NULL;
49     if ( family && --family->num_nodes == 0 )
50       FTC_FAMILY_FREE( family, cache );
51   }
52 
53 
54   FT_LOCAL_DEF( void )
FTC_GNode_Done(FTC_GNode gnode,FTC_Cache cache)55   FTC_GNode_Done( FTC_GNode  gnode,
56                   FTC_Cache  cache )
57   {
58     /* finalize the node */
59     gnode->gindex = 0;
60 
61     FTC_GNode_UnselectFamily( gnode, cache );
62   }
63 
64 
65   FT_LOCAL_DEF( FT_Bool )
ftc_gnode_compare(FTC_Node ftcgnode,FT_Pointer ftcgquery,FTC_Cache cache,FT_Bool * list_changed)66   ftc_gnode_compare( FTC_Node    ftcgnode,
67                      FT_Pointer  ftcgquery,
68                      FTC_Cache   cache,
69                      FT_Bool*    list_changed )
70   {
71     FTC_GNode   gnode  = (FTC_GNode)ftcgnode;
72     FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;
73     FT_UNUSED( cache );
74 
75 
76     if ( list_changed )
77       *list_changed = FALSE;
78     return FT_BOOL( gnode->family == gquery->family &&
79                     gnode->gindex == gquery->gindex );
80   }
81 
82 
83 #ifdef FTC_INLINE
84 
85   FT_LOCAL_DEF( FT_Bool )
FTC_GNode_Compare(FTC_GNode gnode,FTC_GQuery gquery,FTC_Cache cache,FT_Bool * list_changed)86   FTC_GNode_Compare( FTC_GNode   gnode,
87                      FTC_GQuery  gquery,
88                      FTC_Cache   cache,
89                      FT_Bool*    list_changed )
90   {
91     return ftc_gnode_compare( FTC_NODE( gnode ), gquery,
92                               cache, list_changed );
93   }
94 
95 #endif
96 
97   /*************************************************************************/
98   /*************************************************************************/
99   /*****                                                               *****/
100   /*****                      CHUNK SETS                               *****/
101   /*****                                                               *****/
102   /*************************************************************************/
103   /*************************************************************************/
104 
105   FT_LOCAL_DEF( void )
FTC_Family_Init(FTC_Family family,FTC_Cache cache)106   FTC_Family_Init( FTC_Family  family,
107                    FTC_Cache   cache )
108   {
109     FTC_GCacheClass  clazz = FTC_CACHE__GCACHE_CLASS( cache );
110 
111 
112     family->clazz     = clazz->family_class;
113     family->num_nodes = 0;
114     family->cache     = cache;
115   }
116 
117 
118   FT_LOCAL_DEF( FT_Error )
ftc_gcache_init(FTC_Cache ftccache)119   ftc_gcache_init( FTC_Cache  ftccache )
120   {
121     FTC_GCache  cache = (FTC_GCache)ftccache;
122     FT_Error    error;
123 
124 
125     error = FTC_Cache_Init( FTC_CACHE( cache ) );
126     if ( !error )
127     {
128       FTC_GCacheClass   clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class;
129 
130       FTC_MruList_Init( &cache->families,
131                         clazz->family_class,
132                         0,  /* no maximum here! */
133                         cache,
134                         FTC_CACHE( cache )->memory );
135     }
136 
137     return error;
138   }
139 
140 
141 #if 0
142 
143   FT_LOCAL_DEF( FT_Error )
144   FTC_GCache_Init( FTC_GCache  cache )
145   {
146     return ftc_gcache_init( FTC_CACHE( cache ) );
147   }
148 
149 #endif /* 0 */
150 
151 
152   FT_LOCAL_DEF( void )
ftc_gcache_done(FTC_Cache ftccache)153   ftc_gcache_done( FTC_Cache  ftccache )
154   {
155     FTC_GCache  cache = (FTC_GCache)ftccache;
156 
157 
158     FTC_Cache_Done( (FTC_Cache)cache );
159     FTC_MruList_Done( &cache->families );
160   }
161 
162 
163 #if 0
164 
165   FT_LOCAL_DEF( void )
166   FTC_GCache_Done( FTC_GCache  cache )
167   {
168     ftc_gcache_done( FTC_CACHE( cache ) );
169   }
170 
171 #endif /* 0 */
172 
173 
174   FT_LOCAL_DEF( FT_Error )
FTC_GCache_New(FTC_Manager manager,FTC_GCacheClass clazz,FTC_GCache * acache)175   FTC_GCache_New( FTC_Manager       manager,
176                   FTC_GCacheClass   clazz,
177                   FTC_GCache       *acache )
178   {
179     return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz,
180                                       (FTC_Cache*)acache );
181   }
182 
183 
184 #ifndef FTC_INLINE
185 
186   FT_LOCAL_DEF( FT_Error )
FTC_GCache_Lookup(FTC_GCache cache,FT_Offset hash,FT_UInt gindex,FTC_GQuery query,FTC_Node * anode)187   FTC_GCache_Lookup( FTC_GCache   cache,
188                      FT_Offset    hash,
189                      FT_UInt      gindex,
190                      FTC_GQuery   query,
191                      FTC_Node    *anode )
192   {
193     FT_Error  error;
194 
195 
196     query->gindex = gindex;
197 
198     FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error );
199     if ( !error )
200     {
201       FTC_Family  family = query->family;
202 
203 
204       /* prevent the family from being destroyed too early when an        */
205       /* out-of-memory condition occurs during glyph node initialization. */
206       family->num_nodes++;
207 
208       error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode );
209 
210       if ( --family->num_nodes == 0 )
211         FTC_FAMILY_FREE( family, cache );
212     }
213     return error;
214   }
215 
216 #endif /* !FTC_INLINE */
217 
218 
219 /* END */
220