[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
This commit is contained in:
Richard Wilson 2005-06-23 17:24:23 +00:00
parent b88a81b9d9
commit f559054c1a
12 changed files with 337 additions and 313 deletions

View File

@ -17,7 +17,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unixlib/features.h> //#include <unixlib/features.h>
#include <unixlib/local.h> #include <unixlib/local.h>
#include "oslib/font.h" #include "oslib/font.h"
#include "oslib/help.h" #include "oslib/help.h"
@ -45,7 +45,9 @@
#include "netsurf/render/box.h" #include "netsurf/render/box.h"
#include "netsurf/render/font.h" #include "netsurf/render/font.h"
#include "netsurf/render/html.h" #include "netsurf/render/html.h"
#include "netsurf/riscos/bitmap.h"
#include "netsurf/riscos/buffer.h" #include "netsurf/riscos/buffer.h"
#include "netsurf/riscos/filename.h"
#include "netsurf/riscos/global_history.h" #include "netsurf/riscos/global_history.h"
#include "netsurf/riscos/gui.h" #include "netsurf/riscos/gui.h"
#include "netsurf/riscos/help.h" #include "netsurf/riscos/help.h"
@ -109,7 +111,7 @@
int os_version = 0; 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 __dynamic_da_max_size = 128 * 1024 * 1024; /**< For UnixLib. */
int __feature_imagefs_is_file = 1; /**< For UnixLib. */ int __feature_imagefs_is_file = 1; /**< For UnixLib. */
/* default filename handling */ /* 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", 0);
xosfile_create_dir("<User$Path>.Choices.NetSurf.Choices.Themes", 0); xosfile_create_dir("<User$Path>.Choices.NetSurf.Choices.Themes", 0);
#endif #endif
ro_filename_initialise();
#ifdef WITH_SAVE_COMPLETE #ifdef WITH_SAVE_COMPLETE
save_complete_init(); save_complete_init();
@ -283,6 +286,7 @@ void gui_init(int argc, char** argv)
ro_gui_choose_language(); ro_gui_choose_language();
bitmap_initialise_memory();
url_store_load("Choices:WWW.NetSurf.URL"); url_store_load("Choices:WWW.NetSurf.URL");
nsdir_temp = getenv("NetSurf$Dir"); nsdir_temp = getenv("NetSurf$Dir");
@ -584,7 +588,8 @@ void gui_init2(int argc, char** argv)
void gui_quit(void) 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_window_quit();
ro_gui_global_history_save(); ro_gui_global_history_save();
ro_gui_hotlist_save(); ro_gui_hotlist_save();
@ -655,7 +660,8 @@ void gui_poll(bool active)
xhourglass_off(); xhourglass_off();
if (active) { if (active) {
event = wimp_poll(mask, &block, 0); 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(); os_t t = os_read_monotonic_time();
if (gui_track) if (gui_track)
@ -686,6 +692,9 @@ void gui_poll(bool active)
if (gui_reformat_pending && event == wimp_NULL_REASON_CODE) if (gui_reformat_pending && event == wimp_NULL_REASON_CODE)
ro_gui_window_process_reformats(); 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->event = event;
q->block = calloc(1, sizeof(*block)); q->block = calloc(1, sizeof(*block));
if (!q->block) { if (!q->block) {
free(q); free(q);
LOG(("Insufficient memory for calloc")); LOG(("Insufficient memory for calloc"));
warn_user("NoMemory", 0); warn_user("NoMemory", 0);
return; return;
@ -903,7 +912,7 @@ void ro_gui_redraw_window_request(wimp_draw *redraw)
else if ((g = ro_gui_window_lookup(redraw->w)) != NULL) else if ((g = ro_gui_window_lookup(redraw->w)) != NULL)
ro_gui_window_redraw(g, redraw); ro_gui_window_redraw(g, redraw);
else if ((g = ro_gui_toolbar_lookup(redraw->w)) != NULL) { 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); ro_gui_theme_redraw(g->toolbar, redraw);
else if ((g->toolbar->editor) && else if ((g->toolbar->editor) &&
(g->toolbar->editor->toolbar_handle == redraw->w)) (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)) (hotlist_tree->toolbar->editor->toolbar_handle == pointer->w))
ro_gui_tree_toolbar_click(pointer, hotlist_tree); ro_gui_tree_toolbar_click(pointer, hotlist_tree);
else if ((global_history_tree) && (global_history_tree->toolbar) && 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); ro_gui_tree_toolbar_click(pointer, global_history_tree);
else if ((global_history_tree) && (global_history_tree->toolbar) && else if ((global_history_tree) && (global_history_tree->toolbar) &&
(global_history_tree->toolbar->editor) && (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 == } else if ((hotlist_tree) && ((wimp_w)hotlist_tree->handle ==
message->data.data_xfer.w)) { message->data.data_xfer.w)) {
if (!title) { if (!title) {
tree_edit = true; tree_edit = true;
title = url; title = url;
} }
ro_gui_tree_get_tree_coordinates(hotlist_tree, ro_gui_tree_get_tree_coordinates(hotlist_tree,
message->data.data_xfer.pos.x, message->data.data_xfer.pos.x,

View File

@ -3,6 +3,7 @@
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license * http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net> * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 Richard Wilson <info@tinct.net>
*/ */
/** \file /** \file
@ -16,12 +17,17 @@
#include "oslib/colourtrans.h" #include "oslib/colourtrans.h"
#include "oslib/font.h" #include "oslib/font.h"
#include "oslib/wimp.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/options.h"
#include "netsurf/riscos/gui.h" #include "netsurf/riscos/gui.h"
#include "netsurf/riscos/thumbnail.h" #include "netsurf/riscos/thumbnail.h"
#include "netsurf/riscos/tinct.h" #include "netsurf/riscos/tinct.h"
#include "netsurf/riscos/wimp.h" #include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h" #include "netsurf/utils/utils.h"
#define SIZE 10 #define SIZE 10
@ -45,7 +51,7 @@ struct history_entry {
struct history_entry *forward_last; /**< Last child. */ struct history_entry *forward_last; /**< Last child. */
unsigned int children; /**< Number of children. */ unsigned int children; /**< Number of children. */
int x, y, width; 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. */ /** 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) void history_add(struct history *history, struct content *content, char *frag_id)
{ {
url_func_result res;
struct history_entry *entry; struct history_entry *entry;
char *url; char *url;
char *title; char *title;
char *split; char *split;
int width; int width;
osspriteop_area *area; struct bitmap *bitmap;
// os_error *error;
if (!history) if (!history)
return; return;
/* allocate space */ /* allocate space */
entry = malloc(sizeof *entry); 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); title = strdup(content->title ? content->title : url);
if (!entry || !url || !title) { if (!entry || !url || !title) {
warn_user("NoMemory", 0); 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->forward = entry->forward_pref = entry->forward_last = 0;
entry->children = 0; entry->children = 0;
entry->width = width / 400; entry->width = width / 400;
entry->sprite_area = 0; entry->bitmap = 0;
if (history->current) { if (history->current) {
if (history->current->forward_last) if (history->current->forward_last)
history->current->forward_last->next = entry; 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; history->current = entry;
/* area = malloc(SPRITE_SIZE); /* if we have a thumbnail, don't update until the page has finished
if (!area) { * loading */
LOG(("malloc failed")); bitmap = url_store_get_thumbnail(url);
return; 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);
} }
entry->bitmap = bitmap;
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;
}
thumbnail_create(content, area,
(osspriteop_header *) (area + 1),
WIDTH / 2, HEIGHT / 2);
/* xosspriteop_save_sprite_file(osspriteop_NAME,
area, "thumbnail");*/
entry->sprite_area = area;
} }
@ -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) 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; return;
thumbnail_create(content, history->current->sprite_area, thumbnail_create(content, history->current->bitmap, NULL);
(osspriteop_header *)
(history->current->sprite_area + 1),
WIDTH / 2, HEIGHT / 2);
} }
@ -248,7 +238,6 @@ void history_free_entry(struct history_entry *entry)
if (entry->frag_id) if (entry->frag_id)
free(entry->frag_id); free(entry->frag_id);
free(entry->title); free(entry->title);
free(entry->sprite_area);
free(entry); 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, -WIDTH - 1, 0);
os_plot(os_PLOT_SOLID | os_PLOT_BY, 0, HEIGHT + 1); os_plot(os_PLOT_SOLID | os_PLOT_BY, 0, HEIGHT + 1);
if (he->sprite_area) { if (he->bitmap) {
osspriteop_area *area = he->sprite_area; if (bitmap_get_buffer(he->bitmap)) {
osspriteop_header *header = (osspriteop_header *)(area + 1); image_redraw(he->bitmap->sprite_area,
osspriteop_trans_tab *table; x0 + he->x * FULL_WIDTH + MARGIN,
y0 - he->y * FULL_HEIGHT - MARGIN,
/* Because we're supporting people with OS3.1 we need to check if the he->bitmap->width, he->bitmap->height,
sprite we have is a legacy 256 colour one he->bitmap->width, he->bitmap->height,
*/ 0xffffff,
if (header->mode == (os_mode)tinct_SPRITE_MODE) { false, false, false,
IMAGE_PLOT_TINCT_OPAQUE);
/* 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);
} else { } else {
unsigned int size; url_store_add_thumbnail(he->url, NULL);
os_factors factors; he->bitmap = NULL;
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);
}
} }
} }
if (he == history_current->current) if (he == history_current->current)
wimp_set_font_colours(wimp_COLOUR_WHITE, wimp_COLOUR_RED); wimp_set_font_colours(wimp_COLOUR_WHITE, wimp_COLOUR_RED);
else else

View File

@ -8,6 +8,8 @@
#ifndef _NETSURF_RISCOS_IMAGE_H_ #ifndef _NETSURF_RISCOS_IMAGE_H_
#define _NETSURF_RISCOS_IMAGE_H_ #define _NETSURF_RISCOS_IMAGE_H_
#include "oslib/osspriteop.h"
struct osspriteop_area; struct osspriteop_area;
typedef enum { typedef enum {

View File

@ -31,6 +31,7 @@
#include "netsurf/riscos/wimp.h" #include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h" #include "netsurf/utils/messages.h"
#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h" #include "netsurf/utils/utils.h"
#include "netsurf/utils/utf8.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; struct node *node;
os_error *error; os_error *error;
char url[80]; char url[80];
url_func_result res;
char *norm_url = NULL;
ro_gui_menu_get_window_details(owner, &g, &bw, &c, &t, &tree); 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 */ /* hotlist actions */
case HOTLIST_ADD_URL: case HOTLIST_ADD_URL:
if ((!hotlist_tree) || (!c)) if ((!hotlist_tree) || (!c) || (!c->url))
return false; 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, 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); time(NULL), -1, 0);
free(norm_url);
if (node) { if (node) {
tree_redraw_area(hotlist_tree, tree_redraw_area(hotlist_tree,
node->box.x - NODE_INSTEP, 0, node->box.x - NODE_INSTEP, 0,
@ -1325,6 +1334,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
false, true); false, true);
ro_gui_tree_scroll_visible(hotlist_tree, ro_gui_tree_scroll_visible(hotlist_tree,
&node->data); &node->data);
ro_gui_hotlist_save();
} }
return true; return true;
case HOTLIST_SHOW: case HOTLIST_SHOW:

View File

@ -24,7 +24,6 @@ extern char *option_theme;
extern char *option_language; extern char *option_language;
extern int option_fg_plot_style; /* tinct flagword */ extern int option_fg_plot_style; /* tinct flagword */
extern int option_bg_plot_style; /* tinct flagword */ extern int option_bg_plot_style; /* tinct flagword */
extern bool option_thumbnail_32bpp;
extern bool option_history_tooltip; extern bool option_history_tooltip;
extern int option_scale; extern int option_scale;
extern int option_toolbar_status_width; extern int option_toolbar_status_width;
@ -60,6 +59,8 @@ extern char *option_font_default_bold;
extern char *option_font_default_bold_italic; extern char *option_font_default_bold_italic;
extern bool option_block_popups; extern bool option_block_popups;
extern bool option_url_suggestion; 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 \ #define EXTRA_OPTION_DEFINE \
bool option_use_mouse_gestures = false;\ bool option_use_mouse_gestures = false;\
@ -68,7 +69,6 @@ char *option_theme = 0;\
char *option_language = 0;\ char *option_language = 0;\
int option_fg_plot_style = tinct_ERROR_DIFFUSE;\ int option_fg_plot_style = tinct_ERROR_DIFFUSE;\
int option_bg_plot_style = tinct_DITHER;\ int option_bg_plot_style = tinct_DITHER;\
bool option_thumbnail_32bpp = true;\
bool option_history_tooltip = true; \ bool option_history_tooltip = true; \
int option_scale = 100; \ int option_scale = 100; \
int option_toolbar_status_width = 5000; \ int option_toolbar_status_width = 5000; \
@ -100,7 +100,9 @@ char *option_font_cursive = 0; \
char *option_font_fantasy = 0; \ char *option_font_fantasy = 0; \
int option_font_default = CSS_FONT_FAMILY_SANS_SERIF; \ int option_font_default = CSS_FONT_FAMILY_SANS_SERIF; \
bool option_block_popups = false; \ 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 \ #define EXTRA_OPTION_TABLE \
{ "use_mouse_gestures", OPTION_BOOL, &option_use_mouse_gestures },\ { "use_mouse_gestures", OPTION_BOOL, &option_use_mouse_gestures },\
@ -109,7 +111,6 @@ bool option_url_suggestion = true;
{ "language", OPTION_STRING, &option_language },\ { "language", OPTION_STRING, &option_language },\
{ "plot_fg_quality", OPTION_INTEGER, &option_fg_plot_style },\ { "plot_fg_quality", OPTION_INTEGER, &option_fg_plot_style },\
{ "plot_bg_quality", OPTION_INTEGER, &option_bg_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 }, \ { "history_tooltip", OPTION_BOOL, &option_history_tooltip }, \
{ "scale", OPTION_INTEGER, &option_scale }, \ { "scale", OPTION_INTEGER, &option_scale }, \
{ "toolbar_show_status", OPTION_BOOL, &option_toolbar_show_status }, \ { "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_fantasy", OPTION_STRING, &option_font_fantasy }, \
{ "font_default", OPTION_INTEGER, &option_font_default }, \ { "font_default", OPTION_INTEGER, &option_font_default }, \
{ "block_popups", OPTION_BOOL, &option_block_popups }, \ { "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 #endif

View File

@ -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, bool ro_plot_bitmap(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg) 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_x + x * 2,
ro_plot_origin_y - y * 2, ro_plot_origin_y - y * 2,
width, height, width, height,
@ -364,7 +365,8 @@ bool ro_plot_bitmap_tile(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg, struct bitmap *bitmap, colour bg,
bool repeat_x, bool repeat_y) 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_x + x * 2,
ro_plot_origin_y - y * 2, ro_plot_origin_y - y * 2,
width, height, width, height,

View File

@ -630,6 +630,7 @@ bool ro_gui_save_complete(struct content *c, char *path)
osspriteop_header *sprite_header; osspriteop_header *sprite_header;
char *appname; char *appname;
unsigned int index; unsigned int index;
struct bitmap *bitmap;
/* Create dir */ /* Create dir */
error = xosfile_create_dir(path, 0); error = xosfile_create_dir(path, 0);
@ -663,21 +664,26 @@ bool ro_gui_save_complete(struct content *c, char *path)
appname = strrchr(path, '.'); appname = strrchr(path, '.');
if (!appname) if (!appname)
appname = path; appname = path;
bitmap = bitmap_create(34, 34, false);
area = thumbnail_initialise(34, 34, os_MODE8BPP90X90); if (!bitmap) {
if (!area) { LOG(("Thumbnail initialisation failed."));
warn_user("NoMemory", 0); 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; return false;
} }
sprite_header = (osspriteop_header *)(area + 1); sprite_header = (osspriteop_header *)(area + 1);
memset(sprite_header->name, 0x00, 12);
strncpy(sprite_header->name, appname + 1, 12); strncpy(sprite_header->name, appname + 1, 12);
/* Paint gets confused with uppercase characters */ /* Paint gets confused with uppercase characters */
for (index = 0; index < 12; index++) for (index = 0; index < 12; index++)
sprite_header->name[index] = tolower(sprite_header->name[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); error = xosspriteop_save_sprite_file(osspriteop_NAME, area, buf);
free(area); free(area);
if (error) { if (error) {

View File

@ -1051,7 +1051,7 @@ bool draw_plot_bitmap(int x, int y, int width, int height,
drawfile_object *dro; drawfile_object *dro;
drawfile_sprite *ds; 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) if ((dro = (drawfile_object *)drawbuf_claim(8 + 16 + sprite_length, DrawBuf_eBody)) == NULL)
return false; 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.x1 = (x + width) * 512;
ds->bbox.y1 = (draw_plot_origin_y - y) * 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; return true;
} }

View File

@ -3,7 +3,7 @@
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license * http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net> * 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 /** \file
@ -20,8 +20,11 @@
#include "oslib/osfile.h" #include "oslib/osfile.h"
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "netsurf/content/content.h" #include "netsurf/content/content.h"
#include "netsurf/content/url_store.h"
#include "netsurf/desktop/plotters.h" #include "netsurf/desktop/plotters.h"
#include "netsurf/image/bitmap.h"
#include "netsurf/render/font.h" #include "netsurf/render/font.h"
#include "netsurf/riscos/bitmap.h"
#include "netsurf/riscos/gui.h" #include "netsurf/riscos/gui.h"
#include "netsurf/riscos/options.h" #include "netsurf/riscos/options.h"
#include "netsurf/riscos/thumbnail.h" #include "netsurf/riscos/thumbnail.h"
@ -46,9 +49,11 @@ struct thumbnail_save_area {
/* Internal prototypes /* Internal prototypes
*/ */
static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap);
static void thumbnail_test(void); static void thumbnail_test(void);
static struct thumbnail_save_area* thumbnail_switch_output(osspriteop_area *sprite_area, static struct thumbnail_save_area* thumbnail_switch_output(
osspriteop_header *sprite_header); osspriteop_area *sprite_area,
osspriteop_header *sprite_header);
static void thumbnail_restore_output(struct thumbnail_save_area *save_area); 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. * Create a thumbnail of a page.
* *
* \param content content structure to thumbnail * \param content content structure to thumbnail
* \param area sprite area containing thumbnail sprite * \param bitmap the bitmap to draw to
* \param sprite pointer to sprite * \param url the URL the thumnail belongs to, or NULL
* \param width sprite width / pixels
* \param height sprite height / pixels
*
* The thumbnail is rendered in the given sprite.
*/ */
void thumbnail_create(struct content *content, osspriteop_area *area, bool thumbnail_create(struct content *content, struct bitmap *bitmap,
osspriteop_header *sprite, int width, int height) { const char *url) {
float scale = 1.0; float scale = 1.0;
osspriteop_area *temp_area = NULL;
struct thumbnail_save_area *save_area; struct thumbnail_save_area *save_area;
osspriteop_area *render_area = NULL; osspriteop_area *sprite_area = NULL;
osspriteop_header *render_sprite = sprite; osspriteop_header *sprite_header = NULL;
_kernel_oserror *error;
/* Check for 32bpp support in case we've been called for a sprite /* check if we have access to 32bpp sprites natively */
we didn't set up. if (thumbnail_32bpp_available == -1)
*/ thumbnail_test();
if (thumbnail_32bpp_available == -1) thumbnail_test();
/* Get a secondary holder for non-32bpp sprites as we get a better quality by /* if we don't support 32bpp sprites then we redirect to an 8bpp
going to a 32bpp sprite and then down to an [n]bpp one. * image and then convert back. */
*/ if (thumbnail_32bpp_available != 1) {
if ((thumbnail_32bpp_available == 1) && sprite_area = thumbnail_create_8bpp(bitmap);
(sprite->mode != (os_mode)tinct_SPRITE_MODE)) { if (!sprite_area)
temp_area = thumbnail_initialise( return false;
width, height, sprite_header = (osspriteop_header *)(sprite_area + 1);
(os_mode)0x301680b5);
render_area = temp_area;
}
if (temp_area == NULL) {
render_area = area;
} else { } 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 /* set up the plotters */
*/
if (content->width) scale = (float) width / (float) content->width;
/* Set up plotters
*/
plot = ro_plotters; plot = ro_plotters;
ro_plot_origin_x = 0; 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); ro_plot_set_scale(scale);
current_redraw_browser = NULL; /* no selection */ current_redraw_browser = NULL; /* no selection */
/* Switch output and redraw /* switch output and redraw */
*/ save_area = thumbnail_switch_output(sprite_area, sprite_header);
save_area = thumbnail_switch_output(render_area, render_sprite);
if (save_area == NULL) { if (save_area == NULL) {
if (temp_area) free(temp_area); if (thumbnail_32bpp_available != 1)
return; free(sprite_area);
return false;
} }
rufl_invalidate_cache();
colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG, colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG,
os_ACTION_OVERWRITE, 0); os_ACTION_OVERWRITE, 0);
os_clg(); os_clg();
rufl_invalidate_cache(); content_redraw(content, 0, 0, bitmap->width, bitmap->height,
content_redraw(content, 0, 0, width, height, 0, 0, bitmap->width, bitmap->height, scale, 0xFFFFFF);
0, 0, width, height, scale, 0xFFFFFF);
thumbnail_restore_output(save_area); thumbnail_restore_output(save_area);
rufl_invalidate_cache(); rufl_invalidate_cache();
/* Go back from 32bpp to [n]bpp if we should. /* if we changed to 8bpp then go back to 32bpp */
*/ if (thumbnail_32bpp_available != 1) {
if (temp_area != NULL) { bitmap_get_buffer(bitmap);
save_area = thumbnail_switch_output(area, sprite); error = _swix(Tinct_ConvertSprite, _INR(2,3),
if (save_area != NULL) { sprite_header,
_swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), (osspriteop_header *)(bitmap->sprite_area + 1));
(char *)(temp_area + 1), 0, 0, free(sprite_area);
tinct_ERROR_DIFFUSE); if (error)
thumbnail_restore_output(save_area); return false;
}
free(temp_area);
} }
/* 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. * \param bitmap the bitmap to convert
* Any necessary palette data is set up to the default palette. * \return a sprite area containing an 8bpp sprite
* The sprite name is set to "thumbnail".
*
* @param width The sprite width
* @param height The sprite height
* @param mode The preferred mode (0x301680b5 or os_MODE8BPP90X90)
* @return
*/ */
osspriteop_area* thumbnail_initialise(int width, int height, os_mode mode) { osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap) {
unsigned int area_size; struct thumbnail_save_area *save_area;
unsigned int remaining_bytes; osspriteop_area *sprite_area = NULL;
osspriteop_area *sprite_area; osspriteop_header *sprite_header = NULL;
osspriteop_header *sprite_header;
char *sprite_image;
/* Check if we can use 32bpp sprites if we haven't already. By sprite_area = thumbnail_create_8bpp(bitmap);
doing it this way we don't need to allocate lot of memory if (!sprite_area)
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;
}
/* Try to get enough memory
*/
if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
LOG(("Insufficient memory to create thumbnail."));
return NULL; 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 = (osspriteop_header *)(sprite_area + 1);
sprite_header->size = area_size - sizeof(osspriteop_area);
memset(sprite_header->name, 0x00, 12);
strcpy(sprite_header->name, "thumbnail");
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 /* switch output and redraw */
like we really should as we know it's going to have save_area = thumbnail_switch_output(sprite_area, sprite_header);
256 entries of 8 bytes = 2048. if (save_area == NULL) {
*/ if (thumbnail_32bpp_available != 1)
xcolourtrans_read_palette((osspriteop_area *)mode, (osspriteop_id)0, free(sprite_area);
(os_palette *)(sprite_header + 1), 2048, return false;
(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);
} }
_swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7),
/* Return our sprite area (osspriteop_header *)(bitmap->sprite_area + 1),
*/ 0, 0,
tinct_ERROR_DIFFUSE);
thumbnail_restore_output(save_area);
return sprite_area; return sprite_area;
} }
/* /**
* Checks to see whether 32bpp sprites are available. Rather than * Creates an 8bpp canvas.
* using Wimp_ReadSysInfo we test if 32bpp sprites are available in *
* case the user has a 3rd party patch to enable them. * \param bitmap the bitmap to clone the size of
* \return a sprite area containing an 8bpp sprite
*/
osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) {
unsigned int area_size;
osspriteop_area *sprite_area = NULL;
osspriteop_header *sprite_header = NULL;
/* 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;
}
sprite_area->size = area_size;
sprite_area->sprite_count = 1;
sprite_area->first = 16;
sprite_area->used = area_size;
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, "bitmap");
sprite_header->left_bit = 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), 0);
return sprite_area;
}
/**
* 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) { static void thumbnail_test(void) {
unsigned int area_size; unsigned int area_size;
osspriteop_area *sprite_area; osspriteop_area *sprite_area;
/* If we're configured not to use 32bpp then we don't /* try to create a 1x1 32bpp sprite */
*/
if (!option_thumbnail_32bpp) {
thumbnail_32bpp_available = 0;
return;
}
/* Get enough memory for a 1x1 32bpp sprite
*/
area_size = sizeof(osspriteop_area) + area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) + sizeof(int); sizeof(osspriteop_header) + sizeof(int);
if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
LOG(("Insufficient memory to perform sprite test.")); LOG(("Insufficient memory to perform sprite test."));
return; return;
} }
/* Initialise the sprite area
*/
sprite_area->size = area_size + 1; sprite_area->size = area_size + 1;
sprite_area->sprite_count = 0; sprite_area->sprite_count = 0;
sprite_area->first = 16; sprite_area->first = 16;
sprite_area->used = 16; sprite_area->used = 16;
/* Try to create a 32bpp sprite
*/
if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, 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; thumbnail_32bpp_available = 0;
} else { else
thumbnail_32bpp_available = 1; thumbnail_32bpp_available = 1;
}
/* Free our memory
*/
free(sprite_area); free(sprite_area);
} }
/* Switches output to the specified sprite and returns the previous context. /**
*/ * 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) { static struct thumbnail_save_area* thumbnail_switch_output(
osspriteop_area *sprite_area,
osspriteop_header *sprite_header) {
struct thumbnail_save_area *save_area; struct thumbnail_save_area *save_area;
int size; int size;
/* Create a save area /* create a save area */
*/
save_area = calloc(sizeof(struct thumbnail_save_area), 1); save_area = calloc(sizeof(struct thumbnail_save_area), 1);
if (save_area == NULL) return NULL; 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, if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, &size)) { (osspriteop_id)sprite_header, &size)) {
free(save_area); free(save_area);
return NULL; return NULL;
} }
/* Create the save area /* create the save area */
*/
save_area->save_area = malloc((unsigned)size); save_area->save_area = malloc((unsigned)size);
if (save_area->save_area == NULL) { if (save_area->save_area == NULL) {
free(save_area); 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; 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, if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, save_area->save_area, (osspriteop_id)sprite_header, save_area->save_area,
0, &save_area->context1, &save_area->context2, 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) { 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, xosspriteop_switch_output_to_sprite(osspriteop_PTR,
(osspriteop_area *)save_area->context1, (osspriteop_area *)save_area->context1,
(osspriteop_id)save_area->context2, (osspriteop_id)save_area->context2,
(osspriteop_save_area *)save_area->context3, (osspriteop_save_area *)save_area->context3,
0, 0, 0, 0); 0, 0, 0, 0);
/* Free our workspace
*/
free(save_area->save_area); free(save_area->save_area);
free(save_area); free(save_area);
} }

