Permalink
Browse files

in-progress work

  • Loading branch information...
1 parent ca9a50d commit c14e25ea8d668085a27788ebb3dd0602af321edd Tony Cook committed Dec 24, 2010
Showing with 1,215 additions and 43 deletions.
  1. +3 −2 Font-BuiltIn/BuiltIn.xs
  2. +8 −1 Font-BuiltIn/Makefile.PL
  3. +195 −6 Font-BuiltIn/imbif.c
  4. +1 −1 Font-BuiltIn/imbif.h
  5. +9 −5 Font-BuiltIn/imbiff.h
  6. +42 −28 Font-BuiltIn/immkfont.pl
  7. +957 −0 Font-BuiltIn/tiny8.imf
View
@@ -28,7 +28,7 @@ i_bif_new(face)
const char *face
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::ImgRaw im
int tx
@@ -38,6 +38,7 @@ i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8)
SV *text_sv
int align
int utf8
+ int dir
PREINIT:
char *text;
STRLEN len;
@@ -48,7 +49,7 @@ i_bif_text(font, im, tx, ty, size, cl, text_sv, align, utf8)
}
#endif
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:
RETVAL
View
@@ -6,7 +6,7 @@ my %opts =
(
NAME => 'Imager::Font::BuiltIn',
VERSION_FROM => 'BuiltIn.pm',
- OBJECT => 'BuiltIn.o imbif.o',
+ OBJECT => 'BuiltIn.o imbif.o tiny.o',
INC => '-I..',
);
my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
@@ -17,4 +17,11 @@ if ($MM_ver > 6.06) {
WriteMakefile(%opts);
+sub MY::postamble {
+ return <<'MAKE'
+tiny.c : tiny8.imf immkfont.pl
+ perl immkfont.pl tiny
+
+MAKE
+}
View
@@ -1,30 +1,219 @@
#include "imbif.h"
#include <string.h>
#include "imext.h"
+#include "tiny.h"
+#include <math.h>
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_new(const char *name) {
i_bif_handle *font;
+ const i_bif_face *found_face = NULL;
+ int i;
+
i_clear_error();
- if (!name || strcmp(name, "bitmap")) {
- i_push_error(0, "Unknown face");
+ if (!name) {
+ 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 mymalloc(sizeof(i_bif_handle));
+ font = mymalloc(sizeof(i_bif_handle));
+ font->face = found_face;
+
+ return font;
}
void
i_bif_destroy(i_bif_handle *font) {
myfree(font);
}
-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);
+static
+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_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size);
View
@@ -10,7 +10,7 @@ extern i_bif_handle *i_bif_new(const char *name);
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_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_face_name(i_bif_handle *handle, char *name_buf, size_t name_buf_size);
View
@@ -1,6 +1,8 @@
#ifndef IMBIFF_H_
#define IMBIFF_H_
+#include <stddef.h>
+
typedef struct {
/* width and height of the glyph */
int width;
@@ -10,16 +12,16 @@ typedef struct {
char is below the baseline */
int baseline;
- /* distance from the draw point
+ /* distance from the draw point */
int offset;
int advance;
- unsigned char *data;
+ const unsigned char *data;
size_t data_size;
} i_bif_glyph;
typedef struct {
int ch;
- i_bif_glyph *glyph;
+ const i_bif_glyph *glyph;
} i_bif_mapping;
typedef struct {
@@ -32,14 +34,16 @@ typedef struct {
int xwidth;
- i_bif_mapping *chars;
+ const i_bif_glyph *default_glyph;
+
+ const i_bif_mapping *chars;
size_t char_count;
} i_bif_font;
typedef struct {
const char *name;
- i_bif_font *fonts;
+ const i_bif_font * const *fonts;
size_t font_count;
} i_bif_face;
Oops, something went wrong.

0 comments on commit c14e25e

Please sign in to comment.