示例#1
0
static undef_int
i_init_t1_low(int t1log) {
  int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE;

  mm_log((1,"init_t1(%d)\n", t1log));

  i_clear_error();

  if (t1_active_fonts) {
    mm_log((1, "Cannot re-initialize T1 - active fonts\n"));
    i_push_error(0, "Cannot re-initialize T1 - active fonts");
    return 1;
  }

  if (t1_initialized) {
    T1_CloseLib();
    t1_initialized = 0;
  }
  
  if (t1log)
    init_flags |= LOGFILE;
  if ((T1_InitLib(init_flags) == NULL)){
    mm_log((1,"Initialization of t1lib failed\n"));
    i_push_error(0, "T1_InitLib failed");
    return(1);
  }
  T1_SetLogLevel(T1LOG_DEBUG);

  ++t1_initialized;

  return(0);
}
示例#2
0
static i_tt_engine *
i_init_tt(void) {
  TT_Error  error;
  im_context_t ctx = im_get_context();
  TT_Byte palette[] = { 0, 64, 127, 191, 255 };
  i_tt_engine *result = im_context_slot_get(ctx, slot);

  i_clear_error();

  if (result == NULL) {
    result = mymalloc(sizeof(i_tt_engine));
    memset(result, 0, sizeof(*result));
    im_context_slot_set(ctx, slot, result);
    mm_log((1, "allocated FT1 state %p\n", result));
  }

  mm_log((1,"init_tt()\n"));

  if (result->initialized)
    return result;

  error = TT_Init_FreeType( &result->engine );
  if ( error ){
    mm_log((1,"Initialization of freetype failed, code = 0x%x\n",
	    (unsigned)error));
    i_tt_push_error(error);
    i_push_error(0, "Could not initialize freetype 1.x");
    return NULL;
  }

#ifdef FTXPOST
  error = TT_Init_Post_Extension( result->engine );
  if (error) {
    mm_log((1, "Initialization of Post extension failed = 0x%x\n",
	    (unsigned)error));
    
    i_tt_push_error(error);
    i_push_error(0, "Could not initialize FT 1.x POST extension");
    return NULL;
  }
#endif

  error = TT_Set_Raster_Gray_Palette(result->engine, palette);
  if (error) {
    mm_log((1, "Initialization of gray levels failed = 0x%x\n",
	    (unsigned)error));
    i_tt_push_error(error);
    i_push_error(0, "Could not initialize FT 1.x POST extension");
    return NULL;
  }

  mm_log((1, "initialized FT1 state %p\n", result));

  result->initialized = 1;

  return result;
}
示例#3
0
size_t
i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf, 
                 size_t name_buf_size) {
#ifdef FTXPOST
  TT_Error rc;
  TT_String *psname;
  TT_UShort index;

  i_clear_error();

  if (!handle->loaded_names) {
    TT_Post post;
    mm_log((1, "Loading PS Names"));
    handle->load_cond = TT_Load_PS_Names(handle->face, &post);
    ++handle->loaded_names;
  }

  if (handle->load_cond) {
    i_push_errorf(handle->load_cond, "error loading names (%#x)",
		  (unsigned)handle->load_cond);
    return 0;
  }
  
  index = TT_Char_Index(handle->char_map, ch);
  if (!index) {
    i_push_error(0, "no such character");
    return 0;
  }

  rc = TT_Get_PS_Name(handle->face, index, &psname);

  if (rc) {
    i_push_error(rc, "error getting name");
    return 0;
  }

  strncpy(name_buf, psname, name_buf_size);
  name_buf[name_buf_size-1] = '\0';

  return strlen(psname) + 1;
#else
  mm_log((1, "FTXPOST extension not enabled\n"));
  i_clear_error();
  i_push_error(0, "Use of FTXPOST extension disabled");

  return 0;
#endif
}
示例#4
0
static char *
t1_from_utf8(char const *in, size_t len, int *outlen) {
  /* at this point len is from a STRLEN which should be size_t and can't
     be too big for mymalloc */
  char *out = mymalloc(len+1); /* rechecked 29jul11 tonyc */
  char *p = out;
  unsigned long c;

  while (len) {
    c = i_utf8_advance(&in, &len);
    if (c == ~0UL) {
      myfree(out);
      i_push_error(0, "invalid UTF8 character");
      return 0;
    }
    /* yeah, just drop them */
    if (c < 0x100) {
      *p++ = (char)c;
    }
  }
  *p = '\0';
  *outlen = p - out;

  return out;
}
示例#5
0
/*
=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
}
示例#6
0
static
int
my_handler(Display *display, XErrorEvent *error) {
  char buffer[500];

  XGetErrorText(display, error->error_code, buffer, sizeof(buffer));
  i_push_error(error->error_code, buffer);

  return 0;
}
示例#7
0
int
i_t1_has_chars(i_t1_font_t font, const char *text, size_t len, int utf8,
               char *out) {
  int count = 0;
  int font_num = font->font_id;
  
  i_mutex_lock(mutex);

  mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %u, utf8 %d)\n", 
          font_num, text, (unsigned)len, utf8));

  i_clear_error();
  if (T1_LoadFont(font_num)) {
    t1_push_error();
    i_mutex_unlock(mutex);
    return 0;
  }

  while (len) {
    unsigned long c;
    if (utf8) {
      c = i_utf8_advance(&text, &len);
      if (c == ~0UL) {
        i_push_error(0, "invalid UTF8 character");
	i_mutex_unlock(mutex);
        return 0;
      }
    }
    else {
      c = (unsigned char)*text++;
      --len;
    }
    
    if (c >= 0x100) {
      /* limit of 256 characters for T1 */
      *out++ = 0;
    }
    else {
      char const * name = T1_GetCharName(font_num, (unsigned char)c);

      if (name) {
        *out++ = strcmp(name, ".notdef") != 0;
      }
      else {
        mm_log((2, "  No name found for character %lx\n", c));
        *out++ = 0;
      }
    }
    ++count;
  }

  i_mutex_unlock(mutex);

  return count;
}
示例#8
0
i_t1_font_t
i_t1_new(char *pfb,char *afm) {
  int font_id;
  i_t1_font_t font;

  i_mutex_lock(mutex);

  i_clear_error();

  if (!t1_initialized && i_init_t1_low(0)) {
    i_mutex_unlock(mutex);
    return NULL;
  }

  mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL")));
  font_id = T1_AddFont(pfb);
  if (font_id<0) {
    mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id));
    t1_push_error();
    i_mutex_unlock(mutex);
    return NULL;
  }
  
  if (afm != NULL) {
    mm_log((1,"i_t1_new: requesting afm file '%s'.\n",afm));
    if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm));
  }

  if (T1_LoadFont(font_id)) {
    mm_log((1, "i_t1_new() -> -1 - T1_LoadFont failed (%d)\n", T1_errno));
    t1_push_error();
    i_push_error(0, "loading font");
    T1_DeleteFont(font_id);
    i_mutex_unlock(mutex);
    return NULL;
  }

  ++t1_active_fonts;

  i_mutex_unlock(mutex);

  font = mymalloc(sizeof(*font));
  font->font_id = font_id;

  mm_log((1, "i_t1_new() -> %p (%d)\n", font, font_id));

  return font;
}
示例#9
0
static
int
i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit,
                        TT_Raster_Map *small_bit, i_img_dim cords[6], 
                        char const* txt, size_t len, int smooth, int utf8 ) {
  unsigned long j;
  TT_F26Dot6 x,y;
  
  mm_log((1,"i_tt_render_all_glyphs( handle %p, inst %d, bit %p, small_bit %p, txt '%.*s', len %ld, smooth %d, utf8 %d)\n",
	  handle, inst, bit, small_bit, (int)len, txt, (long)len, smooth, utf8));
  
  /* 
     y=-( handle->properties.horizontal->Descender * handle->instanceh[inst].imetrics.y_ppem )/(handle->properties.header->Units_Per_EM);
  */

  x=-cords[0]; /* FIXME: If you font is antialiased this should be expanded by one to allow for aa expansion and the allocation too - do before passing here */
  y=-cords[4];
  
  while (len) {
    if (utf8) {
      j = i_utf8_advance(&txt, &len);
      if (j == ~0UL) {
        i_push_error(0, "invalid UTF8 character");
        return 0;
      }
    }
    else {
      j = (unsigned char)*txt++;
      --len;
    }
    if ( !i_tt_get_glyph(handle,inst,j) ) 
      continue;
    i_tt_render_glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, 
                       &handle->instanceh[inst].gmetrics[TT_HASH(j)], bit, 
                       small_bit, x, y, smooth );
    x += handle->instanceh[inst].gmetrics[TT_HASH(j)].advance / 64;
  }

  return 1;
}
示例#10
0
size_t
i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8,
               char *out) {
  size_t count = 0;
  mm_log((1, "i_tt_has_chars(handle %p, text %p, len %ld, utf8 %d)\n", 
          handle, text, (long)len, utf8));

  while (len) {
    unsigned long c;
    int index;
    if (utf8) {
      c = i_utf8_advance(&text, &len);
      if (c == ~0UL) {
        i_push_error(0, "invalid UTF8 character");
        return 0;
      }
    }
    else {
      c = (unsigned char)*text++;
      --len;
    }
    
    if (TT_VALID(handle->char_map)) {
      index = TT_Char_Index(handle->char_map, c);
    }
    else {
      index = (c - ' ' + 1) < 0 ? 0 : (c - ' ' + 1);
      if (index >= handle->properties.num_Glyphs)
        index = 0;
    }
    *out++ = index != 0;
    ++count;
  }

  return count;
}
示例#11
0
文件: imext.c 项目: tonycoz/imager
static void
mathom_i_push_error(int code, const char *msg) {
  i_push_error(code, msg);
}
示例#12
0
i_img *
imss_darwin(i_img_dim left, i_img_dim top, i_img_dim right, i_img_dim bottom) {
  CGDisplayCount count;
  CGDisplayErr err;
  CGRect rect;
  CGLPixelFormatObj pix;
  GLint npix;
  CGLContextObj ctx;
  i_img *im;
  CGDirectDisplayID disp;
  i_img_dim screen_width, screen_height;
  i_img_dim width, height;

  CGLPixelFormatAttribute pix_attrs[] =
    {
      kCGLPFADisplayMask, 0, /* filled in later */
      kCGLPFAColorSize, 24,
      kCGLPFAAlphaSize, 0,
      kCGLPFAFullScreen,
      0
    };

  i_clear_error();

  disp = CGMainDisplayID();
  if (!disp) {
    i_push_error(0, "No main display");
    return NULL;
  }
  
  /* for now, only interested in the first display */
  rect = CGDisplayBounds(disp);
  screen_width = rect.size.width;
  screen_height = rect.size.height;

  /* adjust negative/zero values to window size */
  if (left < 0)
    left += screen_width;
  if (top < 0)
    top += screen_height;
  if (right <= 0)
    right += screen_width;
  if (bottom <= 0)
    bottom += screen_height;
  
  /* clamp */
  if (left < 0)
    left = 0;
  if (right > screen_width)
    right = screen_width;
  if (top < 0)
    top = 0;
  if (bottom > screen_height)
    bottom = screen_height;

  /* validate */
  if (right <= left || bottom <= top) {
    i_push_error(0, "image would be empty");
    return NULL;
  }

  width = right - left;
  height = bottom - top;

  /* select a pixel format */
  pix_attrs[1] = CGDisplayIDToOpenGLDisplayMask(disp);
  err = CGLChoosePixelFormat(pix_attrs, &pix, &npix);
  if (err) {
    i_push_errorf(err, "CGLChoosePixelFormat: %d", (int)err);
    return NULL;
  }
  if (!npix) {
    i_push_error(0, "No pixel format found - hidden display?");
    return NULL;
  }

  /* make ourselves a context */
  err = CGLCreateContext(pix, NULL, &ctx);
  CGLDestroyPixelFormat(pix);
  if (err) {
    i_push_errorf(err, "CGLCreateContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetCurrentContext(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetCurrentContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetFullScreen(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetFullScreen: %d", (int)err);
    return NULL;
  }

  /* capture */
  im = i_img_8_new(width, height, 3);
  if (im) {
    size_t line_size = width * 4; 
    size_t buf_size = line_size * height;
    unsigned char *buf = malloc(buf_size);
    i_img_dim y = height - 1;
    i_color *bufp = (i_color *)buf; /* hackish */

    /* GL has the vertical axis going from bottom to top, so translate it */

    glReadBuffer(GL_FRONT);
    glReadPixels(left, screen_height - top - height, width, height,
		 GL_RGBA, GL_UNSIGNED_BYTE, buf);

    /* transfer */
    while (y >= 0) {
      i_plin(im, 0, width, y, bufp);
      bufp += width;
      --y;
    }
    
    free(buf);

    i_tags_setn(&im->tags, "ss_window_width", width);
    i_tags_setn(&im->tags, "ss_window_height", height);
    i_tags_set(&im->tags, "ss_type", "Darwin", 6);
    i_tags_set(&im->tags, "ss_variant", "<11", 3);
    i_tags_setn(&im->tags, "ss_left", left);
    i_tags_setn(&im->tags, "ss_top", top);
  }

  /* clean up */
  CGLSetCurrentContext(NULL);
  CGLDestroyContext(ctx);

  return im;
}
示例#13
0
static void
t1_push_error(void) {
#if T1LIB_VERSION > 5 || T1LIB_VERSION == 5 && T1LIB_VERSION >= 1
  /* I don't know when T1_StrError() was introduced, be conservative */
  i_push_error(T1_errno, T1_StrError(T1_errno));
#else
  switch (T1_errno) {
  case 0: 
    i_push_error(0, "No error"); 
    break;

#ifdef T1ERR_SCAN_FONT_FORMAT
  case T1ERR_SCAN_FONT_FORMAT:
    i_push_error(T1ERR_SCAN_FONT_FORMAT, "Attempt to Load Multiple Master Font"); 
    break;
#endif

#ifdef T1ERR_SCAN_FILE_OPEN_ERR
  case T1ERR_SCAN_FILE_OPEN_ERR:
    i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "Type 1 Font File Open Error"); 
    break;
#endif

#ifdef T1ERR_SCAN_OUT_OF_MEMORY
  case T1ERR_SCAN_OUT_OF_MEMORY:
    i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "Virtual Memory Exceeded"); 
    break;
