/*
FONTS.C - Display fonts

This program was used to produce the font displays in the Window Server
Reference manual.
*/

#include <plib.h>
#include <wlib.h>

#define MINX 2
#define MINY 2
#define WIDTH 160

LOCAL_D INT FontID;
LOCAL_D INT CurrentY,CurrentX;
LOCAL_D G_FONT_INFO FontInfo;

LOCAL_C VOID DrawSideLines(INT y1,INT dy)
    {
    gDrawLine(0,y1,0,y1+dy+1);
    gDrawLine(WIDTH-1,y1,WIDTH-1,y1+dy+1);
    }

LOCAL_C VOID PrintHexNumber(INT x,INT y,UINT n)
    {
    TEXT buf[5];

    gPrintText(x,y,&buf[0],p_gtob(&buf[0],n,16));
    }

LOCAL_C VOID CDECL PrintLine(INT style,INT final,TEXT *fmt,...)
    {
    INT height,ascent,len;
    P_RECT box;
    G_GC gc;
    TEXT b[80];

    height=FontInfo.height;
    ascent=FontInfo.ascent;
    if (style&G_STY_DOUBLE)
        {
        height<<=1;
        ascent<<=1;
        }
    if (CurrentX==MINX)
        DrawSideLines(CurrentY,height+1);
    gc.font=FontID;
    gc.style=style;
    gSetGC(0,G_GC_MASK_FONT|G_GC_MASK_STYLE,&gc);
    len=p_atob(&b[0],fmt,&fmt+1);
    box.tl.x=CurrentX;
    box.br.x=WIDTH-MINX;
    box.tl.y=CurrentY;
    box.br.y=box.tl.y+height;
    if (box.br.x>box.tl.x)
        gPrintBoxText(&box,ascent,G_TEXT_ALIGN_LEFT,0,&b[0],len);
    if (final)
        {
        CurrentY+=height+1;
        CurrentX=MINX;
        }
    else 
        CurrentX+=gTextWidth(FontID,style,&b[0],len);
    }

LOCAL_C VOID SaveFontCodes(VOID)
    {
    INT x,y,dx,dy,xo,yo,yy;
    INT bitmap;
    W_OPEN_BIT_SEG bit;
    G_GC gc;
    P_RECT rect;
    TEXT name[32];

    dx=18;
    dy=FontInfo.height+1;
    xo=FontInfo.numeric_width+(MINX+5);
    yo=FontInfo.ascent+(MINY+3);
    bit.size.x=dx*16+xo+MINX;
    bit.size.y=dy*16+yo+MINY;
    bitmap=gCreateBit(0,&bit);
    gCreateTempGC0(bitmap);
    gc.font=FontID;
    gSetGC(0,G_GC_MASK_FONT,&gc);
    rect.tl.x=rect.tl.y=0;
    rect.br=bit.size;
    gClrRect(&rect,G_TRMODE_CLR);
    gDrawBox(&rect);
    rect.tl.x=xo-2;
    rect.tl.y=yo-2;
    gDrawBox(&rect);
    for (x=0;x<16;x++)
        PrintHexNumber(x*dx+xo,FontInfo.ascent+1,x);
    name[0]=0;
    for (y=0;y<16;y++)
        {
        PrintHexNumber(3,yy=y*dy+yo+FontInfo.ascent,y);
        for (x=0;x<16;x++)
            {
            gPrintText(x*dx+xo,yy,&name[0],1);
            name[0]++;
            }
        }
    gFreeTempGC();
    p_atos(&name[0],"rem::fcode%d.pic",FontID-WS_FONT_BASE);
    gSaveBit(&name[0],bitmap);
    wFree(bitmap);
    }

LOCAL_C VOID DrawFontStyles(VOID)
    {
    P_RECT rect;

    CurrentY=MINY;
    CurrentX=MINX;
    rect.tl.x=rect.tl.y=0;
    rect.br.x=WIDTH;
    rect.br.y=1000;
    gClrRect(&rect,G_TRMODE_CLR);
    gDrawLine(0,0,WIDTH,0);
    DrawSideLines(0,MINY);
    PrintLine(G_STY_NORMAL,FALSE,"Normal text (%d)  ",FontInfo.height);
    PrintLine(G_STY_BOLD,TRUE,"Bold text");
    PrintLine(G_STY_ITALIC,FALSE,"Italic text  ");
    PrintLine(G_STY_MONO,TRUE,"Mono text");
    PrintLine(G_STY_DOUBLE,FALSE,"Double height  ");
    PrintLine(G_STY_DOUBLE|G_STY_BOLD,TRUE,"Double bold");
    gDrawLine(0,CurrentY,WIDTH,CurrentY);
    }

LOCAL_C VOID SaveFontStyles(VOID)
    {
    INT bitmap;
    W_OPEN_BIT_SEG bit;
    TEXT name[32];

    bit.size.x=WIDTH;
    bit.size.y=CurrentY+1;
    bitmap=gCreateBit(0,&bit);
    gCreateTempGC0(bitmap);
    DrawFontStyles();
    gFreeTempGC();
    p_atos(&name[0],"rem::font%d.pic",FontID-WS_FONT_BASE);
    gSaveBit(&name[0],bitmap);
    wFree(bitmap);
    }

LOCAL_C VOID SetFont(INT fid)
    {
    gFontInfo(FontID=fid,0,&FontInfo);
    }

LOCAL_C VOID HandleKeyPress(INT code)
    {
    INT i;

    if (code=='\r')
        p_exit(0);
    if ('0'<=code && code<'6')
        {
        SetFont(code-'0'+WS_FONT_BASE);
        DrawFontStyles();
        }
    if (code=='s')
        {
        wSetBusyMsg("Saving",W_CORNER_TOP_LEFT);
        SaveFontStyles();
        wCancelBusyMsg();
        wInfoMsg("Styles bitmap saved");
        }
    if (code=='a')
        {
        wSetBusyMsg("Saving",W_CORNER_TOP_LEFT);
        for (i=0;i<6;i++)
            {
            SetFont(i+WS_FONT_BASE);
            DrawFontStyles();
            SaveFontStyles();
            }
        wCancelBusyMsg();
        wInfoMsg("Bitmaps saved");
        }
    if (code=='c')
        {
        wSetBusyMsg("Saving",W_CORNER_TOP_LEFT);
        SaveFontCodes();
        wCancelBusyMsg();
        wInfoMsg("Codes bitmap saved");
        }
    if (code=='z')
        {
        wSetBusyMsg("Saving",W_CORNER_TOP_LEFT);
        for (i=0;i<6;i++)
            {
            SetFont(i+WS_FONT_BASE);
            SaveFontCodes();
            }
        wCancelBusyMsg();
        wInfoMsg("Bitmaps saved");
        }
    }

GLDEF_C INT main(VOID)
    {
    WS_EV event;

    wStartup();
    SetFont(WS_FONT_BASE);
    DrawFontStyles();
    for (;;)
        {
        wGetEventWait(&event);
        if (event.type==WM_KEY)
            HandleKeyPress(event.p.key.keycode);
        }
    return(0);
    }
