html: Add canvas node handling in dom_event

Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
Daniel Silverstone 2020-05-22 15:59:47 +01:00
parent a5572cde76
commit b39f418bca
No known key found for this signature in database
GPG Key ID: C30DF439F2987D74

View File

@ -32,6 +32,10 @@
#include "content/content.h"
#include "javascript/js.h"
#include "desktop/gui_internal.h"
#include "desktop/gui_table.h"
#include "netsurf/bitmap.h"
#include "html/private.h"
#include "html/object.h"
#include "html/css.h"
@ -102,6 +106,69 @@ static bool html_process_inserted_base(html_content *htmlc, dom_node *node)
return true;
}
/**
* deal with events from the DOM for canvas node user data
*
* \param operation The DOM operation happening
* \param key The user data key
* \param data The user data (our bitmap)
* \param src The DOM node emitting the event (our <canvas>)
* \param dst The target DOM node if applicable
*/
static void
html__canvas_user_data_handler(dom_node_operation operation,
dom_string *key,
void *data,
struct dom_node *src,
struct dom_node *dst)
{
struct bitmap *newbitmap, *bitmap = (struct bitmap*)data, *oldbitmap = NULL;
int width, height;
size_t stride;
if (dom_string_isequal(key,corestring_dom___ns_key_canvas_node_data) == false || data == NULL) {
/* Not for us */
return;
}
switch (operation) {
case DOM_NODE_CLONED:
width = guit->bitmap->get_width(bitmap);
height = guit->bitmap->get_height(bitmap);
stride = guit->bitmap->get_rowstride(bitmap);
newbitmap = guit->bitmap->create(width, height,
BITMAP_NEW);
if (newbitmap != NULL) {
if (guit->bitmap->get_rowstride(newbitmap) == stride) {
// Compatible bitmap, bung the data over
memcpy(guit->bitmap->get_buffer(newbitmap),
guit->bitmap->get_buffer(bitmap),
stride * height);
guit->bitmap->modified(newbitmap);
}
}
if (dom_node_set_user_data(dst,
corestring_dom___ns_key_canvas_node_data,
newbitmap, html__canvas_user_data_handler,
&oldbitmap) == DOM_NO_ERR) {
if (oldbitmap != NULL)
guit->bitmap->destroy(oldbitmap);
}
break;
case DOM_NODE_RENAMED:
case DOM_NODE_IMPORTED:
case DOM_NODE_ADOPTED:
break;
case DOM_NODE_DELETED:
guit->bitmap->destroy(bitmap);
break;
default:
NSLOG(netsurf, INFO, "User data operation not handled.");
assert(0);
}
}
/**
* process a canvas element being inserted into the DOM
@ -112,6 +179,72 @@ static bool html_process_inserted_base(html_content *htmlc, dom_node *node)
*/
static nserror html_process_inserted_canvas(html_content *htmlc, dom_node *node)
{
dom_exception exc;
dom_string *width_s = NULL, *height_s = NULL;
unsigned long width = 300, height = 150;
struct bitmap *bitmap, *oldbitmap = NULL;
exc = dom_element_get_attribute(node,
corestring_dom_width,
&width_s);
if (exc == DOM_NO_ERR && width_s != NULL) {
const char *ptr = (const char *)dom_string_data(width_s);
const char *endptr = ptr + dom_string_length(width_s);
char * ended;
unsigned long width_n = strtoul(ptr, &ended, 10);
if (ended == endptr) {
/* parsed it all */
width = width_n;
}
dom_string_unref(width_s);
}
exc = dom_element_get_attribute(node,
corestring_dom_height,
&height_s);
if (exc == DOM_NO_ERR && height_s != NULL) {
const char *ptr = (const char *)dom_string_data(height_s);
const char *endptr = ptr + dom_string_length(height_s);
char * ended;
unsigned long height_n = strtoul(ptr, &ended, 10);
if (ended == endptr) {
/* parsed it all */
height = height_n;
}
dom_string_unref(height_s);
}
bitmap = guit->bitmap->create(
(int)width, (int)height,
BITMAP_NEW);
if (bitmap == NULL) {
return NSERROR_NOMEM;
}
memset(guit->bitmap->get_buffer(bitmap),
0, /* Transparent black */
height * guit->bitmap->get_rowstride(bitmap));
guit->bitmap->modified(bitmap);
exc = dom_node_set_user_data(node,
corestring_dom___ns_key_canvas_node_data,
bitmap,
html__canvas_user_data_handler,
&oldbitmap);
if (exc != DOM_NO_ERR) {
guit->bitmap->destroy(bitmap);
return NSERROR_DOM;
}
if (oldbitmap != NULL)
guit->bitmap->destroy(oldbitmap);
return NSERROR_OK;
}