summaryrefslogtreecommitdiff
path: root/atari/plot/font_freetype.c
diff options
context:
space:
mode:
Diffstat (limited to 'atari/plot/font_freetype.c')
-rwxr-xr-xatari/plot/font_freetype.c211
1 files changed, 109 insertions, 102 deletions
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 <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