astext.html

Generated from astext.c with ROBODoc v3.2.3 on Fri Jul 13 13:35:02 2001

## libAfterImage/tutorials/ASText

NAME

     Tutorial 7: Text rendering.

SYNOPSIS

     libAfterImage application for rendering texturized text.

DESCRIPTION

     In this tutorial we will attempt to render arbitrary text in window,
     with optional texturized background and foreground. We shall also
     surround rendered text with beveled frame, creating an illusion of a
     button.

     New steps described in this tutorial are :
     ASText.1. Openning and closing fonts.
     ASText.2. Approximating rendered text size.
     ASText.3. Rendering texturized text.
     ASText.4. Merging foreground and background with bevel.

SEE ALSO

     Tutorial 1: ASView  - explanation of basic steps needed to use
                           libAfterImage and some other simple things.
     Tutorial 2: ASScale - image scaling basics.
     Tutorial 3: ASTile  - image tiling and tinting.
     Tutorial 4: ASMerge - scaling and blending of arbitrary number of
                           images.
     Tutorial 5: ASGrad  - drawing multipoint linear gradients.
     Tutorial 6: ASFlip  - image rotation.

SOURCE

        #include <X11/Xlib.h>
        #include <X11/Xutil.h>
        #include <X11/Xproto.h>
        #include <X11/Xatom.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 3
        #define BEVEL_LO_WIDTH 2
        #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( "  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( "         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");

        }

        int main(int argc, char* argv[])
        {
            Window w ;
            ASVisual *asv = NULL ;
            int screen, depth ;
            char *font_name = "test.ttf";
            int size = 32 ;
            char *text = "Smart Brown Dog jumps\n Over The Lazy Fox,\n and falls into the ditch.";
            ARGB32 text_color = ARGB32_White, back_color = ARGB32_Black;
            char *text_color_name = "#FFFFFFFF", *back_color_name = "#FF000000";
            char *fore_image_file = "fore.xpm", *back_image_file = "back.xpm" ;
            Bool scale_fore_image = False, scale_back_image = False ;
            ASImage *fore_im = NULL, *back_im = NULL;
            ASText3DType type_3d = AST_ShadeBelow ;
            struct ASFontManager *fontman = NULL;
            struct ASFont  *font = NULL;
            unsigned int width, height ;
            int i ;
            int text_margin = size/2 ;

            /* 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( 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 )
                    {
                        type_3d = atoi(argv[i+1]);
                        if( type_3d >= AST_3DTypes )
                        {
                            fprintf( stderr, "3D type is wrong. Using 2D Plain instead.\n");
                            type_3d = 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);
                }
            }

            dpy = XOpenDisplay(NULL);
            _XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
            screen = DefaultScreen(dpy);
            depth = DefaultDepth( dpy, screen );

            /* see ASText.1 : */
            if( (fontman = create_font_manager( dpy, NULL, NULL )) != NULL )
                font = get_asfont( fontman, font_name, 0, size, ASF_GuessWho );

            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;
                }
            }

            parse_argb_color( text_color_name, &text_color );
            parse_argb_color( back_color_name, &back_color );

            /* see ASView.3 : */
            asv = create_asvisual( dpy, screen, depth, NULL );

            /* see ASText.2 : */
            get_text_size( text, font, type_3d, &width, &height );
            if( fore_image_file )
            {
                ASImage *tmp = file2ASImage( fore_image_file, 0xFFFFFFFF,
                                             SCREEN_GAMMA, 0, 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 ;
                }
            }
            width  += text_margin*2 ;
            height += text_margin*2 ;
            if( back_image_file )
            { /* see ASView.2 : */
                ASImage *tmp = file2ASImage( back_image_file, 0xFFFFFFFF,
                                            SCREEN_GAMMA, 0, 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 ;
                }
            }
            /* see ASView.4 : */
            w = create_top_level_window( asv, DefaultRootWindow(dpy), 32, 32,
                                         width+BEVEL_ADDON, height+BEVEL_ADDON, 1, 0, NULL,
                                         "ASText" );
            if( w != None )
            {
                Pixmap p ;
                ASImage *text_im ;
                ASImage *rendered_im ;
                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 } ;

                XSelectInput (dpy, w, (StructureNotifyMask | ButtonPressMask|ButtonReleaseMask));
                XMapRaised   (dpy, w);

                /* see ASText.3 : */
                text_im = draw_text( text, font, type_3d, 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.4 : */
                memset( &(layers[0]), 0x00, sizeof(layers) );
                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].merge_scanlines = alphablend_scanlines ;
                layers[0].back_color = back_color ;
                layers[0].bevel = &bevel ;
                layers[1].im = fore_im ;
                layers[1].dst_x = text_margin+BEVEL_HI_WIDTH ;
                layers[1].dst_y = text_margin+MIN(text_margin,(font->max_height-font->max_ascend))/2+BEVEL_HI_WIDTH;
                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 );
                /* see ASView.5 : */
                p = asimage2pixmap( asv, DefaultRootWindow(dpy), rendered_im,
                                    NULL, True );
                /* see common.c: set_window_background_and_free() : */
                p = set_window_background_and_free( w, p );
            }
            /* see ASView.6 : */
            while(w != None)
            {
                XEvent event ;
                XNextEvent (dpy, &event);
                switch(event.type)
                {
                    case ButtonPress:
                        XDestroyWindow( dpy, w );
                        XFlush( dpy );
                        w = None ;
                        break ;
                    case ClientMessage:
                        if ((event.xclient.format == 32) &&
                            (event.xclient.data.l[0] == _XA_WM_DELETE_WINDOW))
                        {
                            XDestroyWindow( dpy, w );
                            XFlush( dpy );
                            w = None ;
                        }
                        break;
                }
            }
            /* see ASText.1 : */
            destroy_font( font );
            destroy_font_manager( fontman, False );
            if( dpy )
                XCloseDisplay (dpy);
            return 0 ;
        }