#endif

#ifdef T1ERR_SCAN_ERROR
  case T1ERR_SCAN_ERROR:
    i_push_error(T1ERR_SCAN_ERROR, "Syntactical Error Scanning Font File"); 
    break;
#endif

#ifdef T1ERR_SCAN_FILE_EOF
  case T1ERR_SCAN_FILE_EOF:
    i_push_error(T1ERR_SCAN_FILE_EOF, "Premature End of Font File Encountered"); 
    break;
#endif

#ifdef T1ERR_PATH_ERROR
  case T1ERR_PATH_ERROR:
    i_push_error(T1ERR_PATH_ERROR, "Path Construction Error"); 
    break;
#endif

#ifdef T1ERR_PARSE_ERROR
  case T1ERR_PARSE_ERROR:
    i_push_error(T1ERR_PARSE_ERROR, "Font is Corrupt"); 
    break;
#endif

#ifdef T1ERR_TYPE1_ABORT
  case T1ERR_TYPE1_ABORT:
    i_push_error(T1ERR_TYPE1_ABORT, "Rasterization Aborted"); 
    break;
#endif

#ifdef T1ERR_INVALID_FONTID
  case T1ERR_INVALID_FONTID:
    i_push_error(T1ERR_INVALID_FONTID, "Font ID Invalid in this Context"); 
    break;
