From: Michael Orlitzky Date: Fri, 4 Aug 2023 22:33:48 +0000 (-0400) Subject: io-svg.c: add "incremental load" scaffolding. X-Git-Tag: 0.0.1~36 X-Git-Url: https://gitweb.michael.orlitzky.com/?a=commitdiff_plain;h=23314169d6c89b87f35dd0c9b4927f361adc4cc1;p=libsvgtiny-pixbuf.git io-svg.c: add "incremental load" scaffolding. --- diff --git a/io-svg.c b/io-svg.c index 13b692b..2d509c6 100644 --- a/io-svg.c +++ b/io-svg.c @@ -21,6 +21,14 @@ typedef struct svgtiny_diagram diagram_t; typedef struct svgtiny_shape shape_t; +typedef struct { + GdkPixbufModuleUpdatedFunc updated_func; + GdkPixbufModulePreparedFunc prepared_func; + GdkPixbufModuleSizeFunc size_func; + gpointer user_data; +} SvgTinyContext; + + /** * @brief Render an svgtiny path using cairo. * @@ -303,8 +311,77 @@ static GdkPixbuf* gdk_pixbuf_from_svg_file_stream(FILE *fp, GError** error) { } +static gpointer gdk_pixbuf_begin_load(GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prep_func, + GdkPixbufModuleUpdatedFunc updated_func, + gpointer user_data, + GError **error) +{ + SvgTinyContext* context = g_new0(SvgTinyContext, 1); + + context->size_func = size_func; + context->prepared_func = prep_func; + context->updated_func = updated_func; + context->user_data = user_data; + + return context; +} + +static gboolean gdk_pixbuf_load_increment(gpointer data, + const guchar* buf, + guint size, + GError** error) { + SvgTinyContext* context = (SvgTinyContext*)data; + /* + if (!rsvg_handle_write (context->handle, buf, size, error)) { + rsvg_propagate_error (error, _("Error writing"), ERROR_WRITING); + return FALSE; + } + */ + return TRUE; +} + +static void emit_updated(SvgTinyContext* context, GdkPixbuf* pixbuf) { + if (context->updated_func != NULL) { + (*context->updated_func)(pixbuf, + 0, + 0, + gdk_pixbuf_get_width(pixbuf), + gdk_pixbuf_get_height(pixbuf), + context->user_data); + } +} + +static void emit_prepared(SvgTinyContext* context, GdkPixbuf* pixbuf) { + if (context->prepared_func != NULL) { + (*context->prepared_func)(pixbuf, NULL, context->user_data); + } +} + +static gboolean gdk_pixbuf_stop_load(gpointer data, GError **error) { + SvgTinyContext* context = (SvgTinyContext*)data; + GdkPixbuf* pixbuf = NULL; + gboolean result = TRUE; + + if (pixbuf != NULL) { + emit_prepared(context, pixbuf); + emit_updated(context, pixbuf); + g_object_unref(pixbuf); + } + else { + result = FALSE; + } + g_free (context); + + return result; +} + + G_MODULE_EXPORT void fill_vtable(GdkPixbufModule* module); void fill_vtable(GdkPixbufModule* module) { + module->begin_load = gdk_pixbuf_begin_load; + module->load_increment = gdk_pixbuf_load_increment; + module->stop_load = gdk_pixbuf_stop_load; module->load = gdk_pixbuf_from_svg_file_stream; }