mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-26 00:09:41 +03:00
canvas: Support changing canvas size at runtime
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
parent
121c41a730
commit
d157b505e6
@ -9,11 +9,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class CanvasRenderingContext2D {
|
class CanvasRenderingContext2D {
|
||||||
private struct dom_html_element *canvas;
|
private struct dom_html_canvas_element *canvas;
|
||||||
private struct bitmap *bitmap;
|
private struct bitmap *bitmap;
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private size_t stride;
|
private size_t stride;
|
||||||
|
private dom_event_listener *listener;
|
||||||
prologue %{
|
prologue %{
|
||||||
/* prologue */
|
/* prologue */
|
||||||
#include "desktop/gui_internal.h"
|
#include "desktop/gui_internal.h"
|
||||||
@ -202,11 +203,79 @@ static nserror canvas2d_create_bitmap(dom_node *node, struct bitmap **bitmap_out
|
|||||||
return NSERROR_OK;
|
return NSERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle subtree modified events for our canvas node
|
||||||
|
*
|
||||||
|
* If width or height has changed relative to our priv, then
|
||||||
|
* we need to recreate the bitmap and reset our cached width
|
||||||
|
* and height values in order to be safe. Plus redraw ourselves.
|
||||||
|
*
|
||||||
|
* \param evt The event which occurred
|
||||||
|
* \param pw The private pointer for our canvas object
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
canvas2d__handle_dom_event(dom_event *evt, void *pw)
|
||||||
|
{
|
||||||
|
canvas_rendering_context2d_private_t *priv = pw;
|
||||||
|
dom_ulong width;
|
||||||
|
dom_ulong height;
|
||||||
|
dom_exception exc;
|
||||||
|
struct bitmap *newbitmap, *oldbitmap = NULL;
|
||||||
|
size_t stride;
|
||||||
|
dom_event_flow_phase phase;
|
||||||
|
|
||||||
|
exc = dom_event_get_event_phase(evt, &phase);
|
||||||
|
assert(exc == DOM_NO_ERR);
|
||||||
|
/* If we're not being hit right now, we're not up for it */
|
||||||
|
if (phase != DOM_AT_TARGET) return;
|
||||||
|
|
||||||
|
/* Rather than being complex about things, let's just work out
|
||||||
|
* what the width and height are and hope nothing else matters
|
||||||
|
*/
|
||||||
|
|
||||||
|
exc = dom_html_canvas_element_get_width(priv->canvas, &width);
|
||||||
|
if (exc != DOM_NO_ERR) return;
|
||||||
|
exc = dom_html_canvas_element_get_height(priv->canvas, &height);
|
||||||
|
if (exc != DOM_NO_ERR) return;
|
||||||
|
|
||||||
|
if ((int)height == priv->height && (int)width == priv->width) return;
|
||||||
|
|
||||||
|
/* Okay, we need to reallocate our bitmap and re-cache values */
|
||||||
|
|
||||||
|
newbitmap = guit->bitmap->create(width, height, BITMAP_NEW);
|
||||||
|
stride = guit->bitmap->get_rowstride(newbitmap);
|
||||||
|
|
||||||
|
if (newbitmap != NULL) {
|
||||||
|
memset(guit->bitmap->get_buffer(newbitmap),
|
||||||
|
0,
|
||||||
|
stride * height);
|
||||||
|
guit->bitmap->modified(newbitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dom_node_set_user_data(priv->canvas,
|
||||||
|
corestring_dom___ns_key_canvas_node_data,
|
||||||
|
newbitmap, canvas2d_user_data_handler,
|
||||||
|
&oldbitmap) == DOM_NO_ERR) {
|
||||||
|
if (oldbitmap != NULL)
|
||||||
|
guit->bitmap->destroy(oldbitmap);
|
||||||
|
} else {
|
||||||
|
guit->bitmap->destroy(newbitmap);
|
||||||
|
/* We'll stick with the old, odd though that might be */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cache the new values */
|
||||||
|
priv->width = (int)width;
|
||||||
|
priv->height = (int)height;
|
||||||
|
priv->stride = stride;
|
||||||
|
priv->bitmap = newbitmap;
|
||||||
|
}
|
||||||
|
|
||||||
/* prologue ends */
|
/* prologue ends */
|
||||||
%};
|
%};
|
||||||
};
|
};
|
||||||
|
|
||||||
init CanvasRenderingContext2D(struct dom_html_element *canvas)
|
init CanvasRenderingContext2D(struct dom_html_canvas_element *canvas)
|
||||||
%{
|
%{
|
||||||
struct bitmap *bitmap;
|
struct bitmap *bitmap;
|
||||||
dom_exception exc;
|
dom_exception exc;
|
||||||
@ -216,6 +285,18 @@ init CanvasRenderingContext2D(struct dom_html_element *canvas)
|
|||||||
priv->canvas = canvas;
|
priv->canvas = canvas;
|
||||||
dom_node_ref(canvas);
|
dom_node_ref(canvas);
|
||||||
|
|
||||||
|
exc = dom_event_listener_create(canvas2d__handle_dom_event,
|
||||||
|
priv,
|
||||||
|
&priv->listener);
|
||||||
|
assert(exc == DOM_NO_ERR);
|
||||||
|
|
||||||
|
exc = dom_event_target_add_event_listener(
|
||||||
|
canvas,
|
||||||
|
corestring_dom_DOMSubtreeModified,
|
||||||
|
priv->listener,
|
||||||
|
false);
|
||||||
|
assert(exc == DOM_NO_ERR);
|
||||||
|
|
||||||
exc = dom_node_get_user_data(canvas,
|
exc = dom_node_get_user_data(canvas,
|
||||||
corestring_dom___ns_key_canvas_node_data,
|
corestring_dom___ns_key_canvas_node_data,
|
||||||
&bitmap);
|
&bitmap);
|
||||||
@ -242,6 +323,14 @@ init CanvasRenderingContext2D(struct dom_html_element *canvas)
|
|||||||
|
|
||||||
fini CanvasRenderingContext2D()
|
fini CanvasRenderingContext2D()
|
||||||
%{
|
%{
|
||||||
|
dom_exception exc;
|
||||||
|
exc = dom_event_target_remove_event_listener(
|
||||||
|
priv->canvas,
|
||||||
|
corestring_dom_DOMSubtreeModified,
|
||||||
|
priv->listener,
|
||||||
|
false);
|
||||||
|
assert(exc == DOM_NO_ERR);
|
||||||
|
dom_event_listener_unref(priv->listener);
|
||||||
dom_node_unref(priv->canvas);
|
dom_node_unref(priv->canvas);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -251,6 +340,52 @@ getter CanvasRenderingContext2D::canvas()
|
|||||||
return 1;
|
return 1;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
getter CanvasRenderingContext2D::width()
|
||||||
|
%{
|
||||||
|
dom_exception exc;
|
||||||
|
dom_ulong width;
|
||||||
|
|
||||||
|
exc = dom_html_canvas_element_get_width(priv->canvas, &width);
|
||||||
|
if (exc != DOM_NO_ERR) return 0;
|
||||||
|
|
||||||
|
duk_push_number(ctx, (duk_double_t)width);
|
||||||
|
return 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
setter CanvasRenderingContext2D::width()
|
||||||
|
%{
|
||||||
|
dom_exception exc;
|
||||||
|
dom_ulong width = duk_get_uint(ctx, 0);
|
||||||
|
|
||||||
|
exc = dom_html_canvas_element_set_width(priv->canvas, width);
|
||||||
|
if (exc != DOM_NO_ERR) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
getter CanvasRenderingContext2D::height()
|
||||||
|
%{
|
||||||
|
dom_exception exc;
|
||||||
|
dom_ulong height;
|
||||||
|
|
||||||
|
exc = dom_html_canvas_element_get_height(priv->canvas, &height);
|
||||||
|
if (exc != DOM_NO_ERR) return 0;
|
||||||
|
|
||||||
|
duk_push_number(ctx, (duk_double_t)height);
|
||||||
|
return 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
setter CanvasRenderingContext2D::height()
|
||||||
|
%{
|
||||||
|
dom_exception exc;
|
||||||
|
dom_ulong height = duk_get_uint(ctx, 0);
|
||||||
|
|
||||||
|
exc = dom_html_canvas_element_set_height(priv->canvas, height);
|
||||||
|
if (exc != DOM_NO_ERR) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
%}
|
||||||
|
|
||||||
method CanvasRenderingContext2D::createImageData()
|
method CanvasRenderingContext2D::createImageData()
|
||||||
%{
|
%{
|
||||||
/* Can be called either with width and height, or with a reference
|
/* Can be called either with width and height, or with a reference
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
init HTMLCanvasElement(struct dom_html_element *html_canvas_element::html_element);
|
init HTMLCanvasElement(struct dom_html_element *html_canvas_element::html_element);
|
||||||
|
|
||||||
getter HTMLCanvasElement::width();
|
getter HTMLCanvasElement::width();
|
||||||
/* setter HTMLCanvasElement::width(); */
|
setter HTMLCanvasElement::width();
|
||||||
|
|
||||||
getter HTMLCanvasElement::height();
|
getter HTMLCanvasElement::height();
|
||||||
/* setter HTMLCanvasElement::height(); */
|
setter HTMLCanvasElement::height();
|
||||||
|
|
||||||
method HTMLCanvasElement::getContext()
|
method HTMLCanvasElement::getContext()
|
||||||
%{
|
%{
|
||||||
|
Loading…
Reference in New Issue
Block a user