#endif

#ifdef T1ERR_INVALID_PARAMETER
  case T1ERR_INVALID_PARAMETER:
    i_push_error(T1ERR_INVALID_PARAMETER, "Invalid Argument in Function Call"); 
    break;
#endif

#ifdef T1ERR_OP_NOT_PERMITTED
  case T1ERR_OP_NOT_PERMITTED:
    i_push_error(T1ERR_OP_NOT_PERMITTED, "Operation not Permitted"); 
    break;
#endif

#ifdef T1ERR_ALLOC_MEM
  case T1ERR_ALLOC_MEM:
    i_push_error(T1ERR_ALLOC_MEM, "Memory Allocation Error"); 
    break;
#endif

#ifdef T1ERR_FILE_OPEN_ERR
  case T1ERR_FILE_OPEN_ERR:
    i_push_error(T1ERR_FILE_OPEN_ERR, "Error Opening File"); 
    break;
#endif

#ifdef T1ERR_UNSPECIFIED
  case T1ERR_UNSPECIFIED:
    i_push_error(T1ERR_UNSPECIFIED, "Unspecified T1Lib Error"); 
    break;
#endif

#ifdef T1ERR_NO_AFM_DATA
  case T1ERR_NO_AFM_DATA:
    i_push_error(T1ERR_NO_AFM_DATA, "Missing AFM Data"); 
    break;
