1
0
Fork 0
forked from Miroirs/x49gp

Compare commits

...

3 commits

Author SHA1 Message Date
Gwenhael Le Moine
cadc26714e
prefix ui_ 2024-11-03 09:06:49 +01:00
Gwenhael Le Moine
c2d142281c
move fonts' functions into their own files 2024-11-03 09:01:21 +01:00
Gwenhael Le Moine
e28b228c09
write letter outside of button like x48ng/saturnng 2024-11-02 23:27:28 +01:00
11 changed files with 875 additions and 914 deletions

View file

@ -123,8 +123,9 @@ SRCS = ./src/x49gpng/main.c \
./src/x49gpng/s3c2410_arm.c \
./src/x49gpng/ui.c \
./src/x49gpng/timer.c \
./src/x49gpng/tiny_font.c \
./src/x49gpng/symbol.c \
./src/x49gpng/ui_tiny_font.c \
./src/x49gpng/ui_regular_font.c \
./src/x49gpng/ui_symbol.c \
./src/x49gpng/gdbstub.c \
./src/x49gpng/block.c \
./src/x49gpng/options.c

View file

@ -1,203 +0,0 @@
/* $Id: tiny_font.c,v 1.6 2008/12/11 12:18:17 ecd Exp $
*/
#include <stdlib.h>
#include "tiny_font.h"
#include "bitmaps/tiny_notdef.xbm"
#include "bitmaps/tiny_quotedbl.xbm"
#include "bitmaps/tiny_numbersign.xbm"
#include "bitmaps/tiny_ampersand.xbm"
#include "bitmaps/tiny_parenleft.xbm"
#include "bitmaps/tiny_parenright.xbm"
#include "bitmaps/tiny_comma.xbm"
#include "bitmaps/tiny_hyphen.xbm"
#include "bitmaps/tiny_period.xbm"
#include "bitmaps/tiny_slash.xbm"
#include "bitmaps/tiny_colon.xbm"
#include "bitmaps/tiny_less.xbm"
#include "bitmaps/tiny_equal.xbm"
#include "bitmaps/tiny_greater.xbm"
#include "bitmaps/tiny_bracketleft.xbm"
#include "bitmaps/tiny_bracketright.xbm"
#include "bitmaps/tiny_underscore.xbm"
#include "bitmaps/tiny_braceleft.xbm"
#include "bitmaps/tiny_braceright.xbm"
#include "bitmaps/tiny_guillemotleft.xbm"
#include "bitmaps/tiny_guillemotright.xbm"
#include "bitmaps/tiny_arrowleft.xbm"
#include "bitmaps/tiny_arrowright.xbm"
#include "bitmaps/tiny_large_comma.xbm"
#include "bitmaps/tiny_overscore.xbm"
#include "bitmaps/tiny_xsuperior.xbm"
#include "bitmaps/tiny_twosuperior.xbm"
#include "bitmaps/tiny_math_e.xbm"
#include "bitmaps/tiny_math_x.xbm"
#include "bitmaps/tiny_math_y.xbm"
#include "bitmaps/tiny_math_pi.xbm"
#include "bitmaps/tiny_math_summation.xbm"
#include "bitmaps/tiny_math_radical.xbm"
#include "bitmaps/tiny_math_partialdiff.xbm"
#include "bitmaps/tiny_math_integral.xbm"
#include "bitmaps/tiny_math_infinity.xbm"
#include "bitmaps/tiny_math_numbersign.xbm"
#include "bitmaps/tiny_math_less.xbm"
#include "bitmaps/tiny_math_greater.xbm"
#include "bitmaps/tiny_math_lessequal.xbm"
#include "bitmaps/tiny_math_greaterequal.xbm"
#include "bitmaps/tiny_math_equal.xbm"
#include "bitmaps/tiny_math_notequal.xbm"
#include "bitmaps/tiny_math_arrowleft.xbm"
#include "bitmaps/tiny_math_arrowright.xbm"
#include "bitmaps/tiny_math_downarrowleft.xbm"
#include "bitmaps/tiny_math_downarrowright.xbm"
#include "bitmaps/tiny_zero.xbm"
#include "bitmaps/tiny_one.xbm"
#include "bitmaps/tiny_two.xbm"
#include "bitmaps/tiny_three.xbm"
#include "bitmaps/tiny_A.xbm"
#include "bitmaps/tiny_B.xbm"
#include "bitmaps/tiny_C.xbm"
#include "bitmaps/tiny_D.xbm"
#include "bitmaps/tiny_E.xbm"
#include "bitmaps/tiny_F.xbm"
#include "bitmaps/tiny_G.xbm"
#include "bitmaps/tiny_H.xbm"
#include "bitmaps/tiny_I.xbm"
#include "bitmaps/tiny_J.xbm"
#include "bitmaps/tiny_K.xbm"
#include "bitmaps/tiny_L.xbm"
#include "bitmaps/tiny_M.xbm"
#include "bitmaps/tiny_N.xbm"
#include "bitmaps/tiny_O.xbm"
#include "bitmaps/tiny_P.xbm"
#include "bitmaps/tiny_Q.xbm"
#include "bitmaps/tiny_R.xbm"
#include "bitmaps/tiny_S.xbm"
#include "bitmaps/tiny_T.xbm"
#include "bitmaps/tiny_U.xbm"
#include "bitmaps/tiny_V.xbm"
#include "bitmaps/tiny_W.xbm"
#include "bitmaps/tiny_X.xbm"
#include "bitmaps/tiny_Y.xbm"
#include "bitmaps/tiny_Z.xbm"
#include "bitmaps/tiny__i.xbm"
const tiny_font_t tiny_font = {
7,
-3,
{ GLYPH( tiny, notdef ),
SPACE( "space", 4, 0 ),
GLYPH( tiny, quotedbl ),
GLYPH( tiny, numbersign ),
GLYPH( tiny, ampersand ),
GLYPH( tiny, parenleft ),
GLYPH( tiny, parenright ),
GLYPH( tiny, comma ),
GLYPH( tiny, hyphen ),
GLYPH( tiny, period ),
GLYPH( tiny, slash ),
GLYPH( tiny, zero ),
GLYPH( tiny, one ),
GLYPH( tiny, two ),
GLYPH( tiny, three ),
GLYPH( tiny, colon ),
GLYPH( tiny, less ),
GLYPH( tiny, equal ),
GLYPH( tiny, greater ),
GLYPH( tiny, A ),
GLYPH( tiny, B ),
GLYPH( tiny, C ),
GLYPH( tiny, D ),
GLYPH( tiny, E ),
GLYPH( tiny, F ),
GLYPH( tiny, G ),
GLYPH( tiny, H ),
GLYPH( tiny, I ),
GLYPH( tiny, J ),
GLYPH( tiny, K ),
GLYPH( tiny, L ),
GLYPH( tiny, M ),
GLYPH( tiny, N ),
GLYPH( tiny, O ),
GLYPH( tiny, P ),
GLYPH( tiny, Q ),
GLYPH( tiny, R ),
GLYPH( tiny, S ),
GLYPH( tiny, T ),
GLYPH( tiny, U ),
GLYPH( tiny, V ),
GLYPH( tiny, W ),
GLYPH( tiny, X ),
GLYPH( tiny, Y ),
GLYPH( tiny, Z ),
GLYPH( tiny, bracketleft ),
GLYPH( tiny, bracketright ),
GLYPH( tiny, underscore ),
GLYPH( tiny, i ),
GLYPH( tiny, overscore ),
GLYPH( tiny, arrowleft ),
GLYPH( tiny, arrowright ),
GLYPH( tiny, guillemotleft ),
GLYPH( tiny, guillemotright ),
GLYPH( tiny, braceleft ),
GLYPH( tiny, braceright ),
GLYPH( tiny, large_comma ),
GLYPH( tiny, xsuperior ),
GLYPH( tiny, twosuperior ),
GLYPH( tiny, math_e ),
GLYPH( tiny, math_x ),
GLYPH( tiny, math_y ),
GLYPH( tiny, math_pi ),
GLYPH( tiny, math_summation ),
GLYPH( tiny, math_radical ),
GLYPH( tiny, math_partialdiff ),
GLYPH( tiny, math_integral ),
GLYPH( tiny, math_infinity ),
GLYPH( tiny, math_numbersign ),
GLYPH( tiny, math_less ),
GLYPH( tiny, math_greater ),
GLYPH( tiny, math_lessequal ),
GLYPH( tiny, math_greaterequal ),
GLYPH( tiny, math_equal ),
GLYPH( tiny, math_notequal ),
GLYPH( tiny, math_arrowleft ),
GLYPH( tiny, math_arrowright ),
GLYPH( tiny, math_downarrowleft ),
GLYPH( tiny, math_downarrowright ),
SPACE( "kern-1", -1, -1 ),
SPACE( "kern-2", -2, -2 ),
SPACE( "kern-3", -3, -3 ),
SPACE( "kern-4", -4, -4 ),
SPACE( "kern-5", -5, -5 ),
SPACE( "kern-6", -6, -6 ),
SPACE( "kern-7", -7, -7 ),
{ NULL } }
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,310 @@
#include <stdbool.h>
#include <stddef.h>
#include <gdk/gdk.h>
#include <cairo.h>
#include "options.h"
#include "ui_symbol.h"
#include "ui_glyphname.h"
#include "ui_regular_font.h"
static void _regular_font_symbol_path( cairo_t* cr, double size, double xoffset, double yoffset, const x49gp_symbol_t* symbol )
{
const symbol_path_t* path;
const cairo_path_data_t* data;
path = symbol->path;
if ( NULL == path )
return;
cairo_move_to( cr, xoffset, yoffset );
for ( int i = 0; i < path->num_data; i += path->data[ i ].header.length ) {
data = &path->data[ i ];
switch ( data->header.type ) {
case CAIRO_PATH_MOVE_TO:
cairo_rel_move_to( cr, size * data[ 1 ].point.x, -size * data[ 1 ].point.y );
break;
case CAIRO_PATH_LINE_TO:
cairo_rel_line_to( cr, size * data[ 1 ].point.x, -size * data[ 1 ].point.y );
break;
case CAIRO_PATH_CURVE_TO:
cairo_rel_curve_to( cr, size * data[ 1 ].point.x, -size * data[ 1 ].point.y, size * data[ 2 ].point.x,
-size * data[ 2 ].point.y, size * data[ 3 ].point.x, -size * data[ 3 ].point.y );
break;
case CAIRO_PATH_CLOSE_PATH:
cairo_close_path( cr );
break;
}
}
}
static bool _regular_font_lookup_glyph( const char* name, int namelen, gunichar* glyph )
{
for ( int i = 0; i < NR_GLYPHNAMES; i++ ) {
if ( ( strlen( x49gp_glyphs[ i ].name ) == namelen ) && !strncmp( x49gp_glyphs[ i ].name, name, namelen ) ) {
if ( glyph )
*glyph = x49gp_glyphs[ i ].unichar;
return true;
}
}
return false;
}
static int _regular_font_text_strlen( const char* text )
{
const char *p, *q;
char c;
int namelen;
int n = 0;
p = text;
while ( ( c = *p++ ) ) {
if ( c != '\\' ) {
n++;
continue;
}
q = p;
while ( *q ) {
if ( ( *q == '\\' ) || ( *q == ' ' ) )
break;
q++;
}
if ( q == p ) {
n++;
p++;
continue;
}
namelen = q - p;
if ( *q == ' ' )
q++;
if ( symbol_lookup_glyph_by_name( p, namelen, NULL ) ) {
p = q;
n++;
continue;
}
if ( _regular_font_lookup_glyph( p, namelen, NULL ) ) {
p = q;
n++;
continue;
}
/*
* Insert symbol .notdef here...
*/
p = q;
n++;
}
return n;
}
static int _regular_font_text_to_ucs4( const char* text, gunichar** ucs4p )
{
const char *p, *q;
gunichar glyph;
gunichar* ucs4;
char c;
int namelen;
int i = 0;
int n = _regular_font_text_strlen( text );
if ( n <= 0 )
return n;
ucs4 = malloc( n * sizeof( gunichar ) );
p = text;
while ( ( c = *p++ ) ) {
if ( i == n ) {
free( ucs4 );
return -1;
}
if ( c != '\\' ) {
ucs4[ i++ ] = c;
continue;
}
q = p;
while ( *q ) {
if ( ( *q == '\\' ) || ( *q == ' ' ) )
break;
q++;
}
if ( q == p ) {
ucs4[ i++ ] = *p++;
continue;
}
namelen = q - p;
if ( *q == ' ' )
q++;
if ( symbol_lookup_glyph_by_name( p, namelen, &glyph ) ) {
ucs4[ i++ ] = glyph;
p = q;
continue;
}
if ( _regular_font_lookup_glyph( p, namelen, &glyph ) ) {
ucs4[ i++ ] = glyph;
p = q;
continue;
}
/*
* Insert symbol .notdef here...
*/
ucs4[ i++ ] = 0xe000;
p = q;
}
*ucs4p = ucs4;
return n;
}
static void _regular_font_vtext_path( cairo_t* cr, double size, double x, double y, va_list ap )
{
cairo_text_extents_t extents;
cairo_font_weight_t weight;
cairo_font_slant_t slant;
const x49gp_symbol_t* symbol;
const char* text;
gunichar* ucs4;
char out[ 8 ];
int bytes;
int len;
slant = va_arg( ap, cairo_font_slant_t );
weight = va_arg( ap, cairo_font_weight_t );
text = va_arg( ap, const char* );
cairo_select_font_face( cr, opt.font, slant, weight );
cairo_set_font_size( cr, size );
ucs4 = NULL;
len = _regular_font_text_to_ucs4( text, &ucs4 );
if ( len <= 0 )
return;
for ( int j = 0; j < len; j++ ) {
if ( g_unichar_type( ucs4[ j ] ) == G_UNICODE_PRIVATE_USE ) {
/*
* Draw Symbol, Increment x...
*/
symbol = symbol_get_by_glyph( ucs4[ j ] );
if ( NULL == symbol )
symbol = symbol_get_by_glyph( 0xe000 );
size *= symbol->prescale;
_regular_font_symbol_path( cr, size, x, y, symbol );
x += size * symbol->x_advance;
y -= size * symbol->y_advance;
size *= symbol->postscale;
if ( symbol->prescale * symbol->postscale != 1. )
cairo_set_font_size( cr, size );
continue;
}
bytes = g_unichar_to_utf8( ucs4[ j ], out );
out[ bytes ] = '\0';
cairo_text_extents( cr, out, &extents );
cairo_move_to( cr, x, y );
cairo_text_path( cr, out );
x += extents.x_advance;
y += extents.y_advance;
}
free( ucs4 );
}
void regular_font_measure_text( cairo_t* cr, double size, double* x_bearing, double* y_bearing, double* width, double* height,
double* ascent, double* descent, ... )
{
va_list ap0, ap1;
cairo_font_extents_t font_extents;
cairo_font_weight_t weight;
cairo_font_slant_t slant;
double x1, y1, x2, y2, a, d;
const char* text;
va_start( ap0, descent );
va_copy( ap1, ap0 );
_regular_font_vtext_path( cr, size, 0.0, 0.0, ap0 );
va_end( ap0 );
cairo_fill_extents( cr, &x1, &y1, &x2, &y2 );
if ( y2 < 0.0 )
y2 = 0.0;
a = 0.0;
d = 0.0;
slant = va_arg( ap1, cairo_font_slant_t );
weight = va_arg( ap1, cairo_font_weight_t );
text = va_arg( ap1, const char* );
( void )text;
cairo_select_font_face( cr, opt.font, slant, weight );
cairo_set_font_size( cr, size );
cairo_font_extents( cr, &font_extents );
/*
* Cairo seems to return overall height in ascent,
* so fix this by calculating ascent = height - descent.
*/
if ( font_extents.ascent - font_extents.descent > a )
a = font_extents.ascent - font_extents.descent;
if ( font_extents.descent > -d )
d = -font_extents.descent;
*x_bearing = x1;
*y_bearing = y2;
*width = x2 - x1;
*height = y2 - y1;
*ascent = a;
*descent = d;
va_end( ap1 );
}
void regular_font_draw_text( cairo_t* cr, GdkColor* color, double size, double line_width, int xoffset, int yoffset, ... )
{
va_list ap;
va_start( ap, yoffset );
cairo_set_line_width( cr, line_width );
cairo_set_source_rgb( cr, ( ( double )color->red ) / 65535.0, ( ( double )color->green ) / 65535.0,
( ( double )color->blue ) / 65535.0 );
_regular_font_vtext_path( cr, size, xoffset, yoffset, ap );
if ( line_width == 0.0 )
cairo_fill( cr );
else
cairo_stroke( cr );
va_end( ap );
}

View file

@ -0,0 +1,13 @@
/* $Id: bitmap_font.h,v 1.5 2008/12/11 12:18:17 ecd Exp $
*/
#ifndef _REGULAR_FONT_H
#define _REGULAR_FONT_H 1
#include <cairo.h>
void regular_font_measure_text( cairo_t* cr, double size, double* x_bearing, double* y_bearing, double* width, double* height,
double* ascent, double* descent, ... );
void regular_font_draw_text( cairo_t* cr, GdkColor* color, double size, double line_width, int xoffset, int yoffset, ... );
#endif /* !(_REGULAR_FONT_H) */

View file

@ -7,7 +7,7 @@
#include <glib.h>
#include <cairo.h>
#include "symbol.h"
#include "ui_symbol.h"
static const cairo_path_data_t symbol_square_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.100 ), SYMBOL_LINE_TO( 0.500, 0.000 ),
SYMBOL_LINE_TO( 0.000, 0.500 ), SYMBOL_LINE_TO( -0.500, 0.000 ),

