summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2012-11-07 22:52:03 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2012-11-07 22:52:03 +0000
commit55c6841eca063e8fe4db0b8ac67c8a61da9b7312 (patch)
tree17e0ed1b1d0130404e15e73708903c3ed729a6b6
parentf37a8ad58be683bc42e7cff692c78797a580b921 (diff)
parent9482bb464a157265a555dfa38fcf2dc37ade12fd (diff)
downloadnetsurf-55c6841eca063e8fe4db0b8ac67c8a61da9b7312.tar.gz
netsurf-55c6841eca063e8fe4db0b8ac67c8a61da9b7312.tar.bz2
Merge branch 'master' of git://git.netsurf-browser.org/netsurf
-rw-r--r--Makefile.sources2
-rw-r--r--Makefile.sources.javascript1
-rw-r--r--amiga/font_scan.c1
-rwxr-xr-xatari/plot/plot.c693
-rw-r--r--gtk/Makefile.target12
-rw-r--r--javascript/jsapi/binding.h14
-rw-r--r--javascript/jsapi/dom.bnd5
-rw-r--r--javascript/jsapi/htmldocument.bnd83
-rw-r--r--javascript/jsapi/text.bnd44
-rw-r--r--javascript/jsapi/window.bnd5
-rw-r--r--render/html.c43
-rw-r--r--utils/domutils.c66
-rw-r--r--utils/domutils.h24
13 files changed, 597 insertions, 396 deletions
diff --git a/Makefile.sources b/Makefile.sources
index 32db5e666..50dec8e5a 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -19,7 +19,7 @@ S_RENDER := box.c box_construct.c box_normalise.c \
S_UTILS := base64.c corestrings.c filename.c filepath.c hashtable.c \
libdom.c locale.c log.c messages.c nsurl.c talloc.c url.c \
- utf8.c utils.c useragent.c
+ utf8.c utils.c useragent.c domutils.c
S_HTTP := challenge.c generics.c primitives.c parameter.c \
content-disposition.c content-type.c www-authenticate.c
diff --git a/Makefile.sources.javascript b/Makefile.sources.javascript
index da7c2101e..88412ec57 100644
--- a/Makefile.sources.javascript
+++ b/Makefile.sources.javascript
@@ -19,6 +19,7 @@ JSAPI_BINDING_console := javascript/jsapi/console.bnd
JSAPI_BINDING_location := javascript/jsapi/location.bnd
JSAPI_BINDING_htmlcollection := javascript/jsapi/htmlcollection.bnd
JSAPI_BINDING_nodelist := javascript/jsapi/nodelist.bnd
+JSAPI_BINDING_text := javascript/jsapi/text.bnd
# 1: input file
# 2: output file
diff --git a/amiga/font_scan.c b/amiga/font_scan.c
index 449397605..8f909ad29 100644
--- a/amiga/font_scan.c
+++ b/amiga/font_scan.c
@@ -313,7 +313,6 @@ ULONG ami_font_scan_list(struct MinList *list)
}
}
}
- af++;
}
FreeVec(afh);
} else {
diff --git a/atari/plot/plot.c b/atari/plot/plot.c
index 66407ffa6..ca3f2b726 100755
--- a/atari/plot/plot.c
+++ b/atari/plot/plot.c
@@ -159,8 +159,8 @@ static struct s_vdi_sysinfo vdi_sysinfo;
static int atari_plot_bpp_virt;
static struct s_view view;
-static HermesHandle hermes_pal_h; /* hermes palette handle */
-static HermesHandle hermes_cnv_h; /* hermes converter instance handle */
+static HermesHandle hermes_pal_h; /* hermes palette handle */
+static HermesHandle hermes_cnv_h; /* hermes converter instance handle */
static HermesHandle hermes_res_h;
static short prev_vdi_clip[4];
@@ -232,118 +232,118 @@ inline static void vsf_rgbcolor(short vdih, colour cin)
}
-
+
/**
- * Get current visible coords
+ * Get current visible coords
*/
-inline static void plot_get_visible_grect(GRECT * out)
-{
- out->g_x = view.vis_x;
- out->g_y = view.vis_y;
- out->g_w = view.vis_w;
- out->g_h = view.vis_h;
+inline static void plot_get_visible_grect(GRECT * out)
+{
+ out->g_x = view.vis_x;
+ out->g_y = view.vis_y;
+ out->g_w = view.vis_w;
+ out->g_h = view.vis_h;
}
-
-
+
+
/* calculate visible area of framebuffer in coords relative to framebuffer */
/* position */
-/* result: */
+/* result: */
/* this function should calculates an rectangle relative to the plot origin*/
/* and size. */
-/* If the ploter coords do not fall within the screen region, */
-/* all values of the region are set to zero. */
-inline static void update_visible_rect(void)
-{
- GRECT screen;
- GRECT common;
- GRECT frame;
-
- screen.g_x = 0;
- screen.g_y = 0;
- screen.g_w = vdi_sysinfo.scr_w;
+/* If the ploter coords do not fall within the screen region, */
+/* all values of the region are set to zero. */
+inline static void update_visible_rect(void)
+{
+ GRECT screen;
+ GRECT common;
+ GRECT frame;
+
+ screen.g_x = 0;
+ screen.g_y = 0;
+ screen.g_w = vdi_sysinfo.scr_w;
screen.g_h = vdi_sysinfo.scr_h;
-
- common.g_x = frame.g_x = view.x;
- common.g_y = frame.g_y = view.y;
- common.g_w = frame.g_w = view.w;
+
+ common.g_x = frame.g_x = view.x;
+ common.g_y = frame.g_y = view.y;
+ common.g_w = frame.g_w = view.w;
common.g_h = frame.g_h = view.h;
-
- if( rc_intersect( &screen, &common ) ) {
- view.vis_w = common.g_w;
- view.vis_h = common.g_h;
- if( view.x < screen.g_x )
- view.vis_x = frame.g_w - common.g_w;
- else
- view.vis_x = 0;
- if( view.y <screen.g_y )
- view.vis_y = frame.g_h - common.g_h;
- else
- view.vis_y = 0;
- } else {
- view.vis_w = view.vis_h = 0;
- view.vis_x = view.vis_y = 0;
- }
-}
-
-/* Returns the visible parts of the box (relative coords within framebuffer),*/
-/* relative to screen coords (normally starting at 0,0 ) */
-inline static bool fbrect_to_screen(GRECT box, GRECT * ret)
-{
- GRECT out, vis, screen;
-
- screen.g_x = 0;
- screen.g_y = 0;
- screen.g_w = vdi_sysinfo.scr_w;
- screen.g_h = vdi_sysinfo.scr_h;
-
- /* get visible region: */
- vis.g_x = view.x;
- vis.g_y = view.y;
- vis.g_w = view.w;
- vis.g_h = view.h;
-
- if ( !rc_intersect( &screen, &vis ) ) {
- return( false );
- }
- vis.g_x = view.w - vis.g_w;
- vis.g_y = view.h - vis.g_h;
-
- /* clip box to visible region: */
- if( !rc_intersect(&vis, &box) ) {
- return( false );
- }
- out.g_x = box.g_x + view.x;
- out.g_y = box.g_y + view.y;
- out.g_w = box.g_w;
- out.g_h = box.g_h;
- *ret = out;
- return ( true );
+
+ if( rc_intersect( &screen, &common ) ) {
+ view.vis_w = common.g_w;
+ view.vis_h = common.g_h;
+ if( view.x < screen.g_x )
+ view.vis_x = frame.g_w - common.g_w;
+ else
+ view.vis_x = 0;
+ if( view.y <screen.g_y )
+ view.vis_y = frame.g_h - common.g_h;
+ else
+ view.vis_y = 0;
+ } else {
+ view.vis_w = view.vis_h = 0;
+ view.vis_x = view.vis_y = 0;
+ }
+}
+
+/* Returns the visible parts of the box (relative coords within framebuffer),*/
+/* relative to screen coords (normally starting at 0,0 ) */
+inline static bool fbrect_to_screen(GRECT box, GRECT * ret)
+{
+ GRECT out, vis, screen;
+
+ screen.g_x = 0;
+ screen.g_y = 0;
+ screen.g_w = vdi_sysinfo.scr_w;
+ screen.g_h = vdi_sysinfo.scr_h;
+
+ /* get visible region: */
+ vis.g_x = view.x;
+ vis.g_y = view.y;
+ vis.g_w = view.w;
+ vis.g_h = view.h;
+
+ if ( !rc_intersect( &screen, &vis ) ) {
+ return( false );
+ }
+ vis.g_x = view.w - vis.g_w;
+ vis.g_y = view.h - vis.g_h;
+
+ /* clip box to visible region: */
+ if( !rc_intersect(&vis, &box) ) {
+ return( false );
+ }
+ out.g_x = box.g_x + view.x;
+ out.g_y = box.g_y + view.y;
+ out.g_w = box.g_w;
+ out.g_h = box.g_h;
+ *ret = out;
+ return ( true );
}
/* convert framebuffer clipping to vdi clipping and activates it */
-inline static void plot_vdi_clip(bool set)
+inline static void plot_vdi_clip(bool set)
{
// TODO : check this
- return;
- if( set == true ) {
- struct rect c;
- short vdiflags[58];
+ return;
+ if( set == true ) {
+ struct rect c;
+ short vdiflags[58];
short newclip[4];
- plot_get_clip(&c);
- vq_extnd(atari_plot_vdi_handle, 1, (short*)&vdiflags);
- prev_vdi_clip[0] = vdiflags[45];
- prev_vdi_clip[1] = vdiflags[46];
- prev_vdi_clip[2] = vdiflags[47];
- prev_vdi_clip[3] = vdiflags[48];
- newclip[0] = view.x + MAX(c.x0, 0);
- newclip[1] = view.y + MAX(c.y0, 0);
- newclip[2] = MIN(view.x+view.w, newclip[0] + (c.x1 - c.x0) )-1;
- newclip[3] = MIN(view.y+view.h, newclip[1] + (c.y1 - c.y0) )-1;
- vs_clip(atari_plot_vdi_handle, 1, (short*)&newclip );
- } else {
- vs_clip(atari_plot_vdi_handle, 1, (short *)&prev_vdi_clip );
- }
+ plot_get_clip(&c);
+ vq_extnd(atari_plot_vdi_handle, 1, (short*)&vdiflags);
+ prev_vdi_clip[0] = vdiflags[45];
+ prev_vdi_clip[1] = vdiflags[46];
+ prev_vdi_clip[2] = vdiflags[47];
+ prev_vdi_clip[3] = vdiflags[48];
+ newclip[0] = view.x + MAX(c.x0, 0);
+ newclip[1] = view.y + MAX(c.y0, 0);
+ newclip[2] = MIN(view.x+view.w, newclip[0] + (c.x1 - c.x0) )-1;
+ newclip[3] = MIN(view.y+view.h, newclip[1] + (c.y1 - c.y0) )-1;
+ vs_clip(atari_plot_vdi_handle, 1, (short*)&newclip );
+ } else {
+ vs_clip(atari_plot_vdi_handle, 1, (short *)&prev_vdi_clip );
+ }
}
@@ -562,12 +562,12 @@ inline void vdi1000_to_rgb(unsigned short * in, unsigned char * out)
/**
* Set pixel within an 8 bit VDI standard bitmap.
*/
-inline static void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned char val )
-{
- short * buf;
- short whichbit = (1<<(15-(x%16)));
-
- buf = dst->fd_addr;
+inline static void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned char val )
+{
+ short * buf;
+ short whichbit = (1<<(15-(x%16)));
+
+ buf = dst->fd_addr;
buf += ((dst->fd_wdwidth*(y))+(x>>4));
*buf = (val&1) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
@@ -591,7 +591,7 @@ inline static void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned
*buf = (val&(1<<6)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
buf += wdplanesz;
- *buf = (val&(1<<7)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
+ *buf = (val&(1<<7)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
}
/**
@@ -600,10 +600,10 @@ inline static void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned
inline static unsigned char get_stdpx(MFDB * dst, int wdplanesz, int x, int y)
{
unsigned char ret=0;
- short * buf;
- short whichbit = (1<<(15-(x%16)));
-
- buf = dst->fd_addr;
+ short * buf;
+ short whichbit = (1<<(15-(x%16)));
+
+ buf = dst->fd_addr;
buf += ((dst->fd_wdwidth*(y))+(x>>4));
if( *buf & whichbit )
@@ -933,19 +933,19 @@ static void snapshot_destroy(void)
}
-inline static uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
-{
- int opacity = pixel & 0xFF;
- int transp = 0x100 - opacity;
- uint32_t rb, g;
- pixel >>= 8;
- scrpixel >>= 8;
- rb = ((pixel & 0xFF00FF) * opacity +
- (scrpixel & 0xFF00FF) * transp) >> 8;
- g = ((pixel & 0x00FF00) * opacity +
- (scrpixel & 0x00FF00) * transp) >> 8;
-
- return ((rb & 0xFF00FF) | (g & 0xFF00)) << 8;
+inline static uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
+{
+ int opacity = pixel & 0xFF;
+ int transp = 0x100 - opacity;
+ uint32_t rb, g;
+ pixel >>= 8;
+ scrpixel >>= 8;
+ rb = ((pixel & 0xFF00FF) * opacity +
+ (scrpixel & 0xFF00FF) * transp) >> 8;
+ g = ((pixel & 0x00FF00) * opacity +
+ (scrpixel & 0x00FF00) * transp) >> 8;
+
+ return ((rb & 0xFF00FF) | (g & 0xFF00)) << 8;
}
/*
@@ -959,11 +959,11 @@ inline static bool ablend_pixel(struct bitmap * img, uint32_t bg, GRECT * clip)
img_stride= bitmap_get_rowstride(img);
- for( img_y = 0; img_y < clip->g_h; img_y++) {
- imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
+ for( img_y = 0; img_y < clip->g_h; img_y++) {
+ imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
for( img_x = 0; img_x < clip->g_w; img_x++ ) {
- imgrow[img_x] = ablend( imgrow[img_x], bg );
- }
+ imgrow[img_x] = ablend( imgrow[img_x], bg );
+ }
}
return(true);
}
@@ -977,38 +977,38 @@ inline static bool ablend_pixel(struct bitmap * img, uint32_t bg, GRECT * clip)
inline static bool ablend_bitmap( struct bitmap * img, struct bitmap * bg,
GRECT * img_clip, GRECT * bg_clip )
{
- uint32_t * imgrow;
- uint32_t * screenrow;
+ uint32_t * imgrow;
+ uint32_t * screenrow;
int img_x, img_y, bg_x, bg_y, img_stride, bg_stride;
bg_clip = bg_clip;
img_stride= bitmap_get_rowstride(img);
bg_stride = bitmap_get_rowstride(bg);
- for( img_y = img_clip->g_y, bg_y = 0; bg_y < img_clip->g_h; bg_y++, img_y++) {
- imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
- screenrow = (uint32_t *)(bg->pixdata + (bg_stride * bg_y));
+ for( img_y = img_clip->g_y, bg_y = 0; bg_y < img_clip->g_h; bg_y++, img_y++) {
+ imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
+ screenrow = (uint32_t *)(bg->pixdata + (bg_stride * bg_y));
for( img_x = img_clip->g_x, bg_x = 0; bg_x < img_clip->g_w; bg_x++, img_x++ ) {
// when the pixel isn't fully transparent,...:
- if( (imgrow[img_x] & 0x0FF) != 0 ){
- screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
+ if( (imgrow[img_x] & 0x0FF) != 0 ){
+ screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
}
// FIXME, maybe this loop would be faster??:
// ---
- //if( (imgrow[img_x] & 0x0FF) != 0xFF ){
- // imgrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
+ //if( (imgrow[img_x] & 0x0FF) != 0xFF ){
+ // imgrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
//}
// or maybe even this???
// ---
//if( (imgrow[img_x] & 0x0FF) == 0xFF ){
- // screenrow[bg_x] = imgrow[img_x];
+ // screenrow[bg_x] = imgrow[img_x];
//} else if( (imgrow[img_x] & 0x0FF) != 0x00 ) {
// screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
- //}
- }
+ //}
+ }
}
return(false);
}
@@ -1021,13 +1021,13 @@ static bool bitmap_convert_8(struct bitmap * img, int x,
{
MFDB native;
MFDB stdform;
- int dststride; /* stride of dest. image */
- int dstsize; /* size of dest. in byte */
- int err;
+ int dststride; /* stride of dest. image */
+ int dstsize; /* size of dest. in byte */
+ int err;
int bw, bh;
int process_w, process_h;
struct bitmap * scrbuf = NULL;
- struct bitmap * source;
+ struct bitmap * source;
bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
bool opaque = bitmap_get_opaque( img );
@@ -1090,7 +1090,7 @@ static bool bitmap_convert_8(struct bitmap * img, int x,
assert( out->fd_addr == NULL );
native.fd_addr = (void*)malloc( dstsize );
if (native.fd_addr == NULL){
- if (scrbuf != NULL)
+ if (scrbuf != NULL)
bitmap_destroy(scrbuf);
return( 0-ERR_NO_MEM );
}
@@ -1233,16 +1233,16 @@ static bool bitmap_convert_8(struct bitmap * img, int x,
* bg: background color
* flags: blit flags
* out: the result MFDB
-*/
+*/
static bool bitmap_convert_tc(struct bitmap * img, int x, int y,
- GRECT * clip, uint32_t bg, uint32_t flags, MFDB *out )
-{
- int dststride; /* stride of dest. image */
- int dstsize; /* size of dest. in byte */
- int err;
+ GRECT * clip, uint32_t bg, uint32_t flags, MFDB *out )
+{
+ int dststride; /* stride of dest. image */
+ int dstsize; /* size of dest. in byte */
+ int err;
int bw, bh;
struct bitmap * scrbuf = NULL;
- struct bitmap * source = NULL;
+ struct bitmap * source = NULL;
bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
bool opaque = bitmap_get_opaque( img );
@@ -1253,9 +1253,9 @@ static bool bitmap_convert_tc(struct bitmap * img, int x, int y,
opaque = true;
}
}
-
-
- assert( clip->g_h > 0 );
+
+
+ assert( clip->g_h > 0 );
assert( clip->g_w > 0 );
bw = bitmap_get_width( img );
@@ -1282,13 +1282,13 @@ static bool bitmap_convert_tc(struct bitmap * img, int x, int y,
}
}
- /* rem. if eddi xy is installed, we could directly access the screen! */
- /* apply transparency to the image: */
+ /* rem. if eddi xy is installed, we could directly access the screen! */
+ /* apply transparency to the image: */
if (( opaque == false )) {
/* copy the screen to an temp buffer: */
if ((flags & BITMAPF_BUFFER_NATIVE) == 0) {
- scrbuf = snapshot_create(x, y, clip->g_w, clip->g_h);
- if( scrbuf != NULL ) {
+ scrbuf = snapshot_create(x, y, clip->g_w, clip->g_h);
+ if( scrbuf != NULL ) {
assert( clip->g_w <= bw );
assert( clip->g_h <= bh );
@@ -1302,7 +1302,7 @@ static bool bitmap_convert_tc(struct bitmap * img, int x, int y,
clip->g_x = 0;
clip->g_y = 0;
/* set the source of conversion: */
- source = scrbuf;
+ source = scrbuf;
}
} else {
/*
@@ -1315,213 +1315,213 @@ static bool bitmap_convert_tc(struct bitmap * img, int x, int y,
}
} else {
source = img;
- }
- /* (re)allocate buffer for converted image: */
- dststride = MFDB_STRIDE(bw);
+ }
+ /* (re)allocate buffer for converted image: */
+ dststride = MFDB_STRIDE(bw);
dstsize = ( ((dststride >> 3) * bh) * atari_plot_bpp_virt );
- if (cache == false) {
- if (dstsize > size_buf_packed) {
- int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
- if( buf_packed == NULL )
- buf_packed =(void*)malloc( blocks * CONV_BLOCK_SIZE );
- else
+ if (cache == false) {
+ if (dstsize > size_buf_packed) {
+ int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
+ if( buf_packed == NULL )
+ buf_packed =(void*)malloc( blocks * CONV_BLOCK_SIZE );
+ else
buf_packed =(void*)realloc(buf_packed,
- blocks * CONV_BLOCK_SIZE);
- assert( buf_packed );
- if( buf_packed == NULL ) {
- if( scrbuf != NULL )
- bitmap_destroy( scrbuf );
- return( 0-ERR_NO_MEM );
- }
- size_buf_packed = blocks * CONV_BLOCK_SIZE;
+ blocks * CONV_BLOCK_SIZE);
+ assert( buf_packed );
+ if( buf_packed == NULL ) {
+ if( scrbuf != NULL )
+ bitmap_destroy( scrbuf );
+ return( 0-ERR_NO_MEM );
+ }
+ size_buf_packed = blocks * CONV_BLOCK_SIZE;
}
out->fd_addr = buf_packed;
} else {
assert( out->fd_addr == NULL );
out->fd_addr = (void*)malloc( dstsize );
if( out->fd_addr == NULL ){
- if( scrbuf != NULL )
+ if( scrbuf != NULL )
bitmap_destroy( scrbuf );
return( 0-ERR_NO_MEM );
}
- }
-
- out->fd_w = dststride;
- out->fd_h = bh;
- out->fd_wdwidth = dststride >> 4;
- out->fd_stand = 0;
- out->fd_nplanes = (short)atari_plot_bpp_virt;
- out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
-
- err = Hermes_ConverterRequest(
- hermes_cnv_h,
- &nsfmt,
- &vfmt
- );
+ }
+
+ out->fd_w = dststride;
+ out->fd_h = bh;
+ out->fd_wdwidth = dststride >> 4;
+ out->fd_stand = 0;
+ out->fd_nplanes = (short)atari_plot_bpp_virt;
+ out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
+
+ err = Hermes_ConverterRequest(
+ hermes_cnv_h,
+ &nsfmt,
+ &vfmt
+ );
assert( err != 0 );
// FIXME: here we can use the same optimization which is used for
// the snapshot creation.
- /* convert image to virtual format: */
- err = Hermes_ConverterCopy( hermes_cnv_h,
- source->pixdata,
- 0, /* x src coord of top left in pixel coords */
- 0, /* y src coord of top left in pixel coords */
- bw, bh,
- source->rowstride, /* stride as bytes */
- out->fd_addr,
- 0, /* x dst coord of top left in pixel coords */
- 0, /* y dst coord of top left in pixel coords */
- bw, bh,
- (dststride >> 3) * atari_plot_bpp_virt /* stride as bytes */
+ /* convert image to virtual format: */
+ err = Hermes_ConverterCopy( hermes_cnv_h,
+ source->pixdata,
+ 0, /* x src coord of top left in pixel coords */
+ 0, /* y src coord of top left in pixel coords */
+ bw, bh,
+ source->rowstride, /* stride as bytes */
+ out->fd_addr,
+ 0, /* x dst coord of top left in pixel coords */
+ 0, /* y dst coord of top left in pixel coords */
+ bw, bh,
+ (dststride >> 3) * atari_plot_bpp_virt /* stride as bytes */
);
assert( err != 0 );
if( cache == true ){
img->native = *out;
img->converted = true;
- }
- return( 0 );
-
-}
-
- inline static void convert_bitmap_done(void)
-{
- if (size_buf_packed > CONV_KEEP_LIMIT) {
- /* free the mem if it was an large allocation ... */
- buf_packed = realloc(buf_packed, CONV_KEEP_LIMIT);
- size_buf_packed = CONV_KEEP_LIMIT;
- }
-}
-
-
-bool plot_blit_bitmap(struct bitmap * bmp, int x, int y,
- unsigned long bg, unsigned long flags )
-{
- MFDB src_mf;
- MFDB scrmf;
- short pxy[8];
+ }
+ return( 0 );
+
+}
+
+ inline static void convert_bitmap_done(void)
+{
+ if (size_buf_packed > CONV_KEEP_LIMIT) {
+ /* free the mem if it was an large allocation ... */
+ buf_packed = realloc(buf_packed, CONV_KEEP_LIMIT);
+ size_buf_packed = CONV_KEEP_LIMIT;
+ }
+}
+
+
+bool plot_blit_bitmap(struct bitmap * bmp, int x, int y,
+ unsigned long bg, unsigned long flags )
+{
+ MFDB src_mf;
+ MFDB scrmf;
+ short pxy[8];
GRECT off, clip, vis;
- int screen_x, screen_y;
-
- src_mf.fd_addr = NULL;
- scrmf.fd_addr = NULL;
-
- off.g_x = x;
- off.g_y = y;
- off.g_h = bmp->height;
+ int screen_x, screen_y;
+
+ src_mf.fd_addr = NULL;
+ scrmf.fd_addr = NULL;
+
+ off.g_x = x;
+ off.g_y = y;
+ off.g_h = bmp->height;
off.g_w = bmp->width;
- // clip plotter clip rectangle:
- clip.g_x = view.clipping.x0;
- clip.g_y = view.clipping.y0;
- clip.g_w = view.clipping.x1 - view.clipping.x0;
- clip.g_h = view.clipping.y1 - view.clipping.y0;
-
- if( !rc_intersect( &clip, &off) ) {
- return(true);
+ // clip plotter clip rectangle:
+ clip.g_x = view.clipping.x0;
+ clip.g_y = view.clipping.y0;
+ clip.g_w = view.clipping.x1 - view.clipping.x0;
+ clip.g_h = view.clipping.y1 - view.clipping.y0;
+
+ if( !rc_intersect( &clip, &off) ) {
+ return(true);
}
// clip the visible rectangle of the plot area
// this is the area of the plotter which falls into
- // screen region:
+ // screen region:
plot_get_visible_grect(&vis);
- if( !rc_intersect( &vis, &off) ) {
- return(true);
- }
+ if( !rc_intersect( &vis, &off) ) {
+ return(true);
+ }
screen_x = view.x + off.g_x;
screen_y = view.y + off.g_y;
- // convert the clipping relative to bitmap:
- off.g_x = off.g_x - x;
+ // convert the clipping relative to bitmap:
+ off.g_x = off.g_x - x;
off.g_y = off.g_y - y;
assert( (off.g_x >= 0) && (off.g_y >= 0) );
/* Convert the Bitmap to native screen format - ready for output. */
/* This includes blending transparent pixels: */
if (bitmap_convert(bmp, screen_x, screen_y, &off, bg, flags, &src_mf)
- != 0 ) {
- return(true);
+ != 0 ) {
+ return(true);
}
-
- // setup the src region:
- pxy[0] = off.g_x;
- pxy[1] = off.g_y;
- pxy[2] = off.g_x + off.g_w-1;
+
+ // setup the src region:
+ pxy[0] = off.g_x;
+ pxy[1] = off.g_y;
+ pxy[2] = off.g_x + off.g_w-1;
pxy[3] = off.g_y + off.g_h-1;
- // setup the target region:
- pxy[4] = screen_x;
- pxy[5] = screen_y;
- pxy[6] = screen_x + off.g_w-1;
+ // setup the target region:
+ pxy[4] = screen_x;
+ pxy[5] = screen_y;
+ pxy[6] = screen_x + off.g_w-1;
pxy[7] = screen_y + off.g_h-1;
- vro_cpyfm(atari_plot_vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf);
+ vro_cpyfm(atari_plot_vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf);
convert_bitmap_done();
- snapshot_suspend();
- return(true);
-}
-
+ snapshot_suspend();
+ return(true);
+}
+
bool plot_blit_mfdb(GRECT * loc, MFDB * insrc, unsigned char fgcolor,
- uint32_t flags)
-{
-
- MFDB screen, tran;
- MFDB * src;
- short pxy[8];
- short c[2] = {fgcolor, WHITE};
- GRECT off;
-
- plot_get_clip_grect(&off);
- if( rc_intersect(loc, &off) == 0 ){
- return( 1 );
- }
-
- init_mfdb( 0, loc->g_w, loc->g_h, 0, &screen );
-
- if( insrc->fd_stand ){
- int size = init_mfdb( insrc->fd_nplanes, loc->g_w, loc->g_h,
- MFDB_FLAG_NOALLOC,
- &tran
- );
- if( size_buf_scr == 0 ){
- buf_scr.fd_addr = malloc( size );
- size_buf_scr = size;
- } else {
- if( size > size_buf_scr ) {
- buf_scr.fd_addr = realloc(
- buf_scr.fd_addr, size
- );
- size_buf_scr = size;
- }
- }
- tran.fd_addr = buf_scr.fd_addr;
- vr_trnfm(atari_plot_vdi_handle, insrc, &tran );
- src = &tran;
- } else {
- src = insrc;
- }
-
- pxy[0] = off.g_x - loc->g_x;
- pxy[1] = off.g_y - loc->g_y;
- pxy[2] = pxy[0] + off.g_w - 1;
- pxy[3] = pxy[1] + off.g_h - 1;
- pxy[4] = view.x + off.g_x;
- pxy[5] = view.y + off.g_y;
- pxy[6] = pxy[4] + off.g_w-1;
- pxy[7] = pxy[5] + off.g_h-1;
-
-
- if( flags & PLOT_FLAG_TRANS && src->fd_nplanes == 1){
- vrt_cpyfm(atari_plot_vdi_handle, MD_TRANS, (short*)pxy, src, &screen, (short*)&c );
- } else {
- /* this method only plots transparent bitmaps, right now... */
- }
- return( 1 );
-}
-
+ uint32_t flags)
+{
+
+ MFDB screen, tran;
+ MFDB * src;
+ short pxy[8];
+ short c[2] = {fgcolor, WHITE};
+ GRECT off;
+
+ plot_get_clip_grect(&off);
+ if( rc_intersect(loc, &off) == 0 ){
+ return( 1 );
+ }
+
+ init_mfdb( 0, loc->g_w, loc->g_h, 0, &screen );
+
+ if( insrc->fd_stand ){
+ int size = init_mfdb( insrc->fd_nplanes, loc->g_w, loc->g_h,
+ MFDB_FLAG_NOALLOC,
+ &tran
+ );
+ if( size_buf_scr == 0 ){
+ buf_scr.fd_addr = malloc( size );
+ size_buf_scr = size;
+ } else {
+ if( size > size_buf_scr ) {
+ buf_scr.fd_addr = realloc(
+ buf_scr.fd_addr, size
+ );
+ size_buf_scr = size;
+ }
+ }
+ tran.fd_addr = buf_scr.fd_addr;
+ vr_trnfm(atari_plot_vdi_handle, insrc, &tran );
+ src = &tran;
+ } else {
+ src = insrc;
+ }
+
+ pxy[0] = off.g_x - loc->g_x;
+ pxy[1] = off.g_y - loc->g_y;
+ pxy[2] = pxy[0] + off.g_w - 1;
+ pxy[3] = pxy[1] + off.g_h - 1;
+ pxy[4] = view.x + off.g_x;
+ pxy[5] = view.y + off.g_y;
+ pxy[6] = pxy[4] + off.g_w-1;
+ pxy[7] = pxy[5] + off.g_h-1;
+
+
+ if( flags & PLOT_FLAG_TRANS && src->fd_nplanes == 1){
+ vrt_cpyfm(atari_plot_vdi_handle, MD_TRANS, (short*)pxy, src, &screen, (short*)&c );
+ } else {
+ /* this method only plots transparent bitmaps, right now... */
+ }
+ return( 1 );
+}
+
/*
Init screen and font driver objects.
Returns non-zero value > -1 when the objects could be succesfully created.
@@ -1543,8 +1543,8 @@ int plot_init(char * fdrvrname)
atari_plot_vdi_handle = app.graf.handle;
read_vdi_sysinfo(atari_plot_vdi_handle, &vdi_sysinfo);
- if( verbose_log ) {
- dump_vdi_info( atari_plot_vdi_handle ) ;
+ if(verbose_log) {
+ dump_vdi_info(atari_plot_vdi_handle) ;
dump_font_drivers();
}
@@ -1840,27 +1840,27 @@ bool plot_line(int x0, int y0, int x1, int y1,
static bool plot_polygon(const int *p, unsigned int n,
const plot_style_t *pstyle)
{
- short pxy[n*2];
- unsigned int i=0;
- short d[4];
- if (vdi_sysinfo.maxpolycoords > 0)
- assert( (signed int)n < vdi_sysinfo.maxpolycoords);
- plot_vdi_clip(true);
- vsf_interior(atari_plot_vdi_handle, FIS_SOLID);
- vsf_style(atari_plot_vdi_handle, 1);
- for (i = 0; i<n*2; i=i+2) {
- pxy[i] = (short)view.x+p[i];
- pxy[i+1] = (short)view.y+p[i+1];
- }
- if (pstyle->fill_type == PLOT_OP_TYPE_SOLID) {
- vsf_rgbcolor(atari_plot_vdi_handle, pstyle->fill_colour);
- v_fillarea(atari_plot_vdi_handle, n, (short*)&pxy);
- } else {
- pxy[n*2]=pxy[0];
- pxy[n*2+1]=pxy[1];
- vsl_rgbcolor(atari_plot_vdi_handle, pstyle->stroke_colour);
- v_pline(atari_plot_vdi_handle, n+1, (short *)&pxy);
- }
+ short pxy[n*2];
+ unsigned int i=0;
+ short d[4];
+ if (vdi_sysinfo.maxpolycoords > 0)
+ assert( (signed int)n < vdi_sysinfo.maxpolycoords);
+ plot_vdi_clip(true);
+ vsf_interior(atari_plot_vdi_handle, FIS_SOLID);
+ vsf_style(atari_plot_vdi_handle, 1);
+ for (i = 0; i<n*2; i=i+2) {
+ pxy[i] = (short)view.x+p[i];
+ pxy[i+1] = (short)view.y+p[i+1];
+ }
+ if (pstyle->fill_type == PLOT_OP_TYPE_SOLID) {
+ vsf_rgbcolor(atari_plot_vdi_handle, pstyle->fill_colour);
+ v_fillarea(atari_plot_vdi_handle, n, (short*)&pxy);
+ } else {
+ pxy[n*2]=pxy[0];
+ pxy[n*2+1]=pxy[1];
+ vsl_rgbcolor(atari_plot_vdi_handle, pstyle->stroke_colour);
+ v_pline(atari_plot_vdi_handle, n+1, (short *)&pxy);
+ }
plot_vdi_clip(false);
return ( true );
}
@@ -1891,19 +1891,20 @@ bool plot_set_dimensions(int x, int y, int w, int h)
bool plot_clip(const struct rect *clip)
{
// FIXME: consider the canvas size
- view.clipping.x0 = clip->x0;
- view.clipping.y0 = clip->y0;
- view.clipping.x1 = clip->x1;
+ view.clipping.x0 = clip->x0;
+ view.clipping.y0 = clip->y0;
+ view.clipping.x1 = clip->x1;
view.clipping.y1 = clip->y1;
+
return ( true );
}
bool plot_get_clip(struct rect * out)
{
- out->x0 = view.clipping.x0;
+ out->x0 = view.clipping.x0;
out->y0 = view.clipping.y0;
- out->x1 = view.clipping.x1;
+ out->x1 = view.clipping.x1;
out->y1 = view.clipping.y1;
return( true );
}
diff --git a/gtk/Makefile.target b/gtk/Makefile.target
index 08d3bbf47..91ffb526e 100644
--- a/gtk/Makefile.target
+++ b/gtk/Makefile.target
@@ -139,12 +139,12 @@ install-gtk:
$(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)throbber
$(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)icons
$(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_BIN)
- $(Q)install -v nsgtk $(DESTDIR)$(NETSURF_GTK_BIN)netsurf
- $(Q)install -v -m 0644 -t $(DESTDIR)$(NETSURF_GTK_RESOURCES) $(GTK_RESOURCES_LIST)
- $(Q)install -v -m 0644 -t $(DESTDIR)$(NETSURF_GTK_RESOURCES)/icons gtk/res/icons/*.png
- $(Q)install -v -m 0644 -t $(DESTDIR)$(NETSURF_GTK_RESOURCES)/throbber gtk/res/throbber/*.png
- $(Q)tar c -h -C gtk/res themes | tar xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES)
- $(Q)tar c -h -C gtk/res $(GTK_TRANSLATIONS_HTML) | tar xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES)
+ $(Q)install nsgtk $(DESTDIR)$(NETSURF_GTK_BIN)netsurf
+ $(Q)install -m 0644 $(GTK_RESOURCES_LIST) $(DESTDIR)$(NETSURF_GTK_RESOURCES)
+ $(Q)install -m 0644 gtk/res/icons/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/icons
+ $(Q)install -m 0644 gtk/res/throbber/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/throbber
+ $(Q)tar -c -h -C gtk/res -f - themes | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f -
+ $(Q)tar -c -h -C gtk/res -f - $(GTK_TRANSLATIONS_HTML) | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f -
$(call split_install_messages, gtk, $(DESTDIR)$(NETSURF_GTK_RESOURCES))
# ----------------------------------------------------------------------------
diff --git a/javascript/jsapi/binding.h b/javascript/jsapi/binding.h
index c1006589e..446fb0c51 100644
--- a/javascript/jsapi/binding.h
+++ b/javascript/jsapi/binding.h
@@ -124,4 +124,18 @@ JSObject *jsapi_new_NodeList(JSContext *cx,
dom_nodelist *nodelist,
struct html_content *htmlc);
+
+JSObject *jsapi_InitClass_Text(JSContext *cx, JSObject *parent);
+/** Create a new javascript text object
+ *
+ * @param cx The javascript context.
+ * @param parent The parent object, usually a global window object
+ * @param node The dom node to use in the object
+ * @return new javascript object or NULL on error
+ */
+JSObject *jsapi_new_Text(JSContext *cx,
+ JSObject *prototype,
+ JSObject *parent,
+ dom_text *node);
+
#endif
diff --git a/javascript/jsapi/dom.bnd b/javascript/jsapi/dom.bnd
index cd252fc27..bf3b44ea3 100644
--- a/javascript/jsapi/dom.bnd
+++ b/javascript/jsapi/dom.bnd
@@ -2,6 +2,8 @@
webidlfile "dom.idl";
+/* interface Node members */
+
getter textContent %{
dom_exception exc;
@@ -21,3 +23,6 @@ getter textContent %{
+operation appendChild %{
+/* void * JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv); */
+%}
diff --git a/javascript/jsapi/htmldocument.bnd b/javascript/jsapi/htmldocument.bnd
index 7574512dd..b642cabe6 100644
--- a/javascript/jsapi/htmldocument.bnd
+++ b/javascript/jsapi/htmldocument.bnd
@@ -12,6 +12,8 @@ preamble %{
#include "utils/config.h"
#include "utils/log.h"
+#include "utils/corestrings.h"
+#include "utils/domutils.h"
#include "content/urldb.h"
@@ -23,13 +25,13 @@ preamble %{
binding document {
type js_libdom; /* the binding type */
+ interface Document; /* Web IDL interface to generate */
+
/* parameters to constructor value stored in private
* context structure.
*/
private "dom_document *" node;
private "struct html_content *" htmlc;
-
- interface Document; /* Web IDL interface to generate */
}
api finalise %{
@@ -49,6 +51,61 @@ getter cookie %{
}
%}
+getter documentElement %{
+ dom_exception exc;
+ dom_element *element;
+
+ /* document (html) element */
+ exc = dom_document_get_document_element(private->node, (void *)&element);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (element != NULL) {
+ jsret = jsapi_new_HTMLElement(cx, NULL, NULL, element, private->htmlc);
+ }
+%}
+
+getter head %{
+ dom_node *element;
+ dom_node *head;
+ dom_exception exc;
+
+ /* document (html) element */
+ exc = dom_document_get_document_element(private->node, &element);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (element != NULL) {
+ head = find_first_named_dom_element(element, corestring_lwc_head) ;
+ if (head != NULL) {
+ jsret = jsapi_new_HTMLElement(cx, NULL, NULL, (dom_element *)head, private->htmlc);
+ }
+ dom_node_unref(element);
+ }
+%}
+
+getter body %{
+ dom_node *element;
+ dom_node *body;
+ dom_exception exc;
+
+ /* document (html) element */
+ exc = dom_document_get_document_element(private->node, &element);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (element != NULL) {
+ body = find_first_named_dom_element(element, corestring_lwc_body) ;
+ if (body != NULL) {
+ jsret = jsapi_new_HTMLElement(cx, NULL, NULL, (dom_element *)body, private->htmlc);
+ }
+ dom_node_unref(element);
+ }
+%}
+
operation getElementById %{
dom_string *elementId_dom;
dom_element *element;
@@ -112,3 +169,25 @@ operation write %{
dom_hubbub_parser_insert_chunk(private->htmlc->parser, (uint8_t *)text, text_len);
}
%}
+
+/* in dom Document */
+operation createTextNode %{
+ dom_string *data_dom;
+ dom_element *element;
+ dom_exception exc;
+ dom_text *text;
+
+ exc = dom_string_create((unsigned char*)data, data_len, &data_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_document_create_text_node(private->node, data_dom, &text);
+ dom_string_unref(data_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ jsret = jsapi_new_Text(cx, NULL, NULL, text);
+
+%}
diff --git a/javascript/jsapi/text.bnd b/javascript/jsapi/text.bnd
new file mode 100644
index 000000000..53e93803d
--- /dev/null
+++ b/javascript/jsapi/text.bnd
@@ -0,0 +1,44 @@
+/* Binding to generate Text interface
+ *
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ * http://www.opensource.org/licenses/mit-license
+ */
+
+#include "dom.bnd"
+
+webidlfile "html.idl";
+
+hdrcomment "Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>";
+hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/";
+hdrcomment "Released under the terms of the MIT License,";
+hdrcomment " http://www.opensource.org/licenses/mit-license";
+
+preamble %{
+
+#include <dom/dom.h>
+
+#include "utils/config.h"
+#include "utils/log.h"
+
+#include "javascript/jsapi.h"
+#include "javascript/jsapi/binding.h"
+
+%}
+
+binding text {
+ type js_libdom; /* the binding type */
+
+ interface Text; /* Web IDL interface to generate */
+
+ private "dom_text *" node;
+}
+
+api finalise %{
+ if (private != NULL) {
+ dom_node_unref(private->node);
+ }
+%}
diff --git a/javascript/jsapi/window.bnd b/javascript/jsapi/window.bnd
index 865cbf3d4..5a7de530f 100644
--- a/javascript/jsapi/window.bnd
+++ b/javascript/jsapi/window.bnd
@@ -130,6 +130,11 @@ api init %{
return NULL;
}
+ user_proto = jsapi_InitClass_Text(cx, prototype);
+ if (user_proto == NULL) {
+ return NULL;
+ }
+
%}
api new %{
diff --git a/render/html.c b/render/html.c
index 4e79e085e..616ae7b2a 100644
--- a/render/html.c
+++ b/render/html.c
@@ -53,6 +53,7 @@
#include "utils/url.h"
#include "utils/utf8.h"
#include "utils/utils.h"
+#include "utils/domutils.h"
#define CHUNK 4096
@@ -464,6 +465,7 @@ parse_chunk_to_nserror(dom_hubbub_error error)
case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_UNKNOWN):
/* currently only generated by the libdom hubbub binding */
+ return NSERROR_DOM;
default:
/* unknown error */
/** @todo better error handling and reporting */
@@ -2030,46 +2032,7 @@ html_begin_conversion(html_content *htmlc)
}
dom_string_unref(node_name);
- /* ensure the head element is found */
- exc = dom_node_get_first_child(html, &head);
- if ((exc != DOM_NO_ERR) || (head == NULL)) {
- head = NULL;
- LOG(("head element not found"));
- } else {
- dom_node_type node_type;
- dom_node *next_node;
-
- /* find first node thats a element */
- do {
- exc = dom_node_get_node_type(head, &node_type);
-
- if ((exc != DOM_NO_ERR) ||
- (node_type == DOM_ELEMENT_NODE))
- break;
-
- exc = dom_node_get_next_sibling(head, &next_node);
- dom_node_unref(head);
- if (exc == DOM_NO_ERR) {
- head = next_node;
- } else {
- head = NULL;
- }
- } while (head != NULL);
-
- if (head != NULL) {
- exc = dom_node_get_node_name(head, &node_name);
- if ((exc == DOM_NO_ERR) || (node_name != NULL)) {
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_head)) {
- dom_node_unref(head);
- LOG(("head element not found"));
- head = NULL;
- }
- dom_string_unref(node_name);
- }
- }
- }
-
+ head = find_first_named_dom_element(html, corestring_lwc_head);
if (head != NULL) {
if (html_head(htmlc, head) == false) {
msg_data.error = messages_get("NoMemory");
diff --git a/utils/domutils.c b/utils/domutils.c
new file mode 100644
index 000000000..4d32a67d8
--- /dev/null
+++ b/utils/domutils.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * 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 <dom/dom.h>
+
+#include "utils/config.h"
+#include "utils/log.h"
+
+#include "domutils.h"
+
+/* search children of a node for first named element */
+dom_node *find_first_named_dom_element(dom_node *parent, lwc_string *element_name)
+{
+ dom_node *element;
+ dom_exception exc;
+ dom_string *node_name = NULL;
+ dom_node_type node_type;
+ dom_node *next_node;
+
+ exc = dom_node_get_first_child(parent, &element);
+ if ((exc != DOM_NO_ERR) || (element == NULL)) {
+ return NULL;
+ }
+
+ /* find first node thats a element */
+ do {
+ exc = dom_node_get_node_type(element, &node_type);
+
+ if ((exc != DOM_NO_ERR) || (node_type == DOM_ELEMENT_NODE)) {
+ exc = dom_node_get_node_name(element, &node_name);
+ if ((exc == DOM_NO_ERR) || (node_name != NULL)) {
+ if (dom_string_caseless_lwc_isequal(node_name,
+ element_name)) {
+ dom_string_unref(node_name);
+ break;
+ }
+ dom_string_unref(node_name);
+ }
+ }
+
+ exc = dom_node_get_next_sibling(element, &next_node);
+ dom_node_unref(element);
+ if (exc == DOM_NO_ERR) {
+ element = next_node;
+ } else {
+ element = NULL;
+ }
+ } while (element != NULL);
+
+ return element;
+}
diff --git a/utils/domutils.h b/utils/domutils.h
new file mode 100644
index 000000000..ecdf2bc4a
--- /dev/null
+++ b/utils/domutils.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * 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/>.
+ */
+
+#ifndef _NETSURF_UTILS_DOMUTILS_H_
+#define _NETSURF_UTILS_DOMUTILS_H_
+
+dom_node *find_first_named_dom_element(dom_node *parent, lwc_string *element_name);
+
+#endif