Add reference counters and to FT_Library and FT_Face objects.

* include/freetype/freetype.h (FT_Reference_Face): New function.
* include/freetype/ftmodapi.h (FT_Rererence_Library): New function.

* include/freetype/internal/ftobjs.h (FT_Face_InternalRec,
FT_LibraryRec): New field `refcount'.

* src/base/ftobjs.c (FT_Open_Face, FT_New_Library): Handle
`refcount'.
(FT_Reference_Face, FT_Reference_Library): Implement new functions.
(FT_Done_Face, FT_Done_Library): Handle `refcount'.

* docs/CHANGES: Updated.
diff --git a/ChangeLog b/ChangeLog
index 72d7dd7..54c49b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2010-07-18  Werner Lemberg  <wl@gnu.org>
 
+	Add reference counters and to FT_Library and FT_Face objects.
+
+	* include/freetype/freetype.h (FT_Reference_Face): New function.
+	* include/freetype/ftmodapi.h (FT_Rererence_Library): New function.
+
+	* include/freetype/internal/ftobjs.h (FT_Face_InternalRec,
+	FT_LibraryRec): New field `refcount'.
+
+	* src/base/ftobjs.c (FT_Open_Face, FT_New_Library): Handle
+	`refcount'.
+	(FT_Reference_Face, FT_Reference_Library): Implement new functions.
+	(FT_Done_Face, FT_Done_Library): Handle `refcount'.
+
+	* docs/CHANGES: Updated.
+
+2010-07-18  Werner Lemberg  <wl@gnu.org>
+
 	* Version 2.4.1 released.
 	=========================
 
diff --git a/docs/CHANGES b/docs/CHANGES
index cc38a75..6c952ac 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,3 +1,18 @@
+CHANGES BETWEEN 2.4.1 and 2.4.2
+
+  I. MISCELLANEOUS
+
+    - Two new functions,  `FT_Reference_Library' (in FT_MODULE_H)  and
+      `FT_Reference_Face'  (in  FT_FREETYPE_H),  have  been  added  to
+      simplify life-cycle management.  A counter gets initialized to 1
+      at the  time an  FT_Library (or  FT_Face) structure  is created.
+      The  two  new   functions  increment  the  respective   counter.
+      `FT_Done_Library' and `FT_Done_Face' then only destroy a library
+      or face if the counter is 1, otherwise they simply decrement the
+      counter. 
+
+
+======================================================================
 
 CHANGES BETWEEN 2.4.0 and 2.4.1
 
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index e2ab774..17c8547 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -1952,6 +1952,9 @@
   /*    Each new face object created with this function also owns a        */
   /*    default @FT_Size object, accessible as `face->size'.               */
   /*                                                                       */
