[goffice] More work on EMF support.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] More work on EMF support.
- Date: Sat, 10 Mar 2012 14:47:41 +0000 (UTC)
commit b2198aac12cb885731cf02b6fd13d1c1b4b692c0
Author: Jean Brefort <jean brefort normalesup org>
Date: Sat Mar 10 15:46:37 2012 +0100
More work on EMF support.
ChangeLog | 16 ++++++
goffice/component/go-component.c | 39 +++++++++++++++-
goffice/graph/gog-renderer.c | 2 +-
goffice/gtk/go-optionmenu.c | 4 +-
goffice/utils/go-emf.c | 95 ++++++++++++++++++++++++++++++-------
goffice/utils/go-image.c | 6 ++-
goffice/utils/go-image.h | 3 +-
goffice/utils/go-spectre.c | 15 ++----
goffice/utils/go-svg.c | 33 ++++++-------
9 files changed, 162 insertions(+), 51 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 95b69b9..9020a79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2012-03-10 Jean Brefort <jean brefort normalesup org>
+ * goffice/component/go-component.c: add some doc.
+ * goffice/utils/go-emf.c (go_emf_save), (go_emf_load_data),
+ (go_emf_differ), (go_emf_new_from_file), (go_emf_new_from_data),
+ (go_emf_setworldtransform), (go_emf_modifyworldtransform),
+ (go_emf_createpen), (go_emf_polygon16), (go_emf_polyline16),
+ (go_emf_extcreatepen): more implementations and fixes.
+ * goffice/utils/go-image.c (go_image_get_data): new function, replaces
+ obsolete go_image_get_pixels.
+ * goffice/utils/go-image.h: ditto.
+ * goffice/utils/go-spectre.c (go_spectre_save),
+ (go_spectre_load_data), (go_spectre_differ): ditto.
+ * goffice/utils/go-svg.c (go_svg_save), (go_svg_load_data),
+ (go_svg_differ), (go_svg_new_from_file), (go_svg_new_from_data): ditto.
+
+2012-03-10 Jean Brefort <jean brefort normalesup org>
+
* configure.in: add a test for ghostscript to avoid crashes when using
libspectre.
* goffice/Makefile.am: make introspection build when libgoffice is not
diff --git a/goffice/component/go-component.c b/goffice/component/go-component.c
index b4d08dd..6648494 100644
--- a/goffice/component/go-component.c
+++ b/goffice/component/go-component.c
@@ -457,6 +457,13 @@ editor_destroy_cb (GOComponent *component)
component->editor = NULL;
}
+/**
+ * go_component_edit:
+ * @component: #GOComponent
+ *
+ * Opens a top level window editor for the component if it can be edited.
+ * Returns: (transfer none): the editor window or NULL
+ */
GtkWindow *
go_component_edit (GOComponent *component)
{
@@ -497,7 +504,7 @@ go_component_emit_changed (GOComponent *component)
go_component_signals [CHANGED], 0);
}
-static GOCmdContext *goc_cc;
+static GOCmdContext *goc_cc = NULL;
void
go_component_set_command_context (GOCmdContext *cc)
@@ -509,6 +516,11 @@ go_component_set_command_context (GOCmdContext *cc)
g_object_ref (goc_cc);
}
+/**
+ * go_component_get_command_context:
+ *
+ * Returns: (transfer none): the command context used for components.
+ */
GOCmdContext *
go_component_get_command_context (void)
{
@@ -658,6 +670,15 @@ _go_component_sax_parser_done (GsfXMLIn *xin, GOCompXMLReadState *state)
g_free (state);
}
+/**
+ * go_component_sax_push_parser:
+ * @xin: #GsfInput
+ * @attrs: the current node attributes.
+ * @handler: (scope call): #GOComponentSaxHandler
+ * @user_data: data to pass to @handler
+ *
+ * Loads the component from the xml stream. @handler will be called when done.
+ */
void
go_component_sax_push_parser (GsfXMLIn *xin, xmlChar const **attrs,
GOComponentSaxHandler handler, gpointer user_data)
@@ -778,6 +799,15 @@ go_component_new_from_uri (char const *uri)
return component;
}
+/**
+ * go_component_get_snapshot:
+ * @component: #GOComponent
+ * @type: #GOSnapshotType
+ * @length: where to store the data length
+ *
+ * Returns a snapshot is either svg or png format for the component.
+ * Returns: (transfer none): the snapshot as an arry of bytes.
+ */
void const *
go_component_get_snapshot (GOComponent *component, GOSnapshotType *type, size_t *length)
{
@@ -819,6 +849,13 @@ go_component_export_image (GOComponent *component, GOImageFormat format, GsfOutp
return FALSE;
}
+/**
+ * go_component_duplicate:
+ * @component: a #GOComponent
+ *
+ * Duplicates the component.
+ * Returns: (transfer full): the duplicated component.
+ */
GOComponent *
go_component_duplicate (GOComponent const *component)
{
diff --git a/goffice/graph/gog-renderer.c b/goffice/graph/gog-renderer.c
index 6fe9ba2..5fdd567 100644
--- a/goffice/graph/gog-renderer.c
+++ b/goffice/graph/gog-renderer.c
@@ -840,7 +840,7 @@ gog_renderer_draw_marker (GogRenderer *rend, double x, double y)
* @str: the #GOString to draw
* @pos: #GogViewAllocation
* @anchor: #GOAnchorType how to draw relative to @pos
- * @width: if positive, the maximum width to get a multiline string if needed.
+ * @width: if positive, the maximum width to get a multiline string if needed.
*
* Have @rend draw @layout in the at @pos.{x,y} anchored by the @anchor corner.
* If @pos.w or @pos.h are >= 0 then clip the results to less than that size.
diff --git a/goffice/gtk/go-optionmenu.c b/goffice/gtk/go-optionmenu.c
index 0027750..4ce00dc 100644
--- a/goffice/gtk/go-optionmenu.c
+++ b/goffice/gtk/go-optionmenu.c
@@ -295,10 +295,10 @@ go_option_menu_set_menu (GOOptionMenu *option_menu,
/**
* go_option_menu_set_history:
- * @selection: a list of indices giving the menu to select.
+ * @selection: a list of indices giving the menu to select.
*
* Selects an item. The last number in the list is the rank of the item to select
- * in its menu and the previous ones are the ranks of the submenus containing
+ * in its menu and the previous ones are the ranks of the submenus containing
* the item to select.
**/
void
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
index 6067b24..6bdddfd 100644
--- a/goffice/utils/go-emf.c
+++ b/goffice/utils/go-emf.c
@@ -32,7 +32,6 @@
struct _GOEmf {
GOImage parent;
GocCanvas *canvas;
- gsize data_length;
};
typedef GOImageClass GOEmfClass;
@@ -49,7 +48,7 @@ go_emf_save (GOImage *image, GsfXMLOut *output)
GOEmf *emf = GO_EMF (image);
g_return_if_fail (emf);
gsf_xml_out_add_base64 (output, NULL,
- image->data, emf->data_length);
+ image->data, image->data_length);
}
static void
@@ -62,10 +61,20 @@ static void
go_emf_load_data (GOImage *image, GsfXMLIn *xin)
{
GOEmf *emf = GO_EMF (image);
- emf->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
- image->data = g_malloc (emf->data_length);
- memcpy (image->data, xin->content->str, emf->data_length);
- /* FIXME: build the canvas */
+ GError *error = NULL;
+ GsfInput *input;
+ image->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
+ image->data = g_malloc (image->data_length);
+ memcpy (image->data, xin->content->str, image->data_length);
+#ifdef GOFFICE_EMF_SUPPORT
+ input = gsf_input_memory_new (image->data, image->data_length, FALSE);
+ go_emf_parse (emf, input, &error);
+ g_object_unref (input);
+ if (error) {
+ // FIXME: emit at least a warning
+ g_error_free (error);
+ }
+#endif
}
static void
@@ -121,10 +130,9 @@ go_emf_get_scaled_pixbuf (GOImage *image, int width, int height)
static gboolean
go_emf_differ (GOImage *first, GOImage *second)
{
- GOEmf *sfirst = GO_EMF (first), *ssecond = GO_EMF (second);
- if (sfirst->data_length != ssecond->data_length)
+ if (first->data_length != second->data_length)
return TRUE;
- return memcmp (first->data, second->data, sfirst->data_length);
+ return memcmp (first->data, second->data, first->data_length);
}
static void
@@ -192,11 +200,11 @@ go_emf_new_from_file (char const *filename, GError **error)
}
g_object_unref (input);
emf = g_object_new (GO_TYPE_EMF, NULL);
- emf->data_length = size;
image = GO_IMAGE (emf);
+ image->data_length = size;
image->data = data;
- input = gsf_input_memory_new (data, emf->data_length, FALSE);
+ input = gsf_input_memory_new (data, image->data_length, FALSE);
if (!go_emf_parse (emf, input, error)) {
g_object_unref (emf);
emf = NULL;
@@ -231,13 +239,13 @@ go_emf_new_from_data (char const *data, size_t length, GError **error)
return NULL;
}
emf = g_object_new (GO_TYPE_EMF, NULL);
- emf->data_length = gsf_input_size (input);
+ image = GO_IMAGE (emf);
+ image->data_length = gsf_input_size (input);
if (!go_emf_parse (emf, input, error)) {
g_object_unref (emf);
image = NULL;
} else {
double x0, y0, x1, y1;
- image = GO_IMAGE (emf);
image->data = g_malloc (length);
memcpy (image->data, data, length);
goc_canvas_get_bounds (emf->canvas, &x0, &y0, &x1, &y1);
@@ -2953,14 +2961,45 @@ go_emf_restoredc (GOEmfState *state)
static gboolean
go_emf_setworldtransform (GOEmfState *state)
{
+ double m11, m12, m21, m22, dx, dy;
d_(("setworldtransform\n"));
+ m11 = GSF_LE_GET_FLOAT (state->data);
+ m12 = GSF_LE_GET_FLOAT (state->data + 4);
+ m21 = GSF_LE_GET_FLOAT (state->data + 8);
+ m22 = GSF_LE_GET_FLOAT (state->data + 12);
+ dx = GSF_LE_GET_FLOAT (state->data + 16);
+ dy = GSF_LE_GET_FLOAT (state->data + 20);
+ d_(("\tm11 = %g m12 = %g dx=%g\n\tm21 = %g m22=%g dy=%g\n",
+ m11, m12, dx, m21, m22, dy));
+ /* FIXME: do something with it */
return TRUE;
}
static gboolean
go_emf_modifyworldtransform (GOEmfState *state)
{
+#ifdef DEBUG_EMF_SUPPORT
+ char const *tmas[5] = {
+ NULL,
+ "MWT_IDENTITY",
+ "MWT_LEFTMULTIPLY",
+ "MWT_RIGHTMULTIPLY",
+ "MWT_SET"
+ };
+#endif
+ double m11, m12, m21, m22, dx, dy;
+ unsigned mode;
d_(("modifyworldtransform\n"));
+ m11 = GSF_LE_GET_FLOAT (state->data);
+ m12 = GSF_LE_GET_FLOAT (state->data + 4);
+ m21 = GSF_LE_GET_FLOAT (state->data + 8);
+ m22 = GSF_LE_GET_FLOAT (state->data + 12);
+ dx = GSF_LE_GET_FLOAT (state->data + 16);
+ dy = GSF_LE_GET_FLOAT (state->data + 20);
+ mode = GSF_LE_GET_GUINT32 (state + 24);
+ d_(("\tm11 = %g m12 = %g dx=%g\n\tm21 = %g m22=%g dy=%g\n\tmode = %s\n",
+ m11, m12, dx, m21, m22, dy, tmas[mode]));
+ /* FIXME: do something with it */
return TRUE;
}
@@ -3141,9 +3180,6 @@ go_emf_selectobject (GOEmfState *state)
return TRUE;
}
-static gboolean
-go_emf_createpen (GOEmfState *state)
-{
#ifdef DEBUG_EMF_SUPPORT
char const *dashes[] = {
"Solid",
@@ -3167,6 +3203,10 @@ char const *cap[]= {
"flat"
};
#endif
+
+static gboolean
+go_emf_createpen (GOEmfState *state)
+{
unsigned index;
GOEmfPen *pen = g_new0 (GOEmfPen, 1);
pen->obj_type = GO_EMF_OBJ_TYPE_PEN;
@@ -3735,7 +3775,7 @@ go_emf_polygon16 (GOEmfState *state)
nb_pts = GSF_LE_GET_GUINT32 (state->data + 16);
d_(("\t%u points\n", nb_pts));
points = goc_points_new (nb_pts);
- for (n = 0, offset = 20; n < nb_pts; n++, offset += 8) {
+ for (n = 0, offset = 20; n < nb_pts; n++, offset += 4) {
go_wmf_read_points (state->data + offset, &x, &y);
go_emf_convert_coords (state, &x, &y);
points->points[n].x = x;
@@ -3767,7 +3807,7 @@ go_emf_polyline16 (GOEmfState *state)
nb_pts = GSF_LE_GET_GUINT32 (state->data + 16);
d_(("\t%u points\n", nb_pts));
points = goc_points_new (nb_pts);
- for (n = 0, offset = 20; n < nb_pts; n++, offset += 8) {
+ for (n = 0, offset = 20; n < nb_pts; n++, offset += 4) {
go_wmf_read_points (state->data + offset, &x, &y);
go_emf_convert_coords (state, &x, &y);
points->points[n].x = x;
@@ -3952,7 +3992,26 @@ go_emf_createdibpatternbrushpt (GOEmfState *state)
static gboolean
go_emf_extcreatepen (GOEmfState *state)
{
+ unsigned index/*, offBmi, cbBmi, offBits, cbBits*/;
+ GOEmfPen *pen = g_new0 (GOEmfPen, 1);
+ pen->obj_type = GO_EMF_OBJ_TYPE_PEN;
d_(("extcreatepen\n"));
+ index = GSF_LE_GET_GUINT32 (state->data);
+/* offBmi = GSF_LE_GET_GUINT32 (state->data + 4);
+ cbBmi = GSF_LE_GET_GUINT32 (state->data + 8);
+ offBits = GSF_LE_GET_GUINT32 (state->data + 12);
+ cbBits = GSF_LE_GET_GUINT32 (state->data + 16);
+ if (cbBmi != 0 || cbBits != NULL) {
+ FIXME: load DIB data if any
+ }*/
+ pen->style = GSF_LE_GET_GUINT32 (state->data + 20);
+ pen->width = GSF_LE_GET_GUINT32 (state->data + 24);
+ pen->clr = go_wmf_read_gocolor (state->data + 32);
+ d_(("\tpen index=%u style=%s width=%g color=%08x join=%s cap=%s%s\n",index,
+ dashes[pen->style&0xf], pen->width, pen->clr,
+ join[(pen->style&0xf000)>>24], cap[(pen->style&0xf00)>>16],
+ pen->style&0x00010000? "Geometric": ""));
+ g_hash_table_replace (state->mfobjs, GUINT_TO_POINTER (index), pen);
return TRUE;
}
diff --git a/goffice/utils/go-image.c b/goffice/utils/go-image.c
index 14ceb11..66f6286 100644
--- a/goffice/utils/go-image.c
+++ b/goffice/utils/go-image.c
@@ -540,10 +540,12 @@ go_image_type_for_format (char const *format)
return 0;
}
-guint8 *
-go_image_get_pixels (GOImage *image)
+guint8 const *
+go_image_get_data (GOImage *image, gsize *length)
{
g_return_val_if_fail (image, NULL);
+ if (length)
+ *length = image->data_length;
return image->data;
}
diff --git a/goffice/utils/go-image.h b/goffice/utils/go-image.h
index 16ad5b9..a79e0fb 100644
--- a/goffice/utils/go-image.h
+++ b/goffice/utils/go-image.h
@@ -72,6 +72,7 @@ struct _GOImage {
GdkPixbuf *thumbnail;
GdkPixbuf *pixbuf;
char *name;
+ gsize data_length;
};
typedef struct {
@@ -97,7 +98,7 @@ GOImage *go_image_new_from_data (char const *type, guint8 const *data, gsize l
GOImage *go_image_new_for_format (char const *format);
GType go_image_type_for_format (char const *format);
-guint8 *go_image_get_pixels (GOImage *image);
+guint8 const *go_image_get_data (GOImage *image, gsize *length);
void go_image_fill (GOImage *image, GOColor color);
void go_image_set_name (GOImage *image, char const *name);
diff --git a/goffice/utils/go-spectre.c b/goffice/utils/go-spectre.c
index bad2d83..10b5dde 100644
--- a/goffice/utils/go-spectre.c
+++ b/goffice/utils/go-spectre.c
@@ -36,7 +36,6 @@ struct _GOSpectre {
#ifdef GOFFICE_WITH_EPS
SpectreDocument *doc;
#endif
- gsize data_length;
cairo_surface_t *surface;
};
@@ -51,7 +50,7 @@ go_spectre_save (GOImage *image, GsfXMLOut *output)
(image);
g_return_if_fail (spectre);
gsf_xml_out_add_base64 (output, NULL,
- image->data, spectre->data_length);
+ image->data, image->data_length);
}
static void
@@ -63,16 +62,15 @@ go_spectre_load_attr (G_GNUC_UNUSED GOImage *image, G_GNUC_UNUSED xmlChar const
static void
go_spectre_load_data (GOImage *image, GsfXMLIn *xin)
{
- GOSpectre *spectre = GO_SPECTRE (image);
#ifdef GOFFICE_WITH_EPS
int width, height;
char *tmpname;
int f;
#endif
- spectre->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
- image->data = g_malloc (spectre->data_length);
- memcpy (image->data, xin->content->str, spectre->data_length);
+ image->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
+ image->data = g_malloc (image->data_length);
+ memcpy (image->data, xin->content->str, image->data_length);
#ifdef GOFFICE_WITH_EPS
spectre->doc = spectre_document_new ();
if (spectre->doc == NULL)
@@ -190,10 +188,9 @@ go_spectre_get_scaled_pixbuf (GOImage *image, int width, int height)
static gboolean
go_spectre_differ (GOImage *first, GOImage *second)
{
- GOSpectre *sfirst = GO_SPECTRE (first), *ssecond = GO_SPECTRE (second);
- if (sfirst->data_length != ssecond->data_length)
+ if (first->data_length != second->data_length)
return TRUE;
- return memcmp (first->data, second->data, sfirst->data_length);
+ return memcmp (first->data, second->data, first->data_length);
}
static void
diff --git a/goffice/utils/go-svg.c b/goffice/utils/go-svg.c
index 603ffe5..bd304f2 100644
--- a/goffice/utils/go-svg.c
+++ b/goffice/utils/go-svg.c
@@ -32,7 +32,6 @@
struct _GOSvg {
GOImage parent;
RsvgHandle *handle;
- gsize data_length;
};
typedef GOImageClass GOSvgClass;
@@ -45,7 +44,7 @@ go_svg_save (GOImage *image, GsfXMLOut *output)
GOSvg *svg = GO_SVG (image);
g_return_if_fail (svg);
gsf_xml_out_add_base64 (output, NULL,
- image->data, svg->data_length);
+ image->data, image->data_length);
}
static void
@@ -59,10 +58,10 @@ go_svg_load_data (GOImage *image, GsfXMLIn *xin)
{
GOSvg *svg = GO_SVG (image);
double dpi_x, dpi_y;
- svg->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
- image->data = g_malloc (svg->data_length);
- memcpy (image->data, xin->content->str, svg->data_length);
- svg->handle = rsvg_handle_new_from_data (image->data, svg->data_length, NULL);
+ image->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
+ image->data = g_malloc (image->data_length);
+ memcpy (image->data, xin->content->str, image->data_length);
+ svg->handle = rsvg_handle_new_from_data (image->data, image->data_length, NULL);
go_image_get_default_dpi (&dpi_x, &dpi_y);
rsvg_handle_set_dpi_x_y (svg->handle, dpi_x, dpi_y);
}
@@ -120,10 +119,9 @@ go_svg_get_scaled_pixbuf (GOImage *image, int width, int height)
static gboolean
go_svg_differ (GOImage *first, GOImage *second)
{
- GOSvg *sfirst = GO_SVG (first), *ssecond = GO_SVG (second);
- if (sfirst->data_length != ssecond->data_length)
+ if (first->data_length != second->data_length)
return TRUE;
- return memcmp (first->data, second->data, sfirst->data_length);
+ return memcmp (first->data, second->data, first->data_length);
}
static void
@@ -160,7 +158,7 @@ GSF_CLASS (GOSvg, go_svg,
GOImage *
go_svg_new_from_file (char const *filename, GError **error)
{
- GOSvg *svg = g_object_new (GO_TYPE_SVG, NULL);
+ GOSvg *svg;
guint8 *data;
GsfInput *input = gsf_input_stdio_new (filename, error);
RsvgDimensionData dim;
@@ -169,16 +167,17 @@ go_svg_new_from_file (char const *filename, GError **error)
if (!input)
return NULL;
- svg->data_length = gsf_input_size (input);
- data = g_malloc (svg->data_length);
- if (!data || !gsf_input_read (input, svg->data_length, data)) {
+ svg = g_object_new (GO_TYPE_SVG, NULL);
+ image = GO_IMAGE (svg);
+ image->data_length = gsf_input_size (input);
+ data = g_malloc (image->data_length);
+ if (!data || !gsf_input_read (input, image->data_length, data)) {
g_object_unref (svg);
g_free (data);
return NULL;
}
- image = GO_IMAGE (svg);
image->data = data;
- svg->handle = rsvg_handle_new_from_data (data, svg->data_length, error);
+ svg->handle = rsvg_handle_new_from_data (data, image->data_length, error);
if (svg->handle == NULL) {
g_object_unref (svg);
return NULL;
@@ -201,15 +200,15 @@ go_svg_new_from_data (char const *data, size_t length, GError **error)
g_return_val_if_fail (data != NULL && length != 0, NULL);
svg = g_object_new (GO_TYPE_SVG, NULL);
- svg->data_length = length;
image = GO_IMAGE (svg);
+ image->data_length = length;
image->data = g_malloc (length);
if (image->data == NULL) {
g_object_unref (svg);
return NULL;
}
memcpy (image->data, data, length);
- svg->handle = rsvg_handle_new_from_data (image->data, svg->data_length, error);
+ svg->handle = rsvg_handle_new_from_data (image->data, image->data_length, error);
if (svg->handle == NULL) {
g_object_unref (svg);
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]