[dia] wpg: overhaul of WPG export and implementation of import



commit ee23c32cc8a3cf6a174e1b88955e711f3072abe3
Author: Hans Breuer <hans breuer org>
Date:   Sun Apr 20 11:42:08 2014 +0200

    wpg: overhaul of WPG export and implementation of import
    
    Export had some things wrong for years, like:
     - images were flipped upside down
     - WPG Polycurve was not used due to some misunderstanding with the
       specification http://www.fileformat.info/format/wpg/egff.htm
     - object positioning was slightly wrong
    
    Import was only test code compiled on Windows, now:
     - split test code to it's own file and make it a full WPG importer
     - can read in again everything Dia writes with the exporter
     - some type information still lost due limitations in WPG (e.g. font
       handling, image bit depth and alpha) as well as limitations with
       Dia (e.g. no filled arc object yet)
    
    Exported files (render-test.dia, std-props-test.dia bezier-approx.dia)
    were tested for conformance with WordPerfect 5.1 (DOS) and "My ViewPad"
    4.1.122 (Windows 7/32).
    Also some test were performed with Inkscape 0.48.1 but Inkscape's WPG
    import has issues with positioning, filling, line style, text, arcs and
    poly curves at least.

 lib/Doxyfile              |    3 +-
 plug-ins/makefile.msc     |    6 +
 plug-ins/wpg/Makefile.am  |    2 +-
 plug-ins/wpg/wpg-import.c |  620 +++++++++++++++++++++++++++++++++++++++++++++
 plug-ins/wpg/wpg.c        |  359 +++++---------------------
 plug-ins/wpg/wpg_defs.h   |   10 +
 6 files changed, 705 insertions(+), 295 deletions(-)
---
diff --git a/lib/Doxyfile b/lib/Doxyfile
index 155d5eb..c1783c7 100644
--- a/lib/Doxyfile
+++ b/lib/Doxyfile
@@ -12,7 +12,8 @@ WARN_IF_UNDOCUMENTED   = NO
 WARN_LOGFILE           = doxygen.log
 INPUT                  = ../lib ../objects/standard ../objects/custom \
                          ../plug-ins/python ../plug-ins/svg ../plug-ins/shape \
-                         ../plug-ins/cairo ../plug-ins/layout ../plug-ins/svg
+                         ../plug-ins/cairo ../plug-ins/layout ../plug-ins/svg \
+                         ../plug-ins/wpg
 #STRIP_FROM_PATH        = ../
 FILE_PATTERNS          = *.c *.h *.dox *.py *.cpp
 # define HAVE_CAIRO to get the Outline dox
diff --git a/plug-ins/makefile.msc b/plug-ins/makefile.msc
index e9e4842..4fefedb 100644
--- a/plug-ins/makefile.msc
+++ b/plug-ins/makefile.msc
@@ -183,6 +183,12 @@ OBJECTS = \
   wmf_gdi.obj
 !ENDIF
 
+!IFDEF OBJ_wpg
+OBJECTS = \
+  wpg.obj \
+  wpg-import.obj
+!ENDIF
+
 !IFDEF OBJ_xfig
 OBJECTS = \
   xfig.obj \
diff --git a/plug-ins/wpg/Makefile.am b/plug-ins/wpg/Makefile.am
index ba145b9..3ca581d 100644
--- a/plug-ins/wpg/Makefile.am
+++ b/plug-ins/wpg/Makefile.am
@@ -1,6 +1,6 @@
 pkglib_LTLIBRARIES = libwpg_filter.la
 
-libwpg_filter_la_SOURCES = wpg.c wpg_defs.h
+libwpg_filter_la_SOURCES = wpg.c wpg_defs.h wpg-import.c
 libwpg_filter_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED)
 
 libwpg_filter_la_LIBADD = $(top_builddir)/lib/libdia.la