+  /*    See the discussion of reference counters in the description of     */
+  /*    @FT_Reference_Face.                                                */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Open_Face( FT_Library           library,
                 const FT_Open_Args*  args,
@@ -2019,6 +2022,33 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Reference_Face                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A counter gets initialized to~1 at the time an @FT_Face structure  */
+  /*    is created.  This function increments the counter.  @FT_Done_Face  */
+  /*    then only destroys a face if the counter is~1, otherwise it simply */
+  /*    decrements the counter.                                            */
+  /*                                                                       */
+  /*    This function helps in managing life-cycles of structures which    */
+  /*    reference @FT_Face objects.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a target face object.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  /* <Since>                                                               */
+  /*    2.4.2                                                              */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Reference_Face( FT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Done_Face                                                       */
   /*                                                                       */
   /* <Description>                                                         */
@@ -2031,6 +2061,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    See the discussion of reference counters in the description of     */
+  /*    @FT_Reference_Face.                                                */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Done_Face( FT_Face  face );
 
diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
index e7f5927..0b55ebe 100644
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -58,7 +58,7 @@
 
   /****************************************************************************
    *
-   * @func:
+   * @enum:
    *   FT_LcdFilter
    *
    * @description:
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index 17868b2..8f2e017 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -252,6 +252,33 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Reference_Library                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A counter gets initialized to~1 at the time an @FT_Library         */
+  /*    structure is created.  This function increments the counter.       */
+  /*    @FT_Done_Library then only destroys a library if the counter is~1, */
+  /*    otherwise it simply decrements the counter.                        */
+  /*                                                                       */
+  /*    This function helps in managing life-cycles of structures which    */
+  /*    reference @FT_Library objects.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a target library object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  /* <Since>                                                               */
+  /*    2.4.2                                                              */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Reference_Library( FT_Library  library );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_New_Library                                                     */
   /*                                                                       */
   /* <Description>                                                         */
@@ -275,6 +302,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    See the discussion of reference counters in the description of     */
+  /*    @FT_Reference_Library.                                             */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_New_Library( FT_Memory    memory,
                   FT_Library  *alibrary );
@@ -295,6 +326,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    See the discussion of reference counters in the description of     */
+  /*    @FT_Reference_Library.                                             */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Done_Library( FT_Library  library );
 
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 574cf58..670eb78 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -311,6 +311,12 @@
   /*      in the case when the unpatented hinter is compiled within the    */
   /*      library.                                                         */
   /*                                                                       */
+  /*    refcount ::                                                        */
+  /*      A counter initialized to~1 at the time an @FT_Face structure is  */
+  /*      created.  @FT_Reference_Face increments this counter, and        */
+  /*      @FT_Done_Face only destroys a face if the counter is~1,          */
+  /*      otherwise it simply decrements it.                               */
+  /*                                                                       */
   typedef struct  FT_Face_InternalRec_
   {
 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
@@ -328,6 +334,7 @@
 #endif
 
     FT_Bool             ignore_unpatented_hinter;
+    FT_UInt             refcount;
 
   } FT_Face_InternalRec;
 
@@ -805,10 +812,28 @@
   /*                                                                       */
   /*    debug_hooks      :: XXX                                            */
   /*                                                                       */
+  /*    lcd_filter       :: If subpixel rendering is activated, the        */
+  /*                        selected LCD filter mode.                      */
+  /*                                                                       */
+  /*    lcd_extra        :: If subpixel rendering is activated, the number */
+  /*                        of extra pixels needed for the LCD filter.     */
+  /*                                                                       */
+  /*    lcd_weights      :: If subpixel rendering is activated, the LCD    */
+  /*                        filter weights, if any.                        */
+  /*                                                                       */
+  /*    lcd_filter_func  :: If subpixel rendering is activated, the LCD    */
+  /*                        filtering callback function.                   */
+  /*                                                                       */
   /*    pic_container    :: Contains global structs and tables, instead    */
   /*                        of defining them globallly.                    */
   /*                                                                       */
-
+  /*    refcount         :: A counter initialized to~1 at the time an      */
+  /*                        @FT_Library structure is created.              */
+  /*                        @FT_Reference_Library increments this counter, */
+  /*                        and @FT_Done_Library only destroys a library   */
+  /*                        if the counter is~1, otherwise it simply       */
+  /*                        decrements it.                                 */
+  /*                                                                       */
   typedef struct  FT_LibraryRec_
   {
     FT_Memory          memory;           /* library's memory manager */
@@ -843,6 +868,8 @@
     FT_PIC_Container   pic_container;
 #endif
 
+    FT_UInt            refcount;
+
   } FT_LibraryRec;
 
 
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index aa84cf1..9dce576 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -142,7 +142,7 @@
     if ( !args )
       return FT_Err_Invalid_Argument;
 
-    memory   = library->memory;
+    memory = library->memory;
 
     if ( FT_NEW( stream ) )
       goto Exit;
@@ -1960,9 +1960,9 @@
     FT_Error     error;
     FT_Driver    driver;
     FT_Memory    memory;
-    FT_Stream    stream = 0;
-    FT_Face      face = 0;
-    FT_ListNode  node = 0;
+    FT_Stream    stream = NULL;
+    FT_Face      face   = NULL;
+    FT_ListNode  node   = NULL;
     FT_Bool      external_stream;
     FT_Module*   cur;
     FT_Module*   limit;
@@ -2186,6 +2186,8 @@
 
       internal->transform_delta.x = 0;
       internal->transform_delta.y = 0;
+
+      internal->refcount = 1;
     }
 
     if ( aface )
@@ -2274,6 +2276,17 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Error )
+  FT_Reference_Face( FT_Face  face )
+  {
+    face->internal->refcount++;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Error )
   FT_Done_Face( FT_Face  face )
   {
     FT_Error     error;
@@ -2285,22 +2298,29 @@
     error = FT_Err_Invalid_Face_Handle;
     if ( face && face->driver )
     {
-      driver = face->driver;
-      memory = driver->root.memory;
-
-      /* find face in driver's list */
-      node = FT_List_Find( &driver->faces_list, face );
-      if ( node )
-      {
-        /* remove face object from the driver's list */
-        FT_List_Remove( &driver->faces_list, node );
-        FT_FREE( node );
-
-        /* now destroy the object proper */
-        destroy_face( memory, face, driver );
+      face->internal->refcount--;
+      if ( face->internal->refcount > 0 )
         error = FT_Err_Ok;
+      else
+      {
+        driver = face->driver;
+        memory = driver->root.memory;
+
+        /* find face in driver's list */
+        node = FT_List_Find( &driver->faces_list, face );
+        if ( node )
+        {
+          /* remove face object from the driver's list */
+          FT_List_Remove( &driver->faces_list, node );
+          FT_FREE( node );
+
+          /* now destroy the object proper */
+          destroy_face( memory, face, driver );
+          error = FT_Err_Ok;
+        }
       }
     }
+
     return error;
   }
 
@@ -4265,10 +4285,21 @@
   /* documentation is in ftmodapi.h */
 
   FT_EXPORT_DEF( FT_Error )
+  FT_Reference_Library( FT_Library  library )
+  {
+    library->refcount++;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* documentation is in ftmodapi.h */
+
+  FT_EXPORT_DEF( FT_Error )
   FT_New_Library( FT_Memory    memory,
                   FT_Library  *alibrary )
   {
-    FT_Library  library = 0;
+    FT_Library  library = NULL;
     FT_Error    error;
 
 
@@ -4304,6 +4335,8 @@
     library->version_minor = FREETYPE_MINOR;
     library->version_patch = FREETYPE_PATCH;
 
+    library->refcount = 1;
+
     /* That's ok now */
     *alibrary = library;
 
@@ -4360,6 +4393,10 @@
     if ( !library )
       return FT_Err_Invalid_Library_Handle;
 
+    library->refcount--;
+    if ( library->refcount > 0 )
+      goto Exit;
+
     memory = library->memory;
 
     /* Discard client-data */
@@ -4435,6 +4472,8 @@
 #endif
 
     FT_FREE( library );
+
+  Exit:
     return FT_Err_Ok;
   }