[goffice] Fix text item position when clipped. [#676067]
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Fix text item position when clipped. [#676067]
- Date: Tue, 15 May 2012 14:07:55 +0000 (UTC)
commit be976884a891ac787bdaf9bc93a04fd67b3c6001
Author: Jean Brefort <jean brefort normalesup org>
Date: Tue May 15 16:07:40 2012 +0200
Fix text item position when clipped. [#676067]
ChangeLog | 17 +++
NEWS | 1 +
goffice/canvas/goc-group.c | 8 +-
goffice/canvas/goc-group.h | 2 -
goffice/canvas/goc-item.c | 32 +++++
goffice/canvas/goc-item.h | 4 +
goffice/canvas/goc-text.c | 4 +-
goffice/utils/go-emf.c | 245 +++++++++++++++++++++++++++++++++------
goffice/utils/go-pango-extras.c | 28 +++---
9 files changed, 282 insertions(+), 59 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d1e0ba2..249ec67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2012-05-15 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-group.c: moved transfrom to GocItem.
+ * goffice/canvas/goc-group.h: ditto.
+ * goffice/canvas/goc-item.c (goc_item_init),
+ (goc_item_get_operator), (goc_item_set_transform),
+ (_goc_item_transform): ditto.
+ * goffice/canvas/goc-item.h: ditto.
+ * goffice/canvas/goc-text.c (go_anchor_type_get_type): typo,
+ (goc_text_draw): fix text position when clipped. [#676067]
+ * goffice/utils/go-emf.c (go_dib_read_header),
+ (go_dib_create_pixbuf_from_data), (go_wmf_mr_arc), (go_emf_header),
+ (go_emf_polybezier), (go_emf_setworldtransform),
+ (go_emf_modifyworldtransform), (go_emf_selectobject),
+ (go_emf_rectangle), (go_emf_stretchdibits), (go_emf_polybezier16),
+ (go_emf_polygon16), (go_emf_parse): more work.
+
2012-05-12 Andreas J. Guelzow <aguelzow pyrshep ca>
* utils/go-pango-extras.c (go_pango_attrs_to_markup): new
diff --git a/NEWS b/NEWS
index a2e19f5..3e4299b 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Andreas:
Jean:
* Fixed logfit equation typo. [#675560]
+ * Fix text item position when clipped. [#676067]
--------------------------------------------------------------------------
goffice 0.9.3:
diff --git a/goffice/canvas/goc-group.c b/goffice/canvas/goc-group.c
index 1d189ac..0c85d57 100644
--- a/goffice/canvas/goc-group.c
+++ b/goffice/canvas/goc-group.c
@@ -265,14 +265,8 @@ goc_group_class_init (GocItemClass *item_klass)
item_klass->notify_scrolled = goc_group_notify_scrolled;
}
-static void
-goc_group_init (GocGroup *group)
-{
- cairo_matrix_init_identity (&group->transform);
-}
-
GSF_CLASS (GocGroup, goc_group,
- goc_group_class_init, goc_group_init,
+ goc_group_class_init, NULL,
GOC_TYPE_ITEM)
/**
diff --git a/goffice/canvas/goc-group.h b/goffice/canvas/goc-group.h
index bbe3b27..d91ce80 100644
--- a/goffice/canvas/goc-group.h
+++ b/goffice/canvas/goc-group.h
@@ -33,8 +33,6 @@ struct _GocGroup {
GList *children;
GOPath *clip_path;
cairo_fill_rule_t clip_rule;
- cairo_matrix_t transform; /* not used for now */
- gboolean transformed; /* TRUE if the matrix is not identity */
gpointer priv;
};
diff --git a/goffice/canvas/goc-item.c b/goffice/canvas/goc-item.c
index a5cd572..c37a170 100644
--- a/goffice/canvas/goc-item.c
+++ b/goffice/canvas/goc-item.c
@@ -286,6 +286,7 @@ static void
goc_item_init (GocItem *item)
{
item->visible = TRUE;
+ cairo_matrix_init_identity (&item->transform);
}
GSF_CLASS_FULL (GocItem, goc_item, NULL, NULL,
@@ -772,3 +773,34 @@ goc_item_get_operator (GocItem *item)
{
return item->op;
}
+
+#define matrix_epsilon 1e-12
+void
+goc_item_set_transform (GocItem *item, cairo_matrix_t *m)
+{
+ item->transformed = fabs (m->xx - 1.) > matrix_epsilon
+ || fabs (m->xy) > matrix_epsilon
+ || fabs (m->xy) > matrix_epsilon
+ || fabs (m->yx) > matrix_epsilon
+ || fabs (m->yy - 1.) > matrix_epsilon
+ || fabs (m->x0) > matrix_epsilon
+ || fabs (m->x0) > matrix_epsilon;
+ if (item->transformed)
+ item->transform = *m;
+ else
+ cairo_matrix_init_identity (&item->transform);
+}
+
+void
+_goc_item_transform (GocItem const *item, cairo_t *cr)
+{
+ cairo_matrix_t m = item->transform, buf,
+ sc = {item->canvas->pixels_per_unit, 0., 0., item->canvas->pixels_per_unit, 0., 0.};
+ while ((item = GOC_ITEM (item->parent)))
+ if (item->transformed) {
+ cairo_matrix_multiply (&buf, &m, &item->transform);
+ m = buf;
+ }
+ cairo_matrix_multiply (&buf, &m, &sc);
+ cairo_set_matrix (cr, &buf);
+}
diff --git a/goffice/canvas/goc-item.h b/goffice/canvas/goc-item.h
index dfcc872..264c4e2 100644
--- a/goffice/canvas/goc-item.h
+++ b/goffice/canvas/goc-item.h
@@ -36,6 +36,8 @@ struct _GocItem {
gboolean realized;
double x0, y0, x1, y1; /* the bounds */
cairo_operator_t op;
+ cairo_matrix_t transform; /* not used for now */
+ gboolean transformed; /* TRUE if the matrix is not identity */
gpointer priv;
};
@@ -107,9 +109,11 @@ void goc_item_lower_to_bottom (GocItem *item);
void goc_item_raise_to_top (GocItem *item);
void _goc_item_realize (GocItem *item);
void _goc_item_unrealize (GocItem *item);
+void _goc_item_transform (GocItem const *item, cairo_t *cr);
void goc_item_set_operator (GocItem *item, cairo_operator_t op);
cairo_operator_t goc_item_get_operator (GocItem *item);
+void goc_item_set_transform (GocItem *item, cairo_matrix_t *m);
G_END_DECLS
diff --git a/goffice/canvas/goc-text.c b/goffice/canvas/goc-text.c
index a471460..580ba86 100644
--- a/goffice/canvas/goc-text.c
+++ b/goffice/canvas/goc-text.c
@@ -65,7 +65,7 @@ go_anchor_type_get_type (void)
{ GO_ANCHOR_SOUTH_EAST, "GO_ANCHOR_SOUTH_EAST", "south-east" },
{ GO_ANCHOR_WEST, "GO_ANCHOR_WEST", "west" },
{ GO_ANCHOR_EAST, "GO_ANCHOR_EAST", "east" },
- { GO_ANCHOR_N, "GO_ANCHOR_Ngo_anchor_type_get_type", "n" },
+ { GO_ANCHOR_N, "GO_ANCHOR_N", "n" },
{ GO_ANCHOR_NW, "GO_ANCHOR_NW", "nw" },
{ GO_ANCHOR_NE, "GO_ANCHOR_NE", "ne" },
{ GO_ANCHOR_S, "GO_ANCHOR_S", "s" },
@@ -419,7 +419,7 @@ goc_text_draw (GocItem const *item, cairo_t *cr)
cairo_set_source_rgb (cr, 0., 0., 0.);
goc_group_cairo_transform (item->parent, cr, x, y);
cairo_rotate (cr, text->rotation * sign);
- cairo_move_to (cr, dx, dy);
+ cairo_translate (cr, dx, dy);
if (text->clip_height > 0. && text->clip_width > 0.) {
cairo_rectangle (cr, 0., 0., text->clip_width, text->clip_height);
cairo_clip (cr);
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
index 533a0bc..2a119a1 100644
--- a/goffice/utils/go-emf.c
+++ b/goffice/utils/go-emf.c
@@ -287,16 +287,17 @@ go_emf_new_from_data (char const *data, size_t length, GError **error)
******************************************************************************/
typedef struct {
guint8 type; /* 0: BitmapCoreHeader, 1: BitmapInfoHeader */
- unsigned width, height, planes, bit_count, compression,
+ unsigned size, width, height, planes, bit_count, compression,
image_size, x_pixels_per_m, y_pixels_per_m,
color_used, color_important;
+ GOColor *colors;
} GODibHeader;
static void
go_dib_read_header (GODibHeader *header, guint8 const *data)
{
- guint32 size = GSF_LE_GET_GUINT32 (data);
- header->type = (size == 12)? 0: 1;
+ header->size = GSF_LE_GET_GUINT32 (data);
+ header->type = (header->size == 12)? 0: 1;
if (header->type == 0) {
header->width = GSF_LE_GET_GUINT16 (data + 4);
header->height = GSF_LE_GET_GUINT16 (data + 6);
@@ -310,7 +311,7 @@ go_dib_read_header (GODibHeader *header, guint8 const *data)
header->color_used = 0;
header->color_important = 0;
} else {
- if (size != 40) {
+ if (header->size != 40) {
/* Invalid header */
header->type = 255;
return;
@@ -326,6 +327,8 @@ go_dib_read_header (GODibHeader *header, guint8 const *data)
header->color_used = GSF_LE_GET_GUINT32 (data + 32);
header->color_important = GSF_LE_GET_GUINT32 (data + 36);
}
+ if (header->bit_count <= 16 && header->color_used == 0)
+ header->color_used = 1 << header->bit_count;
}
static GdkPixbuf *
@@ -333,8 +336,9 @@ go_dib_create_pixbuf_from_data (GODibHeader const *header, guint8 const *data)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, header->width, header->height);
unsigned i, j;
- unsigned dst_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ unsigned dst_rowstride = gdk_pixbuf_get_rowstride (pixbuf), src_rowstride;
guint8 *row, *cur;
+ guint8 const *src_row;
/* FIXME, this implementation is very incomplete */
switch (header->bit_count) {
case 0:
@@ -344,28 +348,28 @@ go_dib_create_pixbuf_from_data (GODibHeader const *header, guint8 const *data)
case 4:
break;
case 8:
- break;
- case 16:
- break;
- case 24:
- break;
- case 32:
switch (header->compression) {
case 0:
- if (header->type == 1 && header->width * header->height * 4 != header->image_size)
- g_warning ("Invalid bitmap");
+ src_rowstride = (header->width + 3) / 4 * 4;
+ if (header->type == 1 && header->image_size > 0 && src_rowstride * header->height != header->image_size)
+ g_warning ("Invalid bitmap size");
row = gdk_pixbuf_get_pixels (pixbuf) + header->height * dst_rowstride;
+ src_row = data;
for (i = 0; i < header->height; i++) {
row -= dst_rowstride;
cur = row;
+ data = src_row;
for (j = 0; j < header->width; j++) {
- cur[0] = data[2];
- cur[1] = data[1];
- cur[2] = data[0];
+ /* FIXME: this does not work if the color table is not RGB */
+ GOColor color = header->colors[*data];
+ cur[0] = GO_COLOR_UINT_R (color);
+ cur[1] = GO_COLOR_UINT_G (color);
+ cur[2] = GO_COLOR_UINT_B (color);
cur[3] = 0xff;
- data += 4;
+ data ++;
cur += 4;
}
+ src_row += src_rowstride;
}
break;
case 1:
@@ -386,6 +390,34 @@ go_dib_create_pixbuf_from_data (GODibHeader const *header, guint8 const *data)
break;
}
break;
+ case 16:
+ break;
+ case 24:
+ break;
+ case 32:
+ switch (header->compression) {
+ case 0:
+ if (header->type == 1 && header->width * header->height * 4 != header->image_size)
+ g_warning ("Invalid bitmap");
+ row = gdk_pixbuf_get_pixels (pixbuf) + header->height * dst_rowstride;
+ for (i = 0; i < header->height; i++) {
+ row -= dst_rowstride;
+ cur = row;
+ for (j = 0; j < header->width; j++) {
+ cur[0] = data[2];
+ cur[1] = data[1];
+ cur[2] = data[0];
+ cur[3] = 0xff;
+ data += 4;
+ cur += 4;
+ }
+ }
+ break;
+ default:
+ g_warning ("Invalid compression for a DIB file");
+ break;
+ }
+ break;
}
return pixbuf;
}
@@ -885,6 +917,7 @@ typedef struct {
gboolean PolygonFillMode; /* TRUE: winding, FALSE: alternate */
unsigned text_align;
GOColor text_color;
+ cairo_matrix_t m;
} GOEmfDC;
typedef struct {
@@ -2221,8 +2254,8 @@ go_wmf_mr_arc (GsfInput* input, GOWmfPage* pg, GocCanvas* canvas, int type)
yc = (arc->b + arc->t) * 0.5;
rx = abs ((arc->l - arc->r) * 0.5);
ry = abs ((arc->b - arc->t) * 0.5);
- a2 = atan2 (arc->xs - xc, arc->ys - yc);
- a1 = atan2 (xc - arc->xe, yc - arc->ye);
+ a1 = atan2 (yc - arc->ys, arc->xs - xc);
+ a2 = atan2 (yc - arc->ye, arc->xe - xc);
arc->xs = xc;
arc->ys = yc;
arc->r = rx;
@@ -2480,6 +2513,7 @@ static gboolean
go_emf_header (GOEmfState *state)
{
guint32 signature = GSF_LE_GET_GINT32 (state->data + 32);
+ cairo_matrix_t m;
switch (signature) {
case 0x464D4520:
state->is_emf = TRUE;
@@ -2497,6 +2531,12 @@ go_emf_header (GOEmfState *state)
d_(("\tbounds are (mm): left=%g top=%g right=%g bottom=%g\n",
(double) state->mmbounds.left / 100., (double) state->mmbounds.top / 100.,
(double) state->mmbounds.right / 100., (double) state->mmbounds.bottom / 100.));
+ cairo_matrix_init_scale (&m,
+ ((double) (state->mmbounds.right - state->mmbounds.left)) / (state->dubounds.right - state->dubounds.left) / 2540. * 72.,
+ ((double) (state->mmbounds.bottom - state->mmbounds.top)) / (state->dubounds.bottom - state->dubounds.top) / 2540. * 72.);
+ m.x0 = -(double) state->mmbounds.left / 2540. * 72.;
+ m.y0 = -(double) state->mmbounds.top / 2540. * 72.;
+ goc_item_set_transform (GOC_ITEM (goc_canvas_get_root (state->canvas)), &m);
return TRUE;
}
@@ -2506,7 +2546,45 @@ go_emf_header (GOEmfState *state)
static gboolean
go_emf_polybezier (GOEmfState *state)
{
+ unsigned count, n, offset;
+ double x0, y0, x1, y1, x2, y2;
+ GOPath *path;
+#ifdef DEBUG_EMF_SUPPORT
+ GOWmfRectL rect;
+#endif
d_(("polybezier\n"));
+#ifdef DEBUG_EMF_SUPPORT
+ go_wmf_read_rectl (&rect, state->data);
+#endif
+ d_(("\tbounds: left: %u; right: %u; top:%u bottom:%u\n",
+ rect.left,rect.right, rect.top, rect.bottom));
+ count = GSF_LE_GET_GUINT32 (state->data + 16);
+ d_(("\tfound %u points\n", count));
+ if (count % 3 != 1)
+ return FALSE;
+ path = go_path_new ();
+ count /= 3;
+ go_wmf_read_pointl (state->data + 20, &x0, &y0);
+ go_emf_convert_coords (state, &x0, &y0);
+ d_(("\tmove to x0=%g y0=%g\n", x0, y0));
+ go_path_move_to (path, x0, y0);
+ for (n = 0, offset = 28; n < count; n++, offset += 24) {
+ go_wmf_read_pointl (state->data + offset, &x0, &y0);
+ go_emf_convert_coords (state, &x0, &y0);
+ go_wmf_read_pointl (state->data + offset + 8, &x1, &y1);
+ go_emf_convert_coords (state, &x1, &y1);
+ go_wmf_read_pointl (state->data + offset + 16, &x2, &y2);
+ go_emf_convert_coords (state, &x2, &y2);
+ go_path_curve_to (path, x0, y0, x1, y1, x2, y2);
+ d_(("\tcurve to x0=%g y0=%g x1=%g y1=%g x2=%g y2=%g\n", x0, y0, x1, y1, x2, y2));
+ }
+ goc_item_set_transform (goc_item_new (state->curDC->group, GOC_TYPE_PATH,
+ "path", path,
+ "style", state->curDC->style,
+ "closed", FALSE,
+ NULL),
+ &state->curDC->m);
+ go_path_free (path);
return TRUE;
}
@@ -3002,16 +3080,23 @@ go_emf_setworldtransform (GOEmfState *state)
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 */
+ cairo_matrix_init (&state->curDC->m, m11, m12, m21, m22, dx, dy);
return TRUE;
}
+enum {
+ GO_MWT_IDENTITY = 0x01,
+ GO_MWT_LEFTMULTIPLY = 0x02,
+ GO_MWT_RIGHTMULTIPLY = 0x03,
+ GO_MWT_SET = 0x04
+};
+
static gboolean
go_emf_modifyworldtransform (GOEmfState *state)
{
#ifdef DEBUG_EMF_SUPPORT
char const *tmas[5] = {
- NULL,
+ "INVALID",
"MWT_IDENTITY",
"MWT_LEFTMULTIPLY",
"MWT_RIGHTMULTIPLY",
@@ -3020,6 +3105,7 @@ go_emf_modifyworldtransform (GOEmfState *state)
#endif
double m11, m12, m21, m22, dx, dy;
unsigned mode;
+ cairo_matrix_t m;
d_(("modifyworldtransform\n"));
m11 = GSF_LE_GET_FLOAT (state->data);
m12 = GSF_LE_GET_FLOAT (state->data + 4);
@@ -3027,10 +3113,26 @@ go_emf_modifyworldtransform (GOEmfState *state)
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);
+ mode = GSF_LE_GET_GUINT32 (state->data + 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]));
+ m11, m12, dx, m21, m22, dy, tmas[(mode < 4)? mode: 0]));
/* FIXME: do something with it */
+ switch (mode) {
+ case GO_MWT_IDENTITY:
+ cairo_matrix_init_identity (&state->curDC->m);
+ break;
+ case GO_MWT_LEFTMULTIPLY:
+ cairo_matrix_init (&m, m11, m12, m21, m22, dx, dy);
+ cairo_matrix_multiply (&state->curDC->m, &m, &state->curDC->m);
+ break;
+ case GO_MWT_RIGHTMULTIPLY:
+ cairo_matrix_init (&m, m11, m12, m21, m22, dx, dy);
+ cairo_matrix_multiply (&state->curDC->m, &state->curDC->m, &m);
+ break;
+ case GO_MWT_SET:
+ cairo_matrix_init (&state->curDC->m, m11, m12, m21, m22, dx, dy);
+ break;
+ }
return TRUE;
}
@@ -3167,13 +3269,25 @@ go_emf_selectobject (GOEmfState *state)
d_(("\tNull brush\n"));
break;
case GO_EMF_WHITE_PEN:
+ state->curDC->style->line.dash_type = GO_LINE_SOLID;
+ state->curDC->style->line.color = GO_COLOR_WHITE;
+ state->curDC->style->line.width = 0.;
+ state->curDC->style->line.auto_dash = FALSE;
+ state->curDC->style->line.auto_color = FALSE;
d_(("\tWhite pen\n"));
break;
case GO_EMF_BLACK_PEN:
- d_(("\tWhite pen\n"));
+ state->curDC->style->line.dash_type = GO_LINE_SOLID;
+ state->curDC->style->line.color = GO_COLOR_BLACK;
+ state->curDC->style->line.width = 0.;
+ state->curDC->style->line.auto_dash = FALSE;
+ state->curDC->style->line.auto_color = FALSE;
+ d_(("\tBlack pen\n"));
break;
case GO_EMF_NULL_PEN:
- d_(("\tWhite pen\n"));
+ state->curDC->style->line.dash_type = GO_LINE_NONE;
+ state->curDC->style->line.auto_dash = FALSE;
+ d_(("\tNull pen\n"));
break;
case GO_EMF_OEM_FIXED_FONT:
d_(("\tEOM fixed font\n"));
@@ -3376,8 +3490,10 @@ go_emf_rectangle (GOEmfState *state)
w = rect.right;
h = rect.bottom;
go_emf_convert_coords (state, &w, &h);
- goc_item_new (state->curDC->group, GOC_TYPE_RECTANGLE,
- "x", x, "y", y, "width", w - x, "height", h - y, NULL);
+ goc_item_set_transform (goc_item_new (state->curDC->group, GOC_TYPE_RECTANGLE,
+ "x", x, "y", y, "width", w - x,
+ "height", h - y, NULL),
+ &state->curDC->m);
return TRUE;
}
@@ -3692,8 +3808,10 @@ go_emf_stretchdibits (GOEmfState *state)
gint32 src_x, src_y, src_cx, src_cy;
guint32 usage_src, op;
guint32 header_pos, header_size, buffer_pos, buffer_size;
+ unsigned offset;
GODibHeader header;
GdkPixbuf *pixbuf;
+ unsigned i;
d_(("stretchdibits\n"));
go_wmf_read_rectl (&rect, state->data);
@@ -3716,10 +3834,29 @@ go_emf_stretchdibits (GOEmfState *state)
d_ (("\tsource format: %s, operation: %s\n", go_emf_dib_colors[usage_src], go_emf_ternary_raster_operation[op >> 16]));
d_ (("\tsource: x=%d y=%d cx=%d cy=%d\n",src_x, src_y, src_cx, src_cy));
d_ (("\tdestination: x=%d y=%d cx=%d cy=%d\n",dst_x, dst_y, dst_cx, dst_cy));
+ /* try building an in memory BMP file from the data */
go_dib_read_header (&header, state->data + header_pos);
if (header.type == 0xff)
return FALSE;
+ /* load the colors if needed */
+ if (header.color_used != 0) {
+ /* check that the header has the right size */
+ if (header_size - header.size != 4 * header.color_used) {
+ g_warning ("Invalid color table");
+ return FALSE;
+ }
+ offset = header_pos + header.size;
+ header.colors = g_new (GOColor, 256);
+ for (i = 0; i < header.color_used; i++) {
+ header.colors[i] = GO_COLOR_FROM_RGB (state->data[offset + 2],
+ state->data[offset + 1],
+ state->data[offset]);
+ offset += 4;
+ }
+ } else
+ header.colors = NULL;
pixbuf = go_dib_create_pixbuf_from_data (&header, state->data + buffer_pos);
+ g_free (header.colors);
if (src_x != 0 || src_y != 0 || src_cx != dst_cx || src_cy != dst_cy) {
/* FIXME: take src coordinates into account */
}
@@ -3784,7 +3921,45 @@ go_emf_exttextoutw (GOEmfState *state)
static gboolean
go_emf_polybezier16 (GOEmfState *state)
{
+ unsigned count, n, offset;
+ double x0, y0, x1, y1, x2, y2;
+ GOPath *path;
+#ifdef DEBUG_EMF_SUPPORT
+ GOWmfRectL rect;
+#endif
d_(("polybezier16\n"));
+#ifdef DEBUG_EMF_SUPPORT
+ go_wmf_read_rectl (&rect, state->data);
+#endif
+ d_(("\tbounds: left: %u; right: %u; top:%u bottom:%u\n",
+ rect.left,rect.right, rect.top, rect.bottom));
+ count = GSF_LE_GET_GUINT32 (state->data + 16);
+ d_(("\tfound %u points\n", count));
+ if (count % 3 != 1)
+ return FALSE;
+ path = go_path_new ();
+ count /= 3;
+ go_wmf_read_points (state->data + 20, &x0, &y0);
+ go_emf_convert_coords (state, &x0, &y0);
+ d_(("\tmove to x0=%g y0=%g\n", x0, y0));
+ go_path_move_to (path, x0, y0);
+ for (n = 0, offset = 24; n < count; n++, offset += 12) {
+ go_wmf_read_points (state->data + offset, &x0, &y0);
+ go_emf_convert_coords (state, &x0, &y0);
+ go_wmf_read_points (state->data + offset + 4, &x1, &y1);
+ go_emf_convert_coords (state, &x1, &y1);
+ go_wmf_read_points (state->data + offset + 8, &x2, &y2);
+ go_emf_convert_coords (state, &x2, &y2);
+ go_path_curve_to (path, x0, y0, x1, y1, x2, y2);
+ d_(("\tcurve to x0=%g y0=%g x1=%g y1=%g x2=%g y2=%g\n", x0, y0, x1, y1, x2, y2));
+ }
+ goc_item_set_transform (goc_item_new (state->curDC->group, GOC_TYPE_PATH,
+ "path", path,
+ "style", state->curDC->style,
+ "closed", FALSE,
+ NULL),
+ &state->curDC->m);
+ go_path_free (path);
return TRUE;
}
@@ -3813,10 +3988,11 @@ go_emf_polygon16 (GOEmfState *state)
points->points[n].y = y;
d_(("\tpoint #%u at x=%g y=%g\n", n, x, y));
}
- goc_item_new (state->curDC->group, GOC_TYPE_POLYGON,
- "points", points,
- "style", state->curDC->style,
- NULL);
+ goc_item_set_transform (goc_item_new (state->curDC->group, GOC_TYPE_POLYGON,
+ "points", points,
+ "style", state->curDC->style,
+ NULL),
+ &state->curDC->m);
return TRUE;
}
@@ -4093,7 +4269,7 @@ typedef gboolean (*GOEmfHandler) (GOEmfState* state);
static GOEmfHandler go_emf_handlers[] = {
NULL,
go_emf_header, /* 0x0001 ok */
- go_emf_polybezier, /* 0x0002 todo */
+ go_emf_polybezier, /* 0x0002 untested */
go_emf_polygon, /* 0x0003 ok */
go_emf_polyline, /* 0x0004 ok */
go_emf_polybezierto, /* 0x0005 ok */
@@ -4176,8 +4352,8 @@ static GOEmfHandler go_emf_handlers[] = {
go_emf_extcreatefontindirectw, /* 0x0052 partial */
go_emf_exttextouta, /* 0x0053 todo */
go_emf_exttextoutw, /* 0x0054 todo */
- go_emf_polybezier16, /* 0x0055 todo */
- go_emf_polygon16, /* 0x0056 untested */
+ go_emf_polybezier16, /* 0x0055 ok */
+ go_emf_polygon16, /* 0x0056 ok */
go_emf_polyline16, /* 0x0057 untested */
go_emf_polybezierto16, /* 0x0058 untested */
go_emf_polylineto16, /* 0x0059 untested */
@@ -4336,6 +4512,7 @@ go_emf_parse (GOEmf *emf, GsfInput *input, GError **error)
state.dw = state.dh = state.ww = state.wh = 1.;
state.mfobjs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_free);
+ cairo_matrix_init_identity (&state.curDC->m);
offset = 4;
while ((offset += 4) < fsize && rid != 0xe) { /* EOF */
data = gsf_input_read (input, 4, NULL);
diff --git a/goffice/utils/go-pango-extras.c b/goffice/utils/go-pango-extras.c
index dbf9c93..ca11d23 100644
--- a/goffice/utils/go-pango-extras.c
+++ b/goffice/utils/go-pango-extras.c
@@ -749,9 +749,9 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
int spans = 0;
switch (a->klass->type) {
- case PANGO_ATTR_FONT_DESC :
+ case PANGO_ATTR_FONT_DESC :
{
- char *str = pango_font_description_to_string
+ char *str = pango_font_description_to_string
(((PangoAttrFontDesc *)a)->desc);
spans += 1;
g_string_append_printf (gstr, "<span font_desc=\"%s\">", str);
@@ -760,18 +760,18 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
break;
case PANGO_ATTR_FAMILY :
spans += 1;
- g_string_append_printf (gstr, "<span font_family=\"%s\">",
+ g_string_append_printf (gstr, "<span font_family=\"%s\">",
((PangoAttrString *)a)->value);
break;
case PANGO_ATTR_ABSOLUTE_SIZE :
case PANGO_ATTR_SIZE :
spans += 1;
- g_string_append_printf (gstr, "<span font_size=\"%i\">",
+ g_string_append_printf (gstr, "<span font_size=\"%i\">",
((PangoAttrSize *)a)->size);
break;
case PANGO_ATTR_RISE:
spans += 1;
- g_string_append_printf (gstr, "<span rise=\"%i\">",
+ g_string_append_printf (gstr, "<span rise=\"%i\">",
((PangoAttrInt *)a)->value);
break;
case PANGO_ATTR_STYLE :
@@ -787,11 +787,11 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
default:
g_string_append (gstr, "<span font_style=\"normal\">");
break;
- }
+ }
break;
case PANGO_ATTR_WEIGHT :
spans += 1;
- g_string_append_printf (gstr, "<span font_weight=\"%i\">",
+ g_string_append_printf (gstr, "<span font_weight=\"%i\">",
((PangoAttrInt *)a)->value);
break;
case PANGO_ATTR_STRIKETHROUGH :
@@ -820,11 +820,11 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
default:
g_string_append (gstr, "<span underline=\"none\">");
break;
- }
+ }
break;
case PANGO_ATTR_LANGUAGE :
spans += 1;
- g_string_append_printf (gstr, "<span lang=\"%s\">",
+ g_string_append_printf (gstr, "<span lang=\"%s\">",
pango_language_to_string (((PangoAttrLanguage *)a)->value));
break;
case PANGO_ATTR_VARIANT :
@@ -836,7 +836,7 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
break;
case PANGO_ATTR_LETTER_SPACING :
spans += 1;
- g_string_append_printf (gstr, "<span letter_spacing=\"%i\">",
+ g_string_append_printf (gstr, "<span letter_spacing=\"%i\">",
((PangoAttrInt *)a)->value);
break;
case PANGO_ATTR_FALLBACK :
@@ -877,7 +877,7 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
default:
g_string_append (gstr, "<span font_stretch=\"normal\">");
break;
- }
+ }
break;
case PANGO_ATTR_GRAVITY :
spans += 1;
@@ -898,7 +898,7 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
default:
g_string_append (gstr, "<span gravity=\"auto\">");
break;
- }
+ }
break;
case PANGO_ATTR_GRAVITY_HINT :
spans += 1;
@@ -913,9 +913,9 @@ go_pango_attr_as_markup_string (PangoAttribute *a, GString *gstr)
default:
g_string_append (gstr, "<span gravity_hint=\"natural\">");
break;
- }
+ }
break;
-
+
case PANGO_ATTR_FOREGROUND :
{
PangoColor *color = &((PangoAttrColor *)a)->color;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]