ref: 9b8f5c4ce1ac3f75c2b8960fc31cafe868fa8731
parent: 47c14b9db3ebb058756971f0164a2fdc9125903a
author: David Turner <[email protected]>
date: Sat Oct 28 03:26:59 EDT 2000
small updates: - reworked slightly the cache manager to better differentiate between the abstract class in "ftcglyph.h" and the FT_Glyph sub-class in "ftcimage.h", and slightly reduced the size of FTC_GlyphNodeRec, saving 8 bytes on a 32-bit system. Yes, I'm crazy ;-) - added build files to compile with LCC on Unix too (compile speeds _are_ insane with it). There is unfortunately a bug in the version I'm using (LCC 4.1) that prevents it to compile FT_MulTo64 correctly (in src/base/ftcalc.c) the generated assembly is incorrect, I don't know what to do ?? the build files are ok, though.. you should invoke "make setup lcc" to select them..
--- /dev/null
+++ b/builds/compiler/unix-lcc.mk
@@ -1,0 +1,86 @@
+#
+# FreeType 2 Unix LCC specific definitions
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+# Command line name
+#
+CC := lcc
+
+
+# The object file extension (for standard and static libraries). This can be
+# .o, .tco, .obj, etc., depending on the platform.
+#
+O := o
+SO := o
+
+
+# The library file extension (for standard and static libraries). This can
+# be .a, .lib, etc., depending on the platform.
+#
+A := a
+SA := a
+
+
+# Path inclusion flag. Some compilers use a different flag than `-I' to
+# specify an additional include path. Examples are `/i=' or `-J'.
+#
+I := -I
+
+
+# C flag used to define a macro before the compilation of a given source
+# object. Usually it is `-D' like in `-DDEBUG'.
+#
+D := -D
+
+
+# The link flag used to specify a given library file on link. Note that
+# this is only used to compile the demo programs, not the library itself.
+#
+L := -l
+
+
+# Target flag.
+#
+T := -o # don't remove this comment, we need a trailing space !!
+
+
+# C flags
+#
+# These should concern: debug output, optimization & warnings.
+#
+# Use the ANSIFLAGS variable to define the compiler flags used to enfore
+# ANSI compliance.
+#
+ifndef CFLAGS
+ CFLAGS := -c -g
+endif
+
+# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
+#
+# LCC is pure ANSI anyway!
+#
+# the "-A" flag simply increments verbosity about non ANSI code
+#
+ANSIFLAGS := -A
+
+
+# library linking
+#
+ifndef CLEAN_LIBRARY
+ CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) \
+ $(NO_OUTPUT)
+endif
+LINK_LIBRARY = $(AR) -r $@ $(OBJECTS_LIST)
+
+# EOF
--- a/builds/unix/detect.mk
+++ b/builds/unix/detect.mk
@@ -30,21 +30,30 @@
CONFIG_FILE := unix-dev.mk
devel: setup
else
- # If a Unix platform is detected, the configure script is called and
- # `unix-def.mk' together with `unix-cc.mk' is created.
- #
- # Arguments to `configure' should be in the CFG variable. Example:
- #
- # make CFG="--prefix=/usr --disable-static"
- #
- # If you need to set CFLAGS or LDFLAGS, do it here also.
- #
- # Feel free to add support for other platform specific compilers in this
- # directory (e.g. solaris.mk + changes here to detect the platform).
- #
- CONFIG_FILE := unix.mk
- setup: unix-def.mk
- unix: setup
+
+ # If `lccl' is the requested target, we use a special configuration
+ # file named `unix-lcc.mk'. It disables libtool for LCC
+ #
+ ifneq ($(findstring lcc,$(MAKECMDGOALS)),)
+ CONFIG_FILE := unix-lcc.mk
+ lcc: setup
+ else
+ # If a Unix platform is detected, the configure script is called and
+ # `unix-def.mk' together with `unix-cc.mk' is created.
+ #
+ # Arguments to `configure' should be in the CFG variable. Example:
+ #
+ # make CFG="--prefix=/usr --disable-static"
+ #
+ # If you need to set CFLAGS or LDFLAGS, do it here also.
+ #
+ # Feel free to add support for other platform specific compilers in this
+ # directory (e.g. solaris.mk + changes here to detect the platform).
+ #
+ CONFIG_FILE := unix.mk
+ setup: unix-def.mk
+ unix: setup
+ endif
endif
setup: std_setup
--- /dev/null
+++ b/builds/unix/unix-lcc.mk
@@ -1,0 +1,23 @@
+#
+# FreeType 2 Configuration rules for Unix + LCC
+#
+# Development version without optimizations & libtool
+# and no installation.
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+include $(TOP)/builds/unix/unixddef.mk
+include $(TOP)/builds/compiler/unix-lcc.mk
+include $(TOP)/builds/link_std.mk
+
+# EOF
--- a/include/freetype/cache/ftcglyph.h
+++ b/include/freetype/cache/ftcglyph.h
@@ -49,7 +49,6 @@
#include <freetype/cache/ftcmanag.h>
-#include <freetype/ftglyph.h>
#include <stddef.h>
@@ -58,7 +57,7 @@
#endif
- /* maximum number of queues per image cache; must be < 256 */
+ /* maximum number of queues per glyph cache; must be < 256 */
#define FTC_MAX_GLYPH_QUEUES 16
#define FTC_QUEUE_HASH_SIZE_DEFAULT 64
@@ -70,10 +69,7 @@
typedef struct FTC_GlyphNodeRec_
{
FTC_CacheNodeRec root;
-
- /* link.data contains a handle to a FT_Glyph object */
- FT_ListNodeRec link;
-
+ FTC_GlyphNode queue_next; /* next in queue's bucket list */
FT_UShort glyph_index;
FT_UShort queue_index;
@@ -80,25 +76,7 @@
} FTC_GlyphNodeRec;
-#define FTC_GLYPHNODE_GET_GLYPH( n ) \
- ( (FT_Glyph)((n)->link.data) )
-#define FTC_GLYPHNODE_SET_GLYPH( n, g ) \
- do \
- { \
- (n)->link.data = (g); \
- } while ( 0 )
-
- /* this macro is used to extract a handle to the bucket's lru list */
- /* corresponding to a given image node */
-#define FTC_GLYPHNODE_TO_LISTNODE( n ) \
- ( (FT_ListNode)&(n)->link )
-
- /* this macro is used to extract a handle to a given image node from */
- /* the corresponding LRU glyph list node. That's a bit hackish... */
-#define FTC_LISTNODE_TO_GLYPHNODE( p ) \
- ( (FTC_GlyphNode)( (char*)(p) - \
- offsetof( FTC_GlyphNodeRec,link ) ) )
-
+#define FTC_GLYPHNODE(x) ( (FTC_GlyphNode)(x) )
#define FTC_GLYPHNODE_TO_LRUNODE( n ) ( (FT_ListNode)(n) )
#define FTC_LRUNODE_TO_GLYPHNODE( n ) ( (FTC_GlyphNode)(n) )
@@ -150,7 +128,7 @@
FTC_Glyph_Queue_Class* clazz;
FTC_Image_Desc descriptor;
FT_UInt hash_size;
- FT_List buckets;
+ FTC_GlyphNode* buckets;
FT_UInt queue_index; /* index in parent cache */
} FTC_Glyph_QueueRec;
@@ -170,7 +148,7 @@
{
FTC_CacheRec root;
FT_Lru queues_lru; /* static queues lru list */
- FTC_Glyph_Queue last_queue; /* small cache */
+ FTC_Glyph_Queue last_queue; /* small cache :-) */
} FTC_Glyph_CacheRec;
@@ -182,9 +160,10 @@
/* cache sub-system internals. */
/* */
- FT_EXPORT_FUNC( void ) FTC_GlyphNode_Init( FTC_GlyphNode node,
- FTC_Glyph_Queue queue,
- FT_UInt gindex );
+ FT_EXPORT_FUNC( void )
+ FTC_GlyphNode_Init( FTC_GlyphNode node,
+ FTC_Glyph_Queue queue,
+ FT_UInt gindex );
#define FTC_GlyphNode_Ref( n ) \
FTC_CACHENODE_TO_DATA_P( &(n)->root )->ref_count++
@@ -193,21 +172,30 @@
FTC_CACHENODE_TO_DATA_P( &(n)->root )->ref_count--
- FT_EXPORT_DEF( void ) FTC_Destroy_Glyph_Node( FTC_GlyphNode node,
- FTC_Glyph_Cache cache );
+ FT_EXPORT_DEF( void )
+ FTC_Destroy_Glyph_Node( FTC_GlyphNode node,
+ FTC_Glyph_Cache cache );
- FT_EXPORT_DEF( FT_Error ) FTC_Glyph_Cache_Init( FTC_Glyph_Cache cache );
- FT_EXPORT_DEF( void ) FTC_Glyph_Cache_Done( FTC_Glyph_Cache cache );
+ FT_EXPORT_DEF( FT_Error )
+ FTC_Glyph_Cache_Init( FTC_Glyph_Cache cache );
- FT_EXPORT_DEF( FT_Error ) FTC_Glyph_Queue_New( FTC_Glyph_Cache cache,
- FT_Pointer type,
- FTC_Glyph_Queue* aqueue );
+ FT_EXPORT_DEF( void )
+ FTC_Glyph_Cache_Done( FTC_Glyph_Cache cache );
- FT_EXPORT_DEF( FT_Error ) FTC_Glyph_Queue_Lookup_Node(
- FTC_Glyph_Queue queue,
+
+
+
+ FT_EXPORT_DEF( FT_Error )
+ FTC_Glyph_Queue_New( FTC_Glyph_Cache cache,
+ FT_Pointer type,
+ FTC_Glyph_Queue* aqueue );
+
+
+ FT_EXPORT_DEF( FT_Error )
+ FTC_Glyph_Queue_Lookup_Node( FTC_Glyph_Queue queue,
FT_UInt glyph_index,
FTC_GlyphNode* anode );
--- a/include/freetype/cache/ftcmanag.h
+++ b/include/freetype/cache/ftcmanag.h
@@ -74,9 +74,9 @@
/* default values */
-#define FTC_MAX_FACES_DEFAULT 4
-#define FTC_MAX_SIZES_DEFAULT 8
-#define FTC_MAX_BYTES_DEFAULT 300000 /* 300kByte by default! */
+#define FTC_MAX_FACES_DEFAULT 2
+#define FTC_MAX_SIZES_DEFAULT 4
+#define FTC_MAX_BYTES_DEFAULT 200000 /* 200kByte by default! */
/* maximum number of caches registered in a single manager */
#define FTC_MAX_CACHES 16
@@ -114,7 +114,7 @@
/* the global_lru list of the manager. Its `data' field however is used */
/* as a reference count for now. */
/* */
- /* A node can be anything, depending on the type of information hold by */
+ /* A node can be anything, depending on the type of information held by */
/* the cache. It can be an individual glyph image, a set of bitmaps */
/* glyphs for a given size, some metrics, etc. */
/* */
@@ -123,7 +123,7 @@
typedef FTC_CacheNodeRec* FTC_CacheNode;
- /* the fields `cachenode.data' is typecast to this type */
+ /* the fields `cachenode.data' is typecasted to this type */
typedef struct FTC_CacheNode_Data_
{
FT_UShort cache_index;
@@ -169,8 +169,7 @@
typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache );
-
- typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache );
+ typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache );
struct FTC_Cache_Class_
--- a/include/freetype/cache/ftlru.h
+++ b/include/freetype/cache/ftlru.h
@@ -20,7 +20,7 @@
/* */
/* An LRU is a list that cannot hold more than a certain number of */
/* elements (`max_elements'). All elements on the list are sorted in */
- /* lest-recently-used order, i.e., the `oldest' element is at the tail */
+ /* least-recently-used order, i.e., the `oldest' element is at the tail */
/* of the list. */
/* */
/* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -65,7 +65,7 @@
/* Important: This function is called from the cache manager to */
/* destroy a given cache node during `cache compression'. The */
/* second argument is always `cache.user_data'. Thus be */
- /* certain that the function FTC_Image_Cache_New() does indeed */
+ /* certain that the function FTC_Glyph_Cache_New() does indeed */
/* set its `user_data' field correctly, otherwise bad things */
/* will happen! */
@@ -75,12 +75,32 @@
FT_LruNode queue_lru = cache->queues_lru->nodes + node->queue_index;
FTC_Glyph_Queue queue = (FTC_Glyph_Queue)queue_lru->root.data;
FT_UInt hash = node->glyph_index % queue->hash_size;
- FT_List bucket = queue->buckets + hash;
+
+ /* remove the node from its queue's bucket list */
+ {
+ FTC_GlyphNode* pnode = queue->buckets + hash;
+ FTC_GlyphNode cur;
+
+ for (;;)
+ {
+ cur = *pnode;
+ if (!cur)
+ {
+ /* that's very strange, this should not happen !! */
+ FT_ERROR(( "FTC_GlyphNode_Destroy:"
+ " trying to delete an unlisted node !!!!" ));
+ return;
+ }
+
+ if (cur == node)
+ {
+ *pnode = cur->queue_next;
+ break;
+ }
+ pnode = &cur->queue_next;
+ }
+ }
-
- /* remove node from its queue's bucket list */
- FT_List_Remove( bucket, FTC_GLYPHNODE_TO_LISTNODE( node ) );
-
/* destroy the node */
queue->clazz->destroy_node( node, queue );
}
@@ -89,7 +109,7 @@
/* Important: This function is called from the cache manager to */
/* size a given cache node during `cache compression'. The */
/* second argument is always `cache.user_data'. Thus be */
- /* certain that the function FTC_Image_Cache_New() does indeed */
+ /* certain that the function FTC_Glyph_Cache_New() does indeed */
/* set its `user_data' field correctly, otherwise bad things */
/* will happen! */
@@ -148,7 +168,7 @@
queue->clazz = clazz;
/* allocate buckets table */
- if ( ALLOC_ARRAY( queue->buckets, queue->hash_size, FT_ListRec ) )
+ if ( ALLOC_ARRAY( queue->buckets, queue->hash_size, FTC_GlyphNode ) )
goto Exit;
/* initialize queue by type if needed */
@@ -177,8 +197,8 @@
FTC_Glyph_Cache cache = queue->cache;
FTC_Manager manager = cache->root.manager;
FT_List glyphs_lru = &manager->global_lru;
- FT_List bucket = queue->buckets;
- FT_List bucket_limit = bucket + queue->hash_size;
+ FTC_GlyphNode* bucket = queue->buckets;
+ FTC_GlyphNode* bucket_limit = bucket + queue->hash_size;
FT_Memory memory = cache->root.memory;
FTC_Glyph_Queue_Class* clazz = queue->clazz;
@@ -187,26 +207,24 @@
/* for each bucket, free the list of glyph nodes */
for ( ; bucket < bucket_limit; bucket++ )
{
- FT_ListNode node = bucket->head;
- FT_ListNode next = 0;
- FT_ListNode lrunode;
- FTC_GlyphNode inode;
+ FTC_GlyphNode node = bucket[0];
+ FTC_GlyphNode next = 0;
+ FT_ListNode lrunode;
for ( ; node; node = next )
{
- next = node->next;
- inode = FTC_LISTNODE_TO_GLYPHNODE( node );
- lrunode = FTC_GLYPHNODE_TO_LRUNODE( inode );
+ next = node->queue_next;
+ lrunode = FTC_GLYPHNODE_TO_LRUNODE( node );
- manager->num_bytes -= clazz->size_node( inode, queue );
+ manager->num_bytes -= clazz->size_node( node, queue );
FT_List_Remove( glyphs_lru, lrunode );
- clazz->destroy_node( inode, queue );
+ clazz->destroy_node( node, queue );
}
- bucket->head = bucket->tail = 0;
+ bucket[0] = 0;
}
if ( clazz->done )
@@ -217,58 +235,63 @@
}
- FT_EXPORT_FUNC( FT_Error ) FTC_Glyph_Queue_Lookup_Node(
- FTC_Glyph_Queue queue,
- FT_UInt glyph_index,
- FTC_GlyphNode* anode )
+ FT_EXPORT_FUNC( FT_Error )
+ FTC_Glyph_Queue_Lookup_Node( FTC_Glyph_Queue queue,
+ FT_UInt glyph_index,
+ FTC_GlyphNode* anode )
{
FTC_Glyph_Cache cache = queue->cache;
FTC_Manager manager = cache->root.manager;
FT_UInt hash_index = glyph_index % queue->hash_size;
- FT_List bucket = queue->buckets + hash_index;
- FT_ListNode node;
+ FTC_GlyphNode* bucket = queue->buckets + hash_index;
+ FTC_GlyphNode* pnode = bucket;
+ FTC_GlyphNode node;
FT_Error error;
- FTC_GlyphNode inode;
FTC_Glyph_Queue_Class* clazz = queue->clazz;
*anode = 0;
- for ( node = bucket->head; node; node = node->next )
+
+ for ( ;; )
{
- FT_UInt gindex;
-
-
- inode = FTC_LISTNODE_TO_GLYPHNODE( node );
- gindex = inode->glyph_index;
-
- if ( gindex == glyph_index )
+ node = *pnode;
+ if (!node)
+ break;
+
+ if ( node->glyph_index == glyph_index )
{
/* we found it! -- move glyph to start of the lists */
- FT_List_Up( bucket, node );
- FT_List_Up( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( inode ) );
- *anode = inode;
+ *pnode = node->queue_next;
+ node->queue_next = bucket[0];
+ bucket[0] = node;
+
+ FT_List_Up( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) );
+ *anode = node;
return 0;
}
+ /* go to next node in bucket */
+ pnode = &node->queue_next;
}
/* we didn't found the glyph image, we will now create a new one */
- error = clazz->new_node( queue, glyph_index, &inode );
+ error = clazz->new_node( queue, glyph_index, &node );
if ( error )
goto Exit;
/* insert the node at the start of our bucket list */
- FT_List_Insert( bucket, FTC_GLYPHNODE_TO_LISTNODE( inode ) );
+ node->queue_next = bucket[0];
+ bucket[0] = node;
/* insert the node at the start the global LRU glyph list */
- FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( inode ) );
+ FT_List_Insert( &manager->global_lru, FTC_GLYPHNODE_TO_LRUNODE( node ) );
- manager->num_bytes += clazz->size_node( inode, queue );
+ manager->num_bytes += clazz->size_node( node, queue );
if (manager->num_bytes > manager->max_bytes)
FTC_Manager_Compress( manager );
- *anode = inode;
+ *anode = node;
Exit:
return error;
--- a/src/cache/ftcimage.c
+++ b/src/cache/ftcimage.c
@@ -39,13 +39,13 @@
/* this is a simple glyph image destructor, which is called exclusively */
/* from the CacheQueue object */
LOCAL_FUNC_X
- void ftc_glyph_image_node_destroy( FTC_GlyphNode node,
+ void ftc_glyph_image_node_destroy( FTC_GlyphImage node,
FTC_Glyph_Queue queue )
{
FT_Memory memory = queue->memory;
- FT_Done_Glyph( FTC_GLYPHNODE_GET_GLYPH( node ) );
+ FT_Done_Glyph( node->ft_glyph );
FREE( node );
}
@@ -53,12 +53,12 @@
LOCAL_FUNC_X
FT_Error ftc_glyph_image_node_new( FTC_Glyph_Queue queue,
FT_UInt glyph_index,
- FTC_GlyphNode* anode )
+ FTC_GlyphImage *anode )
{
FT_Memory memory = queue->memory;
FTC_Image_Queue imageq = (FTC_Image_Queue)queue;
FT_Error error;
- FTC_GlyphNode node = 0;
+ FTC_GlyphImage node = 0;
FT_Face face;
FT_Size size;
@@ -68,7 +68,7 @@
goto Exit;
/* init its inner fields */
- FTC_GlyphNode_Init( node, queue, glyph_index );
+ FTC_GlyphNode_Init( FTC_GLYPHNODE(node), queue, glyph_index );
/* we will now load the glyph image */
error = FTC_Manager_Lookup_Size( queue->manager,
@@ -76,7 +76,7 @@
&face, &size );
if ( !error )
{
- FT_UInt glyph_index = node->glyph_index;
+ FT_UInt glyph_index = node->root.glyph_index;
FT_UInt load_flags = FT_LOAD_DEFAULT;
FT_UInt image_type = imageq->description.image_type;
@@ -118,7 +118,7 @@
error = FT_Get_Glyph( face->glyph, &glyph );
if ( !error )
- FTC_GLYPHNODE_SET_GLYPH( node, glyph );
+ node->ft_glyph = glyph;
}
else
error = FT_Err_Invalid_Argument;
@@ -138,10 +138,10 @@
/* a FTC_Glyph_Queue_Class and a FTC_CacheNode_Class */
/* */
LOCAL_FUNC_X
- FT_ULong ftc_glyph_image_node_size( FTC_GlyphNode node )
+ FT_ULong ftc_glyph_image_node_size( FTC_GlyphImage node )
{
FT_ULong size = 0;
- FT_Glyph glyph = FTC_GLYPHNODE_GET_GLYPH( node );
+ FT_Glyph glyph = node->ft_glyph;
switch ( glyph->format )
@@ -249,15 +249,15 @@
}
- FT_EXPORT_DEF( FT_Error ) FTC_Image_Cache_Lookup(
- FTC_Image_Cache cache,
- FTC_Image_Desc* desc,
- FT_UInt gindex,
- FT_Glyph* aglyph )
+ FT_EXPORT_DEF( FT_Error )
+ FTC_Image_Cache_Lookup( FTC_Image_Cache cache,
+ FTC_Image_Desc* desc,
+ FT_UInt gindex,
+ FT_Glyph* aglyph )
{
FT_Error error;
FTC_Glyph_Queue queue;
- FTC_GlyphNode inode;
+ FTC_GlyphNode node;
FTC_Manager manager;
FTC_Image_Queue img_queue;
@@ -281,7 +281,7 @@
goto Exit;
}
- error = FTC_Glyph_Queue_Lookup_Node( queue, gindex, &inode );
+ error = FTC_Glyph_Queue_Lookup_Node( queue, gindex, &node );
if ( error )
goto Exit;
@@ -289,12 +289,12 @@
manager = cache->root.root.manager;
if ( manager->num_bytes > manager->max_bytes )
{
- FTC_GlyphNode_Ref( inode );
+ FTC_GlyphNode_Ref ( node );
FTC_Manager_Compress( manager );
- FTC_GlyphNode_Unref( inode );
+ FTC_GlyphNode_Unref ( node );
}
- *aglyph = FTC_GLYPHNODE_GET_GLYPH( inode );
+ *aglyph = ((FTC_GlyphImage)node)->ft_glyph;
Exit:
return error;
--- a/src/cache/ftcimage.h
+++ b/src/cache/ftcimage.h
@@ -21,11 +21,20 @@
#include <freetype/cache/ftcglyph.h>
+#include <freetype/ftglyph.h>
#ifdef __cplusplus
extern "C" {
#endif
+
+ /* the FT_Glyph image "glyph node" type */
+ typedef struct FTC_GlyphImageRec_
+ {
+ FTC_GlyphNodeRec root;
+ FT_Glyph ft_glyph;
+
+ } FTC_GlyphImageRec, *FTC_GlyphImage;
/* the glyph image queue type */