Skip to content

Commit

Permalink
in-progress work
Browse files Browse the repository at this point in the history
  • Loading branch information
Tony Cook committed Dec 24, 2010
1 parent ca9a50d commit c14e25e
Show file tree
Hide file tree
Showing 7 changed files with 1,215 additions and 43 deletions.
5 changes: 3 additions & 2 deletions Font-BuiltIn/BuiltIn.xs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ i_bif_new(face)
const char *face const char *face


int int
i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8) i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8=0, dir=0)
Imager::Font::BI font Imager::Font::BI font
Imager::ImgRaw im Imager::ImgRaw im
int tx int tx
Expand All @@ -38,6 +38,7 @@ i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8)
SV *text_sv SV *text_sv
int align int align
int utf8 int utf8
int dir
PREINIT: PREINIT:
char *text; char *text;
STRLEN len; STRLEN len;
Expand All @@ -48,7 +49,7 @@ i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8)
} }
#endif #endif
text = SvPV(text_sv, len); text = SvPV(text_sv, len);
RETVAL = i_bif_text(font, im, tx, ty, size, cl, text, len, align, utf8); RETVAL = i_bif_text(font, im, tx, ty, size, cl, text, len, align, utf8, dir);
OUTPUT: OUTPUT:
RETVAL RETVAL


Expand Down
9 changes: 8 additions & 1 deletion Font-BuiltIn/Makefile.PL
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ my %opts =
( (
NAME => 'Imager::Font::BuiltIn', NAME => 'Imager::Font::BuiltIn',
VERSION_FROM => 'BuiltIn.pm', VERSION_FROM => 'BuiltIn.pm',
OBJECT => 'BuiltIn.o imbif.o', OBJECT => 'BuiltIn.o imbif.o tiny.o',
INC => '-I..', INC => '-I..',
); );
my $MM_ver = eval $ExtUtils::MakeMaker::VERSION; my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
Expand All @@ -17,4 +17,11 @@ if ($MM_ver > 6.06) {


WriteMakefile(%opts); WriteMakefile(%opts);


sub MY::postamble {
return <<'MAKE'
tiny.c : tiny8.imf immkfont.pl
perl immkfont.pl tiny
MAKE
}
201 changes: 195 additions & 6 deletions Font-BuiltIn/imbif.c
Original file line number Original file line Diff line number Diff line change
@@ -1,30 +1,219 @@
#include "imbif.h" #include "imbif.h"
#include <string.h> #include <string.h>
#include "imext.h" #include "imext.h"
#include "tiny.h"
#include <math.h>


struct i_bif_handle_tag { struct i_bif_handle_tag {
int dummy; i_bif_face const *face;
}; };


static i_bif_face const *faces[] = {
&i_face_tiny
};

static int face_count = sizeof(faces) / sizeof(*faces);

i_bif_handle * i_bif_handle *
i_bif_new(const char *name) { i_bif_new(const char *name) {
i_bif_handle *font; i_bif_handle *font;
const i_bif_face *found_face = NULL;
int i;

i_clear_error(); i_clear_error();
if (!name || strcmp(name, "bitmap")) { if (!name) {
i_push_error(0, "Unknown face"); i_push_error(0, "No face specified");
return NULL;
}

for (i = 0; i < face_count; ++i) {
i_bif_face const * face = faces[i];
if (stricmp(face->name, name) == 0) {
found_face = face;
break;
}
}

if (!found_face) {
i_push_errorf(0, "Face %s not found", name);
return NULL; return NULL;
} }


return mymalloc(sizeof(i_bif_handle)); font = mymalloc(sizeof(i_bif_handle));
font->face = found_face;

return font;
} }


void void
i_bif_destroy(i_bif_handle *font) { i_bif_destroy(i_bif_handle *font) {
myfree(font); myfree(font);
} }


extern int i_bif_bbox(i_bif_handle *handle, double size, char const *text, int len, int utf8, int *bbox); static
extern int i_bif_text(i_bif_handle *handle, i_img *im, int tx, int ty, double size, i_color *cl, const char *text, int len, int align, int utf8); const i_bif_font *
_find_font(i_bif_handle *handle, int size) {
i_bif_face const *face = handle->face;
int i;
for (i = 0; i < face->font_count; ++i) {
if (face->fonts[i]->size >= size) {
return face->fonts[i];
}
}

return NULL;
}

static
const i_bif_glyph *
_find_glyph(i_bif_font const *font, int code) {
/* linear for now */
int i = 0;
while (i < font->char_count) {
if (font->chars[i].ch == code)
return font->chars[i].glyph;
++i;
}

return font->default_glyph;
}

int
i_bif_bbox(i_bif_handle *handle, double size, char const *text, int len, int utf8, int *bbox) {
int isize = ceil(size);
i_bif_font const * font = _find_font(handle, isize);
int width = 0;
int advance = 0;
int ascent = 0;
int descent = 0;
int neg_width = 0;
int rightb = 0;
int i;

if (!font) {
i_push_errorf(0, "No size %d font found", isize);
return 0;
}

if (len) {
const char *p = text;
const i_bif_glyph *glyph;

while (len) {
unsigned long c;
if (utf8) {
c = i_utf8_advance(&p, &len);
if (c == ~0UL) {
i_push_error(0, "invalid UTF8 character");
return 0;
}
}
else {
c = (unsigned char)*text++;
--len;
}

glyph = _find_glyph(font, c);
advance += glyph->advance;
if (glyph->baseline > ascent)
ascent = glyph->baseline;
if (glyph->baseline - glyph->height > descent)
descent = glyph->baseline - glyph->height;
neg_width = glyph->offset;
}

/* get rightb from the last char processed */
rightb = glyph->advance - glyph->width - glyph->offset;
}

bbox[BBOX_GLOBAL_DESCENT] = font->descent;
bbox[BBOX_GLOBAL_ASCENT] = font->ascent;
bbox[BBOX_ADVANCE_WIDTH] = advance;
bbox[BBOX_NEG_WIDTH] = neg_width;
bbox[BBOX_POS_WIDTH] = width - (rightb < 0 ? rightb : 0);
bbox[BBOX_DESCENT] = descent;
bbox[BBOX_ASCENT] = ascent;
bbox[BBOX_RIGHT_BEARING] = rightb;

return BBOX_RIGHT_BEARING + 1;
}

const int dir_cos[4] = { 1, 0, -1, 0 };
const int dir_sin[4] = { 0, 1, 0, -1 };

int
i_bif_text(i_bif_handle *handle, i_img *im, int tx, int ty, double size, i_color *cl, const char *text, int len, int align, int utf8, int dir) {
int isize = ceil(size);
i_bif_font const * font = _find_font(handle, isize);
int dcos, dsin;

if (!font) {
i_push_errorf(0, "No size %d font found", isize);
return 0;
}

dir = dir & 3;
dcos = dir_cos[dir];
dsin = dir_sin[dir];

if (len) {
const char *p = text;
while (len) {
const i_bif_glyph *glyph;
unsigned long c;
int px, py;
int outx, outy;
int width_bytes;
unsigned char *gbyte;

if (utf8) {
c = i_utf8_advance(&p, &len);
if (c == ~0UL) {
i_push_error(0, "invalid UTF8 character");
return 0;
}
}
else {
c = (unsigned char)*text++;
--len;
}

glyph = _find_glyph(font, c);
width_bytes = (glyph->width + 7) / 8;

outy = ty - glyph->baseline;
gbyte = glyph->data;
for (py = 0; py < glyph->height; ++py) {
if (outy >= 0 && outy < im->ysize) {
outx = tx;
for (px = 0; px < width_bytes; ++px) {
unsigned char b = *gbyte++;
if (b) {
unsigned char mask = 0x80;
while (mask) {
if (b & mask)
i_ppix(im, outx, outy, cl);
++outx;
mask >>= 1;
}
}
else {
outx += 8;
}
}
}
else
gbyte += width_bytes;
++outy;
}

tx += glyph->advance;
}
}

return 1;
}

extern int i_bif_has_chars(i_bif_handle *handle, char const *test, int len, int utf8, char *out); extern int i_bif_has_chars(i_bif_handle *handle, char const *test, int len, int utf8, char *out);
extern int i_bif_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size); extern int i_bif_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size);


