r4412 adamblokus - in /branches/adamblokus/netsurf: Makefile desktop/print.c desktop/print.h desktop/printer.h pdf/pdf_plotters.c pdf/pdf_plotters.h
by netsurf@semichrome.net
Author: adamblokus
Date: Sat Jun 21 13:22:07 2008
New Revision: 4412
URL: http://source.netsurf-browser.org?rev=4412&view=rev
Log:
Added 'fuzzy' margins on page bottom.
Disabled direct png embedding, because it is too unstable in Haru now.
Modified:
branches/adamblokus/netsurf/Makefile
branches/adamblokus/netsurf/desktop/print.c
branches/adamblokus/netsurf/desktop/print.h
branches/adamblokus/netsurf/desktop/printer.h
branches/adamblokus/netsurf/pdf/pdf_plotters.c
branches/adamblokus/netsurf/pdf/pdf_plotters.h
Modified: branches/adamblokus/netsurf/Makefile
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/Makefile?re...
==============================================================================
--- branches/adamblokus/netsurf/Makefile (original)
+++ branches/adamblokus/netsurf/Makefile Sat Jun 21 13:22:07 2008
@@ -122,7 +122,7 @@
-D_XOPEN_SOURCE=600 \
-D_POSIX_C_SOURCE=200112L \
-D_NETBSD_SOURCE \
- $(WARNFLAGS) -I. -I../../libsprite/trunk/ -g -O \
+ $(WARNFLAGS) -I. -I../../libsprite/trunk/ -g \
$(shell $(PKG_CONFIG) --cflags libglade-2.0 gtk+-2.0 librsvg-2.0) \
$(shell $(PKG_CONFIG) --cflags librosprite) \
$(shell xml2-config --cflags)
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 Sat Jun 21 13:22:07 2008
@@ -30,7 +30,9 @@
struct print_settings *print_make_settings(print_configuration configuration);
static float content_width, content_height;
+
static float page_content_width, page_content_height;
+static float text_margin_height;
bool print_run(struct content *content,
struct printer *printer,
@@ -46,9 +48,7 @@
print_apply_settings(printed_content, settings);
- printer->print_begin(settings->output,
- settings->page_width,
- settings->page_height);
+ printer->print_begin(settings);
/*Do some printing :)*/
@@ -62,15 +62,15 @@
while (done_height < printed_content->height){
printer->print_next_page();
content_redraw(printed_content,
- settings->margins[LEFT],
- -done_height + settings->margins[TOP],
+ 0,
+ -done_height,
+ 0,0,
+ 0,
0,
- 0, settings->margins[LEFT],
- settings->margins[TOP],
- page_content_width + settings->margins[LEFT],
- page_content_height + settings->margins[TOP],
+ page_content_width,
+ page_content_height,
1, 0xffffff);
- done_height += page_content_height;
+ done_height += page_content_height - text_margin_height;
}
print_cleanup(printed_content, printer);
@@ -89,16 +89,18 @@
/*Apply settings - adjust page size etc*/
+ text_margin_height = settings->margins[MARGINTEXT];
+
content_width = content->width;
content_height = content->height;
- page_content_width = settings->page_width - settings->margins[LEFT] -
- settings->margins[RIGHT];
+ page_content_width = settings->page_width - settings->margins[MARGINLEFT] -
+ settings->margins[MARGINRIGHT];
- page_content_height = settings->page_height - settings->margins[TOP] -
- settings->margins[BOTTOM];
+ page_content_height = settings->page_height - settings->margins[MARGINTOP] -
+ settings->margins[MARGINBOTTOM];
- content_reformat(content, page_content_width, page_content_height);
+ content_reformat(content, page_content_width, 0);
LOG(("New layout applied.New height = %d ; New width = %d ",
content->height, content->width));
@@ -124,10 +126,12 @@
settings->page_height = 840;
settings->copies = 1;
- settings->margins[LEFT] = 36;
- settings->margins[RIGHT] = 36;
- settings->margins[TOP] = 36;
- settings->margins[BOTTOM] = 36;
+ settings->margins[MARGINLEFT] = 30;
+ settings->margins[MARGINRIGHT] = 30;
+ settings->margins[MARGINTOP] = 30;
+ settings->margins[MARGINBOTTOM] = 30;
+
+ settings->margins[MARGINTEXT] = 10;
settings->output = NULL;
Modified: branches/adamblokus/netsurf/desktop/print.h
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/desktop/pri...
==============================================================================
--- branches/adamblokus/netsurf/desktop/print.h (original)
+++ branches/adamblokus/netsurf/desktop/print.h Sat Jun 21 13:22:07 2008
@@ -31,14 +31,15 @@
struct content;
struct printer;
-enum {MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3};
+enum { MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3,
+ MARGINTEXT = 4};
typedef enum {DEFAULT} print_configuration;
struct print_settings{
/*Standard parameters*/
float page_width, page_height;
- float margins[4];
+ float margins[5];
unsigned int copies;
Modified: branches/adamblokus/netsurf/desktop/printer.h
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/desktop/pri...
==============================================================================
--- branches/adamblokus/netsurf/desktop/printer.h (original)
+++ branches/adamblokus/netsurf/desktop/printer.h Sat Jun 21 13:22:07 2008
@@ -24,13 +24,14 @@
#define NETSURF_DESKTOP_PRINTER_H
#include "desktop/plotters.h"
+#include "desktop/print.h"
struct printer{
struct plotter_table *plotter;
- bool (*print_begin) (const char *path, float width, float height);
+ bool (*print_begin) (struct print_settings*);
- void (*print_next_page)();
+ bool (*print_next_page)();
void (*print_end)();
};
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 Sat Jun 21 13:22:07 2008
@@ -20,6 +20,8 @@
#include <string.h>
#include "desktop/plotters.h"
+#include "desktop/print.h"
+
#include "utils/log.h"
#include "utils/utils.h"
#include "image/bitmap.h"
@@ -29,7 +31,7 @@
#define R(x) (( (x) & 0x0000ff )/256.0)
#define G(x) ((( (x) & 0x00ff00)>>8 )/256.0)
#define B(x) ((( (x) & 0xff0000)>>16)/256.0)
-
+
// #define PDF_DEBUG
static bool pdf_plot_clg(colour c);
@@ -59,11 +61,14 @@
static void pdf_set_dashed();
static void pdf_set_dotted();
+static void pdf_page_apply_notext_clip();
+
static HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content);
-bool pdf_begin(const char *, float, float);
-void pdf_next_page();
+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,
void *user_data);
@@ -81,7 +86,8 @@
/*Remeber if pdf_plot_clip was invoked for current page*/
static bool page_clipped;
-static char *filename;
+static struct print_settings* settings;
+static float text_margin;
extern struct plotter_table plot;
@@ -132,7 +138,7 @@
bool pdf_plot_line(int x0, int y0, int x1, int y1, int width,
colour c, bool dotted, bool dashed){
#ifdef PDF_DEBUG
- LOG(("."));
+ //LOG(("."));
#endif
HPDF_Page_SetLineWidth(pdf_page, width);
@@ -208,25 +214,29 @@
bool pdf_plot_clip(int clip_x0, int clip_y0,
int clip_x1, int clip_y1){
-
#ifdef PDF_DEBUG
LOG(("%d %d %d %d", clip_x0, clip_y0, clip_x1, clip_y1));
#endif
+
+ HPDF_Page_GRestore(pdf_page);
if (page_clipped)
HPDF_Page_GRestore(pdf_page);
-
+
/*Normalize cllipping area - to prevent overflows*/
clip_x0 = min(max(clip_x0, 0), page_width);
clip_y0 = min(max(clip_y0, 0), page_height);
clip_x1 = min(max(clip_x1, 0), page_width);
clip_y1 = min(max(clip_y1, 0), page_height);
+
HPDF_Page_GSave(pdf_page);
HPDF_Page_Rectangle(pdf_page, clip_x0, page_height-clip_y1,
clip_x1-clip_x0, clip_y1-clip_y0);
HPDF_Page_Clip(pdf_page);
HPDF_Page_EndPath(pdf_page);
+ pdf_page_apply_notext_clip();
+
page_clipped = true;
return true;
@@ -235,29 +245,53 @@
bool pdf_plot_text(int x, int y, const struct css_style *style,
const char *text, size_t length, colour bg, colour c){
#ifdef PDF_DEBUG
- LOG(("."));
+ LOG((". %d %d %s", x, y, text));
#endif
char *word;
HPDF_REAL size;
-
- word = (char*)malloc(sizeof(char)*(length+1));
- if (word == NULL)
- return false;
-
- strncpy(word, text, length);
- word[length] = '\0';
+ bool fuzzy=false;
+ float text_bottom_position, descent;
+
+ if (length == 0)
+ return true;
if (style->font_size.value.length.unit == CSS_UNIT_PX)
size = style->font_size.value.length.value;
else
size = css_len2pt(&style->font_size.value.length, style);
+ size = size * 1.5;
+ descent = size * (HPDF_Font_GetDescent(pdf_font) / 1000.0);
+ text_bottom_position = page_height - y + descent;
+
+ if ( (size > y) && (y - descent <= text_margin) )
+ return true;
+
+ if (text_bottom_position < settings->margins[MARGINBOTTOM] + text_margin ){
+ if ((text_bottom_position >= settings->margins[MARGINBOTTOM]) &&
+ (page_height - (y - size) >
+ settings->margins[MARGINBOTTOM] + text_margin)) {
+ fuzzy = true;
+ HPDF_Page_GRestore(pdf_page);
+ }
+ }
+
+ word = (char*)malloc(sizeof(char)*(length+1));
+ if (word == NULL)
+ return false;
+
+ strncpy(word, text, length);
+ word[length] = '\0';
+
HPDF_Page_SetRGBFill(pdf_page, R(c), G(c), B(c));
HPDF_Page_BeginText(pdf_page);
- HPDF_Page_SetFontAndSize (pdf_page, pdf_font, size*1.5);
+ HPDF_Page_SetFontAndSize (pdf_page, pdf_font, size);
HPDF_Page_TextOut (pdf_page, x, page_height - y, word);
HPDF_Page_EndText(pdf_page);
+
+ if (fuzzy)
+ pdf_page_apply_notext_clip();
free(word);
@@ -386,11 +420,13 @@
content->total_size);
break;
+ /*Disabled until HARU PNG support will be more stable.
+
case CONTENT_PNG:
image = HPDF_LoadPngImageFromMem(pdf_doc,
content->source_data,
content->total_size);
- break;
+ break;*/
}
}
@@ -560,7 +596,10 @@
* \param pg_width page width
* \param pg_height page height
*/
-bool pdf_begin(const char *path, float pg_width, float pg_height){
+bool pdf_begin(struct print_settings* print_settings){
+
+ pdf_doc = NULL;
+
#ifdef PDF_DEBUG
pdf_doc = HPDF_New(error_handler, NULL);
#else
@@ -571,16 +610,19 @@
return false;
}
- page_width = pg_width;
- page_height = pg_height;
+ settings = print_settings;
+
+ page_width = settings->page_width - settings->margins[MARGINLEFT] -
+ settings->margins[MARGINRIGHT];
+
+ page_height = settings->page_height - settings->margins[MARGINTOP];
+
+ text_margin = settings->margins[MARGINTEXT];
HPDF_SetCompressionMode(pdf_doc, HPDF_COMP_ALL); /*Compression on*/
pdf_font = HPDF_GetFont (pdf_doc, "Times-Roman", "StandardEncoding");
- if (path == NULL)
- filename = strdup("out.pdf");
- else
- filename = strdup(path);
+ pdf_page = NULL;
#ifdef PDF_DEBUG
LOG(("pdf_begin finishes"));
@@ -588,25 +630,54 @@
return true;
}
-void pdf_next_page(){
+bool pdf_next_page(){
+#ifdef PDF_DEBUG
+ if (pdf_page != NULL){
+ HPDF_Page_GRestore(pdf_page);
+ if (page_clipped)
+ HPDF_Page_GRestore(pdf_page);
+ pdf_plot_grid(10, 10, 0xCCCCCC);
+ pdf_plot_grid(100, 100, 0xCCCCFF);
+ }
+#endif
pdf_page = HPDF_AddPage(pdf_doc);
- HPDF_Page_SetWidth (pdf_page, page_width);
- HPDF_Page_SetHeight(pdf_page, page_height);
+ if (pdf_page == NULL)
+ return false;
+
+ HPDF_Page_SetWidth (pdf_page, settings->page_width);
+ HPDF_Page_SetHeight(pdf_page, settings->page_height);
+
+ HPDF_Page_Concat(pdf_page,1,0,0,1,settings->margins[MARGINLEFT],0);
+
+ pdf_page_apply_notext_clip();
+
page_clipped = false;
+
#ifdef PDF_DEBUG
LOG(("%f %f", page_width, page_height));
- pdf_plot_grid(10, 10, 0xCCCCCC);
- pdf_plot_grid(100, 100, 0xCCCCFF);
-#endif
+#endif
+
+ return true;
}
void pdf_end(){
#ifdef PDF_DEBUG
LOG(("pdf_end begins"));
-#endif
-
- HPDF_SaveToFile(pdf_doc, filename);
+ if (pdf_page != NULL){
+ HPDF_Page_GRestore(pdf_page);
+ if (page_clipped)
+ HPDF_Page_GRestore(pdf_page);
+ pdf_plot_grid(10, 10, 0xCCCCCC);
+ pdf_plot_grid(100, 100, 0xCCCCFF);
+ }
+#endif
+
+ if (settings->output)
+ HPDF_SaveToFile(pdf_doc, settings->output);
+ else
+ HPDF_SaveToFile(pdf_doc, "out.pdf");
+
HPDF_Free(pdf_doc);
#ifdef PDF_DEBUG
@@ -636,4 +707,24 @@
}
-
+void pdf_page_apply_notext_clip(){
+ /*Save state underneath*/
+ HPDF_Page_GSave(pdf_page);
+
+ /*Apply no-text clipping (stadard page)*/
+ HPDF_Page_Rectangle(pdf_page,
+ 0,
+ text_margin + settings->margins[MARGINBOTTOM],
+ page_width,
+ page_height - settings->margins[MARGINTOP] - text_margin);
+
+ HPDF_Page_Clip(pdf_page);
+
+#ifdef PDF_DEBUG
+ HPDF_Page_Stroke(pdf_page);
+#else
+ HPDF_Page_EndPath(pdf_page);
+#endif
+}
+
+
Modified: branches/adamblokus/netsurf/pdf/pdf_plotters.h
URL: http://source.netsurf-browser.org/branches/adamblokus/netsurf/pdf/pdf_plo...
==============================================================================
--- branches/adamblokus/netsurf/pdf/pdf_plotters.h (original)
+++ branches/adamblokus/netsurf/pdf/pdf_plotters.h Sat Jun 21 13:22:07 2008
@@ -27,11 +27,11 @@
extern const struct plotter_table pdf_plotters;
-/**Start plotting a pdf file - takes filename as argument*/
-bool pdf_begin(const char *, float, float);
+/**Start plotting a pdf file*/
+bool pdf_begin(struct print_settings* settings);
/**Finish the current page and start a new one*/
-void pdf_next_page();
+bool pdf_next_page();
/**Close pdf document and save changes to file*/
void pdf_end();
14 years, 11 months
r4411 bursa - /branches/dynis/nsgiftest/gif.c
by netsurf@semichrome.net
Author: bursa
Date: Sat Jun 21 13:12:09 2008
New Revision: 4411
URL: http://source.netsurf-browser.org?rev=4411&view=rev
Log:
Fix structure name.
Modified:
branches/dynis/nsgiftest/gif.c
Modified: branches/dynis/nsgiftest/gif.c
URL: http://source.netsurf-browser.org/branches/dynis/nsgiftest/gif.c?rev=4411...
==============================================================================
--- branches/dynis/nsgiftest/gif.c (original)
+++ branches/dynis/nsgiftest/gif.c Sat Jun 21 13:12:09 2008
@@ -41,7 +41,7 @@
/* The Bitmap callbacks function table;
necessary for interaction with nsgiflib.
*/
-bitmap_callback_vt bitmap_callbacks = {
+gif_bitmap_callback_vt bitmap_callbacks = {
.bitmap_create = (void *)bitmap_create,
.bitmap_destroy = (void *)bitmap_destroy,
.bitmap_get_buffer = (void *)bitmap_get_buffer,
14 years, 11 months
r4410 takkaria - in /trunk/hubbub: src/tokeniser/tokeniser.c src/tokeniser/tokeniser.h test/data/tokeniser2/INDEX test/data/tokeniser2/cdata.test test/tokeniser2.c test/tokeniser3.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 20:49:02 2008
New Revision: 4410
URL: http://source.netsurf-browser.org?rev=4410&view=rev
Log:
Add CDATA tests and the infrastructure to support them.
Added:
trunk/hubbub/test/data/tokeniser2/cdata.test
Modified:
trunk/hubbub/src/tokeniser/tokeniser.c
trunk/hubbub/src/tokeniser/tokeniser.h
trunk/hubbub/test/data/tokeniser2/INDEX
trunk/hubbub/test/tokeniser2.c
trunk/hubbub/test/tokeniser3.c
Modified: trunk/hubbub/src/tokeniser/tokeniser.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.c?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.c (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.c Wed Jun 18 20:49:02 2008
@@ -361,6 +361,9 @@
case HUBBUB_TOKENISER_CONTENT_MODEL:
tokeniser->content_model = params->content_model.model;
break;
+ case HUBBUB_TOKENISER_PROCESS_CDATA:
+ tokeniser->process_cdata_section = params->process_cdata;
+ break;
}
return HUBBUB_OK;
Modified: trunk/hubbub/src/tokeniser/tokeniser.h
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.h?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.h (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.h Wed Jun 18 20:49:02 2008
@@ -27,6 +27,7 @@
HUBBUB_TOKENISER_BUFFER_HANDLER,
HUBBUB_TOKENISER_ERROR_HANDLER,
HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_PROCESS_CDATA
} hubbub_tokeniser_opttype;
/**
@@ -51,6 +52,8 @@
struct {
hubbub_content_model model;
} content_model;
+
+ bool process_cdata;
} hubbub_tokeniser_optparams;
/* Create a hubbub tokeniser */
Modified: trunk/hubbub/test/data/tokeniser2/INDEX
URL: http://source.netsurf-browser.org/trunk/hubbub/test/data/tokeniser2/INDEX...
==============================================================================
--- trunk/hubbub/test/data/tokeniser2/INDEX (original)
+++ trunk/hubbub/test/data/tokeniser2/INDEX Wed Jun 18 20:49:02 2008
@@ -9,3 +9,4 @@
contentModelFlags.test html5lib content model tests
entities.test html5lib entity tests
escapeFlag.test html5lib escape flag tests
+cdata.test CDATA section tests
Added: trunk/hubbub/test/data/tokeniser2/cdata.test
URL: http://source.netsurf-browser.org/trunk/hubbub/test/data/tokeniser2/cdata...
==============================================================================
--- trunk/hubbub/test/data/tokeniser2/cdata.test (added)
+++ trunk/hubbub/test/data/tokeniser2/cdata.test Wed Jun 18 20:49:02 2008
@@ -1,0 +1,23 @@
+{"tests": [
+
+{"description":"Basic CDATA test",
+"processCDATA":true,
+"input":"<![CDATA[test]]>",
+"output":[["Character", "test"]]},
+
+{"description":"Unfinished CDATA test",
+"processCDATA":true,
+"input":"<![CDAT",
+"output":["ParseError", ["Comment", "[CDAT"]]},
+
+{"description":"EOF in CDATA chunk",
+"processCDATA":true,
+"input":"<![CDATA[aa",
+"output":[["Character", "aa"]]},
+
+{"description":"False end in CDATA chunk",
+"processCDATA":true,
+"input":"<![CDATA[aa]]aa",
+"output":[["Character", "aa]]aa"]]},
+
+]}
Modified: trunk/hubbub/test/tokeniser2.c
URL: http://source.netsurf-browser.org/trunk/hubbub/test/tokeniser2.c?rev=4410...
==============================================================================
--- trunk/hubbub/test/tokeniser2.c (original)
+++ trunk/hubbub/test/tokeniser2.c Wed Jun 18 20:49:02 2008
@@ -25,6 +25,7 @@
const char *last_start_tag;
struct array_list *content_model;
+ bool process_cdata;
} context;
static void run_test(context *ctx);
@@ -97,6 +98,9 @@
} else if (strcmp(key, "contentModelFlags") == 0) {
ctx.content_model =
json_object_get_array(val);
+ } else if (strcmp(key, "processCDATA") == 0) {
+ ctx.process_cdata =
+ json_object_get_boolean(val);
}
}
@@ -151,6 +155,13 @@
HUBBUB_OK);
assert(hubbub_tokeniser_run(tok) == HUBBUB_OK);
+ }
+
+ if (ctx->process_cdata) {
+ params.process_cdata = ctx->process_cdata;
+ assert(hubbub_tokeniser_setopt(tok,
+ HUBBUB_TOKENISER_PROCESS_CDATA,
+ ¶ms) == HUBBUB_OK);
}
params.buffer_handler.handler = buffer_handler;
Modified: trunk/hubbub/test/tokeniser3.c
URL: http://source.netsurf-browser.org/trunk/hubbub/test/tokeniser3.c?rev=4410...
==============================================================================
--- trunk/hubbub/test/tokeniser3.c (original)
+++ trunk/hubbub/test/tokeniser3.c Wed Jun 18 20:49:02 2008
@@ -25,6 +25,7 @@
const char *last_start_tag;
struct array_list *content_model;
+ bool process_cdata;
} context;
static void run_test(context *ctx);
@@ -97,6 +98,9 @@
} else if (strcmp(key, "contentModelFlags") == 0) {
ctx.content_model =
json_object_get_array(val);
+ } else if (strcmp(key, "processCDATA") == 0) {
+ ctx.process_cdata =
+ json_object_get_boolean(val);
}
}
@@ -152,6 +156,13 @@
HUBBUB_OK);
assert(hubbub_tokeniser_run(tok) == HUBBUB_OK);
+ }
+
+ if (ctx->process_cdata) {
+ params.process_cdata = ctx->process_cdata;
+ assert(hubbub_tokeniser_setopt(tok,
+ HUBBUB_TOKENISER_PROCESS_CDATA,
+ ¶ms) == HUBBUB_OK);
}
params.buffer_handler.handler = buffer_handler;
14 years, 11 months
r4409 takkaria - in /trunk/hubbub/test: INDEX Makefile tokeniser3.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 20:20:15 2008
New Revision: 4409
URL: http://source.netsurf-browser.org?rev=4409&view=rev
Log:
Add a tokeniser3, which tests the tokeniser byte-by-byte rather than with all the data at once.
Added:
trunk/hubbub/test/tokeniser3.c (with props)
Modified:
trunk/hubbub/test/INDEX
trunk/hubbub/test/Makefile
Modified: trunk/hubbub/test/INDEX
URL: http://source.netsurf-browser.org/trunk/hubbub/test/INDEX?rev=4409&r1=440...
==============================================================================
--- trunk/hubbub/test/INDEX (original)
+++ trunk/hubbub/test/INDEX Wed Jun 18 20:20:15 2008
@@ -14,6 +14,7 @@
parser-utf16 Public parser API (utf-16 internally) html
tokeniser HTML tokeniser html
tokeniser2 HTML tokeniser (again) tokeniser2
+tokeniser3 HTML tokeniser (byte-by-byte) tokeniser2
tree Treebuilding API html
# Regression tests
Modified: trunk/hubbub/test/Makefile
URL: http://source.netsurf-browser.org/trunk/hubbub/test/Makefile?rev=4409&r1=...
==============================================================================
--- trunk/hubbub/test/Makefile (original)
+++ trunk/hubbub/test/Makefile Wed Jun 18 20:20:15 2008
@@ -39,7 +39,7 @@
# Tests
TESTS_$(d) := aliases cscodec csdetect dict entities filter hubbub \
- inputstream parser parser-utf16 tokeniser tokeniser2 \
+ inputstream parser parser-utf16 tokeniser tokeniser2 tokeniser3 \
tree
TESTS_$(d) := $(TESTS_$(d)) regression/cscodec-segv regression/filter-segv \
regression/stream-nomem
Added: trunk/hubbub/test/tokeniser3.c
URL: http://source.netsurf-browser.org/trunk/hubbub/test/tokeniser3.c?rev=4409...
==============================================================================
--- trunk/hubbub/test/tokeniser3.c (added)
+++ trunk/hubbub/test/tokeniser3.c Wed Jun 18 20:20:15 2008
@@ -1,0 +1,476 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <json.h>
+
+#include <hubbub/hubbub.h>
+
+#include "utils/utils.h"
+
+#include "input/inputstream.h"
+#include "tokeniser/tokeniser.h"
+
+#include "testutils.h"
+
+typedef struct context {
+ const uint8_t *pbuffer;
+
+ const uint8_t *input;
+ size_t input_len;
+
+ struct array_list *output;
+ int output_index;
+ size_t char_off;
+
+ const char *last_start_tag;
+ struct array_list *content_model;
+} context;
+
+static void run_test(context *ctx);
+static void buffer_handler(const uint8_t *buffer, size_t len, void *pw);
+static void token_handler(const hubbub_token *token, void *pw);
+
+static void *myrealloc(void *ptr, size_t len, void *pw)
+{
+ UNUSED(pw);
+
+ return realloc(ptr, len);
+}
+
+int main(int argc, char **argv)
+{
+ struct json_object *json;
+ struct array_list *tests;
+ struct lh_entry *entry;
+ char *key;
+ struct json_object *val;
+ int i;
+ context ctx;
+
+ if (argc != 3) {
+ printf("Usage: %s <aliases_file> <filename>\n", argv[0]);
+ return 1;
+ }
+
+ /* Initialise library */
+ assert(hubbub_initialise(argv[1], myrealloc, NULL) == HUBBUB_OK);
+
+ json = json_object_from_file(argv[2]);
+ assert(!is_error(json));
+
+ assert(strcmp((char *) ((json_object_get_object(json)->head)->k),
+ "tests") == 0);
+
+ /* Get array of tests */
+ tests = json_object_get_array((struct json_object *)
+ (json_object_get_object(json)->head)->v);
+
+ for (i = 0; i < array_list_length(tests); i++) {
+ /* Get test */
+ struct json_object *test =
+ (struct json_object *) array_list_get_idx(tests, i);
+
+ ctx.last_start_tag = NULL;
+ ctx.content_model = NULL;
+
+ /* Extract settings */
+ for (entry = json_object_get_object(test)->head; entry;
+ entry = entry->next) {
+ key = (char *) entry->k;
+ val = (struct json_object *) entry->v;
+
+ if (strcmp(key, "description") == 0) {
+ printf("Test: %s\n",
+ json_object_get_string(val));
+ } else if (strcmp(key, "input") == 0) {
+ ctx.input = (const uint8_t *)
+ json_object_get_string_len(val,
+ (int *) &ctx.input_len);
+ } else if (strcmp(key, "output") == 0) {
+ ctx.output = json_object_get_array(val);
+ ctx.output_index = 0;
+ ctx.char_off = 0;
+ } else if (strcmp(key, "lastStartTag") == 0) {
+ ctx.last_start_tag = (const char *)
+ json_object_get_string(val);
+ } else if (strcmp(key, "contentModelFlags") == 0) {
+ ctx.content_model =
+ json_object_get_array(val);
+ }
+ }
+
+ /* And run the test */
+ run_test(&ctx);
+ }
+
+ assert(hubbub_finalise(myrealloc, NULL) == HUBBUB_OK);
+
+ printf("PASS\n");
+
+ return 0;
+}
+
+void run_test(context *ctx)
+{
+ hubbub_inputstream *stream;
+ hubbub_tokeniser *tok;
+ hubbub_tokeniser_optparams params;
+ int i, max_i;
+ size_t j;
+ struct array_list *outputsave = ctx->output;
+
+ if (ctx->content_model == NULL) {
+ max_i = 1;
+ } else {
+ max_i = array_list_length(ctx->content_model);
+ }
+
+ /* We test for each of the content models specified */
+ for (i = 0; i < max_i; i++) {
+ /* Reset expected output */
+ ctx->output = outputsave;
+ ctx->output_index = 0;
+ ctx->char_off = 0;
+
+ stream = hubbub_inputstream_create("UTF-8", "UTF-8",
+ myrealloc, NULL);
+ assert(stream != NULL);
+
+ tok = hubbub_tokeniser_create(stream, myrealloc, NULL);
+ assert(tok != NULL);
+
+ if (ctx->last_start_tag != NULL) {
+ /* Fake up a start tag, in PCDATA state */
+ uint8_t buf [strlen(ctx->last_start_tag) + 3];
+
+ snprintf((char *) buf, sizeof buf, "<%s>",
+ ctx->last_start_tag);
+
+ assert(hubbub_inputstream_append(stream,
+ buf, strlen(ctx->last_start_tag) + 2) ==
+ HUBBUB_OK);
+
+ assert(hubbub_tokeniser_run(tok) == HUBBUB_OK);
+ }
+
+ params.buffer_handler.handler = buffer_handler;
+ params.buffer_handler.pw = ctx;
+ assert(hubbub_tokeniser_setopt(tok,
+ HUBBUB_TOKENISER_BUFFER_HANDLER,
+ ¶ms) == HUBBUB_OK);
+
+ params.token_handler.handler = token_handler;
+ params.token_handler.pw = ctx;
+ assert(hubbub_tokeniser_setopt(tok,
+ HUBBUB_TOKENISER_TOKEN_HANDLER,
+ ¶ms) == HUBBUB_OK);
+
+ if (ctx->content_model == NULL) {
+ params.content_model.model =
+ HUBBUB_CONTENT_MODEL_PCDATA;
+ } else {
+ char *cm = json_object_get_string(
+ (struct json_object *)
+ array_list_get_idx(ctx->content_model, i));
+
+ if (strcmp(cm, "PCDATA") == 0) {
+ params.content_model.model =
+ HUBBUB_CONTENT_MODEL_PCDATA;
+ } else if (strcmp(cm, "RCDATA") == 0) {
+ params.content_model.model =
+ HUBBUB_CONTENT_MODEL_RCDATA;
+ } else if (strcmp(cm, "CDATA") == 0) {
+ params.content_model.model =
+ HUBBUB_CONTENT_MODEL_CDATA;
+ } else {
+ params.content_model.model =
+ HUBBUB_CONTENT_MODEL_PLAINTEXT;
+ }
+ }
+ assert(hubbub_tokeniser_setopt(tok,
+ HUBBUB_TOKENISER_CONTENT_MODEL,
+ ¶ms) == HUBBUB_OK);
+
+ printf("Input: '%.*s' (%d)\n", (int) ctx->input_len,
+ (const char *) ctx->input, ctx->input_len);
+
+ for (j = 0; j < ctx->input_len; j++) {
+ assert(hubbub_inputstream_append(stream,
+ ctx->input + j, 1) ==
+ HUBBUB_OK);
+
+ assert(hubbub_tokeniser_run(tok) == HUBBUB_OK);
+ }
+
+ assert(hubbub_inputstream_append(stream, NULL, 0) ==
+ HUBBUB_OK);
+
+ assert(hubbub_tokeniser_run(tok) == HUBBUB_OK);
+
+ hubbub_tokeniser_destroy(tok);
+
+ hubbub_inputstream_destroy(stream);
+ }
+}
+
+void buffer_handler(const uint8_t *buffer, size_t len, void *pw)
+{
+ context *ctx = (context *) pw;
+
+ UNUSED(len);
+
+ ctx->pbuffer = buffer;
+}
+
+void token_handler(const hubbub_token *token, void *pw)
+{
+ static const char *token_names[] = {
+ "DOCTYPE", "StartTag", "EndTag",
+ "Comment", "Character", "EOF"
+ };
+ size_t i;
+ context *ctx = (context *) pw;
+ struct json_object *obj = NULL;
+ struct array_list *items;
+
+ for (; ctx->output_index < array_list_length(ctx->output);
+ ctx->output_index++) {
+ /* Get object for index */
+ obj = (struct json_object *)
+ array_list_get_idx(ctx->output,
+ ctx->output_index);
+
+ /* If it's not a string, we've found the expected output */
+ if (json_object_get_type(obj) != json_type_string)
+ break;
+
+ /* Otherwise, it must be a parse error */
+ assert(strcmp(json_object_get_string(obj),
+ "ParseError") == 0);
+ }
+
+ /* If we've run off the end, this is an error -- the tokeniser has
+ * produced more tokens than expected. We allow for the generation
+ * of a terminating EOF token, however. */
+ assert("too many tokens" &&
+ (ctx->output_index < array_list_length(ctx->output) ||
+ token->type == HUBBUB_TOKEN_EOF));
+
+ /* Got a terminating EOF -- no error */
+ if (ctx->output_index >= array_list_length(ctx->output))
+ return;
+
+ /* Now increment the output index so we don't re-expect this token */
+ ctx->output_index++;
+
+ /* Expected output must be an array */
+ assert(json_object_get_type(obj) == json_type_array);
+
+ items = json_object_get_array(obj);
+
+ printf("got %s: expected %s\n", token_names[token->type],
+ json_object_get_string((struct json_object *)
+ array_list_get_idx(items, 0)));
+
+ /* Make sure we got the token we expected */
+ assert(strcmp(token_names[token->type],
+ json_object_get_string((struct json_object *)
+ array_list_get_idx(items, 0))) == 0);
+
+ switch (token->type) {
+ case HUBBUB_TOKEN_DOCTYPE:
+ {
+ char *expname = json_object_get_string(
+ array_list_get_idx(items, 1));
+ char *exppub = json_object_get_string(
+ array_list_get_idx(items, 2));
+ char *expsys = json_object_get_string(
+ array_list_get_idx(items, 3));
+ bool expquirks = !json_object_get_boolean(
+ array_list_get_idx(items, 4));
+ char *gotname = (char *) (ctx->pbuffer +
+ token->data.doctype.name.data.off);
+ char *gotpub, *gotsys;
+
+ printf("'%.*s' %sids:\n",
+ (int) token->data.doctype.name.len,
+ gotname,
+ token->data.doctype.force_quirks ?
+ "(force-quirks) " : "");
+
+ if (token->data.doctype.public_missing) {
+ gotpub = NULL;
+ printf("\tpublic: missing\n");
+ } else {
+ gotpub = (char *) (ctx->pbuffer +
+ token->data.doctype.public_id.data.off);
+ printf("\tpublic: '%.*s'\n",
+ (int) token->data.doctype.public_id.len,
+ gotpub);
+ }
+
+ if (token->data.doctype.system_missing) {
+ gotsys = NULL;
+ printf("\tsystem: missing\n");
+ } else {
+ gotsys = (char *) (ctx->pbuffer +
+ token->data.doctype.system_id.data.off);
+ printf("\tsystem: '%.*s'\n",
+ (int) token->data.doctype.system_id.len,
+ gotsys);
+ }
+
+ assert(token->data.doctype.name.len == strlen(expname));
+ assert(strncmp(gotname, expname, strlen(expname)) == 0);
+
+ assert((exppub == NULL) == (gotpub == NULL));
+ if (exppub) {
+ assert(token->data.doctype.public_id.len == strlen(exppub));
+ assert(strncmp(gotpub, exppub, strlen(exppub)) == 0);
+ }
+
+ assert((expsys == NULL) == (gotsys == NULL));
+ if (gotsys) {
+ assert(token->data.doctype.system_id.len == strlen(expsys));
+ assert(strncmp(gotsys, expsys, strlen(expsys)) == 0);
+ }
+
+ assert(expquirks == token->data.doctype.force_quirks);
+ }
+ break;
+ case HUBBUB_TOKEN_START_TAG:
+ {
+ char *expname = json_object_get_string(
+ array_list_get_idx(items, 1));
+ struct lh_entry *expattrs = json_object_get_object(
+ array_list_get_idx(items, 2))->head;
+ bool self_closing = json_object_get_boolean(
+ array_list_get_idx(items, 3));
+
+ char *tagname = (char *) (ctx->pbuffer +
+ token->data.tag.name.data.off);
+
+ printf("'%.*s' %s%s\n",
+ (int) token->data.tag.name.len,
+ tagname,
+ (token->data.tag.self_closing) ?
+ "(self-closing) " : "",
+ (token->data.tag.n_attributes > 0) ?
+ "attributes:" : "");
+
+ assert(token->data.tag.name.len == strlen(expname));
+ assert(strncmp(tagname, expname, strlen(expname)) == 0);
+
+ assert((token->data.tag.n_attributes == 0) ==
+ (expattrs == NULL));
+
+ assert(self_closing == token->data.tag.self_closing);
+
+ for (i = 0; i < token->data.tag.n_attributes; i++) {
+ char *expname = (char *) expattrs->k;
+ char *expval = json_object_get_string(
+ (struct json_object *) expattrs->v);
+ char *gotname = (char *) (ctx->pbuffer +
+ token->data.tag.attributes[i].name.data.off);
+ size_t namelen =
+ token->data.tag.attributes[i].name.len;
+ char *gotval = (char *) (ctx->pbuffer +
+ token->data.tag.attributes[i].value.data.off);
+ size_t vallen =
+ token->data.tag.attributes[i].value.len;
+
+ printf("\t'%.*s' = '%.*s'\n",
+ (int) namelen, gotname,
+ (int) vallen, gotval);
+
+ assert(namelen == strlen(expname));
+ assert(strncmp(gotname, expname,
+ strlen(expname)) == 0);
+ assert(vallen == strlen(expval));
+ assert(strncmp(gotval, expval, strlen(expval)) == 0);
+
+ expattrs = expattrs->next;
+ }
+
+ assert(expattrs == NULL);
+ }
+ break;
+ case HUBBUB_TOKEN_END_TAG:
+ {
+ char *expname = json_object_get_string(
+ array_list_get_idx(items, 1));
+ char *tagname = (char *) (ctx->pbuffer +
+ token->data.tag.name.data.off);
+
+ printf("'%.*s' %s\n",
+ (int) token->data.tag.name.len,
+ tagname,
+ (token->data.tag.n_attributes > 0) ?
+ "attributes:" : "");
+
+ assert(token->data.tag.name.len == strlen(expname));
+ assert(strncmp(tagname, expname, strlen(expname)) == 0);
+ }
+ break;
+ case HUBBUB_TOKEN_COMMENT:
+ {
+ char *expstr = json_object_get_string(
+ array_list_get_idx(items, 1));
+ char *gotstr = (char *) (ctx->pbuffer +
+ token->data.comment.data.off);
+
+ printf("'%.*s'\n", (int) token->data.comment.len, gotstr);
+
+ assert(token->data.comment.len == strlen(expstr));
+ assert(strncmp(gotstr, expstr, strlen(expstr)) == 0);
+ }
+ break;
+ case HUBBUB_TOKEN_CHARACTER:
+ {
+ int expstrlen;
+ char *expstr = json_object_get_string_len(
+ array_list_get_idx(items, 1), &expstrlen);
+ char *gotstr = (char *) (ctx->pbuffer +
+ token->data.character.data.off);
+ size_t len = min(token->data.character.len,
+ expstrlen - ctx->char_off);
+
+ printf("expected: '%.*s'\n",
+ len, expstr + ctx->char_off);
+ printf(" got: '%.*s'\n",
+ (int) token->data.character.len, gotstr);
+
+ assert(memcmp(gotstr, expstr + ctx->char_off, len) == 0);
+
+ if (len < token->data.character.len) {
+ /* Expected token only contained part of the data
+ * Calculate how much is left, then try again with
+ * the next expected token */
+ hubbub_token t;
+
+ t.type = HUBBUB_TOKEN_CHARACTER;
+ t.data.character.data.off += len;
+ t.data.character.len -= len;
+
+ ctx->char_off = 0;
+
+ token_handler(&t, pw);
+ } else if (strlen(expstr + ctx->char_off) >
+ token->data.character.len) {
+ /* Tokeniser output only contained part of the data
+ * in the expected token; calculate the offset into
+ * the token and process the remainder next time */
+ ctx->char_off += len;
+ ctx->output_index--;
+ } else {
+ /* Exact match - clear offset */
+ ctx->char_off = 0;
+ }
+ }
+ break;
+ case HUBBUB_TOKEN_EOF:
+ printf("\n");
+ break;
+ }
+}
Propchange: trunk/hubbub/test/tokeniser3.c
------------------------------------------------------------------------------
svn:eol-style = native
14 years, 11 months
r4408 takkaria - /trunk/hubbub/src/tokeniser/tokeniser.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 20:19:06 2008
New Revision: 4408
URL: http://source.netsurf-browser.org?rev=4408&view=rev
Log:
Fix assert()s, and only compile the preceding line when debugging to avoid warnings.
Modified:
trunk/hubbub/src/tokeniser/tokeniser.c
Modified: trunk/hubbub/src/tokeniser/tokeniser.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.c?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.c (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.c Wed Jun 18 20:19:06 2008
@@ -713,10 +713,12 @@
return hubbub_tokeniser_consume_character_reference(tokeniser);
} else {
hubbub_token token;
+#ifndef NDEBUG
uint32_t c = hubbub_inputstream_peek(tokeniser->input);
- assert(c != HUBBUB_INPUTSTREAM_OOD ||
- c == HUBBUB_INPUTSTREAM_EOF);
+ assert(c != HUBBUB_INPUTSTREAM_OOD &&
+ c != HUBBUB_INPUTSTREAM_EOF);
+#endif
/* Emit character */
token.type = HUBBUB_TOKEN_CHARACTER;
@@ -1565,10 +1567,12 @@
if (tokeniser->context.match_entity.complete == false) {
return hubbub_tokeniser_consume_character_reference(tokeniser);
} else {
+#ifndef NDEBUG
uint32_t c = hubbub_inputstream_peek(tokeniser->input);
- assert(c != HUBBUB_INPUTSTREAM_OOD ||
- c == HUBBUB_INPUTSTREAM_EOF);
+ assert(c != HUBBUB_INPUTSTREAM_OOD &&
+ c != HUBBUB_INPUTSTREAM_EOF);
+#endif
pos = hubbub_inputstream_cur_pos(tokeniser->input, &len);
14 years, 11 months
r4407 takkaria - in /trunk/hubbub/test/data/tokeniser2: test1.test test2.test
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 20:03:53 2008
New Revision: 4407
URL: http://source.netsurf-browser.org?rev=4407&view=rev
Log:
Add some new tests (also committed to html5lib).
Modified:
trunk/hubbub/test/data/tokeniser2/test1.test
trunk/hubbub/test/data/tokeniser2/test2.test
Modified: trunk/hubbub/test/data/tokeniser2/test1.test
URL: http://source.netsurf-browser.org/trunk/hubbub/test/data/tokeniser2/test1...
==============================================================================
--- trunk/hubbub/test/data/tokeniser2/test1.test (original)
+++ trunk/hubbub/test/data/tokeniser2/test1.test Wed Jun 18 20:03:53 2008
@@ -141,6 +141,10 @@
"input":"I'm &no",
"output":[["Character","I'm "], "ParseError", ["Character", "&no"]]},
+{"description":"Non-ASCII character reference name",
+"input":"&\u00AC;",
+"output":["ParseError", ["Character", "&\u00AC;"]]},
+
{"description":"ASCII decimal entity",
"input":"$",
"output":[["Character","$"]]},
Modified: trunk/hubbub/test/data/tokeniser2/test2.test
URL: http://source.netsurf-browser.org/trunk/hubbub/test/data/tokeniser2/test2...
==============================================================================
--- trunk/hubbub/test/data/tokeniser2/test2.test (original)
+++ trunk/hubbub/test/data/tokeniser2/test2.test Wed Jun 18 20:03:53 2008
@@ -144,6 +144,10 @@
"input":"\nx\n>\n",
"output":[["Character","\nx\n>\n"]]},
+{"description":"Start tag with no attributes but space before the greater-than sign",
+"input":"<h >",
+"output":[["StartTag", "h", {}]]},
+
{"description":"Empty attribute followed by uppercase attribute",
"input":"<h a B=''>",
"output":[["StartTag", "h", {"a":"", "b":""}]]},
14 years, 11 months
r4406 takkaria - /trunk/hubbub/src/tokeniser/tokeniser.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 19:58:58 2008
New Revision: 4406
URL: http://source.netsurf-browser.org?rev=4406&view=rev
Log:
Use assert() instead of abort() or returning NULL in code that should not be reached.
Modified:
trunk/hubbub/src/tokeniser/tokeniser.c
Modified: trunk/hubbub/src/tokeniser/tokeniser.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.c?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.c (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.c Wed Jun 18 19:58:58 2008
@@ -4,6 +4,7 @@
* http://www.opensource.org/licenses/mit-license.php
* Copyright 2007 John-Mark Bell <jmb(a)netsurf-browser.org>
*/
+#include <assert.h>
#include <stdbool.h>
#include <string.h>
@@ -714,11 +715,8 @@
hubbub_token token;
uint32_t c = hubbub_inputstream_peek(tokeniser->input);
- if (c == HUBBUB_INPUTSTREAM_OOD ||
- c == HUBBUB_INPUTSTREAM_EOF) {
- /* Should never happen */
- abort();
- }
+ assert(c != HUBBUB_INPUTSTREAM_OOD ||
+ c == HUBBUB_INPUTSTREAM_EOF);
/* Emit character */
token.type = HUBBUB_TOKEN_CHARACTER;
@@ -1569,11 +1567,8 @@
} else {
uint32_t c = hubbub_inputstream_peek(tokeniser->input);
- if (c == HUBBUB_INPUTSTREAM_OOD ||
- c == HUBBUB_INPUTSTREAM_EOF) {
- /* Should never happen */
- abort();
- }
+ assert(c != HUBBUB_INPUTSTREAM_OOD ||
+ c == HUBBUB_INPUTSTREAM_EOF);
pos = hubbub_inputstream_cur_pos(tokeniser->input, &len);
@@ -1938,18 +1933,14 @@
size_t len;
/* In order to get to this state, the previous character must
- * be '-'. This means we can safely rewind and add to the
+ * be '-'. This means we can safely rewind and add 1 to the
* comment buffer. */
hubbub_inputstream_rewind(tokeniser->input, 1);
-
- pos = hubbub_inputstream_cur_pos(tokeniser->input, &len);
-
- if (tokeniser->context.current_comment.len == 0)
- tokeniser->context.current_comment.data.off = pos;
- tokeniser->context.current_comment.len += len;
- hubbub_inputstream_advance(tokeniser->input);
-
+ tokeniser->context.current_comment.len += 1;
+
+ /* Now add the input char */
+ hubbub_inputstream_advance(tokeniser->input);
pos = hubbub_inputstream_cur_pos(tokeniser->input, &len);
tokeniser->context.current_comment.len += len;
hubbub_inputstream_advance(tokeniser->input);
@@ -1986,11 +1977,6 @@
if (tokeniser->context.current_comment.len == 0) {
tokeniser->context.current_comment.data.off = pos;
- tokeniser->context.current_comment.len = len;
- } else {
- /* Need to do this to get length of '-' */
- len = pos -
- tokeniser->context.current_comment.data.off;
}
tokeniser->context.current_comment.len = len;
@@ -3175,8 +3161,8 @@
void hubbub_tokeniser_emit_token(hubbub_tokeniser *tokeniser,
hubbub_token *token)
{
- if (tokeniser == NULL || token == NULL)
- return;
+ assert(tokeniser != NULL);
+ assert(token != NULL);
if (token->type == HUBBUB_TOKEN_START_TAG) {
tokeniser->context.last_start_tag_name = token->data.tag.name;
14 years, 11 months
r4405 takkaria - /trunk/hubbub/src/tokeniser/tokeniser.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 19:30:58 2008
New Revision: 4405
URL: http://source.netsurf-browser.org?rev=4405&view=rev
Log:
Fix remaining issues with byte-by-byte tokenisation.
Modified:
trunk/hubbub/src/tokeniser/tokeniser.c
Modified: trunk/hubbub/src/tokeniser/tokeniser.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.c?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.c (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.c Wed Jun 18 19:30:58 2008
@@ -91,6 +91,7 @@
* emitted */
struct {
uint32_t count;
+ bool match;
} close_tag_match;
struct {
@@ -758,6 +759,9 @@
tokeniser->context.current_chars.len += len;
+ tokeniser->context.close_tag_match.match = false;
+ tokeniser->context.close_tag_match.count = 0;
+
tokeniser->state =
HUBBUB_TOKENISER_STATE_CLOSE_TAG_OPEN;
hubbub_inputstream_advance(tokeniser->input);
@@ -790,6 +794,9 @@
tokeniser->context.current_chars.len += len;
+ tokeniser->context.close_tag_match.match = false;
+ tokeniser->context.close_tag_match.count = 0;
+
tokeniser->state =
HUBBUB_TOKENISER_STATE_CLOSE_TAG_OPEN;
hubbub_inputstream_advance(tokeniser->input);
@@ -867,7 +874,7 @@
bool hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
{
- bool match = false;
+ hubbub_tokeniser_context *ctx = &tokeniser->context;
/**\todo Handle the fragment case here */
@@ -881,37 +888,37 @@
while ((c = hubbub_inputstream_peek(tokeniser->input)) !=
HUBBUB_INPUTSTREAM_EOF &&
c != HUBBUB_INPUTSTREAM_OOD &&
- match != true) {
+ ctx->close_tag_match.match != true) {
uint32_t pos;
size_t len;
pos = hubbub_inputstream_cur_pos(tokeniser->input,
&len);
- if (tokeniser->context.close_tag_match.count+1 ==
+ if (ctx->close_tag_match.count+1 ==
start_tag.len) {
- match = true;
+ ctx->close_tag_match.match = true;
} else if (hubbub_inputstream_compare_range_ci(
tokeniser->input, pos,
start_tag.data.off +
- tokeniser->context.close_tag_match.count,
+ ctx->close_tag_match.count,
len) != 0) {
break;
}
hubbub_inputstream_advance(tokeniser->input);
- tokeniser->context.close_tag_match.count += len;
+ ctx->close_tag_match.count += len;
}
if (c == HUBBUB_INPUTSTREAM_OOD)
return false;
- if (match) {
+ if (ctx->close_tag_match.match) {
c = hubbub_inputstream_peek(tokeniser->input);
if (c != '\t' && c != '\n' && c != '\f' &&
c != ' ' && c != '>' && c != '/' &&
c != HUBBUB_INPUTSTREAM_EOF) {
- match = false;
+ ctx->close_tag_match.match = false;
}
}
@@ -921,8 +928,8 @@
tokeniser->context.close_tag_match.count = 0;
}
- if (match == false && tokeniser->content_model !=
- HUBBUB_CONTENT_MODEL_PCDATA) {
+ if (ctx->close_tag_match.match == false && tokeniser->content_model !=
+ HUBBUB_CONTENT_MODEL_PCDATA) {
hubbub_token token;
uint32_t pos;
14 years, 11 months
r4404 takkaria - /trunk/hubbub/src/tokeniser/tokeniser.c
by netsurf@semichrome.net
Author: takkaria
Date: Wed Jun 18 18:59:26 2008
New Revision: 4404
URL: http://source.netsurf-browser.org?rev=4404&view=rev
Log:
Fix entity tokenisation when data is given one byte at a time.
Modified:
trunk/hubbub/src/tokeniser/tokeniser.c
Modified: trunk/hubbub/src/tokeniser/tokeniser.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/tokeniser/tokeniser.c?...
==============================================================================
--- trunk/hubbub/src/tokeniser/tokeniser.c (original)
+++ trunk/hubbub/src/tokeniser/tokeniser.c Wed Jun 18 18:59:26 2008
@@ -116,6 +116,9 @@
* matching completed */
bool done_setup; /**< Flag that match setup
* has completed */
+ bool overflow; /**< Whether this entity has
+ * has overflowed the maximum
+ * numeric entity value */
void *context; /**< Context for named
* entity search */
size_t prev_len; /**< Previous byte length
@@ -2881,6 +2884,7 @@
tokeniser->context.match_entity.return_state = tokeniser->state;
tokeniser->context.match_entity.complete = false;
tokeniser->context.match_entity.done_setup = true;
+ tokeniser->context.match_entity.overflow = false;
tokeniser->context.match_entity.context = NULL;
tokeniser->context.match_entity.prev_len = len;
@@ -2888,8 +2892,11 @@
c = hubbub_inputstream_peek(tokeniser->input);
- if (c == HUBBUB_INPUTSTREAM_OOD)
- return false;
+ if (c == HUBBUB_INPUTSTREAM_OOD) {
+ /* rewind because we need more data */
+ hubbub_inputstream_rewind(tokeniser->input, 1);
+ return false;
+ }
/* Reset allowed character for future calls */
tokeniser->context.allowed_char = '\0';
@@ -2922,7 +2929,6 @@
uint32_t c = hubbub_inputstream_peek(tokeniser->input);
uint32_t pos;
size_t len;
- bool overflow = false;
hubbub_error error;
if (c == HUBBUB_INPUTSTREAM_OOD)
@@ -2978,7 +2984,7 @@
}
if (ctx->match_entity.codepoint >= 0x10FFFF) {
- overflow = true;
+ ctx->match_entity.overflow = true;
}
hubbub_inputstream_advance(tokeniser->input);
@@ -3007,7 +3013,7 @@
cp = cp1252Table[cp - 0x80];
} else if (cp == 0x0D) {
cp = 0x000A;
- } else if (overflow || cp <= 0x0008 ||
+ } else if (ctx->match_entity.overflow || cp <= 0x0008 ||
(0x000E <= cp && cp <= 0x001F) ||
(0x007F <= cp && cp <= 0x009F) ||
(0xD800 <= cp && cp <= 0xDFFF) ||
@@ -3086,12 +3092,13 @@
hubbub_inputstream_advance(tokeniser->input);
}
+ if (c == HUBBUB_INPUTSTREAM_OOD) {
+ return false;
+ }
+
/* Rewind back possible matches, if any */
hubbub_inputstream_rewind(tokeniser->input,
ctx->match_entity.poss_len);
-
- if (c == HUBBUB_INPUTSTREAM_OOD)
- return false;
c = hubbub_inputstream_peek(tokeniser->input);
14 years, 11 months
r4403 dynis - in /branches/dynis/netsurf/image: bmpread.c bmpread.h
by netsurf@semichrome.net
Author: dynis
Date: Wed Jun 18 18:41:53 2008
New Revision: 4403
URL: http://source.netsurf-browser.org?rev=4403&view=rev
Log:
Remove NetSurf's bmpread.c and bmpread.h (replaced by libnsbmp)
Removed:
branches/dynis/netsurf/image/bmpread.c
branches/dynis/netsurf/image/bmpread.h
Removed: branches/dynis/netsurf/image/bmpread.c
URL: http://source.netsurf-browser.org/branches/dynis/netsurf/image/bmpread.c?...
==============================================================================
--- branches/dynis/netsurf/image/bmpread.c (original)
+++ branches/dynis/netsurf/image/bmpread.c (removed)
@@ -1,816 +1,0 @@
-/*
- * Copyright 2006 Richard Wilson <info(a)tinct.net>
- *
- * 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 <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "image/bmpread.h"
-#include "image/bitmap.h"
-#include "utils/log.h"
-#include "utils/config.h"
-
-#define READ_SHORT(a, o) (a[o]|(a[o+1]<<8))
-#define READ_INT(a, o) (a[o]|(a[o+1]<<8)|(a[o+2]<<16)|(a[o+3]<<24))
-
-bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data);
-bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes);
-bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes);
-bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes);
-bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes);
-bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size);
-void bmp_invalidate(struct bitmap *bitmap, void *private_word);
-
-
-/**
- * Analyse a BMP prior to decoding.
- *
- * This function will scan the data provided and perform simple checks to
- * ensure the data is a valid BMP.
- *
- * This function must be called before bmp_decode() and sets up all the
- * relevant values in the bmp structure.
- *
- * \param bmp the BMP image to analyse
- * \return BMP_OK on success
- */
-bmp_result bmp_analyse(struct bmp_image *bmp) {
- char *data = (char *) bmp->bmp_data;
-
- /* ensure we aren't already initialised */
- if (bmp->bitmap)
- return BMP_OK;
-
- /* standard 14-byte BMP file header is:
- *
- * +0 SHORT 'BM'
- * +2 INT size of file (in bytes)
- * +6 SHORT reserved field (1)
- * +8 SHORT reserved field (2)
- * +10 INT starting position of image data (in bytes)
- */
- if (bmp->buffer_size < 14)
- return BMP_INSUFFICIENT_DATA;
- if ((data[0] != 'B') || (data[1] != 'M'))
- return BMP_DATA_ERROR;
- bmp->bitmap_offset = READ_INT(data, 10);
-
- /* decode the BMP header */
- return bmp_analyse_header(bmp, data + 14);
-}
-
-
-/**
- * Analyse an ICO prior to decoding.
- *
- * This function will scan the data provided and perform simple checks to
- * ensure the data is a valid ICO.
- *
- * This function must be called before ico_find().
- *
- * \param ico the ICO image to analyse
- * \return BMP_OK on success
- */
-bmp_result ico_analyse(struct ico_collection *ico) {
- char *data = (char *) ico->ico_data;
- unsigned int count, i;
- bmp_result result;
- struct ico_image *image;
- int area, max_area = 0;
-
- /* ensure we aren't already initialised */
- if (ico->first)
- return BMP_OK;
-
- /* standard 6-byte ICO file header is:
- *
- * +0 INT 0x00010000
- * +4 SHORT number of BMPs to follow
- */
- if (ico->buffer_size < 6)
- return BMP_INSUFFICIENT_DATA;
- if (READ_INT(data, 0) != 0x00010000)
- return BMP_DATA_ERROR;
- count = READ_SHORT(data, 4);
- if (count == 0)
- return BMP_DATA_ERROR;
- data += 6;
-
- /* decode the BMP files */
- if (ico->buffer_size < 6 + (16 * count))
- return BMP_INSUFFICIENT_DATA;
- for (i = 0; i < count; i++) {
- image = calloc(1, sizeof(struct ico_image));
- if (!image)
- return BMP_INSUFFICIENT_MEMORY;
- image->next = ico->first;
- ico->first = image;
- image->bmp.width = data[0];
- image->bmp.height = data[1];
- image->bmp.buffer_size = READ_INT(data, 8) + 40;
- image->bmp.bmp_data = ico->ico_data + READ_INT(data, 12);
- image->bmp.ico = true;
- data += 16;
- result = bmp_analyse_header(&image->bmp,
- (char *) image->bmp.bmp_data);
- if (result != BMP_OK)
- return result;
- area = image->bmp.width * image->bmp.height;
- if (area > max_area) {
- ico->width = image->bmp.width;
- ico->height = image->bmp.height;
- max_area = area;
- }
- }
- return BMP_OK;
-}
-
-
-bmp_result bmp_analyse_header(struct bmp_image *bmp, char *data) {
- unsigned int header_size;
- unsigned int i;
- int width, height, j;
- int palette_size;
- unsigned int flags;
-
- /* a variety of different bitmap headers can follow, depending
- * on the BMP variant. A full description of the various headers
- * can be found at http://www.fileformat.info/format/bmp/
- */
- header_size = READ_INT(data, 0);
- if (bmp->buffer_size < (14 + header_size))
- return BMP_INSUFFICIENT_DATA;
- if (header_size == 12) {
- /* the following header is for os/2 and windows 2.x and consists of:
- *
- * +0 INT size of this header (in bytes)
- * +4 SHORT image width (in pixels)
- * +6 SHORT image height (in pixels)
- * +8 SHORT number of color planes (always 1)
- * +10 SHORT number of bits per pixel
- */
- width = READ_SHORT(data, 4);
- height = READ_SHORT(data, 6);
- if (width < 0)
- return BMP_DATA_ERROR;
- if (height < 0) {
- bmp->reversed = true;
- height = -height;
- }
- bmp->width = width;
- bmp->height = height;
- if (READ_SHORT(data, 8) != 1)
- return BMP_DATA_ERROR;
- bmp->bpp = READ_SHORT(data, 10);
- bmp->colours = (1 << bmp->bpp);
- palette_size = 3;
- } else if (header_size < 40) {
- return BMP_DATA_ERROR;
- } else {
- /* the following header is for windows 3.x and onwards. it is a
- * minimum of 40 bytes and (as of Windows 95) a maximum of 108 bytes.
- *
- * +0 INT size of this header (in bytes)
- * +4 INT image width (in pixels)
- * +8 INT image height (in pixels)
- * +12 SHORT number of color planes (always 1)
- * +14 SHORT number of bits per pixel
- * +16 INT compression methods used
- * +20 INT size of bitmap (in bytes)
- * +24 INT horizontal resolution (in pixels per meter)
- * +28 INT vertical resolution (in pixels per meter)
- * +32 INT number of colors in the image
- * +36 INT number of important colors
- * +40 INT mask identifying bits of red component
- * +44 INT mask identifying bits of green component
- * +48 INT mask identifying bits of blue component
- * +52 INT mask identifying bits of alpha component
- * +56 INT color space type
- * +60 INT x coordinate of red endpoint
- * +64 INT y coordinate of red endpoint
- * +68 INT z coordinate of red endpoint
- * +72 INT x coordinate of green endpoint
- * +76 INT y coordinate of green endpoint
- * +80 INT z coordinate of green endpoint
- * +84 INT x coordinate of blue endpoint
- * +88 INT y coordinate of blue endpoint
- * +92 INT z coordinate of blue endpoint
- * +96 INT gamma red coordinate scale value
- * +100 INT gamma green coordinate scale value
- * +104 INT gamma blue coordinate scale value
- */
- if (!bmp->ico) {
- width = READ_INT(data, 4);
- height = READ_INT(data, 8);
- if (width < 0)
- return BMP_DATA_ERROR;
- if (height < 0) {
- bmp->reversed = true;
- height = -height;
- }
- bmp->width = width;
- bmp->height = height;
- }
- if (READ_SHORT(data, 12) != 1)
- return BMP_DATA_ERROR;
- bmp->bpp = READ_SHORT(data, 14);
- if (bmp->bpp == 0)
- bmp->bpp = 8;
- bmp->encoding = READ_INT(data, 16);
- if (bmp->encoding > BMP_ENCODING_BITFIELDS)
- return BMP_DATA_ERROR;
- if (bmp->encoding == BMP_ENCODING_BITFIELDS) {
- if ((bmp->bpp != 16) && (bmp->bpp != 32))
- return BMP_DATA_ERROR;
- if (header_size == 40) {
- header_size += 12;
- if (bmp->buffer_size < (14 + header_size))
- return BMP_INSUFFICIENT_DATA;
- for (i = 0; i < 3; i++)
- bmp->mask[i] = READ_INT(data, 40 + (i << 2));
- } else {
- for (i = 0; i < 4; i++)
- bmp->mask[i] = READ_INT(data, 40 + (i << 2));
- }
- for (i = 0; i < 4; i++) {
- if (bmp->mask[i] == 0)
- break;
- for (j = 31; j > 0; j--)
- if (bmp->mask[i] & (1 << j)) {
- if ((j - 7) > 0)
- bmp->mask[i] &= 0xff << (j - 7);
- else
- bmp->mask[i] &= 0xff >> (-(j - 7));
- bmp->shift[i] = (i << 3) - (j - 7);
- break;
- }
- }
- }
- bmp->colours = READ_INT(data, 32);
- if (bmp->colours == 0)
- bmp->colours = (1 << bmp->bpp);
- palette_size = 4;
- }
- data += header_size;
-
- /* we only have a palette for <16bpp */
- if (bmp->bpp < 16) {
- /* we now have a series of palette entries of the format:
- *
- * +0 BYTE blue
- * +1 BYTE green
- * +2 BYTE red
- *
- * if the palette is from an OS/2 or Win2.x file then the entries
- * are padded with an extra byte.
- */
- if (bmp->buffer_size < (14 + header_size + (4 * bmp->colours)))
- return BMP_INSUFFICIENT_DATA;
- bmp->colour_table = (unsigned int *)
- malloc(bmp->colours * sizeof(int));
- if (!bmp->colour_table)
- return BMP_INSUFFICIENT_MEMORY;
- for (i = 0; i < bmp->colours; i++) {
- bmp->colour_table[i] = data[2] | (data[1] << 8) |
- (data[0] << 16);
- data += palette_size;
- }
- }
-
- /* create our bitmap */
- flags = BITMAP_NEW | BITMAP_CLEAR_MEMORY;
- if ((!bmp->ico) && (bmp->mask[3] == 0))
- flags |= BITMAP_OPAQUE;
- bmp->bitmap = bitmap_create(bmp->width, bmp->height, flags);
- if (!bmp->bitmap) {
- if (bmp->colour_table)
- free(bmp->colour_table);
- bmp->colour_table = NULL;
- return BMP_INSUFFICIENT_MEMORY;
- }
- bmp->bitmap_offset = (intptr_t)data - (intptr_t)bmp->bmp_data;
- bitmap_set_suspendable(bmp->bitmap, bmp, bmp_invalidate);
- return BMP_OK;
-}
-
-
-/*
- * Finds the closest BMP within an ICO collection
- *
- * This function finds the BMP with dimensions as close to a specified set
- * as possible from the images in the collection.
- *
- * \param ico the ICO collection to examine
- * \param width the preferred width
- * \param height the preferred height
- */
-struct bmp_image *ico_find(struct ico_collection *ico, int width, int height) {
- struct bmp_image *bmp = NULL;
- struct ico_image *image;
- int x, y, cur, distance = (1 << 24);
-
- for (image = ico->first; image; image = image->next) {
- if (((int)image->bmp.width == width) && ((int)image->bmp.height == height))
- return &image->bmp;
- x = image->bmp.width - width;
- y = image->bmp.height - height;
- cur = (x * x) + (y * y);
- if (cur < distance) {
- distance = cur;
- bmp = &image->bmp;
- }
- }
- return bmp;
-}
-
-
-/**
- * Invalidates a BMP
- *
- * This function sets the BMP into a state such that the bitmap image data
- * can be released from memory.
- *
- * \param bmp the BMP image to invalidate
- */
-void bmp_invalidate(struct bitmap *bitmap, void *private_word) {
- struct bmp_image *bmp = (struct bmp_image *)private_word;
-
- bmp->decoded = false;
-}
-
-
-/**
- * Decode a BMP
- *
- * This function decodes the BMP data such that bmp->bitmap is a valid
- * image. The state of bmp->decoded is set to TRUE on exit such that it
- * can easily be identified which BMPs are in a fully decoded state.
- *
- * \param bmp the BMP image to decode
- * \return BMP_OK on success
- */
-bmp_result bmp_decode(struct bmp_image *bmp) {
- char *data;
- int bytes;
- bmp_result result = BMP_OK;
-
- assert(bmp->bitmap);
-
- data = (char *) bmp->bmp_data + bmp->bitmap_offset;
- bytes = bmp->buffer_size - bmp->bitmap_offset;
-
- switch (bmp->encoding) {
- case BMP_ENCODING_RGB:
- if (bmp->bpp >= 24)
- result = bmp_decode_rgb24(bmp, &data, bytes);
- else if (bmp->bpp > 8)
- result = bmp_decode_rgb16(bmp, &data, bytes);
- else
- result = bmp_decode_rgb(bmp, &data, bytes);
- break;
- case BMP_ENCODING_RLE8:
- result = bmp_decode_rle(bmp, data, bytes, 8);
- break;
- case BMP_ENCODING_RLE4:
- result = bmp_decode_rle(bmp, data, bytes, 4);
- break;
- case BMP_ENCODING_BITFIELDS:
- if (bmp->bpp == 32)
- result = bmp_decode_rgb24(bmp, &data, bytes);
- else if (bmp->bpp == 16)
- result = bmp_decode_rgb16(bmp, &data, bytes);
- else
- return BMP_DATA_ERROR;
- }
-
- if ((!bmp->ico) || (result != BMP_OK))
- return result;
-
- bytes = (intptr_t)bmp->bmp_data + bmp->buffer_size - (intptr_t)data;
- return bmp_decode_mask(bmp, data, bytes);
-}
-
-
-/**
- * Decode BMP data stored in 24bpp colour.
- *
- * \param bmp the BMP image to decode
- * \param start the data to decode, updated to last byte read on success
- * \param bytes the number of bytes of data available
- * \return BMP_OK on success
- */
-bmp_result bmp_decode_rgb24(struct bmp_image *bmp, char **start, int bytes) {
- char *top, *bottom, *end, *data;
- unsigned int *scanline;
- unsigned int x, y, swidth, skip;
- intptr_t addr;
- unsigned int i, word;
-
- data = *start;
- swidth = bitmap_get_rowstride(bmp->bitmap);
- top = bitmap_get_buffer(bmp->bitmap);
- if (!top)
- return BMP_INSUFFICIENT_MEMORY;
- bottom = top + swidth * (bmp->height - 1);
- end = data + bytes;
- addr = ((intptr_t)data) & 3;
- skip = bmp->bpp >> 3;
- bmp->decoded = true;
-
- for (y = 0; y < bmp->height; y++) {
- while (addr != (((intptr_t)data) & 3))
- data++;
- if ((data + (skip * bmp->width)) > end)
- return BMP_INSUFFICIENT_DATA;
- if (bmp->reversed)
- scanline = (unsigned int *)(top + (y * swidth));
- else
- scanline = (unsigned int *)(bottom - (y * swidth));
- if (bmp->encoding == BMP_ENCODING_BITFIELDS) {
- for (x = 0; x < bmp->width; x++) {
- word = data[0] | (data[1] << 8) | (data[2] << 16) |
- (data[3] << 24);
- scanline[x] = (0xff << 24);
- for (i = 0; i < 4; i++)
- if (bmp->shift[i] > 0)
- scanline[x] ^= ((word & bmp->mask[i]) <<
- bmp->shift[i]);
- else
- scanline[x] ^= ((word & bmp->mask[i]) >>
- (-bmp->shift[i]));
- data += 4;
- }
- } else {
- for (x = 0; x < bmp->width; x++) {
- scanline[x] = data[2] | (data[1] << 8) | (data[0] << 16) |
- (data[3] << 24);
- data += skip;
- }
- }
- }
- *start = data;
- return BMP_OK;
-}
-
-
-/**
- * Decode BMP data stored in 16bpp colour.
- *
- * \param bmp the BMP image to decode
- * \param start the data to decode, updated to last byte read on success
- * \param bytes the number of bytes of data available
- * \return BMP_OK on success
- */
-bmp_result bmp_decode_rgb16(struct bmp_image *bmp, char **start, int bytes) {
- char *top, *bottom, *end, *data;
- unsigned int *scanline;
- unsigned int x, y, swidth;
- intptr_t addr;
- unsigned int word, i;
-
- data = *start;
- swidth = bitmap_get_rowstride(bmp->bitmap);
- top = bitmap_get_buffer(bmp->bitmap);
- if (!top)
- return BMP_INSUFFICIENT_MEMORY;
- bottom = top + swidth * (bmp->height - 1);
- end = data + bytes;
- addr = ((intptr_t)data) & 3;
- bmp->decoded = true;
-
- for (y = 0; y < bmp->height; y++) {
- if (addr != (((intptr_t)data) & 3))
- data += 2;
- if ((data + (2 * bmp->width)) > end)
- return BMP_INSUFFICIENT_DATA;
- if (bmp->reversed)
- scanline = (unsigned int *)(top + (y * swidth));
- else
- scanline = (unsigned int *)(bottom - (y * swidth));
- if (bmp->encoding == BMP_ENCODING_BITFIELDS) {
- for (x = 0; x < bmp->width; x++) {
- word = data[0] | (data[1] << 8);
- scanline[x] = (0xff << 24);
- for (i = 0; i < 4; i++)
- if (bmp->shift[i] > 0)
- scanline[x] ^= ((word & bmp->mask[i]) <<
- bmp->shift[i]);
- else
- scanline[x] ^= ((word & bmp->mask[i]) >>
- (-bmp->shift[i]));
- data += 2;
- }
- } else {
- for (x = 0; x < bmp->width; x++) {
- word = data[0] | (data[1] << 8);
- scanline[x] = ((word & (31 << 0)) << 19) |
- ((word & (31 << 5)) << 6) |
- ((word & (31 << 10)) >> 7);
- data += 2;
- }
- }
- }
- *start = data;
- return BMP_OK;
-}
-
-
-/**
- * Decode BMP data stored with a palette and in 8bpp colour or less.
- *
- * \param bmp the BMP image to decode
- * \param start the data to decode, updated to last byte read on success
- * \param bytes the number of bytes of data available
- * \return BMP_OK on success
- */
-bmp_result bmp_decode_rgb(struct bmp_image *bmp, char **start, int bytes) {
- char *top, *bottom, *end, *data;
- unsigned int *scanline;
- intptr_t addr;
- unsigned int x, y, swidth;
- int i;
- int bit_shifts[8];
- int ppb = 8 / bmp->bpp;
- int bit_mask = (1 << bmp->bpp) - 1;
- int cur_byte = 0, bit;
-
- for (i = 0; i < ppb; i++)
- bit_shifts[i] = 8 - ((i + 1) * bmp->bpp);
-
- data = *start;
- swidth = bitmap_get_rowstride(bmp->bitmap);
- top = bitmap_get_buffer(bmp->bitmap);
- if (!top)
- return BMP_INSUFFICIENT_MEMORY;
- bottom = top + swidth * (bmp->height - 1);
- end = data + bytes;
- addr = ((intptr_t)data) & 3;
- bmp->decoded = true;
-
- for (y = 0; y < bmp->height; y++) {
- while (addr != (((intptr_t)data) & 3))
- data++;
- bit = 32;
- if ((data + (bmp->width / ppb)) > end)
- return BMP_INSUFFICIENT_DATA;
- if (bmp->reversed)
- scanline = (unsigned int *)(top + (y * swidth));
- else
- scanline = (unsigned int *)(bottom - (y * swidth));
- for (x = 0; x < bmp->width; x++) {
- if (bit >= ppb) {
- bit = 0;
- cur_byte = *data++;
- }
- scanline[x] = bmp->colour_table[(cur_byte >>
- bit_shifts[bit++]) & bit_mask];
- }
- }
- *start = data;
- return BMP_OK;
-}
-
-
-/**
- * Decode a 1bpp mask for an ICO
- *
- * \param bmp the BMP image to decode
- * \param data the data to decode
- * \param bytes the number of bytes of data available
- * \return BMP_OK on success
- */
-bmp_result bmp_decode_mask(struct bmp_image *bmp, char *data, int bytes) {
- char *top, *bottom, *end;
- unsigned int *scanline;
- intptr_t addr;
- unsigned int x, y, swidth;
- int cur_byte = 0;
-
- swidth = bitmap_get_rowstride(bmp->bitmap);
- top = bitmap_get_buffer(bmp->bitmap);
- if (!top)
- return BMP_INSUFFICIENT_MEMORY;
- bottom = top + swidth * (bmp->height - 1);
- end = data + bytes;
- addr = ((intptr_t)data) & 3;
-
- for (y = 0; y < bmp->height; y++) {
- while (addr != (((intptr_t)data) & 3))
- data++;
- if ((data + (bmp->width >> 3)) > end)
- return BMP_INSUFFICIENT_DATA;
- scanline = (unsigned int *)(bottom - (y * swidth));
- for (x = 0; x < bmp->width; x++) {
- if ((x & 7) == 0)
- cur_byte = *data++;
- if ((cur_byte & 128) == 0)
- scanline[x] |= (0xff << 24);
- cur_byte = cur_byte << 1;
- }
- }
- return BMP_OK;
-}
-
-
-/**
- * Decode BMP data stored encoded in either RLE4 or RLE8.
- *
- * \param bmp the BMP image to decode
- * \param data the data to decode
- * \param bytes the number of bytes of data available
- * \param size the size of the RLE tokens (4 or 8)
- * \return BMP_OK on success
- */
-bmp_result bmp_decode_rle(struct bmp_image *bmp, char *data, int bytes, int size) {
- char *top, *bottom, *end;
- unsigned int *scanline;
- unsigned int swidth;
- int i, length, pixels_left;
- unsigned int x = 0, y = 0, last_y = 0;
- unsigned int pixel = 0, pixel2;
-
- if (bmp->ico)
- return BMP_DATA_ERROR;
-
- swidth = bitmap_get_rowstride(bmp->bitmap);
- top = bitmap_get_buffer(bmp->bitmap);
- if (!top)
- return BMP_INSUFFICIENT_MEMORY;
- bottom = top + swidth * (bmp->height - 1);
- end = data + bytes;
- bmp->decoded = true;
-
- do {
- if (data + 2 > end)
- return BMP_INSUFFICIENT_DATA;
- length = *data++;
- if (length == 0) {
- length = *data++;
- if (length == 0) {
- /* 00 - 00 means end of scanline */
- x = 0;
- if (last_y == y) {
- if (++y > bmp->height)
- return BMP_DATA_ERROR;
- }
- last_y = y;
- } else if (length == 1) {
- /* 00 - 01 means end of RLE data */
- return BMP_OK;
- } else if (length == 2) {
- /* 00 - 02 - XX - YY means move cursor */
- if (data + 2 > end)
- return BMP_INSUFFICIENT_DATA;
- x += *data++;
- if (x >= bmp->width)
- return BMP_DATA_ERROR;
- y += *data++;
- if (y >= bmp->height)
- return BMP_DATA_ERROR;
- } else {
- /* 00 - NN means escape NN pixels */
- if (bmp->reversed) {
- pixels_left = (y + 1) * bmp->width - x;
- scanline = (unsigned int *)(top + (y * swidth));
- } else {
- pixels_left = (bmp->height - y + 1) * bmp->width - x;
- scanline = (unsigned int *)(bottom - (y * swidth));
- }
- if (length > pixels_left)
- length = pixels_left;
- if (data + length > end)
- return BMP_INSUFFICIENT_DATA;
-
- /* the following code could be easily optimised by simply
- * checking the bounds on entry and using some simply copying
- * routines if so */
- if (size == 8) {
- for (i = 0; i < length; i++) {
- if (x >= bmp->width) {
- x = 0;
- if (++y > bmp->height)
- return BMP_DATA_ERROR;
- scanline -= bmp->width;
- }
- scanline[x++] = bmp->colour_table[(int)*data++];
- }
- } else {
- for (i = 0; i < length; i++) {
- if (x >= bmp->width) {
- x = 0;
- if (++y > bmp->height)
- return BMP_DATA_ERROR;
- scanline -= bmp->width;
- }
- if ((i & 1) == 0) {
- pixel = *data++;
- scanline[x++] = bmp->colour_table
- [pixel >> 4];
- } else {
- scanline[x++] = bmp->colour_table
- [pixel & 0xf];
- }
- }
- length = (length + 1) >> 1;
- }
- if ((length & 1) && (*data++ != 0x00))
- return BMP_DATA_ERROR;
-
- }
- } else {
- /* NN means perform RLE for NN pixels */
- if (bmp->reversed) {
- pixels_left = (y + 1) * bmp->width - x;
- scanline = (unsigned int *)(top + (y * swidth));
- } else {
- pixels_left = (bmp->height - y + 1) * bmp->width - x;
- scanline = (unsigned int *)(bottom - (y * swidth));
- }
- if (length > pixels_left)
- length = pixels_left;
-
- /* the following code could be easily optimised by simply
- * checking the bounds on entry and using some simply copying
- * routines if so */
- if (size == 8) {
- pixel = bmp->colour_table[(int)*data++];
- for (i = 0; i < length; i++) {
- if (x >= bmp->width) {
- x = 0;
- if (++y > bmp->height)
- return BMP_DATA_ERROR;
- scanline -= bmp->width;
- }
- scanline[x++] = pixel;
- }
- } else {
- pixel2 = *data++;
- pixel = bmp->colour_table[pixel2 >> 4];
- pixel2 = bmp->colour_table[pixel2 & 0xf];
- for (i = 0; i < length; i++) {
- if (x >= bmp->width) {
- x = 0;
- if (++y > bmp->height)
- return BMP_DATA_ERROR;
- scanline -= bmp->width;
- }
- if ((i & 1) == 0)
- scanline[x++] = pixel;
- else
- scanline[x++] = pixel2;
- }
- }
- }
- } while (data < end);
- return BMP_OK;
-}
-
-
-/**
- * Finalise a BMP prior to destruction.
- *
- * \param bmp the BMP image to finalise
- */
-void bmp_finalise(struct bmp_image *bmp) {
- if (bmp->bitmap)
- bitmap_destroy(bmp->bitmap);
- bmp->bitmap = NULL;
- if (bmp->colour_table)
- free(bmp->colour_table);
- bmp->colour_table = NULL;
-}
-
-
-/**
- * Finalise an ICO prior to destruction.
- *
- * \param ico the ICO image to finalise
- */
-void ico_finalise(struct ico_collection *ico) {
- struct ico_image *image;
-
- for (image = ico->first; image; image = image->next)
- bmp_finalise(&image->bmp);
- while (ico->first) {
- image = ico->first;
- ico->first = image->next;
- free(image);
- }
-}
Removed: branches/dynis/netsurf/image/bmpread.h
URL: http://source.netsurf-browser.org/branches/dynis/netsurf/image/bmpread.h?...
==============================================================================
--- branches/dynis/netsurf/image/bmpread.h (original)
+++ branches/dynis/netsurf/image/bmpread.h (removed)
@@ -1,84 +1,0 @@
-/*
- * Copyright 2006 Richard Wilson <info(a)tinct.net>
- *
- * 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
- * BMP file decoding (interface).
- */
-
-#ifndef _NETSURF_IMAGE_BMPREAD_H_
-#define _NETSURF_IMAGE_BMPREAD_H_
-
-#include <stdbool.h>
-#include "image/bitmap.h"
-
-/* error return values */
-typedef enum {
- BMP_OK = 0,
- BMP_INSUFFICIENT_MEMORY = 1,
- BMP_INSUFFICIENT_DATA = 2,
- BMP_DATA_ERROR = 3
-} bmp_result;
-
-/* encoding types */
-typedef enum {
- BMP_ENCODING_RGB = 0,
- BMP_ENCODING_RLE8 = 1,
- BMP_ENCODING_RLE4 = 2,
- BMP_ENCODING_BITFIELDS = 3
-} bmp_encoding;
-
-struct bmp_image {
- unsigned char *bmp_data; /** pointer to BMP data */
- unsigned int buffer_size; /** total number of bytes of BMP data available */
- unsigned int width; /** width of BMP (valid after _analyse) */
- unsigned int height; /** heigth of BMP (valid after _analyse) */
- bmp_encoding encoding; /** pixel encoding type */
- unsigned int bitmap_offset; /** offset of bitmap data */
- unsigned int bpp; /** bits per pixel */
- unsigned int colours; /** number of colours */
- unsigned int *colour_table; /** colour table */
- bool reversed; /** scanlines are top to bottom */
- bool decoded; /** whether the image has been decoded */
- bool ico; /** image is part of an ICO, mask follows */
- unsigned int mask[4]; /** four bitwise mask */
- int shift[4]; /** four bitwise shifts */
- struct bitmap *bitmap; /** decoded image */
-};
-
-struct ico_image {
- struct bmp_image bmp;
- struct ico_image *next;
-};
-
-struct ico_collection {
- unsigned char *ico_data; /** pointer to ICO data */
- unsigned int buffer_size; /** total number of bytes of ICO data available */
- unsigned int width; /** width of largest BMP */
- unsigned int height; /** heigth of largest BMP */
- struct ico_image *first;
-};
-
-bmp_result bmp_analyse(struct bmp_image *bmp);
-bmp_result bmp_decode(struct bmp_image *bmp);
-void bmp_finalise(struct bmp_image *bmp);
-
-bmp_result ico_analyse(struct ico_collection *ico);
-struct bmp_image *ico_find(struct ico_collection *ico, int width, int height);
-void ico_finalise(struct ico_collection *ico);
-
-#endif
14 years, 11 months