r4442 takkaria - in /trunk/hubbub/src/treebuilder: Makefile in_table_body.c modes.h
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 25 03:54:18 2008
New Revision: 4442
URL: http://source.netsurf-browser.org?rev=4442&view=rev
Log:
Add the "in table body" insertion mode.
Added:
trunk/hubbub/src/treebuilder/in_table_body.c (with props)
Modified:
trunk/hubbub/src/treebuilder/Makefile
trunk/hubbub/src/treebuilder/modes.h
Modified: trunk/hubbub/src/treebuilder/Makefile
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/Makefile?r...
==============================================================================
--- trunk/hubbub/src/treebuilder/Makefile (original)
+++ trunk/hubbub/src/treebuilder/Makefile Wed Jun 25 03:54:18 2008
@@ -35,7 +35,7 @@
SRCS_$(d) := treebuilder.c \
initial.c before_html.c before_head.c in_head.c \
in_head_noscript.c after_head.c in_body.c \
- in_caption.c in_column_group.c \
+ in_caption.c in_column_group.c in_table_body.c \
generic_rcdata.c script_collect.c
# Append to sources for component
Added: trunk/hubbub/src/treebuilder/in_table_body.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_table_b...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_table_body.c (added)
+++ trunk/hubbub/src/treebuilder/in_table_body.c Wed Jun 25 03:54:18 2008
@@ -1,0 +1,170 @@
+/*
+ * This file is part of Hubbub.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2008 Andrew Sidwell
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "treebuilder/modes.h"
+#include "treebuilder/internal.h"
+#include "treebuilder/treebuilder.h"
+#include "utils/utils.h"
+
+
+/**
+ * Clear the stack back to a table body context.
+ *
+ * \param treebuilder The treebuilder instance
+ */
+static void table_clear_stack(hubbub_treebuilder *treebuilder)
+{
+ element_type cur_node = treebuilder->context.element_stack[
+ treebuilder->context.current_node].type;
+
+ while (cur_node != TBODY && cur_node != TFOOT &&
+ cur_node != THEAD && cur_node != HTML) {
+ element_type type;
+ void *node;
+
+ if (!element_stack_pop(treebuilder, &type, &node)) {
+ /** \todo errors */
+ }
+
+ cur_node = treebuilder->context.element_stack[
+ treebuilder->context.current_node].type;
+ }
+
+ return;
+}
+
+
+/**
+ * Handle the case common to some start tag and the table end tag cases.
+ *
+ * \param treebuilder The treebuilder instance
+ */
+static bool table_sub_start_or_table_end(hubbub_treebuilder *treebuilder)
+{
+ if (element_in_scope(treebuilder, TBODY, true) ||
+ element_in_scope(treebuilder, THEAD, true) ||
+ element_in_scope(treebuilder, TFOOT, true)) {
+ element_type otype;
+ void *node;
+
+ table_clear_stack(treebuilder);
+
+ /* "Act as if an end tag with the same name as the current
+ * node had been seen" -- this behaviour should be identical
+ * to handling for (tbody/tfoot/thead) end tags in this mode */
+ if (!element_stack_pop(treebuilder, &otype, &node)) {
+ /** \todo errors */
+ }
+
+ treebuilder->context.mode = IN_TABLE;
+
+ return true;
+ } else {
+ /** \todo parse error */
+ }
+
+ return false;
+}
+
+
+/**
+ * Handle tokens in "in column group" insertion mode
+ *
+ * Up to date with the spec as of 25 June 2008
+ *
+ * \param treebuilder The treebuilder instance
+ * \param token The token to process
+ * \return True to reprocess the token, false otherwise
+ */
+bool handle_in_column_group(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token)
+{
+ bool reprocess = false;
+
+ switch (token->type) {
+ case HUBBUB_TOKEN_START_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == TR) {
+ table_clear_stack(treebuilder);
+ insert_element(treebuilder, &token->data.tag);
+ treebuilder->context.mode = IN_ROW;
+ } else if (type == TH || TD) {
+ hubbub_tag tag;
+
+ /** \todo parse error */
+
+ /* Manufacture tr tag */
+ tag.name.type = HUBBUB_STRING_PTR;
+ tag.name.data.ptr = (const uint8_t *) "tr";
+ tag.name.len = SLEN("tr");
+
+ tag.n_attributes = 0;
+ tag.attributes = NULL;
+
+ insert_element(treebuilder, &tag);
+ treebuilder->context.mode = IN_ROW;
+
+ reprocess = true;
+ } else if (type == CAPTION || type == COL ||
+ type == COLGROUP || type == TBODY ||
+ type == TFOOT || type == THEAD) {
+ table_sub_start_or_table_end(treebuilder);
+ } else {
+ reprocess = true;
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_END_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == TBODY || type == TFOOT || type == THEAD) {
+ if (!element_in_scope(treebuilder, type, true)) {
+ /** \todo parse error */
+ /* Ignore the token */
+ } else {
+ element_type otype;
+ void *node;
+
+ table_clear_stack(treebuilder);
+ if (!element_stack_pop(treebuilder, &otype,
+ &node)) {
+ /** \todo errors */
+ }
+
+ treebuilder->context.mode = IN_TABLE;
+ }
+ } else if (type == TABLE) {
+ table_sub_start_or_table_end(treebuilder);
+ } else if (type == BODY || type == CAPTION || type == COL ||
+ type == COLGROUP || type == HTML ||
+ type == TD || type == TH || type == TR) {
+ /** \todo parse error */
+ /* Ignore the token */
+ } else {
+ reprocess = process_in_table(treebuilder, token);
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_CHARACTER:
+ case HUBBUB_TOKEN_COMMENT:
+ case HUBBUB_TOKEN_DOCTYPE:
+ case HUBBUB_TOKEN_EOF:
+ reprocess = process_in_table(treebuilder, token);
+ break;
+ }
+
+ return reprocess;
+}
+
Propchange: trunk/hubbub/src/treebuilder/in_table_body.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/hubbub/src/treebuilder/modes.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/modes.h?re...
==============================================================================
--- trunk/hubbub/src/treebuilder/modes.h (original)
+++ trunk/hubbub/src/treebuilder/modes.h Wed Jun 25 03:54:18 2008
@@ -66,6 +66,8 @@
bool process_in_head(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
+bool process_in_table(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token);
bool process_tag_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
14 years, 9 months
r4441 takkaria - /trunk/hubbub/src/treebuilder/in_column_group.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 25 02:25:50 2008
New Revision: 4441
URL: http://source.netsurf-browser.org?rev=4441&view=rev
Log:
*Really* implement "in column group" insertion mode.
Added:
trunk/hubbub/src/treebuilder/in_column_group.c (with props)
Added: trunk/hubbub/src/treebuilder/in_column_group.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_column_...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_column_group.c (added)
+++ trunk/hubbub/src/treebuilder/in_column_group.c Wed Jun 25 02:25:50 2008
@@ -1,0 +1,97 @@
+/*
+ * This file is part of Hubbub.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2008 Andrew Sidwell
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "treebuilder/modes.h"
+#include "treebuilder/internal.h"
+#include "treebuilder/treebuilder.h"
+#include "utils/utils.h"
+
+
+/**
+ * Handle tokens in "in column group" insertion mode
+ *
+ * \param treebuilder The treebuilder instance
+ * \param token The token to process
+ * \return True to reprocess the token, false otherwise
+ */
+bool handle_in_column_group(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token)
+{
+ bool reprocess = false;
+ bool handled = false;
+
+ switch (token->type) {
+ case HUBBUB_TOKEN_CHARACTER:
+ if (process_characters_expect_whitespace(treebuilder,
+ token, true)) {
+ reprocess = true;
+ }
+ break;
+ case HUBBUB_TOKEN_COMMENT:
+ process_comment_append(treebuilder, token,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+ break;
+ case HUBBUB_TOKEN_DOCTYPE:
+ /** \todo parse error */
+ break;
+ case HUBBUB_TOKEN_START_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == HTML) {
+ /* Process as if "in body" */
+ process_tag_in_body(treebuilder, token);
+ } else if (type == COL) {
+ insert_element_no_push(treebuilder, &token->data.tag);
+
+ /** \todo ack sc flag */
+ } else {
+ reprocess = true;
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_END_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == COLGROUP) {
+ /** \todo fragment case */
+ handled = true;
+ } else if (type == COL) {
+ /** \todo parse error */
+ } else {
+ reprocess = true;
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_EOF:
+ /** \todo fragment case */
+ reprocess = true;
+ break;
+ }
+
+ if (handled || reprocess) {
+ element_type otype;
+ void *node;
+
+ /* Pop the current node (which will be a colgroup) */
+ if (!element_stack_pop(treebuilder, &otype, &node)) {
+ /** \todo errors */
+ }
+
+ treebuilder->context.mode = IN_TABLE;
+ }
+
+ return reprocess;
+}
+
Propchange: trunk/hubbub/src/treebuilder/in_column_group.c
------------------------------------------------------------------------------
svn:eol-style = native
14 years, 9 months
r4440 takkaria - in /trunk/hubbub/src/treebuilder: Makefile modes.h
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 25 02:23:07 2008
New Revision: 4440
URL: http://source.netsurf-browser.org?rev=4440&view=rev
Log:
Implement "in column group" insertion mode.
Modified:
trunk/hubbub/src/treebuilder/Makefile
trunk/hubbub/src/treebuilder/modes.h
Modified: trunk/hubbub/src/treebuilder/Makefile
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/Makefile?r...
==============================================================================
--- trunk/hubbub/src/treebuilder/Makefile (original)
+++ trunk/hubbub/src/treebuilder/Makefile Wed Jun 25 02:23:07 2008
@@ -35,7 +35,7 @@
SRCS_$(d) := treebuilder.c \
initial.c before_html.c before_head.c in_head.c \
in_head_noscript.c after_head.c in_body.c \
- in_caption.c \
+ in_caption.c in_column_group.c \
generic_rcdata.c script_collect.c
# Append to sources for component
Modified: trunk/hubbub/src/treebuilder/modes.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/modes.h?re...
==============================================================================
--- trunk/hubbub/src/treebuilder/modes.h (original)
+++ trunk/hubbub/src/treebuilder/modes.h Wed Jun 25 02:23:07 2008
@@ -57,6 +57,8 @@
const hubbub_token *token);
bool handle_in_caption(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
+bool handle_in_column_group(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token);
bool handle_generic_rcdata(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
bool handle_script_collect_characters(hubbub_treebuilder *treebuilder,
14 years, 9 months
r4439 dynis - in /branches/dynis/libnsgif: libnsgif.c libnsgif.h
by netsurf@semichrome.net
Author: dynis
Date: Wed Jun 25 02:16:48 2008
New Revision: 4439
URL: http://source.netsurf-browser.org?rev=4439&view=rev
Log:
Corrected the implementation of frame disposal methods
Modified:
branches/dynis/libnsgif/libnsgif.c
branches/dynis/libnsgif/libnsgif.h
Modified: branches/dynis/libnsgif/libnsgif.c
URL: http://source.netsurf-browser.org/branches/dynis/libnsgif/libnsgif.c?rev=...
==============================================================================
--- branches/dynis/libnsgif/libnsgif.c (original)
+++ branches/dynis/libnsgif/libnsgif.c Wed Jun 25 02:16:48 2008
@@ -66,9 +66,8 @@
/* TO-DO LIST
=================
- + Correct the usage of the background_action variable, which is actually
- an implementation of the "Disposal Method" flag in the Graphic Control
- Extension.
+ + Plain text and comment extensions could be implemented if there is any
+ interest in doing so.
*/
@@ -82,14 +81,20 @@
*/
#define GIF_PROCESS_COLOURS 0xaa000000
+/* Internal flag that a frame is invalid/unprocessed
+*/
+#define GIF_INVALID_FRAME -1
+
/* Maximum LZW bits available
*/
#define GIF_MAX_LZW 12
/* GIF Flags
*/
-#define GIF_DISPOSE_RESTORE_TO_BG 2
-#define GIF_DISPOSE_RESTORE_TO_PREV 3
+#define GIF_FRAME_COMBINE 1
+#define GIF_FRAME_CLEAR 2
+#define GIF_FRAME_RESTORE 3
+#define GIF_FRAME_QUIRKS_RESTORE 4
#define GIF_IMAGE_SEPARATOR 0x2c
#define GIF_INTERLACE_MASK 0x40
#define GIF_COLOUR_TABLE_MASK 0x80
@@ -188,7 +193,7 @@
*/
gif->frame_count = 0;
gif->frame_count_partial = 0;
- gif->decoded_frame = -1;
+ gif->decoded_frame = GIF_INVALID_FRAME;
/* 6-byte GIF file header is:
*
@@ -224,7 +229,7 @@
gif->colour_table_size = (2 << (gif_data[4] & GIF_COLOUR_TABLE_SIZE_MASK));
gif->background_colour = gif_data[5];
gif->aspect_ratio = gif_data[6];
- gif->dirty_frame = -1;
+ gif->dirty_frame = GIF_INVALID_FRAME;
gif->loop_count = 1;
gif_data += 7;
@@ -368,7 +373,7 @@
/* Invalidate our currently decoded image
*/
- gif->decoded_frame = -1;
+ gif->decoded_frame = GIF_INVALID_FRAME;
return GIF_OK;
}
@@ -445,7 +450,7 @@
/* Invalidate any previous decoding we have of this frame
*/
if (gif->decoded_frame == frame)
- gif->decoded_frame = -1;
+ gif->decoded_frame = GIF_INVALID_FRAME;
/* We pretend to initialise the frames, but really we just skip over all
the data contained within. This is all basically a cut down version of
@@ -508,8 +513,8 @@
/* if we are clearing the background then we need to redraw enough to cover the previous
frame too
*/
- gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
- (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV));
+ gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) ||
+ (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE));
/* Boundary checking - shouldn't ever happen except with junk data
*/
@@ -616,6 +621,13 @@
gif->frames[frame].transparency_index = gif_data[5];
}
gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2);
+ /* I have encountered documentation and GIFs in the wild that use
+ * 0x04 to restore the previous frame, rather than the officially
+ * documented 0x03. I believe some (older?) software may even actually
+ * export this way. We handle this as a type of "quirks" mode.
+ */
+ if (gif->frames[frame].disposal_method == GIF_FRAME_QUIRKS_RESTORE)
+ gif->frames[frame].disposal_method = GIF_FRAME_RESTORE;
gif_data += (2 + gif_data[1]);
break;
@@ -630,11 +642,12 @@
case GIF_EXTENSION_APPLICATION:
if (gif_bytes < 17) return GIF_INSUFFICIENT_FRAME_DATA;
if ((gif_data[1] == 0x0b) &&
- (strncmp((const char *) gif_data + 3,
+ (strncmp((const char *) gif_data + 2,
"NETSCAPE2.0", 11) == 0) &&
(gif_data[13] == 0x03) &&
- (gif_data[14] == 0x01))
+ (gif_data[14] == 0x01)) {
gif->loop_count = gif_data[15] | (gif_data[16] << 8);
+ }
gif_data += (2 + gif_data[1]);
break;
@@ -696,6 +709,7 @@
unsigned int return_value = 0;
unsigned int x, y, decode_y, burst_bytes;
unsigned int block_size;
+ int last_undisposed_frame = (frame - 1);
register unsigned char colour;
/* Ensure this frame is supposed to be decoded
@@ -716,14 +730,14 @@
*/
if (!clear_image) {
if (frame == 0)
- gif->dirty_frame = -1;
+ gif->dirty_frame = GIF_INVALID_FRAME;
if (gif->decoded_frame == gif->dirty_frame) {
clear_image = true;
if (frame != 0)
gif_decode_frame(gif, gif->dirty_frame, bitmap_callbacks);
clear_image = false;
}
- gif->dirty_frame = -1;
+ gif->dirty_frame = GIF_INVALID_FRAME;
}
/* Get the start of our frame data and the end of the GIF data
@@ -736,19 +750,6 @@
* The shortest block of data is a 10-byte image descriptor + 1-byte gif trailer
*/
if (gif_bytes < 12) return GIF_INSUFFICIENT_FRAME_DATA;
-
- /* Clear the previous frame totally. We can't just pretend we've got a smaller
- sprite and clear what we need as some frames have multiple images which would
- produce errors.
- */
- frame_data = (unsigned int *)bitmap_callbacks->bitmap_get_buffer(gif->frame_image);
- if (!frame_data)
- return GIF_INSUFFICIENT_MEMORY;
- if (!clear_image) {
- if ((frame == 0) || (gif->decoded_frame == -1))
- memset((char*)frame_data, 0x00, gif->width * gif->height * sizeof(int));
- gif->decoded_frame = frame;
- }
/* Save the buffer position
*/
@@ -844,6 +845,12 @@
goto gif_decode_frame_exit;
}
+ /* Get the frame data
+ */
+ frame_data = (unsigned int *)bitmap_callbacks->bitmap_get_buffer(gif->frame_image);
+ if (!frame_data)
+ return GIF_INSUFFICIENT_MEMORY;
+
/* If we are clearing the image we just clear, if not decode
*/
if (!clear_image) {
@@ -859,11 +866,36 @@
goto gif_decode_frame_exit;
}
- /* Set our dirty status
- */
- if ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
- (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV))
- gif->dirty_frame = frame;
+ /* If the previous frame's disposal method requires we restore the background
+ * colour or this is the first frame, clear the frame data
+ */
+ if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) {
+ memset((char*)frame_data, colour_table[gif->background_colour], gif->width * gif->height * sizeof(int));
+ } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) {
+ clear_image = true;
+ if ((return_value = gif_decode_frame(gif, (frame - 1), bitmap_callbacks)) != GIF_OK)
+ goto gif_decode_frame_exit;
+ clear_image = false;
+ /* If the previous frame's disposal method requires we restore the previous
+ * image, find the last image set to "do not dispose" and get that frame data
+ */
+ } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_RESTORE)) {
+ while ((last_undisposed_frame != -1) && (gif->frames[--last_undisposed_frame].disposal_method == GIF_FRAME_RESTORE));
+ /* If we don't find one, clear the frame data
+ */
+ if (last_undisposed_frame == -1) {
+ memset((char*)frame_data, colour_table[gif->background_colour], gif->width * gif->height * sizeof(int));
+ } else {
+ if ((return_value = gif_decode_frame(gif, last_undisposed_frame, bitmap_callbacks)) != GIF_OK)
+ goto gif_decode_frame_exit;
+ /* Get this frame's data
+ */
+ frame_data = (unsigned int *)bitmap_callbacks->bitmap_get_buffer(gif->frame_image);
+ if (!frame_data)
+ return GIF_INSUFFICIENT_MEMORY;
+ }
+ }
+ gif->decoded_frame = frame;
/* Initialise the LZW decoding
*/
@@ -921,11 +953,10 @@
} else {
/* Clear our frame
*/
- if ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
- (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV)) {
+ if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) {
for (y = 0; y < height; y++) {
frame_scanline = frame_data + offset_x + ((offset_y + y) * gif->width);
- memset(frame_scanline, 0x00, width * 4);
+ memset(frame_scanline, colour_table[gif->background_colour], width * 4);
}
}
Modified: branches/dynis/libnsgif/libnsgif.h
URL: http://source.netsurf-browser.org/branches/dynis/libnsgif/libnsgif.h?rev=...
==============================================================================
--- branches/dynis/libnsgif/libnsgif.h (original)
+++ branches/dynis/libnsgif/libnsgif.h Wed Jun 25 02:16:48 2008
@@ -48,7 +48,7 @@
bool virgin; /**< whether the frame has previously been used */
bool opaque; /**< whether the frame is totally opaque */
bool redraw_required; /**< whether a forcable screen redraw is required */
- char disposal_method; /**< how the previous frame should be disposed; affects plotting */
+ unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */
bool transparency; /**< whether we acknoledge transparency */
unsigned char transparency_index; /**< the index designating a transparent pixel */
unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */
@@ -99,7 +99,7 @@
unsigned int *local_colour_table; /**< local colour table */
int dirty_frame; /**< the current dirty frame, or -1 for none */
void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */
- gif_result current_error; /**< current error type, or 0 for none*/
+ gif_result current_error; /**< current error type, or 0 for none*/
} gif_animation;
gif_result gif_initialise(struct gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);
14 years, 9 months
r4438 dynis - in /branches/dynis/libnsgif: examples/decode_gif.c libnsgif.c libnsgif.h
by netsurf@semichrome.net
Author: dynis
Date: Tue Jun 24 21:52:49 2008
New Revision: 4438
URL: http://source.netsurf-browser.org?rev=4438&view=rev
Log:
Improved functions handling gif extensions; added several constants for gif flags
Modified:
branches/dynis/libnsgif/examples/decode_gif.c
branches/dynis/libnsgif/libnsgif.c
branches/dynis/libnsgif/libnsgif.h
Modified: branches/dynis/libnsgif/examples/decode_gif.c
URL: http://source.netsurf-browser.org/branches/dynis/libnsgif/examples/decode...
==============================================================================
--- branches/dynis/libnsgif/examples/decode_gif.c (original)
+++ branches/dynis/libnsgif/examples/decode_gif.c Tue Jun 24 21:52:49 2008
@@ -69,8 +69,10 @@
/* begin decoding */
do {
code = gif_initialise(&gif, &bitmap_callbacks);
- if (code != GIF_OK && code != GIF_WORKING)
+ if (code != GIF_OK && code != GIF_WORKING) {
warning("gif_initialise", code);
+ exit(1);
+ }
} while (code != GIF_OK);
printf("P3\n");
Modified: branches/dynis/libnsgif/libnsgif.c
URL: http://source.netsurf-browser.org/branches/dynis/libnsgif/libnsgif.c?rev=...
==============================================================================
--- branches/dynis/libnsgif/libnsgif.c (original)
+++ branches/dynis/libnsgif/libnsgif.c Tue Jun 24 21:52:49 2008
@@ -50,7 +50,7 @@
To decode a frame, the caller must use gif_decode_frame() which updates
the current 'frame_image' to reflect the desired frame. The required
- 'background_action' is also updated to reflect how the frame should be
+ 'disposal_method' is also updated to reflect how the frame should be
plotted. The caller must not assume that the current 'frame_image' will
be valid between calls if initialisation is still occuring, and should
either always request that the frame is decoded (no processing will
@@ -66,25 +66,49 @@
/* TO-DO LIST
=================
- + Merge the gif_initialise_frame_extensions and
- gif_decode_frame_extensions functions, because it seems unnecessary to
- have both.
+ Correct the usage of the background_action variable, which is actually
an implementation of the "Disposal Method" flag in the Graphic Control
Extension.
-/*
-
-
+*/
+
+
+
+
+/* Maximum colour table size
+*/
+#define GIF_MAX_COLOURS 256
+
+/* Internal flag that the colour table needs to be processed
+*/
+#define GIF_PROCESS_COLOURS 0xaa000000
+
+/* Maximum LZW bits available
+*/
+#define GIF_MAX_LZW 12
+
+/* GIF Flags
+*/
+#define GIF_DISPOSE_RESTORE_TO_BG 2
+#define GIF_DISPOSE_RESTORE_TO_PREV 3
+#define GIF_IMAGE_SEPARATOR 0x2c
+#define GIF_INTERLACE_MASK 0x40
+#define GIF_COLOUR_TABLE_MASK 0x80
+#define GIF_COLOUR_TABLE_SIZE_MASK 0x07
+#define GIF_EXTENSION_INTRODUCER 0x21
+#define GIF_EXTENSION_GRAPHIC_CONTROL 0xf9
+#define GIF_DISPOSAL_MASK 0x1c
+#define GIF_TRANSPARENCY_MASK 0x01
+#define GIF_EXTENSION_COMMENT 0xfe
+#define GIF_EXTENSION_PLAIN_TEXT 0x01
+#define GIF_EXTENSION_APPLICATION 0xff
+#define GIF_TRAILER 0x3b
/* Internal GIF routines
*/
-static gif_result gif_initialise_sprite(struct gif_animation *gif, unsigned int width, unsigned int height,
- gif_bitmap_callback_vt *bitmap_callbacks);
+static gif_result gif_initialise_sprite(struct gif_animation *gif, unsigned int width, unsigned int height, gif_bitmap_callback_vt *bitmap_callbacks);
static gif_result gif_initialise_frame(struct gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);
-static gif_result gif_initialise_frame_extensions(struct gif_animation *gif, const int frame,
- unsigned int *background_action_p);
-static gif_result gif_decode_frame_extensions(struct gif_animation *gif, unsigned int *background_action_p,
- unsigned int *flags_p, int *transparency_index_p);
+static gif_result gif_initialise_frame_extensions(struct gif_animation *gif, const int frame);
+static gif_result gif_skip_frame_extensions(struct gif_animation *gif);
static unsigned int gif_interlaced_line(int height, int y);
@@ -168,8 +192,8 @@
/* 6-byte GIF file header is:
*
- * +0 CHAR[2] Signature ('GIF')
- * +3 CHAR[2] Version ('87a' or '89a')
+ * +0 3CHARS Signature ('GIF')
+ * +3 3CHARS Version ('87a' or '89a')
*/
if (strncmp((const char *) gif_data, "GIF", 3) != 0)
return GIF_DATA_ERROR;
@@ -184,20 +208,20 @@
/* 7-byte Logical Screen Descriptor is:
*
- * +6 SHORT Logical Screen Width
- * +8 SHORT Logical Screen Height
- * +10 CHAR __Packed Fields__
- * 1BIT Global Color Table Flag
- * 3BITS Color Resolution
+ * +0 SHORT Logical Screen Width
+ * +2 SHORT Logical Screen Height
+ * +4 CHAR __Packed Fields__
+ * 1BIT Global Colour Table Flag
+ * 3BITS Colour Resolution
* 1BIT Sort Flag
- * 3BITS Size of Global Color Table
- * +11 CHAR Background Color Index
- * +12 CHAR Pixel Aspect Ratio
+ * 3BITS Size of Global Colour Table
+ * +5 CHAR Background Colour Index
+ * +6 CHAR Pixel Aspect Ratio
*/
gif->width = gif_data[0] | (gif_data[1] << 8);
gif->height = gif_data[2] | (gif_data[3] << 8);
- gif->global_colours = (gif_data[4] & 0x80);
- gif->colour_table_size = (2 << (gif_data[4] & 0x07));
+ gif->global_colours = (gif_data[4] & GIF_COLOUR_TABLE_MASK);
+ gif->colour_table_size = (2 << (gif_data[4] & GIF_COLOUR_TABLE_SIZE_MASK));
gif->background_colour = gif_data[5];
gif->aspect_ratio = gif_data[6];
gif->dirty_frame = -1;
@@ -234,7 +258,7 @@
/* Set the first colour to a value that will never occur in reality so we
know if we've processed it
*/
- gif->global_colour_table[0] = 0xaa000000;
+ gif->global_colour_table[0] = GIF_PROCESS_COLOURS;
/* Check if the GIF has no frame data (13-byte header + 1-byte termination block)
* Although generally useless, the GIF specification does not expressly prohibit this
@@ -269,7 +293,7 @@
/* Do the colour map if we haven't already. As the top byte is always 0xff or 0x00
depending on the transparency we know if it's been filled in.
*/
- if (gif->global_colour_table[0] == 0xaa000000) {
+ if (gif->global_colour_table[0] == GIF_PROCESS_COLOURS) {
/* Check for a global colour map signified by bit 7
*/
if (gif->global_colours) {
@@ -366,7 +390,6 @@
unsigned char *gif_data, *gif_end;
int gif_bytes;
unsigned int flags = 0;
- unsigned int background_action;
unsigned int width, height, offset_x, offset_y;
unsigned int block_size, colour_table_size;
bool first_image = true;
@@ -414,6 +437,8 @@
gif->frames[frame].frame_pointer = gif->buffer_position;
gif->frames[frame].display = false;
gif->frames[frame].virgin = true;
+ gif->frames[frame].disposal_method = 0;
+ gif->frames[frame].transparency = false;
gif->frames[frame].frame_delay = 100;
gif->frames[frame].redraw_required = false;
@@ -427,10 +452,10 @@
gif_decode_frame that doesn't have any of the LZW bits in it.
*/
- /* Initialise any extensions occurring prior to image data
+ /* Initialise any extensions
*/
gif->buffer_position = gif_data - gif->gif_data;
- if ((return_value = gif_initialise_frame_extensions(gif, frame, &background_action)) != GIF_OK)
+ if ((return_value = gif_initialise_frame_extensions(gif, frame)) != GIF_OK)
return return_value;
gif_data = (gif->gif_data + gif->buffer_position);
gif_bytes = (gif_end - gif_data);
@@ -447,7 +472,7 @@
/* If we're not done, there should be an image descriptor
*/
- if (gif_data[0] != 0x2c) return GIF_FRAME_DATA_ERROR;
+ if (gif_data[0] != GIF_IMAGE_SEPARATOR) return GIF_FRAME_DATA_ERROR;
/* Do some simple boundary checking
*/
@@ -483,7 +508,8 @@
/* if we are clearing the background then we need to redraw enough to cover the previous
frame too
*/
- gif->frames[frame].redraw_required = ((background_action == 2) || (background_action == 3));
+ gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
+ (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV));
/* Boundary checking - shouldn't ever happen except with junk data
*/
@@ -493,7 +519,7 @@
/* Decode the flags
*/
flags = gif_data[9];
- colour_table_size = 2 << (flags & 0x07);
+ colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
/* Move our data onwards and remember we've got a bit of this frame
*/
@@ -503,7 +529,7 @@
/* Skip the local colour table
*/
- if (flags & 0x80) {
+ if (flags & GIF_COLOUR_TABLE_MASK) {
gif_data += 3 * colour_table_size;
if ((gif_bytes = (gif_end - gif_data)) < 0)
return GIF_INSUFFICIENT_FRAME_DATA;
@@ -551,58 +577,86 @@
@return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
GIF_OK for successful initialisation
*/
-static gif_result gif_initialise_frame_extensions(struct gif_animation *gif, const int frame, unsigned int *background_action_p) {
+static gif_result gif_initialise_frame_extensions(struct gif_animation *gif, const int frame) {
unsigned char *gif_data, *gif_end;
int gif_bytes;
- unsigned int extension_size, block_size;
+ unsigned int block_size;
/* Get our buffer position etc.
*/
gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
- gif_bytes = (gif_end - gif_data);
/* Initialise the extensions
*/
- *background_action_p = 0;
- while (gif_data[0] == 0x21) {
- /* Get the extension size
- */
- extension_size = gif_data[2];
-
- /* Graphic control extension - store the frame delay.
- */
- if (gif_data[1] == 0xf9) {
- if (gif_bytes < 6) return GIF_INSUFFICIENT_FRAME_DATA;
- gif->frames[frame].frame_delay = gif_data[4] | (gif_data[5] << 8);
- *background_action_p = ((gif_data[3] & 0x1c) >> 2);
-
- /* Application extension - handle NETSCAPE2.0 looping
- */
- } else if (gif_data[1] == 0xff) {
- if (gif_bytes < 18) return GIF_INSUFFICIENT_FRAME_DATA;
- if ((gif_data[2] == 0x0b) &&
- (strncmp((const char *) gif_data + 3,
- "NETSCAPE2.0", 11) == 0) &&
- (gif_data[14] == 0x03) &&
- (gif_data[15] == 0x01))
- gif->loop_count = gif_data[16] | (gif_data[17] << 8);
- }
-
- /* Move to the first sub-block
- * Skip 3 bytes for extension introducer, label, and extension size fields
- * Skip the extension size itself
- * The special case here is the comment extension (0xfe) because it has no
- * size field and therefore extension size is not skipped either
- */
- if (gif_data[1] == 0xfe)
- gif_data += 2;
- else
- gif_data += (3 + extension_size);
+ while (gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+ ++gif_data;
+ gif_bytes = (gif_end - gif_data);
+
+ /* Switch on extension label
+ */
+ switch(gif_data[0]) {
+ /* 6-byte Graphic Control Extension is:
+ *
+ * +0 CHAR Graphic Control Label
+ * +1 CHAR Block Size
+ * +2 CHAR __Packed Fields__
+ * 3BITS Reserved
+ * 3BITS Disposal Method
+ * 1BIT User Input Flag
+ * 1BIT Transparent Color Flag
+ * +3 SHORT Delay Time
+ * +5 CHAR Transparent Color Index
+ */
+ case GIF_EXTENSION_GRAPHIC_CONTROL:
+ if (gif_bytes < 6) return GIF_INSUFFICIENT_FRAME_DATA;
+ gif->frames[frame].frame_delay = gif_data[3] | (gif_data[4] << 8);
+ if (gif_data[2] & GIF_TRANSPARENCY_MASK) {
+ gif->frames[frame].transparency = true;
+ gif->frames[frame].transparency_index = gif_data[5];
+ }
+ gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2);
+ gif_data += (2 + gif_data[1]);
+ break;
+
+ /* 14-byte+ Application Extension is:
+ *
+ * +0 CHAR Application Extension Label
+ * +1 CHAR Block Size
+ * +2 8CHARS Application Identifier
+ * +10 3CHARS Appl. Authentication Code
+ * +13 1-256 Application Data (Data sub-blocks)
+ */
+ case GIF_EXTENSION_APPLICATION:
+ if (gif_bytes < 17) return GIF_INSUFFICIENT_FRAME_DATA;
+ if ((gif_data[1] == 0x0b) &&
+ (strncmp((const char *) gif_data + 3,
+ "NETSCAPE2.0", 11) == 0) &&
+ (gif_data[13] == 0x03) &&
+ (gif_data[14] == 0x01))
+ gif->loop_count = gif_data[15] | (gif_data[16] << 8);
+ gif_data += (2 + gif_data[1]);
+ break;
+
+ /* Move the pointer to the first data sub-block
+ * Skip 1 byte for the extension label
+ */
+ case GIF_EXTENSION_COMMENT:
+ ++gif_data;
+ break;
+
+ /* Move the pointer to the first data sub-block
+ * Skip 2 bytes for the extension label and size fields
+ * Skip the extension size itself
+ */
+ default:
+ gif_data += (2 + gif_data[1]);
+ }
/* Repeatedly skip blocks until we get a zero block or run out of data
- * This library does not process this data
- */
+ * This data is ignored by this gif decoder
+ */
+ gif_bytes = (gif_end - gif_data);
block_size = 0;
while (block_size != 1) {
block_size = gif_data[0] + 1;
@@ -638,13 +692,11 @@
unsigned int *colour_table;
unsigned int *frame_data = 0; // Set to 0 for no warnings
unsigned int *frame_scanline;
- unsigned int background_action;
- int transparency_index = -1;
unsigned int save_buffer_position;
unsigned int return_value = 0;
unsigned int x, y, decode_y, burst_bytes;
unsigned int block_size;
- register int colour;
+ register unsigned char colour;
/* Ensure this frame is supposed to be decoded
*/
@@ -703,9 +755,9 @@
save_buffer_position = gif->buffer_position;
gif->buffer_position = gif_data - gif->gif_data;
- /* Decode any extensions occurring prior to image data
- */
- if ((return_value = gif_decode_frame_extensions(gif, &background_action, &flags, &transparency_index)) != GIF_OK)
+ /* Skip any extensions because we all ready processed them
+ */
+ if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK)
goto gif_decode_frame_exit;
gif_data = (gif->gif_data + gif->buffer_position);
gif_bytes = (gif_end - gif_data);
@@ -718,20 +770,20 @@
}
/* 10-byte Image Descriptor is:
- *
- * +0 CHAR Image Separator (0x2c)
- * +1 SHORT Image Left Position
- * +3 SHORT Image Top Position
- * +5 SHORT Width
- * +7 SHORT Height
- * +9 CHAR __Packed Fields__
- * 1BIT Local Color Table Flag
- * 1BIT Interlace Flag
- * 1BIT Sort Flag
- * 2BITS Reserved
- * 3BITS Size of Local Color Table
- */
- if (gif_data[0] != 0x2c) {
+ *
+ * +0 CHAR Image Separator (0x2c)
+ * +1 SHORT Image Left Position
+ * +3 SHORT Image Top Position
+ * +5 SHORT Width
+ * +7 SHORT Height
+ * +9 CHAR __Packed Fields__
+ * 1BIT Local Colour Table Flag
+ * 1BIT Interlace Flag
+ * 1BIT Sort Flag
+ * 2BITS Reserved
+ * 3BITS Size of Local Colour Table
+ */
+ if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
return_value = GIF_DATA_ERROR;
goto gif_decode_frame_exit;
}
@@ -751,8 +803,8 @@
/* Decode the flags
*/
flags = gif_data[9];
- colour_table_size = 2 << (flags & 0x07);
- interlace = flags & 0x40;
+ colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
+ interlace = flags & GIF_INTERLACE_MASK;
/* Move our pointer to the colour table or image data (if no colour table is given)
*/
@@ -761,7 +813,7 @@
/* Set up the colour table
*/
- if (flags & 0x80) {
+ if (flags & GIF_COLOUR_TABLE_MASK) {
if (gif_bytes < (int)(3 * colour_table_size)) {
return_value = GIF_INSUFFICIENT_FRAME_DATA;
goto gif_decode_frame_exit;
@@ -795,21 +847,22 @@
/* If we are clearing the image we just clear, if not decode
*/
if (!clear_image) {
- /* Ensure we have enough data for the 1-byte LZW code size + 1-byte gif trailer
+ /* Ensure we have enough data for a 1-byte LZW code size + 1-byte gif trailer
*/
if (gif_bytes < 2) {
return_value = GIF_INSUFFICIENT_FRAME_DATA;
goto gif_decode_frame_exit;
- /* If we only have the 1-byte LZW code size + 1-byte gif trailer, we're finished
- */
- } else if ((gif_bytes = 2) && (gif_data[1] == GIF_TRAILER)) {
+ /* If we only have a 1-byte LZW code size + 1-byte gif trailer, we're finished
+ */
+ } else if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) {
return_value = GIF_OK;
goto gif_decode_frame_exit;
}
/* Set our dirty status
*/
- if ((background_action == 2) || (background_action == 3))
+ if ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
+ (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV))
gif->dirty_frame = frame;
/* Initialise the LZW decoding
@@ -850,7 +903,10 @@
burst_bytes = x;
x -= burst_bytes;
while (burst_bytes-- > 0) {
- if ((colour = *--stack_pointer) != transparency_index)
+ colour = *--stack_pointer;
+ if (((gif->frames[frame].transparency) &&
+ (colour != gif->frames[frame].transparency_index)) ||
+ (!gif->frames[frame].transparency))
*frame_scanline = colour_table[colour];
frame_scanline++;
}
@@ -865,7 +921,8 @@
} else {
/* Clear our frame
*/
- if ((background_action == 2) || (background_action == 3)) {
+ if ((gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_BG) ||
+ (gif->frames[frame].disposal_method == GIF_DISPOSE_RESTORE_TO_PREV)) {
for (y = 0; y < height; y++) {
frame_scanline = frame_data + offset_x + ((offset_y + y) * gif->width);
memset(frame_scanline, 0x00, width * 4);
@@ -912,56 +969,49 @@
}
-/** Attempts to decode the frame's extensions
+/** Skips the frame's extensions (which have been previously initialised)
@return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
GIF_OK for successful decoding
*/
-static gif_result gif_decode_frame_extensions(struct gif_animation *gif, unsigned int *background_action_p,
- unsigned int *flags_p, int *transparency_index_p) {
- unsigned int extension_size, block_size;
+static gif_result gif_skip_frame_extensions(struct gif_animation *gif) {
unsigned char *gif_data, *gif_end;
int gif_bytes;
+ unsigned int block_size;
/* Get our buffer position etc.
*/
gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
gif_bytes = (gif_end - gif_data);
-
- /* Decode the extensions
- */
- *background_action_p = 0;
- while (gif_data[0] == 0x21) {
-
- /* Get the extension size
- */
- extension_size = gif_data[2];
-
- /* Graphic control extension - store the frame delay.
- */
- if (gif_data[1] == 0xf9) {
- if (gif_bytes < 7)
- return GIF_INSUFFICIENT_FRAME_DATA;
- *flags_p = gif_data[3];
- if (*flags_p & 0x01) *transparency_index_p = gif_data[6];
- *background_action_p = ((*flags_p & 0x1c) >> 2);
- }
-
- /* Move to the first sub-block
- * Skip 3 bytes for extension introducer, label, and extension size fields
- * Skip the extension size itself
- * The special case here is the comment extension (0xfe) because it has no
- * size field and therefore extension size is not skipped either
- */
- if (gif_data[1] == 0xfe)
- gif_data += 2;
- else
- gif_data += (3 + extension_size);
-
+
+ /* Skip the extensions
+ */
+ while (gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+ ++gif_data;
+
+ /* Switch on extension label
+ */
+ switch(gif_data[0]) {
+ /* Move the pointer to the first data sub-block
+ * 1 byte for the extension label
+ */
+ case GIF_EXTENSION_COMMENT:
+ ++gif_data;
+ break;
+
+ /* Move the pointer to the first data sub-block
+ * 2 bytes for the extension label and size fields
+ * Skip the extension size itself
+ */
+ default:
+ gif_data += (2 + gif_data[1]);
+ }
+
/* Repeatedly skip blocks until we get a zero block or run out of data
- * This library does not process this data
- */
+ * This data is ignored by this gif decoder
+ */
+ gif_bytes = (gif_end - gif_data);
block_size = 0;
while (block_size != 1) {
block_size = gif_data[0] + 1;
Modified: branches/dynis/libnsgif/libnsgif.h
URL: http://source.netsurf-browser.org/branches/dynis/libnsgif/libnsgif.h?rev=...
==============================================================================
--- branches/dynis/libnsgif/libnsgif.h (original)
+++ branches/dynis/libnsgif/libnsgif.h Tue Jun 24 21:52:49 2008
@@ -39,18 +39,6 @@
GIF_FRAME_NO_DISPLAY = -6
} gif_result;
-/* Maximum colour table size
-*/
-#define GIF_MAX_COLOURS 256
-
-/* Maximum LZW bits available
-*/
-#define GIF_MAX_LZW 12
-
-/* 1-byte GIF Trailer "[indicates] the end of the GIF Data Stream" (fixed value: 0x3b)
-*/
-#define GIF_TRAILER 0x3b
-
/* The GIF frame data
*/
typedef struct gif_frame {
@@ -60,6 +48,9 @@
bool virgin; /**< whether the frame has previously been used */
bool opaque; /**< whether the frame is totally opaque */
bool redraw_required; /**< whether a forcable screen redraw is required */
+ char disposal_method; /**< how the previous frame should be disposed; affects plotting */
+ bool transparency; /**< whether we acknoledge transparency */
+ unsigned char transparency_index; /**< the index designating a transparent pixel */
unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */
unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */
unsigned int redraw_width; /**< width of redraw rectangle */
@@ -108,7 +99,7 @@
unsigned int *local_colour_table; /**< local colour table */
int dirty_frame; /**< the current dirty frame, or -1 for none */
void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */
- int current_error; /**< current error type, or 0 for none*/
+ gif_result current_error; /**< current error type, or 0 for none*/
} gif_animation;
gif_result gif_initialise(struct gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);
14 years, 9 months
r4437 adamblokus - in /branches/adamblokus/netsurf: Makefile.sources desktop/print.c pdf/pdf_plotters.c render/loosen.c render/loosen.h
by netsurf@semichrome.net
Author: adamblokus
Date: Tue Jun 24 19:44:46 2008
New Revision: 4437
URL: http://source.netsurf-browser.org?rev=4437&view=rev
Log:
Added skeleton of applying loose layout.
Minor code cleaning-up.
Added:
branches/adamblokus/netsurf/render/loosen.c
branches/adamblokus/netsurf/render/loosen.h
Modified:
branches/adamblokus/netsurf/Makefile.sources
branches/adamblokus/netsurf/desktop/print.c
branches/adamblokus/netsurf/pdf/pdf_plotters.c
Modified: branches/adamblokus/netsurf/Makefile.sources
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/Makefile.so...
==============================================================================
--- branches/adamblokus/netsurf/Makefile.sources (original)
+++ branches/adamblokus/netsurf/Makefile.sources Tue Jun 24 19:44:46 2008
@@ -60,7 +60,9 @@
# S_PDF are sources of the pdf plotter + the ones for paged-printing
S_PDF := pdf_plotters.c
S_PRINT := print.c
-S_PDF := $(addprefix pdf/,$(S_PDF)) $(addprefix desktop/,$(S_PRINT))
+S_LOOSE := loosen.c
+S_PDF := $(addprefix pdf/,$(S_PDF)) $(addprefix desktop/,$(S_PRINT)) \
+ $(addprefix render/,$(S_LOOSE))
# Some extra rules for building the scanner etc.
css/css_enum.c css/css_enum.h: css/css_enums css/makeenum
Modified: branches/adamblokus/netsurf/desktop/print.c
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/desktop/pri...
==============================================================================
--- branches/adamblokus/netsurf/desktop/print.c (original)
+++ branches/adamblokus/netsurf/desktop/print.c Tue Jun 24 19:44:46 2008
@@ -21,13 +21,11 @@
#include "content/content.h"
#include "utils/log.h"
+#include "render/loosen.h"
+
static struct content *print_init(struct content *);
static bool print_apply_settings(struct content *, struct print_settings *);
static bool print_cleanup(struct content *, struct printer *);
-
-bool print_run(struct content *, struct printer *, struct print_settings *);
-
-struct print_settings *print_make_settings(print_configuration configuration);
static float content_width, content_height;
Modified: branches/adamblokus/netsurf/pdf/pdf_plotters.c
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/pdf/pdf_plo...
==============================================================================
--- branches/adamblokus/netsurf/pdf/pdf_plotters.c (original)
+++ branches/adamblokus/netsurf/pdf/pdf_plotters.c Tue Jun 24 19:44:46 2008
@@ -21,7 +21,7 @@
#include "desktop/plotters.h"
#include "desktop/print.h"
-
+#include "pdf/pdf_plotters.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "image/bitmap.h"
@@ -65,12 +65,7 @@
static HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content);
-bool pdf_begin(struct print_settings* settings);
-bool pdf_next_page();
-void pdf_end();
-
-
-void error_handler (HPDF_STATUS error_no, HPDF_STATUS detail_no,
+static void error_handler (HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data);
static void pdf_plot_grid(int x_dist,int y_dist,unsigned int colour);
Added: branches/adamblokus/netsurf/render/loosen.c
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/render/loos...
==============================================================================
--- branches/adamblokus/netsurf/render/loosen.c (added)
+++ branches/adamblokus/netsurf/render/loosen.c Tue Jun 24 19:44:46 2008
@@ -1,0 +1,120 @@
+/*
+ * Copyright 2008 Adam Blokus <adamblokus(a)gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdbool.h>
+#include "render/box.h"
+#include "content/content.h"
+
+
+bool loosen_document_layout(struct content *content, struct box *layout,
+ int width, int height);
+static bool loosen_line(struct box *first, int *width, int *y,
+ int cx, int cy, struct box *cont, bool indent,
+ bool has_text_children,
+ struct content *content, struct box **next_box);
+static bool loosen_table(struct box *box, int available_width,
+ struct content *content);
+static bool loosen_block_context(struct box *block, struct content *content);
+static bool loosen_inline_container(struct box *inline_container, int width,
+ struct box *cont, int cx, int cy,
+ struct content *content);
+
+static bool loosen_make_block_element(struct box *box, int width,
+ struct content *content);
+
+static bool loosen_shrink_object(struct box* box, int width);
+
+/**
+Main loosing procedure
+*/
+bool loosen_document_layout(struct content *content, struct box *layout,
+ int width, int height){
+ bool width_fits = false;
+
+ /* Optional try - if the current layout is not more than xx% to wide,
+ * maybe we scale the content to preserve the original layout
+ */
+
+ /*pass 1 - obvious changes: break too long words, move absolute
+ * positioned objects into the visibile scope of width
+ */
+
+ /*Check if pass 1 was enough - if re-layouting doesn't give
+ *us the right width, go on to pass 2
+ */
+
+ /* pass 2 - break table rows, change the display of some elements to
+ * block
+ */
+ if (!width_fits){
+ }
+
+ return true;
+}
+
+/** Primarily - break too wide words into pieces.
+*/
+bool loosen_line(struct box *first, int *width, int *y,
+ int cx, int cy, struct box *cont, bool indent,
+ bool has_text_children,
+ struct content *content, struct box **next_box){
+ return true;
+}
+
+/**
+Try first the unavoidable changes (too wide words etc.).
+If this isn't enough - try breaking too wide rows into narrower ones.
+In the most extreme case - the table has no influence on the width
+ (each row is broken into one-cell rows)
+*/
+bool loosen_table(struct box *box, int available_width,
+ struct content *content){
+ return true;
+}
+
+/**
+Recursively loosen children
+*/
+bool loosen_block_context(struct box *block, struct content *content){
+ return true;
+}
+
+/**
+Recursively loosen children
+*/
+bool loosen_inline_container(struct box *inline_container, int width,
+ struct box *cont, int cx, int cy, struct content *content){
+ return true;
+}
+
+/**
+Change absolute and relative positioned elements into block elements
+in case they are positioned to far to the rigth
+*/
+bool loosen_make_block_element(struct box *box, int width,
+ struct content *content){
+ return true;
+}
+
+/**
+Shrink an object (esp. an image) to fit the page-width
+\note Not sure wheter it won't be better for images to be cropped
+*/
+bool loosen_shrink_object(struct box* box, int width ){
+ return true;
+}
Added: branches/adamblokus/netsurf/render/loosen.h
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/render/loos...
==============================================================================
--- branches/adamblokus/netsurf/render/loosen.h (added)
+++ branches/adamblokus/netsurf/render/loosen.h Tue Jun 24 19:44:46 2008
@@ -1,0 +1,35 @@
+/*
+ * Copyright 2008 Adam Blokus <adamblokus(a)gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+\file
+General idea - a set of routines working themselves recursively through
+the box tree and trying to change the layout of the document as little
+as possible to acquire the desired width ( - to make it fit in a printed
+page ), where possible - also taking the dividing height into consideration,
+to prevent objects being cut by ends of pages.
+*/
+
+#ifndef NETSURF_RENDER_LOOSEN_H
+#define NETSURF_RENDER_LOOSEN_H
+#include <stdbool.h>
+
+bool loosen_document_layout(struct content *content, struct box *layout,
+ int width, int height);
+
+#endif
14 years, 9 months
r4436 takkaria - in /trunk/hubbub/src/treebuilder: Makefile in_caption.c modes.h
by netsurf@semichrome.net
Author: takkaria
Date: Tue Jun 24 18:42:13 2008
New Revision: 4436
URL: http://source.netsurf-browser.org?rev=4436&view=rev
Log:
Add "in caption" insertion mode.
Added:
trunk/hubbub/src/treebuilder/in_caption.c (with props)
Modified:
trunk/hubbub/src/treebuilder/Makefile
trunk/hubbub/src/treebuilder/modes.h
Modified: trunk/hubbub/src/treebuilder/Makefile
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/Makefile?r...
==============================================================================
--- trunk/hubbub/src/treebuilder/Makefile (original)
+++ trunk/hubbub/src/treebuilder/Makefile Tue Jun 24 18:42:13 2008
@@ -35,6 +35,7 @@
SRCS_$(d) := treebuilder.c \
initial.c before_html.c before_head.c in_head.c \
in_head_noscript.c after_head.c in_body.c \
+ in_caption.c \
generic_rcdata.c script_collect.c
# Append to sources for component
Added: trunk/hubbub/src/treebuilder/in_caption.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_caption...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_caption.c (added)
+++ trunk/hubbub/src/treebuilder/in_caption.c Tue Jun 24 18:42:13 2008
@@ -1,0 +1,100 @@
+/*
+ * This file is part of Hubbub.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2008 Andrew Sidwell
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "treebuilder/modes.h"
+#include "treebuilder/internal.h"
+#include "treebuilder/treebuilder.h"
+#include "utils/utils.h"
+
+
+/**
+ * Handle tokens in "in caption" insertion mode
+ *
+ * \param treebuilder The treebuilder instance
+ * \param token The token to process
+ * \return True to reprocess the token, false otherwise
+ */
+bool handle_in_caption(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token)
+{
+ bool reprocess = false;
+ bool handled = false;
+
+ switch (token->type) {
+ case HUBBUB_TOKEN_START_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == CAPTION || type == COL || type == COLGROUP ||
+ type == TBODY || type == TD || type == TFOOT ||
+ type == TH || type == THEAD || type == TR) {
+ /** \todo parse error */
+ handled = true;
+ } else {
+ /* Process as if "in body" */
+ process_tag_in_body(treebuilder, token);
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_END_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+
+ if (type == CAPTION || type == TABLE) {
+ /** \todo parse error if type == TABLE */
+ handled = true;
+ } else if (type == BODY || type == COL || type == COLGROUP ||
+ type == HTML || type == TBODY || type == TD ||
+ type == TFOOT || type == TH ||
+ type == THEAD || type == TR) {
+ /** \todo parse error */
+ } else {
+ /* Process as if "in body" */
+ process_tag_in_body(treebuilder, token);
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_CHARACTER:
+ case HUBBUB_TOKEN_COMMENT:
+ case HUBBUB_TOKEN_DOCTYPE:
+ case HUBBUB_TOKEN_EOF:
+ /* Process as if "in body" */
+ process_tag_in_body(treebuilder, token);
+
+ break;
+ }
+
+ if (handled || reprocess) {
+ element_type otype = UNKNOWN;
+ void *node;
+
+ /** \todo fragment case */
+
+ close_implied_end_tags(treebuilder, UNKNOWN);
+
+
+ while (otype != CAPTION) {
+ /** \todo parse error */
+
+ if (!element_stack_pop(treebuilder, &otype, &node)) {
+ /** \todo errors */
+ }
+ }
+
+ clear_active_formatting_list_to_marker(treebuilder);
+
+ treebuilder->context.mode = IN_TABLE;
+ }
+
+ return reprocess;
+}
+
Propchange: trunk/hubbub/src/treebuilder/in_caption.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/hubbub/src/treebuilder/modes.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/modes.h?re...
==============================================================================
--- trunk/hubbub/src/treebuilder/modes.h (original)
+++ trunk/hubbub/src/treebuilder/modes.h Tue Jun 24 18:42:13 2008
@@ -55,6 +55,8 @@
const hubbub_token *token);
bool handle_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
+bool handle_in_caption(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token);
bool handle_generic_rcdata(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
bool handle_script_collect_characters(hubbub_treebuilder *treebuilder,
14 years, 9 months
r4435 takkaria - /trunk/hubbub/src/treebuilder/treebuilder.c
by netsurf@semichrome.net
Author: takkaria
Date: Tue Jun 24 18:41:42 2008
New Revision: 4435
URL: http://source.netsurf-browser.org?rev=4435&view=rev
Log:
Update the list of implied end tags.
Modified:
trunk/hubbub/src/treebuilder/treebuilder.c
Modified: trunk/hubbub/src/treebuilder/treebuilder.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/treebuilde...
==============================================================================
--- trunk/hubbub/src/treebuilder/treebuilder.c (original)
+++ trunk/hubbub/src/treebuilder/treebuilder.c Tue Jun 24 18:41:42 2008
@@ -795,18 +795,20 @@
* Close implied end tags
*
* \param treebuilder The treebuilder instance
- * \param except Tag type to exclude from processing [DD,DT,LI,P],
- * or UNKNOWN to exclude nothing
- */
-void close_implied_end_tags(hubbub_treebuilder *treebuilder,
+ * \param except Tag type to exclude from processing [DD,DT,LI,OPTION,
+ * OPTGROUP,P,RP,RT], UNKNOWN to exclude nothing
+ */
+void close_implied_end_tags(hubbub_treebuilder *treebuilder,
element_type except)
{
element_type type;
type = treebuilder->context.element_stack[
treebuilder->context.current_node].type;
-
- while (type == DD || type == DT || type == LI || type == P) {
+
+ while (type == DD || type == DT || type == LI || type == OPTION ||
+ type == OPTGROUP || type == P || type == RP ||
+ type == RT) {
element_type otype;
void *node;
14 years, 9 months
r4434 takkaria - in /trunk/hubbub/src/treebuilder: after_head.c in_body.c in_body.h in_head.c in_head_noscript.c modes.h
by netsurf@semichrome.net
Author: takkaria
Date: Tue Jun 24 16:48:09 2008
New Revision: 4434
URL: http://source.netsurf-browser.org?rev=4434&view=rev
Log:
Make everything that is meant to have processing equivalent to "in head" use the same code.
Removed:
trunk/hubbub/src/treebuilder/in_body.h
Modified:
trunk/hubbub/src/treebuilder/after_head.c
trunk/hubbub/src/treebuilder/in_body.c
trunk/hubbub/src/treebuilder/in_head.c
trunk/hubbub/src/treebuilder/in_head_noscript.c
trunk/hubbub/src/treebuilder/modes.h
Modified: trunk/hubbub/src/treebuilder/after_head.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/after_head...
==============================================================================
--- trunk/hubbub/src/treebuilder/after_head.c (original)
+++ trunk/hubbub/src/treebuilder/after_head.c Tue Jun 24 16:48:09 2008
@@ -67,19 +67,9 @@
}
- /* This should be identical to handling "in head" */
- if (type == BASE || type == LINK || type == META) {
- /** \todo ack sc flag */
- process_base_link_meta_in_head(treebuilder,
- token, type);
- } else if (type == SCRIPT) {
- process_script_in_head(treebuilder, token);
- } else if (type == STYLE || type == NOFRAMES) {
- parse_generic_rcdata(treebuilder, token, false);
- } else if (type == TITLE) {
- parse_generic_rcdata(treebuilder, token, true);
- }
+ /* Process as "in head" */
+ reprocess = process_in_head(treebuilder, token);
if (!element_stack_pop(treebuilder, &otype, &node)) {
/** \todo errors */
Modified: trunk/hubbub/src/treebuilder/in_body.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_body.c?...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_body.c (original)
+++ trunk/hubbub/src/treebuilder/in_body.c Tue Jun 24 16:48:09 2008
@@ -8,7 +8,9 @@
#include <assert.h>
#include <string.h>
-#include "treebuilder/in_body.h"
+#include "treebuilder/modes.h"
+#include "treebuilder/internal.h"
+#include "treebuilder/treebuilder.h"
#include "utils/utils.h"
#undef DEBUG_IN_BODY
@@ -248,21 +250,11 @@
if (type == HTML) {
process_html_in_body(treebuilder, token);
} else if (type == BASE || type == COMMAND ||
- type == EVENT_SOURCE || type == LINK) {
- process_base_link_meta_in_head(treebuilder, token, type);
-
- /** \todo ack sc flag */
- } else if (type == META) {
- process_base_link_meta_in_head(treebuilder, token, type);
-
- /** \todo ack sc flag */
- /** \todo detect charset */
- } else if (type == SCRIPT) {
- process_script_in_head(treebuilder, token);
- } else if (type == NOFRAMES || type == STYLE) {
- parse_generic_rcdata(treebuilder, token, false);
- } else if (type == TITLE) {
- parse_generic_rcdata(treebuilder, token, true);
+ type == EVENT_SOURCE || type == LINK ||
+ type == META || type == NOFRAMES || type == SCRIPT ||
+ type == STYLE || type == TITLE) {
+ /* Process as "in head" */
+ process_in_head(treebuilder, token);
} else if (type == BODY) {
process_body_in_body(treebuilder, token);
} else if (type == ADDRESS || type == ARTICLE || type == ASIDE ||
Removed: trunk/hubbub/src/treebuilder/in_body.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_body.h?...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_body.h (original)
+++ trunk/hubbub/src/treebuilder/in_body.h (removed)
@@ -1,18 +1,0 @@
-/*
- * This file is part of Hubbub.
- * Licensed under the MIT License,
- * http://www.opensource.org/licenses/mit-license.php
- * Copyright 2008 John-Mark Bell <jmb(a)netsurf-browser.org>
- */
-
-#ifndef hubbub_treebuilder_in_body_h_
-#define hubbub_treebuilder_in_body_h_
-
-#include "treebuilder/internal.h"
-
-bool handle_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token);
-bool process_tag_in_body(hubbub_treebuilder *treebuilder,
- const hubbub_token *token);
-
-#endif
-
Modified: trunk/hubbub/src/treebuilder/in_head.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_head.c?...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_head.c (original)
+++ trunk/hubbub/src/treebuilder/in_head.c Tue Jun 24 16:48:09 2008
@@ -117,3 +117,17 @@
return reprocess;
}
+
+
+/**
+ * Process a tag as if in the "in head" state.
+ *
+ * \param treebuilder The treebuilder instance
+ * \param token The token to process
+ * \return True to reprocess the token, false otherwise
+ */
+bool process_in_head(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token)
+{
+ return handle_in_head(treebuilder, token);
+}
Modified: trunk/hubbub/src/treebuilder/in_head_noscript.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/in_head_no...
==============================================================================
--- trunk/hubbub/src/treebuilder/in_head_noscript.c (original)
+++ trunk/hubbub/src/treebuilder/in_head_noscript.c Tue Jun 24 16:48:09 2008
@@ -29,15 +29,10 @@
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- /* This should be equivalent to "in head" processing */
- reprocess = process_characters_expect_whitespace(treebuilder,
- token, true);
+ reprocess = process_in_head(treebuilder, token);
break;
case HUBBUB_TOKEN_COMMENT:
- /* This should be equivalent to "in head" processing */
- process_comment_append(treebuilder, token,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node);
+ reprocess = process_in_head(treebuilder, token);
break;
case HUBBUB_TOKEN_DOCTYPE:
/** \todo parse error */
@@ -52,26 +47,10 @@
process_tag_in_body(treebuilder, token);
} else if (type == NOSCRIPT) {
handled = true;
- } else if (type == LINK) {
- /* This should be equivalent to "in head" processing */
- process_base_link_meta_in_head(treebuilder,
- token, type);
-
- /** \todo ack sc flag */
- } else if (type == META) {
- /* This should be equivalent to "in head" processing */
- process_base_link_meta_in_head(treebuilder,
- token, type);
-
- /** \todo ack sc flag */
-
- /** \todo detect charset */
- } else if (type == NOFRAMES) {
- /* This should be equivalent to "in head" processing */
- parse_generic_rcdata(treebuilder, token, true);
- } else if (type == STYLE) {
- /* This should be equivalent to "in head" processing */
- parse_generic_rcdata(treebuilder, token, false);
+ } else if (type == LINK || type == META || type == NOFRAMES ||
+ type == STYLE) {
+ /* Process as "in head" */
+ reprocess = process_in_head(treebuilder, token);
} else if (type == HEAD || type == NOSCRIPT) {
/** \todo parse error */
} else {
Modified: trunk/hubbub/src/treebuilder/modes.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/modes.h?re...
==============================================================================
--- trunk/hubbub/src/treebuilder/modes.h (original)
+++ trunk/hubbub/src/treebuilder/modes.h Tue Jun 24 16:48:09 2008
@@ -60,6 +60,8 @@
bool handle_script_collect_characters(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
+bool process_in_head(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token);
bool process_tag_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
14 years, 9 months
r4433 mikeL - /branches/mikeL/netsurf/gtk/res/netsurf.glade
by netsurf@semichrome.net
Author: mikeL
Date: Mon Jun 23 22:25:33 2008
New Revision: 4433
URL: http://source.netsurf-browser.org?rev=4433&view=rev
Log:
Added accelerator to 'Select All'
Modified:
branches/mikeL/netsurf/gtk/res/netsurf.glade
Modified: branches/mikeL/netsurf/gtk/res/netsurf.glade
URL: http://source.netsurf-browser.org/branches/mikeL/netsurf/gtk/res/netsurf....
==============================================================================
--- branches/mikeL/netsurf/gtk/res/netsurf.glade (original)
+++ branches/mikeL/netsurf/gtk/res/netsurf.glade Mon Jun 23 22:25:33 2008
@@ -232,6 +232,7 @@
<property name="label">gtk-select-all</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
+ <accelerator key="a" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -329,9 +330,9 @@
<property name="visible">True</property>
<property name="label" translatable="yes">Zoom _in</property>
<property name="use_underline">True</property>
+ <accelerator key="equal" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <accelerator key="KP_Add" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<accelerator key="plus" modifiers="GDK_CONTROL_MASK" signal="activate"/>
- <accelerator key="KP_Add" modifiers="GDK_CONTROL_MASK" signal="activate"/>
- <accelerator key="equal" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image564">
<property name="visible">True</property>
@@ -346,8 +347,8 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Normal size</property>
<property name="use_underline">True</property>
+ <accelerator key="KP_0" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<accelerator key="0" modifiers="GDK_CONTROL_MASK" signal="activate"/>
- <accelerator key="KP_0" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image565">
<property name="visible">True</property>
@@ -362,8 +363,8 @@
<property name="visible">True</property>
<property name="label" translatable="yes">Zoom _out</property>
<property name="use_underline">True</property>
+ <accelerator key="KP_Subtract" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<accelerator key="minus" modifiers="GDK_CONTROL_MASK" signal="activate"/>
- <accelerator key="KP_Subtract" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image566">
<property name="visible">True</property>
@@ -801,25 +802,17 @@
<placeholder/>
</child>
<child>
- <widget class="GtkHSeparator" id="hseparator3">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVScrollbar" id="coreScrollVertical">
- <property name="visible">True</property>
- <property name="adjustment">0 0 100 1 10 0</property>
+ <widget class="GtkStatusbar" id="statusbar1">
+ <property name="height_request">1</property>
+ <property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
@@ -858,17 +851,25 @@
</packing>
</child>
<child>
- <widget class="GtkStatusbar" id="statusbar1">
- <property name="height_request">1</property>
- <property name="visible">True</property>
+ <widget class="GtkVScrollbar" id="coreScrollVertical">
+ <property name="visible">True</property>
+ <property name="adjustment">0 0 100 1 10 0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator3">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
</packing>
</child>
</widget>
@@ -912,18 +913,75 @@
<property name="column_spacing">11</property>
<property name="row_spacing">10</property>
<child>
- <widget class="GtkEntry" id="entryLoginUser">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="text" translatable="yes">sesame</property>
+ <widget class="GtkLabel" id="labelLoginHost">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">moo.yoo.com</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label57">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label56">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Username</property>
+ </widget>
+ <packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
- <property name="y_options"></property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label54">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Host</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label55">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Realm</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="labelLoginRealm">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">my sekr3t area</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
@@ -943,75 +1001,18 @@
</packing>
</child>
<child>
- <widget class="GtkLabel" id="labelLoginRealm">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">my sekr3t area</property>
+ <widget class="GtkEntry" id="entryLoginUser">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="text" translatable="yes">sesame</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label55">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Realm</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label54">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Host</property>
- </widget>
- <packing>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label56">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Username</property>
- </widget>
- <packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label57">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Password</property>
- </widget>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="labelLoginHost">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">moo.yoo.com</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
</packing>
</child>
</widget>
@@ -1344,39 +1345,30 @@
<property name="n_columns">2</property>
<property name="column_spacing">4</property>
<child>
- <widget class="GtkLabel" id="label117">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Address</property>
+ <widget class="GtkLabel" id="labelHistoryAddress">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">http://netsurf.sf.net/</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
</widget>
<packing>
- <property name="x_options">GTK_FILL</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label118">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Last visited</property>
+ <widget class="GtkLabel" id="labelHistoryLastVisit">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fri Aug 09 00:00:00 2006</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label119">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Number of visits</property>
- </widget>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
@@ -1396,30 +1388,39 @@
</packing>
</child>
<child>
- <widget class="GtkLabel" id="labelHistoryLastVisit">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Fri Aug 09 00:00:00 2006</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ <widget class="GtkLabel" id="label119">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Number of visits</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label118">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Last visited</property>
+ </widget>
+ <packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="labelHistoryAddress">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">http://netsurf.sf.net/</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
+ <widget class="GtkLabel" id="label117">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Address</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
14 years, 9 months