Back to index

tetex-bin  3.0
t1win32.c
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------------
00002   ----- File:        t1win32.c 
00003   ----- Author:      Rainer Menzner (rmz@neuroinformatik.ruhr-uni-bochum.de)
00004                      modified for win32 by Fabrice Popineau (Fabrice.Popineau@supelec.fr)
00005   ----- Date:        1999-06-24
00006   ----- Description: This file is part of the t1-library. It contains
00007                      functions for generating glyphs with data in
00008                    Win32 dib format.
00009   ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-1998. 
00010                      As of version 0.5, t1lib is distributed under the
00011                    GNU General Public Library Lincense. The
00012                    conditions can be found in the files LICENSE and
00013                    LGPL, which should reside in the toplevel
00014                    directory of the distribution.  Please note that 
00015                    there are parts of t1lib that are subject to
00016                    other licenses:
00017                    The parseAFM-package is copyrighted by Adobe Systems
00018                    Inc.
00019                    The type1 rasterizer is copyrighted by IBM and the
00020                    X11-consortium.
00021   ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
00022   ----- Credits:     I want to thank IBM and the X11-consortium for making
00023                      their rasterizer freely available.
00024                    Also thanks to Piet Tutelaers for his ps2pk, from
00025                    which I took the rasterizer sources in a format
00026                    independent from X11.
00027                      Thanks to all people who make free software living!
00028 --------------------------------------------------------------------------*/
00029   
00030 #define T1WIN32_C
00031 
00032 
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <fcntl.h>
00038 #include <stdlib.h>
00039 #include <math.h>
00040 
00041 #include <windows.h>
00042 
00043 #include "../type1/types.h"
00044 #include "parseAFM.h" 
00045 #include "../type1/objects.h" 
00046 #include "../type1/spaces.h"  
00047 #include "../type1/util.h" 
00048 #include "../type1/fontfcn.h"
00049 #include "../type1/regions.h"
00050 
00051 #include "t1types.h"
00052 #include "t1extern.h"
00053 #include "t1set.h"
00054 #include "t1aaset.h"
00055 #include "t1load.h"
00056 #include "t1finfo.h"
00057 #include "t1misc.h"
00058 #include "t1win32.h"
00059 #include "t1base.h"
00060 
00061 
00062 
00063 #define T1GCMASK GCForeground | GCBackground 
00064 
00065 /* As a fall back */
00066 #ifndef T1_AA_TYPE16 
00067 #define T1_AA_TYPE16    short
00068 #endif
00069 #ifndef T1_AA_TYPE32 
00070 #define T1_AA_TYPE32    int
00071 #endif
00072 
00073 
00074 
00075 /* The three important X11 parameters t1lib has to deal with: */
00076 static HDC  *T1_display=NULL;  /* Must be accessible from t1delete.c */
00077 static Colormap T1_colormap;
00078 static unsigned int T1_depth;
00079 static int T1_byte_order;
00080 static int lastlevel=0;
00081 static unsigned long oldfg_n=0, oldbg_n=0, oldfg_l=0, oldbg_l=0;
00082 static unsigned long oldfg_h=0, oldbg_h=0, oldfg=0, oldbg=0;
00083 
00084 
00085 extern int T1aa_SmartOn;        /* from t1aaset.c */
00086 extern float T1aa_smartlimit1;
00087 extern float T1aa_smartlimit2;
00088 
00089 
00090 
00091 static XColor aacolors[AAMAXPLANES];
00092 static unsigned long aapixels[AAMAXPLANES];
00093 
00094 
00095 /* The following parameter determines whether t1lib will use logical
00096    positioning of chars and string (place the origin at specified
00097    destination-point) or absolute positioning with respect to the
00098    origin (upper left corner) of the generated bitmap/pixmap. */
00099 static int T1_lposition=1;
00100 
00101 
00102 
00103 /* T1_SetX11Params(): Set X11-parameters which t1lib has to know in order
00104    to properly generate pixmaps from characters */
00105 int T1_SetWin32Params( HDC hDc,
00106                    unsigned int depth,
00107                    Colormap colormap)
00108 {
00109 
00110   T1_display  =display;
00111   T1_visual   =visual;
00112   T1_depth    =depth;
00113   T1_colormap =colormap;
00114 
00115   if (T1_CheckEndian()==0)
00116     T1_byte_order=0;
00117   else
00118     T1_byte_order=1;
00119 
00120   /* For bug hunting: */
00121   if (ImageByteOrder( T1_display)==0)
00122     T1_PrintLog( "T1_SetX11Params()",
00123                "X-Server uses Little Endian data representation",
00124                T1LOG_DEBUG);
00125   else
00126     T1_PrintLog( "T1_SetX11Params()",
00127                "X-Server uses Big Endian data representation",
00128                T1LOG_DEBUG);
00129   
00130   return(0);
00131 }
00132 
00133 
00134 
00135 /* T1_SetCharX(): Generate an object of type GLYPH, i.e, a glyph with
00136    a pixmap ID instead of a pointer to a bitmap: */
00137 
00138 GLYPH *T1_SetCharX( HDC hDc, int mode, int x_dest, int y_dest,
00139                   int FontID, char charcode,
00140                   float size, T1_TMATRIX *transform)
00141 {
00142   GLYPH  *pglyph;
00143   static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
00144  
00145   int height, width;
00146   Pixmap clipmask=0;
00147   int opaque;
00148   
00149 
00150   xglyph.metrics.leftSideBearing=0;
00151   xglyph.metrics.rightSideBearing=0;
00152   xglyph.metrics.advanceX=0;
00153   xglyph.metrics.advanceY=0;
00154   xglyph.metrics.ascent=0;
00155   xglyph.metrics.descent=0;
00156   xglyph.pFontCacheInfo=NULL;
00157   
00158 
00159   opaque=mode;
00160   
00161   
00162   if ((pglyph=T1_SetChar( FontID, charcode, size, transform))==NULL){
00163     T1_PrintLog( "T1_SetCharX()",
00164                "T1_SetChar() returned NULL-pointer!",
00165                T1LOG_WARNING);
00166     return(NULL);
00167   }
00168 
00169   /* Check for empty bitmap */
00170   if (pglyph->bits==NULL) {
00171     xglyph=*pglyph;
00172     return( &xglyph);
00173   }
00174   
00175   width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
00176   height=pglyph->metrics.ascent-pglyph->metrics.descent;
00177   
00178   
00179   clipmask=XCreateBitmapFromData( T1_display,
00180                               d,
00181                               (char *)pglyph->bits,
00182                               PAD(width, pFontBase->bitmap_pad),  
00183                               height
00184                               );
00185                               
00186   /* Correct position */
00187   if (T1_lposition){
00188     x_dest += pglyph->metrics.leftSideBearing;
00189     y_dest -= pglyph->metrics.ascent;
00190   }
00191 
00192   if (opaque==0){
00193     XSetClipMask(T1_display, gc, clipmask);
00194     XSetClipOrigin(T1_display, gc, x_dest, y_dest);
00195   }
00196   
00197   XCopyPlane( T1_display, clipmask, d, gc, 0, 0,
00198              width, height, x_dest, y_dest, 0x01);
00199   
00200   if (clipmask){
00201     XFreePixmap( T1_display, clipmask);
00202     clipmask=0;
00203     XSetClipMask(T1_display, gc, None);
00204     XSetClipOrigin(T1_display, gc, 0, 0);
00205   }
00206   
00207   pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
00208   xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
00209   xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
00210   xglyph.metrics.advanceX=pglyph->metrics.advanceX;
00211   xglyph.metrics.advanceY=pglyph->metrics.advanceY;
00212   xglyph.metrics.ascent=pglyph->metrics.ascent;
00213   xglyph.metrics.descent=pglyph->metrics.descent;
00214   xglyph.bpp=pglyph->bpp;
00215   
00216   return( &xglyph);
00217   
00218   
00219 }
00220 
00221 
00222 
00223 /* T1_SetStringX(...): Draw a string of characters into an X11 drawable */
00224 GLYPH *T1_SetStringX( HDC hDc, int mode, int x_dest, int y_dest,
00225                     int FontID, char *string, int len, 
00226                     long spaceoff, int modflag, float size,
00227                     T1_TMATRIX *transform)
00228 {
00229   GLYPH  *pglyph;
00230   static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
00231  
00232   int height, width;
00233   Pixmap clipmask=0;
00234   int opaque;
00235   
00236 
00237   xglyph.metrics.leftSideBearing=0;
00238   xglyph.metrics.rightSideBearing=0;
00239   xglyph.metrics.advanceX=0;
00240   xglyph.metrics.advanceY=0;
00241   xglyph.metrics.ascent=0;
00242   xglyph.metrics.descent=0;
00243   xglyph.pFontCacheInfo=NULL;
00244   
00245 
00246   opaque=mode;
00247   
00248 
00249   if ((pglyph=T1_SetString( FontID, string, len, 
00250                          spaceoff, modflag, size,
00251                          transform))==NULL){
00252     T1_PrintLog( "T1_SetStringX()",
00253                "T1_SetString() returned NULL-pointer!",
00254                T1LOG_WARNING);
00255     return(NULL);
00256   }
00257 
00258   /* Check for empty bitmap */
00259   if (pglyph->bits==NULL) {
00260     xglyph=*pglyph;
00261     return( &xglyph);
00262   }
00263 
00264   width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
00265   height=pglyph->metrics.ascent-pglyph->metrics.descent;
00266   
00267   clipmask=XCreateBitmapFromData( T1_display,
00268                               d,
00269                               (char *)pglyph->bits,
00270                               PAD(width, pFontBase->bitmap_pad), /* width */
00271                               height
00272                               );
00273   
00274   /* Correct position */
00275   if (T1_lposition){
00276     x_dest += pglyph->metrics.leftSideBearing;
00277     y_dest -= pglyph->metrics.ascent;
00278   }
00279 
00280   if (opaque==0){
00281     XSetClipMask(T1_display, gc, clipmask);
00282     XSetClipOrigin(T1_display, gc, x_dest, y_dest);
00283   }
00284   
00285   XCopyPlane( T1_display, clipmask, d, gc, 0, 0,
00286              width, height, x_dest, y_dest, 0x01);
00287   
00288   if (clipmask){
00289     XFreePixmap( T1_display, clipmask);
00290     clipmask=0;
00291     XSetClipMask(T1_display, gc, None);
00292     XSetClipOrigin(T1_display, gc, 0, 0);
00293   }
00294   
00295   pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
00296   xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
00297   xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
00298   xglyph.metrics.advanceX=pglyph->metrics.advanceX;
00299   xglyph.metrics.advanceY=pglyph->metrics.advanceY;
00300   xglyph.metrics.ascent=pglyph->metrics.ascent;
00301   xglyph.metrics.descent=pglyph->metrics.descent;
00302   xglyph.bpp=pglyph->bpp;
00303   
00304   return( &xglyph);
00305   
00306   
00307 }
00308 
00309 
00310 
00311 /* T1_AASetCharX(): Generate an object of type GLYPH, i.e, a glyph with
00312    a pixmap ID instead of a pointer to a bitmap: */
00313 
00314 GLYPH *T1_AASetCharX( HDC hDc, int mode, int x_dest, int y_dest,
00315                     int FontID, char charcode,
00316                     float size, T1_TMATRIX *transform)
00317 {
00318   int j, k;
00319 
00320   GLYPH  *pglyph;
00321   XImage *ximage;
00322 
00323   static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
00324  
00325   int height, width, width_pad;
00326   
00327   XGCValues xgcvalues;
00328   static unsigned long fg, bg, oldfg=0, oldbg=0;
00329   static unsigned long oldfg_l=0, oldbg_l=0, oldfg_h=0, oldbg_h=0;
00330 
00331   Pixmap clipmask=0;
00332   int clipmask_h, clipmask_v, line_off;
00333   char *clipmask_ptr;
00334   
00335   int opaque;
00336   
00337 
00338               
00339   xglyph.metrics.leftSideBearing=0;
00340   xglyph.metrics.rightSideBearing=0;
00341   xglyph.metrics.advanceX=0;
00342   xglyph.metrics.advanceY=0;
00343   xglyph.metrics.ascent=0;
00344   xglyph.metrics.descent=0;
00345   xglyph.pFontCacheInfo=NULL;
00346   
00347 
00348   opaque=mode;
00349   
00350   xglyph.bpp=T1_depth;
00351   
00352   /* In order to be able to contruct the pixmap we need to know
00353      foreground and background color as well the copy function */
00354   XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues);
00355   fg=xgcvalues.foreground;
00356   bg=xgcvalues.background;
00357   
00358 
00359   /* At this point we must compute the colors that are needed to do
00360      antialiasing between fore- and background. The following function
00361      fills the static aacolors */
00362   if (T1aa_SmartOn==0)
00363     j=T1_AAGetLevel();
00364   else if (size>=T1aa_smartlimit2)
00365     j=1;
00366   else if (size>=T1aa_smartlimit1)
00367     j=2;
00368   else
00369     j=4;
00370   if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){
00371     switch ( j){
00372     case 1:
00373       if ( fg!=oldfg_n || bg!=oldbg_n){
00374        oldfg_n=fg;
00375        oldbg_n=bg;
00376        /* computing colors is not necessary here */
00377        T1_AANSetGrayValues( bg, fg);
00378       }
00379       break;
00380     case 2:
00381       if ( fg!=oldfg_l || bg!=oldbg_l){
00382        oldfg_l=fg;
00383        oldbg_l=bg;
00384        T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
00385        T1_AASetGrayValues(aapixels[0],   /* white */
00386                         aapixels[4],
00387                         aapixels[8],
00388                         aapixels[12],
00389                         aapixels[16] ); /* black */
00390       }
00391       break;
00392     case 4:
00393       if ( fg!=oldfg_h || bg!=oldbg_h){
00394        oldfg_h=fg;
00395        oldbg_h=bg;
00396        T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
00397        T1_AAHSetGrayValues( aapixels); 
00398       }
00399       break;
00400     }
00401     lastlevel=j;
00402     oldfg=fg;
00403     oldbg=bg;
00404   }
00405 
00406   if ((pglyph=T1_AASetChar( FontID, charcode, size,
00407                          transform))==NULL){
00408     T1_PrintLog( "T1_AASetCharX()",
00409                "T1_AASetChar() returned NULL-pointer!",
00410                T1LOG_WARNING);
00411     return(NULL);
00412   }
00413 
00414   /* Check for empty bitmap */
00415   if (pglyph->bits==NULL) {
00416     xglyph=*pglyph;
00417     return( &xglyph);
00418   }
00419 
00420   width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
00421   height=pglyph->metrics.ascent-pglyph->metrics.descent;
00422   
00423               
00424   /* Correct position */
00425   if (T1_lposition){
00426     x_dest += pglyph->metrics.leftSideBearing;
00427     y_dest -= pglyph->metrics.ascent;
00428   }
00429 
00430   if (opaque==0){
00431     clipmask_v=height;
00432     clipmask_h=width;
00433     width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp;
00434     clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); 
00435     if (clipmask_ptr==NULL){
00436       T1_errno=T1ERR_ALLOC_MEM;
00437       return(NULL);
00438     }
00439     /* Note: We pad the clipmask always to byte boundary */
00440     if (pglyph->bpp==8)
00441       for ( k=0; k<clipmask_v; k++){
00442        line_off=k*(PAD(clipmask_h, 8)>>3);
00443        for (j=0; j<clipmask_h; j++){
00444          if (((char *)(pglyph->bits))[k*width_pad+j]!=bg)
00445            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00446        }
00447       }
00448     else if (pglyph->bpp==16)
00449       for ( k=0; k<clipmask_v; k++){
00450        line_off=k*(PAD(clipmask_h, 8)>>3);
00451        for (j=0; j<clipmask_h; j++){
00452          if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg)
00453            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00454        }
00455       }
00456     else 
00457       for ( k=0; k<clipmask_v; k++){
00458        line_off=k*(PAD(clipmask_h, 8)>>3);
00459        for (j=0; j<clipmask_h; j++){
00460          if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg)
00461            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00462        }
00463       }
00464     
00465     clipmask=XCreateBitmapFromData( T1_display,
00466                                 d,
00467                                 (char *)clipmask_ptr,
00468                                 width,
00469                                 height
00470                                 );
00471     free( clipmask_ptr);
00472     XSetClipMask(T1_display, gc, clipmask);
00473     XSetClipOrigin(T1_display, gc, x_dest, y_dest);
00474 
00475   }
00476   ximage=XCreateImage( T1_display,
00477                      T1_visual,
00478                      T1_depth, 
00479                      ZPixmap, /* XYBitmap or XYPixmap */
00480                      0, /* No offset */
00481                      (char *)pglyph->bits,
00482                      width,
00483                      height,
00484                      pFontBase->bitmap_pad,  
00485                      0 /*PAD(width,8)/8*/  /* number of bytes per line */
00486                      );
00487   ximage->byte_order=T1_byte_order;
00488   XPutImage(T1_display,
00489            d,
00490            gc,
00491            ximage,
00492            0,  
00493            0,  
00494            x_dest,  
00495            y_dest,  
00496            width,
00497            height
00498            );
00499   XDestroyImage(ximage);
00500   if (clipmask){
00501     XFreePixmap( T1_display, clipmask);
00502     clipmask=0;
00503     XSetClipMask(T1_display, gc, None);
00504     XSetClipOrigin(T1_display, gc, 0, 0);
00505   }
00506   
00507   pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
00508   xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
00509   xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
00510   xglyph.metrics.advanceX=pglyph->metrics.advanceX;
00511   xglyph.metrics.advanceY=pglyph->metrics.advanceY;
00512   xglyph.metrics.ascent=pglyph->metrics.ascent;
00513   xglyph.metrics.descent=pglyph->metrics.descent;
00514   xglyph.bpp=pglyph->bpp;
00515   
00516   return( &xglyph);
00517   
00518   
00519 }
00520 
00521 
00522 
00523 /* T1_AASetStringX(...): Draw a string of characters into an X11 drawable */
00524 GLYPH *T1_AASetStringX( HDC hDc, int mode, int x_dest, int y_dest,
00525                      int FontID, char *string, int len, 
00526                      long spaceoff, int modflag, float size,
00527                      T1_TMATRIX *transform)
00528 {
00529   int  j, k;
00530 
00531   GLYPH  *pglyph;
00532   XImage *ximage;
00533 
00534   
00535   static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
00536 
00537   int height, width, width_pad;
00538   
00539   XGCValues xgcvalues;
00540   static unsigned long fg, bg;
00541   
00542 
00543   Pixmap clipmask=0;
00544   int clipmask_h, clipmask_v, line_off;
00545   char *clipmask_ptr;
00546   
00547   int opaque;
00548   
00549 
00550   xglyph.metrics.leftSideBearing=0;
00551   xglyph.metrics.rightSideBearing=0;
00552   xglyph.metrics.advanceX=0;
00553   xglyph.metrics.advanceY=0;
00554   xglyph.metrics.ascent=0;
00555   xglyph.metrics.descent=0;
00556   xglyph.pFontCacheInfo=NULL;
00557   
00558 
00559   opaque=mode;
00560   
00561   
00562   /* In order to be able to contruct the pixmap we need to know
00563      foreground and background color as well the copy function */
00564   XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues);
00565   fg=xgcvalues.foreground;
00566   bg=xgcvalues.background;
00567   
00568   xglyph.bpp=T1_depth;
00569   
00570   /* At this point we must compute the colors that are needed to do
00571      antialiasing between fore- and background. The following function
00572      fills the static aacolors */
00573   if (T1aa_SmartOn==0)
00574     j=T1_AAGetLevel();
00575   else if (size>=T1aa_smartlimit2)
00576     j=1;
00577   else if (size>=T1aa_smartlimit1)
00578     j=2;
00579   else
00580     j=4;
00581   if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){
00582     switch ( j){
00583     case 1:
00584       if ( fg!=oldfg_n || bg!=oldbg_n){
00585        oldfg_n=fg;
00586        oldbg_n=bg;
00587        /* computing colors is not necessary here */
00588        T1_AANSetGrayValues( bg, fg);
00589       }
00590       break;
00591     case 2:
00592       if ( fg!=oldfg_l || bg!=oldbg_l){
00593        oldfg_l=fg;
00594        oldbg_l=bg;
00595        T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
00596        T1_AASetGrayValues(aapixels[0],   /* white */
00597                         aapixels[4],
00598                         aapixels[8],
00599                         aapixels[12],
00600                         aapixels[16] ); /* black */
00601       }
00602       break;
00603     case 4:
00604       if ( fg!=oldfg_h || bg!=oldbg_h){
00605        oldfg_h=fg;
00606        oldbg_h=bg;
00607        T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
00608        T1_AAHSetGrayValues( aapixels); 
00609       }
00610       break;
00611     }
00612     lastlevel=j;
00613     oldfg=fg;
00614     oldbg=bg;
00615   }
00616 
00617   
00618   if ((pglyph=T1_AASetString( FontID, string, len, 
00619                            spaceoff, modflag, size,
00620                            transform))==NULL){
00621     T1_PrintLog( "T1_AASetStringX()",
00622                "T1_AASetString() returned NULL-pointer!",
00623                T1LOG_WARNING);
00624     return(NULL);
00625   }
00626 
00627   /* Check for empty bitmap */
00628   if (pglyph->bits==NULL) {
00629     xglyph=*pglyph;
00630     return( &xglyph);
00631   }
00632 
00633   width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
00634   height=pglyph->metrics.ascent-pglyph->metrics.descent;
00635   
00636   
00637   /* Correct position */
00638   if (T1_lposition){
00639     x_dest += pglyph->metrics.leftSideBearing;
00640     y_dest -= pglyph->metrics.ascent;
00641   }
00642 
00643   if (opaque==0){
00644     clipmask_v=height;
00645     clipmask_h=width;
00646     width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp;
00647     clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char));
00648     if (clipmask_ptr==NULL){
00649       T1_errno=T1ERR_ALLOC_MEM;
00650       return(NULL);
00651     }
00652     /* Note: We pad the clipmask always to byte boundary */
00653     if (pglyph->bpp==8)
00654       for ( k=0; k<clipmask_v; k++){
00655        line_off=k*(PAD(clipmask_h, 8)>>3);
00656        for (j=0; j<clipmask_h; j++){
00657          if (((char *)(pglyph->bits))[k*width_pad+j]!=bg)
00658            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00659        }
00660       }
00661     else if (pglyph->bpp==16)
00662       for ( k=0; k<clipmask_v; k++){
00663        line_off=k*(PAD(clipmask_h, 8)>>3);
00664        for (j=0; j<clipmask_h; j++){
00665          if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg)
00666            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00667        }
00668       }
00669     else 
00670       for ( k=0; k<clipmask_v; k++){
00671        line_off=k*(PAD(clipmask_h, 8)>>3);
00672        for (j=0; j<clipmask_h; j++){
00673          if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg)
00674            clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
00675        }
00676       }
00677     
00678     clipmask=XCreateBitmapFromData( T1_display,
00679                                 d,
00680                                 (char *)clipmask_ptr,
00681                                 width,
00682                                 height
00683                                 );
00684     free( clipmask_ptr);
00685     XSetClipMask(T1_display, gc, clipmask);
00686     XSetClipOrigin(T1_display, gc, x_dest, y_dest);
00687 
00688   }
00689   ximage=XCreateImage( T1_display,
00690                      T1_visual,
00691                      T1_depth, 
00692                      ZPixmap, /* XYBitmap or XYPixmap */
00693                      0, /* No offset */
00694                      (char *)pglyph->bits,
00695                      width,
00696                      height,
00697                      pFontBase->bitmap_pad,  /* lines padded to bytes */
00698                      0 /*PAD(width,8)/8*/  /* number of bytes per line */
00699                      );
00700   ximage->byte_order=T1_byte_order;
00701   XPutImage(T1_display,
00702            d,
00703            gc,
00704            ximage,
00705            0,  
00706            0,  
00707            x_dest,  
00708            y_dest,  
00709            width,
00710            height
00711            );
00712   XDestroyImage(ximage);
00713   if (clipmask){
00714     XFreePixmap( T1_display, clipmask);
00715     clipmask=0;
00716     XSetClipMask(T1_display, gc, None);
00717     XSetClipOrigin(T1_display, gc, 0, 0);
00718   }
00719   
00720   pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
00721   xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
00722   xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
00723   xglyph.metrics.advanceX=pglyph->metrics.advanceX;
00724   xglyph.metrics.advanceY=pglyph->metrics.advanceY;
00725   xglyph.metrics.ascent=pglyph->metrics.ascent;
00726   xglyph.metrics.descent=pglyph->metrics.descent;
00727   xglyph.bpp=pglyph->bpp;
00728   
00729   return( &xglyph);
00730   
00731   
00732 }
00733 
00734 
00735 
00736 /* T1_ComputeAAColorsX(): Compute the antialiasing colors in dependency
00737    of foreground and background */
00738 int T1_ComputeAAColorsX( unsigned long fg, unsigned long bg, int nolevels)
00739 {
00740 
00741   static unsigned long last_fg;
00742   static unsigned long last_bg;
00743   unsigned long delta_red, delta_green, delta_blue;
00744   int i;
00745   int nocolors=0;
00746   
00747   
00748   aacolors[0].pixel=bg;
00749   aacolors[nolevels-1].pixel=fg;
00750 
00751   if ((fg==last_fg)&&(bg==last_bg))
00752     return(nocolors);
00753   
00754   /* Get RGB values for fore- and background */
00755   XQueryColor( T1_display, T1_colormap, &aacolors[0]);
00756   XQueryColor( T1_display, T1_colormap, &aacolors[nolevels-1]);
00757   delta_red   = (aacolors[nolevels-1].red - aacolors[0].red)/(nolevels-1);
00758   delta_green = (aacolors[nolevels-1].green - aacolors[0].green)/(nolevels-1);
00759   delta_blue  = (aacolors[nolevels-1].blue - aacolors[0].blue)/(nolevels-1);
00760   aapixels[0]=aacolors[0].pixel;
00761   aapixels[nolevels-1]=aacolors[nolevels-1].pixel;
00762 
00763   
00764   for (i=1; i<nolevels-1; i++){
00765     aacolors[i].red   = aacolors[i-1].red + delta_red;
00766     aacolors[i].green = aacolors[i-1].green + delta_green;
00767     aacolors[i].blue  = aacolors[i-1].blue + delta_blue;
00768     /* Allocate color in current palette */
00769     if (XAllocColor( T1_display, T1_colormap, &aacolors[i])!=0){
00770       aapixels[i]=aacolors[i].pixel;
00771       nocolors++;
00772     }
00773     
00774   }
00775   
00776   return(nocolors);
00777 
00778 }
00779 
00780 
00781 
00782 /* Set the positioning switch */
00783 void T1_LogicalPositionX( int pos_switch)
00784 {
00785   if (pos_switch)
00786     T1_lposition=1;
00787   else
00788     T1_lposition=0;
00789   return;
00790 }
00791