#endif

#ifdef T1ERR_X11
  case T1ERR_X11:
    i_push_error(T1ERR_X11, "X11 Interface Error"); 
    break;
#endif

#ifdef T1ERR_COMPOSITE_CHAR
  case T1ERR_COMPOSITE_CHAR:
    i_push_error(T1ERR_COMPOSITE_CHAR, "Missing Component of Composite Character"); 
    break;
#endif

#ifdef T1ERR_SCAN_ENCODING
  case T1ERR_SCAN_ENCODING:
    i_push_error(T1ERR_SCAN_ENCODING, "Error Scanning Encoding File"); 
    break;
#endif

  default:
    i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno);
  }
#endif
}
示例#14
0
TT_Fonthandle*
i_tt_new(const char *fontname) {
  TT_Error error;
  TT_Fonthandle *handle;
  unsigned short i,n;
  unsigned short platform,encoding;
  i_tt_engine *tteng;

  if ((tteng = i_init_tt()) == NULL) {
    i_push_error(0, "Could not initialize FT1 engine");
    return NULL;
  }

  i_clear_error();
  
  mm_log((1,"i_tt_new(fontname '%s')\n",fontname));
  
  /* allocate memory for the structure */
  
  handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */

  /* load the typeface */
  error = TT_Open_Face( tteng->engine, fontname, &handle->face );
  if ( error ) {
    myfree(handle);
    if ( error == TT_Err_Could_Not_Open_File ) {
      mm_log((1, "Could not find/open %s.\n", fontname ));
    }
    else {
      mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname, 
              (unsigned)error )); 
    }
    i_tt_push_error(error);
    return NULL;
  }
  
  TT_Get_Face_Properties( handle->face, &(handle->properties) );

  /* First, look for a Unicode charmap */
  n = handle->properties.num_CharMaps;
  USTRCT( handle->char_map )=NULL; /* Invalidate character map */
  
  for ( i = 0; i < n; i++ ) {
    TT_Get_CharMap_ID( handle->face, i, &platform, &encoding );
    if ( (platform == 3 && encoding == 1 ) 
         || (platform == 0 && encoding == 0 ) ) {
      mm_log((2,"i_tt_new - found char map platform %u encoding %u\n", 
              platform, encoding));
      TT_Get_CharMap( handle->face, i, &(handle->char_map) );
      break;
    }
  }
  if (!USTRCT(handle->char_map) && n != 0) {
    /* just use the first one */
    TT_Get_CharMap( handle->face, 0, &(handle->char_map));
  }

  /* Zero the pointsizes - and ordering */
  
  for(i=0;i<TT_CHC;i++) {
    USTRCT(handle->instanceh[i].instance)=NULL;
    handle->instanceh[i].order=i;
    handle->instanceh[i].ptsize=0;
    handle->instanceh[i].smooth=-1;
  }

