Fix provided by Michale Drake.

Fix freetype nsfont_position_in_string to return nearest, rather than
next.
This commit is contained in:
Ole Loots 2012-08-04 02:51:46 +02:00
parent 2694a98f81
commit e454cf3f9c

View File

@ -20,16 +20,16 @@
#ifdef WITH_FREETYPE_FONT_DRIVER
#include <ft2build.h>
#include FT_CACHE_H
#include "desktop/options.h"
#include "atari/plot/plot.h"
#include "atari/plot/font_freetype.h"
#define DEJAVU_PATH "/usr/share/fonts/truetype/ttf-dejavu/"
extern unsigned long atari_plot_flags;
extern int atari_plot_vdi_handle;
extern unsigned long atari_plot_flags;
extern int atari_plot_vdi_handle;
static FT_Library library;
static FTC_Manager ft_cmanager;
@ -56,19 +56,19 @@ static int pixel_pos( FONT_PLOTTER self, const plot_font_style_t *fstyle,
size_t *char_offset, int *actual_x );
static int text( FONT_PLOTTER self, int x, int y, const char *text,
size_t length, const plot_font_style_t *fstyle );
static void draw_glyph8(FONT_PLOTTER self, GRECT *clip, GRECT * loc,
uint8_t * pixdata, int pitch, uint32_t colour);
static void draw_glyph1(FONT_PLOTTER self, GRECT * clip, GRECT * loc,
uint8_t * pixdata, int pitch, uint32_t colour);
static ftc_faceid_t *font_faces[FONT_FACE_COUNT];
static void draw_glyph8(FONT_PLOTTER self, GRECT *clip, GRECT * loc,
uint8_t * pixdata, int pitch, uint32_t colour);
static void draw_glyph1(FONT_PLOTTER self, GRECT * clip, GRECT * loc,
uint8_t * pixdata, int pitch, uint32_t colour);
static ftc_faceid_t *font_faces[FONT_FACE_COUNT];
static MFDB tmp;
static int tmp_mfdb_size;
static int tmp_mfdb_size;
static bool init = false;
static struct bitmap * fontbmp;
static size_t fontbmp_stride;
static int fontbmp_allocated_height;
static size_t fontbmp_stride;
static int fontbmp_allocated_height;
static int fontbmp_allocated_width;
@ -164,7 +164,7 @@ static void ft_fill_scalar(const plot_font_style_t *fstyle, FTC_Scaler srec)
}
srec->face_id = (FTC_FaceID)font_faces[selected_face];
srec->width = srec->height = (fstyle->size * 64) / FONT_SIZE_SCALE;
srec->width = srec->height = (fstyle->size * 64) / FONT_SIZE_SCALE;
srec->pixel = 0;
srec->x_res = srec->y_res = 72;
}
@ -358,6 +358,7 @@ static int pixel_pos( FONT_PLOTTER self, const plot_font_style_t *fstyle,
uint32_t ucs4;
size_t nxtchr = 0;
FT_Glyph glyph;
int prev_x = 0;
*actual_x = 0;
while (nxtchr < length) {
@ -368,24 +369,30 @@ static int pixel_pos( FONT_PLOTTER self, const plot_font_style_t *fstyle,
*actual_x += glyph->advance.x >> 16;
if (*actual_x > x)
break;
prev_x = *actual_x;
nxtchr = utf8_next(string, length, nxtchr);
}
*char_offset = nxtchr;
/* choose nearest of previous and last x */
if (abs(*actual_x - x) > abs(prev_x - x))
*actual_x = prev_x;
*char_offset = nxtchr;
return ( 1 );
}
static void draw_glyph8(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t * pixdata, int pitch, uint32_t colour)
{
uint32_t * linebuf;
uint32_t fontpix;
int xloop,yloop,xoff,yoff;
int x,y,w,h;
int x,y,w,h;
x = loc->g_x;
y = loc->g_y;
w = loc->g_w;
h = loc->g_h;
h = loc->g_h;
if( !rc_intersect( clip, loc ) ){
return;
@ -393,17 +400,17 @@ static void draw_glyph8(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t *
xoff = loc->g_x - x;
yoff = loc->g_y - y;
assert( loc->g_h <= h );
assert( loc->g_w <= w );
assert( loc->g_h <= h );
assert( loc->g_w <= w );
h = loc->g_h;
w = loc->g_w;
assert( h <= fontbmp_allocated_height );
assert( w <= fontbmp_allocated_width );
assert( w <= fontbmp_allocated_width );
fontbmp->height = h;
fontbmp->height = h;
fontbmp->width = w;
for( yloop = 0; yloop < MIN(fontbmp_allocated_height, h); yloop++) {
linebuf = (uint32_t *)(fontbmp->pixdata + (fontbmp_stride * yloop));
@ -413,19 +420,19 @@ static void draw_glyph8(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t *
}
}
plot_blit_bitmap(fontbmp, loc->g_x, loc->g_y, 0, BITMAPF_MONOGLYPH);
}
static void draw_glyph1(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t * pixdata, int pitch, uint32_t colour)
{
}
static void draw_glyph1(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t * pixdata, int pitch, uint32_t colour)
{
int xloop,yloop,xoff,yoff;
int x,y,w,h;
uint8_t bitm;
const uint8_t *fntd;
int x,y,w,h;
uint8_t bitm;
const uint8_t *fntd;
x = loc->g_x;
y = loc->g_y;
w = loc->g_w;
h = loc->g_h;
h = loc->g_h;
if( !rc_intersect( clip, loc ) ){
return;
@ -438,45 +445,45 @@ static void draw_glyph1(FONT_PLOTTER self, GRECT * clip, GRECT * loc, uint8_t *
h = loc->g_h;
if (w > loc->g_w)
w = loc->g_w;
w = loc->g_w;
int stride = MFDB_STRIDE( w );
if( tmp.fd_addr == NULL || tmp_mfdb_size < MFDB_SIZE( 1, stride, h) ){
if( tmp.fd_addr == NULL || tmp_mfdb_size < MFDB_SIZE( 1, stride, h) ){
tmp_mfdb_size = init_mfdb( 1, w, h, MFDB_FLAG_STAND | MFDB_FLAG_ZEROMEM, &tmp );
} else {
void * buf = tmp.fd_addr;
int size = init_mfdb( 1, w, h, MFDB_FLAG_STAND | MFDB_FLAG_NOALLOC, &tmp );
tmp.fd_addr = buf;
memset( tmp.fd_addr, 0, size );
}
short * buf;
for( yloop = 0; yloop < h; yloop++) {
fntd = pixdata + (pitch * (yloop+yoff))+(xoff>>3);
buf = tmp.fd_addr;
}
short * buf;
for( yloop = 0; yloop < h; yloop++) {
fntd = pixdata + (pitch * (yloop+yoff))+(xoff>>3);
buf = tmp.fd_addr;
buf += (tmp.fd_wdwidth*yloop);
for ( xloop = 0, bitm = (1<<(7-(xoff%8))); xloop < w; xloop++, bitm=(bitm>>1) ) {
if( (*fntd & bitm) != 0 ){
for ( xloop = 0, bitm = (1<<(7-(xoff%8))); xloop < w; xloop++, bitm=(bitm>>1) ) {
if( (*fntd & bitm) != 0 ){
short whichbit = (1<<(15-(xloop%16)));
buf[xloop>>4] = ((buf[xloop>>4])|(whichbit));
}
if( bitm == 1 ) {
fntd++;
bitm = 128;
}
buf[xloop>>4] = ((buf[xloop>>4])|(whichbit));
}
if( bitm == 1 ) {
fntd++;
bitm = 128;
}
}
}
#ifdef WITH_8BPP_SUPPORT
if( app.nplanes > 8 ){
}
#ifdef WITH_8BPP_SUPPORT
if( app.nplanes > 8 ){
#endif
plot_blit_mfdb(loc, &tmp, OFFSET_CUSTOM_COLOR, PLOT_FLAG_TRANS );
#ifdef WITH_8BPP_SUPPORT
} else {
plot_blit_mfdb(loc, &tmp, colour, PLOT_FLAG_TRANS );
}
#endif
}
plot_blit_mfdb(loc, &tmp, OFFSET_CUSTOM_COLOR, PLOT_FLAG_TRANS );
#ifdef WITH_8BPP_SUPPORT
} else {
plot_blit_mfdb(loc, &tmp, colour, PLOT_FLAG_TRANS );
}
#endif
}
static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle )
{
@ -484,47 +491,47 @@ static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t leng
size_t nxtchr = 0;
FT_Glyph glyph;
FT_BitmapGlyph bglyph;
GRECT loc, clip;
uint32_t c = fstyle->foreground ;
GRECT loc, clip;
uint32_t c = fstyle->foreground ;
struct rect clipping;
/* in -> BGR */
/* out -> ARGB */
if( !(self->flags & FONTPLOT_FLAG_MONOGLYPH) ){
c = ABGR_TO_RGB(c);
} else {
#ifdef WITH_8BPP_SUPPORT
if( app.nplanes > 8 ){
/* in -> BGR */
/* out -> ARGB */
if( !(self->flags & FONTPLOT_FLAG_MONOGLYPH) ){
c = ABGR_TO_RGB(c);
} else {
#ifdef WITH_8BPP_SUPPORT
if( app.nplanes > 8 ){
#endif
unsigned short out[4];
rgb_to_vdi1000( (unsigned char*)&c, (unsigned short*)&out );
vs_color(atari_plot_vdi_handle, OFFSET_CUSTOM_COLOR, (unsigned short*)&out[0]);
#ifdef WITH_8BPP_SUPPORT
} else {
c = RGB_TO_VDI(c);
}
#endif
}
vs_color(atari_plot_vdi_handle, OFFSET_CUSTOM_COLOR, (unsigned short*)&out[0]);
#ifdef WITH_8BPP_SUPPORT
} else {
c = RGB_TO_VDI(c);
}
#endif
}
plot_get_clip(&clipping);
clip.g_x = clipping.x0;
clip.g_y = clipping.y0;
clip.g_w = (clipping.x1 - clipping.x0)+1;
clip.g_h = (clipping.y1 - clipping.y0)+1;
clip.g_h = (clipping.y1 - clipping.y0)+1;
fontbmp = bitmap_realloc( clip.g_w, clip.g_h,
4, clip.g_w << 2,
BITMAP_GROW, fontbmp );
fontbmp_stride = bitmap_get_rowstride(fontbmp);
fontbmp_allocated_height = clip.g_h;
fontbmp_allocated_width = clip.g_w;
BITMAP_GROW, fontbmp );
fontbmp_stride = bitmap_get_rowstride(fontbmp);
fontbmp_allocated_height = clip.g_h;
fontbmp_allocated_width = clip.g_w;
while (nxtchr < length) {
ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr);
nxtchr = utf8_next(text, length, nxtchr);
glyph = ft_getglyph(fstyle, ucs4);
if (glyph == NULL){
continue;
continue;
}
if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
@ -532,8 +539,8 @@ static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t leng
loc.g_x = x + bglyph->left;
loc.g_y = y - bglyph->top;
loc.g_w = bglyph->bitmap.width;
loc.g_h = bglyph->bitmap.rows;
loc.g_h = bglyph->bitmap.rows;
if( loc.g_w > 0) {
self->draw_glyph( self,
&clip, &loc,
@ -546,7 +553,7 @@ static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t leng
x += glyph->advance.x >> 16;
}
return( 0 );
}
}
int ctor_font_plotter_freetype( FONT_PLOTTER self )
@ -555,17 +562,17 @@ int ctor_font_plotter_freetype( FONT_PLOTTER self )
self->str_width = str_width;
self->str_split = str_split;
self->pixel_pos = pixel_pos;
self->text = text;
/* set the default render mode */
if( (self->flags & FONTPLOT_FLAG_MONOGLYPH) != 0 ){
ft_load_type = FT_LOAD_MONOCHROME;
self->draw_glyph = draw_glyph1;
}
else{
ft_load_type = 0;
self->draw_glyph = draw_glyph8;
}
self->text = text;
/* set the default render mode */
if( (self->flags & FONTPLOT_FLAG_MONOGLYPH) != 0 ){
ft_load_type = FT_LOAD_MONOCHROME;
self->draw_glyph = draw_glyph1;
}
else{
ft_load_type = 0;
self->draw_glyph = draw_glyph8;
}
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
if( !init ) {
@ -583,12 +590,12 @@ static int dtor( FONT_PLOTTER self )
ft_font_finalise();
if( fontbmp != NULL ) {
bitmap_destroy( fontbmp );
fontbmp = NULL;
fontbmp = NULL;
}
if( tmp.fd_addr != NULL ){
free( tmp.fd_addr );
}
return( 1 );
}
#endif
}
#endif