519
src/x49gpng/ui_tiny_font.c Normal file
View file

@ -0,0 +1,519 @@
/* $Id: tiny_font.c,v 1.6 2008/12/11 12:18:17 ecd Exp $
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <gdk/gdk.h>
#include "ui_tiny_font.h"
#include "bitmaps/tiny_notdef.xbm"
#include "bitmaps/tiny_quotedbl.xbm"
#include "bitmaps/tiny_numbersign.xbm"
#include "bitmaps/tiny_ampersand.xbm"
#include "bitmaps/tiny_parenleft.xbm"
#include "bitmaps/tiny_parenright.xbm"
#include "bitmaps/tiny_comma.xbm"
#include "bitmaps/tiny_hyphen.xbm"
#include "bitmaps/tiny_period.xbm"
#include "bitmaps/tiny_slash.xbm"
#include "bitmaps/tiny_colon.xbm"
#include "bitmaps/tiny_less.xbm"
#include "bitmaps/tiny_equal.xbm"
#include "bitmaps/tiny_greater.xbm"
#include "bitmaps/tiny_bracketleft.xbm"
#include "bitmaps/tiny_bracketright.xbm"
#include "bitmaps/tiny_underscore.xbm"
#include "bitmaps/tiny_braceleft.xbm"
#include "bitmaps/tiny_braceright.xbm"
#include "bitmaps/tiny_guillemotleft.xbm"
#include "bitmaps/tiny_guillemotright.xbm"
#include "bitmaps/tiny_arrowleft.xbm"
#include "bitmaps/tiny_arrowright.xbm"
#include "bitmaps/tiny_large_comma.xbm"
#include "bitmaps/tiny_overscore.xbm"
#include "bitmaps/tiny_xsuperior.xbm"
#include "bitmaps/tiny_twosuperior.xbm"
#include "bitmaps/tiny_math_e.xbm"
#include "bitmaps/tiny_math_x.xbm"
#include "bitmaps/tiny_math_y.xbm"
#include "bitmaps/tiny_math_pi.xbm"
#include "bitmaps/tiny_math_summation.xbm"
#include "bitmaps/tiny_math_radical.xbm"
#include "bitmaps/tiny_math_partialdiff.xbm"
#include "bitmaps/tiny_math_integral.xbm"
#include "bitmaps/tiny_math_infinity.xbm"
#include "bitmaps/tiny_math_numbersign.xbm"
#include "bitmaps/tiny_math_less.xbm"
#include "bitmaps/tiny_math_greater.xbm"
#include "bitmaps/tiny_math_lessequal.xbm"
#include "bitmaps/tiny_math_greaterequal.xbm"
#include "bitmaps/tiny_math_equal.xbm"
#include "bitmaps/tiny_math_notequal.xbm"
#include "bitmaps/tiny_math_arrowleft.xbm"
#include "bitmaps/tiny_math_arrowright.xbm"
#include "bitmaps/tiny_math_downarrowleft.xbm"
#include "bitmaps/tiny_math_downarrowright.xbm"
#include "bitmaps/tiny_zero.xbm"
#include "bitmaps/tiny_one.xbm"
#include "bitmaps/tiny_two.xbm"
#include "bitmaps/tiny_three.xbm"
#include "bitmaps/tiny_A.xbm"
#include "bitmaps/tiny_B.xbm"
#include "bitmaps/tiny_C.xbm"
#include "bitmaps/tiny_D.xbm"
#include "bitmaps/tiny_E.xbm"
#include "bitmaps/tiny_F.xbm"
#include "bitmaps/tiny_G.xbm"
#include "bitmaps/tiny_H.xbm"
#include "bitmaps/tiny_I.xbm"
#include "bitmaps/tiny_J.xbm"
#include "bitmaps/tiny_K.xbm"
#include "bitmaps/tiny_L.xbm"
#include "bitmaps/tiny_M.xbm"
#include "bitmaps/tiny_N.xbm"
#include "bitmaps/tiny_O.xbm"
#include "bitmaps/tiny_P.xbm"
#include "bitmaps/tiny_Q.xbm"
#include "bitmaps/tiny_R.xbm"
#include "bitmaps/tiny_S.xbm"
#include "bitmaps/tiny_T.xbm"
#include "bitmaps/tiny_U.xbm"
#include "bitmaps/tiny_V.xbm"
#include "bitmaps/tiny_W.xbm"
#include "bitmaps/tiny_X.xbm"
#include "bitmaps/tiny_Y.xbm"
#include "bitmaps/tiny_Z.xbm"
#include "bitmaps/tiny__i.xbm"
const tiny_font_t tiny_font = {
7,
-3,
{ GLYPH( tiny, notdef ),
SPACE( "space", 4, 0 ),
GLYPH( tiny, quotedbl ),
GLYPH( tiny, numbersign ),
GLYPH( tiny, ampersand ),
GLYPH( tiny, parenleft ),
GLYPH( tiny, parenright ),
GLYPH( tiny, comma ),
GLYPH( tiny, hyphen ),
GLYPH( tiny, period ),
GLYPH( tiny, slash ),
GLYPH( tiny, zero ),
GLYPH( tiny, one ),
GLYPH( tiny, two ),
GLYPH( tiny, three ),
GLYPH( tiny, colon ),
GLYPH( tiny, less ),
GLYPH( tiny, equal ),
GLYPH( tiny, greater ),
GLYPH( tiny, A ),
GLYPH( tiny, B ),
GLYPH( tiny, C ),
GLYPH( tiny, D ),
GLYPH( tiny, E ),
GLYPH( tiny, F ),
GLYPH( tiny, G ),
GLYPH( tiny, H ),
GLYPH( tiny, I ),
GLYPH( tiny, J ),
GLYPH( tiny, K ),
GLYPH( tiny, L ),
GLYPH( tiny, M ),
GLYPH( tiny, N ),
GLYPH( tiny, O ),
GLYPH( tiny, P ),
GLYPH( tiny, Q ),
GLYPH( tiny, R ),
GLYPH( tiny, S ),
GLYPH( tiny, T ),
GLYPH( tiny, U ),
GLYPH( tiny, V ),
GLYPH( tiny, W ),
GLYPH( tiny, X ),
GLYPH( tiny, Y ),
GLYPH( tiny, Z ),
GLYPH( tiny, bracketleft ),
GLYPH( tiny, bracketright ),
GLYPH( tiny, underscore ),
GLYPH( tiny, i ),
GLYPH( tiny, overscore ),
GLYPH( tiny, arrowleft ),
GLYPH( tiny, arrowright ),
GLYPH( tiny, guillemotleft ),
GLYPH( tiny, guillemotright ),
GLYPH( tiny, braceleft ),
GLYPH( tiny, braceright ),
GLYPH( tiny, large_comma ),
GLYPH( tiny, xsuperior ),
GLYPH( tiny, twosuperior ),
GLYPH( tiny, math_e ),
GLYPH( tiny, math_x ),
GLYPH( tiny, math_y ),
GLYPH( tiny, math_pi ),
GLYPH( tiny, math_summation ),
GLYPH( tiny, math_radical ),
GLYPH( tiny, math_partialdiff ),
GLYPH( tiny, math_integral ),
GLYPH( tiny, math_infinity ),
GLYPH( tiny, math_numbersign ),
GLYPH( tiny, math_less ),
GLYPH( tiny, math_greater ),
GLYPH( tiny, math_lessequal ),
GLYPH( tiny, math_greaterequal ),
GLYPH( tiny, math_equal ),
GLYPH( tiny, math_notequal ),
GLYPH( tiny, math_arrowleft ),
GLYPH( tiny, math_arrowright ),
GLYPH( tiny, math_downarrowleft ),
GLYPH( tiny, math_downarrowright ),
SPACE( "kern-1", -1, -1 ),
SPACE( "kern-2", -2, -2 ),
SPACE( "kern-3", -3, -3 ),
SPACE( "kern-4", -4, -4 ),
SPACE( "kern-5", -5, -5 ),
SPACE( "kern-6", -6, -6 ),
SPACE( "kern-7", -7, -7 ),
{ NULL } }
};
static unsigned char _tiny_font_lookup_glyph( const char* name, int namelen )
{
for ( int i = 0; tiny_font.glyphs[ i ].name; i++ )
if ( ( strlen( tiny_font.glyphs[ i ].name ) == namelen ) && !strncmp( tiny_font.glyphs[ i ].name, name, namelen ) )
return i;
return 0;
}
static unsigned char _tiny_font_lookup_ascii( char c )
{
int namelen = 0;
char* name;
switch ( c ) {
case ' ':
name = "space";
break;
case '!':
name = "exclam";
break;
case '"':
name = "quotedbl";
break;
case '#':
name = "numbersign";
break;
case '$':
name = "dollar";
break;
case '%':
name = "percent";
break;
case '&':
name = "ampersand";
break;
case '(':
name = "parenleft";
break;
case ')':
name = "parenright";
break;
case '*':
name = "asterisk";
break;
case '+':
name = "plus";
break;
case ',':
name = "comma";
break;
case '-':
name = "hyphen";
break;
case '.':
name = "period";
break;
case '/':
name = "slash";
break;
case '0':
name = "zero";
break;
case '1':
name = "one";
break;
case '2':
name = "two";
break;
case '3':
name = "three";
break;
case '4':
name = "four";
break;
case '5':
name = "five";
break;
case '6':
name = "six";
break;
case '7':
name = "seven";
break;
case '8':
name = "eight";
break;
case '9':
name = "nine";
break;
case ':':
name = "colon";
break;
case ';':
name = "semicolon";
break;
case '<':
name = "less";
break;
case '=':
name = "equal";
break;
case '>':
name = "greater";
break;
case '?':
name = "question";
break;
case '@':
name = "at";
break;
case '[':
name = "bracketleft";
break;
case '\\':
name = "backslash";
break;
case ']':
name = "bracketright";
break;
case '^':
name = "asciicircum";
break;
case '_':
name = "underscore";
break;
case '`':
name = "quoteleft";
break;
case '{':
name = "braceleft";
break;
case '|':
name = "bar";
break;
case '}':
name = "braceright";
break;
case '~':
name = "asciitilde";
break;
default:
name = &c;
namelen = 1;
break;
}
if ( 0 == namelen )
namelen = strlen( name );
return _tiny_font_lookup_glyph( name, namelen );
}
static inline int _tiny_font_strlen( const char* text )
{
const char *p, *q;
char c;
int n = 0;
p = text;
while ( ( c = *p++ ) ) {
if ( c != '\\' ) {
n++;
continue;
}
q = p;
while ( *q ) {
if ( ( *q == '\\' ) || ( *q == ' ' ) )
break;
q++;
}
if ( q == p ) {
n++;
p++;
continue;
}
if ( *q == ' ' )
q++;
n++;
p = q;
}
return n;
}
static int _tiny_font_text_to_glyphs( const char* text, unsigned char** glyphp )
{
unsigned char* glyphs;
const char *p, *q;
unsigned char c;
int namelen;
int i, n;
n = _tiny_font_strlen( text );
if ( n <= 0 )
return n;
glyphs = malloc( n );
i = 0;
p = text;
while ( ( c = *p++ ) ) {
if ( i == n ) {
free( glyphs );
return -1;
}
if ( c != '\\' ) {
glyphs[ i++ ] = _tiny_font_lookup_ascii( c );
continue;
}
q = p;
while ( *q ) {
if ( ( *q == '\\' ) || ( *q == ' ' ) )
break;
q++;
}
if ( q == p ) {
glyphs[ i++ ] = _tiny_font_lookup_ascii( *p++ );
continue;
}
namelen = q - p;
if ( *q == ' ' )
q++;
glyphs[ i++ ] = _tiny_font_lookup_glyph( p, namelen );
p = q;
}
*glyphp = glyphs;
return n;
}
void tiny_font_measure_text( const char* text, int* width, int* height, int* ascent, int* descent )
{
const tiny_glyph_t* glyph;
unsigned char* glyphs;
int n, w, a, d;
w = 0;
a = 0;
d = 0;
n = _tiny_font_text_to_glyphs( text, &glyphs );
for ( int i = 0; i < n; i++ ) {
glyph = &tiny_font.glyphs[ glyphs[ i ] ];
w += glyph->width;
if ( glyph->ascent > a )
a = glyph->ascent;
if ( glyph->descent < d )
d = glyph->descent;
}
*width = w - 1;
*height = tiny_font.ascent - tiny_font.descent;
*ascent = a;
*descent = d;
if ( n > 0 )
free( glyphs );
}
void tiny_font_draw_text( GdkDrawable* drawable, GdkColor* color, int x, int y, const char* text )
{
const tiny_glyph_t* glyph;
unsigned char* glyphs;
GdkBitmap* bitmap;
GdkGC* gc;
int n, w, h;
gc = gdk_gc_new( drawable );
gdk_gc_set_rgb_fg_color( gc, color );
n = _tiny_font_text_to_glyphs( text, &glyphs );
for ( int i = 0; i < n; i++ ) {
glyph = &tiny_font.glyphs[ glyphs[ i ] ];
w = glyph->width - glyph->kern;
h = glyph->ascent - glyph->descent;
if ( w <= 0 || h <= 0 ) {
x += glyph->width;
continue;
}
bitmap = gdk_bitmap_create_from_data( NULL, ( char* )glyph->bits, w, h );
gdk_gc_set_ts_origin( gc, x + glyph->kern, y + tiny_font.ascent - glyph->ascent );
gdk_gc_set_stipple( gc, bitmap );
gdk_gc_set_fill( gc, GDK_STIPPLED );
gdk_draw_rectangle( drawable, gc, true, x + glyph->kern, y + tiny_font.ascent - glyph->ascent, w, h );
g_object_unref( bitmap );
x += glyph->width;
}
g_object_unref( gc );
if ( n > 0 )
free( glyphs );
}

View file

@ -31,4 +31,7 @@ typedef struct {
extern const tiny_font_t tiny_font;
void tiny_font_measure_text( const char* text, int* width, int* height, int* ascent, int* descent );
void tiny_font_draw_text( GdkDrawable* drawable, GdkColor* color, int x, int y, const char* text );
#endif /* !(_X49GP_TINY_FONT_H) */

View file

@ -42,8 +42,6 @@ typedef enum {
UI_COLOR_MAX,
} x49gp_ui_color_t;
typedef enum { UI_LAYOUT_LEFT = 0, UI_LAYOUT_LEFT_NO_SPACE, UI_LAYOUT_BELOW, UI_LAYOUT_MAX } x49gp_ui_layout_t;
typedef enum {
UI_CALCULATOR_HP49GP = 0,
UI_CALCULATOR_HP49GP_NEWRPL,
@ -61,7 +59,6 @@ typedef struct {
double font_size;
cairo_font_weight_t font_weight;
double letter_size;
x49gp_ui_layout_t layout;
int x;
int y;
int width;