diff --git a/plug-ins/wpg/wpg-import.c b/plug-ins/wpg/wpg-import.c
new file mode 100644
index 0000000..0fd7f47
--- /dev/null
+++ b/plug-ins/wpg/wpg-import.c
@@ -0,0 +1,620 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * wpg-import.c -- WordPerfect Graphics import plug-in for Dia
+ * Copyright (C) 2014 Hans Breuer <hans breuer org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "diaimportrenderer.h"
+#include "wpg_defs.h"
+#include "dia_image.h"
+#include "diacontext.h"
+#include "intl.h"
+
+typedef struct _WpgImportRenderer  WpgImportRenderer;
+
+/*!
+ * \brief Renderer for WordPerfect Graphics import
+ * \extends _DiaImportRenderer
+ */
+typedef struct _WpgImportRenderer {
+  DiaImportRenderer parent_instance;
+
+  WPGStartData Box;
+  WPGFillAttr  FillAttr;
+  WPGLineAttr  LineAttr;
+  WPGColorRGB* pPal;
+
+  Color stroke;
+  Color fill;
+  Color text_color;
+  Alignment text_align;
+};
+
+typedef struct _WpgImportRendererClass WpgImportRendererClass;
+struct _WpgImportRendererClass {
+  DiaRendererClass parent_class;
+};
+
+G_DEFINE_TYPE(WpgImportRenderer, wpg_import_renderer, DIA_TYPE_IMPORT_RENDERER);
+
+#define WPG_TYPE_IMPORT_RENDERER (wpg_import_renderer_get_type ())
+#define WPG_IMPORT_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WPG_TYPE_IMPORT_RENDERER, 
WpgImportRenderer))
+
+static void 
+wpg_import_renderer_class_init (WpgImportRendererClass *klass)
+{
+  /* anything to initialize? */
+}
+static void 
+wpg_import_renderer_init (WpgImportRenderer *self)
+{
+  /* anything to initialize? */
+  self->LineAttr.Type = WPG_LA_SOLID;
+  self->FillAttr.Type = WPG_FA_HOLLOW;
+}
+
+static Point *
+_make_points (WpgImportRenderer *ren,
+             WPGPoint          *pts,
+             int                num)
+{
+  int    i;
+  int    ofs = ren->Box.Height;
+  Point *points = g_new (Point, num);
+
+  for (i = 0; i < num; ++i) {
+    points[i].x = pts[i].x / WPU_PER_DCM;
+    points[i].y = (ofs - pts[i].y) / WPU_PER_DCM;
+  }
+  return points;
+}
+static Point *
+_make_rect (WpgImportRenderer *ren,
+           WPGPoint          *pts)
+{
+  /* WPG has position and size, Dia wants top-left and bottom-right */
+  int       ofs = ren->Box.Height;
+  Point    *points = g_new (Point, 2);
+  WPGPoint *pos = pts;
+  WPGPoint *wh = pts+1;
+  /* also it bottom vs. top position */
+  points[0].x = pos->x / WPU_PER_DCM;
+  points[1].y = (ofs - pos->y) / WPU_PER_DCM;
+  points[1].x = points[0].x + (wh->x / WPU_PER_DCM);
+  points[0].y = points[1].y - (wh->y / WPU_PER_DCM);
+  return points;
+}
+
+static void
+_do_ellipse (WpgImportRenderer *ren, WPGEllipse* pEll)
+{
+  int    h = ren->Box.Height;
+  Point center;
+  center.x = pEll->x / WPU_PER_DCM;
+  center.y = (h - pEll->y) / WPU_PER_DCM;
+  
+  if (fabs(pEll->EndAngle - pEll->StartAngle) < 360) {
+    if (ren->LineAttr.Type != WPG_LA_NONE)
+      DIA_RENDERER_GET_CLASS(ren)->draw_arc (DIA_RENDERER(ren), &center,
+                                            2 * pEll->rx / WPU_PER_DCM,
+                                            2 * pEll->ry / WPU_PER_DCM,
+                                            pEll->StartAngle, pEll->EndAngle,
+                                            &ren->stroke);
+    if (ren->FillAttr.Type != WPG_FA_HOLLOW)
+      DIA_RENDERER_GET_CLASS(ren)->fill_arc (DIA_RENDERER(ren), &center,
+                                            2 * pEll->rx / WPU_PER_DCM,
+                                            2 * pEll->ry / WPU_PER_DCM,
+                                            pEll->StartAngle, pEll->EndAngle,
+                                            &ren->fill);
+  } else {
+    if (ren->LineAttr.Type != WPG_LA_NONE)
+      DIA_RENDERER_GET_CLASS(ren)->draw_ellipse (DIA_RENDERER(ren), &center,
+                                                2 * pEll->rx / WPU_PER_DCM,
+                                                2 * pEll->ry / WPU_PER_DCM,
+                                                &ren->stroke);
+    if (ren->FillAttr.Type != WPG_FA_HOLLOW)
+      DIA_RENDERER_GET_CLASS(ren)->fill_ellipse (DIA_RENDERER(ren), &center,
+                                                2 * pEll->rx / WPU_PER_DCM,
+                                                2 * pEll->ry / WPU_PER_DCM,
+                                                &ren->fill);
+  }
+}
+
+static void
+_do_polygon (WpgImportRenderer *ren, Point *points, int iNum)
+{
+  g_return_if_fail (iNum > 2);
+  if (ren->LineAttr.Type != WPG_LA_NONE)
+    DIA_RENDERER_GET_CLASS(ren)->draw_polygon (DIA_RENDERER(ren), points, iNum, &ren->stroke);
+  if (ren->FillAttr.Type != WPG_FA_HOLLOW)
+    DIA_RENDERER_GET_CLASS(ren)->fill_polygon (DIA_RENDERER(ren), points, iNum, &ren->fill);
+}
+static void
+_do_rect (WpgImportRenderer *ren, Point *points)
+{
+  if (ren->LineAttr.Type != WPG_LA_NONE)
+    DIA_RENDERER_GET_CLASS(ren)->draw_rect (DIA_RENDERER(ren),
+                                           &points[0], &points[1], &ren->stroke);
+  if (ren->FillAttr.Type != WPG_FA_HOLLOW)
+    DIA_RENDERER_GET_CLASS(ren)->fill_rect (DIA_RENDERER(ren),
+                                           &points[0], &points[1], &ren->fill);
+}
+static void
+_do_bezier (WpgImportRenderer *ren, WPGPoint *pts, int iNum)
+{
+  int num_points = (iNum + 2) / 3;
+  int i;
+  int ofs = ren->Box.Height;
+  BezPoint *bps;
+
+  g_return_if_fail (num_points > 1);
+
+  bps = g_alloca (num_points * sizeof(BezPoint));
+
+  bps[0].type = BEZ_MOVE_TO;
+  bps[0].p1.x = pts[0].x / WPU_PER_DCM;
+  bps[0].p1.y = (ofs - pts[0].y) / WPU_PER_DCM;
+  for (i = 1; i < num_points; ++i) {
+    bps[i].type = BEZ_CURVE_TO;
+    /* although declared as unsigned (WORD) these values have to be treaded
+     * as signed, because they can move in both directions.
+     */
+    bps[i].p1.x =        (gint16)pts[i*3-2].x  / WPU_PER_DCM;
+    bps[i].p1.y = (ofs - (gint16)pts[i*3-2].y) / WPU_PER_DCM;
+    bps[i].p2.x =        (gint16)pts[i*3-1].x  / WPU_PER_DCM;
+    bps[i].p2.y = (ofs - (gint16)pts[i*3-1].y) / WPU_PER_DCM;
+    bps[i].p3.x =        (gint16)pts[i*3  ].x  / WPU_PER_DCM;
+    bps[i].p3.y = (ofs - (gint16)pts[i*3  ].y) / WPU_PER_DCM;
+  }
+  if (ren->LineAttr.Type != WPG_LA_NONE)
+    DIA_RENDERER_GET_CLASS(ren)->draw_bezier (DIA_RENDERER(ren),
+                                             bps, num_points, &ren->stroke);
+  if (ren->FillAttr.Type != WPG_FA_HOLLOW)
+    DIA_RENDERER_GET_CLASS(ren)->fill_bezier (DIA_RENDERER(ren),
+                                             bps, num_points, &ren->fill);
+}
+
+/*
+ * Import (under construction)
+ */
+static void
+import_object(DiaRenderer* self, DiagramData *dia,
+              WPG_Type type, int iSize, guchar* pData)
+{
+  WpgImportRenderer *renderer = WPG_IMPORT_RENDERER(self);
+  WPGPoint* pts = NULL;
+  gint16* pInt16 = NULL;
+  int    iNum = 0;
+  gint32 iPre51 = 0;
+  Point *points = NULL;
+
+  switch (type) {
+  case WPG_LINE:
+    iNum = 2;
+    pts = (WPGPoint*)pData;
+    points = _make_points (renderer, pts, iNum);
+    DIA_RENDERER_GET_CLASS(renderer)->draw_line (self, &points[0], &points[1], &renderer->stroke);
+    break;
+  case WPG_POLYLINE:
+    pInt16 = (gint16*)pData;
+    iNum = pInt16[0];
+    pts = (WPGPoint*)(pData + sizeof(gint16));
+    points = _make_points (renderer, pts, iNum);
+    DIA_RENDERER_GET_CLASS(renderer)->draw_polyline (self, points, iNum, &renderer->stroke);
+    break;
+  case WPG_RECTANGLE:
+    points = _make_rect (renderer, (WPGPoint*)pData);
+    _do_rect (renderer, points);
+    break;
+  case WPG_POLYGON:
+    pInt16 = (gint16*)pData;
+    iNum = pInt16[0];
+    pts = (WPGPoint*)(pData + sizeof(gint16));
+    points = _make_points (renderer, pts, iNum);
+    _do_polygon (renderer, points, iNum);
+    break;
+  case WPG_ELLIPSE:
+    {
+      WPGEllipse* pEll = (WPGEllipse*)pData;
+      _do_ellipse (renderer, pEll);
+    }
+    break;
+  case WPG_POLYCURVE:
+    iPre51 = *((gint32*)pData);
+    pInt16 = (gint16*)pData;
+    iNum = pInt16[2];
+    pts = (WPGPoint*)(pData + 3*sizeof(gint16));
+    DIAG_NOTE(g_message("POLYCURVE Num pts %d Pre51 %d", iNum, iPre51));
+    _do_bezier (renderer, pts, iNum);
+    break;
+  } /* switch */
+  g_free (points);
+  DIAG_NOTE(g_message("Type %d Num pts %d Size %d", type, iNum, iSize));
+} 
+
+static void
+_make_stroke (WpgImportRenderer *ren)
+{
+  WPGColorRGB c;
+
+  g_return_if_fail (ren->pPal != NULL);
+  c = ren->pPal[ren->LineAttr.Color];
+  ren->stroke.red = c.r / 255.0;
+  ren->stroke.green = c.g / 255.0;
+  ren->stroke.blue = c.b / 255.0;
+  ren->stroke.alpha = 1.0;
+  switch (ren->LineAttr.Type) {
+  case WPG_LA_SOLID:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_SOLID);
+    break;
+  case WPG_LA_MEDIUMDASH:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_DASHED);
+    DIA_RENDERER_GET_CLASS(ren)->set_dashlength (DIA_RENDERER(ren), 0.66);
+    break;
+  case WPG_LA_SHORTDASH:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_DASHED);
+    DIA_RENDERER_GET_CLASS(ren)->set_dashlength (DIA_RENDERER(ren), 0.33);
+    break;
+  case WPG_LA_DASHDOT:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_DASH_DOT);
+    DIA_RENDERER_GET_CLASS(ren)->set_dashlength (DIA_RENDERER(ren), 1.0);
+    break;
+  case WPG_LA_DASHDOTDOT:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_DASH_DOT_DOT);
+    DIA_RENDERER_GET_CLASS(ren)->set_dashlength (DIA_RENDERER(ren), 1.0);
+    break;
+  case WPG_LA_DOTS:
+    DIA_RENDERER_GET_CLASS(ren)->set_linestyle (DIA_RENDERER(ren), LINESTYLE_DOTTED);
+    DIA_RENDERER_GET_CLASS(ren)->set_dashlength (DIA_RENDERER(ren), 1.0);
+    break;
+  }
+
+  DIA_RENDERER_GET_CLASS(ren)->set_linewidth (DIA_RENDERER(ren),
+                                             ren->LineAttr.Width / WPU_PER_DCM);
+}
+
+static void
+_make_fill (WpgImportRenderer *ren)
+{
+  WPGColorRGB c;
+
+  g_return_if_fail (ren->pPal != NULL);
+  c = ren->pPal[ren->FillAttr.Color];
+  ren->fill.red = c.r / 255.0;
+  ren->fill.green = c.g / 255.0;
+  ren->fill.blue = c.b / 255.0;
+  ren->fill.alpha = 1.0;
+}
+
+static gboolean
+_render_bmp (WpgImportRenderer *ren, WPGBitmap2 *bmp, FILE *f, int len)
+{
+  GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, /* no alpha */
+                                     8, /* bits per sample: nothing else */
+                                     bmp->Width, bmp->Height);
+  guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
+#define PUT_PIXEL(pix) \
+  { WPGColorRGB rgb = ren->pPal[pix]; \
+    pixels[0] = rgb.r; pixels[1] = rgb.g; pixels[2] = rgb.b; \
+    pixels[3] = 0xff; pixels+=4; }
+#define REPEAT_LINE(sth) \
+  { memcpy (pixels + 4 * bmp->Width, pixels, 4 * bmp->Width); pixels+=(4 * bmp->Width); }
+  if (pixbuf) {
+    DiaImage *image;
+    int    h = ren->Box.Height;
+    Point pt = { bmp->Left / WPU_PER_DCM, (h - bmp->Top) / WPU_PER_DCM };
+    if (bmp->Depth != 8)
+      g_warning ("WPGBitmap2 unsupported depth %d", bmp->Depth);
+    while (len > 0) {
+      guint8 b, rc, i;
+      if (1 == fread(&b, sizeof(guint8), 1, f)) {
+       if (b & 0x80) {
+         rc = b & 0x7F;
+         if (rc != 0) { /* Read the next BYTE and repeat it RunCount times */
+           fread(&b, sizeof(guint8), 1, f); len--;
+           for (i = 0; i < rc; ++i)
+             PUT_PIXEL (b)
+         } else { /* Repeat the value FFh RunCount times */
+           fread (&rc, sizeof(guint8), 1, f); len--;
+           for (i = 0; i < rc; ++i)
+             PUT_PIXEL (0xFF)
+         }
+       } else {
+         rc = b & 0x7F;
+         if (rc != 0) { /* The next RunCount BYTEs are read literally */
+           for (i = 0; i < rc; ++i) {
+             fread (&b, sizeof(guint8), 1, f); len--;
+             PUT_PIXEL (b)
+           }
+         } else { /* Repeat the previous scan line RunCount times */
+           fread (&rc, sizeof(guint8), 1, f); len--;
+           for (i = 0; i < rc; ++i)
+             REPEAT_LINE (0xFF);
+         }
+       }
+      }
+      len--;
+    }
+    image = dia_image_new_from_pixbuf (pixbuf);
+    if (bmp->Right - bmp->Left == 0 || bmp->Bottom - bmp->Top == 0)
+      DIA_RENDERER_GET_CLASS(ren)->draw_image (DIA_RENDERER(ren), &pt,
+                                              bmp->Xdpi / 2.54, bmp->Ydpi / 2.54,
+                                              image);
+    else /* real WPGBitmap2 */
+      DIA_RENDERER_GET_CLASS(ren)->draw_image (DIA_RENDERER(ren), &pt,
+                                              (bmp->Right - bmp->Left) / WPU_PER_DCM,
+                                              (bmp->Bottom - bmp->Top) / WPU_PER_DCM,
+                                              image);
+    g_object_unref (pixbuf);
+    g_object_unref (image);
+    return TRUE;
+  }
+#undef PUT_PIXEL
+#undef REPEAT_LINE
+  return FALSE;
+}
+
+static void
+_do_textstyle (WpgImportRenderer *ren, WPGTextStyle *ts)
+{
+  WPGColorRGB c;
+
+  /* change some text properties directly, store the res for draw_string */
+  real height;
+  DiaFont *font;
+
+  g_return_if_fail(sizeof(WPGTextStyle) == 22);
+
+  c = ren->pPal[ts->Color];
+  ren->text_color.red = c.r / 255.0;
+  ren->text_color.green = c.g / 255.0;
+  ren->text_color.blue = c.b / 255.0;
+  ren->text_color.alpha = 1.0;
+
+  ren->text_align = ts->XAlign == 0 ? ALIGN_LEFT :
+                   ts->XAlign == 1 ? ALIGN_CENTER : ALIGN_RIGHT;
+  /* select font */
+  height = ts->Height / WPU_PER_DCM;
+  if (ts->Font == 0x0DF0)
+    font = dia_font_new_from_style (DIA_FONT_MONOSPACE, height);
+  else if (ts->Font == 0x1950)
+    font = dia_font_new_from_style (DIA_FONT_SERIF, height);
+  else if (ts->Font == 0x1150)
+    font = dia_font_new_from_style (DIA_FONT_SANS, height);
+  else /* any is not advices */
+    font = dia_font_new_from_style (DIA_FONT_SANS, height);
+
+  DIA_RENDERER_GET_CLASS(ren)->set_font (DIA_RENDERER(ren), font, height);
+
+  dia_font_unref (font);
+}
+
+static void
+_render_text (WpgImportRenderer *ren, WPGPoint *pos, gchar *text)
+{
+  Point pt;
+  pt.x = pos->x / WPU_PER_DCM;
+  pt.y = (ren->Box.Height - pos->y ) / WPU_PER_DCM;
+
+  DIA_RENDERER_GET_CLASS(ren)->draw_string (DIA_RENDERER(ren), text, &pt,
+                                           ren->text_align, &ren->text_color);
+}
+
+gboolean
+import_data (const gchar *filename, DiagramData *dia, DiaContext *ctx, void* user_data)
+{
+  FILE* f;
+  gboolean bRet;
+  WPGHead8 rh;
+
+  f = g_fopen(filename, "rb");
+
+  if (NULL == f) {
+    dia_context_add_message(ctx, _("Couldn't open: '%s' for reading.\n"), filename);
+    bRet = FALSE;
+  }
+  
+  /* check header */
+  if (bRet) {
+    WPGFileHead fhead;
+    bRet = ( (1 == fread(&fhead, sizeof(WPGFileHead), 1, f))
+            && fhead.fid[0] == 255 && fhead.fid[1] == 'W'
+            && fhead.fid[2] == 'P' && fhead.fid[3] == 'C'
+            && (1 == fhead.MajorVersion) && (0 == fhead.MinorVersion));
+    if (!bRet)
+      dia_context_add_message(ctx, _("File: %s type/version unsupported.\n"), filename);
+  }
+
+  if (bRet) {
+    int iSize;
+    gint16 i16, iNum16;
+    guint8 i8;
+    WpgImportRenderer *ren = g_object_new (WPG_TYPE_IMPORT_RENDERER, NULL);
+
+    ren->pPal = g_new0(WPGColorRGB, 256);
+
+    DIAG_NOTE(g_message("Parsing: %s ", filename));
+
+    do {
+      if (1 == fread(&rh, sizeof(WPGHead8), 1, f)) {
+        if (rh.Size < 0xFF)
+          iSize = rh.Size;
+        else {
+          bRet = (1 == fread(&i16, sizeof(guint16), 1, f));
+          if (0x8000 & i16) {
+            DIAG_NOTE(g_print("Large Object: hi:lo %04X", (int)i16));
+            iSize = (0x7FFF & i16) << 16;
+            /* Reading large objects involves major uglyness. Instead of getting 
+             * one size, as implied by "Encyclopedia of Graphics File Formats",
+             * it would require putting together small chunks of data to one large 
+             * object. The criteria when to stop isn't absolutely clear.
+             */
+            bRet = (1 == fread(&i16, sizeof(guint16), 1, f));
+            DIAG_NOTE(g_print("Large Object: %d\n", (int)i16));
+            iSize += (unsigned short)i16;
+#if 0
+            /* Ignore this large objec part */
+            fseek(f, iSize, SEEK_CUR);
+            continue;
+#endif
+          }
+          else
+            iSize = i16; 
+        }
+      } else
+        iSize = 0;
+
+      /* DIAG_NOTE(g_message("Type %d Size %d", rh.Type, iSize)); */
+      if (iSize > 0) {
+        switch (rh.Type) {
+        case WPG_FILLATTR:
+          bRet = (1 == fread(&ren->FillAttr, sizeof(WPGFillAttr), 1, f));
+         _make_fill (ren);
+          break;
+        case WPG_LINEATTR:
+          bRet = (1 == fread(&ren->LineAttr, sizeof(WPGLineAttr), 1, f));
+         _make_stroke (ren);
+          break;
+        case WPG_START:
+          bRet = (1 == fread(&ren->Box, sizeof(WPGStartData), 1, f));
+          break;
+        case WPG_STARTWPG2:
+          /* not sure if this is the right thing to do */
+          bRet &= (1 == fread(&i8, sizeof(gint8), 1, f));
+          bRet &= (1 == fread(&i16, sizeof(gint16), 1, f));
+          DIAG_NOTE(g_message("Ignoring tag WPG_STARTWPG2, Size %d\n Type? %d Size? %d", 
+                    iSize, (int)i8, i16));
+          fseek(f, iSize - 3, SEEK_CUR);
+          break;
+        case WPG_LINE:
+        case WPG_POLYLINE:
+        case WPG_RECTANGLE:
+        case WPG_POLYGON:
+        case WPG_POLYCURVE:
+        case WPG_ELLIPSE:
+          {
+            guchar* pData;
+
+            pData = g_new(guchar, iSize);
+            bRet = (iSize == (int)fread(pData, 1, iSize, f));
+            import_object(DIA_RENDERER(ren), dia, rh.Type, iSize, pData);
+            g_free(pData);
+          }
+          break;
+        case WPG_COLORMAP:
+          bRet &= (1 == fread(&i16, sizeof(gint16), 1, f));
+          bRet &= (1 == fread(&iNum16, sizeof(gint16), 1, f));
+          if (iNum16 != (gint16)((iSize - 2) / sizeof(WPGColorRGB)))
+            g_warning("WpgImporter : colormap size/header mismatch.");
+          if (i16 >= 0 && i16 <= iSize) {
+            bRet &= (iNum16 == (int)fread(&ren->pPal[i16], sizeof(WPGColorRGB), iNum16, f));
+          }
+          else {
+            g_warning("WpgImporter : start color map index out of range.");
+            bRet &= (iNum16 == (int)fread(ren->pPal, sizeof(WPGColorRGB), iNum16, f));
+          }
+          break;
+       case WPG_BITMAP1:
+          {
+            WPGBitmap1 bmp;
+            WPGBitmap2 bmp2 = { 0, };
+
+            fread(&bmp, sizeof(WPGBitmap1), 1, f);
+           /* transfer data to bmp2 struct */
+           bmp2.Width = bmp.Width;
+           bmp2.Height = bmp.Height;
+           bmp2.Depth = bmp.BitsPerPixel; /* really? */
+           bmp2.Xdpi = bmp.Xdpi;
+           bmp2.Ydpi = bmp.Ydpi;
+
+           if (!_render_bmp (ren, &bmp2, f, iSize - sizeof(WPGBitmap1)))
+             fseek(f, iSize - sizeof(WPGBitmap2), SEEK_CUR);
+          }
+         break;
+        case WPG_BITMAP2:
+          {
+            WPGBitmap2 bmp;
+
+            fread(&bmp, sizeof(WPGBitmap2), 1, f);
+           if (!_render_bmp (ren, &bmp, f, iSize - sizeof(WPGBitmap2)))
+             fseek(f, iSize - sizeof(WPGBitmap2), SEEK_CUR);
+          }
+          break;
+       case WPG_TEXT:
+         {
+           guint16 len;
+           WPGPoint pos;
+           gchar *text;
+
+           fread(&len, sizeof(guint16), 1, f);
+           fread(&pos, sizeof(WPGPoint), 1, f);
+           text = g_alloca (len+1);
+           fread(text, 1, len, f);
+           text[len] = 0;
+           if (len > 0)
+             _render_text (ren, &pos, text);
+         }
+         break;
+       case WPG_TEXTSTYLE:
+         {
+           WPGTextStyle ts;
+           fread(&ts, sizeof(WPGTextStyle), 1, f);
+           _do_textstyle (ren, &ts);
+         }
+         break;
+        default:
+          fseek(f, iSize, SEEK_CUR);
+          dia_context_add_message (ctx, _("Unknown WPG type %d size %d."),
+                                  (int)rh.Type, iSize);
+        } /* switch */
+      } else { /* if iSize */
+        if (WPG_END != rh.Type) {
+          dia_context_add_message (ctx, _("Size 0 on WPG type %d, expecting WPG_END\n"),
+                                  (int)rh.Type);
+         bRet = FALSE;
+       }
+      }
+    }
+    while ((iSize > 0) && (bRet));
+
+    if (!bRet)
+      dia_context_add_message (ctx, _("Unexpected end of file. WPG type %d, size %d.\n"),
+                              rh.Type, iSize);
+    if (ren->pPal) 
+      g_free(ren->pPal);
+    /* transfer to diagram data */
+    {
+      DiaObject *objs = dia_import_renderer_get_objects (DIA_RENDERER(ren));
+      if (objs) {
+       layer_add_object (dia->active_layer, objs);
+      } else {
+       dia_context_add_message (ctx, _("Empty WPG file?"));
+       bRet = FALSE;
+      }
+    }
+    g_object_unref (ren);
+  } /* bRet */
+
+  if (f)
+    fclose(f);
+  return bRet;
+}
diff --git a/plug-ins/wpg/wpg.c b/plug-ins/wpg/wpg.c
index b39dced..6274521 100644
--- a/plug-ins/wpg/wpg.c
+++ b/plug-ins/wpg/wpg.c
@@ -2,8 +2,7 @@
  * Copyright (C) 1998 Alexander Larsson
  *
  * wpg.c -- WordPerfect Graphics export plugin for dia
