diff options
author | Richard Wilson <rjw@netsurf-browser.org> | 2005-06-23 17:24:23 +0000 |
---|---|---|
committer | Richard Wilson <rjw@netsurf-browser.org> | 2005-06-23 17:24:23 +0000 |
commit | f559054c1a1b0819e52e0f9d04fc55be484746c5 (patch) | |
tree | 2c6652666c751a1a368920679da0ba85b01854d8 | |
parent | b88a81b9d9570c3219dc924c3dd2b424d99ee4c3 (diff) | |
download | netsurf-f559054c1a1b0819e52e0f9d04fc55be484746c5.tar.gz netsurf-f559054c1a1b0819e52e0f9d04fc55be484746c5.tar.bz2 |
[project @ 2005-06-23 17:24:23 by rjw]
Allow images to be unloaded to disk or compressed in memory. Provide thumbnails in all tree windows (hotlist, history). Optimise the application initialisation times. Part 2 of 2.
svn path=/import/netsurf/; revision=1762
-rw-r--r-- | riscos/gui.c | 27 | ||||
-rw-r--r-- | riscos/history.c | 133 | ||||
-rw-r--r-- | riscos/image.h | 2 | ||||
-rw-r--r-- | riscos/menus.c | 14 | ||||
-rw-r--r-- | riscos/options.h | 13 | ||||
-rw-r--r-- | riscos/plotters.c | 6 | ||||
-rw-r--r-- | riscos/save.c | 20 | ||||
-rw-r--r-- | riscos/save_draw.c | 4 | ||||
-rw-r--r-- | riscos/thumbnail.c | 327 | ||||
-rw-r--r-- | riscos/thumbnail.h | 8 | ||||
-rw-r--r-- | riscos/treeview.c | 83 | ||||
-rw-r--r-- | riscos/treeview.h | 1 |
12 files changed, 331 insertions, 307 deletions
diff --git a/riscos/gui.c b/riscos/gui.c index 0248476cc..2b8b17ce3 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -17,7 +17,7 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include <unixlib/features.h> +//#include <unixlib/features.h> #include <unixlib/local.h> #include "oslib/font.h" #include "oslib/help.h" @@ -45,7 +45,9 @@ #include "netsurf/render/box.h" #include "netsurf/render/font.h" #include "netsurf/render/html.h" +#include "netsurf/riscos/bitmap.h" #include "netsurf/riscos/buffer.h" +#include "netsurf/riscos/filename.h" #include "netsurf/riscos/global_history.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/help.h" @@ -109,7 +111,7 @@ int os_version = 0; -const char *__dynamic_da_name = "NetSurf"; /**< For UnixLib. */ +const char * const __dynamic_da_name = "NetSurf"; /**< For UnixLib. */ int __dynamic_da_max_size = 128 * 1024 * 1024; /**< For UnixLib. */ int __feature_imagefs_is_file = 1; /**< For UnixLib. */ /* default filename handling */ @@ -260,6 +262,7 @@ void gui_init(int argc, char** argv) xosfile_create_dir("<User$Path>.Choices.NetSurf.Choices", 0); xosfile_create_dir("<User$Path>.Choices.NetSurf.Choices.Themes", 0); #endif + ro_filename_initialise(); #ifdef WITH_SAVE_COMPLETE save_complete_init(); @@ -283,6 +286,7 @@ void gui_init(int argc, char** argv) ro_gui_choose_language(); + bitmap_initialise_memory(); url_store_load("Choices:WWW.NetSurf.URL"); nsdir_temp = getenv("NetSurf$Dir"); @@ -584,7 +588,8 @@ void gui_init2(int argc, char** argv) void gui_quit(void) { - url_store_save("<Choices$Write>.WWW.NetSurf.URL"); + bitmap_quit(); + url_store_save("<Choices$Write>.WWW.NetSurf.URL"); ro_gui_window_quit(); ro_gui_global_history_save(); ro_gui_hotlist_save(); @@ -655,7 +660,8 @@ void gui_poll(bool active) xhourglass_off(); if (active) { event = wimp_poll(mask, &block, 0); - } else if (sched_active || gui_track || gui_reformat_pending) { + } else if (sched_active || gui_track || gui_reformat_pending || + bitmap_maintenance) { os_t t = os_read_monotonic_time(); if (gui_track) @@ -686,6 +692,9 @@ void gui_poll(bool active) if (gui_reformat_pending && event == wimp_NULL_REASON_CODE) ro_gui_window_process_reformats(); + else if (bitmap_maintenance_priority || + (bitmap_maintenance && event == wimp_NULL_REASON_CODE)) + bitmap_maintain(); } @@ -801,7 +810,7 @@ void ro_gui_poll_queue(wimp_event_no event, wimp_block *block) q->event = event; q->block = calloc(1, sizeof(*block)); if (!q->block) { - free(q); + free(q); LOG(("Insufficient memory for calloc")); warn_user("NoMemory", 0); return; @@ -903,7 +912,7 @@ void ro_gui_redraw_window_request(wimp_draw *redraw) else if ((g = ro_gui_window_lookup(redraw->w)) != NULL) ro_gui_window_redraw(g, redraw); else if ((g = ro_gui_toolbar_lookup(redraw->w)) != NULL) { - if (g->toolbar->toolbar_handle == redraw->w) + if (g->toolbar->toolbar_handle == redraw->w) ro_gui_theme_redraw(g->toolbar, redraw); else if ((g->toolbar->editor) && (g->toolbar->editor->toolbar_handle == redraw->w)) @@ -1045,7 +1054,7 @@ void ro_gui_mouse_click(wimp_pointer *pointer) (hotlist_tree->toolbar->editor->toolbar_handle == pointer->w)) ro_gui_tree_toolbar_click(pointer, hotlist_tree); else if ((global_history_tree) && (global_history_tree->toolbar) && - (global_history_tree->toolbar->toolbar_handle == pointer->w)) + (global_history_tree->toolbar->toolbar_handle == pointer->w)) ro_gui_tree_toolbar_click(pointer, global_history_tree); else if ((global_history_tree) && (global_history_tree->toolbar) && (global_history_tree->toolbar->editor) && @@ -1410,8 +1419,8 @@ void ro_msg_dataload(wimp_message *message) } else if ((hotlist_tree) && ((wimp_w)hotlist_tree->handle == message->data.data_xfer.w)) { if (!title) { - tree_edit = true; - title = url; + tree_edit = true; + title = url; } ro_gui_tree_get_tree_coordinates(hotlist_tree, message->data.data_xfer.pos.x, diff --git a/riscos/history.c b/riscos/history.c index 79f2665d5..c423272e4 100644 --- a/riscos/history.c +++ b/riscos/history.c @@ -3,6 +3,7 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> */ /** \file @@ -16,12 +17,17 @@ #include "oslib/colourtrans.h" #include "oslib/font.h" #include "oslib/wimp.h" +#include "netsurf/content/url_store.h" +#include "netsurf/image/bitmap.h" +#include "netsurf/riscos/bitmap.h" +#include "netsurf/riscos/image.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/thumbnail.h" #include "netsurf/riscos/tinct.h" #include "netsurf/riscos/wimp.h" #include "netsurf/utils/log.h" +#include "netsurf/utils/url.h" #include "netsurf/utils/utils.h" #define SIZE 10 @@ -45,7 +51,7 @@ struct history_entry { struct history_entry *forward_last; /**< Last child. */ unsigned int children; /**< Number of children. */ int x, y, width; - osspriteop_area *sprite_area; /**< Thumbnail sprite area, or 0. */ + struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */ }; /** History tree for a window. */ @@ -108,20 +114,24 @@ struct history *history_create(void) void history_add(struct history *history, struct content *content, char *frag_id) { + url_func_result res; struct history_entry *entry; char *url; char *title; char *split; int width; - osspriteop_area *area; -// os_error *error; + struct bitmap *bitmap; if (!history) return; /* allocate space */ entry = malloc(sizeof *entry); - url = strdup(content->url); + res = url_normalize(content->url, &url); + if (res != URL_FUNC_OK) { + warn_user("NoMemory", 0); + return; + } title = strdup(content->title ? content->title : url); if (!entry || !url || !title) { warn_user("NoMemory", 0); @@ -148,7 +158,7 @@ void history_add(struct history *history, struct content *content, char *frag_id entry->forward = entry->forward_pref = entry->forward_last = 0; entry->children = 0; entry->width = width / 400; - entry->sprite_area = 0; + entry->bitmap = 0; if (history->current) { if (history->current->forward_last) history->current->forward_last->next = entry; @@ -162,37 +172,20 @@ void history_add(struct history *history, struct content *content, char *frag_id } history->current = entry; -/* area = malloc(SPRITE_SIZE); - if (!area) { - LOG(("malloc failed")); - return; - } - - area->size = SPRITE_SIZE; - area->sprite_count = 0; - area->first = 16; - area->used = 16; - - error = xosspriteop_create_sprite(osspriteop_NAME, - area, "thumbnail", false, - WIDTH / 2, HEIGHT / 2, os_MODE8BPP90X90); - if (error) { - LOG(("0x%x: %s", error->errnum, error->errmess)); - return; - } - */ - area = thumbnail_initialise(WIDTH / 2, HEIGHT / 2, (os_mode)0x301680b5); - if (!area) { - LOG(("Thumbnail initialisation failed.")); - return; + /* if we have a thumbnail, don't update until the page has finished + * loading */ + bitmap = url_store_get_thumbnail(url); + bitmap = NULL; + if (!bitmap) { + bitmap = bitmap_create(WIDTH / 2, HEIGHT / 2, false); + if (!bitmap) { + LOG(("Thumbnail initialisation failed.")); + return; + } + bitmap_set_opaque(bitmap, true); + thumbnail_create(content, bitmap, url); } - thumbnail_create(content, area, - (osspriteop_header *) (area + 1), - WIDTH / 2, HEIGHT / 2); -/* xosspriteop_save_sprite_file(osspriteop_NAME, - area, "thumbnail");*/ - - entry->sprite_area = area; + entry->bitmap = bitmap; } @@ -205,13 +198,10 @@ void history_add(struct history *history, struct content *content, char *frag_id void history_update(struct history *history, struct content *content) { - if (!history || !history->current || !history->current->sprite_area) + if (!history || !history->current || !history->current->bitmap) return; - thumbnail_create(content, history->current->sprite_area, - (osspriteop_header *) - (history->current->sprite_area + 1), - WIDTH / 2, HEIGHT / 2); + thumbnail_create(content, history->current->bitmap, NULL); } @@ -248,7 +238,6 @@ void history_free_entry(struct history_entry *entry) if (entry->frag_id) free(entry->frag_id); free(entry->title); - free(entry->sprite_area); free(entry); } @@ -412,59 +401,23 @@ void ro_gui_history_redraw_tree(struct history_entry *he, os_plot(os_PLOT_SOLID | os_PLOT_BY, -WIDTH - 1, 0); os_plot(os_PLOT_SOLID | os_PLOT_BY, 0, HEIGHT + 1); - if (he->sprite_area) { - osspriteop_area *area = he->sprite_area; - osspriteop_header *header = (osspriteop_header *)(area + 1); - osspriteop_trans_tab *table; - - /* Because we're supporting people with OS3.1 we need to check if the - sprite we have is a legacy 256 colour one - */ - if (header->mode == (os_mode)tinct_SPRITE_MODE) { - - /* We plot with no mask and no scaling as any EIG factors are - handled internally by Tinct - */ - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - (char *)(header), - x0 + he->x * FULL_WIDTH + MARGIN, - y0 - he->y * FULL_HEIGHT - FULL_HEIGHT + MARGIN, - tinct_ERROR_DIFFUSE | tinct_BILINEAR_FILTER); + if (he->bitmap) { + if (bitmap_get_buffer(he->bitmap)) { + image_redraw(he->bitmap->sprite_area, + x0 + he->x * FULL_WIDTH + MARGIN, + y0 - he->y * FULL_HEIGHT - MARGIN, + he->bitmap->width, he->bitmap->height, + he->bitmap->width, he->bitmap->height, + 0xffffff, + false, false, false, + IMAGE_PLOT_TINCT_OPAQUE); } else { - unsigned int size; - os_factors factors; - - xcolourtrans_generate_table_for_sprite( - area, (osspriteop_id)header, - colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE, - 0, colourtrans_GIVEN_SPRITE, 0, 0, &size); - table = calloc(size, 1); - if (!table) { - LOG(("Insufficient memory for calloc")); - warn_user("NoMemory", 0); - } else { - xcolourtrans_generate_table_for_sprite( - area, (osspriteop_id)header, - colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE, - table, colourtrans_GIVEN_SPRITE, 0, 0, 0); - - factors.xmul = 1; - factors.ymul = 1; - factors.xdiv = 1; - factors.ydiv = 1; - - xosspriteop_put_sprite_scaled(osspriteop_PTR, - area, (osspriteop_id)header, - x0 + he->x * FULL_WIDTH + MARGIN, - y0 - he->y * FULL_HEIGHT - FULL_HEIGHT + MARGIN, - osspriteop_USE_MASK | osspriteop_USE_PALETTE, - &factors, table); - free(table); - } + url_store_add_thumbnail(he->url, NULL); + he->bitmap = NULL; + } } - if (he == history_current->current) wimp_set_font_colours(wimp_COLOUR_WHITE, wimp_COLOUR_RED); else diff --git a/riscos/image.h b/riscos/image.h index b2f8b9b09..e480697e6 100644 --- a/riscos/image.h +++ b/riscos/image.h @@ -8,6 +8,8 @@ #ifndef _NETSURF_RISCOS_IMAGE_H_ #define _NETSURF_RISCOS_IMAGE_H_ +#include "oslib/osspriteop.h" + struct osspriteop_area; typedef enum { diff --git a/riscos/menus.c b/riscos/menus.c index b895395c9..1cb4cae05 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -31,6 +31,7 @@ #include "netsurf/riscos/wimp.h" #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" +#include "netsurf/utils/url.h" #include "netsurf/utils/utils.h" #include "netsurf/utils/utf8.h" @@ -1277,6 +1278,8 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, struct node *node; os_error *error; char url[80]; + url_func_result res; + char *norm_url = NULL; ro_gui_menu_get_window_details(owner, &g, &bw, &c, &t, &tree); @@ -1312,11 +1315,17 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, /* hotlist actions */ case HOTLIST_ADD_URL: - if ((!hotlist_tree) || (!c)) + if ((!hotlist_tree) || (!c) || (!c->url)) return false; + res = url_normalize(c->url, &norm_url); + if (res != URL_FUNC_OK) { + warn_user("NoMemory", 0); + return false; + } node = tree_create_URL_node(hotlist_tree->root, - c->title, c->url, ro_content_filetype(c), + c->title, norm_url, ro_content_filetype(c), time(NULL), -1, 0); + free(norm_url); if (node) { tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, 0, @@ -1325,6 +1334,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, false, true); ro_gui_tree_scroll_visible(hotlist_tree, &node->data); + ro_gui_hotlist_save(); } return true; case HOTLIST_SHOW: diff --git a/riscos/options.h b/riscos/options.h index e0e32f8cf..b97ddc6e2 100644 --- a/riscos/options.h +++ b/riscos/options.h @@ -24,7 +24,6 @@ extern char *option_theme; extern char *option_language; extern int option_fg_plot_style; /* tinct flagword */ extern int option_bg_plot_style; /* tinct flagword */ -extern bool option_thumbnail_32bpp; extern bool option_history_tooltip; extern int option_scale; extern int option_toolbar_status_width; @@ -60,6 +59,8 @@ extern char *option_font_default_bold; extern char *option_font_default_bold_italic; extern bool option_block_popups; extern bool option_url_suggestion; +extern int option_image_memory_direct; /* -1 means auto-detect */ +extern int option_image_memory_compressed; /* -1 means auto-detect */ #define EXTRA_OPTION_DEFINE \ bool option_use_mouse_gestures = false;\ @@ -68,7 +69,6 @@ char *option_theme = 0;\ char *option_language = 0;\ int option_fg_plot_style = tinct_ERROR_DIFFUSE;\ int option_bg_plot_style = tinct_DITHER;\ -bool option_thumbnail_32bpp = true;\ bool option_history_tooltip = true; \ int option_scale = 100; \ int option_toolbar_status_width = 5000; \ @@ -100,7 +100,9 @@ char *option_font_cursive = 0; \ char *option_font_fantasy = 0; \ int option_font_default = CSS_FONT_FAMILY_SANS_SERIF; \ bool option_block_popups = false; \ -bool option_url_suggestion = true; +bool option_url_suggestion = true; \ +int option_image_memory_direct = -1; \ +int option_image_memory_compressed = -1; #define EXTRA_OPTION_TABLE \ { "use_mouse_gestures", OPTION_BOOL, &option_use_mouse_gestures },\ @@ -109,7 +111,6 @@ bool option_url_suggestion = true; { "language", OPTION_STRING, &option_language },\ { "plot_fg_quality", OPTION_INTEGER, &option_fg_plot_style },\ { "plot_bg_quality", OPTION_INTEGER, &option_bg_plot_style },\ -{ "thumbnail_32bpp", OPTION_BOOL, &option_thumbnail_32bpp },\ { "history_tooltip", OPTION_BOOL, &option_history_tooltip }, \ { "scale", OPTION_INTEGER, &option_scale }, \ { "toolbar_show_status", OPTION_BOOL, &option_toolbar_show_status }, \ @@ -141,6 +142,8 @@ bool option_url_suggestion = true; { "font_fantasy", OPTION_STRING, &option_font_fantasy }, \ { "font_default", OPTION_INTEGER, &option_font_default }, \ { "block_popups", OPTION_BOOL, &option_block_popups }, \ -{ "url_suggestion", OPTION_BOOL, &option_url_suggestion } +{ "url_suggestion", OPTION_BOOL, &option_url_suggestion }, \ +{ "image_memory_direct", OPTION_INTEGER, &option_image_memory_direct }, \ +{ "image_memory_compressed",OPTION_INTEGER, &option_image_memory_compressed } #endif diff --git a/riscos/plotters.c b/riscos/plotters.c index a017c12c8..8b3a5a80b 100644 --- a/riscos/plotters.c +++ b/riscos/plotters.c @@ -347,7 +347,8 @@ bool ro_plot_disc(int x, int y, int radius, colour colour) bool ro_plot_bitmap(int x, int y, int width, int height, struct bitmap *bitmap, colour bg) { - return image_redraw(&bitmap->sprite_area, + bitmap_get_buffer(bitmap); + return image_redraw(bitmap->sprite_area, ro_plot_origin_x + x * 2, ro_plot_origin_y - y * 2, width, height, @@ -364,7 +365,8 @@ bool ro_plot_bitmap_tile(int x, int y, int width, int height, struct bitmap *bitmap, colour bg, bool repeat_x, bool repeat_y) { - return image_redraw(&bitmap->sprite_area, + bitmap_get_buffer(bitmap); + return image_redraw(bitmap->sprite_area, ro_plot_origin_x + x * 2, ro_plot_origin_y - y * 2, width, height, diff --git a/riscos/save.c b/riscos/save.c index 139ca08f9..522759061 100644 --- a/riscos/save.c +++ b/riscos/save.c @@ -630,6 +630,7 @@ bool ro_gui_save_complete(struct content *c, char *path) osspriteop_header *sprite_header; char *appname; unsigned int index; + struct bitmap *bitmap; /* Create dir */ error = xosfile_create_dir(path, 0); @@ -663,21 +664,26 @@ bool ro_gui_save_complete(struct content *c, char *path) appname = strrchr(path, '.'); if (!appname) appname = path; - - area = thumbnail_initialise(34, 34, os_MODE8BPP90X90); - if (!area) { - warn_user("NoMemory", 0); + bitmap = bitmap_create(34, 34, false); + if (!bitmap) { + LOG(("Thumbnail initialisation failed.")); + return false; + } + bitmap_set_opaque(bitmap, true); + thumbnail_create(c, bitmap, NULL); + area = thumbnail_convert_8bpp(bitmap); + bitmap_destroy(bitmap); + if (!area) { + LOG(("Thumbnail conversion failed.")); return false; } sprite_header = (osspriteop_header *)(area + 1); + memset(sprite_header->name, 0x00, 12); strncpy(sprite_header->name, appname + 1, 12); /* Paint gets confused with uppercase characters */ for (index = 0; index < 12; index++) sprite_header->name[index] = tolower(sprite_header->name[index]); - thumbnail_create(c, area, - (osspriteop_header *) ((char *) area + 16), - 34, 34); error = xosspriteop_save_sprite_file(osspriteop_NAME, area, buf); free(area); if (error) { diff --git a/riscos/save_draw.c b/riscos/save_draw.c index 5d06d508f..ba4842ca2 100644 --- a/riscos/save_draw.c +++ b/riscos/save_draw.c @@ -1051,7 +1051,7 @@ bool draw_plot_bitmap(int x, int y, int width, int height, drawfile_object *dro; drawfile_sprite *ds; - sprite_length = ((osspriteop_header*)((char*)&bitmap->sprite_area+bitmap->sprite_area.first))->size; + sprite_length = ((osspriteop_header*)((char*)bitmap->sprite_area+bitmap->sprite_area->first))->size; if ((dro = (drawfile_object *)drawbuf_claim(8 + 16 + sprite_length, DrawBuf_eBody)) == NULL) return false; @@ -1065,7 +1065,7 @@ bool draw_plot_bitmap(int x, int y, int width, int height, ds->bbox.x1 = (x + width) * 512; ds->bbox.y1 = (draw_plot_origin_y - y) * 512; - memcpy((char*)ds+16, (char*)&bitmap->sprite_area+bitmap->sprite_area.first, (unsigned)sprite_length); + memcpy((char*)ds+16, (char*)bitmap->sprite_area+bitmap->sprite_area->first, (unsigned)sprite_length); return true; } diff --git a/riscos/thumbnail.c b/riscos/thumbnail.c index c0c667a1d..123e84d37 100644 --- a/riscos/thumbnail.c +++ b/riscos/thumbnail.c @@ -3,7 +3,7 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> */ /** \file @@ -20,8 +20,11 @@ #include "oslib/osfile.h" #include "oslib/osspriteop.h" #include "netsurf/content/content.h" +#include "netsurf/content/url_store.h" #include "netsurf/desktop/plotters.h" +#include "netsurf/image/bitmap.h" #include "netsurf/render/font.h" +#include "netsurf/riscos/bitmap.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/thumbnail.h" @@ -46,9 +49,11 @@ struct thumbnail_save_area { /* Internal prototypes */ +static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap); static void thumbnail_test(void); -static struct thumbnail_save_area* thumbnail_switch_output(osspriteop_area *sprite_area, - osspriteop_header *sprite_header); +static struct thumbnail_save_area* thumbnail_switch_output( + osspriteop_area *sprite_area, + osspriteop_header *sprite_header); static void thumbnail_restore_output(struct thumbnail_save_area *save_area); @@ -56,257 +61,213 @@ static void thumbnail_restore_output(struct thumbnail_save_area *save_area); * Create a thumbnail of a page. * * \param content content structure to thumbnail - * \param area sprite area containing thumbnail sprite - * \param sprite pointer to sprite - * \param width sprite width / pixels - * \param height sprite height / pixels - * - * The thumbnail is rendered in the given sprite. + * \param bitmap the bitmap to draw to + * \param url the URL the thumnail belongs to, or NULL */ -void thumbnail_create(struct content *content, osspriteop_area *area, - osspriteop_header *sprite, int width, int height) { +bool thumbnail_create(struct content *content, struct bitmap *bitmap, + const char *url) { float scale = 1.0; - osspriteop_area *temp_area = NULL; struct thumbnail_save_area *save_area; - osspriteop_area *render_area = NULL; - osspriteop_header *render_sprite = sprite; - - /* Check for 32bpp support in case we've been called for a sprite - we didn't set up. - */ - if (thumbnail_32bpp_available == -1) thumbnail_test(); - - /* Get a secondary holder for non-32bpp sprites as we get a better quality by - going to a 32bpp sprite and then down to an [n]bpp one. - */ - if ((thumbnail_32bpp_available == 1) && - (sprite->mode != (os_mode)tinct_SPRITE_MODE)) { - temp_area = thumbnail_initialise( - width, height, - (os_mode)0x301680b5); - render_area = temp_area; - } - if (temp_area == NULL) { - render_area = area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + _kernel_oserror *error; + + /* check if we have access to 32bpp sprites natively */ + if (thumbnail_32bpp_available == -1) + thumbnail_test(); + + /* if we don't support 32bpp sprites then we redirect to an 8bpp + * image and then convert back. */ + if (thumbnail_32bpp_available != 1) { + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return false; + sprite_header = (osspriteop_header *)(sprite_area + 1); } else { - render_sprite = (osspriteop_header *)(temp_area + 1); + bitmap_get_buffer(bitmap); + sprite_area = bitmap->sprite_area; + sprite_header = (osspriteop_header *)(sprite_area + 1); } - /* Calculate the scale - */ - if (content->width) scale = (float) width / (float) content->width; - - /* Set up plotters - */ + /* set up the plotters */ plot = ro_plotters; ro_plot_origin_x = 0; - ro_plot_origin_y = height * 2; + ro_plot_origin_y = bitmap->height * 2; + if (content->width) + scale = (float)bitmap->width / (float)content->width; ro_plot_set_scale(scale); - current_redraw_browser = NULL; /* no selection */ - /* Switch output and redraw - */ - save_area = thumbnail_switch_output(render_area, render_sprite); + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); if (save_area == NULL) { - if (temp_area) free(temp_area); - return; + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; } + rufl_invalidate_cache(); colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG, os_ACTION_OVERWRITE, 0); os_clg(); - rufl_invalidate_cache(); - content_redraw(content, 0, 0, width, height, - 0, 0, width, height, scale, 0xFFFFFF); + content_redraw(content, 0, 0, bitmap->width, bitmap->height, + 0, 0, bitmap->width, bitmap->height, scale, 0xFFFFFF); thumbnail_restore_output(save_area); rufl_invalidate_cache(); - /* Go back from 32bpp to [n]bpp if we should. - */ - if (temp_area != NULL) { - save_area = thumbnail_switch_output(area, sprite); - if (save_area != NULL) { - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - (char *)(temp_area + 1), 0, 0, - tinct_ERROR_DIFFUSE); - thumbnail_restore_output(save_area); - } - free(temp_area); + /* if we changed to 8bpp then go back to 32bpp */ + if (thumbnail_32bpp_available != 1) { + bitmap_get_buffer(bitmap); + error = _swix(Tinct_ConvertSprite, _INR(2,3), + sprite_header, + (osspriteop_header *)(bitmap->sprite_area + 1)); + free(sprite_area); + if (error) + return false; } + + /* register the thumbnail with the URL */ + if (url) + url_store_add_thumbnail(url, bitmap); + + bitmap_modified(bitmap); + bitmap->persistent = true; + return true; } /** - * Initialises a sprite. + * Convert a bitmap to 8bpp. * - * The sprite background cleared to white. - * Any necessary palette data is set up to the default palette. - * The sprite name is set to "thumbnail". + * \param bitmap the bitmap to convert + * \return a sprite area containing an 8bpp sprite + */ +osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap) { + struct thumbnail_save_area *save_area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return NULL; + sprite_header = (osspriteop_header *)(sprite_area + 1); + + + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); + if (save_area == NULL) { + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; + } + _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), + (osspriteop_header *)(bitmap->sprite_area + 1), + 0, 0, + tinct_ERROR_DIFFUSE); + thumbnail_restore_output(save_area); + + return sprite_area; +} + + +/** + * Creates an 8bpp canvas. * - * @param width The sprite width - * @param height The sprite height - * @param mode The preferred mode (0x301680b5 or os_MODE8BPP90X90) - * @return + * \param bitmap the bitmap to clone the size of + * \return a sprite area containing an 8bpp sprite */ -osspriteop_area* thumbnail_initialise(int width, int height, os_mode mode) { +osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) { unsigned int area_size; - unsigned int remaining_bytes; - osspriteop_area *sprite_area; - osspriteop_header *sprite_header; - char *sprite_image; - - /* Check if we can use 32bpp sprites if we haven't already. By - doing it this way we don't need to allocate lot of memory - first which will probably not be available on machines that - can't handle such sprites.. - */ - if (thumbnail_32bpp_available == -1) thumbnail_test(); - - /* If we can't handle 32bpp then we get 8bpp. - */ - if (thumbnail_32bpp_available != 1) mode = os_MODE8BPP90X90; - - /* Calculate our required memory - */ - area_size = sizeof(osspriteop_area) + sizeof(osspriteop_header); - if (mode == (os_mode)0x301680b5) { - area_size += width * height * 4; - } else { - area_size += ((width + 3) & ~3) * height + 2048; - } + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; - /* Try to get enough memory - */ - if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { - LOG(("Insufficient memory to create thumbnail.")); + /* clone the sprite */ + area_size = sizeof(osspriteop_area) + + sizeof(osspriteop_header) + + ((bitmap->width + 3) & ~3) * bitmap->height + + 2048; + sprite_area = (osspriteop_area *)malloc(area_size); + if (!sprite_area) { + LOG(("no memory for malloc()")); return NULL; } - - /* Initialise the sprite area - */ sprite_area->size = area_size; sprite_area->sprite_count = 1; sprite_area->first = 16; sprite_area->used = area_size; - - /* Initialise the sprite header. We can't trust OS_SpriteOp to - set up our palette properly due to insane legacy 8bpp palettes, - so we do it all manually. - */ sprite_header = (osspriteop_header *)(sprite_area + 1); sprite_header->size = area_size - sizeof(osspriteop_area); memset(sprite_header->name, 0x00, 12); - strcpy(sprite_header->name, "thumbnail"); + strcpy(sprite_header->name, "bitmap"); sprite_header->left_bit = 0; - sprite_header->height = height - 1; - sprite_header->mode = mode; - if (mode == (os_mode)0x301680b5) { - sprite_header->right_bit = 31; - sprite_header->width = width - 1; - sprite_header->image = sizeof(osspriteop_header); - sprite_header->mask = sizeof(osspriteop_header); - - /* Clear to white, full opacity - */ - sprite_image = ((char *)sprite_header) + sprite_header->image; - memset(sprite_image, 0xff, area_size - sizeof(osspriteop_area) - - sizeof(osspriteop_header)); - } else { - sprite_header->right_bit = ((width << 3) - 1) & 31; - sprite_header->width = ((width + 3) >> 2) - 1; - sprite_header->image = sizeof(osspriteop_header) + 2048; - sprite_header->mask = sizeof(osspriteop_header) + 2048; - - /* Create the palette. We don't read the necessary size - like we really should as we know it's going to have - 256 entries of 8 bytes = 2048. - */ - xcolourtrans_read_palette((osspriteop_area *)mode, (osspriteop_id)0, + sprite_header->height = bitmap->height - 1; + sprite_header->mode = os_MODE8BPP90X90; + sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31; + sprite_header->width = ((bitmap->width + 3) >> 2) - 1; + sprite_header->image = sizeof(osspriteop_header) + 2048; + sprite_header->mask = sizeof(osspriteop_header) + 2048; + + /* create the palette. we don't read the necessary size like + * we really should as we know it's going to have 256 entries + * of 8 bytes = 2048. */ + xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90, + (osspriteop_id)0, (os_palette *)(sprite_header + 1), 2048, - (colourtrans_palette_flags)(1 << 1), &remaining_bytes); - - /* Clear to white - */ - sprite_image = ((char *)sprite_header) + sprite_header->image; - memset(sprite_image, 0xff, area_size - sizeof(osspriteop_area) - - sizeof(osspriteop_header) - 2048); - } - - /* Return our sprite area - */ + (colourtrans_palette_flags)(1 << 1), 0); return sprite_area; } -/* - * Checks to see whether 32bpp sprites are available. Rather than - * using Wimp_ReadSysInfo we test if 32bpp sprites are available in - * case the user has a 3rd party patch to enable them. +/** + * Check to see whether 32bpp sprites are available. + * + * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available + * in case the user has a 3rd party patch to enable them. */ static void thumbnail_test(void) { unsigned int area_size; osspriteop_area *sprite_area; - /* If we're configured not to use 32bpp then we don't - */ - if (!option_thumbnail_32bpp) { - thumbnail_32bpp_available = 0; - return; - } - - /* Get enough memory for a 1x1 32bpp sprite - */ + /* try to create a 1x1 32bpp sprite */ area_size = sizeof(osspriteop_area) + sizeof(osspriteop_header) + sizeof(int); if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { LOG(("Insufficient memory to perform sprite test.")); return; } - - /* Initialise the sprite area - */ sprite_area->size = area_size + 1; sprite_area->sprite_count = 0; sprite_area->first = 16; sprite_area->used = 16; - - /* Try to create a 32bpp sprite - */ if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, - "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) { + "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) thumbnail_32bpp_available = 0; - } else { + else thumbnail_32bpp_available = 1; - } - - /* Free our memory - */ free(sprite_area); } -/* Switches output to the specified sprite and returns the previous context. -*/ -static struct thumbnail_save_area* thumbnail_switch_output(osspriteop_area *sprite_area, - osspriteop_header *sprite_header) { +/** + * Switches output to the specified sprite and returns the previous context. + */ +static struct thumbnail_save_area* thumbnail_switch_output( + osspriteop_area *sprite_area, + osspriteop_header *sprite_header) { struct thumbnail_save_area *save_area; int size; - /* Create a save area - */ + /* create a save area */ save_area = calloc(sizeof(struct thumbnail_save_area), 1); if (save_area == NULL) return NULL; - /* Allocate OS_SpriteOp save area - */ + /* allocate OS_SpriteOp save area */ if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area, (osspriteop_id)sprite_header, &size)) { free(save_area); return NULL; } - /* Create the save area - */ + /* create the save area */ save_area->save_area = malloc((unsigned)size); if (save_area->save_area == NULL) { free(save_area); @@ -314,8 +275,7 @@ static struct thumbnail_save_area* thumbnail_switch_output(osspriteop_area *spri } save_area->save_area->a[0] = 0; - /* Switch output to sprite - */ + /* switch output to sprite */ if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area, (osspriteop_id)sprite_header, save_area->save_area, 0, &save_area->context1, &save_area->context2, @@ -328,20 +288,17 @@ static struct thumbnail_save_area* thumbnail_switch_output(osspriteop_area *spri } -/* Restores output to the specified context, and destroys it. -*/ +/** + * Restores output to the specified context, and destroys it. + */ static void thumbnail_restore_output(struct thumbnail_save_area *save_area) { - /* We don't care if we err, as there's nothing we can do about it - */ + /* we don't care if we err, as there's nothing we can do about it */ xosspriteop_switch_output_to_sprite(osspriteop_PTR, (osspriteop_area *)save_area->context1, (osspriteop_id)save_area->context2, (osspriteop_save_area *)save_area->context3, 0, 0, 0, 0); - - /* Free our workspace - */ free(save_area->save_area); free(save_area); } diff --git a/riscos/thumbnail.h b/riscos/thumbnail.h index 429e14fa8..6943f2bbb 100644 --- a/riscos/thumbnail.h +++ b/riscos/thumbnail.h @@ -3,6 +3,7 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> */ /** \file @@ -10,7 +11,8 @@ */ #include "oslib/osspriteop.h" +#include "netsurf/image/bitmap.h" -void thumbnail_create(struct content *content, osspriteop_area *area, - osspriteop_header *sprite, int width, int height); -osspriteop_area* thumbnail_initialise(int width, int height, os_mode mode); +bool thumbnail_create(struct content *content, struct bitmap *bitmap, + const char *url); +osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap); diff --git a/riscos/treeview.c b/riscos/treeview.c index d2096a2ed..5a1a77752 100644 --- a/riscos/treeview.c +++ b/riscos/treeview.c @@ -2,7 +2,7 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> */ /** \file @@ -20,8 +20,12 @@ #include "oslib/osbyte.h" #include "oslib/osspriteop.h" #include "oslib/wimp.h" +#include "netsurf/content/url_store.h" +#include "netsurf/desktop/browser.h" #include "netsurf/desktop/tree.h" +#include "netsurf/riscos/bitmap.h" #include "netsurf/riscos/gui.h" +#include "netsurf/riscos/image.h" #include "netsurf/riscos/menus.h" #include "netsurf/riscos/theme.h" #include "netsurf/riscos/tinct.h" @@ -38,6 +42,7 @@ static bool ro_gui_tree_initialise_sprite(const char *name, int number); static void ro_gui_tree_launch_selected_node(struct node *node, bool all); static bool ro_gui_tree_launch_node(struct node *node); +static void tree_handle_node_changed_callback(void *p); /* an array of sprite addresses for Tinct */ static char *ro_gui_tree_sprites[2]; @@ -61,6 +66,12 @@ static wimp_icon_create ro_gui_tree_edit_icon; /* dragging information */ static char ro_gui_tree_drag_name[12]; +/* callback update */ +struct node_update { + struct tree *tree; + struct node *node; +}; + /** * Performs any initialisation for tree rendering @@ -181,6 +192,10 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) { os_error *error; int temp; int toolbar_height = 0; + struct node_element *url_element; + struct bitmap *bitmap = NULL; + struct node_update *update; + char *frame; assert(tree); assert(element); @@ -265,6 +280,50 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) { ro_gui_tree_icon.data.indirected_sprite.size = strlen(element->sprite->name); break; + case NODE_ELEMENT_THUMBNAIL: + url_element = tree_find_element(element->parent, TREE_ELEMENT_URL); + if (url_element) + bitmap = url_store_get_thumbnail(url_element->text); + if (bitmap) { + frame = bitmap_get_buffer(bitmap); + if (!frame) + url_store_add_thumbnail(url_element->text, NULL); + if ((!frame) || (element->box.width == 0)) { + update = calloc(sizeof(struct node_update), 1); + if (!update) + return; + update->tree = tree; + update->node = element->parent; + schedule(0, tree_handle_node_changed_callback, + update); + return; + } + image_redraw(bitmap->sprite_area, + ro_gui_tree_origin_x + element->box.x + 2, + ro_gui_tree_origin_y - element->box.y, + bitmap->width, bitmap->height, + bitmap->width, bitmap->height, + 0xffffff, + false, false, false, + IMAGE_PLOT_TINCT_OPAQUE); + tree_draw_line(tree, element->box.x, + element->box.y, + element->box.width - 1, + 0); + tree_draw_line(tree, element->box.x, + element->box.y, + 0, + element->box.height - 3); + tree_draw_line(tree, element->box.x, + element->box.y + element->box.height - 3, + element->box.width - 1, + 0); + tree_draw_line(tree, element->box.x + element->box.width - 1, + element->box.y, + 0, + element->box.height - 3); + } + return; } error = xwimp_plot_icon(&ro_gui_tree_icon); @@ -276,6 +335,14 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) { } +void tree_handle_node_changed_callback(void *p) { + struct node_update *update = p; + + tree_handle_node_changed(update->tree, update->node, true, false); + free(update); +} + + /** * Draws an elements expansion icon * @@ -342,6 +409,8 @@ void tree_recalculate_node_element(struct node_element *element) { int sprite_width; int sprite_height; osspriteop_flags flags; + struct bitmap *bitmap = NULL; + struct node_element *url_element; assert(element); @@ -384,6 +453,17 @@ void tree_recalculate_node_element(struct node_element *element) { if (element->box.height < TREE_TEXT_HEIGHT) element->box.height = TREE_TEXT_HEIGHT; break; + case NODE_ELEMENT_THUMBNAIL: + url_element = tree_find_element(element->parent, TREE_ELEMENT_URL); + if (url_element) + bitmap = url_store_get_thumbnail(url_element->text); + if (bitmap) { + element->box.width = bitmap->width * 2 + 2; + element->box.height = bitmap->height * 2 + 4; + } else { + element->box.width = 0; + element->box.height = 0; + } } } @@ -502,7 +582,6 @@ void tree_update_URL_node(struct node *node) { element->user_data); element->text = strdup(buffer); } - } diff --git a/riscos/treeview.h b/riscos/treeview.h index 053709f66..40ee3fbe1 100644 --- a/riscos/treeview.h +++ b/riscos/treeview.h @@ -16,6 +16,7 @@ #include "oslib/osspriteop.h" #include "oslib/wimp.h" #include "netsurf/desktop/tree.h" +#include "netsurf/image/bitmap.h" #define TREE_TEXT_HEIGHT 40 #define TREE_SPRITE_WIDTH 40 /* text plus sprite entries only */ |