pike.git / src / modules / Image / font.c

version» Context lines:

pike.git/src/modules/Image/font.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: font.c,v 1.87 2005/08/15 17:00:39 grubba Exp $ + || $Id: font.c,v 1.88 2005/11/03 16:08:51 grubba Exp $   */      #include "global.h"      #define SPACE_CHAR 'i'      extern const unsigned char image_default_font[];   #define IMAGE_DEFAULT_FONT_SIZE 30596      
pike.git/src/modules/Image/font.c:176:      /***************** init & exit *********************************/      static INLINE void free_font_struct(struct font *font)   {    if (font)    {    if (font->mem && font->mem!=image_default_font)    {   #ifdef HAVE_MMAP +  if (font->mmaped_size) {    munmap(font->mem,font->mmaped_size); -  +  } else   #else    free(font->mem);   #endif -  +  font->mem = NULL;    }    free(font);    }   }      static void init_font_struct(struct object *o)   {    THIS=NULL;   }   
pike.git/src/modules/Image/font.c:213:    return DOUBLE_TO_INT((this->height*this->xspacing_scale)/18);    return DOUBLE_TO_INT(this->charinfo[c].spacing*this->xspacing_scale);   }      static INLINE int char_width(struct font *this, INT32 c)   {    if(c==0x20 || c==0x20+128) return 0;    return this->charinfo[c].width;   }    - #ifndef HAVE_MMAP - static INLINE ptrdiff_t my_read(int from, void *t, size_t towrite) + static INLINE ptrdiff_t my_read(int fd, void *t, size_t towrite)   {    ptrdiff_t res; -  while((res = fd_read(from, t, towrite)) < 0) +  while((res = fd_read(fd, t, towrite)) < 0)    {    switch(errno)    {    case EAGAIN: case EINTR:    continue;       default:    res = 0;    return 0;    }    }    return res;   } - #endif +       static INLINE off_t file_size(int fd)   {    PIKE_STAT_T tmp;    if((!fd_fstat(fd, &tmp)) &&    ( tmp.st_mode & S_IFMT) == S_IFREG)    return (off_t)tmp.st_size;    return -1;   }   
pike.git/src/modules/Image/font.c:283:   /*! @decl Image.Font|int load(string filename)    *! Loads a font file to this font object.    *! @returns    *! Returns zero upon failure and a font object upon success.    *! @param filename    *! The path to the font file.    *! @seealso    *! @[write]    */    - /*! @decl void create(string filename) -  *! Loads a font file to this font object. -  *! Similar to @[load()]. -  */ + #ifndef MAP_FAILED + #define MAP_FAILED ((void *)-1) + #endif    - void font_load(INT32 args); -  - void font_create(INT32 args) - { -  font_load(args); -  pop_stack(); - } -  +    void font_load(INT32 args)   { -  int fd = -1; -  size_t size; -  -  if (THIS) +  struct file_head    { -  free_font_struct(THIS); -  THIS=NULL; -  } +  unsigned INT32 cookie; +  unsigned INT32 version; +  unsigned INT32 chars; +  unsigned INT32 height; +  unsigned INT32 baseline; +  unsigned INT32 o[1]; +  } *fh = NULL; + #ifdef HAVE_MMAP +  size_t mmaped_size = 0; + #endif +  size_t size = 0;    -  +  if (args && Pike_sp[-args].type != T_STRING) +  Pike_error("font->read: illegal or wrong number of arguments\n"); +     if (!args)    { -  THIS=(struct font *)xalloc(sizeof(struct font)); -  THIS->mem=(void *)image_default_font; -  size=IMAGE_DEFAULT_FONT_SIZE; -  goto loading_default; -  } +  fh = (struct file_head *)image_default_font; +  size = IMAGE_DEFAULT_FONT_SIZE; +  } else { +  int fd = -1;    -  if (sp[-args].type!=T_STRING) -  Pike_error("font->read: illegal or wrong number of arguments\n"); -  +     do    {   #ifdef FONT_DEBUG    fprintf(stderr,"FONT open '%s'\n",sp[-args].u.string->str);   #endif    fd = fd_open(sp[-args].u.string->str,fd_RDONLY,0);    if (errno == EINTR) check_threads_etc();    } while(fd < 0 && errno == EINTR);       if (fd >= 0)    { -  struct font *new_font; -  +     size = (size_t) file_size(fd);    if (size > 0)    { -  new_font=(struct font *)xalloc(sizeof(struct font)); -  +     THREADS_ALLOW();   #ifdef HAVE_MMAP -  new_font->mem = -  mmap(0,size,PROT_READ,MAP_SHARED,fd,0); - #ifdef MAP_FAILED -  if ((char *)new_font->mem == (char *)MAP_FAILED) - #else -  if (new_font->mem==(void*)-1) - #endif -  { -  new_font->mem=0; -  new_font->mmaped_size=0; -  } +  fh = (struct file_head *) +  mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); +  if (fh != (struct file_head *)MAP_FAILED) +  mmaped_size = size;    else -  new_font->mmaped_size=size; - #else -  new_font->mem = malloc(size); +  { + #endif +  fh = (struct file_head *)malloc(size);   #ifdef FONT_DEBUG -  fprintf(stderr,"FONT Malloced %p (%d)\n",new_font->mem,size); +  fprintf(stderr,"FONT Malloced %p (%d)\n", fh, size);   #endif -  if ((new_font->mem) && (!my_read(fd,new_font->mem,size))) +  if (fh && (!my_read(fd, fh, size)))    { -  free(new_font->mem); -  new_font->mem = NULL; +  free(fh); +  fh = NULL;    } -  + #ifdef HAVE_MMAP +  }   #endif    THREADS_DISALLOW();    -  +  } /* size failure */ + #ifdef FONT_DEBUG +  else fprintf(stderr,"FONT size failure\n"); + #endif +  fd_close(fd); +  } /* fd failure */ + #ifdef FONT_DEBUG +  else fprintf(stderr,"FONT fd failure\n"); + #endif +  } +     if (THIS) -  /* In case font_load got called again in the THREADS_ALLOW block. */ +  {    free_font_struct(THIS); -  THIS = new_font; +  THIS=NULL; +  }    - loading_default: -  -  if (THIS->mem) +  if (fh)    { -  struct file_head -  { -  unsigned INT32 cookie; -  unsigned INT32 version; -  unsigned INT32 chars; -  unsigned INT32 height; -  unsigned INT32 baseline; -  unsigned INT32 o[1]; -  } *fh; +     struct char_head    {    unsigned INT32 width;    unsigned INT32 spacing;    unsigned char data[1];    } *ch;      #ifdef FONT_DEBUG    fprintf(stderr,"FONT mapped ok\n");   #endif    -  fh=(struct file_head*)THIS->mem; -  +     if (ntohl(fh->cookie)==0x464f4e54) /* "FONT" */    {   #ifdef FONT_DEBUG    fprintf(stderr,"FONT cookie ok\n");   #endif    if (ntohl(fh->version)==1)    { -  +  struct font *new_font; +  unsigned long num_chars;    unsigned long i;      #ifdef FONT_DEBUG    fprintf(stderr,"FONT version 1\n");   #endif    -  THIS->chars=ntohl(fh->chars); +  num_chars = ntohl(fh->chars);       new_font=malloc(sizeof(struct font)+ -  sizeof(struct _char)*(THIS->chars-1)); +  sizeof(struct _char)*(num_chars-1));    if(!new_font) { -  free(THIS); +  if (args) { + #ifdef HAVE_MMAP +  if (mmaped_size) +  munmap((void *)fh, mmaped_size); +  else + #endif +  free(fh); +  }    SIMPLE_OUT_OF_MEMORY_ERROR(0,0);    } -  new_font->mem=THIS->mem; +  +  new_font->mem = (void *)fh;   #ifdef HAVE_MMAP -  new_font->mmaped_size=THIS->mmaped_size; +  new_font->mmaped_size = mmaped_size;   #endif -  new_font->chars=THIS->chars; +  new_font->chars = num_chars;    new_font->xspacing_scale = 1.0;    new_font->yspacing_scale = 1.0;    new_font->justification = J_LEFT; -  free(THIS); -  THIS=new_font; +  new_font->height=ntohl(fh->height); +  new_font->baseline=ntohl(fh->baseline);    -  THIS->height=ntohl(fh->height); -  THIS->baseline=ntohl(fh->baseline); -  -  for (i=0; i<THIS->chars; i++) +  for (i=0; i<num_chars; i++)    { -  if (i*sizeof(INT32)<(size_t)size -  && ntohl(fh->o[i])<(size_t)size +  if (i*sizeof(INT32)<size +  && ntohl(fh->o[i])<size    && ! ( ntohl(fh->o[i]) % 4) ) /* must be aligned */    { -  ch=(struct char_head*) -  ((char *)(THIS->mem)+ntohl(fh->o[i])); -  THIS->charinfo[i].width = ntohl(ch->width); -  THIS->charinfo[i].spacing = ntohl(ch->spacing); -  THIS->charinfo[i].pixels = ch->data; +  ch = (struct char_head*) +  (((char *)(fh)) + ntohl(fh->o[i])); +  new_font->charinfo[i].width = ntohl(ch->width); +  new_font->charinfo[i].spacing = ntohl(ch->spacing); +  new_font->charinfo[i].pixels = ch->data;    }    else /* illegal <tm> offset or illegal align */    {   #ifdef FONT_DEBUG    fprintf(stderr,"FONT failed on char %02xh %d '%c'\n",    i,i,i);   #endif    free_font_struct(new_font); -  THIS=NULL; -  if (fd >= 0) { -  fd_close(fd); -  } +     pop_n_elems(args);    push_int(0);    return;    } -  +     }    -  if (!args) goto done; -  -  fd_close(fd); +     pop_n_elems(args); -  +  THIS = new_font;    ref_push_object(THISOBJ); /* success */   #ifdef FONT_DEBUG    fprintf(stderr,"FONT successfully loaded\n");   #endif    return;    } /* wrong version */   #ifdef FONT_DEBUG    else fprintf(stderr,"FONT unknown version\n");   #endif    } /* wrong cookie */   #ifdef FONT_DEBUG    else fprintf(stderr,"FONT wrong cookie\n");   #endif -  if (!args) goto done; /* just in case */ +  if (args) { + #ifdef HAVE_MMAP +  if (mmaped_size) +  munmap((void *)fh, mmaped_size); +  else + #endif +  free(fh); +  }    } /* mem failure */   #ifdef FONT_DEBUG    else fprintf(stderr,"FONT mem failure\n");   #endif -  free_font_struct(THIS); -  THIS=NULL; -  } /* size failure */ - #ifdef FONT_DEBUG -  else fprintf(stderr,"FONT size failure\n"); - #endif -  fd_close(fd); -  } /* fd failure */ - #ifdef FONT_DEBUG -  else fprintf(stderr,"FONT fd failure\n"); - #endif +     - done: -  +     pop_n_elems(args);    push_int(0);    return;   }    -  + /*! @decl void create(string filename) +  *! Loads a font file to this font object. +  *! Similar to @[load()]. +  */ +  + void font_create(INT32 args) + { +  font_load(args); +  pop_stack(); + } +    /*! @decl Image.Image write(string text, string ... more_text_lines)    *! Writes some text; thus creating an image object    *! that can be used as mask or as a complete picture.    *! One or more text lines may be provided.    *!    *! @seealso    *! @[text_extents], @[load], @[Image.Image->paste_mask], @[Image.Image->paste_alpha_color]   */      void font_write(INT32 args)
pike.git/src/modules/Image/font.c:698:    this->height);    xsize += char_space(this, c);    }    }    /* THREADS_DISALLOW(); */    break;    default:    Pike_fatal("Illegal shift size!\n");    }    } -  UNSET_ONERROR(err); -  free(width_of); +  CALL_AND_UNSET_ONERROR(err);       pop_n_elems(args);    push_object(o);   }      /*! @decl int height()    *! Returns the font height.    *!    *! @seealso    *! @[baseline], @[text_extents]