## libAfterImage/tutorials/ASText.1

SYNOPSIS

     Step 1. Openning and closing fonts.

DESCRIPTION

     Before any text can be rendered using libAfterImage - desired font
     has to be opened for use. Font opening process is two-step. At first
     we need to create font manager ( ASFontManager ). That is done once,
     and same font manger can be used throughout entire application. It
     contains information about used external libraries, hash of opened
     fonts, and some other info.

     When ASFontManager is created it could be used to obtain actuall fonts.
     get_asfont() call is used to query cahce of the ASFontManager, to see
     if the font has been loaded already, and if not - then it will load
     the font and prepare it for drawing.

EXAMPLE

         if( (fontman = create_font_manager( dpy, NULL, NULL )) != NULL )
             font = get_asfont( fontman, font_name, 0, size, ASF_GuessWho);
         if( font == NULL )
         {
             font = get_asfont( fontman, "fixed", 0, size, ASF_GuessWho );
             if( font == NULL )
             {
                 show_error( "font \"fixed\" is not available either. Aborting.");
                 return 1;
             }
         }
         ...
         destroy_font( font );
         destroy_font_manager( fontman, False );

SEE ALSO

     create_font_manager(), get_asfont(), destroy_font(),
     destroy_font_manager()

## libAfterImage/tutorials/ASText.2

SYNOPSIS

     Step 2. Approximating rendered text size.

DESCRIPTION

     Prior to actually drawing the text it is usefull to estimate the size
     of the image, that rendered text will occupy, So that window can be
     created of appropriate size, and othe interface elements laid out
     accordingly. get_text_size() could be used to obtain rendered text
     size without actually drawing it.

EXAMPLE

         get_text_size( text, font, type_3d, &width, &height );
         if( fore_image_file )
         {
             ASImage *tmp = file2ASImage( fore_image_file, 0xFFFFFFFF,
                                          SCREEN_GAMMA, 0, NULL );
             if( tmp )
             {
                 if( tmp->width != width || tmp->height != height )
                 {
                     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 ;
             }
         }

NOTES

     In this particular example we either tile or scale foreground texture
     to fit the text. In order to texturize the text  - we need to use
     rendered text as an alpha channel on texture image. That can easily
     be done only if both images are the same size.

SEE ALSO

     get_text_size(), scale_asimage(), tile_asimage(), ASText.3

## libAfterImage/tutorials/ASText.3

SYNOPSIS

     Step 3. Rendering texturized text.

DESCRIPTION

     The most effective text texturization technique provided by
     libAfterImage consists of substitution of the alpha channel of the
     texture, with rendered text. That is possible since all the text is
     rendered into alpha channel only. move_asimage_channel() call is used
     to accomplish this operation. This call actually removes channel
     data from the original image and stores it in destination image. If
     there was something in destination image's channel  already - it will
     be destroyed.
     All kinds of nifty things could be done using this call, actually.
     Like, for example, rendered text can be moved into green channel of
     the texture, creating funky effect.

EXAMPLE

         text_im = draw_text( text, font, 0 );
         if( fore_im )
         {
             move_asimage_channel( fore_im, IC_ALPHA, text_im, IC_ALPHA );
             destroy_asimage( &text_im );
         }else
             fore_im = text_im ;

NOTES

     move_asimage_channel() will only work if both images have exactly the
     same size. It will do nothing otherwise.

SEE ALSO

     draw_text(), move_asimage_channel()

## libAfterImage/tutorials/ASText.4

SYNOPSIS

     Step 4. Merging foreground and background with bevel.

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 (remeber - 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 );

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()