/* * Styled HTML text * ---------------- * This program allows you to create styled HTML, ready to paste * into an HTML document. It has a number of special effects, * producing colour grades along a line of text, normal HTML * effects such as centering, italics, bold, different font sizes, * colours and also a few different typefaces. * * This program shows a number of features. The window uses the * Floating attribute so that it floats above other windows. * The power of gettext and inserttext used with textboxes is * evident. The menubar is used to the full as well. */ #include #include #include /* Global variables */ window w; textbox txt = NULL; textbox htm = NULL; int min_height = 10; menuitem copy_item, clear_item; menuitem styles[Bold+Italic]; menuitem center; /* Typeface variables */ char * typeface_names[] = { "Normal", "Times", "Helvetica", "Wingdings", }; #define NUM_TYPEFACES (sizeof(typeface_names)/sizeof(typeface_names[0])) char * typeface_values[NUM_TYPEFACES] = { NULL, "Times", "Arial, Helvetica", "Wingdings, Zapf Wingdings, Symbol" }; char * typeface_fonts[NUM_TYPEFACES] = { "Times", "Times", "Helvetica", "Wingdings", }; menuitem typefaces[NUM_TYPEFACES]; int the_typeface = 0; font fonts[NUM_TYPEFACES][4]; /* Font sizes */ char * size_names [] = { "Default Size", "Big", "Small", "Heading 1", "Heading 2", "Heading 3", "Heading 4", }; #define NUM_SIZES (sizeof(size_names)/sizeof(size_names[0])) char * size_values [NUM_SIZES] = { NULL, "big", "small", "h1", "h2", "h3", "h4", }; menuitem sizes[NUM_SIZES]; int the_size = 0; /* Colour variables */ char * colour_names[] = { "Default", "Black", "Red", "Blue", "Purple", "Yellow", "Orange", "Green", "Grey", "Dark Red", "Dark Blue", "Dark Green", "Sky Blue", "Deep Blue", "Steel", }; #define NUM_COLOURS (sizeof(colour_names)/sizeof(colour_names[0])) rgb colour_values[NUM_COLOURS] = { Black, Black, Red, Blue, 0xCC33CC, 0xCCFF00, 0xFF6600, 0x009900, 0x666666, 0x990000, 0x000099, 0x006600, 0x0066FF, 0x3333CC, 0x336699, }; menuitem colours[NUM_COLOURS]; int the_colour = 0; /* Colour effects */ char * effect_styles[] = { "Solid Colour", "Repeating Effect", "Gradual Effect", }; #define SOLID 0 #define REPEATING 1 #define GRADUAL 2 #define NUM_FX_STYLES (sizeof(effect_styles)/sizeof(effect_styles[0])) menuitem fxstyles[NUM_FX_STYLES]; int fx_style = SOLID; char * effect_names[] = { "Rainbow", "Black -> Red", "Red -> Blue", "Red -> Green -> Blue -> Orange", "Blue -> Dark -> Green -> Sky", "Black -> Grey", "Blue -> Purple -> Red -> Blue", "Red -> Orange -> Yellow", "Green Leaves, Purple Flowers", "Dark Reds", "Dark Purples", "Dark Shades", "Blues", "Reds", }; #define NUM_EFFECTS (sizeof(effect_names)/sizeof(effect_names[0])) int effect_size [NUM_EFFECTS] = { 20, 10, 10, 17, 13, 7, 10, 10, 9, 8, 8, 6, 14, 14, }; rgb effect_def [NUM_EFFECTS][20] = { {Red, 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xCCFF00, 0x99CC00, 0x66CC00, 0x339900, 0x009900, 0x009933, 0x009966, 0x009999, 0x0099CC, 0x0066FF, 0x3333FF, 0x6600FF, 0x9900FF, 0xCC33CC, 0xFF3399, }, {Black, 0x330000, 0x660000, 0x990000, 0xCC0000, Red, 0xCC0000, 0x990000, 0x660000, 0x330000, }, {Red, 0xCC0033, 0x990066, 0x660099, 0x3300CC, Blue, 0x3300CC, 0x660099, 0x990066, 0xCC0033, }, {Red, 0xCC0000, 0x990000, 0x663300, 0x336600, 0x009900, 0x006633, 0x003366, 0x000099, 0x0000CC, Blue, 0x3300CC, 0x660099, 0x990066, 0xCC3333, 0xFF6600, 0xFF3300, }, {Blue, 0x0000CC, 0x000099, 0x000066, 0x003333, 0x006600, 0x009900, 0x009933, 0x009966, 0x009999, 0x0066CC, 0x0066FF, 0x0033FF, }, {Black, 0x333333, 0x666666, 0x999999, 0x999999, 0x666666, 0x333333, }, {Blue, 0x0000CC, 0x3333CC, 0x6633CC, 0x9933CC, 0xCC0099, 0xCC0066, 0x990099, 0x6600CC, 0x3300FF, }, {Red, 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, 0xFFCC00, 0xFF9900, 0xFF6600, 0xFF3300, }, {0x009900, 0x009900, 0x00AA00, 0x009900, 0x009900, 0xFF00FF, 0x009900, 0x00AA00, 0x009900, }, {0x990000, 0x880000, 0x770000, 0x660000, 0x660000, 0x770000, 0x880000, 0x990000, }, {0x990099, 0x880088, 0x770077, 0x660066, 0x660066, 0x770077, 0x880088, 0x990099, }, {0x000066, 0x006666, 0x006600, 0x666600, 0x660000, 0x660066, }, {0x000088, 0x000099, 0x0000AA, 0x0000BB, 0x0000CC, 0x0000DD, 0x0000EE, 0x0000FF, 0x0000EE, 0x0000DD, 0x0000CC, 0x0000BB, 0x0000AA, 0x000099, }, {0x880000, 0x990000, 0xAA0000, 0xBB0000, 0xCC0000, 0xDD0000, 0xEE0000, 0xFF0000, 0xEE0000, 0xDD0000, 0xCC0000, 0xBB0000, 0xAA0000, 0x990000, }, }; menuitem effects[NUM_EFFECTS]; int the_effect = 0; /* Function prototypes */ void init(void); /* The Main function */ int main() { init(); mainloop(); return 0; } /* Styling functions */ int count_chars(char *str) { /* skip HTML tags and spaces */ int i, length, inside = 0; for (i=length=0; str[i]; i++) { if (str[i] == '>') inside = 0; else if (str[i] == '<') inside = 1; else if ((! inside) && (! isspace(str[i]))) length++; } return length; } void insert_main_text(void) { int i, c, fx; char ch[2]; char col[32]; rgb clr = Transparent; char * str = gettext(txt); int length = count_chars(str); int size = effect_size[the_effect]; ch[1] = '\0'; for (i=c=fx=0; str[i]; i++) { if (str[i] == '<') { for (;str[i];i++) { ch[0] = str[i]; inserttext(htm, ch); if (str[i] == '>') break; } } else if (str[i] == '\n') { inserttext(htm, "
\n"); } else if (isspace(str[i])) { ch[0] = str[i]; inserttext(htm, ch); } else if (fx_style == SOLID) { ch[0] = str[i]; inserttext(htm, ch); } else { if (fx_style == GRADUAL) fx = (c++) * size / (length+1); if (clr != effect_def[the_effect][fx]) { inserttext(htm, "", clr); inserttext(htm, col); } ch[0] = str[i]; inserttext(htm, ch); if (fx_style == GRADUAL) { fx = c * size / (length+1); } else if (fx_style == REPEATING) { fx++; c++; fx %= size; } if ((c >= length) || (clr != effect_def[the_effect][fx])) inserttext(htm, ""); } } } void process_text(void) { char str[64]; rgb col; int font_used = 0; settext(htm, ""); if (ischecked(center)) inserttext(htm, "
"); if (the_size != 0) { inserttext(htm, "<"); inserttext(htm, size_values[the_size]); inserttext(htm, ">"); } if ((the_typeface != 0) || ((fx_style == SOLID) && (the_colour != 0)) ) font_used = 1; if (font_used) inserttext(htm, ""); if (ischecked(styles[Bold])) inserttext(htm, ""); if (ischecked(styles[Italic])) inserttext(htm, ""); insert_main_text(); if (ischecked(styles[Italic])) inserttext(htm, ""); if (ischecked(styles[Bold])) inserttext(htm, ""); if (font_used) inserttext(htm, ""); if (the_size != 0) { inserttext(htm, ""); } if (ischecked(center)) inserttext(htm, "
"); } void update(void) { if (txt != NULL) { process_text(); selecttext(htm, 0, -1); copytext(htm); selecttext(htm, 0, 0); redraw(w); } } void copy_text(menuitem m) { update(); } void clear_text(menuitem m) { selecttext(txt, 0, -1); cleartext(txt); update(); } void set_style(menuitem m) { int style = Plain; if (m == styles[Plain]) { check(m); uncheck(styles[Bold]); uncheck(styles[Italic]); } else { if (ischecked(m)) { uncheck(m); } else { check(m); } uncheck(styles[Plain]); } style = ischecked(styles[Bold]) + ischecked(styles[Italic]); if (style == Plain) check(styles[Plain]); update(); } void set_center(menuitem m) { if (ischecked(m)) uncheck(m); else check(m); update(); } void set_face(menuitem m) { int i; for (i=0; i < NUM_TYPEFACES; i++) uncheck(typefaces[i]); check(m); the_typeface = getvalue(m); update(); } void set_size(menuitem m) { int i; for (i=0; i < NUM_SIZES; i++) uncheck(sizes[i]); check(m); the_size = getvalue(m); update(); } void set_colour(menuitem m) { int i; for (i=0; i < NUM_COLOURS; i++) uncheck(colours[i]); check(m); the_colour = getvalue(m); update(); } void set_fx_style(menuitem m) { int i; for (i=0; i < NUM_FX_STYLES; i++) uncheck(fxstyles[i]); check(m); fx_style = getvalue(m); for (i=0; i < NUM_EFFECTS; i++) { if (fx_style == SOLID) disable(effects[i]); else enable(effects[i]); } update(); } void set_effect(menuitem m) { uncheck(effects[the_effect]); check(m); the_effect = getvalue(m); update(); } char * copy_of_string(char *str) { char *s = (char *) malloc(strlen(str)+1); strcpy(s, str); return s; } void save_as(menuitem m) { static char *name = NULL; char * filename; FILE *f; if (name == NULL) name = copy_of_string("untitled.htm"); filename = askfilesave("Save As:", name); if (filename == NULL) /* operation cancelled */ return; free(name); name = copy_of_string(filename); f = fopen(name, "w"); if (f == NULL) { askok("That file could not be created."); return; } fprintf(f, "%s", gettext(htm)); /* save the HTML */ fclose(f); } void exit_program(menuitem m) { exitapp(); } void check_menu_options(menubar m) { char *text = gettext(txt); if (strcmp(text, "") == 0) { disable(copy_item); disable(clear_item); update(); } else if (! isenabled(copy_item)) { enable(copy_item); enable(clear_item); update(); } } void show_text(menuitem m) { update(); } void close_about_box(window w) { del(w); } void about_this_program(menuitem m) { char *lines[] = { "This program (c) 1998 by L. Patrick", "All rights reserved.", NULL, }; rect r = rect(0,0,300,100); int i, height; window w; w = newwindow("About Styled HTML", r, Titlebar + Closebox + Modal + Floating + Centered); height = getheight(SystemFont); for (i=0; lines[i]; i++) { newlabel(lines[i], rect(10,10+i*(height+5),r.width-20,height+5), AlignCenter); } setclose(w, close_about_box); show(w); } void init_menu_bar(window w) { int i; newmenubar(check_menu_options); newmenu("File"); newmenuitem("Save As...", 'S', save_as); newmenuitem("-", 0, NULL); /* separator */ newmenuitem("Exit", 'Q', exit_program); newmenu("Edit"); copy_item = newmenuitem("Copy", 'C', copy_text); clear_item = newmenuitem("Clear", 'X', clear_text); newmenuitem("-", 0, NULL); /* separator */ newmenuitem("Preview", 0, show_text); newmenu("Style"); styles[Plain] = newmenuitem("Plain", 'P', set_style); check(styles[Plain]); styles[Bold] = newmenuitem("Bold", 'B', set_style); styles[Italic] = newmenuitem("Italic", 'I', set_style); newmenuitem("-", 0, NULL); /* separator */ center = newmenuitem("Center", 'C', set_center); newmenuitem("-", 0, NULL); /* separator */ for (i=0; i")) style |= Italic; else if (strcontains(str+i, "")) style &= ~Italic; else if (strcontains(str+i, "")) style |= Bold; else if (strcontains(str+i, "")) style &= ~Bold; setfont(fonts[face][style]); for (;str[i];i++) { if (str[i] == '>') break; } } else if ((str[i] == '\n') || (str[i] == '\t')) { ch[0] = ' '; p.x += drawstr(p, ch); } else if ((fx_style == SOLID) || (str[i] == ' ')) { ch[0] = str[i]; p.x += drawstr(p, ch); } else if (fx_style == REPEATING) { ch[0] = str[i]; clr = currentcolour(); setcolour(effect_def[the_effect][fx++]); p.x += drawstr(p, ch); setcolour(clr); fx %= size; } else if (fx_style == GRADUAL) { ch[0] = str[i]; clr = currentcolour(); fx = (c++) * size / (length+1); setcolour(effect_def[the_effect][fx]); p.x += drawstr(p, ch); setcolour(clr); } if (p.x > r.width-10) break; /* clip to edge for efficiency */ } } void resize_window(window w, rect wr) { int h = min_height; rect r = rect(5, 10+h, wr.width-10, wr.height-15-h); if (r.height < h*10) { resize(txt, r); r.y = wr.height+10; resize(htm, r); } else { r.height = (r.height-5)/2; resize(txt, r); r.y += (r.height + 5); resize(htm, r); } } void init(void) { int h; rect r = rect(0,300,630,160); w = newwindow("Styled HTML", r, StandardWindow + Centered + Floating); setbackground(w, LightGrey); setresize(w, resize_window); init_menu_bar(w); h = getheight(SystemFont); txt = newtextbox("", rect(5,10+h,r.width-10,r.height-15-h)); htm = newtextbox("", rect(5,r.height+10,r.width-10,40)); disable(htm); settextfont(txt, Courier); settextfont(htm, Courier); init_fonts(); setredraw(w, redraw_window); show(w); }