void sort_and_compact_ranges(Range *, unsigned *);
int range_cmp(const void *, const void *);
unsigned round_to_pot(unsigned);
-void *alloc_image_data(size_t, size_t);
+int init_image(Image *, size_t, size_t);
int init_font(Font *, FT_Face, const Range *, unsigned, bool, unsigned, unsigned);
int init_glyphs(Font *, FT_Face, const Range *, bool, unsigned, unsigned);
int copy_bitmap(const FT_Bitmap *, Image *);
return n+1;
}
-void *alloc_image_data(size_t a, size_t b)
+int init_image(Image *image, size_t w, size_t h)
{
- void *ptr;
+ size_t s;
- /* Carry out the multiplication manually so we can check for overflow. */
- while(b>1)
+ image->w = w;
+ image->h = h;
+ image->data = NULL;
+
+ if(!image->w || !image->h)
+ return 0;
+
+ s = w*h;
+ if(s/h!=w)
{
- size_t c = a;
- a *= 2;
- if(b&1)
- a += c;
- if(a<c)
- {
- fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(c/1024*b));
- return NULL;
- }
- b /= 2;
+ fprintf(stderr, "Cannot allocate memory for a %dx%d image\n", image->w, image->h);
+ return -1;
+ }
+
+ image->data = malloc(s);
+ if(!image->data)
+ {
+ fprintf(stderr, "Cannot allocate memory for a %dx%d image\n", image->w, image->h);
+ return -1;
}
- ptr = malloc(a);
- if(!ptr)
- fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(a/1024*b));
- return ptr;
+
+ return 0;
}
int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges, bool autohinter, unsigned distfield, unsigned border)
unsigned char *src;
unsigned char *dst;
- image->w = bmp->width;
- image->h = bmp->rows;
+ if(init_image(image, bmp->width, bmp->rows))
+ return -1;
if(!image->w || !image->h)
- {
- image->data = NULL;
return 0;
- }
-
- image->data = (unsigned char *)malloc(image->w*image->h);
- if(!image->data)
- {
- fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", image->w*image->h);
- return -1;
- }
if(bmp->pitch<0)
src = bmp->buffer+(bmp->rows-1)*-bmp->pitch;
unsigned x, y;
Image base_image;
- if(!bmp->width || !bmp->rows)
- {
- image->w = 0;
- image->h = 0;
- image->data = NULL;
+ if(init_image(image, (bmp->width+scale-1)/scale+2*margin, (bmp->rows+scale-1)/scale+2*margin))
+ return -1;
+ if(!image->w || !image->h)
return 0;
- }
if(copy_bitmap(bmp, &base_image))
return -1;
- image->w = (base_image.w-1)/scale+2*margin+1;
- image->h = (base_image.h-1)/scale+2*margin+1;
- image->data = (unsigned char *)malloc(image->w*image->h);
- if(!image->data)
- {
- fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", image->w*image->h);
- free(base_image.data);
- return -1;
- }
-
for(y=0; y<image->h; ++y) for(x=0; x<image->w; ++x)
{
int bx = (x-margin)*scale+scale/2;
{
unsigned i;
int top = 0, bot = 0;
- unsigned first, last;
+ unsigned first, n_cells;
unsigned maxw = 0, maxh = 0;
/* Find extremes of the glyph images. */
}
first = font->glyphs[0].code;
- if(!seq)
- first -= first%cpl;
- last = font->glyphs[font->n_glyphs-1].code;
-
- font->image.w = cpl*cellw;
if(seq)
- font->image.h = (font->n_glyphs+cpl-1)/cpl*cellh;
+ n_cells = font->n_glyphs;
else
- font->image.h = (last-first+cpl)/cpl*cellh;
+ {
+ first -= first%cpl;
+ n_cells = font->glyphs[font->n_glyphs-1].code+1-first;
+ }
- font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h);
- if(!font->image.data)
+ if(init_image(&font->image, cpl*cellw, (n_cells+cpl-1)/cpl*cellh))
return -1;
memset(font->image.data, 0, font->image.w*font->image.h);
glyphs. Since glyphs are rectangular and the image is filled starting from
the top, it's enough to track the number of used pixels at the top of each
column. */
- font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h);
- if(!font->image.data)
+ if(init_image(&font->image, font->image.w, font->image.h))
return -1;
memset(font->image.data, 0, font->image.w*font->image.h);
used_pixels = (unsigned *)malloc(font->image.w*sizeof(unsigned));