#ifdef FTXPOST
  handle->loaded_names = 0;
#endif

  mm_log((1,"i_tt_new <- %p\n",handle));
  return handle;
}
示例#15
0
static
int
i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j) {
  unsigned short load_flags, code;
  TT_Error error;

  mm_log((1, "i_tt_get_glyph(handle %p, inst %d, j %lu (%c))\n",
          handle,inst,j, (int)((j >= ' ' && j <= '~') ? j : '.')));
  
  /*mm_log((1, "handle->instanceh[inst].glyphs[j]=0x%08X\n",handle->instanceh[inst].glyphs[j] ));*/

  if ( TT_VALID(handle->instanceh[inst].glyphs[TT_HASH(j)].glyph)
       && handle->instanceh[inst].glyphs[TT_HASH(j)].ch == j) {
    mm_log((1,"i_tt_get_glyph: %lu in cache\n",j));
    return 1;
  }

  if ( TT_VALID(handle->instanceh[inst].glyphs[TT_HASH(j)].glyph) ) {
    /* clean up the entry */
    TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph );
    USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL;
    handle->instanceh[inst].glyphs[TT_HASH(j)].ch = TT_NOCHAR;
  }
  
  /* Ok - it wasn't cached - try to get it in */
  load_flags = TTLOAD_SCALE_GLYPH;
  if ( LTT_hinted ) load_flags |= TTLOAD_HINT_GLYPH;
  
  if ( !TT_VALID(handle->char_map) ) {
    code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1);
    if ( code >= handle->properties.num_Glyphs ) code = 0;
  } else code = TT_Char_Index( handle->char_map, j );
  
  if ( (error = TT_New_Glyph( handle->face, &handle->instanceh[inst].glyphs[TT_HASH(j)].glyph)) ) {
    mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error ));
    i_push_error(error, "TT_New_Glyph()");
    return 0;
  }
  if ( (error = TT_Load_Glyph( handle->instanceh[inst].instance, handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, code, load_flags)) ) {
    mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error ));
    /* Don't leak */
    TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph );
    USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL;
    i_push_error(error, "TT_Load_Glyph()");
    return 0;
  }

  /* At this point the glyph should be allocated and loaded */
  handle->instanceh[inst].glyphs[TT_HASH(j)].ch = j;

  /* Next get the glyph metrics */
  error = TT_Get_Glyph_Metrics( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, 
                                &handle->instanceh[inst].gmetrics[TT_HASH(j)] );
  if (error) {
    mm_log((1, "TT_Get_Glyph_Metrics: error %#x.\n", (unsigned)error ));
    TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph );
    USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL;
    handle->instanceh[inst].glyphs[TT_HASH(j)].ch = TT_NOCHAR;
    i_push_error(error, "TT_Get_Glyph_Metrics()");
    return 0;
  }

  return 1;
}
示例#16
0
undef_int
i_t1_text(i_t1_font_t font, i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl, double points,const char* str,size_t len,int align, int utf8, char const *flags, int aa) {
  GLYPH *glyph;
  int xsize,ysize,y;
  int mod_flags = t1_get_flags(flags);
  i_render *r;
  int fontnum = font->font_id;

  mm_log((1, "i_t1_text(font %p (%d), im %p, (xb,yb)=" i_DFp ", cl (%d,%d,%d,%d), points %g, str %p, len %u, align %d, utf8 %d, flags '%s', aa %d)\n",
	  font, fontnum, im, i_DFcp(xb, yb), cl->rgba.r, cl->rgba.g, cl->rgba.b, cl->rgba.a, points, str, (unsigned)len, align, utf8, flags, aa));

  i_clear_error();

  if (im == NULL) {
    i_push_error(0, "null image");
    mm_log((1,"i_t1_text: Null image in input\n"));
    return(0);
  }

  i_mutex_lock(mutex);

  i_t1_set_aa(aa);

  if (utf8) {
    int worklen;
    char *work = t1_from_utf8(str, len, &worklen);
    if (!work) {
      i_mutex_unlock(mutex);
      return 0;
    }
    glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
    myfree(work);
  }
  else {
    /* T1_AASetString() accepts a char * not a const char */
    glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL);
  }
  if (glyph == NULL) {
    mm_log((1, "T1_AASetString failed\n"));
    t1_push_error();
    i_push_error(0, "i_t1_text(): T1_AASetString failed");
    i_mutex_unlock(mutex);
    return 0;
  }

  mm_log((1,"metrics:  ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
  mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
  mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
  mm_log((1,"bpp: %lu\n",(unsigned long)glyph->bpp));
  
  xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
  ysize=glyph->metrics.ascent-glyph->metrics.descent;
  
  mm_log((1,"width: %d height: %d\n",xsize,ysize));

  if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }

  r = i_render_new(im, xsize);
  for(y=0;y<ysize;y++) {
    i_render_color(r, xb, yb+y, xsize, (unsigned char *)glyph->bits+y*xsize, cl);
  }
  i_render_delete(r);

  i_mutex_unlock(mutex);
    
  return 1;
}
示例#17
0
/*
=item i_tt_face_name(handle, name_buf, name_buf_size)

Retrieve's the font's postscript name.

This is complicated by the need to handle encodings and so on.

=cut
 */
