summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscos/gui.c27
-rw-r--r--riscos/history.c133
-rw-r--r--riscos/image.h2
-rw-r--r--riscos/menus.c14
-rw-r--r--riscos/options.h13
-rw-r--r--riscos/plotters.c6
-rw-r--r--riscos/save.c20
-rw-r--r--riscos/save_draw.c4
-rw-r--r--riscos/thumbnail.c327
-rw-r--r--riscos/thumbnail.h8
-rw-r--r--riscos/treeview.c83
-rw-r--r--riscos/treeview.h1
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 */