-#include "image.h"
+#include "imager.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
+#ifdef HAVE_LIBT1
+#include <t1lib.h>
+#endif
+
+
/*
=head1 NAME
static void t1_push_error(void);
+static int t1_active_fonts = 0;
+static int t1_initialized = 0;
+
/*
=item i_init_t1(t1log)
i_init_t1(int t1log) {
int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE;
mm_log((1,"init_t1()\n"));
+
+ if (t1_active_fonts) {
+ mm_log((1, "Cannot re-initialize T1 - active fonts\n"));
+ return 1;
+ }
+
+ if (t1_initialized) {
+ T1_CloseLib();
+ }
if (t1log)
init_flags |= LOGFILE;
}
T1_SetLogLevel(T1LOG_DEBUG);
i_t1_set_aa(1); /* Default Antialias value */
+
+ ++t1_initialized;
+
return(0);
}
void
i_close_t1(void) {
T1_CloseLib();
+ t1_initialized = 0;
}
if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm));
}
+ ++t1_active_fonts;
+
return font_id;
}
int
i_t1_destroy(int font_id) {
mm_log((1,"i_t1_destroy(font_id %d)\n",font_id));
+
+ --t1_active_fonts;
+
return T1_DeleteFont(font_id);
}
*/
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);
myfree(work);
}
else {
- bbox = T1_GetStringBBox(fontnum,str,len,0,mod_flags);
+ bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags);
}
gbbox = T1_GetFontBBox(fontnum);
- advance = T1_GetStringWidth(fontnum, str, len, 0, mod_flags);
+ advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags);
mm_log((1,"bbox: (%d,%d,%d,%d)\n",
(int)(bbox.llx*points/1000),
cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000;
cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000;
+ cords[BBOX_RIGHT_BEARING] =
+ cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
- return BBOX_ADVANCE_WIDTH+1;
+ return BBOX_RIGHT_BEARING+1;
}
*/
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;
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;
static char *
t1_from_utf8(char const *in, int len, int *outlen) {
- char *out = mymalloc(len+1);
+ /* at this point len is from a perl SV, so can't approach MAXINT */
+ char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */
char *p = out;
unsigned long c;
while (len) {
unsigned long c;
- int index;
if (utf8) {
c = i_utf8_advance(&text, &len);
if (c == ~0UL) {
/* Truetype font support */
#ifdef HAVE_LIBTT
-/* This is enabled by default when configuring Freetype 1.x
+/* These are enabled by default when configuring Freetype 1.x
I haven't a clue how to reliably detect it at compile time.
We need a compilation probe in Makefile.PL
*/
#define FTXPOST 1
+#define FTXERR18 1
#include <freetype.h>
#define TT_CHC 5
#include <ftxpost.h>
#endif
+#ifdef FTXERR18
+#include <ftxerr18.h>
+#endif
+
/* some versions of FT1.x don't seem to define this - it's font defined
so it won't change */
#ifndef TT_MS_LANGID_ENGLISH_GENERAL
#define USTRCT(x) ((x).z)
#define TT_VALID( handle ) ( ( handle ).z != NULL )
+static void i_tt_push_error(TT_Error rc);
/* Prototypes */
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],
*/
TT_Fonthandle*
-i_tt_new(char *fontname) {
+i_tt_new(const char *fontname) {
TT_Error error;
TT_Fonthandle *handle;
unsigned short i,n;
unsigned short platform,encoding;
+
+ i_clear_error();
mm_log((1,"i_tt_new(fontname '%s')\n",fontname));
/* allocate memory for the structure */
- handle = mymalloc( sizeof(TT_Fonthandle) );
+ handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */
/* load the typeface */
error = TT_Open_Face( engine, fontname, &handle->face );
mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname,
error ));
}
+ i_tt_push_error(error);
return NULL;
}
bit->cols = ( bit->width + 7 ) / 8; /* convert to # of bytes */
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",
+ 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 );
+ 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 );
}
i_tt_has_chars(TT_Fonthandle *handle, char const *text, int len, int utf8,
char *out) {
int count = 0;
- int inst;
mm_log((1, "i_tt_has_chars(handle %p, text %p, len %d, utf8 %d)\n",
handle, text, len, utf8));
TT_Raster_Map *small_bit, int cords[6],
char const* txt, int len, int smooth, int utf8 ) {
unsigned long j;
- int i;
TT_F26Dot6 x,y;
mm_log((1,"i_tt_render_all_glyphs( handle 0x%X, inst %d, bit 0x%X, small_bit 0x%X, txt '%.*s', len %d, smooth %d, utf8 %d)\n",
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;
return 0;
}
- /* ascent = ( handle->properties.horizontal->Ascender * handle->instanceh[inst].imetrics.y_ppem ) / handle->properties.header->Units_Per_EM; */
-
if ( smooth ) i_tt_done_raster_map( &small_bit );
return 1;
}
*/
undef_int
-i_tt_cp( TT_Fonthandle *handle, i_img *im, int xb, int yb, int channel, float points, char const* txt, int len, int smooth, int utf8 ) {
+i_tt_cp( TT_Fonthandle *handle, i_img *im, int xb, int yb, int channel, float points, char const* txt, int len, int smooth, int utf8, int align ) {
int cords[BOUNDING_BOX_COUNT];
- int ascent, st_offset;
+ int ascent, st_offset, y;
TT_Raster_Map bit;
i_clear_error();
if (! i_tt_rasterize( handle, &bit, cords, points, txt, len, smooth, utf8 ) ) return 0;
- ascent=cords[5];
- st_offset=cords[0];
+ ascent=cords[BBOX_ASCENT];
+ st_offset=cords[BBOX_NEG_WIDTH];
+ y = align ? yb-ascent : yb;
- i_tt_dump_raster_map_channel( im, &bit, xb-st_offset , yb-ascent, channel, smooth );
+ i_tt_dump_raster_map_channel( im, &bit, xb-st_offset , y, channel, smooth );
i_tt_done_raster_map( &bit );
return 1;
*/
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) {
+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;
+ int ascent, st_offset, y;
TT_Raster_Map bit;
i_clear_error();
if (! i_tt_rasterize( handle, &bit, cords, points, txt, len, smooth, utf8 ) ) return 0;
- ascent=cords[5];
- st_offset=cords[0];
+ ascent=cords[BBOX_ASCENT];
+ st_offset=cords[BBOX_NEG_WIDTH];
+ y = align ? yb-ascent : yb;
- i_tt_dump_raster_map2( im, &bit, xb+st_offset, yb-ascent, cl, smooth );
+ i_tt_dump_raster_map2( im, &bit, xb+st_offset, y, cl, smooth );
i_tt_done_raster_map( &bit );
return 1;
static
undef_int
i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, int len, int cords[BOUNDING_BOX_COUNT], int utf8 ) {
- int i, upm, casc, cdesc, first;
+ int upm, casc, cdesc, first;
int start = 0;
int width = 0;
descent = (gm->bbox.yMin-63) / 64;
first = 0;
}
- if (i == len-1) {
+ if (!len) { /* if at end of string */
/* the right-side bearing - in case the right-side of a
character goes past the right of the advance width,
as is common for italic fonts
- (gm->bbox.xMax - gm->bbox.xMin);
/* fprintf(stderr, "font info last: %d %d %d %d\n",
gm->bbox.xMax, gm->bbox.xMin, gm->advance, rightb); */
- if (rightb > 0)
- rightb = 0;
}
ascent = (ascent > casc ? ascent : casc );
cords[BBOX_NEG_WIDTH]=start;
cords[BBOX_GLOBAL_DESCENT]=gdescent;
- cords[BBOX_POS_WIDTH]=width - rightb / 64;
+ cords[BBOX_POS_WIDTH]=width;
+ if (rightb < 0)
+ cords[BBOX_POS_WIDTH] -= rightb / 64;
cords[BBOX_GLOBAL_ASCENT]=gascent;
cords[BBOX_DESCENT]=descent;
cords[BBOX_ASCENT]=ascent;
cords[BBOX_ADVANCE_WIDTH] = width;
+ cords[BBOX_RIGHT_BEARING] = rightb / 64;
- return BBOX_ADVANCE_WIDTH + 1;
+ return BBOX_RIGHT_BEARING + 1;
}
*/
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();
#endif
}
+/*
+=item i_tt_push_error(code)
+
+Push an error message and code onto the Imager error stack.
+
+=cut
+*/
+static void
+i_tt_push_error(TT_Error rc) {
+#ifdef FTXERR18
+ TT_String const *msg = TT_ErrToString18(rc);
+
+ i_push_error(rc, msg);
+#else
+ i_push_errorf(rc, "Error code 0x%04x", (unsigned)rc);
+#endif
+}
+
#endif /* HAVE_LIBTT */