- * Copyright (C) 2000, Hans Breuer, <Hans Breuer Org>
- *   based on dummy.c 
+ * Copyright (C) 2000, 2014  Hans Breuer <Hans Breuer Org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,12 +24,6 @@
  * - if helper points - like arc centers - are not in Dia's extent box
  *   their clipping produces unpredictable results 
  * - the font setting needs improvement (maybe on Dia's side)
- * - bezier curves are not correctly converted to WPG's poly curve
- *   (two point beziers are)
- *
- * MayBe:
- * - full featured import (IMO Dia's import support should be improved
- *   before / on the way ...)
  */
 
 #include <config.h>
@@ -63,14 +56,6 @@
 
 /* #define DEBUG_WPG */
 
-/* Import is not yet finished but only implemented to check the
- * export capabilities and to investigate other programs WPG
- * formats. 
- * The following is not the reason for <en/dis>abling import, 
- * but it should do it for now ...
- */
-#define WPG_WITH_IMPORT defined (_MSC_VER)
-
 /*
  * helper macros
  */
@@ -108,7 +93,6 @@ struct _WpgRenderer
   WPGLineAttr  LineAttr;
   WPGTextStyle TextStyle;
 
-  WPGColorRGB* pPal;
 
   DiaContext* ctx;
 };
