/*
* 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, "");
inserttext(htm, size_values[the_size]);
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);
}