View File

@ -3,6 +3,7 @@
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license * http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net> * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 Richard Wilson <info@tinct.net>
*/ */
/** \file /** \file
@ -10,7 +11,8 @@
*/ */
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "netsurf/image/bitmap.h"
void thumbnail_create(struct content *content, osspriteop_area *area, bool thumbnail_create(struct content *content, struct bitmap *bitmap,
osspriteop_header *sprite, int width, int height); const char *url);
osspriteop_area* thumbnail_initialise(int width, int height, os_mode mode); osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap);

View File

@ -2,7 +2,7 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/ * This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-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 /** \file
@ -20,8 +20,12 @@
#include "oslib/osbyte.h" #include "oslib/osbyte.h"
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "oslib/wimp.h" #include "oslib/wimp.h"
#include "netsurf/content/url_store.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/tree.h" #include "netsurf/desktop/tree.h"
#include "netsurf/riscos/bitmap.h"
#include "netsurf/riscos/gui.h" #include "netsurf/riscos/gui.h"
#include "netsurf/riscos/image.h"
#include "netsurf/riscos/menus.h" #include "netsurf/riscos/menus.h"
#include "netsurf/riscos/theme.h" #include "netsurf/riscos/theme.h"
#include "netsurf/riscos/tinct.h" #include "netsurf/riscos/tinct.h"
@ -38,6 +42,7 @@
static bool ro_gui_tree_initialise_sprite(const char *name, int number); 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 void ro_gui_tree_launch_selected_node(struct node *node, bool all);
static bool ro_gui_tree_launch_node(struct node *node); 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 */ /* an array of sprite addresses for Tinct */
static char *ro_gui_tree_sprites[2]; static char *ro_gui_tree_sprites[2];
@ -61,6 +66,12 @@ static wimp_icon_create ro_gui_tree_edit_icon;
/* dragging information */ /* dragging information */
static char ro_gui_tree_drag_name[12]; 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 * 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; os_error *error;
int temp; int temp;
int toolbar_height = 0; int toolbar_height = 0;
struct node_element *url_element;
struct bitmap *bitmap = NULL;
struct node_update *update;
char *frame;
assert(tree); assert(tree);
assert(element); 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 = ro_gui_tree_icon.data.indirected_sprite.size =
strlen(element->sprite->name); strlen(element->sprite->name);
break; 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); 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 * Draws an elements expansion icon
* *
@ -342,6 +409,8 @@ void tree_recalculate_node_element(struct node_element *element) {
int sprite_width; int sprite_width;
int sprite_height; int sprite_height;
osspriteop_flags flags; osspriteop_flags flags;
struct bitmap *bitmap = NULL;
struct node_element *url_element;
assert(element); assert(element);
@ -384,6 +453,17 @@ void tree_recalculate_node_element(struct node_element *element) {
if (element->box.height < TREE_TEXT_HEIGHT) if (element->box.height < TREE_TEXT_HEIGHT)
element->box.height = TREE_TEXT_HEIGHT; element->box.height = TREE_TEXT_HEIGHT;
break; 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->user_data);
element->text = strdup(buffer); element->text = strdup(buffer);
} }
} }

View File

@ -16,6 +16,7 @@
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "oslib/wimp.h" #include "oslib/wimp.h"
#include "netsurf/desktop/tree.h" #include "netsurf/desktop/tree.h"
#include "netsurf/image/bitmap.h"
#define TREE_TEXT_HEIGHT 40 #define TREE_TEXT_HEIGHT 40
#define TREE_SPRITE_WIDTH 40 /* text plus sprite entries only */ #define TREE_SPRITE_WIDTH 40 /* text plus sprite entries only */