summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-05-22 15:59:47 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-05-22 15:59:47 +0100
commitb39f418bca9d0421eca127a11a0fb65bd2c37459 (patch)
tree264234c5b456d5e808780cc0437a71f3eacd1a05 /content
parenta5572cde76b7a95d670fad3b308e0c1d5c7f1f18 (diff)
downloadnetsurf-b39f418bca9d0421eca127a11a0fb65bd2c37459.tar.gz
netsurf-b39f418bca9d0421eca127a11a0fb65bd2c37459.tar.bz2
html: Add canvas node handling in dom_event
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'content')
-rw-r--r--content/handlers/html/dom_event.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/content/handlers/html/dom_event.c b/content/handlers/html/dom_event.c
index b702cb304..5470f2942 100644
--- a/content/handlers/html/dom_event.c
+++ b/content/handlers/html/dom_event.c
@@ -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;
}