Back to index

tetex-bin  3.0
t1aaset.c
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------------
00002   ----- File:        t1aaset.c 
00003   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
00004                      Subsampling based on code by Raph Levien (raph@acm.org)
00005   ----- Date:        2003-01-02
00006   ----- Description: This file is part of the t1-library. It contains
00007                      functions for antialiased setting of characters
00008                    and strings of characters.
00009   ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
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 T1AASET_C
00031 
00032 
00033 #include <stdio.h>
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <fcntl.h>
00037 #if defined(_MSC_VER)
00038 # include <io.h>
00039 # include <sys/types.h>
00040 # include <sys/stat.h>
00041 #else
00042 # include <unistd.h>
00043 #endif
00044 #include <stdlib.h>
00045 #include <math.h>
00046 #include <string.h>
00047 
00048 #include "../type1/ffilest.h"
00049 #include "../type1/types.h"
00050 #include "parseAFM.h" 
00051 #include "../type1/objects.h"
00052 #include "../type1/spaces.h"
00053 #include "../type1/util.h"
00054 #include "../type1/fontfcn.h"
00055 #include "../type1/regions.h"
00056 
00057 #include "t1types.h"
00058 #include "t1extern.h"
00059 #include "t1aaset.h"
00060 #include "t1set.h"
00061 #include "t1load.h"
00062 #include "t1finfo.h"
00063 #include "t1misc.h"
00064 #include "t1base.h"
00065 #include "t1outline.h"
00066 
00067 
00068 #define DEFAULTBPP 8
00069 
00070 
00071 /* As a fall back */
00072 #ifndef T1_AA_TYPE16 
00073 #define T1_AA_TYPE16    short
00074 #endif
00075 #ifndef T1_AA_TYPE32 
00076 #define T1_AA_TYPE32    int
00077 #endif
00078 
00079 
00080 /* In the following arrays take the gray values. Entry 0 is associated
00081    with the white (background) value and the max entry is the
00082    black (foreground) value. */
00083 static unsigned T1_AA_TYPE32 gv[5]={0,0,0,0,0};
00084 static unsigned T1_AA_TYPE32 gv_h[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00085 static unsigned T1_AA_TYPE32 gv_n[2]={0,0};
00086 
00087 static int T1aa_level=T1_AA_LOW;  /* The default value */
00088 static T1_AA_TYPE32 T1aa_lut[625];
00089 static int T1aa_count[256];
00090 static T1_AA_TYPE32 T1aa_h_lut[289];
00091 static int T1aa_h_count[256];
00092 static T1_AA_TYPE32 T1aa_n_lut[64];
00093 
00094 /* This global is for querying the current bg from other parts
00095    of t1lib */
00096 unsigned T1_AA_TYPE32 T1aa_bg=0;
00097 
00098 /* The limit values for smart antialiasing */
00099 float T1aa_smartlimit1=T1_AA_SMARTLIMIT1;
00100 float T1aa_smartlimit2=T1_AA_SMARTLIMIT2;
00101 int   T1aa_SmartOn=0;     /* We do not enable smart AA by default */
00102 
00103 /* T1_AAInit: This function must be called whenever the T1aa_gray_val
00104    or T1aa_bpp variables change, or the level changes. */
00105 static int T1_AAInit ( int level )
00106 {
00107   int i;
00108   int i0, i1, i2, i3;
00109   int movelow=0, movehigh=0, indlow=0, indhigh=0;
00110 
00111   /* Note: movelow, movehigh, indlow and indhigh take care for proper
00112      byte swapping in dependence of endianess for level=4 */
00113   if (level==T1_AA_NONE){
00114     if (T1aa_bpp==8){
00115       if (pFontBase->endian){
00116        movelow=3;
00117        movehigh=2;
00118       }
00119       else{
00120        movelow=0;
00121        movehigh=1;
00122       }
00123     }
00124     else if (T1aa_bpp==16){
00125       if (pFontBase->endian){
00126        movelow=1;
00127        movehigh=0;
00128       }
00129       else{
00130        movelow=0;
00131        movehigh=1;
00132       }
00133     }
00134   }
00135 
00136   if (level==T1_AA_HIGH){
00137     
00138     if (T1aa_bpp==8){
00139       if (pFontBase->endian){
00140        indlow=17;
00141        indhigh=1;
00142        movelow=3;
00143        movehigh=2;
00144       }
00145       else{
00146        indlow=1;
00147        indhigh=17;
00148        movelow=0;
00149        movehigh=1;
00150       }
00151     }
00152     else if (T1aa_bpp==16){
00153       if (pFontBase->endian){
00154        indlow=17;
00155        indhigh=1;
00156        movelow=1;
00157        movehigh=0;
00158       }
00159       else{
00160        indlow=1;
00161        indhigh=17;
00162        movelow=0;
00163        movehigh=1;
00164       }
00165     }
00166     else if (T1aa_bpp==32){
00167       indlow=1;
00168       indhigh=17;
00169     }
00170     for (i = 0; i < 256; i++) {
00171       T1aa_h_count[i] = 0;
00172       if (i & 0x80) T1aa_h_count[i] += indhigh; 
00173       if (i & 0x40) T1aa_h_count[i] += indhigh;
00174       if (i & 0x20) T1aa_h_count[i] += indhigh;
00175       if (i & 0x10) T1aa_h_count[i] += indhigh;
00176       if (i & 0x08) T1aa_h_count[i] += indlow;
00177       if (i & 0x04) T1aa_h_count[i] += indlow;
00178       if (i & 0x02) T1aa_h_count[i] += indlow;
00179       if (i & 0x01) T1aa_h_count[i] += indlow;
00180     }
00181   }
00182   
00183   if (level == 2 && T1aa_bpp == 8) {
00184     for (i0 = 0; i0 < 5; i0++)
00185       for (i1 = 0; i1 < 5; i1++)
00186        for (i2 = 0; i2 < 5; i2++)
00187          for (i3 = 0; i3 < 5; i3++) {
00188            ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4] = gv[i3];
00189            ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 1] = gv[i2];
00190            ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 2] = gv[i1];
00191            ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 3] = gv[i0];
00192          }
00193     for (i = 0; i < 256; i++) {
00194       T1aa_count[i] = 0;
00195       if (i & 0x80) T1aa_count[i] += 125;
00196       if (i & 0x40) T1aa_count[i] += 125;
00197       if (i & 0x20) T1aa_count[i] += 25;
00198       if (i & 0x10) T1aa_count[i] += 25;
00199       if (i & 0x08) T1aa_count[i] += 5;
00200       if (i & 0x04) T1aa_count[i] += 5;
00201       if (i & 0x02) T1aa_count[i] += 1;
00202       if (i & 0x01) T1aa_count[i] += 1;
00203     }
00204     return(0);
00205   } else if (level == 2 && T1aa_bpp == 16) {
00206     for (i0 = 0; i0 < 5; i0++)
00207       for (i1 = 0; i1 < 5; i1++) {
00208        ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2] = gv[i1];
00209        ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2 + 1] = gv[i0];
00210       }
00211     for (i = 0; i < 256; i++) {
00212       T1aa_count[i] = 0;
00213       if (i & 0x80) T1aa_count[i] += 160;
00214       if (i & 0x40) T1aa_count[i] += 160;
00215       if (i & 0x20) T1aa_count[i] += 32;
00216       if (i & 0x10) T1aa_count[i] += 32;
00217       if (i & 0x08) T1aa_count[i] += 5;
00218       if (i & 0x04) T1aa_count[i] += 5;
00219       if (i & 0x02) T1aa_count[i] += 1;
00220       if (i & 0x01) T1aa_count[i] += 1;
00221     }
00222     return(0);
00223   } else if (level == 2 && T1aa_bpp == 32) {
00224     for (i0 = 0; i0 < 5; i0++)
00225       ((T1_AA_TYPE32 *)T1aa_lut)[i0] = gv[i0];
00226     for (i = 0; i < 256; i++) {
00227       T1aa_count[i] = 0;
00228       if (i & 0x80) T1aa_count[i] += 512;
00229       if (i & 0x40) T1aa_count[i] += 512;
00230       if (i & 0x20) T1aa_count[i] += 64;
00231       if (i & 0x10) T1aa_count[i] += 64;
00232       if (i & 0x08) T1aa_count[i] += 8;
00233       if (i & 0x04) T1aa_count[i] += 8;
00234       if (i & 0x02) T1aa_count[i] += 1;
00235       if (i & 0x01) T1aa_count[i] += 1;
00236     }
00237     return(0);
00238   }
00239   else if (level == 4 && T1aa_bpp == 8) {
00240     for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
00241       for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
00242        ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movelow] = gv_h[i1];
00243        ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movehigh] = gv_h[i0];
00244       }
00245     }
00246     return(0);
00247   }
00248   else if (level == 4 && T1aa_bpp == 16) {
00249     for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
00250       for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
00251        ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movelow] = gv_h[i1];
00252        ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movehigh] = gv_h[i0];
00253       }
00254     }
00255     return(0);
00256   }
00257   else if (level == 4 && T1aa_bpp == 32) {
00258     for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
00259       for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
00260        ((T1_AA_TYPE32 *)T1aa_h_lut)[(i0 * 17 + i1)] = gv_h[i1];
00261       }
00262     }
00263     return(0);
00264   }
00265   else if (level == 1 && T1aa_bpp == 8) {
00266     for (i0=0; i0<16; i0++) {
00267       ((char *)T1aa_n_lut)[i0*4+movelow]=gv_n[i0 & 0x01];
00268       ((char *)T1aa_n_lut)[i0*4+movelow+1]=gv_n[(i0>>1) & 0x01];
00269       ((char *)T1aa_n_lut)[i0*4+movelow+2]=gv_n[(i0>>2) & 0x01];
00270       ((char *)T1aa_n_lut)[i0*4+movelow+3]=gv_n[(i0>>3) & 0x01];
00271     }
00272     return(0);
00273   }
00274   else if (level == 1 && T1aa_bpp == 16) {
00275     for (i0=0; i0<4; i0++) {
00276       ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2]=gv_n[i0 & 0x01];
00277       ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2+1]=gv_n[(i0>>1) & 0x01];
00278     }
00279     return(0);
00280   }
00281   else if (level == 1 && T1aa_bpp == 32) {
00282     for ( i0=0; i0<2; i0++) {
00283       ((T1_AA_TYPE32 *)T1aa_n_lut)[i0]=gv_n[i0];
00284     }
00285     return(0);
00286   }
00287   else {
00288     /* unsupported combination of level and bpp -> we set T1_errno and
00289        put an entry into the logfile! */
00290     T1_errno=T1ERR_INVALID_PARAMETER;
00291     sprintf( err_warn_msg_buf,
00292             "Unsupported AA specification: level=%d, bpp=%d",
00293             level, T1aa_bpp);
00294     T1_PrintLog( "T1_AAInit()", err_warn_msg_buf, T1LOG_WARNING);
00295   }
00296   return(1);
00297 }
00298 
00299 
00300 /* T1_AADoLine: Create a single scanline of antialiased output. The
00301    (x, y) arguments refer to the number of pixels in the input image
00302    to convert down. The width argument is the number of bytes
00303    separating scanlines in the input. The quantity hcorr describes the
00304    number of subpixels. It is the shift of the oversampled bitmap to
00305    the right */
00306 static void T1_AADoLine ( int level, int x, int y, int width,
00307                        char *c_in_ptr, char *target_ptr, int hcorr )
00308 {
00309   int i=0;
00310   int size;
00311   int count=0;
00312   int mod;
00313   
00314   unsigned char bcarry1=0, bcarry2=0, bcarry3=0, bcarry4=0;
00315   
00316   static char *align_buf = NULL;
00317   static int align_buf_size = 0;
00318   unsigned char *in_ptr;
00319   
00320   int new_size=55;
00321   register char *optr;
00322 
00323   
00324   
00325   /* We convert the input pointer to unsigned since we use it as index! */
00326   in_ptr=(unsigned char*)c_in_ptr;
00327   
00328   
00329   if ((long)target_ptr & 3){
00330     /* calculate new_size (size in bytes of output buffer */
00331     if (level == T1_AA_LOW){
00332       new_size=((x + hcorr + 1) >> 1) * (T1aa_bpp >> 3);
00333     }
00334     else{ /* T1_AA_HIGH */
00335       new_size = ((x + hcorr + 3) >> 2) * (T1aa_bpp >> 3);
00336     }
00337     if (new_size > align_buf_size)
00338       {
00339        if (align_buf)
00340          free (align_buf);
00341        /* Note: we allocate 12 more than necessary to have tolerance
00342           at the end of line */
00343        align_buf = (char *)malloc(new_size+12);
00344        align_buf_size = new_size;
00345       }
00346     optr = align_buf;
00347   }
00348   else
00349     optr = target_ptr;
00350 
00351 
00352   /* size: The number of valid byte in the input string, i.e., the number of bytes
00353            partially filled with pixels before shifting with hcorr.
00354      mod:  Is 1 if after shifting with hcorr the last byte in the input line has an
00355            overflow.
00356   */
00357   
00358   if (level == T1_AA_LOW) {
00359     size=(x+7)>>3; 
00360     mod=(x+hcorr)>(size*8) ? 1 : 0;
00361     
00362     if (T1aa_bpp == 8) {
00363       if (y == 2){
00364        for (i = 0; i < size; i++) {
00365          ((T1_AA_TYPE32 *)optr)[i] =
00366            T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00367                     T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
00368          bcarry1=in_ptr[i]>>(8-hcorr);
00369          bcarry2=in_ptr[i+width]>>(8-hcorr);
00370        }
00371        if (size==0){
00372          bcarry1=in_ptr[0]<<hcorr;
00373          bcarry2=in_ptr[width]<<hcorr;
00374        }
00375       }
00376       else if (y == 1){
00377        for (i = 0; i < size; i++) {
00378          ((T1_AA_TYPE32 *)optr)[i] =
00379            T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
00380          bcarry1=in_ptr[i]>>(8-hcorr);
00381        }
00382        if (size==0){
00383          bcarry1=in_ptr[0]<<hcorr;
00384        }
00385       }
00386       if (mod) {
00387        if (y == 2)
00388          ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1] +
00389                                          T1aa_count[bcarry2])];
00390        else if (y == 1)
00391          ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1])];
00392       }
00393     }
00394     else if (T1aa_bpp == 16) {
00395       if (y == 2){
00396        for (i = 0; i < size; i++) {
00397          count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]
00398            + T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)];
00399          ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
00400          ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
00401          bcarry1=in_ptr[i]>>(8-hcorr);
00402          bcarry2=in_ptr[i+width]>>(8-hcorr);
00403        }
00404        if (size==0){
00405          bcarry1=in_ptr[0]<<hcorr;
00406          bcarry2=in_ptr[width]<<hcorr;
00407        }
00408       }
00409       else if (y == 1){
00410        for (i = 0; i < size; i++) {
00411          count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
00412          ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
00413          ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
00414          bcarry1=in_ptr[i]>>(8-hcorr);
00415        }
00416        if (size==0){
00417          bcarry1=in_ptr[0]<<hcorr;
00418        }
00419       }
00420       if (mod){
00421        if (y == 2)
00422          count = T1aa_count[bcarry1] +
00423            T1aa_count[bcarry2];
00424        else if (y == 1)
00425          count = T1aa_count[bcarry1];
00426        ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
00427        ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
00428       }
00429     }
00430     else if (T1aa_bpp == 32) {
00431       if (y == 2){
00432        for (i = 0; i < size; i++) {
00433          count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00434            T1aa_count[(unsigned char)((in_ptr[i+width]<<hcorr)|bcarry2)];
00435          ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
00436          ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
00437          ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
00438          ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
00439          bcarry1=in_ptr[i]>>(8-hcorr);
00440          bcarry2=in_ptr[i+width]>>(8-hcorr);
00441        }
00442        if (size==0){
00443          bcarry1=in_ptr[0]<<hcorr;
00444          bcarry2=in_ptr[width]<<hcorr;
00445        }
00446       }
00447       else if (y == 1) {
00448        for (i = 0; i < size; i++) {
00449          count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
00450          ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
00451          ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
00452          ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
00453          ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
00454          bcarry1=in_ptr[i]>>(8-hcorr);
00455        }
00456        if (size==0){
00457          bcarry1=in_ptr[0]<<hcorr;
00458        }
00459       }
00460       if(mod) {
00461        if (y == 2){
00462          count = T1aa_count[bcarry1] +
00463            T1aa_count[bcarry2];
00464        }
00465        else if (y == 1){
00466          count = T1aa_count[bcarry1];
00467        }
00468        ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
00469        ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
00470        ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
00471        ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
00472       }
00473     }
00474   }
00475   else if (level==T1_AA_HIGH){ 
00476     size=(x+7)>>3; 
00477     mod=(x+hcorr)>(size*8) ? 1 : 0;
00478     
00479     if (T1aa_bpp == 8) {
00480       if (y == 4){
00481        for (i = 0; i < size; i++) {
00482          ((T1_AA_TYPE16 *)optr)[i] =
00483            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + 
00484                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + 
00485                      T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + 
00486                      T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])];
00487          bcarry1=in_ptr[i]>>(8-hcorr);
00488          bcarry2=in_ptr[i+width]>>(8-hcorr);
00489          bcarry3=in_ptr[i+2*width]>>(8-hcorr);
00490          bcarry4=in_ptr[i+3*width]>>(8-hcorr);
00491        }
00492       }
00493       else if (y == 3){
00494        for (i = 0; i < size; i++) {
00495          ((T1_AA_TYPE16 *)optr)[i] =
00496            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00497                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
00498                      T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])];
00499          bcarry1=in_ptr[i]>>(8-hcorr);
00500          bcarry2=in_ptr[i+width]>>(8-hcorr);
00501          bcarry3=in_ptr[i+2*width]>>(8-hcorr);
00502        }
00503       }
00504       else if (y == 2){
00505        for (i = 0; i < size; i++) {
00506          ((T1_AA_TYPE16 *)optr)[i] =
00507            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00508                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
00509          bcarry1=in_ptr[i]>>(8-hcorr);
00510          bcarry2=in_ptr[i+width]>>(8-hcorr);
00511        }
00512       }
00513       else if (y == 1){
00514        for (i = 0; i < size; i++) {
00515          ((T1_AA_TYPE16 *)optr)[i] =
00516            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
00517          bcarry1=in_ptr[i]>>(8-hcorr);
00518        }
00519       }
00520       if (mod) {
00521        if (y == 4)
00522          ((T1_AA_TYPE16 *)optr)[i] =
00523            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00524                      T1aa_h_count[bcarry2] + 
00525                      T1aa_h_count[bcarry3] +
00526                      T1aa_h_count[bcarry4])];
00527        else if (y == 3)
00528          ((T1_AA_TYPE16 *)optr)[i] =
00529            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00530                      T1aa_h_count[bcarry2] + 
00531                      T1aa_h_count[bcarry3])];
00532        else if (y == 2)
00533          ((T1_AA_TYPE16 *)optr)[i] =
00534            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00535                      T1aa_h_count[bcarry2])];
00536        else if (y == 1)
00537          ((T1_AA_TYPE16 *)optr)[i] =
00538            T1aa_h_lut[(T1aa_h_count[bcarry1])];
00539       }
00540     } else if (T1aa_bpp == 16) {
00541       if (y == 4){
00542        for (i = 0; i < size; i++) {
00543          ((T1_AA_TYPE32 *)optr)[i] =
00544            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + 
00545                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + 
00546                      T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + 
00547                      T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])];
00548          bcarry1=in_ptr[i]>>(8-hcorr);
00549          bcarry2=in_ptr[i+width]>>(8-hcorr);
00550          bcarry3=in_ptr[i+2*width]>>(8-hcorr);
00551          bcarry4=in_ptr[i+3*width]>>(8-hcorr);
00552        }
00553        if (size==0){
00554          bcarry1=in_ptr[0]<<hcorr;
00555          bcarry2=in_ptr[width]<<hcorr;
00556          bcarry3=in_ptr[2*width]<<hcorr;
00557          bcarry4=in_ptr[3*width]<<hcorr;
00558        }
00559       }
00560       else if (y == 3){
00561        for (i = 0; i < size; i++) {
00562          ((T1_AA_TYPE32 *)optr)[i] =
00563            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00564                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
00565                      T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])];
00566          bcarry1=in_ptr[i]>>(8-hcorr);
00567          bcarry2=in_ptr[i+2*width]>>(8-hcorr);
00568          bcarry3=in_ptr[i+3*width]>>(8-hcorr);
00569        }
00570        if (size==0){
00571          bcarry1=in_ptr[0]<<hcorr;
00572          bcarry2=in_ptr[width]<<hcorr;
00573          bcarry3=in_ptr[2*width]<<hcorr;
00574        }
00575       }
00576       else if (y == 2){
00577        for (i = 0; i < size; i++) {
00578          ((T1_AA_TYPE32 *)optr)[i] =
00579            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00580                      T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
00581          bcarry1=in_ptr[i]>>(8-hcorr);
00582          bcarry2=in_ptr[i+width]>>(8-hcorr);
00583        }
00584        if (size==0){
00585          bcarry1=in_ptr[0]<<hcorr;
00586          bcarry2=in_ptr[width]<<hcorr;
00587        }
00588       }
00589       else if (y == 1){
00590        for (i = 0; i < size; i++) {
00591          ((T1_AA_TYPE32 *)optr)[i] =
00592            T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
00593          bcarry1=in_ptr[i]>>(8-hcorr);
00594        }
00595        if (size==0){
00596          bcarry1=in_ptr[0]<<hcorr;
00597        }
00598       }
00599       if (mod) {
00600        if (y == 4)
00601          ((T1_AA_TYPE32 *)optr)[i] =
00602            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00603                      T1aa_h_count[bcarry2] + 
00604                      T1aa_h_count[bcarry3] +
00605                      T1aa_h_count[bcarry4])];
00606        else if (y == 3)
00607          ((T1_AA_TYPE32 *)optr)[i] =
00608            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00609                      T1aa_h_count[bcarry2] + 
00610                      T1aa_h_count[bcarry3])];
00611        else if (y == 2)
00612          ((T1_AA_TYPE32 *)optr)[i] =
00613            T1aa_h_lut[(T1aa_h_count[bcarry1] +
00614                      T1aa_h_count[bcarry2])];
00615        else if (y == 1)
00616          ((T1_AA_TYPE32 *)optr)[i] =
00617          T1aa_h_lut[(T1aa_h_count[bcarry1])]; 
00618       }
00619     }
00620     else if (T1aa_bpp == 32) {
00621       if (y == 4){
00622        for (i = 0; i < size; i++) {
00623          count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00624            T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
00625            T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] +
00626            T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)];
00627          ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
00628          ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
00629          bcarry1=in_ptr[i]>>(8-hcorr);
00630          bcarry2=in_ptr[i+width]>>(8-hcorr);
00631          bcarry3=in_ptr[i+2*width]>>(8-hcorr);
00632          bcarry4=in_ptr[i+3*width]>>(8-hcorr);
00633        }
00634        if (size==0){
00635          bcarry1=in_ptr[0]<<hcorr;
00636          bcarry2=in_ptr[width]<<hcorr;
00637          bcarry3=in_ptr[2*width]<<hcorr;
00638          bcarry4=in_ptr[3*width]<<hcorr;
00639        }
00640       }
00641       else if (y == 3){
00642        for (i = 0; i < size; i++) {
00643          count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00644            T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
00645            T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)];
00646          ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
00647          ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
00648          bcarry1=in_ptr[i]>>(8-hcorr);
00649          bcarry2=in_ptr[i+width]>>(8-hcorr);
00650          bcarry3=in_ptr[i+2*width]>>(8-hcorr);
00651        }
00652        if (size==0){
00653          bcarry1=in_ptr[0]<<hcorr;
00654          bcarry2=in_ptr[width]<<hcorr;
00655          bcarry3=in_ptr[2*width]<<hcorr;
00656        }
00657       }
00658       else if (y == 2){
00659        for (i = 0; i < size; i++) {
00660          count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
00661            T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)];
00662          ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
00663          ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
00664          bcarry1=in_ptr[i]>>(8-hcorr);
00665          bcarry2=in_ptr[i+width]>>(8-hcorr);
00666        }
00667        if (size==0){
00668          bcarry1=in_ptr[0]<<hcorr;
00669          bcarry2=in_ptr[width]<<hcorr;
00670        }
00671       }
00672       else if (y == 1){
00673        for (i = 0; i < size; i++) {
00674          count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
00675          ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
00676          ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
00677          bcarry1=in_ptr[i]>>(8-hcorr);
00678        }
00679        if (size==0){
00680          bcarry1=in_ptr[0]<<hcorr;
00681        }
00682       }
00683       if (mod) {
00684        if (y == 4){
00685          count=T1aa_h_count[bcarry1] +
00686            T1aa_h_count[bcarry2] +
00687            T1aa_h_count[bcarry3] +
00688            T1aa_h_count[bcarry4];
00689        }
00690        else if (y == 3)
00691          count=T1aa_h_count[bcarry1] +
00692            T1aa_h_count[bcarry2] +
00693            T1aa_h_count[bcarry3];
00694        else if (y == 2)
00695          count=T1aa_h_count[bcarry1] +
00696            T1aa_h_count[bcarry2];
00697        else if (y == 1)
00698          count=T1aa_h_count[bcarry1];
00699        ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
00700        ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
00701       }
00702     }
00703   }
00704   
00705   /* Copy to target if necessary */
00706   if ((long)target_ptr & 3){
00707     memcpy (target_ptr, align_buf, new_size);
00708   }
00709   
00710 }
00711 
00712 
00713 
00714 /* T1_DoLine(): Generate a scanline of bytes from a scanline of bits */
00715 static void T1_DoLine ( long wd, long paddedW, char *ptr, register char *target_ptr )
00716 {
00717   register int j;
00718   register unsigned char *in_ptr;
00719   T1_AA_TYPE16 *starget_ptr;
00720   T1_AA_TYPE32 *ltarget_ptr;
00721   
00722   in_ptr=(unsigned char *)ptr;
00723   
00724   if (T1aa_bpp==8) {
00725     for ( j=0; j<wd; j++ ){
00726       *target_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x0F];
00727     }
00728   }
00729   else if (T1aa_bpp==16) {
00730     starget_ptr=(T1_AA_TYPE16 *)target_ptr;
00731     for ( j=0; j<wd; j++){
00732       *starget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x03];
00733     }
00734   }
00735   else if (T1aa_bpp==32) {
00736     ltarget_ptr=(T1_AA_TYPE32 *)target_ptr;
00737     for ( j=0; j<wd; j++)
00738       *ltarget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x01];
00739   }
00740   return;
00741 }
00742 
00743 
00744 
00745 /* T1_AASetChar(...): Generate the anti-aliased bitmap for a character */
00746 GLYPH *T1_AASetChar( int FontID, char charcode, float size,
00747                    T1_TMATRIX *transform)
00748 {
00749   
00750   GLYPH *glyph;   /* pointer to bitmap glyph */
00751   static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
00752   long asc, dsc, ht, wd;
00753   long i;
00754   long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
00755   long v_start, v_end;
00756   char *target_ptr;
00757   long offset;
00758   char *ptr;
00759   int y;
00760   long lsb, aalsb, aahstart;
00761   int memsize;
00762   LONG paddedW;
00763   int savelevel;
00764   FONTSIZEDEPS *font_ptr=NULL;
00765   unsigned char ucharcode;
00766   
00767 
00768   /* Reset character glyph, if necessary */
00769   if (aaglyph.bits!=NULL){
00770     free(aaglyph.bits);
00771     aaglyph.bits=NULL;
00772   }
00773   aaglyph.metrics.leftSideBearing=0;
00774   aaglyph.metrics.rightSideBearing=0;
00775   aaglyph.metrics.advanceX=0;
00776   aaglyph.metrics.advanceY=0;
00777   aaglyph.metrics.ascent=0;
00778   aaglyph.metrics.descent=0;
00779   aaglyph.pFontCacheInfo=NULL;
00780   aaglyph.bpp=T1aa_bpp;
00781 
00782 
00783   ucharcode=charcode;
00784   
00785   /* Check for smart antialiasing */
00786   savelevel=T1aa_level;
00787   if (T1aa_SmartOn){
00788     if (size>=T1aa_smartlimit2) {
00789       T1aa_level=T1_AA_NONE;
00790     }
00791     else if (size>=T1aa_smartlimit1) {
00792       T1aa_level=T1_AA_LOW;
00793     }
00794     else {
00795       T1aa_level=T1_AA_HIGH;
00796     }
00797   }
00798 
00799 
00800   /* The following code is only exectued if caching of antialiased
00801      chracters is enabled. */
00802   /* Check if char is in cache */
00803   if ((pFontBase->t1lib_flags & T1_AA_CACHING)) {
00804     if (transform==NULL){
00805       /* if size/aa is not existent we create it */
00806       if ((font_ptr=T1int_QueryFontSize( FontID, size, T1aa_level))==NULL){
00807        /* We create the required size struct and leave the rest
00808           for T1_SetChar() */
00809        font_ptr=T1int_CreateNewFontSize( FontID, size, T1aa_level);
00810        if (font_ptr==NULL){
00811          T1_errno=T1ERR_ALLOC_MEM;
00812          T1aa_level=savelevel;
00813          return(NULL);
00814        }
00815       }
00816       else {/* size is already existent in cache */
00817        if (font_ptr->pFontCache[ucharcode].bits != NULL){
00818          /* Character is already in Chache -> create a copy of cache
00819             and return a pointer to the result: */
00820          memcpy( &aaglyph, &(font_ptr->pFontCache[ucharcode]), sizeof(GLYPH));
00821          memsize = (aaglyph.metrics.ascent-aaglyph.metrics.descent) *
00822            PAD((aaglyph.metrics.rightSideBearing-aaglyph.metrics.leftSideBearing) *
00823               T1aa_bpp,pFontBase->bitmap_pad)/8;
00824          aaglyph.bits = (char *)malloc(memsize*sizeof( char));
00825          if (aaglyph.bits == NULL){
00826            T1_errno=T1ERR_ALLOC_MEM;
00827            T1aa_level=savelevel;
00828            return(NULL);
00829          }
00830          memcpy( aaglyph.bits, font_ptr->pFontCache[ucharcode].bits, memsize);
00831          return(&(aaglyph));
00832        }
00833       }
00834     } /* (transform==NULL) */ 
00835   } /* T1_AA_CACHING */
00836   
00837 
00838   /* First, call routine to rasterize character, all error checking is
00839      done in this function: */ 
00840   if ((glyph=T1_SetChar( FontID, charcode, T1aa_level*size, transform))==NULL){
00841     /* restore level */
00842     T1aa_level=savelevel;
00843     return(NULL); /* An error occured */
00844   }
00845   
00846   /* In case there are no black pixels, we simply set the dimensions and
00847      then return */
00848   if ( glyph->bits == NULL) {
00849     aaglyph.bits=NULL;
00850     aaglyph.metrics.leftSideBearing=0;
00851     aaglyph.metrics.rightSideBearing=0;
00852     aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
00853     aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
00854     aaglyph.metrics.ascent=0;
00855     aaglyph.metrics.descent=0;
00856     aaglyph.pFontCacheInfo=NULL;
00857     /* restore level and return */
00858     T1aa_level=savelevel;
00859     return(&aaglyph);
00860   }
00861 
00862   /* Get dimensions of bitmap: */
00863   asc=glyph->metrics.ascent;
00864   dsc=glyph->metrics.descent;
00865   lsb=glyph->metrics.leftSideBearing;
00866   ht=asc-dsc;
00867   wd=glyph->metrics.rightSideBearing-lsb;
00868 
00869   
00870   
00871   if (T1aa_level==T1_AA_NONE){
00872     /* we only convert bitmap to bytemap */
00873     aaglyph=*glyph;
00874     aaglyph.bpp=T1aa_bpp;
00875     /* Compute scanline length and such */
00876     n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
00877     /* Allocate memory for glyph */
00878     memsize = n_horz_pad*ht*8;
00879     /*    aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */
00880     aaglyph.bits = (char *)malloc(memsize*sizeof( char));
00881     if (aaglyph.bits == NULL) {
00882       T1_errno=T1ERR_ALLOC_MEM;
00883       /* restore level */
00884       T1aa_level=savelevel;
00885       return(NULL);
00886     }
00887     paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
00888     ptr=glyph->bits;
00889     target_ptr=aaglyph.bits;
00890     for (i = 0; i < ht; i++) {
00891       T1_DoLine ( wd, paddedW, ptr, target_ptr );
00892       ptr += paddedW;
00893       target_ptr += n_horz_pad;
00894     }
00895     /* restore level */
00896     T1aa_level=savelevel;
00897     return(&aaglyph);
00898   }
00899   
00900 
00901   /* Set some looping parameters for subsampling */
00902   if (lsb<0){
00903     aalsb=lsb/T1aa_level-1;
00904     aahstart=T1aa_level+(lsb%T1aa_level);
00905   }
00906   else{
00907     aalsb=lsb/T1aa_level;
00908     aahstart=lsb%T1aa_level;
00909   }
00910   
00911   /* The horizontal number of steps: */
00912   n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
00913   /* And the padded value */
00914   n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
00915 
00916   /* vertical number of steps: */
00917   if (asc % T1aa_level){ /* not aligned */
00918     if ( asc > 0){
00919       n_asc=asc/T1aa_level+1;
00920       v_start=asc % T1aa_level;
00921     }
00922     else{
00923       n_asc=asc/T1aa_level;
00924       v_start=T1aa_level + (asc % T1aa_level); 
00925     }
00926   }
00927   else{
00928     n_asc=asc/T1aa_level;
00929     v_start=T1aa_level;
00930   }
00931   if (dsc % T1aa_level){ /* not aligned */
00932     if ( dsc < 0){
00933       n_dsc=dsc/T1aa_level-1;
00934       v_end=-(dsc % T1aa_level);
00935     }
00936     else{
00937       n_dsc=dsc/T1aa_level;
00938       v_end=T1aa_level - (dsc % T1aa_level);
00939     }
00940   }
00941   else{
00942     n_dsc=dsc/T1aa_level;
00943     v_end=T1aa_level;
00944   }
00945   /* the total number of lines: */
00946   n_vert=n_asc-n_dsc;
00947   
00948   /* Allocate memory for glyph */
00949   memsize = n_horz_pad*n_vert;
00950 
00951   /* Note: we allocate 12 bytes more than necessary */
00952   aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
00953   if (aaglyph.bits == NULL) {
00954     T1_errno=T1ERR_ALLOC_MEM;
00955     /* restore level */
00956     T1aa_level=savelevel;
00957     return(NULL);
00958   }
00959   
00960 
00961   paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
00962   offset=0;
00963   target_ptr=aaglyph.bits;
00964   
00965   /* We must check for n_vert==1 because the computation above is not
00966      valid in this case */
00967   if (n_vert==1)
00968     v_start=v_start < v_end ? v_start : v_end;
00969 
00970   ptr = glyph->bits;
00971   for (i = 0; i < n_vert; i++) {
00972     if (i==0)
00973       y=v_start;
00974     else if (i==n_vert-1)
00975       y=v_end;
00976     else
00977       y=T1aa_level;
00978     T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
00979     ptr += y * paddedW;
00980     target_ptr += n_horz_pad;
00981   }
00982   
00983   /* .. and set them in aaglyph */
00984   aaglyph.metrics.leftSideBearing=aalsb;
00985   aaglyph.metrics.rightSideBearing=aalsb + n_horz;
00986   aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
00987   aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
00988   aaglyph.metrics.ascent=n_asc;
00989   aaglyph.metrics.descent=n_dsc;
00990   aaglyph.pFontCacheInfo=NULL;
00991 
00992   
00993   if ((pFontBase->t1lib_flags & T1_AA_CACHING) && (transform==NULL)) {
00994     /* Put char into cache area */
00995     memcpy( &(font_ptr->pFontCache[ucharcode]), &aaglyph, sizeof(GLYPH));
00996     font_ptr->pFontCache[ucharcode].bits = (char *)malloc(memsize*sizeof( char));
00997     if (font_ptr->pFontCache[ucharcode].bits == NULL){
00998       T1_errno=T1ERR_ALLOC_MEM;
00999       T1aa_level=savelevel;
01000       return(NULL);
01001     }
01002     memcpy( font_ptr->pFontCache[ucharcode].bits, aaglyph.bits, memsize);
01003   }
01004   
01005   /* restore level */
01006   T1aa_level=savelevel;
01007 
01008   return(&aaglyph);
01009 }
01010 
01011 
01012 
01013 /* T1_AASetString(...): Generate the antialiased bitmap for a
01014    string of characters */
01015 GLYPH *T1_AASetString( int FontID, char *string, int len, 
01016                      long spaceoff, int modflag, float size,
01017                      T1_TMATRIX *transform)
01018 {
01019   GLYPH *glyph;   /* pointer to bitmap glyph */
01020   static GLYPH aastring_glyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
01021   long asc, dsc, ht, wd;
01022   long i;
01023   long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
01024   long v_start, v_end;
01025   char *target_ptr;
01026   long offset;
01027   char *ptr;
01028   int y;
01029   long lsb, aalsb, aahstart;
01030   int memsize;
01031   LONG paddedW;
01032   int savelevel;
01033   
01034   
01035   /* Reset character glyph, if necessary */
01036   if (aastring_glyph.bits!=NULL){
01037     free(aastring_glyph.bits);
01038     aastring_glyph.bits=NULL;
01039   }
01040   aastring_glyph.metrics.leftSideBearing=0;
01041   aastring_glyph.metrics.rightSideBearing=0;
01042   aastring_glyph.metrics.advanceX=0;
01043   aastring_glyph.metrics.advanceY=0;
01044   aastring_glyph.metrics.ascent=0;
01045   aastring_glyph.metrics.descent=0;
01046   aastring_glyph.pFontCacheInfo=NULL;
01047   aastring_glyph.bpp=T1aa_bpp;
01048   
01049 
01050   /* Check for smart antialiasing */
01051   savelevel=T1aa_level;
01052   if (T1aa_SmartOn){
01053     if (size>=T1aa_smartlimit2) {
01054       T1aa_level=T1_AA_NONE;
01055     }
01056     else if (size>=T1aa_smartlimit1) {
01057       T1aa_level=T1_AA_LOW;
01058     }
01059     else {
01060       T1aa_level=T1_AA_HIGH;
01061     }
01062   }
01063     
01064   /* First, call routine to rasterize character, all error checking is
01065      done in this function: */ 
01066   if ((glyph=T1_SetString( FontID, string, len, spaceoff,
01067                         modflag, T1aa_level*size, transform))==NULL){
01068     /* restore level */
01069     T1aa_level=savelevel;
01070     return(NULL); /* An error occured */
01071   }
01072   
01073   /* In case there are no black pixels, we simply set the dimensions and
01074      then return */
01075   if ( glyph->bits == NULL) {
01076     aastring_glyph.bits=NULL;
01077     aastring_glyph.metrics.leftSideBearing=0;
01078     aastring_glyph.metrics.rightSideBearing=0;
01079     aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01080     aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01081     aastring_glyph.metrics.ascent=0;
01082     aastring_glyph.metrics.descent=0;
01083     aastring_glyph.pFontCacheInfo=NULL;
01084     /* restore level and return */
01085     T1aa_level=savelevel;
01086     return(&aastring_glyph);
01087   }
01088 
01089 
01090   /* Get dimensions of bitmap: */
01091   asc=glyph->metrics.ascent;
01092   dsc=glyph->metrics.descent;
01093   lsb=glyph->metrics.leftSideBearing;
01094   ht=asc-dsc;
01095   wd=glyph->metrics.rightSideBearing-lsb;
01096   
01097   if (T1aa_level==T1_AA_NONE){
01098     /* we only convert bitmap to bytemap */
01099     aastring_glyph=*glyph;
01100     aastring_glyph.bpp=T1aa_bpp;
01101     /* Compute scanline length and such */
01102     n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01103     /* Allocate memory for glyph */
01104     memsize = n_horz_pad*ht*8;
01105     aastring_glyph.bits = (char *)malloc(memsize*sizeof( char));
01106     if (aastring_glyph.bits == NULL) {
01107       T1_errno=T1ERR_ALLOC_MEM;
01108       /* restore level */
01109       T1aa_level=savelevel;
01110       return(NULL);
01111     }
01112     paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
01113     ptr=glyph->bits;
01114     target_ptr=aastring_glyph.bits;
01115     for (i = 0; i < ht; i++) {
01116       T1_DoLine ( wd, paddedW, ptr, target_ptr );
01117       ptr += paddedW;
01118       target_ptr += n_horz_pad;
01119     }
01120     /* restore level */
01121     T1aa_level=savelevel;
01122     return(&aastring_glyph);
01123   }
01124   
01125 
01126   /* Set some looping parameters for subsampling */
01127   if (lsb<0){
01128     aalsb=lsb/T1aa_level-1;
01129     aahstart=T1aa_level+(lsb%T1aa_level);
01130   }
01131   else{
01132     aalsb=lsb/T1aa_level;
01133     aahstart=lsb%T1aa_level;
01134   }
01135   
01136   /* The horizontal number of steps: */
01137   n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
01138   /* And the padded value */
01139   n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01140 
01141   /* vertical number of steps: */
01142   if (asc % T1aa_level){ /* not aligned */
01143     if ( asc > 0){
01144       n_asc=asc/T1aa_level+1;
01145       v_start=asc % T1aa_level;
01146     }
01147     else{
01148       n_asc=asc/T1aa_level;
01149       v_start=T1aa_level + (asc % T1aa_level); 
01150     }
01151   }
01152   else{
01153     n_asc=asc/T1aa_level;
01154     v_start=T1aa_level;
01155   }
01156   if (dsc % T1aa_level){ /* not aligned */
01157     if ( dsc < 0){
01158       n_dsc=dsc/T1aa_level-1;
01159       v_end=-(dsc % T1aa_level);
01160     }
01161     else{
01162       n_dsc=dsc/T1aa_level;
01163       v_end=T1aa_level - (dsc % T1aa_level);
01164     }
01165   }
01166   else{
01167     n_dsc=dsc/T1aa_level;
01168     v_end=T1aa_level;
01169   }
01170   /* the total number of lines: */
01171   n_vert=n_asc-n_dsc;
01172   
01173   /* Allocate memory for glyph */
01174   memsize = n_horz_pad*n_vert;
01175 
01176   /* Note: we allocate 12 bytes more than necessary */ 
01177   aastring_glyph.bits = (char *)malloc(memsize*sizeof( char) +12);
01178   if (aastring_glyph.bits == NULL) {
01179     T1_errno=T1ERR_ALLOC_MEM;
01180     return(NULL);
01181   }
01182   
01183   paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
01184   offset=0;
01185   target_ptr=aastring_glyph.bits;
01186   
01187   /* We must check for n_vert==1 because the computation above is not
01188      valid in this case */
01189   if (n_vert==1)
01190     v_start=v_start < v_end ? v_start : v_end;
01191   
01192   ptr = glyph->bits;
01193   for (i = 0; i < n_vert; i++) {
01194     if (i==0)
01195       y=v_start;
01196     else if (i==n_vert-1)
01197       y=v_end;
01198     else
01199       y=T1aa_level;
01200     T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
01201     ptr += y * paddedW;
01202     target_ptr += n_horz_pad;
01203   }
01204   
01205   /* .. and set them in aastring_glyph */
01206   aastring_glyph.metrics.leftSideBearing=aalsb;
01207   aastring_glyph.metrics.rightSideBearing=aalsb + n_horz;
01208   aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01209   aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01210   aastring_glyph.metrics.ascent=n_asc;
01211   aastring_glyph.metrics.descent=n_dsc;
01212   aastring_glyph.pFontCacheInfo=NULL;
01213 
01214   /* restore level */
01215   T1aa_level=savelevel;
01216 
01217   return(&aastring_glyph);
01218 }
01219 
01220 
01221 
01222 /* T1_AASetRect(): Raster a rectangle, whose size is given in charspace units.
01223    The resulting glyph does not cause any escapement. */
01224 GLYPH* T1_AASetRect( int FontID, float size,
01225                    float width, float height, T1_TMATRIX *transform)
01226 {
01227   GLYPH *glyph;   /* pointer to bitmap glyph */
01228   static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
01229   long asc, dsc, ht, wd;
01230   long i;
01231   long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
01232   long v_start, v_end;
01233   char *target_ptr;
01234   long offset;
01235   char *ptr;
01236   int y;
01237   long lsb, aalsb, aahstart;
01238   int memsize;
01239   LONG paddedW;
01240   int savelevel;
01241   
01242 
01243   /* Reset character glyph, if necessary */
01244   if (aaglyph.bits!=NULL){
01245     free(aaglyph.bits);
01246     aaglyph.bits=NULL;
01247   }
01248   aaglyph.metrics.leftSideBearing=0;
01249   aaglyph.metrics.rightSideBearing=0;
01250   aaglyph.metrics.advanceX=0;
01251   aaglyph.metrics.advanceY=0;
01252   aaglyph.metrics.ascent=0;
01253   aaglyph.metrics.descent=0;
01254   aaglyph.pFontCacheInfo=NULL;
01255   aaglyph.bpp=T1aa_bpp;
01256 
01257 
01258   /* Check for smart antialiasing */
01259   savelevel=T1aa_level;
01260   if (T1aa_SmartOn){
01261     if (size>=T1aa_smartlimit2) {
01262       T1aa_level=T1_AA_NONE;
01263     }
01264     else if (size>=T1aa_smartlimit1) {
01265       T1aa_level=T1_AA_LOW;
01266     }
01267     else {
01268       T1aa_level=T1_AA_HIGH;
01269     }
01270   }
01271 
01272 
01273   /* First, call routine to rasterize character, all error checking is
01274      done in this function: */ 
01275   if ((glyph=T1_SetRect( FontID, T1aa_level*size, width, height, transform))==NULL){
01276     /* restore level */
01277     T1aa_level=savelevel;
01278     return(NULL); /* An error occured */
01279   }
01280   
01281   /* In case there are no black pixels, we simply set the dimensions and
01282      then return */
01283   if ( glyph->bits == NULL) {
01284     aaglyph.bits=NULL;
01285     aaglyph.metrics.leftSideBearing=0;
01286     aaglyph.metrics.rightSideBearing=0;
01287     aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01288     aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01289     aaglyph.metrics.ascent=0;
01290     aaglyph.metrics.descent=0;
01291     aaglyph.pFontCacheInfo=NULL;
01292     /* restore level and return */
01293     T1aa_level=savelevel;
01294     return(&aaglyph);
01295   }
01296 
01297   /* Get dimensions of bitmap: */
01298   asc=glyph->metrics.ascent;
01299   dsc=glyph->metrics.descent;
01300   lsb=glyph->metrics.leftSideBearing;
01301   ht=asc-dsc;
01302   wd=glyph->metrics.rightSideBearing-lsb;
01303   
01304   if (T1aa_level==T1_AA_NONE){
01305     /* we only convert bitmap to bytemap */
01306     aaglyph=*glyph;
01307     aaglyph.bpp=T1aa_bpp;
01308     /* Compute scanline length and such */
01309     n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01310     /* Allocate memory for glyph */
01311     memsize = n_horz_pad*ht*8;
01312     /*    aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */
01313     aaglyph.bits = (char *)malloc(memsize*sizeof( char));
01314     if (aaglyph.bits == NULL) {
01315       T1_errno=T1ERR_ALLOC_MEM;
01316       /* restore level */
01317       T1aa_level=savelevel;
01318       return(NULL);
01319     }
01320     paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
01321     ptr=glyph->bits;
01322     target_ptr=aaglyph.bits;
01323     for (i = 0; i < ht; i++) {
01324       T1_DoLine ( wd, paddedW, ptr, target_ptr );
01325       ptr += paddedW;
01326       target_ptr += n_horz_pad;
01327     }
01328     /* restore level */
01329     T1aa_level=savelevel;
01330     return(&aaglyph);
01331   }
01332   
01333 
01334   /* Set some looping parameters for subsampling */
01335   if (lsb<0){
01336     aalsb=lsb/T1aa_level-1;
01337     aahstart=T1aa_level+(lsb%T1aa_level);
01338   }
01339   else{
01340     aalsb=lsb/T1aa_level;
01341     aahstart=lsb%T1aa_level;
01342   }
01343   
01344   /* The horizontal number of steps: */
01345   n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
01346   /* And the padded value */
01347   n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01348 
01349   /* vertical number of steps: */
01350   if (asc % T1aa_level){ /* not aligned */
01351     if ( asc > 0){
01352       n_asc=asc/T1aa_level+1;
01353       v_start=asc % T1aa_level;
01354     }
01355     else{
01356       n_asc=asc/T1aa_level;
01357       v_start=T1aa_level + (asc % T1aa_level); 
01358     }
01359   }
01360   else{
01361     n_asc=asc/T1aa_level;
01362     v_start=T1aa_level;
01363   }
01364   if (dsc % T1aa_level){ /* not aligned */
01365     if ( dsc < 0){
01366       n_dsc=dsc/T1aa_level-1;
01367       v_end=-(dsc % T1aa_level);
01368     }
01369     else{
01370       n_dsc=dsc/T1aa_level;
01371       v_end=T1aa_level - (dsc % T1aa_level);
01372     }
01373   }
01374   else{
01375     n_dsc=dsc/T1aa_level;
01376     v_end=T1aa_level;
01377   }
01378   /* the total number of lines: */
01379   n_vert=n_asc-n_dsc;
01380   
01381   /* Allocate memory for glyph */
01382   memsize = n_horz_pad*n_vert;
01383 
01384   /* Note: we allocate 12 bytes more than necessary */
01385   aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
01386   if (aaglyph.bits == NULL) {
01387     T1_errno=T1ERR_ALLOC_MEM;
01388     /* restore level */
01389     T1aa_level=savelevel;
01390     return(NULL);
01391   }
01392   
01393 
01394   paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
01395   offset=0;
01396   target_ptr=aaglyph.bits;
01397   
01398   /* We must check for n_vert==1 because the computation above is not
01399      valid in this case */
01400   if (n_vert==1)
01401     v_start=v_start < v_end ? v_start : v_end;
01402 
01403   ptr = glyph->bits;
01404   for (i = 0; i < n_vert; i++) {
01405     if (i==0)
01406       y=v_start;
01407     else if (i==n_vert-1)
01408       y=v_end;
01409     else
01410       y=T1aa_level;
01411     T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
01412     ptr += y * paddedW;
01413     target_ptr += n_horz_pad;
01414   }
01415   
01416   /* .. and set them in aaglyph */
01417   aaglyph.metrics.leftSideBearing=aalsb;
01418   aaglyph.metrics.rightSideBearing=aalsb + n_horz;
01419   aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01420   aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01421   aaglyph.metrics.ascent=n_asc;
01422   aaglyph.metrics.descent=n_dsc;
01423   aaglyph.pFontCacheInfo=NULL;
01424 
01425   /* restore level */
01426   T1aa_level=savelevel;
01427 
01428   return(&aaglyph);
01429 
01430 }
01431 
01432 
01433 
01434 /* T1_AASetGrayValues(): Sets the byte values that are put into the
01435    pixel position for the respective entries:
01436    Returns 0 if successfull.
01437    */
01438 int T1_AASetGrayValues(unsigned long white,
01439                      unsigned long gray75,
01440                      unsigned long gray50,
01441                      unsigned long gray25,
01442                      unsigned long black)
01443 {
01444   
01445   if (T1_CheckForInit()){
01446     T1_errno=T1ERR_OP_NOT_PERMITTED;
01447     return(-1);
01448   }
01449   
01450   gv[4]=(unsigned T1_AA_TYPE32)black;    /* black value */
01451   gv[3]=(unsigned T1_AA_TYPE32)gray25;   /* gray 25% value */
01452   gv[2]=(unsigned T1_AA_TYPE32)gray50;   /* gray 50% value */   
01453   gv[1]=(unsigned T1_AA_TYPE32)gray75;   /* gray 75% value */
01454   gv[0]=(unsigned T1_AA_TYPE32)white;    /* white value */
01455   
01456   T1aa_bg=white;
01457   
01458   if ((T1_AAInit( T1_AA_LOW)))
01459     return(-1);
01460   return(0);
01461   
01462 }
01463 
01464                    
01465 
01466 /* T1_AAHSetGrayValues(): Sets the byte values that are put into the
01467    pixel position for the respective entries (for 17 gray levels):
01468    Returns 0 if successfull.
01469    */
01470 int T1_AAHSetGrayValues( unsigned long *grayvals)
01471 {
01472   int i;
01473   
01474   if (T1_CheckForInit()){
01475     T1_errno=T1ERR_OP_NOT_PERMITTED;
01476     return(-1);
01477   }
01478 
01479   /* 0==white(background) ... 16==black(foreground) */
01480   for (i=0; i<17; i++){
01481     gv_h[i]=(unsigned T1_AA_TYPE32)grayvals[i];
01482   }
01483   
01484 
01485   T1aa_bg=grayvals[0];
01486   
01487   if ((T1_AAInit( T1_AA_HIGH)))
01488     return(-1);
01489   return(0);
01490   
01491 }
01492 
01493 
01494 
01495 /* T1_AANSetGrayValues(): Sets the byte values that are put into the
01496    pixel position for the respective entries (for 2 gray levels):
01497    Returns 0 if successfull. This is for the case the non-antialiased
01498    "bytemaps" should be generated.
01499    */
01500 int T1_AANSetGrayValues( unsigned long bg, unsigned long fg)
01501 {
01502   
01503   if (T1_CheckForInit()){
01504     T1_errno=T1ERR_OP_NOT_PERMITTED;
01505     return(-1);
01506   }
01507 
01508   gv_n[0]=bg;
01509   gv_n[1]=fg;
01510   
01511   T1aa_bg=bg;
01512   
01513   if ((T1_AAInit( T1_AA_NONE)))
01514     return(-1);
01515   return(0);
01516   
01517 }
01518 
01519 
01520 
01521 /* Get the current setting of graylevels for 2x antialiasing. The 5
01522    values are stored at address pgrayvals in order from background to
01523    foreground */
01524 int T1_AAGetGrayValues( long *pgrayvals)  
01525 {
01526   int i;
01527   
01528   if (T1_CheckForInit()) {
01529     T1_errno=T1ERR_OP_NOT_PERMITTED;
01530     return(-1);
01531   }
01532 
01533   if (pgrayvals==NULL) {
01534     T1_errno=T1ERR_INVALID_PARAMETER;
01535     return(-1);
01536   }
01537   
01538   for ( i=0; i<5; i++) { /* bg (i=0)  to fg (i=4) */
01539     pgrayvals[i]=gv[i];
01540   }
01541   return( 0);
01542   
01543 }
01544 
01545 
01546 
01547 /* Get the current setting of graylevels for 2x antialiasing. The 17
01548    values are stored at address pgrayvals in order from background to
01549    foreground */
01550 int T1_AAHGetGrayValues( long *pgrayvals) 
01551 {
01552   int i;
01553 
01554   if (T1_CheckForInit()) {
01555     T1_errno=T1ERR_OP_NOT_PERMITTED;
01556     return(-1);
01557   }
01558 
01559   if (pgrayvals==NULL) {
01560     T1_errno=T1ERR_INVALID_PARAMETER;
01561     return(-1);
01562   }
01563 
01564   for ( i=0; i<17; i++) { /* bg (i=0)  to fg (i=16) */
01565     pgrayvals[i]=gv[i];
01566   }
01567   return( 0);
01568 }
01569 
01570 
01571 
01572 /* Get the current setting of graylevels for 2x antialiasing. The 2
01573    values are stored at address pgrayvals in order from background to
01574    foreground */
01575 int T1_AANGetGrayValues( long *pgrayvals) 
01576 {
01577 
01578   if (T1_CheckForInit()) {
01579     T1_errno=T1ERR_OP_NOT_PERMITTED;
01580     return(-1);
01581   }
01582 
01583   if (pgrayvals==NULL) {
01584     T1_errno=T1ERR_INVALID_PARAMETER;
01585     return(-1);
01586   }
01587   pgrayvals[0]=gv[0]; /* background */
01588   pgrayvals[1]=gv[1]; /* foreground */
01589   return( 0);
01590 }
01591 
01592 
01593 /* T1_AASetBitsPerPixel(): Sets the depths of the antialiased glyph
01594    pixel. Returns 0 if bpp is valid and -1 otherwise. If 24 is
01595    specified, meaning to be the depth rather than the bpp-value,
01596    automatically 32 bpp is chosen. */
01597 int  T1_AASetBitsPerPixel( int bpp)
01598 {
01599   
01600   if (T1_CheckForInit()){
01601     T1_errno=T1ERR_OP_NOT_PERMITTED;
01602     return(-1);
01603   }
01604   
01605 
01606   /* T1aa_level = 0; */
01607 
01608   if (bpp==8){
01609     T1aa_bpp=8;
01610     return(0);
01611   }
01612   if (bpp==16){
01613     T1aa_bpp=16;
01614     return(0);
01615   }
01616   if ((bpp==32)|(bpp==24)){
01617     T1aa_bpp=32;
01618     return(0);
01619   }
01620 
01621   T1_errno=T1ERR_INVALID_PARAMETER;
01622   return(-1);
01623 }
01624 
01625 
01626 /* T1_AAGetBitsPerPixel(): Return the number of bits per pixel set in
01627    t1lib. 
01628 */
01629 int T1_AAGetBitsPerPixel( void)
01630 {
01631   return( T1aa_bpp);
01632   
01633 }
01634 
01635 
01636 /* Set the Subsampling level for subsequent operations: */
01637 int T1_AASetLevel( int level)
01638 {
01639   
01640    if (T1_CheckForInit()){
01641      T1_errno=T1ERR_OP_NOT_PERMITTED;
01642      return(-1);
01643    }
01644 
01645    if (level==T1_AA_LOW){
01646      T1aa_level=T1_AA_LOW;
01647      return(0);
01648    }
01649    else if (level==T1_AA_HIGH){
01650      T1aa_level=T1_AA_HIGH;
01651      return(0);
01652    }
01653    else if (level==T1_AA_NONE){
01654      T1aa_level=T1_AA_NONE;
01655      return(0);
01656    }
01657    
01658    T1_errno=T1ERR_INVALID_PARAMETER;
01659    return(-1);
01660    
01661 }
01662 
01663 
01664 /* Get the current subsampling level */
01665 int T1_AAGetLevel( void)
01666 {
01667   return( T1aa_level);
01668 }
01669 
01670 
01671 /* T1_AAFillOutline(): Create a filled glyph from an outline description */
01672 GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag)
01673 {
01674   
01675   GLYPH *glyph;   /* pointer to bitmap glyph */
01676   static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
01677   long asc, dsc, ht, wd;
01678   long i;
01679   long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
01680   long v_start, v_end;
01681   char *target_ptr;
01682   long offset;
01683   char *ptr;
01684   int y;
01685   long lsb, aalsb, aahstart;
01686   int memsize;
01687   LONG paddedW;
01688  
01689 
01690   /* Reset character glyph, if necessary */
01691   if (aaglyph.bits!=NULL){
01692     free(aaglyph.bits);
01693     aaglyph.bits=NULL;
01694   }
01695   aaglyph.metrics.leftSideBearing=0;
01696   aaglyph.metrics.rightSideBearing=0;
01697   aaglyph.metrics.advanceX=0;
01698   aaglyph.metrics.advanceY=0;
01699   aaglyph.metrics.ascent=0;
01700   aaglyph.metrics.descent=0;
01701   aaglyph.pFontCacheInfo=NULL;
01702   aaglyph.bpp=T1aa_bpp;
01703 
01704 
01705   /* First, scale outline appropriately: */
01706   path=T1_ScaleOutline( path, T1aa_level);
01707   
01708   /* Second, call routine to fill outline, all error checking is
01709      done in this function: */ 
01710   if ((glyph=T1_FillOutline( path, modflag))==NULL)
01711     return(NULL); /* An error occured */
01712   
01713   /* In case there are no black pixels, we simply set the dimensions and
01714      then return */
01715   if ( glyph->bits == NULL) {
01716     aaglyph.bits=NULL;
01717     aaglyph.metrics.leftSideBearing=0;
01718     aaglyph.metrics.rightSideBearing=0;
01719     aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01720     aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01721     aaglyph.metrics.ascent=0;
01722     aaglyph.metrics.descent=0;
01723     aaglyph.pFontCacheInfo=NULL;
01724     return(&aaglyph);
01725   }
01726 
01727   /* Get dimensions of bitmap: */
01728   asc=glyph->metrics.ascent;
01729   dsc=glyph->metrics.descent;
01730   lsb=glyph->metrics.leftSideBearing;
01731   ht=asc-dsc;
01732   wd=glyph->metrics.rightSideBearing-lsb;
01733   
01734 
01735   if (T1aa_level==T1_AA_NONE){
01736     /* we only convert bitmap to bytemap */
01737     aaglyph=*glyph;
01738     aaglyph.bpp=T1aa_bpp;
01739     /* Compute scanline length and such */
01740     n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01741     /* Allocate memory for glyph, we alloc 12 bytes more to simplify
01742        subsampling! */
01743     memsize = n_horz_pad*ht*8;
01744     aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
01745     if (aaglyph.bits == NULL) {
01746       T1_errno=T1ERR_ALLOC_MEM;
01747       return(NULL);
01748     }
01749     paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
01750     ptr=glyph->bits;
01751     target_ptr=aaglyph.bits;
01752     for (i = 0; i < ht; i++) {
01753       T1_DoLine ( wd, paddedW, ptr, target_ptr );
01754       ptr += paddedW;
01755       target_ptr += n_horz_pad;
01756     }
01757     return(&aaglyph);
01758   }
01759   
01760 
01761   /* Set some looping parameters for subsampling */
01762   if (lsb<0){
01763     aalsb=lsb/T1aa_level-1;
01764     aahstart=T1aa_level+(lsb%T1aa_level);
01765   }
01766   else{
01767     aalsb=lsb/T1aa_level;
01768     aahstart=lsb%T1aa_level;
01769   }
01770   
01771   /* The horizontal number of steps: */
01772   n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
01773   /* And the padded value */
01774   n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
01775   
01776   /* vertical number of steps: */
01777   if (asc % T1aa_level){ /* not aligned */
01778     if ( asc > 0){
01779       n_asc=asc/T1aa_level+1;
01780       v_start=asc % T1aa_level;
01781     }
01782     else{
01783       n_asc=asc/T1aa_level;
01784       v_start=T1aa_level + (asc % T1aa_level); 
01785     }
01786   }
01787   else{
01788     n_asc=asc/T1aa_level;
01789     v_start=T1aa_level;
01790   }
01791   if (dsc % T1aa_level){ /* not aligned */
01792     if ( dsc < 0){
01793       n_dsc=dsc/T1aa_level-1;
01794       v_end=-(dsc % T1aa_level);
01795     }
01796     else{
01797       n_dsc=dsc/T1aa_level;
01798       v_end=T1aa_level - (dsc % T1aa_level);
01799     }
01800   }
01801   else{
01802     n_dsc=dsc/T1aa_level;
01803     v_end=T1aa_level;
01804   }
01805   /* the total number of lines: */
01806   n_vert=n_asc-n_dsc;
01807   
01808   /* Allocate memory for glyph */
01809   memsize = n_horz_pad*n_vert;
01810   
01811   aaglyph.bits = (char *)malloc(memsize*sizeof( char)+12);
01812   if (aaglyph.bits == NULL) {
01813     T1_errno=T1ERR_ALLOC_MEM;
01814     return(NULL);
01815   }
01816   
01817   paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
01818   offset=0;
01819   target_ptr=aaglyph.bits;
01820   
01821   /* We must check for n_vert==1 because the computation above is not
01822      valid in this case */
01823   if (n_vert==1)
01824     v_start=v_start < v_end ? v_start : v_end;
01825 
01826   ptr = glyph->bits;
01827   for (i = 0; i < n_vert; i++) {
01828     if (i==0)
01829       y=v_start;
01830     else if (i==n_vert-1)
01831       y=v_end;
01832     else
01833       y=T1aa_level;
01834     T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
01835     ptr += y * paddedW;
01836     target_ptr += n_horz_pad;
01837   }
01838   
01839   /* .. and set them in aaglyph */
01840   aaglyph.metrics.leftSideBearing=aalsb;
01841   aaglyph.metrics.rightSideBearing=aalsb + n_horz;
01842   aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
01843   aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
01844   aaglyph.metrics.ascent=n_asc;
01845   aaglyph.metrics.descent=n_dsc;
01846   aaglyph.pFontCacheInfo=NULL;
01847 
01848   return(&aaglyph);
01849 }
01850 
01851 
01852 
01853 /* T1_AASetSmartLimits(): Set the limit-values for smart
01854    antialiasing. Returns 0 if OK, and -1 else. */
01855 int T1_AASetSmartLimits( float limit1, float limit2)
01856 {
01857 
01858   if (limit1 > 0.0 && limit2 > 0.0 && limit2 >= limit2) {
01859     T1aa_smartlimit1=limit1;
01860     T1aa_smartlimit2=limit2;
01861     return( 0);
01862   }
01863   else{
01864     T1_errno=T1ERR_INVALID_PARAMETER;
01865     return( -1);
01866   }
01867 }
01868 
01869 
01870 
01871 /* T1_AASetSmartMode(): Enable or disable smart anialiasing */
01872 int T1_AASetSmartMode( int smart)
01873 {
01874 
01875   if (smart==T1_YES) {
01876     T1aa_SmartOn=1;
01877   }
01878   else if (smart==T1_NO) {
01879     T1aa_SmartOn=0;
01880   }
01881   else {
01882     T1_errno=T1ERR_INVALID_PARAMETER;
01883     return( -1);
01884   }
01885   return( 0);
01886 }
01887 
01888