2 changes: 1 addition & 1 deletion Font-BuiltIn/imbif.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern i_bif_handle *i_bif_new(const char *name);
extern void i_bif_destroy(i_bif_handle *handle); extern void i_bif_destroy(i_bif_handle *handle);


extern int i_bif_bbox(i_bif_handle *handle, double size, char const *text, int len, int utf8, int *bbox); extern int i_bif_bbox(i_bif_handle *handle, double size, char const *text, int len, int utf8, int *bbox);
extern int i_bif_text(i_bif_handle *handle, i_img *im, int tx, int ty, double size, i_color *cl, const char *text, int len, int align, int utf8); extern int i_bif_text(i_bif_handle *handle, i_img *im, int tx, int ty, double size, i_color *cl, const char *text, int len, int align, int utf8, int dir);
extern int i_bif_has_chars(i_bif_handle *handle, char const *test, int len, int utf8, char *out); extern int i_bif_has_chars(i_bif_handle *handle, char const *test, int len, int utf8, char *out);
extern int i_bif_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size); extern int i_bif_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size);


Expand Down
14 changes: 9 additions & 5 deletions Font-BuiltIn/imbiff.h
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef IMBIFF_H_ #ifndef IMBIFF_H_
#define IMBIFF_H_ #define IMBIFF_H_


#include <stddef.h>

typedef struct { typedef struct {
/* width and height of the glyph */ /* width and height of the glyph */
int width; int width;
Expand All @@ -10,16 +12,16 @@ typedef struct {
char is below the baseline */ char is below the baseline */
int baseline; int baseline;


/* distance from the draw point /* distance from the draw point */
int offset; int offset;
int advance; int advance;
unsigned char *data; const unsigned char *data;
size_t data_size; size_t data_size;
} i_bif_glyph; } i_bif_glyph;


typedef struct { typedef struct {
int ch; int ch;
i_bif_glyph *glyph; const i_bif_glyph *glyph;
} i_bif_mapping; } i_bif_mapping;


typedef struct { typedef struct {
Expand All @@ -32,14 +34,16 @@ typedef struct {


int xwidth; int xwidth;


i_bif_mapping *chars; const i_bif_glyph *default_glyph;

const i_bif_mapping *chars;
size_t char_count; size_t char_count;
} i_bif_font; } i_bif_font;


typedef struct { typedef struct {
const char *name; const char *name;


i_bif_font *fonts; const i_bif_font * const *fonts;
size_t font_count; size_t font_count;
} i_bif_face; } i_bif_face;


Expand Down
Loading

0 comments on commit c14e25e

Please sign in to comment.