=cut
*/
-#include "image.h"
+#include "imager.h"
#include <stdio.h>
#include <ft2build.h>
#include FT_FREETYPE_H
*/
FT2_Fonthandle *
-i_ft2_new(char *name, int index) {
+i_ft2_new(const char *name, int index) {
FT_Error error;
FT2_Fonthandle *result;
FT_Face face;
=cut
*/
int
-i_ft2_settransform(FT2_Fonthandle *handle, double *matrix) {
+i_ft2_settransform(FT2_Fonthandle *handle, const double *matrix) {
FT_Matrix m;
FT_Vector v;
int i;
FT_Glyph_Metrics *gm;
int start = 0;
int loadFlags = FT_LOAD_DEFAULT;
- int rightb;
+ int rightb = 0;
mm_log((1, "i_ft2_bbox(handle %p, cheight %f, cwidth %f, text %p, len %d, bbox %p)\n",
handle, cheight, cwidth, text, len, bbox));
handle the case where the right the of the character overlaps the
right*/
rightb = (gm->horiAdvance - gm->horiBearingX - gm->width)/64;
- if (rightb > 0)
- rightb = 0;
+ /*if (rightb > 0)
+ rightb = 0;*/
}
}
bbox[BBOX_NEG_WIDTH] = start;
bbox[BBOX_GLOBAL_DESCENT] = handle->face->size->metrics.descender / 64;
- bbox[BBOX_POS_WIDTH] = width - rightb;
+ bbox[BBOX_POS_WIDTH] = width;
+ if (rightb < 0)
+ bbox[BBOX_POS_WIDTH] -= rightb;
bbox[BBOX_GLOBAL_ASCENT] = handle->face->size->metrics.ascender / 64;
bbox[BBOX_DESCENT] = descent;
bbox[BBOX_ASCENT] = ascent;
bbox[BBOX_ADVANCE_WIDTH] = width;
+ bbox[BBOX_RIGHT_BEARING] = rightb;
+ mm_log((1, " bbox=> negw=%d glob_desc=%d pos_wid=%d glob_asc=%d desc=%d asc=%d adv_width=%d rightb=%d\n", bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5], bbox[6], bbox[7]));
- return BBOX_ADVANCE_WIDTH + 1;
+ return BBOX_RIGHT_BEARING + 1;
}
/*
=cut
*/
int
-i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty, i_color *cl,
+i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty, const i_color *cl,
double cheight, double cwidth, char const *text, int len, int align,
int aa, int vlayout, int utf8) {
FT_Error error;
int ch;
i_color pel;
int loadFlags = FT_LOAD_DEFAULT;
+ i_render render;
mm_log((1, "i_ft2_text(handle %p, im %p, tx %d, ty %d, cl %p, cheight %f, cwidth %f, text %p, len %d, align %d, aa %d)\n",
handle, im, tx, ty, cl, cheight, cwidth, text, align, aa));
if (!i_ft2_bbox(handle, cheight, cwidth, text, len, bbox, utf8))
return 0;
+ if (aa)
+ i_render_init(&render, im, bbox[BBOX_POS_WIDTH] - bbox[BBOX_NEG_WIDTH]);
+
if (!align) {
/* this may need adjustment */
tx -= bbox[0] * handle->matrix[0] + bbox[5] * handle->matrix[1] + handle->matrix[2];
ft2_push_message(error);
i_push_errorf(0, "loading glyph for character \\x%02x (glyph 0x%04X)",
c, index);
+ if (aa)
+ i_render_done(&render);
return 0;
}
slot = handle->face->glyph;
gm = &slot->metrics;
- error = FT_Render_Glyph(slot, aa ? ft_render_mode_normal : ft_render_mode_mono);
- if (error) {
- ft2_push_message(error);
- i_push_errorf(0, "rendering glyph 0x%04X (character \\x%02X)");
- return 0;
- }
- if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) {
- bmp = slot->bitmap.buffer;
- for (y = 0; y < slot->bitmap.rows; ++y) {
- int pos = 0;
- int bit = 0x80;
- for (x = 0; x < slot->bitmap.width; ++x) {
- if (bmp[pos] & bit)
- i_ppix(im, tx+x+slot->bitmap_left, ty+y-slot->bitmap_top, cl);
-
- bit >>= 1;
- if (bit == 0) {
- bit = 0x80;
- ++pos;
- }
- }
- bmp += slot->bitmap.pitch;
+ if (gm->width) {
+ error = FT_Render_Glyph(slot, aa ? ft_render_mode_normal : ft_render_mode_mono);
+ if (error) {
+ ft2_push_message(error);
+ i_push_errorf(0, "rendering glyph 0x%04X (character \\x%02X)");
+ if (aa)
+ i_render_done(&render);
+ return 0;
}
- }
- else {
- /* grey scale or something we can treat as greyscale */
- /* we create a map to convert from the bitmap values to 0-255 */
- if (last_mode != slot->bitmap.pixel_mode
- || last_grays != slot->bitmap.num_grays) {
- if (!make_bmp_map(&slot->bitmap, map))
- return 0;
- last_mode = slot->bitmap.pixel_mode;
- last_grays = slot->bitmap.num_grays;
+ if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) {
+ bmp = slot->bitmap.buffer;
+ for (y = 0; y < slot->bitmap.rows; ++y) {
+ int pos = 0;
+ int bit = 0x80;
+ for (x = 0; x < slot->bitmap.width; ++x) {
+ if (bmp[pos] & bit)
+ i_ppix(im, tx+x+slot->bitmap_left, ty+y-slot->bitmap_top, cl);
+
+ bit >>= 1;
+ if (bit == 0) {
+ bit = 0x80;
+ ++pos;
+ }
+ }
+ bmp += slot->bitmap.pitch;
+ }
}
-
- bmp = slot->bitmap.buffer;
- for (y = 0; y < slot->bitmap.rows; ++y) {
- for (x = 0; x < slot->bitmap.width; ++x) {
- int value = map[bmp[x]];
- if (value) {
- i_gpix(im, tx+x+slot->bitmap_left, ty+y-slot->bitmap_top, &pel);
- for (ch = 0; ch < im->channels; ++ch) {
- pel.channel[ch] =
- ((255-value)*pel.channel[ch] + value * cl->channel[ch]) / 255;
- }
- i_ppix(im, tx+x+slot->bitmap_left, ty+y-slot->bitmap_top, &pel);
+ else {
+ /* grey scale or something we can treat as greyscale */
+ /* we create a map to convert from the bitmap values to 0-255 */
+ if (last_mode != slot->bitmap.pixel_mode
+ || last_grays != slot->bitmap.num_grays) {
+ if (!make_bmp_map(&slot->bitmap, map))
+ return 0;
+ last_mode = slot->bitmap.pixel_mode;
+ last_grays = slot->bitmap.num_grays;
+ }
+
+ bmp = slot->bitmap.buffer;
+ for (y = 0; y < slot->bitmap.rows; ++y) {
+ if (last_mode == ft_pixel_mode_grays &&
+ last_grays != 255) {
+ for (x = 0; x < slot->bitmap.width; ++x)
+ bmp[x] = map[bmp[x]];
}
- }
- bmp += slot->bitmap.pitch;
+ i_render_color(&render, tx + slot->bitmap_left, ty-slot->bitmap_top+y,
+ slot->bitmap.width, bmp, cl);
+ bmp += slot->bitmap.pitch;
+ }
}
}
ty -= slot->advance.y / 64;
}
+ if (aa)
+ i_render_done(&render);
+
return 1;
}
}
int
-i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, long *coords) {
+i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, const long *coords) {
#ifdef IM_FT2_MM
int i;
FT_Long ftcoords[T1_MAX_MM_AXIS];