]> git.imager.perl.org - imager.git/blobdiff - font.c
Changes to GIF support:
[imager.git] / font.c
diff --git a/font.c b/font.c
index 4dc1349a4ef6be624eafc098f5bedaaf864a9ecf..9e09b417c12fb6f190fbcf971802073b9b01ce05 100644 (file)
--- a/font.c
+++ b/font.c
@@ -1,4 +1,4 @@
-#include "image.h"
+#include "imager.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -298,6 +298,17 @@ i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,i
   return 1;
 }
 
+static void
+t1_fix_bbox(BBox *bbox, const char *str, int len, int advance, 
+           int space_position) {
+  /* never called with len == 0 */
+  if (str[0] == space_position && bbox->llx > 0)
+    bbox->llx = 0;
+  if (str[len-1] == space_position && bbox->urx < advance)
+    bbox->urx = advance;
+  if (bbox->lly > bbox->ury)
+    bbox->lly = bbox->ury = 0; 
+}
 
 /*
 =item i_t1_bbox(handle, fontnum, points, str, len, cords)
@@ -315,25 +326,38 @@ function to get a strings bounding box given the font id and sizes
 */
 
 int
-i_t1_bbox(int fontnum,float points,char *str,int len,int cords[6], int utf8,char const *flags) {
+i_t1_bbox(int fontnum,float points,const char *str,int len,int cords[6], int utf8,char const *flags) {
   BBox bbox;
   BBox gbbox;
   int mod_flags = t1_get_flags(flags);
   int advance;
+  int space_position = T1_GetEncodingIndex(fontnum, "space");
   
   mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len));
   T1_LoadFont(fontnum);  /* FIXME: Here a return code is ignored - haw haw haw */ 
-  if (utf8) {
-    int worklen;
-    char *work = t1_from_utf8(str, len, &worklen);
-    bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags);
-    myfree(work);
+
+  if (len == 0) {
+    /* len == 0 has special meaning to T1lib, but it means there's
+       nothing to draw, so return that */
+    bbox.llx = bbox.lly = bbox.urx = bbox.ury = 0;
+    advance = 0;
   }
   else {
-    bbox = T1_GetStringBBox(fontnum,str,len,0,mod_flags);
+    if (utf8) {
+      int worklen;
+      char *work = t1_from_utf8(str, len, &worklen);
+      advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags);
+      bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags);
+      t1_fix_bbox(&bbox, work, worklen, advance, space_position);
+      myfree(work);
+    }
+    else {
+      advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags);
+      bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags);
+      t1_fix_bbox(&bbox, str, len, advance, space_position);
+    }
   }
   gbbox = T1_GetFontBBox(fontnum);
-  advance = T1_GetStringWidth(fontnum, str, len, 0, mod_flags);
   
   mm_log((1,"bbox: (%d,%d,%d,%d)\n",
          (int)(bbox.llx*points/1000),
@@ -380,7 +404,7 @@ Interface to text rendering in a single color onto an image
 */
 
 undef_int
-i_t1_text(i_img *im,int xb,int yb,i_color *cl,int fontnum,float points,char* str,int len,int align, int utf8, char const *flags) {
+i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,int len,int align, int utf8, char const *flags) {
   GLYPH *glyph;
   int xsize,ysize,x,y,ch;
   i_color val;
@@ -396,7 +420,8 @@ i_t1_text(i_img *im,int xb,int yb,i_color *cl,int fontnum,float points,char* str
     myfree(work);
   }
   else {
-    glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL);
+    /* T1_AASetString() accepts a char * not a const char */
+    glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL);
   }
   if (glyph == NULL)
     return 0;
@@ -817,7 +842,7 @@ static int
 i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit, 
                         TT_Raster_Map *small_bit, int cords[6], 
                         char const* txt, int len, int smooth, int utf8 );
-static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, i_color *cl, int smooth );
+static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth );
 static void i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, int xb, int yb, int channel, int smooth );
 static  int
 i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6], 
@@ -981,7 +1006,7 @@ the font handle's cache
 */
 
 TT_Fonthandle*
-i_tt_new(char *fontname) {
+i_tt_new(const char *fontname) {
   TT_Error error;
   TT_Fonthandle *handle;
   unsigned short i,n;
@@ -1084,15 +1109,16 @@ i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ) {
     bit->size  = bit->rows * bit->cols;     /* number of bytes in buffer */
   }
 
+  /* rows can be 0 for some glyphs, for example ' ' */
   if (bit->rows && bit->size / bit->rows != bit->cols) {
-    m_fatal(0, "Integer overflow calculating bitmap size (%d, %d)\n",
+    i_fatal(0, "Integer overflow calculating bitmap size (%d, %d)\n",
             bit->width, bit->rows);
   }
   
   mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %d)\n", bit->width, bit->cols, bit->rows, bit->size ));
 
   bit->bitmap = (void *) mymalloc( bit->size ); /* checked 6Nov05 tonyc */
-  if ( !bit->bitmap ) m_fatal(0,"Not enough memory to allocate bitmap (%d)!\n",bit->size );
+  if ( !bit->bitmap ) i_fatal(0,"Not enough memory to allocate bitmap (%d)!\n",bit->size );
 }
 
 
@@ -1478,7 +1504,7 @@ Function to dump a raster onto an image in color used by i_tt_text() (internal).
 
 static
 void
-i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, i_color *cl, int smooth ) {
+i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth ) {
   char *bmap;
   i_color val;
   int c, i, ch, x, y;
@@ -1670,7 +1696,7 @@ Interface to text rendering in a single color onto an image
 */
 
 undef_int
-i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, i_color *cl, float points, char const* txt, int len, int smooth, int utf8, int align) {
+i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, const i_color *cl, float points, char const* txt, int len, int smooth, int utf8, int align) {
   int cords[BOUNDING_BOX_COUNT];
   int ascent, st_offset, y;
   TT_Raster_Map bit;
@@ -1806,7 +1832,7 @@ Interface to get a strings bounding box
 */
 
 undef_int
-i_tt_bbox( TT_Fonthandle *handle, float points,char *txt,int len,int cords[6], int utf8) {
+i_tt_bbox( TT_Fonthandle *handle, float points,const char *txt,int len,int cords[6], int utf8) {
   int inst;
 
   i_clear_error();