Mercurial > pidgin
comparison src/gtkhtml.c @ 954:dde2d3acdb23
[gaim-migrate @ 964]
i can't believe that i should have to do this >:-/
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Sat, 07 Oct 2000 22:51:44 +0000 |
| parents | 00768ed6045f |
| children | 0f9fc69a1f3b |
comparison
equal
deleted
inserted
replaced
| 953:00768ed6045f | 954:dde2d3acdb23 |
|---|---|
| 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->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->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 | 4407 |
| 4449 if (max_height < height) | 4408 if (max_height < height) |
| 4450 max_height = height; | 4409 max_height = height; |
| 4451 if (hbit->newline) | 4410 if (hbit->newline) |
| 4452 break; | 4411 break; |
| 4453 hbits = hbits->next; | 4412 hbits = hbits->next; |
| 4454 } | 4413 } |
| 4455 | 4414 |
| 4456 if (!max_height) | 4415 if (max_height == 0) |
| 4457 max_height = gdk_text_height(hbit->font, "C", 1); | 4416 max_height = gdk_text_height(hbit->font, "C", 1); |
| 4458 | 4417 |
| 4459 return max_height; | 4418 return max_height; |
| 4460 } | 4419 } |
| 4461 | |
| 4462 static void get_line_max_extents(GtkHtml *html, GtkHtmlBit *start, int *max_acsent, int *max_descent) | |
| 4463 { | |
| 4464 int acsent, descent; | |
| 4465 GList *hbits = html->html_bits; | |
| 4466 GtkHtmlBit *hbit = start; /* default this in case hbits is NULL */ | |
| 4467 | |
| 4468 *max_acsent = 0; | |
| 4469 *max_descent = 0; | |
| 4470 | |
| 4471 hbits = g_list_find(hbits, start); | |
| 4472 | |
| 4473 while (hbits) | |
| 4474 { | |
| 4475 hbit = (GtkHtmlBit *)hbits->data; | |
| 4476 if (hbit->font) | |
| 4477 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, &acsent, &descent); | |
| 4478 | |
| 4479 if (*max_acsent < acsent) | |
| 4480 *max_acsent = acsent; | |
| 4481 if (*max_descent < descent) | |
| 4482 *max_descent =descent; | |
| 4483 if (hbit->newline) | |
| 4484 break; | |
| 4485 hbits = hbits->next; | |
| 4486 } | |
| 4487 | |
| 4488 if (!*max_acsent) | |
| 4489 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, max_acsent, NULL); | |
| 4490 if (!*max_descent) | |
| 4491 gdk_text_extents(hbit->font, "yG", strlen("yG"), NULL, NULL, NULL, NULL, max_descent); | |
| 4492 | |
| 4493 return; | |
| 4494 } |
