astext - demonstrates antialiased texturized text rendering libAfterImage/tutorials/ASText
Contents
Description
On this step we have 2 images ready for us - background and texturized text. At this point we need to
merge them together by alpha-blending text over background (remember - text is alpha-channel of
foreground texture). At the same time we would like to add some nice bevel border around entire image. To
accomplish that task all we have to do is setup ASImageLayer structure for both background and
foreground, and apply merge_layers on them. When it is done - we no longer need original images and we
destroy them to free up some memory.
Example
ASImageLayer layers[2] ;
ASImageBevel bevel = {0, 0xFFDDDDDD, 0xFF555555,
0xFFFFFFFF, 0xFF777777, 0xFF444444,
BEVEL_HI_WIDTH, BEVEL_HI_WIDTH,
BEVEL_LO_WIDTH, BEVEL_LO_WIDTH,
BEVEL_HI_WIDTH, BEVEL_HI_WIDTH,
BEVEL_LO_WIDTH, BEVEL_LO_WIDTH } ;
memset( &(layers[0]), 0x00, sizeof(layers) );
layers[0].im = back_im ;
layers[0].clip_width = width ;
layers[0].clip_height = height ;
layers[0].merge_scanlines = alphablend_scanlines ;
layers[0].bevel = &bevel ;
layers[1].im = fore_im ;
layers[1].dst_x = TEXT_MARGIN ;
layers[1].dst_y = TEXT_MARGIN ;
layers[1].clip_width = fore_im->width ;
layers[1].clip_height = fore_im->height ;
layers[1].back_color = text_color ;
layers[1].merge_scanlines = alphablend_scanlines ;
rendered_im = merge_layers( asv, &(layers[0]), 2,
width+BEVEL_ADDON, height+BEVEL_ADDON,
ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
destroy_asimage( &fore_im );
destroy_asimage( &back_im );
Name
astext - demonstrates antialiased texturized text rendering libAfterImage/tutorials/ASText
Nameastext
Notes
We have to remember that outside bevel border will addup to the image size, hence we have to use
width+BEVEL_ADDON , height+BEVEL_ADDON as desired image size.
See Also
ASImageLayer, ASImageBevel, merge_layers()
3rd Berkeley Distribution AfterStep v.2.2.12 astext(3x)
Source
#include "../afterbase.h" #include "../afterimage.h" #include "common.h"
/* Usage: astext [-f font] [-s size] [-t text] [-S 3D_style]
[-c text_color] [-b background_color]
[-T foreground_texture] [-B background_image]
[-r foreground_resize_type] [-R background_resize_type]
*/
#define BEVEL_HI_WIDTH 20 #define BEVEL_LO_WIDTH 30 #define BEVEL_ADDON
(BEVEL_HI_WIDTH+BEVEL_LO_WIDTH)
void usage() {
printf( " Usage: astext [-h] [-f font] [-s size] [-t text] "
"[-S 3D_style] \n");
printf( " [-c text_color] [-b background_color]\n");
printf( " [-T foreground_texture] "
"[-B background_image]\n");
printf( " [-r foreground_resize_type] "
"[-R background_resize_type]\n");
printf( " [-m ]\n");
printf( " Where: font - TrueType font's filename or X font spec or "
"alias;\n");
printf( " size - size in points for TrueType fonts;\n");
printf( " text - text to be drawn;\n");
printf( " 3D_style - 3D style of text. "
"One of the following:\n");
printf( " 0 - plain 2D tetx, 1 - embossed, 2 - sunken, "
"3 - shade above,\n");
printf( " 4 - shade below, 5 - embossed thick, "
"6 - sunken thick.\n");
printf( " 7 - ouline above, 8 - ouline below, "
"9 - full ouline.\n");
printf( " resize_type - tells how texture/image should be "
"transformed to fit\n");
printf( " the text size. Could be: scale or tile."
"Default is tile\n");
printf( " -m make font monospaced. \n");
}
int main(int argc, char* argv[]) {
Display *dpy = NULL;
ASVisual *asv = NULL ;
int screen = 0, depth = 0;
char *font_name = "test.ttf";
int size = 32 ; #if 0
char *text = "ããè¿~没æ"; /* chinese */ #else
char *text = "Smart Brown Dog jumps\nOver The Lazy Fox,\n"
"and falls into the ditch."; #endif
ARGB32 text_color = ARGB32_White, back_color = ARGB32_Black;
char *text_color_name = "#FFFFFFFF", *back_color_name = "#FF000000";
char *fore_image_file = "fore.xpm" ;
char *back_image_file = "back.xpm" ;
Bool scale_fore_image = False, scale_back_image = False ;
ASImage *fore_im = NULL, *back_im = NULL;
ASImage *text_im = NULL ;
struct ASFontManager *fontman = NULL;
struct ASFont *font = NULL;
unsigned int width, height ;
int i ;
int text_margin = size/2 ;
Bool monospaced = False ;
char * font_path = NULL;
ASTextAttributes attr = {ASTA_VERSION_1, ASTA_UseTabStops,
AST_ShadeBelow, ASCT_UTF8, 8, 0,
NULL, 0, ARGB32_White };
/* see ASView.1 : */
set_application_name( argv[0] ); #if (HAVE_AFTERBASE_FLAG==1)
set_output_threshold(OUTPUT_LEVEL_DEBUG); #endif
if( argc == 1 )
usage();
else for( i = 1 ; i < argc ; i++ )
{
if( strncmp( argv[i], "-h", 2 ) == 0 )
{
usage();
return 0;
}
if( strncmp( argv[i], "-m", 2 ) == 0 )
{
monospaced = True ;
}else if( i+1 < argc )
{
if( strncmp( argv[i], "-f", 2 ) == 0 )
font_name = argv[i+1] ;
else if( strncmp( argv[i], "-s", 2 ) == 0 )
{
size = atoi(argv[i+1]);
text_margin = size/2 ;
}else if( strncmp( argv[i], "-t", 2 ) == 0 )
text = argv[i+1] ;
else if( strncmp( argv[i], "-S", 2 ) == 0 )
{
attr.type = atoi(argv[i+1]);
if( attr.type >= AST_3DTypes )
{
show_error( "3D type is wrong. "
"Using 2D Plain instead.");
attr.type = AST_Plain ;
}
}else if( strncmp( argv[i], "-c", 2 ) == 0 )
text_color_name = argv[i+1] ;
else if( strncmp( argv[i], "-b", 2 ) == 0 )
back_color_name = argv[i+1] ;
else if( strncmp( argv[i], "-T", 2 ) == 0 )
fore_image_file = argv[i+1] ;
else if( strncmp( argv[i], "-B", 2 ) == 0 )
back_image_file = argv[i+1] ;
else if( strncmp( argv[i], "-r", 2 ) == 0 )
scale_fore_image = (strcmp( argv[i+1], "scale") == 0);
else if( strncmp( argv[i], "-R", 2 ) == 0 )
scale_back_image = (strcmp( argv[i+1], "scale") == 0);
}
}
#ifndef X_DISPLAY_MISSING
dpy = XOpenDisplay(NULL);
_XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
screen = DefaultScreen(dpy);
depth = DefaultDepth( dpy, screen ); #endif
/* see ASText.1 : */
if( getenv("FONT_PATH") != NULL )
{
font_path = safemalloc( strlen(getenv("FONT_PATH"))+1+2+1);
sprintf( font_path, "%s:./", getenv("FONT_PATH") );
}
if( (fontman = create_font_manager( dpy, font_path, NULL )) != NULL )
font = get_asfont( fontman, font_name, 0, size,
ASF_GuessWho|(monospaced?ASF_Monospaced:0) );
if( font == NULL )
{
show_error( "unable to load requested font \"%s\". "
"Falling back to \"fixed\".", font_name );
font = get_asfont( fontman, "fixed", 0, size, ASF_GuessWho );
if( font == NULL )
{
show_error("font \"fixed\" is not available either. Aborting.");
return 1;
}
}
/*for( i = 0 ; i < 128 ; ++i )
print_asglyph( stderr, font, i); */
parse_argb_color( text_color_name, &text_color );
parse_argb_color( back_color_name, &back_color );
attr.fore_color = text_color ;
if( attr.type >= AST_OutlineAbove )
fore_image_file = NULL ;
/* see ASView.3 : */
asv = create_asvisual( dpy, screen, depth, NULL );
/* see ASText.2 : */
/*set_asfont_glyph_spacing( font, 10, 40 );*/
/*Simple way:get_text_size( text, font, attr.type, &width, &height ); */
/*Fancy way : */
get_fancy_text_size( text, font, &attr, &width, &height, 0, NULL ); /* show_progress( "extimated
text size = %dx%d", width, height ); */
if( fore_image_file )
{
ASImage *tmp = file2ASImage( fore_image_file, 0xFFFFFFFF,
SCREEN_GAMMA, 0, getenv("IMAGE_PATH"), NULL );
if( tmp )
{
if( tmp->width != width || tmp->height != height )
{ /* see ASScale.2 : */
if( scale_fore_image )
fore_im = scale_asimage( asv, tmp, width, height,
ASA_ASImage, 0,
ASIMAGE_QUALITY_DEFAULT );
else
fore_im = tile_asimage( asv, tmp, 0, 0,
width, height, 0,
ASA_ASImage, 0,
ASIMAGE_QUALITY_DEFAULT );
destroy_asimage( &tmp );
}else
fore_im = tmp ;
}else
fore_im = NULL ;
}
width += text_margin*2 + BEVEL_ADDON;
height += text_margin*2 + BEVEL_ADDON;
if( back_image_file )
{ /* see ASView.2 : */
ASImage *tmp = file2ASImage( back_image_file, 0xFFFFFFFF,
SCREEN_GAMMA, 0, getenv("IMAGE_PATH"), NULL );
if( tmp )
{
if( scale_back_image &&
(tmp->width != width || tmp->height != height) )
{ /* see ASScale.2 : */
back_im = scale_asimage( asv, tmp, width, height,
ASA_ASImage, 0,
ASIMAGE_QUALITY_DEFAULT );
destroy_asimage( &tmp );
}else
back_im = tmp ;
}else
back_im = NULL ;
}
/* see ASText.3 : */
/* simple way : text_im = draw_text( text, font, attr.type, 0 ); */
text_im = draw_fancy_text( text, font, &attr, 0, 0 );
if( fore_im )
{
move_asimage_channel( fore_im, IC_ALPHA, text_im, IC_ALPHA );
destroy_asimage( &text_im );
}else
fore_im = text_im ;
/* see ASText.1 : */
release_font( font );
destroy_font_manager( fontman, False );
if( fore_im )
{
ASImage *rendered_im ;
ASImageLayer layers[2] ;
ASImageBevel bevel = {0/*BEVEL_SOLID_INLINE*/, 0xFFDDDDDD,
0xFF555555, 0xFFFFFFFF,
0xFF777777, 0xFF222222,
BEVEL_HI_WIDTH, BEVEL_HI_WIDTH,
BEVEL_LO_WIDTH, BEVEL_LO_WIDTH,
BEVEL_HI_WIDTH, BEVEL_HI_WIDTH,
BEVEL_LO_WIDTH, BEVEL_LO_WIDTH } ;
/* see ASText.4 : */
init_image_layers( &(layers[0]), 2 );
if( back_im )
back_im->back_color = back_color ;
if( fore_im )
fore_im->back_color = text_color ;
layers[0].im = back_im ;
layers[0].dst_x = 0 ;
layers[0].dst_y = 0 ;
layers[0].clip_width = width ;
layers[0].clip_height = height ;
layers[0].bevel = &bevel ;
layers[1].im = fore_im ;
layers[1].dst_x = text_margin+BEVEL_HI_WIDTH*2 ;
layers[1].dst_y = text_margin+
MIN( (int)text_margin,
((int)font->max_height-
(int)font->max_ascend))/2+
BEVEL_HI_WIDTH*2;
if( fore_im )
{
layers[1].clip_width = fore_im->width ;
layers[1].clip_height = fore_im->height ;
}
rendered_im = merge_layers( asv, &(layers[0]), 2,
width+BEVEL_ADDON, height+BEVEL_ADDON, #ifndef X_DISPLAY_MISSING
ASA_XImage, #else
ASA_ASImage, #endif
0, ASIMAGE_QUALITY_DEFAULT);
destroy_asimage( &fore_im );
destroy_asimage( &back_im );
if( rendered_im )
{ #ifndef X_DISPLAY_MISSING
Window w;
/* see ASView.4 : */
w = create_top_level_window( asv, DefaultRootWindow(dpy),
32, 32,
width+BEVEL_ADDON,
height+BEVEL_ADDON,
1, 0, NULL,
"ASText", text );
if( w != None )
{
Pixmap p ;
XMapRaised (dpy, w);
/* see ASView.5 : */
p = asimage2pixmap( asv, DefaultRootWindow(dpy),
rendered_im, NULL, True );
destroy_asimage( &rendered_im );
/* see common.c: set_window_background_and_free() : */
p = set_window_background_and_free( w, p );
/* see common.c: wait_closedown() : */
}
wait_closedown(w);
dpy = NULL; #else
/* writing result into the file */
ASImage2file( rendered_im, NULL, "astext.jpg", ASIT_Jpeg,
NULL );
destroy_asimage( &rendered_im ); #endif
}
}
return 0 ; }
libAfterImage/tutorials/ASText.1 [7.1]
Synopsis
Step 4. Merging foreground and background with bevel.
