Back to index

tetex-bin  3.0
t1trans.c
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------------
00002   ----- File:        t1trans.c 
00003   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
00004   ----- Date:        2003-01-04
00005   ----- Description: This file is part of the t1-library. It contains
00006                      functions for transforming fonts and setting
00007                    line-parameters.
00008   ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
00009                      As of version 0.5, t1lib is distributed under the
00010                    GNU General Public Library Lincense. The
00011                    conditions can be found in the files LICENSE and
00012                    LGPL, which should reside in the toplevel
00013                    directory of the distribution.  Please note that 
00014                    there are parts of t1lib that are subject to
00015                    other licenses:
00016                    The parseAFM-package is copyrighted by Adobe Systems
00017                    Inc.
00018                    The type1 rasterizer is copyrighted by IBM and the
00019                    X11-consortium.
00020   ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
00021   ----- Credits:     I want to thank IBM and the X11-consortium for making
00022                      their rasterizer freely available.
00023                    Also thanks to Piet Tutelaers for his ps2pk, from
00024                    which I took the rasterizer sources in a format
00025                    independent from X11.
00026                      Thanks to all people who make free software living!
00027 --------------------------------------------------------------------------*/
00028   
00029 #define T1TRANS_C
00030 
00031 
00032 #include <stdio.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <fcntl.h>
00036 #if defined(_MSC_VER)
00037 # include <io.h>
00038 # include <sys/types.h>
00039 # include <sys/stat.h>
00040 #else
00041 # include <unistd.h>
00042 #endif
00043 #include <stdlib.h>
00044 #include <math.h>
00045 #include <string.h>
00046 
00047 #include "../type1/ffilest.h"
00048 #include "../type1/types.h"
00049 #include "parseAFM.h" 
00050 #include "../type1/objects.h"
00051 #include "../type1/spaces.h"
00052 #include "../type1/util.h"
00053 #include "../type1/fontfcn.h"
00054 #include "../type1/regions.h"
00055 
00056 
00057 #include "t1types.h"
00058 #include "t1extern.h"
00059 #include "t1trans.h"
00060 #include "t1base.h"
00061 
00062 
00063 /* T1_ExtendFont(): Extend the font referenced by FontID by the factor
00064    extend. This is only allowed if no size dependent data exists.
00065    Of course, the font must already have been loaded.
00066    Returns 0 for success and -1 otherwise.
00067    */
00068 int T1_ExtendFont( int FontID, double extend)
00069 {
00070   
00071   /* First, check for font residing in memory: */
00072   if (T1_CheckForFontID(FontID)!=1){
00073     T1_errno=T1ERR_INVALID_FONTID;
00074     return(-1);
00075   }
00076   
00077   /* Second, check whether size-dependent data exists: */
00078   if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){
00079     T1_errno=T1ERR_OP_NOT_PERMITTED;
00080     return(-1); 
00081   }
00082   
00083   pFontBase->pFontArray[FontID].extend=extend;
00084   pFontBase->pFontArray[FontID].FontTransform[0] = extend;
00085   return(0);
00086 }
00087 
00088 
00089 
00090 /* T1_GetExtend(): Return the current extension factor of the
00091    font FontID
00092    Return: 0.0                    if font not loaded
00093            current extent         otherwise
00094 */
00095 double T1_GetExtend( int FontID)
00096 {
00097   /* First, check for font residing in memory: */
00098   if (T1_CheckForFontID(FontID)!=1){
00099     T1_errno=T1ERR_INVALID_FONTID;
00100     return(0.0);
00101   }
00102 
00103   return( pFontBase->pFontArray[FontID].extend);
00104 }
00105 
00106 
00107 
00108 
00109 /* T1_SlantFont(): Slant the font referenced by FontID by the factor
00110    extend. This is only allowed if no size dependent data exists.
00111    Of course, the font must already have been loaded.
00112    Returns 0 for success and -1 otherwise.
00113    */
00114 int T1_SlantFont( int FontID, double slant)
00115 {
00116   
00117   /* First, check for font residing in memory: */
00118   if (T1_CheckForFontID(FontID)!=1){
00119     T1_errno=T1ERR_INVALID_FONTID;
00120     return(-1);
00121   }
00122   
00123   /* Second, check whether size-dependent data exists: */
00124   if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){
00125     T1_errno=T1ERR_OP_NOT_PERMITTED;
00126     return(-1); 
00127   }
00128   
00129   pFontBase->pFontArray[FontID].slant=slant;
00130   pFontBase->pFontArray[FontID].FontTransform[2] = slant;
00131   return(0);
00132 }
00133 
00134 
00135 
00136 /* T1_GetSlant(): Return the current slanting factor of the
00137    font FontID
00138    Return: 0.0                    if font not loaded
00139            current slant          otherwise (may also be 0.0!)
00140 */
00141 double T1_GetSlant( int FontID)
00142 {
00143   /* First, check for font residing in memory: */
00144   if (T1_CheckForFontID(FontID)!=1){
00145     T1_errno=T1ERR_INVALID_FONTID;
00146     return(0.0);
00147   }
00148 
00149   return( pFontBase->pFontArray[FontID].slant);
00150 }
00151 
00152 
00153 
00154 /* T1_TransformFont(): Transform the font referenced by FontID according
00155    to the transform matrix.  This is only allowed if no size dependent
00156    data exists.  Of course, the font must already have been loaded.
00157    Returns 0 for success and -1 otherwise.
00158    */
00159 int T1_TransformFont( int FontID, T1_TMATRIX *matrix)
00160 {
00161   
00162   /* First, check for font residing in memory: */
00163   if (T1_CheckForFontID(FontID)!=1){
00164     T1_errno=T1ERR_INVALID_FONTID;
00165     return(-1);
00166   }
00167   
00168   /* Second, check whether size-dependent data exists: */
00169   if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){
00170     T1_errno=T1ERR_OP_NOT_PERMITTED;
00171     return(-1); 
00172   }
00173   
00174   pFontBase->pFontArray[FontID].FontTransform[0] = matrix->cxx;
00175   pFontBase->pFontArray[FontID].FontTransform[1] = matrix->cxy;
00176   pFontBase->pFontArray[FontID].FontTransform[2] = matrix->cyx;
00177   pFontBase->pFontArray[FontID].FontTransform[3] = matrix->cyy;
00178   return(0);
00179 }
00180 
00181 
00182 
00183 /* T1_GetTransform(): Return the current transformation matrix for the
00184    font FontID
00185    Return: [0.0, 0.0, 0.0, 0.0]    if font not loaded
00186            current tmatrix         otherwise 
00187 */
00188 T1_TMATRIX T1_GetTransform( int FontID)
00189 {
00190   T1_TMATRIX tmatrix={0.0, 0.0, 0.0, 0.0};
00191   
00192   /* First, check for font residing in memory: */
00193   if (T1_CheckForFontID(FontID)!=1){
00194     T1_errno=T1ERR_INVALID_FONTID;
00195     return(tmatrix);
00196   }
00197 
00198   tmatrix.cxx=pFontBase->pFontArray[FontID].FontTransform[0];
00199   tmatrix.cxy=pFontBase->pFontArray[FontID].FontTransform[1];
00200   tmatrix.cyx=pFontBase->pFontArray[FontID].FontTransform[2];
00201   tmatrix.cyy=pFontBase->pFontArray[FontID].FontTransform[3];
00202   
00203   return( tmatrix);
00204 }
00205 
00206 
00207 
00208 /* Functions for setting line-parameters:
00209    linetypeis expected to be an OR'ed combination of
00210    T1_UNDERLINE, T1_OVERLINE and T1_OVERSTRIKE.
00211  */
00212 int T1_SetLinePosition( int FontID, int linetype, float value)
00213 {
00214 
00215   if (T1_CheckForFontID(FontID)!=1){
00216     T1_errno=T1ERR_INVALID_FONTID;
00217     return(-1);
00218   }
00219 
00220   if (linetype & T1_UNDERLINE){
00221     pFontBase->pFontArray[FontID].UndrLnPos=value;
00222     return( 0);
00223   }
00224   if (linetype & T1_OVERLINE){
00225     pFontBase->pFontArray[FontID].OvrLnPos=value;
00226     return( 0);
00227   }
00228   if (linetype & T1_OVERSTRIKE){
00229     pFontBase->pFontArray[FontID].OvrStrkPos=value;
00230     return( 0);
00231   }
00232     
00233   /* The linetype was bad */
00234   T1_errno=T1ERR_INVALID_PARAMETER;
00235   return( -1);
00236   
00237 }
00238 
00239 
00240 
00241 int T1_SetLineThickness( int FontID, int linetype, float value)
00242 {
00243 
00244   if (T1_CheckForFontID(FontID)!=1){
00245     T1_errno=T1ERR_INVALID_FONTID;
00246     return(-1);
00247   }
00248 
00249   if (linetype & T1_UNDERLINE){
00250     pFontBase->pFontArray[FontID].UndrLnThick=value;
00251     return( 0);
00252   }
00253   if (linetype & T1_OVERLINE){
00254     pFontBase->pFontArray[FontID].OvrLnThick=value;
00255     return( 0);
00256   }
00257   if (linetype & T1_OVERSTRIKE){
00258     pFontBase->pFontArray[FontID].OvrStrkThick=value;
00259     return( 0);
00260   }
00261     
00262   /* The linetype was bad */
00263   T1_errno=T1ERR_INVALID_PARAMETER;
00264   return( -1);
00265   
00266 }
00267 
00268 
00269 float T1_GetLinePosition( int FontID, int linetype)
00270 {
00271 
00272   if (T1_CheckForFontID(FontID)!=1){
00273     T1_errno=T1ERR_INVALID_FONTID;
00274     return(0.0);
00275   }
00276 
00277   if (linetype & T1_UNDERLINE)
00278     return( pFontBase->pFontArray[FontID].UndrLnPos);
00279   if (linetype & T1_OVERLINE)
00280     return( pFontBase->pFontArray[FontID].OvrLnPos);
00281   if (linetype & T1_OVERSTRIKE)
00282     return( pFontBase->pFontArray[FontID].OvrStrkPos);
00283   
00284   /* The linetype was bad */
00285   T1_errno=T1ERR_INVALID_PARAMETER;
00286   return( 0.0);
00287   
00288 }
00289 
00290 
00291 
00292 float T1_GetLineThickness( int FontID, int linetype)
00293 {
00294 
00295   if (T1_CheckForFontID(FontID)!=1){
00296     T1_errno=T1ERR_INVALID_FONTID;
00297     return(0.0);
00298   }
00299 
00300   if (linetype & T1_UNDERLINE)
00301     return( pFontBase->pFontArray[FontID].UndrLnThick);
00302   if (linetype & T1_OVERLINE)
00303     return( pFontBase->pFontArray[FontID].OvrLnThick);
00304   if (linetype & T1_OVERSTRIKE)
00305     return( pFontBase->pFontArray[FontID].OvrStrkThick);
00306   
00307   /* The linetype was bad */
00308   T1_errno=T1ERR_INVALID_PARAMETER;
00309   return( 0.0);
00310 
00311 }
00312 
00313 
00314 /* Functions for intuitively transforming matrices. All function operate on their
00315    original objects. In case NULL is specified, a unity-matrix is allocated by
00316    the function and then tranformed appropriately. Note that in order to concatenate
00317    transformation in the sense of t1lib the current transformation matrix must be
00318    left-multiplied by the trnasformation to be applied! */
00319 /* Rotation:
00320             ( x11'  x21' )   ( cos(a)    -sin(a) )   ( x11  x21 ) 
00321            (            ) = (                   ) * (          ) 
00322             ( x12'  x22' )   ( sin(a)     cos(a) )   ( x12  x22 ) 
00323 */
00324 T1_TMATRIX *T1_RotateMatrix( T1_TMATRIX *matrix, double angle)
00325 {
00326   T1_TMATRIX tmat;
00327   
00328   if (matrix==NULL){
00329     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00330       T1_errno=T1ERR_ALLOC_MEM;
00331       return( NULL);
00332     }
00333     matrix->cxx=1.0;
00334     matrix->cyx=0.0;
00335     matrix->cxy=0.0;
00336     matrix->cyy=1.0;
00337   }
00338   memcpy( &tmat, matrix, sizeof(T1_TMATRIX));
00339   /* Convert angle to radians: */
00340   angle=angle*PI/180.0;
00341   /* multiply matrices */
00342   matrix->cxx=cos((double)angle) * tmat.cxx - sin((double)angle) * tmat.cxy;
00343   matrix->cyx=cos((double)angle) * tmat.cyx - sin((double)angle) * tmat.cyy;
00344   matrix->cxy=sin((double)angle) * tmat.cxx + cos((double)angle) * tmat.cxy;
00345   matrix->cyy=sin((double)angle) * tmat.cyx + cos((double)angle) * tmat.cyy;
00346   return( matrix);
00347 }
00348 
00349 
00350 /* Horizontal mirroring */
00351 /* H-Mirror:
00352             ( x11'  x21' )   ( -1    0 )   ( x11  x21 )   ( -x11   -x21 ) 
00353            (            ) = (         ) * (          ) = (             ) 
00354             ( x12'  x22' )   (  0    1 )   ( x12  x22 )   (  x12    x22 ) 
00355 */
00356 T1_TMATRIX *T1_MirrorHMatrix( T1_TMATRIX *matrix)
00357 {
00358   
00359   if (matrix==NULL){
00360     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00361       T1_errno=T1ERR_ALLOC_MEM;
00362       return( NULL);
00363     }
00364     matrix->cxx=1.0;
00365     matrix->cyx=0.0;
00366     matrix->cxy=0.0;
00367     matrix->cyy=1.0;
00368   }
00369   matrix->cxx *=-1.0;
00370   matrix->cyx *=-1.0;
00371   return( matrix);
00372 }
00373 
00374 
00375 /* Vertical mirroring */
00376 /* V-Mirror:
00377             ( x11'  x21' )   ( 1    0 )   ( x11  x21 )   (  x11    x21 )
00378            (            ) = (        ) * (          ) = (             )
00379             ( x12'  x22' )   ( 0   -1 )   ( x12  x22 )   ( -x12   -x22 )
00380 */
00381 T1_TMATRIX *T1_MirrorVMatrix( T1_TMATRIX *matrix)
00382 {
00383   
00384   if (matrix==NULL){
00385     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00386       T1_errno=T1ERR_ALLOC_MEM;
00387       return( NULL);
00388     }
00389     matrix->cxx=1.0;
00390     matrix->cyx=0.0;
00391     matrix->cxy=0.0;
00392     matrix->cyy=1.0;
00393   }
00394   matrix->cxy *=-1.0;
00395   matrix->cyy *=-1.0;
00396   return( matrix);
00397   
00398 }
00399 
00400 
00401 /* Horizontal shearing */
00402 /* H-Shearing:
00403             ( x11'  x21' )   ( 1    f )   ( x11  x21 )   ( x11+f*x12   x21+f*x22 ) 
00404            (            ) = (        ) * (          ) = (                       ) 
00405             ( x12'  x22' )   ( 0    1 )   ( x12  x22 )   ( x12         x22       ) 
00406 */
00407 T1_TMATRIX *T1_ShearHMatrix( T1_TMATRIX *matrix, double shear)
00408 {
00409   
00410   if (matrix==NULL){
00411     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00412       T1_errno=T1ERR_ALLOC_MEM;
00413       return( NULL);
00414     }
00415     matrix->cxx=1.0;
00416     matrix->cyx=0.0;
00417     matrix->cxy=0.0;
00418     matrix->cyy=1.0;
00419   }
00420   matrix->cxx +=shear*matrix->cxy;
00421   matrix->cyx +=shear*matrix->cyy;
00422   return( matrix);
00423   
00424 }
00425 
00426 
00427 /* Vertical shearing */
00428 /* V-Shearing:
00429             ( x11'  x21' )   ( 1    0 )   ( x11  x21 )   ( x11         x21       ) 
00430            (            ) = (        ) * (          ) = (                       ) 
00431             ( x12'  x22' )   ( f    1 )   ( x12  x22 )   ( x12+f*x11   x22+f*x21 ) 
00432 */
00433 T1_TMATRIX *T1_ShearVMatrix( T1_TMATRIX *matrix, double shear)
00434 {
00435   
00436   if (matrix==NULL){
00437     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00438       T1_errno=T1ERR_ALLOC_MEM;
00439       return( NULL);
00440     }
00441     matrix->cxx=1.0;
00442     matrix->cyx=0.0;
00443     matrix->cxy=0.0;
00444     matrix->cyy=1.0;
00445   }
00446   matrix->cxy +=shear*matrix->cxx;
00447   matrix->cyy +=shear*matrix->cyx;
00448   return( matrix);
00449   
00450 }
00451 
00452 
00453 /* Horizontal extension */
00454 /* Horizontal-Extension:
00455             ( x11'  x21' )   ( f    0 )   ( x11  x21 )   ( f*x11   f*x21 ) 
00456            (            ) = (        ) * (          ) = (               ) 
00457             ( x12'  x22' )   ( 0    1 )   ( x12  x22 )   ( x12     x22   ) 
00458 */
00459 T1_TMATRIX *T1_ExtendHMatrix( T1_TMATRIX *matrix, double extent)
00460 {
00461   
00462   if (matrix==NULL){
00463     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00464       T1_errno=T1ERR_ALLOC_MEM;
00465       return( NULL);
00466     }
00467     matrix->cxx=1.0;
00468     matrix->cyx=0.0;
00469     matrix->cxy=0.0;
00470     matrix->cyy=1.0;
00471   }
00472   matrix->cxx *=extent;
00473   matrix->cyx *=extent;
00474   return( matrix);
00475   
00476 }
00477 
00478 
00479 /* Vertical extension */
00480 /* Vertical-Extension:
00481             ( x11'  x21' )   ( 1    0 )   ( x11  x21 )   ( x11    x21   ) 
00482            (            ) = (        ) * (          ) = (              ) 
00483             ( x12'  x22' )   ( 0    f )   ( x12  x22 )   ( f*x12  f*x22 ) 
00484 */
00485 T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX *matrix, double extent)
00486 {
00487   
00488   if (matrix==NULL){
00489     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00490       T1_errno=T1ERR_ALLOC_MEM;
00491       return( NULL);
00492     }
00493     matrix->cxx=1.0;
00494     matrix->cyx=0.0;
00495     matrix->cxy=0.0;
00496     matrix->cyy=1.0;
00497   }
00498   matrix->cxy *=extent;
00499   matrix->cyy *=extent;
00500   return( matrix);
00501   
00502 }
00503 
00504 
00505 /* General transformation */
00506 /*  
00507     ( x11   x21 )   ( y11   y21 )   ( x11*y11+x21*y12   x11*y21+x21*y22 )
00508     (           ) * (           ) = (                                   )
00509     ( x12   x22 )   ( y12   y22 )   ( x12*y11+x22*y12   x12*y21+x22*y22 )
00510 */
00511 T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix,
00512                             double cxx, double cyx,
00513                             double cxy, double cyy)
00514 {
00515   T1_TMATRIX tmat;
00516   
00517   if (matrix==NULL){
00518     if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){
00519       T1_errno=T1ERR_ALLOC_MEM;
00520       return( NULL);
00521     }
00522     matrix->cxx=1.0;
00523     matrix->cyx=0.0;
00524     matrix->cxy=0.0;
00525     matrix->cyy=1.0;
00526   }
00527   memcpy( &tmat, matrix, sizeof(T1_TMATRIX));
00528   matrix->cxx=cxx * tmat.cxx + cyx * tmat.cxy;
00529   matrix->cyx=cxx * tmat.cyx + cyx * tmat.cyy;
00530   matrix->cxy=cxy * tmat.cxx + cyy * tmat.cxy;
00531   matrix->cyy=cxy * tmat.cyx + cyy * tmat.cyy;
00532   
00533   return( matrix);
00534 }
00535 
00536 
00537 
00538 /* T1_StrokeFont(): Switch the  font referenced by FontID to stroking
00539    or filling. The stroked character will be cached and 
00540    filled characters are no longer cached and vice versa.
00541    This is only allowed if no size dependent data exists.
00542    Of course, the font must already have been loaded.
00543    Returns 0 for success and -1 otherwise.
00544    */
00545 int T1_StrokeFont( int FontID, int dostroke)
00546 {
00547   
00548   /* First, check for font residing in memory: */
00549   if ( T1_CheckForFontID( FontID) != 1 ) {
00550     T1_errno = T1ERR_INVALID_FONTID;
00551     return -1;
00552   }
00553   
00554   /* Second, check whether size-dependent data exists: */
00555   if ( pFontBase->pFontArray[FontID].pFontSizeDeps != NULL ) {
00556     T1_errno = T1ERR_OP_NOT_PERMITTED;
00557     return -1; 
00558   }
00559 
00560   if ( dostroke != 0 ) {
00561     pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED;
00562     pFontBase->pFontArray[FontID].info_flags |= CACHE_STROKED;
00563   }
00564   else {
00565     pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED;
00566     pFontBase->pFontArray[FontID].info_flags &= ~CACHE_STROKED;
00567   }
00568   
00569 
00570   return 0;
00571 }
00572 
00573 
00574 
00575 /* T1_SetStrokeFlag(): Return the stroke flag for font FontID.
00576    Return:  0                      flag has been set
00577            -1                      flag could not be set 
00578 */
00579 int T1_SetStrokeFlag( int FontID)
00580 {
00581   /* First, check for font residing in memory: */
00582   if ( T1_CheckForFontID(FontID) != 1 ) {
00583     T1_errno = T1ERR_INVALID_FONTID;
00584     return -1;
00585   }
00586   
00587   /* Set stroke flag to true */
00588   pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED;
00589   
00590   return 0;
00591   
00592 }
00593 
00594 
00595 
00596 /* T1_ClearStrokeFlag(): Reset the stroke flag for font FontID.
00597    Return:  0                      flag has been reset
00598            -1                      flag could not be reset 
00599 */
00600 int T1_ClearStrokeFlag( int FontID)
00601 {
00602   /* First, check for font residing in memory: */
00603   if ( T1_CheckForFontID(FontID) != 1 ) {
00604     T1_errno = T1ERR_INVALID_FONTID;
00605     return -1;
00606   }
00607 
00608   /* Reset stroke flag */
00609   pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED;
00610   
00611   return 0;
00612   
00613 }
00614 
00615 
00616 
00617 /* T1_GetStrokeMode(): Return the stroke flag for font FontID.
00618    Return: -1                      if font is not loaded.
00619            0                      if flag is reset,
00620            1                      if stroking is enabled for this font,
00621            2                      if stroked characters are cached,
00622            3                      if stroking is enabled and stroked
00623                                   characters are cached.
00624 */
00625 int T1_GetStrokeMode( int FontID)
00626 {
00627   int outval = 0;
00628   
00629   /* First, check for font residing in memory: */
00630   if ( T1_CheckForFontID( FontID) != 1 ) {
00631     T1_errno = T1ERR_INVALID_FONTID;
00632     return -1;
00633   }
00634 
00635   if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) 
00636     outval |= 0x02;
00637   
00638   if ( (pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) != 0 ) 
00639     outval |= 0x01;
00640   
00641   return outval;
00642     
00643 }
00644 
00645 
00646 
00647 /* T1_SetStrokeWidth(): Set the penwidth used when stroking font FontID.
00648    Return  -1           If width could not be set.
00649             0           if width has been set.
00650  */
00651 int T1_SetStrokeWidth( int FontID, float strokewidth)
00652 {
00653   /* First, check for font residing in memory: */
00654   if ( T1_CheckForFontID( FontID) != 1 ) {
00655     T1_errno = T1ERR_INVALID_FONTID;
00656     return -1;
00657   }
00658 
00659   /* Second, check whether caching stroked characters is enabled
00660      for this font and glyph data is already existing. In this case
00661      the operation is forbidden, unless the previous non-zero value
00662      is just restored! */
00663   if ( ((pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0) &&
00664        (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL) &&
00665        (pFontBase->pFontArray[FontID].SavedStrokeWidth != strokewidth)
00666        ) {
00667     T1_errno = T1ERR_OP_NOT_PERMITTED;
00668     return -1; 
00669   }
00670 
00671   /* OK, accept stroke width after ensuring a numerically meaningful
00672      value */
00673   if ( strokewidth < 0.0f ) {
00674     T1_errno = T1ERR_INVALID_PARAMETER;
00675     return -1;
00676   }
00677 
00678   pFontBase->pFontArray[FontID].StrokeWidth = strokewidth;
00679   
00680   if ( strokewidth != 0.0f )
00681     pFontBase->pFontArray[FontID].SavedStrokeWidth = strokewidth;
00682   
00683   return 0;
00684     
00685 }
00686 
00687 
00688 
00689 /* T1_GetStrokeWidth(): Get the penwidth used when stroking font FontID.
00690    If 0.0 is returned, it might also indicate that the font is not loaded.
00691 */
00692 float T1_GetStrokeWidth( int FontID)
00693 {
00694   /* First, check for font residing in memory: */
00695   if ( T1_CheckForFontID( FontID) != 1 ) {
00696     T1_errno = T1ERR_INVALID_FONTID;
00697     return 0.0f;
00698   }
00699 
00700   return pFontBase->pFontArray[FontID].StrokeWidth;  
00701 }
00702