size_t
i_tt_face_name(TT_Fonthandle *handle, char *name_buf, size_t name_buf_size) {
  TT_Face_Properties props;
  int name_count;
  int i;
  TT_UShort platform_id, encoding_id, lang_id, name_id;
  TT_UShort name_len;
  TT_String *name;
  int want_index = -1; /* an acceptable but not perfect name */
  int score = 0;

  i_clear_error();
  
  TT_Get_Face_Properties(handle->face, &props);
  name_count = props.num_Names;
  for (i = 0; i < name_count; ++i) {
    TT_Get_Name_ID(handle->face, i, &platform_id, &encoding_id, &lang_id, 
                   &name_id);

    TT_Get_Name_String(handle->face, i, &name, &name_len);

    if (platform_id != TT_PLATFORM_APPLE_UNICODE && name_len
        && name_id == TT_NAME_ID_PS_NAME) {
      int might_want_index = -1;
      int might_score = 0;
      if ((platform_id == TT_PLATFORM_MACINTOSH && encoding_id == TT_MAC_ID_ROMAN)
          ||
          (platform_id == TT_PLATFORM_MICROSOFT && encoding_id == TT_MS_LANGID_ENGLISH_UNITED_STATES)) {
        /* exactly what we want */
        want_index = i;
        break;
      }
      
      if (platform_id == TT_PLATFORM_MICROSOFT
          && (encoding_id & 0xFF) == TT_MS_LANGID_ENGLISH_GENERAL) {
        /* any english is good */
        might_want_index = i;
        might_score = 9;
      }
      /* there might be something in between */
      else {
        /* anything non-unicode is better than nothing */
        might_want_index = i;
        might_score = 1;
      }
      if (might_score > score) {
        score = might_score;
        want_index = might_want_index;
      }
    }
  }

  if (want_index != -1) {
    TT_Get_Name_String(handle->face, want_index, &name, &name_len);
    
    strncpy(name_buf, name, name_buf_size);
    name_buf[name_buf_size-1] = '\0';

    return strlen(name) + 1;
  }
  else {
    i_push_error(0, "no face name present");
    return 0;
  }
}
示例#18
0
i_img *
imss_x11(unsigned long display_ul, int window_id,
	 int left, int top, int right, int bottom) {
  Display *display = (Display *)display_ul;
  int own_display = 0; /* non-zero if we connect */
  XImage *image;
  XWindowAttributes attr;
  i_img *result;
  i_color *line, *cp;
  int x, y;
  XColor *colors;
  XErrorHandler old_handler;
  int width, height;

  i_clear_error();

  /* we don't want the default noisy error handling */
  old_handler = XSetErrorHandler(my_handler);

  if (!display) {
    display = XOpenDisplay(NULL);
    ++own_display;
    if (!display) {
      XSetErrorHandler(old_handler);
      i_push_error(0, "No display supplied and cannot connect");
      return NULL;
    }
  }

  if (!window_id) {
    int screen = DefaultScreen(display);
    window_id = RootWindow(display, screen);
  }

  if (!XGetWindowAttributes(display, window_id, &attr)) {
    XSetErrorHandler(old_handler);
    if (own_display)
      XCloseDisplay(display);
    i_push_error(0, "Cannot XGetWindowAttributes");
    return NULL;
  }

  /* adjust negative/zero values to window size */
  if (left < 0)
    left += attr.width;
  if (top < 0)
    top += attr.height;
  if (right <= 0)
    right += attr.width;
  if (bottom <= 0)
    bottom += attr.height;
  
  /* clamp */
  if (left < 0)
    left = 0;
  if (right > attr.width)
    right = attr.width;
  if (top < 0)
    top = 0;
  if (bottom > attr.height)
    bottom = attr.height;

  /* validate */
  if (right <= left || bottom <= top) {
    XSetErrorHandler(old_handler);
    if (own_display)
      XCloseDisplay(display);
    i_push_error(0, "image would be empty");
    return NULL;
  }
  width = right - left;
  height = bottom - top;
  image = XGetImage(display, window_id, left, top, width, height,
                    -1, ZPixmap);
  if (!image) {
    XSetErrorHandler(old_handler);
    if (own_display)
      XCloseDisplay(display);
    i_push_error(0, "Cannot XGetImage");
    return NULL;
  }

  result = i_img_8_new(width, height, 3);
  line = mymalloc(sizeof(i_color) * width);
  colors = mymalloc(sizeof(XColor) * width);
  for (y = 0; y < height; ++y) {
    cp = line;
    /* XQueryColors seems to be a round-trip, so do one big request
       instead of one per pixel */
    for (x = 0; x < width; ++x) {
      colors[x].pixel = XGetPixel(image, x, y);
    }
    XQueryColors(display, attr.colormap, colors, width);
    for (x = 0; x < width; ++x) {
      cp->rgb.r = colors[x].red >> 8;
      cp->rgb.g = colors[x].green >> 8;
      cp->rgb.b = colors[x].blue >> 8;
      ++cp;
    }
    i_plin(result, 0, width, y, line);
  }
  myfree(line);
  myfree(colors);
  XDestroyImage(image);

  XSetErrorHandler(old_handler);
  if (own_display)
    XCloseDisplay(display);

  i_tags_setn(&result->tags, "ss_window_width", attr.width);
  i_tags_setn(&result->tags, "ss_window_height", attr.height);
  i_tags_set(&result->tags, "ss_type", "X11", 3);
  i_tags_setn(&result->tags, "ss_left", left);
  i_tags_setn(&result->tags, "ss_top", top);

  return result;
}
示例#19
0
undef_int
i_t1_cp(i_t1_font_t font, i_img *im,i_img_dim xb,i_img_dim yb,int channel,double points,char* str,size_t len,int align, int utf8, char const *flags, int aa) {
  GLYPH *glyph;
  int xsize,ysize,x,y;
  i_color val;
  int mod_flags = t1_get_flags(flags);
  int fontnum = font->font_id;

  unsigned int ch_mask_store;
  
  i_clear_error();

  mm_log((1, "i_t1_cp(font %p (%d), im %p, (xb,yb)=" i_DFp ", channel %d, points %g, str %p, len %u, align %d, utf8 %d, flags '%s', aa %d)\n",
	  font, fontnum, im, i_DFcp(xb, yb), channel, points, str, (unsigned)len, align, utf8, flags, aa));

  if (im == NULL) {
    mm_log((1,"i_t1_cp: Null image in input\n"));
    i_push_error(0, "null image");
    return(0);
  }

  i_mutex_lock(mutex);

  i_t1_set_aa(aa);

  if (utf8) {
    int worklen;
    char *work = t1_from_utf8(str, len, &worklen);
    if (work == NULL) {
      i_mutex_unlock(mutex);
      return 0;
    }
    glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
    myfree(work);
  }
  else {
    glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL);
  }
  if (glyph == NULL) {
    t1_push_error();
    i_push_error(0, "i_t1_cp: T1_AASetString failed");
    i_mutex_unlock(mutex);
    return 0;
  }

  mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
  mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
  mm_log((1," advanceX: %d  advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
  mm_log((1,"bpp: %lu\n", (unsigned long)glyph->bpp));
  
  xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
  ysize=glyph->metrics.ascent-glyph->metrics.descent;
  
  mm_log((1,"width: %d height: %d\n",xsize,ysize));

  ch_mask_store=im->ch_mask;
  im->ch_mask=1<<channel;

  if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }
  
  for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
    val.channel[channel]=glyph->bits[y*xsize+x];
    i_ppix(im,x+xb,y+yb,&val);
  }
  
  im->ch_mask=ch_mask_store;

  i_mutex_unlock(mutex);

  return 1;
}
示例#20
0
static
undef_int
i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim cords[BOUNDING_BOX_COUNT], int utf8 ) {
  int upm, casc, cdesc, first;
  
  int start    = 0;
  i_img_dim width    = 0;
  int gdescent = 0;
  int gascent  = 0;
  int descent  = 0;
  int ascent   = 0;
  int rightb   = 0;

  unsigned long j;

  mm_log((1,"i_tt_box_inst(handle %p,inst %d,txt '%.*s', len %ld, utf8 %d)\n",
	  handle, inst, (int)len, txt, (long)len, utf8));

  upm     = handle->properties.header->Units_Per_EM;
  gascent  = ( handle->properties.horizontal->Ascender  * handle->instanceh[inst].imetrics.y_ppem + upm - 1) / upm;
  gdescent = ( handle->properties.horizontal->Descender * handle->instanceh[inst].imetrics.y_ppem - upm + 1) / upm;
  
  width   = 0;
  start   = 0;
  
  mm_log((1, "i_tt_box_inst: gascent=%d gdescent=%d\n", gascent, gdescent));

  first=1;
  while (len) {
    if (utf8) {
      j = i_utf8_advance(&txt, &len);
      if (j == ~0UL) {
        i_push_error(0, "invalid UTF8 character");
        return 0;
      }
    }
    else {
      j = (unsigned char)*txt++;
      --len;
    }
    if ( i_tt_get_glyph(handle,inst,j) ) {
      TT_Glyph_Metrics *gm = handle->instanceh[inst].gmetrics + TT_HASH(j);
      width += gm->advance   / 64;
      casc   = (gm->bbox.yMax+63) / 64;
      cdesc  = (gm->bbox.yMin-63) / 64;

      mm_log((1, "i_tt_box_inst: glyph='%c' casc=%d cdesc=%d\n", 
              (int)((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc));

      if (first) {
	start    = gm->bbox.xMin / 64;
	ascent   = (gm->bbox.yMax+63) / 64;
	descent  = (gm->bbox.yMin-63) / 64;
	first = 0;
      }
      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
	*/
	rightb = gm->advance - gm->bearingX 
	  - (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); */
      }

      ascent  = (ascent  >  casc ?  ascent : casc );
      descent = (descent < cdesc ? descent : cdesc);
    }
  }
  
  cords[BBOX_NEG_WIDTH]=start;
  cords[BBOX_GLOBAL_DESCENT]=gdescent;
  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_RIGHT_BEARING + 1;
}