Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftcbasic.c                                                             */
  4. /*                                                                         */
  5. /*    The FreeType basic cache interface (body).                           */
  6. /*                                                                         */
  7. /*  Copyright 2003-2007, 2009-2011, 2013 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_INTERNAL_DEBUG_H
  22. #include FT_CACHE_H
  23. #include "ftcglyph.h"
  24. #include "ftcimage.h"
  25. #include "ftcsbits.h"
  26.  
  27. #include "ftccback.h"
  28. #include "ftcerror.h"
  29.  
  30. #define FT_COMPONENT  trace_cache
  31.  
  32.  
  33.   /*
  34.    *  Basic Families
  35.    *
  36.    */
  37.   typedef struct  FTC_BasicAttrRec_
  38.   {
  39.     FTC_ScalerRec  scaler;
  40.     FT_UInt        load_flags;
  41.  
  42.   } FTC_BasicAttrRec, *FTC_BasicAttrs;
  43.  
  44. #define FTC_BASIC_ATTR_COMPARE( a, b )                                 \
  45.           FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
  46.                    (a)->load_flags == (b)->load_flags               )
  47.  
  48. #define FTC_BASIC_ATTR_HASH( a )                                   \
  49.           ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
  50.  
  51.  
  52.   typedef struct  FTC_BasicQueryRec_
  53.   {
  54.     FTC_GQueryRec     gquery;
  55.     FTC_BasicAttrRec  attrs;
  56.  
  57.   } FTC_BasicQueryRec, *FTC_BasicQuery;
  58.  
  59.  
  60.   typedef struct  FTC_BasicFamilyRec_
  61.   {
  62.     FTC_FamilyRec     family;
  63.     FTC_BasicAttrRec  attrs;
  64.  
  65.   } FTC_BasicFamilyRec, *FTC_BasicFamily;
  66.  
  67.  
  68.   FT_CALLBACK_DEF( FT_Bool )
  69.   ftc_basic_family_compare( FTC_MruNode  ftcfamily,
  70.                             FT_Pointer   ftcquery )
  71.   {
  72.     FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
  73.     FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
  74.  
  75.  
  76.     return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
  77.   }
  78.  
  79.  
  80.   FT_CALLBACK_DEF( FT_Error )
  81.   ftc_basic_family_init( FTC_MruNode  ftcfamily,
  82.                          FT_Pointer   ftcquery,
  83.                          FT_Pointer   ftccache )
  84.   {
  85.     FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
  86.     FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;
  87.     FTC_Cache        cache  = (FTC_Cache)ftccache;
  88.  
  89.  
  90.     FTC_Family_Init( FTC_FAMILY( family ), cache );
  91.     family->attrs = query->attrs;
  92.     return 0;
  93.   }
  94.  
  95.  
  96.   FT_CALLBACK_DEF( FT_UInt )
  97.   ftc_basic_family_get_count( FTC_Family   ftcfamily,
  98.                               FTC_Manager  manager )
  99.   {
  100.     FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
  101.     FT_Error         error;
  102.     FT_Face          face;
  103.     FT_UInt          result = 0;
  104.  
  105.  
  106.     error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
  107.                                     &face );
  108.  
  109.     if ( error || !face )
  110.       return result;
  111.  
  112.     if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
  113.     {
  114.       FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
  115.       FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));
  116.     }
  117.  
  118.     if ( !error )
  119.       result = (FT_UInt)face->num_glyphs;
  120.  
  121.     return result;
  122.   }
  123.  
  124.  
  125.   FT_CALLBACK_DEF( FT_Error )
  126.   ftc_basic_family_load_bitmap( FTC_Family   ftcfamily,
  127.                                 FT_UInt      gindex,
  128.                                 FTC_Manager  manager,
  129.                                 FT_Face     *aface )
  130.   {
  131.     FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
  132.     FT_Error         error;
  133.     FT_Size          size;
  134.  
  135.  
  136.     error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
  137.     if ( !error )
  138.     {
  139.       FT_Face  face = size->face;
  140.  
  141.  
  142.       error = FT_Load_Glyph( face, gindex,
  143.                              family->attrs.load_flags | FT_LOAD_RENDER );
  144.       if ( !error )
  145.         *aface = face;
  146.     }
  147.  
  148.     return error;
  149.   }
  150.  
  151.  
  152.   FT_CALLBACK_DEF( FT_Error )
  153.   ftc_basic_family_load_glyph( FTC_Family  ftcfamily,
  154.                                FT_UInt     gindex,
  155.                                FTC_Cache   cache,
  156.                                FT_Glyph   *aglyph )
  157.   {
  158.     FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
  159.     FT_Error         error;
  160.     FTC_Scaler       scaler = &family->attrs.scaler;
  161.     FT_Face          face;
  162.     FT_Size          size;
  163.  
  164.  
  165.     /* we will now load the glyph image */
  166.     error = FTC_Manager_LookupSize( cache->manager,
  167.                                     scaler,
  168.                                     &size );
  169.     if ( !error )
  170.     {
  171.       face = size->face;
  172.  
  173.       error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
  174.       if ( !error )
  175.       {
  176.         if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
  177.              face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
  178.         {
  179.           /* ok, copy it */
  180.           FT_Glyph  glyph;
  181.  
  182.  
  183.           error = FT_Get_Glyph( face->glyph, &glyph );
  184.           if ( !error )
  185.           {
  186.             *aglyph = glyph;
  187.             goto Exit;
  188.           }
  189.         }
  190.         else
  191.           error = FT_THROW( Invalid_Argument );
  192.       }
  193.     }
  194.  
  195.   Exit:
  196.     return error;
  197.   }
  198.  
  199.  
  200.   FT_CALLBACK_DEF( FT_Bool )
  201.   ftc_basic_gnode_compare_faceid( FTC_Node    ftcgnode,
  202.                                   FT_Pointer  ftcface_id,
  203.                                   FTC_Cache   cache,
  204.                                   FT_Bool*    list_changed )
  205.   {
  206.     FTC_GNode        gnode   = (FTC_GNode)ftcgnode;
  207.     FTC_FaceID       face_id = (FTC_FaceID)ftcface_id;
  208.     FTC_BasicFamily  family  = (FTC_BasicFamily)gnode->family;
  209.     FT_Bool          result;
  210.  
  211.  
  212.     if ( list_changed )
  213.       *list_changed = FALSE;
  214.     result = FT_BOOL( family->attrs.scaler.face_id == face_id );
  215.     if ( result )
  216.     {
  217.       /* we must call this function to avoid this node from appearing
  218.        * in later lookups with the same face_id!
  219.        */
  220.       FTC_GNode_UnselectFamily( gnode, cache );
  221.     }
  222.     return result;
  223.   }
  224.  
  225.  
  226.  /*
  227.   *
  228.   * basic image cache
  229.   *
  230.   */
  231.  
  232.   FT_CALLBACK_TABLE_DEF
  233.   const FTC_IFamilyClassRec  ftc_basic_image_family_class =
  234.   {
  235.     {
  236.       sizeof ( FTC_BasicFamilyRec ),
  237.       ftc_basic_family_compare,
  238.       ftc_basic_family_init,
  239.       0,                        /* FTC_MruNode_ResetFunc */
  240.       0                         /* FTC_MruNode_DoneFunc  */
  241.     },
  242.     ftc_basic_family_load_glyph
  243.   };
  244.  
  245.  
  246.   FT_CALLBACK_TABLE_DEF
  247.   const FTC_GCacheClassRec  ftc_basic_image_cache_class =
  248.   {
  249.     {
  250.       ftc_inode_new,
  251.       ftc_inode_weight,
  252.       ftc_gnode_compare,
  253.       ftc_basic_gnode_compare_faceid,
  254.       ftc_inode_free,
  255.  
  256.       sizeof ( FTC_GCacheRec ),
  257.       ftc_gcache_init,
  258.       ftc_gcache_done
  259.     },
  260.     (FTC_MruListClass)&ftc_basic_image_family_class
  261.   };
  262.  
  263.  
  264.   /* documentation is in ftcache.h */
  265.  
  266.   FT_EXPORT_DEF( FT_Error )
  267.   FTC_ImageCache_New( FTC_Manager      manager,
  268.                       FTC_ImageCache  *acache )
  269.   {
  270.     return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
  271.                            (FTC_GCache*)acache );
  272.   }
  273.  
  274.  
  275.   /* documentation is in ftcache.h */
  276.  
  277.   FT_EXPORT_DEF( FT_Error )
  278.   FTC_ImageCache_Lookup( FTC_ImageCache  cache,
  279.                          FTC_ImageType   type,
  280.                          FT_UInt         gindex,
  281.                          FT_Glyph       *aglyph,
  282.                          FTC_Node       *anode )
  283.   {
  284.     FTC_BasicQueryRec  query;
  285.     FTC_Node           node = 0; /* make compiler happy */
  286.     FT_Error           error;
  287.     FT_PtrDist         hash;
  288.  
  289.  
  290.     /* some argument checks are delayed to FTC_Cache_Lookup */
  291.     if ( !aglyph )
  292.     {
  293.       error = FT_THROW( Invalid_Argument );
  294.       goto Exit;
  295.     }
  296.  
  297.     *aglyph = NULL;
  298.     if ( anode )
  299.       *anode  = NULL;
  300.  
  301.     {
  302.       if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
  303.       {
  304.         FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
  305.         FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
  306.       }
  307.  
  308.       query.attrs.scaler.face_id = type->face_id;
  309.       query.attrs.scaler.width   = type->width;
  310.       query.attrs.scaler.height  = type->height;
  311.       query.attrs.load_flags     = (FT_UInt)type->flags;
  312.     }
  313.  
  314.     query.attrs.scaler.pixel = 1;
  315.     query.attrs.scaler.x_res = 0;  /* make compilers happy */
  316.     query.attrs.scaler.y_res = 0;
  317.  
  318.     hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
  319.  
  320. #if 1  /* inlining is about 50% faster! */
  321.     FTC_GCACHE_LOOKUP_CMP( cache,
  322.                            ftc_basic_family_compare,
  323.                            FTC_GNode_Compare,
  324.                            hash, gindex,
  325.                            &query,
  326.                            node,
  327.                            error );
  328. #else
  329.     error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
  330.                                hash, gindex,
  331.                                FTC_GQUERY( &query ),
  332.                                &node );
  333. #endif
  334.     if ( !error )
  335.     {
  336.       *aglyph = FTC_INODE( node )->glyph;
  337.  
  338.       if ( anode )
  339.       {
  340.         *anode = node;
  341.         node->ref_count++;
  342.       }
  343.     }
  344.  
  345.   Exit:
  346.     return error;
  347.   }
  348.  
  349.  
  350.   /* documentation is in ftcache.h */
  351.  
  352.   FT_EXPORT_DEF( FT_Error )
  353.   FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,
  354.                                FTC_Scaler      scaler,
  355.                                FT_ULong        load_flags,
  356.                                FT_UInt         gindex,
  357.                                FT_Glyph       *aglyph,
  358.                                FTC_Node       *anode )
  359.   {
  360.     FTC_BasicQueryRec  query;
  361.     FTC_Node           node = 0; /* make compiler happy */
  362.     FT_Error           error;
  363.     FT_PtrDist         hash;
  364.  
  365.  
  366.     /* some argument checks are delayed to FTC_Cache_Lookup */
  367.     if ( !aglyph || !scaler )
  368.     {
  369.       error = FT_THROW( Invalid_Argument );
  370.       goto Exit;
  371.     }
  372.  
  373.     *aglyph = NULL;
  374.     if ( anode )
  375.       *anode  = NULL;
  376.  
  377.     /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
  378.     if ( load_flags > FT_UINT_MAX )
  379.     {
  380.       FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
  381.       FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
  382.     }
  383.  
  384.     query.attrs.scaler     = scaler[0];
  385.     query.attrs.load_flags = (FT_UInt)load_flags;
  386.  
  387.     hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
  388.  
  389.     FTC_GCACHE_LOOKUP_CMP( cache,
  390.                            ftc_basic_family_compare,
  391.                            FTC_GNode_Compare,
  392.                            hash, gindex,
  393.                            &query,
  394.                            node,
  395.                            error );
  396.     if ( !error )
  397.     {
  398.       *aglyph = FTC_INODE( node )->glyph;
  399.  
  400.       if ( anode )
  401.       {
  402.         *anode = node;
  403.         node->ref_count++;
  404.       }
  405.     }
  406.  
  407.   Exit:
  408.     return error;
  409.   }
  410.  
  411.  
  412.   /*
  413.    *
  414.    * basic small bitmap cache
  415.    *
  416.    */
  417.  
  418.   FT_CALLBACK_TABLE_DEF
  419.   const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
  420.   {
  421.     {
  422.       sizeof ( FTC_BasicFamilyRec ),
  423.       ftc_basic_family_compare,
  424.       ftc_basic_family_init,
  425.       0,                            /* FTC_MruNode_ResetFunc */
  426.       0                             /* FTC_MruNode_DoneFunc  */
  427.     },
  428.     ftc_basic_family_get_count,
  429.     ftc_basic_family_load_bitmap
  430.   };
  431.  
  432.  
  433.   FT_CALLBACK_TABLE_DEF
  434.   const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
  435.   {
  436.     {
  437.       ftc_snode_new,
  438.       ftc_snode_weight,
  439.       ftc_snode_compare,
  440.       ftc_basic_gnode_compare_faceid,
  441.       ftc_snode_free,
  442.  
  443.       sizeof ( FTC_GCacheRec ),
  444.       ftc_gcache_init,
  445.       ftc_gcache_done
  446.     },
  447.     (FTC_MruListClass)&ftc_basic_sbit_family_class
  448.   };
  449.  
  450.  
  451.   /* documentation is in ftcache.h */
  452.  
  453.   FT_EXPORT_DEF( FT_Error )
  454.   FTC_SBitCache_New( FTC_Manager     manager,
  455.                      FTC_SBitCache  *acache )
  456.   {
  457.     return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
  458.                            (FTC_GCache*)acache );
  459.   }
  460.  
  461.  
  462.   /* documentation is in ftcache.h */
  463.  
  464.   FT_EXPORT_DEF( FT_Error )
  465.   FTC_SBitCache_Lookup( FTC_SBitCache  cache,
  466.                         FTC_ImageType  type,
  467.                         FT_UInt        gindex,
  468.                         FTC_SBit      *ansbit,
  469.                         FTC_Node      *anode )
  470.   {
  471.     FT_Error           error;
  472.     FTC_BasicQueryRec  query;
  473.     FTC_Node           node = 0; /* make compiler happy */
  474.     FT_PtrDist         hash;
  475.  
  476.  
  477.     if ( anode )
  478.       *anode = NULL;
  479.  
  480.     /* other argument checks delayed to FTC_Cache_Lookup */
  481.     if ( !ansbit )
  482.       return FT_THROW( Invalid_Argument );
  483.  
  484.     *ansbit = NULL;
  485.  
  486.     {
  487.       if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
  488.       {
  489.         FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
  490.         FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
  491.       }
  492.  
  493.       query.attrs.scaler.face_id = type->face_id;
  494.       query.attrs.scaler.width   = type->width;
  495.       query.attrs.scaler.height  = type->height;
  496.       query.attrs.load_flags     = (FT_UInt)type->flags;
  497.     }
  498.  
  499.     query.attrs.scaler.pixel = 1;
  500.     query.attrs.scaler.x_res = 0;  /* make compilers happy */
  501.     query.attrs.scaler.y_res = 0;
  502.  
  503.     /* beware, the hash must be the same for all glyph ranges! */
  504.     hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
  505.            gindex / FTC_SBIT_ITEMS_PER_NODE;
  506.  
  507. #if 1  /* inlining is about 50% faster! */
  508.     FTC_GCACHE_LOOKUP_CMP( cache,
  509.                            ftc_basic_family_compare,
  510.                            FTC_SNode_Compare,
  511.                            hash, gindex,
  512.                            &query,
  513.                            node,
  514.                            error );
  515. #else
  516.     error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
  517.                                hash,
  518.                                gindex,
  519.                                FTC_GQUERY( &query ),
  520.                                &node );
  521. #endif
  522.     if ( error )
  523.       goto Exit;
  524.  
  525.     *ansbit = FTC_SNODE( node )->sbits +
  526.               ( gindex - FTC_GNODE( node )->gindex );
  527.  
  528.     if ( anode )
  529.     {
  530.       *anode = node;
  531.       node->ref_count++;
  532.     }
  533.  
  534.   Exit:
  535.     return error;
  536.   }
  537.  
  538.  
  539.   /* documentation is in ftcache.h */
  540.  
  541.   FT_EXPORT_DEF( FT_Error )
  542.   FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
  543.                               FTC_Scaler     scaler,
  544.                               FT_ULong       load_flags,
  545.                               FT_UInt        gindex,
  546.                               FTC_SBit      *ansbit,
  547.                               FTC_Node      *anode )
  548.   {
  549.     FT_Error           error;
  550.     FTC_BasicQueryRec  query;
  551.     FTC_Node           node = 0; /* make compiler happy */
  552.     FT_PtrDist         hash;
  553.  
  554.  
  555.     if ( anode )
  556.         *anode = NULL;
  557.  
  558.     /* other argument checks delayed to FTC_Cache_Lookup */
  559.     if ( !ansbit || !scaler )
  560.         return FT_THROW( Invalid_Argument );
  561.  
  562.     *ansbit = NULL;
  563.  
  564.     /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
  565.     if ( load_flags > FT_UINT_MAX )
  566.     {
  567.       FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
  568.       FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
  569.     }
  570.  
  571.     query.attrs.scaler     = scaler[0];
  572.     query.attrs.load_flags = (FT_UInt)load_flags;
  573.  
  574.     /* beware, the hash must be the same for all glyph ranges! */
  575.     hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
  576.              gindex / FTC_SBIT_ITEMS_PER_NODE;
  577.  
  578.     FTC_GCACHE_LOOKUP_CMP( cache,
  579.                            ftc_basic_family_compare,
  580.                            FTC_SNode_Compare,
  581.                            hash, gindex,
  582.                            &query,
  583.                            node,
  584.                            error );
  585.     if ( error )
  586.       goto Exit;
  587.  
  588.     *ansbit = FTC_SNODE( node )->sbits +
  589.               ( gindex - FTC_GNODE( node )->gindex );
  590.  
  591.     if ( anode )
  592.     {
  593.       *anode = node;
  594.       node->ref_count++;
  595.     }
  596.  
  597.   Exit:
  598.     return error;
  599.   }
  600.  
  601.  
  602. /* END */
  603.