diff --git a/atari/plot/font_freetype.c b/atari/plot/font_freetype.c index 4717fdee9..8b526a743 100755 --- a/atari/plot/font_freetype.c +++ b/atari/plot/font_freetype.c @@ -20,16 +20,16 @@ #ifdef WITH_FREETYPE_FONT_DRIVER #include #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