Alexei Podtelezhnikov pushed to branch ftc_resize at FreeType / FreeType
Commits:
-
6ca0a935
by suzuki toshiya at 2023-05-11T14:31:23+00:00
-
ad708d70
by Alexei Podtelezhnikov at 2023-05-11T21:44:31+00:00
4 changed files:
Changes:
... | ... | @@ -94,8 +94,8 @@ |
94 | 94 | |
95 | 95 | |
96 | 96 | idx = hash & cache->mask;
|
97 | - if ( idx < cache->p )
|
|
98 | - idx = hash & ( 2 * cache->mask + 1 );
|
|
97 | + if ( idx >= cache->p )
|
|
98 | + idx = hash & ( cache->mask >> 1 );
|
|
99 | 99 | |
100 | 100 | return cache->buckets + idx;
|
101 | 101 | }
|
... | ... | @@ -113,9 +113,9 @@ |
113 | 113 | for (;;)
|
114 | 114 | {
|
115 | 115 | FTC_Node node, *pnode;
|
116 | - FT_UFast p = cache->p;
|
|
117 | - FT_UFast mask = cache->mask;
|
|
118 | - FT_UFast count = mask + p + 1; /* number of buckets */
|
|
116 | + FT_UFast p = cache->p;
|
|
117 | + FT_UFast size = cache->mask + 1; /* available size */
|
|
118 | + FT_UFast half = size >> 1;
|
|
119 | 119 | |
120 | 120 | |
121 | 121 | /* do we need to expand the buckets array? */
|
... | ... | @@ -127,20 +127,22 @@ |
127 | 127 | /* try to expand the buckets array _before_ splitting
|
128 | 128 | * the bucket lists
|
129 | 129 | */
|
130 | - if ( p >= mask )
|
|
130 | + if ( p == size )
|
|
131 | 131 | {
|
132 | 132 | FT_Memory memory = cache->memory;
|
133 | 133 | FT_Error error;
|
134 | 134 | |
135 | 135 | |
136 | 136 | /* if we can't expand the array, leave immediately */
|
137 | - if ( FT_RENEW_ARRAY( cache->buckets,
|
|
138 | - ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) )
|
|
137 | + if ( FT_QRENEW_ARRAY( cache->buckets, size, size * 2 ) )
|
|
139 | 138 | break;
|
139 | + |
|
140 | + cache->mask = 2 * size - 1;
|
|
141 | + half = size;
|
|
140 | 142 | }
|
141 | 143 | |
142 | - /* split a single bucket */
|
|
143 | - pnode = cache->buckets + p;
|
|
144 | + /* the bucket to split */
|
|
145 | + pnode = cache->buckets + p - half;
|
|
144 | 146 | |
145 | 147 | for (;;)
|
146 | 148 | {
|
... | ... | @@ -148,7 +150,7 @@ |
148 | 150 | if ( !node )
|
149 | 151 | break;
|
150 | 152 | |
151 | - if ( node->hash & ( mask + 1 ) )
|
|
153 | + if ( node->hash & half )
|
|
152 | 154 | {
|
153 | 155 | *pnode = node->link;
|
154 | 156 | node->link = new_list;
|
... | ... | @@ -158,56 +160,50 @@ |
158 | 160 | pnode = &node->link;
|
159 | 161 | }
|
160 | 162 | |
161 | - cache->buckets[p + mask + 1] = new_list;
|
|
163 | + cache->buckets[p] = new_list;
|
|
162 | 164 | |
163 | 165 | cache->slack += FTC_HASH_MAX_LOAD;
|
166 | + cache->p = p + 1;
|
|
164 | 167 | |
165 | - if ( p >= mask )
|
|
166 | - {
|
|
167 | - cache->mask = 2 * mask + 1;
|
|
168 | - cache->p = 0;
|
|
169 | - }
|
|
170 | - else
|
|
171 | - cache->p = p + 1;
|
|
168 | + FT_TRACE2(( "ftc_cache_resize: cache %u increased to %u hashes\n",
|
|
169 | + cache->index, cache->p ));
|
|
172 | 170 | }
|
173 | 171 | |
174 | 172 | /* do we need to shrink the buckets array? */
|
175 | - else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
|
|
173 | + else if ( cache->slack > (FT_Long)p * FTC_HASH_SUB_LOAD )
|
|
176 | 174 | {
|
177 | - FT_UFast old_index = p + mask;
|
|
178 | - FTC_Node* pold;
|
|
175 | + FTC_Node old_list = cache->buckets[--p];
|
|
179 | 176 | |
180 | 177 | |
181 | - if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
|
|
178 | + if ( p < FTC_HASH_INITIAL_SIZE )
|
|
182 | 179 | break;
|
183 | 180 | |
184 | - if ( p == 0 )
|
|
181 | + if ( p == half )
|
|
185 | 182 | {
|
186 | 183 | FT_Memory memory = cache->memory;
|
187 | 184 | FT_Error error;
|
188 | 185 | |
189 | 186 | |
190 | 187 | /* if we can't shrink the array, leave immediately */
|
191 | - if ( FT_QRENEW_ARRAY( cache->buckets,
|
|
192 | - ( mask + 1 ) * 2, mask + 1 ) )
|
|
188 | + if ( FT_QRENEW_ARRAY( cache->buckets, size, half ) )
|
|
193 | 189 | break;
|
194 | 190 | |
195 | - cache->mask >>= 1;
|
|
196 | - p = cache->mask;
|
|
191 | + cache->mask = half - 1;
|
|
197 | 192 | }
|
198 | - else
|
|
199 | - p--;
|
|
200 | 193 | |
201 | - pnode = cache->buckets + p;
|
|
194 | + /* the bucket to merge */
|
|
195 | + pnode = cache->buckets + p - half;
|
|
196 | + |
|
202 | 197 | while ( *pnode )
|
203 | 198 | pnode = &(*pnode)->link;
|
204 | 199 | |
205 | - pold = cache->buckets + old_index;
|
|
206 | - *pnode = *pold;
|
|
207 | - *pold = NULL;
|
|
200 | + *pnode = old_list;
|
|
208 | 201 | |
209 | 202 | cache->slack -= FTC_HASH_MAX_LOAD;
|
210 | 203 | cache->p = p;
|
204 | + |
|
205 | + FT_TRACE2(( "ftc_cache_resize: cache %u decreased to %u hashes\n",
|
|
206 | + cache->index, cache->p ));
|
|
211 | 207 | }
|
212 | 208 | |
213 | 209 | /* otherwise, the hash table is balanced */
|
... | ... | @@ -336,11 +332,11 @@ |
336 | 332 | FT_Error error;
|
337 | 333 | |
338 | 334 | |
339 | - cache->p = 0;
|
|
335 | + cache->p = FTC_HASH_INITIAL_SIZE;
|
|
340 | 336 | cache->mask = FTC_HASH_INITIAL_SIZE - 1;
|
341 | 337 | cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
|
342 | 338 | |
343 | - FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
|
|
339 | + FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE );
|
|
344 | 340 | return error;
|
345 | 341 | }
|
346 | 342 | |
... | ... | @@ -351,11 +347,9 @@ |
351 | 347 | if ( cache && cache->buckets )
|
352 | 348 | {
|
353 | 349 | FTC_Manager manager = cache->manager;
|
350 | + FT_UFast count = cache->p;
|
|
354 | 351 | FT_UFast i;
|
355 | - FT_UFast count;
|
|
356 | - |
|
357 | 352 | |
358 | - count = cache->p + cache->mask + 1;
|
|
359 | 353 | |
360 | 354 | for ( i = 0; i < count; i++ )
|
361 | 355 | {
|
... | ... | @@ -562,12 +556,12 @@ |
562 | 556 | FTC_Cache_RemoveFaceID( FTC_Cache cache,
|
563 | 557 | FTC_FaceID face_id )
|
564 | 558 | {
|
565 | - FT_UFast i, count;
|
|
566 | 559 | FTC_Manager manager = cache->manager;
|
567 | 560 | FTC_Node frees = NULL;
|
561 | + FT_UFast count = cache->p;
|
|
562 | + FT_UFast i;
|
|
568 | 563 | |
569 | 564 | |
570 | - count = cache->p + cache->mask + 1;
|
|
571 | 565 | for ( i = 0; i < count; i++ )
|
572 | 566 | {
|
573 | 567 | FTC_Node* pnode = cache->buckets + i;
|
... | ... | @@ -72,11 +72,12 @@ FT_BEGIN_HEADER |
72 | 72 | #define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next )
|
73 | 73 | #define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev )
|
74 | 74 | |
75 | + /* address the hash table entries */
|
|
75 | 76 | #ifdef FTC_INLINE
|
76 | -#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \
|
|
77 | - ( ( cache )->buckets + \
|
|
78 | - ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \
|
|
79 | - ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \
|
|
77 | +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \
|
|
78 | + ( ( cache )->buckets + \
|
|
79 | + ( ( ( ( hash ) & ( cache )->mask ) >= ( cache )->p ) \
|
|
80 | + ? ( ( hash ) & ( ( cache )->mask >> 1 ) ) \
|
|
80 | 81 | : ( ( hash ) & ( cache )->mask ) ) )
|
81 | 82 | #else
|
82 | 83 | FT_LOCAL( FTC_Node* )
|
... | ... | @@ -139,11 +140,13 @@ FT_BEGIN_HEADER |
139 | 140 | } FTC_CacheClassRec;
|
140 | 141 | |
141 | 142 | |
142 | - /* each cache really implements a dynamic hash table to manage its nodes */
|
|
143 | + /* each cache really implements a hash table to manage its nodes */
|
|
144 | + /* the number of the table entries (buckets) can change dynamically */
|
|
145 | + /* each bucket contains a linked lists of nodes for a given hash */
|
|
143 | 146 | typedef struct FTC_CacheRec_
|
144 | 147 | {
|
145 | - FT_UFast p;
|
|
146 | - FT_UFast mask;
|
|
148 | + FT_UFast p; /* hash table counter */
|
|
149 | + FT_UFast mask; /* hash table index range */
|
|
147 | 150 | FT_Long slack;
|
148 | 151 | FTC_Node* buckets;
|
149 | 152 |
... | ... | @@ -374,6 +374,14 @@ |
374 | 374 | if ( info->is_fixed_pitch )
|
375 | 375 | cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
376 | 376 | |
377 | + /*
|
|
378 | + * For the sfnt-wrapped CID fonts for MacOS, currently,
|
|
379 | + * its `cmap' tables are ignored, and the content in
|
|
380 | + * its `CID ' table is treated the same as naked CID-keyed
|
|
381 | + * font. See ft_lookup_PS_in_sfnt_stream().
|
|
382 | + */
|
|
383 | + cidface->face_flags |= FT_FACE_FLAG_CID_KEYED;
|
|
384 | + |
|
377 | 385 | /* XXX: TODO: add kerning with .afm support */
|
378 | 386 | |
379 | 387 | /* get style name -- be careful, some broken fonts only */
|
... | ... | @@ -141,8 +141,14 @@ |
141 | 141 | FT_UNUSED( face );
|
142 | 142 | |
143 | 143 | |
144 | + /*
|
|
145 | + * XXX: If the ROS is Adobe-Identity-H or -V,
|
|
146 | + * the font has no reliable information about
|
|
147 | + * its glyph collection. Should we not set
|
|
148 | + * *is_cid in such cases?
|
|
149 | + */
|
|
144 | 150 | if ( is_cid )
|
145 | - *is_cid = 1; /* cid driver is only used for CID keyed fonts */
|
|
151 | + *is_cid = 1;
|
|
146 | 152 | |
147 | 153 | return error;
|
148 | 154 | }
|