@@ -120,12 +104,6 @@ struct _WpgRendererClass
 
 G_END_DECLS
 
-#ifdef DEBUG_WPG
-#  define DIAG_NOTE(action) action
-#else
-#  define DIAG_NOTE(action)
-#endif
-
 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
 /* shortcut if testing of indirection isn't needed anymore */
 #define fwrite_le(a,b,c,d) fwrite(a,b,c,d)
@@ -253,6 +231,15 @@ WriteFillAttr(WpgRenderer *renderer, Color* colour, gboolean bFill)
   WriteRecHead(renderer, WPG_FILLATTR, sizeof(WPGFillAttr));
   if (bFill)
   {
+    int v = (int)(colour->alpha * 9);
+    /*
+     * Map transparency to fill style
+     *   0 Hollow
+     *   1 Solid
+     *  11 Dots density 1 (least dense)
+     *  16 Dots density 7 (densest)
+     */
+    renderer->FillAttr.Type = v > 8 ? 1 : v < 1 ? 0 : (10 + v);
     renderer->FillAttr.Color = LookupColor(renderer, colour);
     fwrite(&renderer->FillAttr, sizeof(WPGFillAttr), 1, renderer->file);
   }
@@ -668,7 +655,6 @@ fill_arc(DiaRenderer *self,
   ell.EndAngle   = angle2;
   ell.Flags = 0; /* 0: connect to center; 1: connect start and end */
 
-  WriteLineAttr(renderer, colour);
   WriteFillAttr(renderer, colour, TRUE);
   WriteRecHead(renderer, WPG_ELLIPSE, sizeof(WPGEllipse));
 
@@ -722,7 +708,6 @@ fill_ellipse(DiaRenderer *self,
   WriteFillAttr(renderer, colour, FALSE);
 }
 
-#ifdef USE_OUR_DRAW_BEZIER
 static void
 draw_bezier(DiaRenderer *self, 
             BezPoint *points,
@@ -730,83 +715,75 @@ draw_bezier(DiaRenderer *self,
             Color *colour)
 {
   WpgRenderer *renderer = WPG_RENDERER (self);
-  gint16* pData;
+  WPGPoint* pts;
+  guint16 data[2];
   int i;
 
   DIAG_NOTE(g_message("draw_bezier n:%d %fx%f ...", 
             numpoints, points->p1.x, points->p1.y));
 
   WriteLineAttr(renderer, colour);
-  WriteRecHead(renderer, WPG_POLYCURVE, (numpoints * 2) * 2 * sizeof(gint16) + 3 * sizeof(gint16));
+  WriteRecHead(renderer, WPG_POLYCURVE, (3 * numpoints - 2) * sizeof(WPGPoint) + 3 * sizeof(guint16));
 
-  pData = g_new(gint16, numpoints * 6);
-
-  /* ??? size of equivalent data in pre5.1 files ? */
-#if 1
-  memset(pData, 0, sizeof(gint16)*2);
-#else
-  /* try first point instead */
-  pData[0] = SCX(points[0].p1.x);
-  pData[1] = SCY(-points[0].p1.y);
-#endif
-  fwrite_le(pData, sizeof(gint16), 2, renderer->file);
+  pts = g_new(WPGPoint, 3 * numpoints - 2);
 
-  pData[0] = numpoints * 2;
-  fwrite_le(pData, sizeof(gint16), 1, renderer->file);
+  /* ??? size of equivalent data in pre5.1 files ? DWORD */
+  memset (data, 0, sizeof(guint16) * 2);
+  fwrite_le(data, sizeof(guint16), 2, renderer->file);
+  /* num points */
+  data[0] = 3 * numpoints - 2;
+  fwrite_le(data, sizeof(guint16), 1, renderer->file);
 
-  /* WPG's Poly Curve is not quite the same as DIA's Bezier.
-   * There is only one Control Point per Point and I can't 
-   * get it right, but at least they are read without error.
+  /* WPG's Poly Curve is a cubic bezier compatible with Dia's bezier.
+   * http://www.fileformat.info/format/wpg/egff.htm
+   * could lead to the assumption of ony quadratic bezier support,
+   * but that's not the case.
    */
-  for (i = 0; i < numpoints; i++)
+  pts[0].x = SCX( points[0].p1.x);
+  pts[0].y = SCY(-points[0].p1.y);
+  for (i = 1; i < numpoints; i++)
   {
     switch (points[i].type)
     {
     case BEZ_MOVE_TO:
     case BEZ_LINE_TO:
-      /* real point */
-      pData[4*i  ] = SCX( points[i].p1.x);
-      pData[4*i+1] = SCY(-points[i].p1.y);
-
-      /* control point (1st from next point) */
-      if (i+1 < numpoints) {
-        pData[4*i+2] = SCX( points[i+1].p1.x);
-        pData[4*i+3] = SCY(-points[i+1].p1.y);
-      }
-      else {
-        pData[4*i+2] = SCX( points[i].p1.x);
-        pData[4*i+3] = SCY(-points[i].p1.y);
-      }
+      /* just the point */
+      pts[i*3-2].x = pts[i*3-1].x = pts[i*3].x = SCX( points[i].p1.x);
+      pts[i*3-2].y = pts[i*3-1].y = pts[i*3].y = SCY(-points[i].p1.y);
       break;
     case BEZ_CURVE_TO:
-      if (0 && (i+1 < numpoints)) {
-        /* real point ?? */
-        pData[4*i  ] = SCX( points[i].p3.x);
-        pData[4*i+1] = SCY(-points[i].p3.y);
-        /* control point (1st from next point) */
-        pData[4*i+2] = SCX( points[i+1].p1.x);
-        pData[4*i+3] = SCY(-points[i+1].p1.y);
-      }
-      else {
-        /* need to swap these ?? */
-        /* real point ?? */
-        pData[4*i  ] = SCX( points[i].p2.x);
-        pData[4*i+1] = SCY(-points[i].p2.y);
-
-        /* control point ?? */
-        pData[4*i+2] = SCX( points[i].p3.x);
-        pData[4*i+3] = SCY(-points[i].p3.y);
-      }
+      /* first control point */
+      pts[i*3-2].x = SCX( points[i].p1.x);
+      pts[i*3-2].y = SCY(-points[i].p1.y);
+      /* second control point */
+      pts[i*3-1].x = SCX( points[i].p2.x);
+      pts[i*3-1].y = SCY(-points[i].p2.y);
+      /* this segments end point */
+      pts[i*3].x = SCX( points[i].p3.x);
+      pts[i*3].y = SCY(-points[i].p3.y);
       break;
     }
   }
 
-  fwrite_le(pData, sizeof(gint16), numpoints*4, renderer->file);
-  g_free(pData);
+  fwrite_le(pts, sizeof(gint16), 2*(numpoints*3-2), renderer->file);
+  g_free(pts);
 }
-#endif /* USE_OUR_DRAW_BEZIER */
 
 static void
+fill_bezier(DiaRenderer *self, 
+            BezPoint *points,
+            int numpoints,
+            Color *colour)
+{
+  WpgRenderer *renderer = WPG_RENDERER (self);
+
+  DIAG_NOTE(g_message("fill_beziez %d points", numpoints));
+
+  WriteFillAttr(renderer, colour, TRUE);
+  draw_bezier (self, points, numpoints, colour);
+  WriteFillAttr(renderer, colour, FALSE);
+}
+static void
 draw_string(DiaRenderer *self,
             const char *text,
             Point *pos, Alignment alignment,
@@ -882,9 +859,9 @@ draw_image(DiaRenderer *self,
 
   bmp.Angle  = 0;
   bmp.Left   = SCX(point->x);
-  bmp.Top    = SCY(-point->y - height);
+  bmp.Top    = SCY(-point->y);
   bmp.Right  = SCX(point->x + width);
-  bmp.Bottom = SCY(-point->y);
+  bmp.Bottom = SCY(-point->y - height);
 
   bmp.Width  = dia_image_width(image);
   bmp.Height = dia_image_height(image);
@@ -907,8 +884,8 @@ draw_image(DiaRenderer *self,
 
   for (y = 0; y < bmp.Height; y++)
   {
-    /* starting from last line but left to right */
-    pIn = pDiaImg + stride * (bmp.Height - 1 - y);
+    /* from top to bottom line */
+    pIn = pDiaImg + stride * y;
     cnt = 0; /* reset with every line */
     for (x = 0; x < bmp.Width; x ++)
     {
@@ -1061,13 +1038,13 @@ wpg_renderer_class_init (WpgRendererClass *klass)
   renderer_class->draw_polyline  = draw_polyline;
   renderer_class->draw_polygon   = draw_polygon;
 
-#ifdef USE_OUR_DRAW_BEZIER
-  /* The bezier implementation above does not match, use base class approximation */
   renderer_class->draw_bezier   = draw_bezier;
-#endif
-  /* Implemented by base class approximation
+#if 0 /* FIXME: use fallback from base class until another
+       * program can actually correctly show the filled Polycurve
+       * created by Dia (our own import can).
+       */
   renderer_class->fill_bezier   = fill_bezier;
-   */
+#endif
 }
 
 /* dia export funtion */
@@ -1111,14 +1088,14 @@ export_data(DiagramData *data, DiaContext *ctx,
     while (renderer->Scale * height < 3276.7) renderer->Scale *= 10.0;
 #else
   /* scale from Dia's cm to WPU (1/1200 inch) */
-  renderer->Scale = 1200.0 / 2.54;
+  renderer->Scale = WPU_PER_DCM;
   /* avoid int16 overflow */
   if (width > height)
     while (renderer->Scale * width > 32767) renderer->Scale /= 10.0;
   else
     while (renderer->Scale * height > 32767) renderer->Scale /= 10.0;
   renderer->XOffset = - extent->left;
-  renderer->YOffset = - extent->top;
+  renderer->YOffset =   extent->bottom;
 #endif
   renderer->Box.Width  = width * renderer->Scale;
   renderer->Box.Height = height * renderer->Scale;
@@ -1132,205 +1109,7 @@ export_data(DiagramData *data, DiaContext *ctx,
   return TRUE;
 }
 
-#if WPG_WITH_IMPORT
-/*
- * Import (under construction)
- */
-static void
-import_object(DiaRenderer* self, DiagramData *dia,
-              WPG_Type type, int iSize, guchar* pData)
-{
-  WpgRenderer *renderer = WPG_RENDERER(self);
-  WPGPoint* pts = NULL;
-  gint16* pInt16 = NULL;
-  int    iNum = 0;
-  gint32 iPre51 = 0;
-
-  switch (type) {
-  case WPG_LINE:
-    iNum = 2;
-    pts = (WPGPoint*)pData;
-    break;
-  case WPG_POLYLINE:
-    pInt16 = (gint16*)pData;
-    iNum = pInt16[0];
-    pts = (WPGPoint*)(pData + sizeof(gint16));
-    break;
-  case WPG_RECTANGLE:
-    iNum = 2;
-    pts = (WPGPoint*)pData;
-    break;
-  case WPG_POLYGON:
-    pInt16 = (gint16*)pData;
-    iNum = pInt16[0];
-    pts = (WPGPoint*)(pData + sizeof(gint16));
-    break;
-  case WPG_ELLIPSE:
-    {
-      WPGEllipse* pEll;
-      pEll = (WPGEllipse*)pData;
-    }
-    break;
-  case WPG_POLYCURVE:
-    iPre51 = *((gint32*)pData);
-    pInt16 = (gint16*)pData;
-    iNum = pInt16[2];
-    pts = (WPGPoint*)(pData + 3*sizeof(gint16));
-    DIAG_NOTE(g_message("POLYCURVE Num pts %d Pre51 %d", iNum, iPre51));
-    break;
-  } /* switch */
-  DIAG_NOTE(g_message("Type %d Num pts %d Size %d", type, iNum, iSize));
-} 
-
-static gboolean
-import_data (const gchar *filename, DiagramData *dia, DiaContext *ctx, void* user_data)
-{
-  FILE* f;
-  gboolean bRet;
-  WPGHead8 rh;
 
-  f = g_fopen(filename, "rb");
-
-  if (NULL == f) {
-    dia_context_add_message(ctx, _("Couldn't open: '%s' for reading.\n"), filename);
-    bRet = FALSE;
-  }
-  
-  /* check header */
-  if (bRet) {
-    WPGFileHead fhead;
-    bRet = ( (1 == fread(&fhead, sizeof(WPGFileHead), 1, f))
-            && fhead.fid[0] == 255 && fhead.fid[1] == 'W'
-            && fhead.fid[2] == 'P' && fhead.fid[3] == 'C'
-            && (1 == fhead.MajorVersion) && (0 == fhead.MinorVersion));
-    if (!bRet)
-      dia_context_add_message(ctx, _("File: %s type/version unsupported.\n"), filename);
-  }
-
-  if (bRet) {
-    int iSize;
-    gint16 i16, iNum16;
-    guint8 i8;
-    WpgRenderer *ren = g_object_new (WPG_TYPE_RENDERER, NULL);
-
-    ren->pPal = g_new0(WPGColorRGB, 256);
-
-    DIAG_NOTE(g_message("Parsing: %s ", filename));
-
-    do {
-      if (1 == fread(&rh, sizeof(WPGHead8), 1, f)) {
-        if (rh.Size < 0xFF)
-          iSize = rh.Size;
-        else {
-          bRet = (1 == fread(&i16, sizeof(guint16), 1, f));
-          if (0x8000 & i16) {
-            DIAG_NOTE(g_print("Large Object: hi:lo %04X", (int)i16));
-            iSize = i16 << 16;
-            /* Reading large objects involves major uglyness. Instead of getting 
-             * one size, as implied by "Encyclopedia of Graphics File Formats",
-             * it would require putting together small chunks of data to one large 
-             * object. The criteria when to stop isn't absolutely clear.
-             */
-            iSize = 0;
-            bRet = (1 == fread(&i16, sizeof(guint16), 1, f));
-            DIAG_NOTE(g_print("Large Object: %d\n", (int)i16));
-            iSize += i16;
-#if 1
-            /* Ignore this large objec part */
-            fseek(f, iSize, SEEK_CUR);
-            continue;
-#endif
-          }
-          else
-            iSize = i16; 
-        }
-      } else
-        iSize = 0;
-
-      /* DIAG_NOTE(g_message("Type %d Size %d", rh.Type, iSize)); */
-      if (iSize > 0) {
-        switch (rh.Type) {
-        case WPG_FILLATTR:
-          bRet = (1 == fread(&ren->FillAttr, sizeof(WPGFillAttr), 1, f));
-          break;
-        case WPG_LINEATTR:
-          bRet = (1 == fread(&ren->LineAttr, sizeof(WPGLineAttr), 1, f));
-          break;
-        case WPG_START:
-          bRet = (1 == fread(&ren->Box, sizeof(WPGStartData), 1, f));
-          break;
-        case WPG_STARTWPG2:
-          /* not sure if this is the right thing to do */
-          bRet &= (1 == fread(&i8, sizeof(gint8), 1, f));
-          bRet &= (1 == fread(&i16, sizeof(gint16), 1, f));
-          DIAG_NOTE(g_message("Ignoring tag WPG_STARTWPG2, Size %d\n Type? %d Size? %d", 
-                    iSize, (int)i8, i16));
-          fseek(f, iSize - 3, SEEK_CUR);
-          break;
-        case WPG_LINE:
-        case WPG_POLYLINE:
-        case WPG_RECTANGLE:
-        case WPG_POLYGON:
-        case WPG_POLYCURVE:
-        case WPG_ELLIPSE:
-          {
-            guchar* pData;
-
-            pData = g_new(guchar, iSize);
-            bRet = (iSize == (int)fread(pData, 1, iSize, f));
-            import_object(DIA_RENDERER(ren), dia, rh.Type, iSize, pData);
-            g_free(pData);
-          }
-          break;
-        case WPG_COLORMAP:
-          bRet &= (1 == fread(&i16, sizeof(gint16), 1, f));
-          bRet &= (1 == fread(&iNum16, sizeof(gint16), 1, f));
-          if (iNum16 != (gint16)((iSize - 2) / sizeof(WPGColorRGB)))
-            g_warning("WpgImporter : colormap size/header mismatch.");
-          if (i16 >= 0 && i16 <= iSize) {
-            bRet &= (iNum16 == (int)fread(&ren->pPal[i16], sizeof(WPGColorRGB), iNum16, f));
-          }
-          else {
-            g_warning("WpgImporter : start color map index out of range.");
-            bRet &= (iNum16 == (int)fread(ren->pPal, sizeof(WPGColorRGB), iNum16, f));
-          }
-          break;
-        case WPG_BITMAP2:
-          {
-            WPGBitmap2 bmp;
-
-            fread(&bmp, sizeof(WPGBitmap2), 1, f);
-            DIAG_NOTE(g_message("Bitmap %dx%d %d bits @%d,%d %d,%d.", 
-                      bmp.Width, bmp.Height, bmp.Depth, 
-                      bmp.Left, bmp.Top, bmp.Right, bmp.Bottom));
-            fseek(f, iSize - sizeof(WPGBitmap2), SEEK_CUR);
-          }
-          break;
-        default:
-          fseek(f, iSize, SEEK_CUR);
-          g_warning ("Unknown Type %d Size %d.", (int)rh.Type, iSize);
-        } /* switch */
-      } /* if iSize */
-      else {
-        if (WPG_END != rh.Type)
-          g_warning("Size 0 on Type %d, expecting WPG_END\n", (int)rh.Type);
-      }
-    }
-    while ((iSize > 0) && (bRet));
-
-    if (!bRet)
-      g_warning("WpgImporter : unexpected eof. Type %d, Size %d.\n",
-                rh.Type, iSize);
-    if (ren->pPal) 
-      g_free(ren->pPal);
-    g_object_unref (ren);
-  } /* bRet */
-
-  if (f) fclose(f);
-  return bRet;
-}
-
-#endif /* WPG_WITH_IMPORT */
 
 static const gchar *extensions[] = { "wpg", NULL };
 static DiaExportFilter my_export_filter = {
@@ -1339,13 +1118,11 @@ static DiaExportFilter my_export_filter = {
     export_data
 };
 
-#if WPG_WITH_IMPORT
 DiaImportFilter my_import_filter = {
     N_("WPG"),
     extensions,
     import_data
 };
-#endif /* WPG_WITH_IMPORT */
 
 /* --- dia plug-in interface --- */
 static gboolean
@@ -1358,9 +1135,7 @@ static void
 _plugin_unload (PluginInfo *info)
 {
   filter_unregister_export(&my_export_filter);
-#if WPG_WITH_IMPORT
   filter_unregister_import(&my_import_filter);
-#endif
 }
 
 DIA_PLUGIN_CHECK_INIT
@@ -1375,9 +1150,7 @@ dia_plugin_init(PluginInfo *info)
     return DIA_PLUGIN_INIT_ERROR;
 
   filter_register_export(&my_export_filter);
-#if WPG_WITH_IMPORT
   filter_register_import(&my_import_filter);
-#endif
 
   return DIA_PLUGIN_INIT_OK;
 }
diff --git a/plug-ins/wpg/wpg_defs.h b/plug-ins/wpg/wpg_defs.h
index bab6146..406aaea 100644
--- a/plug-ins/wpg/wpg_defs.h
+++ b/plug-ins/wpg/wpg_defs.h
@@ -6,6 +6,16 @@
  *
  * Translated to "C" by Hans Breuer <Hans Breuer Org>
  */
+#define WPU_PER_DCM (1200.0 / 2.54)
+
+#ifdef DEBUG_WPG
+#  define DIAG_NOTE(action) action
+#else
+#  define DIAG_NOTE(action)
+#endif
+
+gboolean import_data (const gchar *filename, DiagramData *dia,
+                     DiaContext *ctx, void* user_data);
 
 typedef struct
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]