summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <digit@digit-pad.(none)>2009-04-13 00:20:03 +0200
committerDavid Turner <digit@digit-pad.(none)>2009-04-13 00:20:03 +0200
commit929ff6996c020b7cda3c8d928cf3f2de4b063708 (patch)
tree8ecb127108ae1f181bdf4d1ada2e5ab46a5fcab0
parent5bac49d83014b75a2aba013a5b86fad2960235eb (diff)
Introduce FT_PicDataRec in include/freetype/internal/ftpic.h
Modify a few users to use it.
-rw-r--r--include/freetype/internal/ftpic.h91
-rw-r--r--src/base/basepic.c58
-rw-r--r--src/base/basepic.h2
-rw-r--r--src/base/ftinit.c37
-rw-r--r--src/base/ftobjs.c2
-rw-r--r--src/base/ftpic.c68
-rw-r--r--src/truetype/ttpic.c60
7 files changed, 223 insertions, 95 deletions
diff --git a/include/freetype/internal/ftpic.h b/include/freetype/internal/ftpic.h
index 8c441d6b..f887a0f6 100644
--- a/include/freetype/internal/ftpic.h
+++ b/include/freetype/internal/ftpic.h
@@ -31,6 +31,51 @@ FT_BEGIN_HEADER
#ifdef FT_CONFIG_OPTION_PIC
+ /* A FT_PicDataRec object models a heap-allocated structure
+ * used to hold data that, in non-PIC builds of the engine,
+ * would be constant and contain pointers.
+ *
+ * The FT_PicDataRec contains book-keeping information about
+ * the structure, whose exact fields depend on which module
+ * is defining/using it. The structure itself can be
+ * accessed as the 'data' field of a FT_PicDataRec object.
+ */
+ typedef struct FT_PicDataRec_* FT_PicData;
+
+ /* A FT_PicTableRec object contains the FT_PicDataRec of all
+ * PIC structures needed by the library at runtime.
+ */
+ typedef struct FT_PicTableRec_* FT_PicTable;
+
+ /* A special callback function call to finalize the structure
+ * backed by a FT_PicDataRec object. It is called by
+ * ft_pic_table_done_data and its first parameter is the 'data'
+ * field of the corresponding FT_PicDataRec. Note that the
+ * PIC structure itself is allocated by ft_pic_table_init_data
+ * and freed by ft_pic_table_done_data.
+ */
+ typedef void (*FT_PicDataDoneFunc)( void* data, FT_PicTable pic );
+
+ /* A special initialization function called by ft_pic_table_init_data
+ * to initialize a freshly allocated PIC structure.
+ */
+ typedef FT_Error (*FT_PicDataInitFunc)( void* data, FT_PicTable pic );
+
+ /* The FT_PicDataRec itself holds a pointer to heap-allocated
+ * PIC data, a reference count and an optional finalizer function.
+ *
+ * One should call ft_pic_table_init_data() to register a new
+ * heap-allocated PIC structure, which address will be placed
+ * into the 'data' field.
+ */
+ typedef struct FT_PicDataRec_
+ {
+ void* data;
+ FT_Int ref_count;
+ FT_PicDataDoneFunc done;
+
+ } FT_PicDataRec;
+
/* When FT_CONFIG_OPTION_PIC is defined, the FT_PicTable
* is used to hold all constant structures that normally
* contain pointers in the normal build of FreeType.
@@ -41,10 +86,20 @@ FT_BEGIN_HEADER
*/
typedef struct FT_PicTableRec_
{
- /* pic containers for base */
- void* base;
+ FT_Library library;
+ FT_Memory memory;
+
+/* this macro is used to define the list of FT_PicDataRec
+ * stored in the PIC table. Add new entries here.
+ */
+#define FT_PIC_ENTRY_LIST \
+ _FT_PICDATA( base ) \
+
+/* now define the entries in the PIC table itself */
+#define _FT_PICDATA(name) FT_PicDataRec name [1];
+ FT_PIC_ENTRY_LIST
+#undef _FT_PICDATA
- /* pic containers for modules */
void* autofit;
void* cff;
void* pshinter;
@@ -54,13 +109,39 @@ FT_BEGIN_HEADER
void* smooth;
void* truetype;
- } FT_PicTableRec, *FT_PicTable;
+ } FT_PicTableRec;
+
+#define FT_LIBRARY_GET_PIC_DATA(library_,name_) \
+ library_->pic_table.name_->data
+
+ /* allocate and initialize a PIC structure in the heap.
+ * This should be called at module initialization time
+ * before the PIC data can be used.
+ *
+ * if the structure already exists, this simply increments
+ * its reference count.
+ */
+ FT_BASE( FT_Error )
+ ft_pic_table_init_data( FT_PicTable table,
+ FT_PicData data,
+ FT_UInt data_size,
+ FT_PicDataInitFunc data_init,
+ FT_PicDataDoneFunc data_done );
+
+ /* finalize and free a given PIC structure. This really
+ * decrements the reference count and performs destruction
+ * if it reaches 0.
+ *
+ * this should be called a module exit time.
+ */
+ FT_BASE( void )
+ ft_pic_table_done_data( FT_PicTable table,
+ FT_PicData data );
/* Initialize the PIC table's base */
FT_BASE( FT_Error )
ft_library_pic_init( FT_Library library );
-
/* Destroy the contents of the PIC table. */
FT_BASE( void )
ft_library_pic_done( FT_Library library );
diff --git a/src/base/basepic.c b/src/base/basepic.c
index b0d6a18c..280dc701 100644
--- a/src/base/basepic.c
+++ b/src/base/basepic.c
@@ -31,55 +31,47 @@
FT_Error ft_create_default_module_classes(FT_Library);
void ft_destroy_default_module_classes(FT_Library);
- void
- ft_base_pic_free( FT_Library library )
+ static void
+ pic_base_done( void* base, FT_PicTable pic )
{
- FT_PicTable pic_table = &library->pic_table;
- FT_Memory memory = library->memory;
-
-
- if ( pic_table->base )
- {
- /* Destroy default module classes (in case FT_Add_Default_Modules was used) */
- ft_destroy_default_module_classes( library );
+ FT_UNUSED(base);
- FT_FREE( pic_table->base );
- pic_table->base = NULL;
- }
+ /* Destroy default module classes (in case FT_Add_Default_Modules was used) */
+ ft_destroy_default_module_classes( pic->library );
}
-
- FT_Error
- ft_base_pic_init( FT_Library library )
+ static FT_Error
+ pic_base_init( void* data, FT_PicTable pic )
{
- FT_PicTable pic_table = &library->pic_table;
- FT_Error error = FT_Err_Ok;
- FT_Memory memory = library->memory;
- BasePIC* container;
-
- /* allocate pointer, clear and set global container pointer */
- if ( FT_NEW ( container ) )
- return error;
-
- pic_table->base = container;
+ BasePIC* base = (BasePIC*)data;
+ FT_Error error;
/* initialize default modules list and pointers */
- error = ft_create_default_module_classes( library );
+ error = ft_create_default_module_classes( pic->library );
if ( error )
goto Exit;
/* initialize pointer table - this is how the module usually expects this data */
- ft_pic_init_ft_outline_glyph_class(&container->ft_outline_glyph_class);
- ft_pic_init_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class);
-
-Exit:
- if(error)
- ft_base_pic_free(library);
+ ft_pic_init_ft_outline_glyph_class(&base->ft_outline_glyph_class);
+ ft_pic_init_ft_bitmap_glyph_class(&base->ft_bitmap_glyph_class);
+ Exit:
return error;
}
+ FT_Error
+ ft_base_pic_init( FT_Library library )
+ {
+ FT_PicTable pic_table = &library->pic_table;
+
+ return ft_pic_table_init_data( pic_table,
+ pic_table->base,
+ sizeof(BasePIC),
+ pic_base_init,
+ pic_base_done );
+ }
+
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/src/base/basepic.h b/src/base/basepic.h
index e9eb68cf..11936ea7 100644
--- a/src/base/basepic.h
+++ b/src/base/basepic.h
@@ -43,7 +43,7 @@ FT_BEGIN_HEADER
#define GET_PIC(lib) ((BasePIC*)((lib)->pic_table.base))
#define FT_OUTLINE_GLYPH_CLASS_GET (&GET_PIC(library)->ft_outline_glyph_class)
#define FT_BITMAP_GLYPH_CLASS_GET (&GET_PIC(library)->ft_bitmap_glyph_class)
-#define FT_DEFAULT_MODULES_GET (GET_PIC(library)->default_module_classes)
+#define FT_DEFAULT_MODULES_GET (const FT_Module_Class* const*)(GET_PIC(library)->default_module_classes)
void
ft_base_pic_free( FT_Library library );
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index 9ed6c427..ba830b21 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -115,7 +115,7 @@
FT_Module_Class** classes;
FT_Memory memory;
FT_UInt i;
- BasePIC* pic_table = library->pic_table.base;
+ BasePIC* pic_table = FT_LIBRARY_GET_PIC_DATA(library, base);
if ( !pic_table->default_module_classes )
return;
@@ -130,13 +130,6 @@
pic_table->default_module_classes = 0;
}
- /* initialize all module classes and the pointer table */
-#undef FT_USE_MODULE
-#define FT_USE_MODULE( type, x ) \
- error = ft_library_pic_alloc_##x(library, &clazz); \
- if (error) goto Exit; \
- classes[i++] = clazz;
-
FT_BASE_DEF( FT_Error )
ft_create_default_module_classes( FT_Library library )
{
@@ -145,27 +138,35 @@
FT_Module_Class** classes;
FT_Module_Class* clazz;
FT_UInt i;
- BasePIC* pic_table = library->pic_table.base;
+ BasePIC* pic_table = FT_LIBRARY_GET_PIC_DATA(library, base);
memory = library->memory;
pic_table->default_module_classes = 0;
- if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) )
+ if ( FT_NEW_ARRAY(classes, FT_NUM_MODULE_CLASSES + 1 ) )
return error;
- /* initialize all pointers to 0, especially the last one */
- for (i = 0; i < FT_NUM_MODULE_CLASSES; i++)
- classes[i] = 0;
- classes[FT_NUM_MODULE_CLASSES] = 0;
i = 0;
+ /* initialize all module classes and the pointer table */
+#undef FT_USE_MODULE
+#define FT_USE_MODULE( type, x ) \
+ error = ft_library_pic_alloc_##x(library, &clazz); \
+ if (error) \
+ goto Exit; \
+ \
+ classes[i++] = clazz;
+
#include FT_CONFIG_MODULES_H
+#undef FT_USE_MODULE
-Exit:
- if (error) ft_destroy_default_module_classes( library );
- else pic_table->default_module_classes = classes;
+Exit:
+ if (error)
+ ft_destroy_default_module_classes( library );
+ else
+ pic_table->default_module_classes = classes;
- return error;
+ return error;
}
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index cdbc40de..04f5b015 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4144,7 +4144,7 @@
Fail:
#ifdef FT_CONFIG_OPTION_PIC
- ft_library_done_pic( library );
+ ft_library_pic_done( library );
#endif
FT_FREE( library );
return error;
diff --git a/src/base/ftpic.c b/src/base/ftpic.c
index ba07ae5f..095bbf67 100644
--- a/src/base/ftpic.c
+++ b/src/base/ftpic.c
@@ -26,12 +26,74 @@
/* documentation is in ftpic.h */
FT_BASE_DEF( FT_Error )
+ ft_pic_table_init_data( FT_PicTable pic,
+ FT_PicData data,
+ FT_UInt data_size,
+ FT_PicDataInitFunc data_init,
+ FT_PicDataDoneFunc data_done )
+ {
+ void* pic_data = data->data;
+ FT_Error error = 0;
+ FT_Memory memory = pic->memory;
+
+ /* if the PIC structure already exist, just increment its
+ * reference count
+ */
+ if (pic_data != NULL)
+ {
+ data->ref_count += 1;
+ return 0;
+ }
+
+ if ( FT_ALLOC( pic_data, data_size ) )
+ goto Exit;
+
+ error = data_init( pic_data, pic );
+ if (error)
+ {
+ if (data_done)
+ data_done( pic_data, pic );
+
+ FT_FREE( pic_data );
+ goto Exit;
+ }
+
+ data->data = pic_data;
+ data->ref_count = 1;
+ data->done = data_done;
+
+ Exit:
+ return error;
+ }
+
+
+ FT_BASE_DEF( void )
+ ft_pic_table_done_data( FT_PicTable pic,
+ FT_PicData data )
+ {
+ FT_Memory memory = pic->memory;
+
+ if ( --data->ref_count != 0 )
+ return;
+
+ if (data->done)
+ data->done( data->data, pic );
+
+ FT_FREE(data->data);
+ data->done = NULL;
+ }
+
+
+ FT_BASE_DEF( FT_Error )
ft_library_pic_init( FT_Library library )
{
- FT_PicTable pic_table = &library->pic_table;
- FT_Error error = FT_Err_Ok;
+ FT_PicTable pic = &library->pic_table;
+ FT_Error error = FT_Err_Ok;
+
+ FT_ZERO(pic);
- FT_ZERO(pic_table);
+ pic->library = library;
+ pic->memory = library->memory;
error = ft_base_pic_init( library );
if(error)
diff --git a/src/truetype/ttpic.c b/src/truetype/ttpic.c
index 6cc210e8..09ba3f47 100644
--- a/src/truetype/ttpic.c
+++ b/src/truetype/ttpic.c
@@ -29,57 +29,49 @@
void ft_pic_init_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*);
void ft_pic_init_tt_service_truetype_glyf(FT_Service_TTGlyfRec*);
- void
- tt_driver_class_pic_free( FT_Library library )
+ static void
+ pic_tt_driver_done( void* data, FT_PicTable pic )
{
- FT_PicTable pic_table = &library->pic_table;
- FT_Memory memory = library->memory;
+ TTModulePIC* container = (TTModulePIC*) data;
- if ( pic_table->truetype )
+ if (container->tt_services)
{
- TTModulePIC* container = (TTModulePIC*)pic_table->truetype;
-
- if(container->tt_services)
- {
- ft_library_pic_free_tt_services(library, container->tt_services);
- container->tt_services = NULL;
- }
- FT_FREE( container );
- pic_table->truetype = NULL;
+ ft_library_pic_free_tt_services(pic->library, container->tt_services);
+ container->tt_services = NULL;
}
}
-
- FT_Error
- tt_driver_class_pic_init( FT_Library library )
+ static FT_Error
+ pic_tt_driver_init( void* data, FT_PicTable pic )
{
- FT_PicTable pic_table = &library->pic_table;
- FT_Error error = FT_Err_Ok;
- FT_Memory memory = library->memory;
- TTModulePIC* container;
-
- /* allocate pointer, clear and set global container pointer */
- if ( FT_NEW ( container ) )
- return error;
+ TTModulePIC* container = (TTModulePIC*) data;
+ FT_Error error;
- pic_table->truetype = container;
-
- /* initialize pointer table - this is how the module usually expects this data */
- error = ft_library_pic_alloc_tt_services(library, &container->tt_services);
- if(error)
+ error = ft_library_pic_alloc_tt_services(pic->library, &container->tt_services);
+ if (error)
goto Exit;
+
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
ft_pic_init_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters);
#endif
ft_pic_init_tt_service_truetype_glyf(&container->tt_service_truetype_glyf);
-Exit:
- if(error)
- tt_driver_class_pic_free(library);
-
+ Exit:
return error;
}
+ FT_Error
+ tt_driver_class_pic_init( FT_Library library )
+ {
+ FT_PicTable pic_table = &library->pic_table;
+
+ return ft_pic_table_init_data( pic_table,
+ pic_table->truetype,
+ sizeof(TTModulePIC),
+ pic_tt_driver_init,
+ pic_tt_driver_done );
+ }
+
#endif /* FT_CONFIG_OPTION_PIC */