src/gtkhtml.c

changeset 985
3735b78b55a1
parent 957
ca989602d21c
child 1004
c4dc44bbbc18
equal deleted inserted replaced
984:b4b8d9fb7cc8 985:3735b78b55a1
42 42
43 #include "pixmaps/aol_icon.xpm" 43 #include "pixmaps/aol_icon.xpm"
44 #include "pixmaps/admin_icon.xpm" 44 #include "pixmaps/admin_icon.xpm"
45 #include "pixmaps/free_icon.xpm" 45 #include "pixmaps/free_icon.xpm"
46 #include "pixmaps/dt_icon.xpm" 46 #include "pixmaps/dt_icon.xpm"
47 #define MAX_SIZE 7 47 #define MAX_SIZE 7
48 #define MIN_HTML_WIDTH_LINES 20 48 #define MIN_HTML_WIDTH_LINES 20
49 #define MIN_HTML_HEIGHT_LINES 10 49 #define MIN_HTML_HEIGHT_LINES 10
50 #define BORDER_WIDTH 2 50 #define BORDER_WIDTH 2
51 #define SCROLL_TIME 100 51 #define SCROLL_TIME 100
52 #define SCROLL_PIXELS 5 52 #define SCROLL_PIXELS 5
53 #define KEY_SCROLL_PIXELS 10 53 #define KEY_SCROLL_PIXELS 10
54 54
55 int font_sizes[] = { 80, 100, 120, 140, 200, 300, 400 }; 55 int font_sizes[] = { 80, 100, 120, 140, 200, 300, 400 };
56 GtkHtmlBit *start_of_line = NULL;
57 56
58 /* 57 /*
59 GdkFont *fixed_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 58 GdkFont *fixed_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
60 GdkFont *fixed_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 59 GdkFont *fixed_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
61 GdkFont *fixed_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 60 GdkFont *fixed_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
167 static void resize_html(GtkHtml * html); 166 static void resize_html(GtkHtml * html);
168 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb); 167 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb);
169 static void draw_cursor(GtkHtml * html); 168 static void draw_cursor(GtkHtml * html);
170 static void undraw_cursor(GtkHtml * html); 169 static void undraw_cursor(GtkHtml * html);
171 170
172 static int get_line_max_height(GtkHtml *, GtkHtmlBit *); 171 static int get_line_height(GtkHtml *, GtkHtmlBit *);
173 static void get_line_max_extents(GtkHtml *, GtkHtmlBit *, int *, int *);
174 172
175 static GtkWidgetClass *parent_class = NULL; 173 static GtkWidgetClass *parent_class = NULL;
176 174
177 GtkType gtk_html_get_type(void) 175 GtkType gtk_html_get_type(void)
178 { 176 {
1844 GtkHtmlBit *hbit; 1842 GtkHtmlBit *hbit;
1845 1843
1846 if (html->frozen > 0) 1844 if (html->frozen > 0)
1847 return; 1845 return;
1848 1846
1847 hbits = g_list_find(html->html_bits, hb);
1848
1849 if (hb->type == HTML_BIT_TEXT) 1849 if (hb->type == HTML_BIT_TEXT)
1850 { 1850 {
1851 1851
1852 if (!(hb->text)) 1852 if (!(hb->text))
1853 return; 1853 return;
2044 } 2044 }
2045 2045
2046 /*end my stuff*/ 2046 /*end my stuff*/
2047 2047
2048 if (hb->text && hb->back != NULL) { 2048 if (hb->text && hb->back != NULL) {
2049 int hwidth, hheight, tmpcnt, max_ascent, max_descent; 2049 int hwidth, hheight, hei, tmpcnt;
2050 2050 hei = get_line_height(html, hb);
2051 /* get the gtkhtmlbit at the start of each line, and use it as the starting point to calculate the
2052 max height of each line and set the background-rectangle's size accordingly */
2053 /* FIXME: should also include a method of eliminating 'gaps' between different line using
2054 different text sizes */
2055 if (!start_of_line)
2056 start_of_line = hb;
2057 else
2058 {
2059 hbits = g_list_find(html->html_bits, hb);
2060 if (hbits->prev)
2061 {
2062 hbit = hbits->prev->data;
2063 if (hbit && hbit->newline)
2064 start_of_line = hb;
2065 }
2066 else
2067 start_of_line = hb;
2068 }
2069
2070 get_line_max_extents(html, start_of_line, &max_ascent, &max_descent);
2071 gdk_window_get_size(html->html_area, &hwidth, &hheight); 2051 gdk_window_get_size(html->html_area, &hwidth, &hheight);
2072 gdk_gc_set_foreground(gc, hb->back); 2052 gdk_gc_set_foreground(gc, hb->back);
2073 /* we use a 2-pixel window border */ 2053 /* we use a 2-pixel window border */
2074 if (hb->x < 2) 2054 if (hb->x < 2)
2075 hb->x = 2; 2055 hb->x = 2;
2076
2077 gdk_draw_rectangle(html->html_area, gc, TRUE /* filled */, 2056 gdk_draw_rectangle(html->html_area, gc, TRUE /* filled */,
2078 hb->x, hb->y - html->yoffset - max_ascent - max_descent - 2, 2057 hb->x, hb->y - html->yoffset - hei - 6,
2079 hwidth - shift - hb->x + 1, max_ascent + max_descent + 8); 2058 hwidth - shift - hb->x + 1, hei + hei + 2);
2080 for (tmpcnt = 1; tmpcnt < hb->newline; tmpcnt++) { 2059 for (tmpcnt = 1; tmpcnt < hb->newline; tmpcnt++) {
2081 int eoff = max_ascent + max_descent + 2; 2060 int eoff = hei + hei + 2;
2082 eoff *= tmpcnt; 2061 eoff *= tmpcnt;
2083 gdk_draw_rectangle(html->html_area, gc, TRUE, 2062 gdk_draw_rectangle(html->html_area, gc, TRUE,
2084 2, hb->y - html->yoffset - max_ascent - max_descent - 2 + eoff, 2063 2, hb->y - html->yoffset - hei - 6 + eoff,
2085 hwidth, max_ascent + max_descent + 2); 2064 hwidth, hei + hei + 2);
2086 } 2065 }
2087 } 2066 }
2088 2067
2089 if (hb->fore != NULL) 2068 if (hb->fore != NULL)
2090 gdk_gc_set_foreground(gc, hb->fore); 2069 gdk_gc_set_foreground(gc, hb->fore);
2093 2072
2094 gdk_gc_set_font(gc, hb->font); 2073 gdk_gc_set_font(gc, hb->font);
2095 2074
2096 gdk_draw_string(html->html_area, hb->font, gc, shift + hb->x, 2075 gdk_draw_string(html->html_area, hb->font, gc, shift + hb->x,
2097 hb->y - html->yoffset, hb->text); 2076 hb->y - html->yoffset, hb->text);
2098
2099 if (hb->uline) 2077 if (hb->uline)
2100 gdk_draw_line(html->html_area, gc, shift + hb->x, 2078 gdk_draw_line(html->html_area, gc, shift + hb->x,
2101 hb->y - html->yoffset, 2079 hb->y - html->yoffset,
2102 hb->x + gdk_string_measure(hb->font, hb->text), 2080 hb->x + gdk_string_measure(hb->font, hb->text),
2103 hb->y - html->yoffset); 2081 hb->y - html->yoffset);
2112 } 2090 }
2113 else if (hb->type == HTML_BIT_SEP) 2091 else if (hb->type == HTML_BIT_SEP)
2114 { 2092 {
2115 if (hb->back != NULL) { 2093 if (hb->back != NULL) {
2116 int hwidth, hheight, hei, tmpcnt; 2094 int hwidth, hheight, hei, tmpcnt;
2117 2095 hei = get_line_height(html, hb);
2118 if (!start_of_line)
2119 start_of_line = hb;
2120 else
2121 {
2122 hbits = g_list_find(html->html_bits, hb);
2123 if (hbits && hbits->prev)
2124 {
2125 hbit = hbits->prev->data;
2126 if (hbit && hbit->newline)
2127 start_of_line = hb;
2128 }
2129 else
2130 start_of_line = hb;
2131 }
2132
2133 hei = get_line_max_height(html, start_of_line);
2134
2135 gdk_window_get_size(html->html_area, &hwidth, &hheight); 2096 gdk_window_get_size(html->html_area, &hwidth, &hheight);
2136 gdk_gc_set_foreground(gc, hb->back); 2097 gdk_gc_set_foreground(gc, hb->back);
2137 gdk_draw_rectangle(html->html_area, gc, TRUE, 2098 gdk_draw_rectangle(html->html_area, gc, TRUE,
2138 2, hb->y - html->yoffset, 2099 2, hb->y - html->yoffset,
2139 hwidth, 5); 2100 hwidth, 5);
2165 area.width = hb->width; 2126 area.width = hb->width;
2166 area.height = hb->height; 2127 area.height = hb->height;
2167 clear_area(html, &area); 2128 clear_area(html, &area);
2168 if (hb->back != NULL) { 2129 if (hb->back != NULL) {
2169 int hwidth, hheight, hei, tmpcnt; 2130 int hwidth, hheight, hei, tmpcnt;
2170 2131 hei = get_line_height(html, hb);
2171 if (!start_of_line)
2172 start_of_line = hb;
2173 else
2174 {
2175 hbits = g_list_find(html->html_bits, hb);
2176 if (hbits && hbits->prev)
2177 {
2178 hbit = hbits->prev->data;
2179 if (hbit && hbit->newline)
2180 start_of_line = hb;
2181 }
2182 else
2183 start_of_line = hb;
2184 }
2185
2186 hei = get_line_max_height(html, start_of_line);
2187
2188 gdk_window_get_size(html->html_area, &hwidth, &hheight); 2132 gdk_window_get_size(html->html_area, &hwidth, &hheight);
2189 gdk_gc_set_foreground(gc, hb->back); 2133 gdk_gc_set_foreground(gc, hb->back);
2190 for (tmpcnt = 0; tmpcnt < hb->newline; tmpcnt++) { 2134 for (tmpcnt = 0; tmpcnt < hb->newline; tmpcnt++) {
2191 int eoff = hei + hei + 2; 2135 int eoff = hei + hei + 2;
2192 eoff *= tmpcnt; 2136 eoff *= tmpcnt;
2911 *text, 2855 *text,
2912 *tmp; 2856 *tmp;
2913 GdkGC *gc; 2857 GdkGC *gc;
2914 int nl = 0, 2858 int nl = 0,
2915 nl2 = 0; 2859 nl2 = 0;
2916 int maxwidth, ascent, descent; 2860 int maxwidth;
2917 gint lb; 2861 gint lb;
2918 GList *hbits; 2862 GList *hbits;
2919 size_t num = 0; 2863 size_t num = 0;
2920 int i, 2864 int i,
2921 height; 2865 height;
3029 g_free(text); 2973 g_free(text);
3030 count--; 2974 count--;
3031 if (!count) { 2975 if (!count) {
3032 /* FIXME : sometimes we need to add newline, sometimes we don't */ 2976 /* FIXME : sometimes we need to add newline, sometimes we don't */
3033 hbits = g_list_last(html->html_bits); 2977 hbits = g_list_last(html->html_bits);
3034 if (!hbits) 2978 if (!hbits) return; /* does this ever happen? */
3035 return; /* does this ever happen? */
3036 hb = (GtkHtmlBit *)hbits->data; 2979 hb = (GtkHtmlBit *)hbits->data;
3037 hb->newline++; 2980 hb->newline++;
3038 } 2981 }
3039 return; 2982 return;
3040 } 2983 }
3060 } 3003 }
3061 } 3004 }
3062 3005
3063 } 3006 }
3064 3007
3065 gdk_text_extents(cfont, "yG", strlen("yG"), NULL, NULL, NULL, &ascent, &descent); 3008 height = cfont->ascent + cfont->descent + 2;
3066 height = ascent + descent + 2; 3009
3067 3010
3068 if ((int) (html->vadj->upper - html->current_y) < (int) (height * 2)) 3011 if ((int) (html->vadj->upper - html->current_y) < (int) (height * 2))
3069 { 3012 {
3070 int val; 3013 int val;
3071 val = (height * 2) + html->current_y; 3014 val = (height * 2) + html->current_y;
3072 html->vadj->upper = val; 3015 html->vadj->upper = val;
3074 } 3017 }
3075 3018
3076 3019
3077 if (html->current_x == 0) 3020 if (html->current_x == 0)
3078 { 3021 {
3079 html->current_y += height + 6; 3022 html->current_y += height + 3;
3080 gdk_text_extents(cfont, text, 1, &lb, NULL, NULL, NULL, NULL); 3023 gdk_text_extents(cfont, text, 1, &lb, NULL, NULL, NULL, NULL);
3081 html->current_x += (2 - lb); 3024 html->current_x += (2 - lb);
3082 } 3025 }
3083 else if ((hbits = g_list_last(html->html_bits)) != NULL) 3026 else if ((hbits = g_list_last(html->html_bits)) != NULL)
3084 { 3027 {
3486 { 3429 {
3487 if (!strncasecmp(d, "COLOR=", strlen("COLOR="))) 3430 if (!strncasecmp(d, "COLOR=", strlen("COLOR=")))
3488 { 3431 {
3489 d += strlen("COLOR="); 3432 d += strlen("COLOR=");
3490 if (*d == '\"') 3433 if (*d == '\"')
3434 {
3491 d++; 3435 d++;
3436 }
3492 if (*d == '#') 3437 if (*d == '#')
3493 d++; 3438 d++;
3494 if (d[strlen(d) - 1] == '\"') 3439 if (d[strlen(d) - 1] == '\"')
3495 d[strlen(d) - 1] = 0; 3440 d[strlen(d) - 1] = 0;
3496 if (sscanf(d, "%x", &colorv) 3441 if (sscanf(d, "%x", &colorv)
3497 && !(options & HTML_OPTION_NO_COLOURS)) 3442 && !(options & HTML_OPTION_NO_COLOURS))
3498 { 3443 {
3499 current->color = get_color(colorv, map); 3444 current->color = get_color(colorv, map);
3500 current->owncolor = 1; 3445 current->owncolor = 1;
3501 } 3446 }
3447 else
3448 {
3449 }
3502 } 3450 }
3503 if (!strncasecmp(d, "FACE=", strlen("FACE="))) 3451 if (!strncasecmp(d, "FACE=", strlen("FACE=")))
3504 { 3452 {
3505 d += strlen("FACE="); 3453 d += strlen("FACE=");
3506 if (*d == '\"') 3454 if (*d == '\"')
3455 {
3507 d++; 3456 d++;
3457 }
3508 if (d[strlen(d) - 1] == '\"') 3458 if (d[strlen(d) - 1] == '\"')
3509 d[strlen(d) - 1] = 0; 3459 d[strlen(d) - 1] = 0;
3510 strcpy(current->font, d); 3460 strcpy(current->font, d);
3511 } 3461 }
3512 else if (!strncasecmp(d, "BACK=", strlen("BACK="))) 3462 else if (!strncasecmp(d, "BACK=", strlen("BACK=")))
3522 && !(options & HTML_OPTION_NO_COLOURS)) 3472 && !(options & HTML_OPTION_NO_COLOURS))
3523 { 3473 {
3524 current->bgcol = get_color(colorv, map); 3474 current->bgcol = get_color(colorv, map);
3525 current->ownbg = 1; 3475 current->ownbg = 1;
3526 } 3476 }
3477 else
3478 {
3479 }
3527 } 3480 }
3528 else if (!strncasecmp(d, "SIZE=", strlen("SIZE="))) 3481 else if (!strncasecmp(d, "SIZE=", strlen("SIZE=")))
3529 { 3482 {
3530 d += strlen("SIZE="); 3483 d += strlen("SIZE=");
3531 if (*d == '\"') 3484 if (*d == '\"')
3532 d++; 3485 d++;
3533 if (*d == '+') 3486 if (*d == '+')
3534 d++; 3487 d++;
3535 if (sscanf(d, "%d", &colorv)) 3488 if (sscanf(d, "%d", &colorv))
3489 {
3536 current->size = colorv; 3490 current->size = colorv;
3491 }
3492 else
3493 {
3494 }
3537 } 3495 }
3538 else if (strncasecmp(d, "PTSIZE=", strlen("PTSIZE="))) 3496 else if (strncasecmp(d, "PTSIZE=", strlen("PTSIZE=")))
3539 { 3497 {
3540 } 3498 }
3541 } 3499 }
3542 } 3500 }
3543 else if (!strncasecmp(tag, "BODY", strlen("BODY"))) 3501 else if (!strncasecmp(tag, "BODY", strlen("BODY")))
3544 { 3502 {
3503
3545 char *d; 3504 char *d;
3546 current = push_state(current); 3505 current = push_state(current);
3547 html_strtok(tag, ' '); 3506 html_strtok(tag, ' ');
3548 while ((d = html_strtok(NULL, ' '))) 3507 while ((d = html_strtok(NULL, ' ')))
3549 { 3508 {
4430 expose_html(html, &area, TRUE); 4389 expose_html(html, &area, TRUE);
4431 } 4390 }
4432 } 4391 }
4433 } 4392 }
4434 4393
4435 static int get_line_max_height(GtkHtml *html, GtkHtmlBit *start) 4394 static int get_line_height(GtkHtml *html, GtkHtmlBit *start)
4436 { 4395 {
4437 int height, max_height = 0; 4396 int height, max_height = 0;
4438 GList *hbits = html->html_bits; 4397 GList *hbits = html->html_bits;
4439 GtkHtmlBit *hbit = start; /* default this in case hbits is NULL */ 4398 GtkHtmlBit *hbit = start; /* default this in case hbits is NULL */
4440 4399
4441 hbits = g_list_find(hbits, start); 4400 hbits = g_list_find(hbits, start);
4442 4401
4443 while (hbits) 4402 while (hbits)
4444 { 4403 {
4445 hbit = (GtkHtmlBit *)hbits->data; 4404 hbit = hbits->data;
4446 if (hbit->font) 4405 if (hbit->font)
4447 height = gdk_text_height(hbit->font, "C", 1); 4406 height = gdk_text_height(hbit->font, "C", 1);
4448 else if(hbit->type == HTML_BIT_PIXMAP) 4407
4449 height = 19;
4450 if (max_height < height) 4408 if (max_height < height)
4451 max_height = height; 4409 max_height = height;
4452 if (hbit->newline) 4410 if (hbit->newline)
4453 break; 4411 break;
4454 hbits = hbits->next; 4412 hbits = hbits->next;
4455 } 4413 }
4456 4414
4457 if (!max_height) 4415 if (max_height == 0)
4458 max_height = gdk_text_height(hbit->font, "C", 1); 4416 max_height = gdk_text_height(hbit->font, "C", 1);
4459 4417
4460 return max_height; 4418 return max_height;
4461 } 4419 }
4462
4463 static void get_line_max_extents(GtkHtml *html, GtkHtmlBit *start, int *max_acsent, int *max_descent)
4464 {
4465 int acsent, descent;
4466 GList *hbits = html->html_bits;
4467 GtkHtmlBit *hbit = start; /* default this in case hbits is NULL */
4468
4469 *max_acsent = 0;
4470 *max_descent = 0;
4471
4472 hbits = g_list_find(hbits, start);
4473
4474 while (hbits)
4475 {
4476 hbit = (GtkHtmlBit *)hbits->data;
4477 if (hbit->font)
4478 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, &acsent, &descent);
4479 else if (hbit->type == HTML_BIT_PIXMAP)
4480 {
4481 acsent =9;
4482 descent = 8;
4483 }
4484
4485 if (*max_acsent < acsent)
4486 *max_acsent = acsent;
4487 if (*max_descent < descent)
4488 *max_descent =descent;
4489 if (hbit->newline)
4490 break;
4491 hbits = hbits->next;
4492 }
4493
4494 if (!*max_acsent)
4495 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, max_acsent, NULL);
4496 if (!*max_descent)
4497 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, NULL, max_descent);
4498
4499 return;
4500 }

mercurial