Back to index

tetex-bin  3.0
t1.c
Go to the documentation of this file.
00001 /* t1.c */
00002 
00003 /************************************************************************
00004 
00005   Part of the dvipng distribution
00006 
00007   This program is free software; you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation; either version 2 of the License, or
00010   (at your option) any later version.
00011 
00012   This program is distributed in the hope that it will be useful, but
00013   WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with this program; if not, write to the Free Software
00019   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00020   02111-1307, USA.
00021 
00022   Copyright (C) 2002-2005 Jan-Åke Larsson
00023 
00024 ************************************************************************/
00025 
00026 #include "dvipng.h"
00027 #if HAVE_ALLOCA_H
00028 # include <alloca.h>
00029 #endif
00030 
00031 void LoadT1(int32_t c, struct char_entry * ptr)
00032 {
00033   GLYPH *glyph;
00034   int original_width,original_height;
00035   int i,j,k,width,height;
00036   unsigned short   shrunk_width,shrunk_height;
00037   short   xoffset,yoffset;
00038   unsigned short   i_offset,j_offset;
00039 
00040   DEBUG_PRINT(DEBUG_T1,("\n  LOAD T1 CHAR\t%d",c));
00041   if ((glyph=
00042        T1_SetChar(currentfont->T1id, c, (float)currentfont->dpi*currentfont->d/65536/72 ,
00043                 currentfont->psfontmap==NULL ? NULL : currentfont->psfontmap->t1_transformp))
00044       ==NULL)
00045       Fatal("can't load T1 char %d",c);
00046 
00047   DEBUG_PRINT(DEBUG_T1,(" (%d)",ptr->tfmw));
00048   
00049   original_width = glyph->metrics.rightSideBearing 
00050     - glyph->metrics.leftSideBearing;
00051   original_height  = glyph->metrics.ascent - glyph->metrics.descent;
00052   DEBUG_PRINT(DEBUG_T1,(" %dx%d",original_width,original_height));
00053 
00054   if (original_width > 0x7fff || original_height > 0x7fff)
00055     Fatal("Character %d too large in file %s", c, currentfont->name);
00056 
00057   /* 
00058    * Hotspot issues: Shrinking to the topleft corner rather than the
00059      hotspot will displace glyphs a fraction of a pixel. We deal with
00060      this in as follows: The glyph is shrunk to its hotspot by
00061      offsetting the bitmap somewhat to put the hotspot in the lower
00062      left corner of a "shrink square". Shrinking to the topleft corner
00063      will then act as shrinking to the hotspot. This may enlarge the
00064      bitmap somewhat, of course.  (Also remember that the below
00065      calculation of i/j_offset is in integer arithmetics.)
00066      
00067      There will still be a displacement from rounding the dvi
00068      position, but vertically it will be equal for all glyphs on a
00069      line, so we displace a whole line vertically by fractions of a
00070      pixel. This is acceptible, IMHO. Sometime there will be support
00071      for subpixel positioning, horizontally. Will do for now, I
00072      suppose.
00073    */
00074   xoffset = -glyph->metrics.leftSideBearing;
00075   /* printf("xoffset: %d\n",xoffset); */
00076   i_offset = ( shrinkfactor - xoffset % shrinkfactor ) % shrinkfactor;
00077   width = original_width+i_offset;
00078   ptr->xOffset = xoffset+i_offset;
00079 
00080   yoffset = glyph->metrics.ascent-1;
00081   /* printf("yoffset: %d\n",yoffset); */
00082   j_offset = ( shrinkfactor - (yoffset-(shrinkfactor-1)) % shrinkfactor )
00083     % shrinkfactor;
00084   height = original_height+j_offset;
00085   ptr->yOffset = yoffset+j_offset;
00086 
00087   DEBUG_PRINT(DEBUG_T1,(" (%dx%d)",width,height));
00088   /* 
00089      Extra marginal so that we do not crop the image when shrinking.
00090   */
00091   shrunk_width = (width + shrinkfactor - 1) / shrinkfactor;
00092   shrunk_height = (height + shrinkfactor - 1) / shrinkfactor;
00093   ptr->w = shrunk_width;
00094   ptr->h = shrunk_height;
00095 
00096   /* printf("(%d,%d) ",ptr->w,ptr->h); */
00097   DEBUG_PRINT(DEBUG_GLYPH,("\nDRAW GLYPH %d\n", (int)c));
00098 
00099   /*
00100     Shrink raster while doing antialiasing. 
00101   */
00102   if ((ptr->data = calloc(shrunk_width*shrunk_height,sizeof(char))) == NULL)
00103     Fatal("Unable to allocate image space for char <%c>\n", (char)c);
00104   for (j = 0; j < original_height; j++) { 
00105     for (i = 0; i < (original_width+7)/8 ; i++) {    
00106       for (k = 0; k < 8 ; k++) {
00107        DEBUG_PRINT(DEBUG_GLYPH,
00108                   ("%c",
00109                    (glyph->bits[i+j*((original_width+7)/8)] & (1<<k)) ?
00110                     'x' : ' '));
00111        ptr->data[(i*8+k+i_offset)/shrinkfactor
00112                 +(j+j_offset)/shrinkfactor*shrunk_width] += 
00113          (glyph->bits[i+j*((original_width+7)/8)] & (1<<k) ? 1 : 0);
00114       }
00115     }    
00116     DEBUG_PRINT(DEBUG_GLYPH,("|\n"));
00117   }    
00118   for (j = 0; j < shrunk_height; j++) {   
00119     for (i = 0; i < shrunk_width; i++) {    
00120       ptr->data[i+j*shrunk_width] = ptr->data[i+j*shrunk_width]
00121        *255/shrinkfactor/shrinkfactor;
00122       DEBUG_PRINT(DEBUG_GLYPH,("%3u ",ptr->data[i+j*shrunk_width]));
00123     }
00124     DEBUG_PRINT(DEBUG_GLYPH,("|\n"));
00125   }     
00126 }
00127 
00128 bool InitT1(struct font_entry * tfontp)
00129 {
00130   if (libt1==NULL) {
00131     if ((libt1=T1_InitLib( NO_LOGFILE | IGNORE_CONFIGFILE
00132                         | IGNORE_FONTDATABASE | T1_NO_AFM)) == NULL) {
00133       Warning("an error occured during t1lib initialisation, disabling it"); 
00134       flags &= ~USE_LIBT1;
00135       return(false);
00136     }
00137 # ifdef DEBUG
00138     else 
00139       DEBUG_PRINT(DEBUG_T1,("\n  T1LIB VERSION: %s", T1_GetLibIdent()));
00140 # endif
00141   }
00142 
00143   DEBUG_PRINT((DEBUG_DVI|DEBUG_T1),("\n  OPEN T1 FONT:\t'%s'", tfontp->name));
00144   tfontp->T1id = T1_AddFont( tfontp->name );
00145   if (tfontp->T1id < 0) {
00146     Warning("t1lib could not open font file %s", tfontp->name);
00147     return(false);
00148   } 
00149   if (T1_LoadFont(tfontp->T1id)) {
00150     Warning("t1lib could not load font file %s", tfontp->name);
00151     return(false);
00152   } 
00153   Message(BE_VERBOSE,"<%s>", tfontp->name);
00154   if (tfontp->psfontmap!=NULL && tfontp->psfontmap->encoding != NULL) {
00155     DEBUG_PRINT(DEBUG_T1,("\n  USE ENCODING:\t'%s'", tfontp->psfontmap->encoding->name));
00156     if (T1_ReencodeFont(tfontp->T1id,tfontp->psfontmap->encoding->charname)) {
00157       Warning("unable to use font encoding '%s' for %s", 
00158              tfontp->psfontmap->encoding->name,tfontp->name);
00159       return(false);
00160     }
00161   }
00162   tfontp->type = FONT_TYPE_T1;
00163   return(true);
00164 }
00165 
00166 
00167 void UnLoadT1(struct char_entry *ptr)
00168 {
00169   if (ptr->data!=NULL)
00170     free(ptr->data);
00171   ptr->data=NULL;
00172 }
00173 
00174 
00175 void DoneT1(struct font_entry *tfontp)
00176 {
00177   int c=0;
00178 
00179   int error = T1_DeleteFont( tfontp->T1id );
00180   if (error)
00181     Warning("font file %s could not be closed", tfontp->name);
00182   while(c<NFNTCHARS-1) {
00183     if (tfontp->chr[c]!=NULL) {
00184       UnLoadT1((struct char_entry*)tfontp->chr[c]);
00185       free(tfontp->chr[c]);
00186       tfontp->chr[c]=NULL;
00187     }
00188     c++;
00189   }
00190   tfontp->name[0]='\0';
00191 }
00192 
00193