home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / ft-beta.zip / freetype / lib / ttapi.c < prev    next >
C/C++ Source or Header  |  1997-10-06  |  32KB  |  1,156 lines

  1. /*******************************************************************
  2.  *
  3.  *  ttapi.c    
  4.  *
  5.  *    High-level interface implementation
  6.  *
  7.  *  Copyright 1996, 1997 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.  *  Notes:
  17.  *
  18.  *    This file implements most of the features of the high-level
  19.  *    interface. Note however that the character mapping tables
  20.  *    functions ( TT_Get_CharMap and TT_Char_Index ) are all located
  21.  *    in the 'ttindex.c' source file.
  22.  *
  23.  ******************************************************************/
  24.  
  25. #include "freetype.h"
  26. #include "ttcommon.h"
  27. #include "ttengine.h"
  28. #include "ttcalc.h"
  29. #include "ttmemory.h"
  30. #include "ttcache.h"
  31. #include "ttfile.h"
  32. #include "ttobjs.h"
  33. #include "ttload.h"
  34. #include "ttgload.h"
  35. #include "ttraster.h"
  36.  
  37. #ifdef TT_EXTEND_ENGINE
  38. #include "extend/ttextend.h"
  39. #endif
  40.  
  41.   #ifndef TT_CONFIG_REENTRANT
  42.     TEngine_Instance  engine;
  43.   #endif
  44.  
  45.   #ifdef TT_STATIC_RASTER
  46.  
  47.     #define  RAS_OPS   /* void */
  48.     #define  RAS_OP    /* void */
  49.  
  50.   #else
  51.  
  52.     #define  RAS_OPS   ((TRaster_Instance*)engine.raster_component),
  53.     #define  RAS_OP    ((TRaster_Instance*)engine.raster_component)
  54.  
  55.   #endif /* TT_STATIC_RASTER */
  56.   
  57.  
  58.  
  59.   #define RENDER_Glyph(glyph,target) \
  60.             Render_Glyph( RAS_OPS  glyph, target )
  61.  
  62.   #define RENDER_Gray_Glyph(glyph,target,palette) \
  63.             Render_Gray_Glyph( RAS_OPS  glyph, target, palette )
  64.  
  65.   #define SET_High_Precision( high ) \
  66.             Set_High_Precision( RAS_OPS  high )
  67.  
  68.   #define SET_Second_Pass( pass )  \
  69.             Set_Second_Pass( RAS_OPS  pass )
  70.  
  71. /*******************************************************************
  72.  *
  73.  *  Function    : TT_Init_FreeType
  74.  *
  75.  *  Description : The library's engine initializer. This function
  76.  *                must be called prior to any call.
  77.  *
  78.  *  Input  :  None
  79.  *
  80.  *  Output :  Error code.
  81.  *
  82.  ******************************************************************/
  83.  
  84.   TT_Error  TT_Init_FreeType()
  85.   {
  86.     TT_Error  error;
  87.     int       n;
  88.  
  89.     /* Initalize components */
  90.     if ( (error = TTMemory_Init())  ||
  91.          (error = TTLists_Init ())  ||
  92.          (error = TTFile_Init  ())  ||
  93.          (error = TTObjs_Init  ())  ||
  94.          (error = TTRaster_Init())  )
  95.       return error;
  96.  
  97.     /* set the gray palette defaults : 0 to 4 */
  98.     for ( n = 0; n < 5; n++ )
  99.        engine.raster_palette[n] = n;
  100.  
  101.     /* Initialize extensions component if needed */
  102.     #ifdef TT_EXTEND_ENGINE
  103.     if ( (error = TTExtension_Init()) )
  104.       return error;
  105.     #endif
  106.  
  107.     /* create the engine lock */
  108.     MUTEX_Create( engine.lock );
  109.  
  110.     SET_Second_Pass(1);
  111.  
  112.     return TT_Err_Ok;
  113.   }
  114.  
  115. /*******************************************************************
  116.  *
  117.  *  Function    : TT_Done_FreeType
  118.  *
  119.  *  Description : The library's engine finalizer. This function
  120.  *                will discard all active face and glyph objects
  121.  *                from the heap.
  122.  *
  123.  *  Input  :  None
  124.  *
  125.  *  Output :  Error code.
  126.  *
  127.  ******************************************************************/
  128.  
  129.   TT_Error  TT_Done_FreeType()
  130.   {
  131.     MUTEX_Destroy( engine.lock );
  132.  
  133.     #ifdef TT_EXTEND_ENGINE
  134.     TTExtension_Done();
  135.     #endif
  136.  
  137.     TTRaster_Done();
  138.     TTObjs_Done  ();
  139.     TTFile_Done  ();
  140.     TTLists_Done ();
  141.     TTMemory_Done();
  142.  
  143.     return TT_Err_Ok;
  144.   }
  145.  
  146. /*******************************************************************
  147.  *
  148.  *  Function    :  TT_Set_Raster_Gray_Palette
  149.  *
  150.  *  Description :  set the gray-levels palette used for font
  151.  *                 smoothing.
  152.  *
  153.  *  Input  :  palette   address of palette ( a 5 bytes array )
  154.  *
  155.  *  Output :  invalid argument if 'palette' is NULL
  156.  *
  157.  ******************************************************************/
  158.  
  159.   TT_Error  TT_Set_Raster_Gray_Palette( char* palette )
  160.   {  
  161.     int i;
  162.  
  163.     if (!palette)
  164.       return TT_Err_Invalid_Argument;
  165.  
  166.     for (i = 0; i < 5; i++)
  167.       engine.raster_palette[i] = palette[i];
  168.  
  169.     return TT_Err_Ok;
  170.   }
  171.  
  172.  
  173. /*******************************************************************
  174.  *
  175.  *  Function    :  TT_Open_Face
  176.  *
  177.  *  Description :  Create a new face object from a given font file
  178.  *
  179.  *  Input  :  fontpathname    the font file's pathname
  180.  *            face            adress of returned face handle
  181.  *
  182.  *  Output :  Error code.
  183.  *
  184.  *  Note : the face handle is set to NULL in case of failure.
  185.  *
  186.  ******************************************************************/
  187.  
  188.   TT_Error  TT_Open_Face( const char*  fontpathname,
  189.                           TT_Face*     face )
  190.   {
  191.     TFont_Input  input;
  192.     TT_Error     error;
  193.     TT_Stream    stream;
  194.     PFace        _face;
  195.  
  196.     /* open the file */
  197.     error = TT_Open_Stream( fontpathname, &stream );
  198.     if (error)
  199.       return error;
  200.  
  201.     input.stream    = stream;
  202.     input.fontIndex = 0;
  203.  
  204.     /* Create and load the new face object */
  205.     error = CACHE_New( engine.objs_face_cache,
  206.                        _face,
  207.                        &input );
  208.  
  209.     /* Set the handle */
  210.     HANDLE_Set( *face, _face );
  211.  
  212.     if (error)
  213.       goto Fail;
  214.  
  215.     return TT_Err_Ok;
  216.  
  217.   Fail:
  218.     TT_Close_Stream( &stream );
  219.     return error;
  220.   }
  221.  
  222. /*******************************************************************
  223.  *
  224.  *  Function    :  TT_Open_Collection
  225.  *
  226.  *  Description :  Create a new face object from a given font file
  227.  *
  228.  *  Input  :  fontpathname    the font file's pathname
  229.  *            face            adress of returned face handle
  230.  *
  231.  *  Output :  Error code.
  232.  *
  233.  *  Note : the face handle is set to NULL in case of failure.
  234.  *
  235.  ******************************************************************/
  236.  
  237.   TT_Error  TT_Open_Collection( const char*  collectionpathname,
  238.                                 int          fontIndex,
  239.                                 TT_Face*     face )
  240.   {
  241.     TFont_Input  input;
  242.     TT_Error     error;
  243.     TT_Stream    stream;
  244.     PFace        _face;
  245.  
  246.     /* open the file */
  247.     error = TT_Open_Stream( collectionpathname, &stream );
  248.     if (error)
  249.       return error;
  250.  
  251.     input.stream    = stream;
  252.     input.fontIndex = fontIndex;
  253.  
  254.     /* Create and load the new face object */
  255.     error = CACHE_New( engine.objs_face_cache,
  256.                        _face,
  257.                        &input );
  258.  
  259.     /* Set the handle */
  260.     HANDLE_Set( *face, _face );
  261.  
  262.     if (error)
  263.       goto Fail;
  264.  
  265.     return TT_Err_Ok;
  266.  
  267.   Fail:
  268.     TT_Close_Stream( &stream );
  269.     return error;
  270.   }
  271.  
  272.  
  273. /*******************************************************************
  274.  *
  275.  *  Function    :  TT_Get_Face_Properties
  276.  *
  277.  *  Description :  Return face properties
  278.  *
  279.  *  Input  :  face        the face handle
  280.  *            properties  address of target properties record
  281.  *
  282.  *  Output :  Error code.
  283.  *
  284.  *  Note : Currently, max_Faces is always set to 0
  285.  *
  286.  ******************************************************************/
  287.  
  288.   TT_Error  TT_Get_Face_Properties( TT_Face              face,
  289.                                     TT_Face_Properties*  properties )
  290.   {
  291.     PFace _face = HANDLE_Face(face);
  292.  
  293.     if (!_face)
  294.       return TT_Err_Invalid_Face_Handle;
  295.  
  296.     properties->num_Glyphs   = _face->numGlyphs;
  297.     properties->max_Points   = _face->maxPoints;
  298.     properties->max_Contours = _face->maxContours;
  299.  
  300.     properties->max_Faces    = 0;
  301.  
  302.     properties->header     = &_face->fontHeader;
  303.     properties->horizontal = &_face->horizontalHeader;
  304.     properties->os2        = &_face->os2;
  305.     properties->postscript = &_face->postscript;
  306.  
  307.     return TT_Err_Ok;
  308.   }
  309.  
  310. /*******************************************************************
  311.  *
  312.  *  Function    :  TT_Close_Face
  313.  *
  314.  *  Description :  Closing an opened face object. This function
  315.  *                 will destroyed all objects associated to the
  316.  *                 face, except the glyphs.
  317.  *
  318.  *  Input  :  face    the given face handle
  319.  *
  320.  *  Output :  Error code.
  321.  *
  322.  *  NOTE   :  the handle is set to NULL on exit
  323.  *
  324.  ******************************************************************/
  325.  
  326.   TT_Error  TT_Close_Face( TT_Face  face )
  327.   {
  328.     PFace  _face = HANDLE_Face(face);
  329.  
  330.     if (!_face)
  331.       return TT_Err_Invalid_Face_Handle;
  332.  
  333.     return CACHE_Done( engine.objs_face_cache, _face );
  334.   }
  335.  
  336. /*******************************************************************
  337.  *
  338.  *  Function    :  TT_New_Instance
  339.  *
  340.  *  Description :  Create a new instance from a given face
  341.  *
  342.  *  Input  :  face        parent face handle
  343.  *            instance    address of resimt instance handle
  344.  *            resolution  device resolution in dpi
  345.  *            pointsize   point size
  346.  *
  347.  *  Output :  Error code.
  348.  *
  349.  *  Note   :  the handle is set to NULL in case of failure
  350.  *
  351.  ******************************************************************/
  352.  
  353.   TT_Error  TT_New_Instance( TT_Face       face,
  354.                              TT_Instance*  instance )
  355.   {
  356.     TT_Error   error;
  357.     PFace      _face = HANDLE_Face(face);
  358.     PInstance  _ins;
  359.  
  360.     if (!_face)
  361.       return TT_Err_Invalid_Face_Handle;
  362.  
  363.     /* get a new instance from the face's cache */
  364.     error = CACHE_New( &_face->instances, _ins, _face );
  365.  
  366.     HANDLE_Set( *instance, _ins );
  367.  
  368.     if (!error)
  369.     {
  370.       error = Instance_Init( _ins );
  371.       if (error)
  372.       {
  373.         HANDLE_Set( *instance, NULL );
  374.         CACHE_Done( &_face->instances, _ins );
  375.       }
  376.     }
  377.  
  378.     return error;
  379.   }
  380.  
  381. /*******************************************************************
  382.  *
  383.  *  Function    :  TT_Set_Instance_Resolution
  384.  *
  385.  *  Description :  Resets an instance to new device resolutions
  386.  *
  387.  *  Input  :  instance      the instance handle
  388.  *            x_resolution  new horizontal device resolution in dpi
  389.  *            y_resolution  new vertical device resolution in dpi
  390.  *
  391.  *  Output :  Error code.
  392.  *
  393.  *  NOTE : y_resolution is currently ignored
  394.  *
  395.  ******************************************************************/
  396.  
  397.   TT_Error  TT_Set_Instance_Resolution( TT_Instance  instance,
  398.                                         int          x_resolution,
  399.                                         int          y_resolution )
  400.   {
  401.     PInstance  ins = HANDLE_Instance(instance);
  402.  
  403.     if (!ins)
  404.       return TT_Err_Invalid_Instance_Handle;
  405.  
  406.     ins->metrics.x_resolution = x_resolution;
  407.     ins->metrics.y_resolution = y_resolution;
  408.     ins->valid                = FALSE;
  409.  
  410.     return TT_Err_Ok;
  411.   }
  412.  
  413. /*******************************************************************
  414.  *
  415.  *  Function    :  TT_Set_Instance_PointSize
  416.  *
  417.  *  Description :  Resets an instance to new pointsize
  418.  *
  419.  *  Input  :  instance      the instance handle
  420.  *            pointsize     new pointsize
  421.  *
  422.  *  Output :  Error code.
  423.  *
  424.  *  NOTE : y_resolution is currently ignored
  425.  *
  426.  ******************************************************************/
  427.  
  428.   TT_Error  TT_Set_Instance_PointSize( TT_Instance  instance,
  429.                                        int          pointsize )
  430.   {
  431.     PInstance  ins = HANDLE_Instance(instance);
  432.  
  433.     if (!ins)
  434.       return TT_Err_Invalid_Instance_Handle;
  435.  
  436.     ins->metrics.pointSize = pointsize * 64;
  437.     ins->valid             = FALSE;
  438.  
  439.     return TT_Err_Ok;
  440.   }
  441.  
  442. /*******************************************************************
  443.  *
  444.  *  Function    :  TT_Set_Instance_Transforms
  445.  *
  446.  *  Description :  Notice the interpreter about the transforms
  447.  *                 that will be applied to the rendered glyphs
  448.  *
  449.  *  Input  :  instance      the instance handle
  450.  *            rotated       set to TRUE if the glyph are rotated
  451.  *            stretched     set to TRUE if the glyph are stretched
  452.  *
  453.  *  Output :  Error code.
  454.  *
  455.  *  NOTE : y_resolution is currently ignored
  456.  *
  457.  ******************************************************************/
  458.  
  459.   TT_Error  TT_Set_Instance_Transforms( TT_Instance instance,
  460.                     int         rotated,
  461.                     int         stretched )
  462.   {
  463.     PInstance  ins = HANDLE_Instance(instance);
  464.  
  465.     if (!ins)
  466.       return TT_Err_Invalid_Instance_Handle;
  467.  
  468.     ins->metrics.rotated   = rotated;
  469.     ins->metrics.stretched = stretched;
  470.  
  471.     return TT_Err_Ok;
  472.   }
  473.  
  474. /*******************************************************************
  475.  *
  476.  *  Function    :  TT_Get_Instance_Metrics
  477.  *
  478.  *  Description :  returns instance metrics
  479.  *
  480.  *  Input  :  instance   the instance handle.
  481.  *            metrics    address of target instance metrics record
  482.  *
  483.  *  Output :  Error code.
  484.  *
  485.  ******************************************************************/
  486.  
  487.   TT_Error  TT_Get_Instance_Metrics( TT_Instance           instance,
  488.                                      TT_Instance_Metrics*  metrics )
  489.   {
  490.     PInstance  ins = HANDLE_Instance(instance);
  491.  
  492.     if (!ins)
  493.      return TT_Err_Invalid_Instance_Handle;
  494.  
  495.     if (!ins->valid)
  496.       Instance_Reset( ins, FALSE );
  497.  
  498.     metrics->pointSize    = ins->metrics.pointSize;
  499.     metrics->x_resolution = ins->metrics.x_resolution;
  500.     metrics->y_resolution = ins->metrics.y_resolution;
  501.     metrics->x_ppem       = ins->metrics.x_ppem;
  502.     metrics->y_ppem       = ins->metrics.y_ppem;
  503.  
  504.     return TT_Err_Ok;
  505.   }
  506.  
  507. /*******************************************************************
  508.  *
  509.  *  Function    :  TT_Done_Instance
  510.  *
  511.  *  Description :  Closes a given instance
  512.  *
  513.  *  Input  :  instance   address of instance handle.
  514.  *
  515.  *  Output :  Error code.
  516.  *
  517.  ******************************************************************/
  518.  
  519.   TT_Error  TT_Done_Instance( TT_Instance  instance )
  520.   {
  521.     PInstance  ins = HANDLE_Instance(instance);
  522.  
  523.     if (!ins)
  524.       return TT_Err_Invalid_Instance_Handle;
  525.  
  526.     return CACHE_Done( &ins->owner->instances, ins );
  527.   }
  528.  
  529. /*******************************************************************
  530.  *
  531.  *  Function    :  TT_New_Glyph
  532.  *
  533.  *  Description :  Creates a new glyph object related to a given
  534.  *                 face.
  535.  *
  536.  *  Input  :  face       the face handle
  537.  *            glyph      address of target glyph handle
  538.  *
  539.  *  Output :  Error code.
  540.  *
  541.  ******************************************************************/
  542.  
  543.   TT_Error  TT_New_Glyph( TT_Face   face,
  544.                           TT_Glyph* glyph )
  545.   {
  546.     TT_Error  error;
  547.     PFace     _face = HANDLE_Face(face);
  548.     PGlyph    _glyph;
  549.  
  550.     if (!_face)
  551.       return TT_Err_Invalid_Face_Handle;
  552.  
  553.     error = CACHE_New( engine.objs_glyph_cache, _glyph, _face );
  554.  
  555.     HANDLE_Set( *glyph, _glyph );
  556.  
  557.     return error;
  558.   }
  559.  
  560. /*******************************************************************
  561.  *
  562.  *  Function    :  TT_Done_Glyph
  563.  *
  564.  *  Description :  Destroys a given glyph object
  565.  *
  566.  *  Input  :  glyph  the glyph handle
  567.  *
  568.  *  Output :  Error code.
  569.  *
  570.  ******************************************************************/
  571.  
  572.   TT_Error  TT_Done_Glyph( TT_Glyph  glyph )
  573.   {
  574.     PGlyph  _glyph = HANDLE_Glyph(glyph);
  575.  
  576.     if (!_glyph)
  577.       return TT_Err_Invalid_Glyph_Handle;
  578.  
  579.     return CACHE_Done( engine.objs_glyph_cache, _glyph );
  580.   }
  581.  
  582. /*******************************************************************
  583.  *
  584.  *  Function    :  TT_Load_Glyph
  585.  *
  586.  *  Description :  Load a glyph
  587.  *
  588.  *  Input  :  None
  589.  *
  590.  *  Output :  Error code.
  591.  *
  592.  ******************************************************************/
  593.  
  594.   TT_Error  TT_Load_Glyph( TT_Instance  instance,
  595.                            TT_Glyph     glyph,
  596.                            int          glyph_index,
  597.                            int          load_flags   )
  598.   {
  599.     PInstance  _ins;
  600.     PGlyph     _glyph;
  601.     TT_Error   error;
  602.  
  603.     _ins = HANDLE_Instance(instance);
  604.     if (!_ins)
  605.       return TT_Err_Invalid_Instance_Handle;
  606.  
  607.     _glyph = HANDLE_Glyph(glyph);
  608.     if (!_glyph)
  609.       return TT_Err_Invalid_Glyph_Handle;
  610.  
  611.     if ( _ins->owner != _glyph->face )
  612.       return TT_Err_Invalid_Face_Handle;
  613.  
  614.     if ( !_ins->valid )
  615.     {
  616.       error = Instance_Reset( _ins, FALSE );
  617.       if (error)
  618.         return error;
  619.     }
  620.  
  621.     return Load_TrueType_Glyph( _ins, _glyph, glyph_index, load_flags );
  622.   }
  623.  
  624. /*******************************************************************
  625.  *
  626.  *  Function    :  TT_Get_Glyph_Outline
  627.  *
  628.  *  Description :
  629.  *
  630.  *  Input  :  None
  631.  *
  632.  *  Output :  Error code.
  633.  *
  634.  ******************************************************************/
  635.  
  636.   void  Glyph2Outline( PGlyph  glyph, TT_Glyph_Outline*  outline )
  637.   {
  638.     outline->points   = glyph->num_points;
  639.     outline->contours = glyph->num_contours;
  640.  
  641.     outline->xCoord    = glyph->x_coord;
  642.     outline->yCoord    = glyph->y_coord;
  643.     outline->flag      = glyph->touch;
  644.     outline->conStarts = glyph->endContours;
  645.   }
  646.  
  647.   TT_Error  TT_Get_Glyph_Outline( TT_Glyph           glyph,
  648.                                   TT_Glyph_Outline*  outline )
  649.   {
  650.     PGlyph  _glyph = HANDLE_Glyph(glyph);
  651.  
  652.     if (!_glyph)
  653.       return TT_Err_Invalid_Glyph_Handle;
  654.  
  655.     Glyph2Outline( _glyph, outline );
  656.  
  657.     return TT_Err_Ok;
  658.   }
  659.  
  660. /*******************************************************************
  661.  *
  662.  *  Function    :  TT_Get_Glyph_Metrics
  663.  *
  664.  *  Description :
  665.  *
  666.  *  Input  :  None
  667.  *
  668.  *  Output :  Error code.
  669.  *
  670.  ******************************************************************/
  671.  
  672.   TT_Error  TT_Get_Glyph_Metrics( TT_Glyph           glyph,
  673.                                   TT_Glyph_Metrics*  metrics )
  674.   {
  675.     PGlyph  _glyph = HANDLE_Glyph(glyph);
  676.  
  677.     if (!_glyph)
  678.       return TT_Err_Invalid_Glyph_Handle;
  679.  
  680.     metrics->xMin = _glyph->xMin;
  681.     metrics->xMax = _glyph->xMax;
  682.     metrics->yMin = _glyph->yMin;
  683.     metrics->yMax = _glyph->yMax;
  684.  
  685.     metrics->advanceWidth    = _glyph->advanceWidth;
  686.     metrics->leftSideBearing = _glyph->leftSideBearing;
  687.  
  688.     return TT_Err_Ok;
  689.   }
  690.  
  691. /*******************************************************************
  692.  *
  693.  *  Function    :  TT_Get_Glyph_Bitmap
  694.  *
  695.  *  Description :  Produce a bitmap from a glyph outline.
  696.  *
  697.  *  Input  :  glyph      the glyph container's handle
  698.  *            map        target pixmap description block
  699.  *            x_offset   x_offset in fractional pixels ( 26.6 format )
  700.  *            y_offset   y_offset in fractional pixels ( 26.6 format )
  701.  *
  702.  *  Output :  Error code.
  703.  *
  704.  *  Note : Only use integer pixel offsets if you want to preserve
  705.  *         the fine hints applied to the outline. This means that
  706.  *         x_offset and y_offset must be multiples of 64 !
  707.  *
  708.  ******************************************************************/
  709.  
  710.   TT_Error  TT_Get_Glyph_Bitmap( TT_Glyph        glyph,
  711.                                  TT_Raster_Map*  map,
  712.                                  TT_F26Dot6      x_offset,
  713.                                  TT_F26Dot6      y_offset )
  714.   {
  715.     TT_Error  error;
  716.     PGlyph    _glyph = HANDLE_Glyph(glyph);
  717.     Int       i;
  718.  
  719.     TT_Glyph_Outline  outline;
  720.  
  721.     if (!_glyph)
  722.       return TT_Err_Invalid_Glyph_Handle;
  723.  
  724.     x_offset -= 32;
  725.     y_offset -= 32;
  726.  
  727.     if (x_offset)
  728.       for ( i = 0; i < _glyph->num_points; i++ )
  729.         _glyph->x_coord[i] += x_offset;
  730.  
  731.     if (y_offset)
  732.       for ( i = 0; i < _glyph->num_points; i++ )
  733.         _glyph->y_coord[i] += y_offset;
  734.  
  735.     Glyph2Outline( _glyph, &outline );
  736.  
  737.     SET_High_Precision( _glyph->high_precision );
  738.  
  739.     /*  outline.dropout_mode = _glyph->scan_type; */
  740.     outline.dropout_mode = 2;
  741.  
  742.     error = RENDER_Glyph( &outline, map );
  743.  
  744.     if (x_offset)
  745.       for ( i = 0; i < _glyph->num_points; i++ )
  746.         _glyph->x_coord[i] -= x_offset;
  747.  
  748.     if (y_offset)
  749.       for ( i = 0; i < _glyph->num_points; i++ )
  750.         _glyph->y_coord[i] -= y_offset;
  751.  
  752.     return error;
  753.   }
  754.  
  755. /*******************************************************************
  756.  *
  757.  *  Function    :  TT_Get_Glyph_Pixmap
  758.  *
  759.  *  Description :  Produce a grayscaled pixmap from a glyph
  760.  *                 outline.
  761.  *
  762.  *  Input  :  glyph      the glyph container's handle
  763.  *            map        target pixmap description block
  764.  *            x_offset   x_offset in fractional pixels ( 26.6 format )
  765.  *            y_offset   y_offset in fractional pixels ( 26.6 format )
  766.  *
  767.  *  Output :  Error code.
  768.  *
  769.  *  Note : Only use integer pixel offsets to preserve the fine
  770.  *         hinting of the glyph, and the 'correct' anti-aliasing
  771.  *         ( where vertical and horizontal stems aren't grayed ).
  772.  *         This means that x_offset and y_offset must be multiples
  773.  *         of 64 !
  774.  *
  775.  *         You can experiment with offsets of +32 to get 'blurred'
  776.  *         versions of the glyphs (a nice effect at large sizes that
  777.  *         some graphists may appreciate :)
  778.  *
  779.  ******************************************************************/
  780.  
  781.   TT_Error  TT_Get_Glyph_Pixmap( TT_Glyph        glyph,
  782.                                  TT_Raster_Map*  map,
  783.                                  TT_F26Dot6      x_offset,
  784.                                  TT_F26Dot6      y_offset )
  785.   {
  786.     TT_Error  error;
  787.     PGlyph    _glyph = HANDLE_Glyph(glyph);
  788.     Int       i;
  789.  
  790.     TT_Glyph_Outline  outline;
  791.  
  792.     if (!_glyph)
  793.       return TT_Err_Invalid_Glyph_Handle;
  794.  
  795.     x_offset -= 16;
  796.     y_offset -= 16;
  797.  
  798.     for ( i = 0; i < _glyph->num_points; i++ )
  799.       _glyph->x_coord[i] = (_glyph->x_coord[i] + x_offset) << 1;
  800.  
  801.     for ( i = 0; i < _glyph->num_points; i++ )
  802.       _glyph->y_coord[i] = (_glyph->y_coord[i] + y_offset) << 1;
  803.  
  804.     Glyph2Outline( _glyph, &outline );
  805.  
  806.     SET_High_Precision( _glyph->high_precision );
  807.  
  808.     /* outline.dropout_mode = _glyph->scan_type; */
  809.     outline.dropout_mode = 2;
  810.  
  811.     error = RENDER_Gray_Glyph( &outline, 
  812.                                map, 
  813.                                engine.raster_palette );
  814.  
  815.     for ( i = 0; i < _glyph->num_points; i++ )
  816.       _glyph->x_coord[i] = (_glyph->x_coord[i] >> 1) - x_offset;
  817.  
  818.     for ( i = 0; i < _glyph->num_points; i++ )
  819.       _glyph->y_coord[i] = (_glyph->y_coord[i] >> 1) - y_offset;
  820.  
  821.     return error;
  822.   }
  823.  
  824. /*******************************************************************
  825.  *
  826.  *  Function    :  TT_Apply_Outline_Matrix
  827.  *
  828.  *  Description :  Apply a simple transform to an outline
  829.  *
  830.  *  Input  :  outline     the glyph's outline. Can be extracted
  831.  *                        from a glyph container through TT_Get_Glyph_Outline
  832.  *
  833.  *            matrix      simple matrix with 16.16 fixed floats
  834.  *
  835.  *  Output :  Error code. (always TT_Err_Ok)
  836.  *
  837.  ******************************************************************/
  838.  
  839.   TT_Error  TT_Apply_Outline_Matrix( TT_Glyph_Outline*  outline,
  840.                                      TT_Matrix*         matrix )
  841.   {
  842.     Int n;
  843.     TT_F26Dot6  x, y;
  844.  
  845.     for ( n = 0; n < outline->points; n++ )
  846.     {
  847.       x = MulDiv_Round( outline->xCoord[n], matrix->xx, 0x10000 ) +
  848.       MulDiv_Round( outline->yCoord[n], matrix->xy, 0x10000 );
  849.  
  850.       y = MulDiv_Round( outline->xCoord[n], matrix->yx, 0x10000 ) +
  851.       MulDiv_Round( outline->yCoord[n], matrix->yy, 0x10000 );
  852.  
  853.       outline->xCoord[n] = x;
  854.       outline->yCoord[n] = y;
  855.     }
  856.  
  857.     return TT_Err_Ok;
  858.   }  
  859.  
  860.  
  861. /*******************************************************************
  862.  *
  863.  *  Function    :  TT_Apply_Outline_Translation
  864.  *
  865.  *  Description :  Apply a simple translation
  866.  *
  867.  *  Input  :  outline   no comment :)
  868.  *            x_offset
  869.  *            y_offset
  870.  *
  871.  *  Output :  Error code.
  872.  *
  873.  ******************************************************************/
  874.  
  875.   TT_Error  TT_Apply_Outline_Translation( TT_Glyph_Outline*  outline,
  876.                                           TT_F26Dot6         x_offset,
  877.                                           TT_F26Dot6         y_offset )
  878.   {
  879.     Int n;
  880.  
  881.     for ( n = 0; n < outline->points; n++ )
  882.     {
  883.       outline->xCoord[n] += x_offset;
  884.       outline->yCoord[n] += y_offset;
  885.     }
  886.  
  887.     return TT_Err_Ok;
  888.   }
  889.  
  890.  
  891.   /* ----------------- character mappings support ------------- */
  892.  
  893. /*******************************************************************
  894.  *
  895.  *  Function    :  TT_Get_CgharMap_Count
  896.  *
  897.  *  Description :  returns the number of charmaps in a given face
  898.  *
  899.  *  Input  :  face   face object handle
  900.  *
  901.  *  Output :  number of tables. -1 in case of error (bad handle)
  902.  *
  903.  ******************************************************************/
  904.  
  905.   int  TT_Get_CharMap_Count( TT_Face  face )
  906.   {
  907.     PFace  faze = HANDLE_Face(face);
  908.  
  909.     if (!faze)
  910.       return -1;
  911.  
  912.     return faze->numCMaps;
  913.   }
  914.  
  915. /*******************************************************************
  916.  *
  917.  *  Function    :  TT_Get_CharMap_ID
  918.  *
  919.  *  Description :  Returns the ID of a given charmap
  920.  *
  921.  *  Input  :  face             face object handle
  922.  *            charmapIndex     index of charmap in directory
  923.  *            platformID       address of returned platform ID
  924.  *            encodingID       address of returned encoding ID
  925.  *
  926.  *  Output :  error code
  927.  *
  928.  *  Notes  :
  929.  *
  930.  ******************************************************************/
  931.  
  932.   TT_Error   TT_Get_CharMap_ID( TT_Face  face,
  933.                                 int      charmapIndex,
  934.                                 short*   platformID,
  935.                                 short*   encodingID )
  936.   {
  937.     PCMapTable  cmap;
  938.     PFace       faze = HANDLE_Face(face);
  939.  
  940.     if (!faze)
  941.       return TT_Err_Invalid_Face_Handle;
  942.  
  943.     if (charmapIndex < 0 || charmapIndex >= faze->numCMaps )
  944.       return TT_Err_Bad_Argument;
  945.  
  946.     cmap = faze->cMaps + charmapIndex;
  947.  
  948.     *platformID = cmap->platformID;
  949.     *encodingID = cmap->platformEncodingID;
  950.  
  951.     return TT_Err_Ok;
  952.   }
  953.  
  954. /*******************************************************************
  955.  *
  956.  *  Function    :  TT_Get_CharMap
  957.  *
  958.  *  Description :  Look-up for a charmap
  959.  *
  960.  *  Input  :  face          face object handle
  961.  *            charmapIndex  index of charmap in directory
  962.  *            charMap       address of returned charmap handle
  963.  *
  964.  *  Output :  error code
  965.  *
  966.  ******************************************************************/
  967.  
  968.   TT_Error  TT_Get_CharMap( TT_Face      face,
  969.                             int          charmapIndex,
  970.                             TT_CharMap*  charMap )
  971.   {
  972.     TT_Error    error;
  973.     TT_Stream   stream;
  974.     PCMapTable  cmap;
  975.     PFace       faze = HANDLE_Face(face);
  976.  
  977.     if (!faze)
  978.       return TT_Err_Invalid_Face_Handle;
  979.  
  980.     if (charmapIndex < 0 || charmapIndex >= faze->numCMaps)
  981.       return TT_Err_Bad_Argument;
  982.  
  983.     cmap = faze->cMaps + charmapIndex;
  984.  
  985.     /* Load table if needed */
  986.  
  987.     error = TT_Err_Ok;
  988.  
  989.     if (!cmap->loaded)
  990.     {
  991.       USE_Stream( faze->stream, stream );
  992.       if (!error)
  993.       {
  994.     error = CharMap_Load( cmap, stream );
  995.     TT_Done_Stream( &stream );
  996.       }
  997.  
  998.       if (error)
  999.     cmap = NULL;
  1000.       else
  1001.     cmap->loaded = TRUE;
  1002.     }
  1003.  
  1004.     HANDLE_Set( *charMap, cmap );
  1005.     return error;
  1006.   }
  1007.  
  1008. /*******************************************************************
  1009.  *
  1010.  *  Function    :  TT_Char_Index
  1011.  *
  1012.  *  Description :  returns the glyph index corresponding to
  1013.  *                 a given charcode defined for the 'charmap'
  1014.  *
  1015.  *  Input  :  charMap    charmap handle
  1016.  *            charcode   character code in locale
  1017.  *
  1018.  *  Output :  glyph index.
  1019.  *
  1020.  *  Notes  :  a 0 is the unknown glyph, which should never be
  1021.  *            displayed.
  1022.  *
  1023.  ******************************************************************/
  1024.  
  1025.   int  TT_Char_Index( TT_CharMap      charMap,
  1026.                       unsigned short  charCode )
  1027.   {
  1028.     PCMapTable  cmap = HANDLE_CharMap(charMap);
  1029.  
  1030.     if (!cmap)
  1031.       return TT_Err_Invalid_CharMap_Handle;
  1032.  
  1033.     return CharMap_Index( cmap, charCode );
  1034.   }
  1035.  
  1036.  
  1037. /*******************************************************************
  1038.  *
  1039.  *  Function    :  TT_Get_Name_Count
  1040.  *
  1041.  *  Description :  Return the number of strings found in the
  1042.  *                 name table.
  1043.  *
  1044.  *  Input  :  face   face handle
  1045.  *
  1046.  *  Output :  number of strings
  1047.  *
  1048.  *  Notes  :  Returns -1 on error (invalid handle)
  1049.  *
  1050.  ******************************************************************/
  1051.  
  1052.   int  TT_Get_Name_Count( TT_Face  face )
  1053.   {
  1054.     PFace  faze = HANDLE_Face(face);
  1055.  
  1056.     if (!faze)
  1057.       return TT_Err_Invalid_Face_Handle;
  1058.  
  1059.     return faze->nameTable.numNameRecords;
  1060.   }
  1061.  
  1062.  
  1063. /*******************************************************************
  1064.  *
  1065.  *  Function    :  TT_Get_Name_ID
  1066.  *
  1067.  *  Description :  Returns the IDs of the string number 'nameIndex'
  1068.  *                 in the name table of a given face
  1069.  *
  1070.  *  Input  :  face        face handle
  1071.  *            nameIndex   index of string. First is 0
  1072.  *            platformID  addresses of returned IDs
  1073.  *            encodingID
  1074.  *            languageID
  1075.  *            nameID
  1076.  *
  1077.  *  Output :  Error code
  1078.  *
  1079.  *  Notes  :  Some files have a corrupt name table, some of their
  1080.  *            entries having a platformID > 3. These should be
  1081.  *            ignored by a client application.
  1082.  *
  1083.  ******************************************************************/
  1084.  
  1085.   TT_Error  TT_Get_Name_ID( TT_Face  face,
  1086.                             int      nameIndex,
  1087.                             short*   platformID,
  1088.                             short*   encodingID,
  1089.                             short*   languageID,
  1090.                             short*   nameID )
  1091.   {
  1092.     TNameRec*  namerec;
  1093.     PFace      faze = HANDLE_Face(face);
  1094.  
  1095.     if (!faze)
  1096.       return TT_Err_Invalid_Face_Handle;
  1097.  
  1098.     if (nameIndex < 0 || nameIndex >= faze->nameTable.numNameRecords)
  1099.       return TT_Err_Bad_Argument;
  1100.  
  1101.     namerec = faze->nameTable.names + nameIndex;
  1102.  
  1103.     *platformID = namerec->platformID;
  1104.     *encodingID = namerec->encodingID;
  1105.     *languageID = namerec->languageID;
  1106.     *nameID     = namerec->nameID;
  1107.  
  1108.     return TT_Err_Ok;
  1109.   }
  1110.  
  1111.  
  1112. /*******************************************************************
  1113.  *
  1114.  *  Function    :  TT_Get_Name_String
  1115.  *
  1116.  *  Description :  Returns the address and length of a given
  1117.  *                 string found in the name table
  1118.  *
  1119.  *  Input  :  face        face handle
  1120.  *            nameIndex   string index
  1121.  *            stringPtr   address of returned pointer to string
  1122.  *            length      address of returned string length
  1123.  *
  1124.  *  Output :  Error code
  1125.  *
  1126.  *  Notes  :  If the string's platformID is > 3 (which denotes
  1127.  *            an invalid entry in the name table), the returned
  1128.  *            pointer is NULL, and the length is 0.
  1129.  *
  1130.  ******************************************************************/
  1131.  
  1132.   TT_Error  TT_Get_Name_String( TT_Face  face,
  1133.                                 int      nameIndex,
  1134.                                 char**   stringPtr,
  1135.                                 int*     length )
  1136.   {
  1137.     TNameRec*  namerec;
  1138.     PFace      faze = HANDLE_Face(face);
  1139.  
  1140.     if (!faze)
  1141.       return TT_Err_Invalid_Face_Handle;
  1142.  
  1143.     if (nameIndex < 0 || nameIndex >= faze->nameTable.numNameRecords)
  1144.       return TT_Err_Bad_Argument;
  1145.  
  1146.     namerec = faze->nameTable.names + nameIndex;
  1147.  
  1148.     *stringPtr = (char*)namerec->string;
  1149.     *length    = namerec->stringLength;
  1150.  
  1151.     return TT_Err_Ok;
  1152.   }
  1153.  
  1154.  
  1155. /* END */
  1156.