summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 02493e1)
raw | patch | inline | side by side (parent: 02493e1)
author | joncruz <joncruz@users.sourceforge.net> | |
Mon, 19 Feb 2007 20:48:09 +0000 (20:48 +0000) | ||
committer | joncruz <joncruz@users.sourceforge.net> | |
Mon, 19 Feb 2007 20:48:09 +0000 (20:48 +0000) |
35 files changed:
index 2f986f16f748e35c83c125db224fd789be07b0c2..9dfbed9255b9089dfede98270c5e86e0e3b1c454 100644 (file)
-#define SP_CANVAS_AXONOMGRID_C\r
-\r
-/*\r
- * SPCAxonomGrid\r
- *\r
- * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>\r
- * Copyright (C) 2000 Lauris Kaplinski\r
- *\r
- */ \r
- \r
- /* \r
- * Current limits are: one axis (y-axis) is always vertical. The other two\r
- * axes are bound to a certain range of angles. The z-axis always has an angle \r
- * smaller than 90 degrees (measured from horizontal, 0 degrees being a line extending\r
- * to the right). The x-axis will always have an angle between 0 and 90 degrees.\r
- * When I quickly think about it: all possibilities are probably covered this way. Eg.\r
- * a z-axis with negative angle can be replaced with an x-axis, etc.\r
- */ \r
- \r
- /*\r
- * TODO: LOTS LOTS LOTS. Optimization etc.\r
- *\r
- */\r
-\r
-#include "sp-canvas-util.h"\r
-#include "canvas-axonomgrid.h"\r
-#include "display-forward.h"\r
-#include <libnr/nr-pixops.h>\r
-\r
-#define SAFE_SETPIXEL //undefine this when it is certain that setpixel is never called with invalid params\r
-\r
-enum {\r
- ARG_0,\r
- ARG_ORIGINX,\r
- ARG_ORIGINY,\r
- ARG_ANGLEX,\r
- ARG_SPACINGY,\r
- ARG_ANGLEZ,\r
- ARG_COLOR,\r
- ARG_EMPCOLOR,\r
- ARG_EMPSPACING\r
-};\r
-\r
-enum Dim3 { X=0, Y, Z };\r
-\r
-#ifndef M_PI\r
-#define M_PI 3.14159265358979323846\r
-#endif\r
-\r
-static double deg_to_rad(double deg) { return deg*M_PI/180.0;}\r
-\r
-\r
-static void sp_caxonomgrid_class_init (SPCAxonomGridClass *klass);\r
-static void sp_caxonomgrid_init (SPCAxonomGrid *grid);\r
-static void sp_caxonomgrid_destroy (GtkObject *object);\r
-static void sp_caxonomgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);\r
-\r
-static void sp_caxonomgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);\r
-static void sp_caxonomgrid_render (SPCanvasItem *item, SPCanvasBuf *buf);\r
-\r
-static SPCanvasItemClass * parent_class;\r
-\r
-GtkType\r
-sp_caxonomgrid_get_type (void)\r
-{\r
- static GtkType caxonomgrid_type = 0;\r
-\r
- if (!caxonomgrid_type) {\r
- GtkTypeInfo caxonomgrid_info = {\r
- "SPCAxonomGrid",\r
- sizeof (SPCAxonomGrid),\r
- sizeof (SPCAxonomGridClass),\r
- (GtkClassInitFunc) sp_caxonomgrid_class_init,\r
- (GtkObjectInitFunc) sp_caxonomgrid_init,\r
- NULL, NULL,\r
- (GtkClassInitFunc) NULL\r
- };\r
- caxonomgrid_type = gtk_type_unique (sp_canvas_item_get_type (), &caxonomgrid_info);\r
- }\r
- return caxonomgrid_type;\r
-}\r
-\r
-static void\r
-sp_caxonomgrid_class_init (SPCAxonomGridClass *klass)\r
-{\r
-\r
- GtkObjectClass *object_class;\r
- SPCanvasItemClass *item_class;\r
-\r
- object_class = (GtkObjectClass *) klass;\r
- item_class = (SPCanvasItemClass *) klass;\r
-\r
- parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ());\r
-\r
- gtk_object_add_arg_type ("SPCAxonomGrid::originx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINX);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::originy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINY);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::anglex", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ANGLEX);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::spacingy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGY);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::anglez", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ANGLEZ);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::color", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_COLOR);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::empcolor", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPCOLOR);\r
- gtk_object_add_arg_type ("SPCAxonomGrid::empspacing", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPSPACING);\r
-\r
- object_class->destroy = sp_caxonomgrid_destroy;\r
- object_class->set_arg = sp_caxonomgrid_set_arg;\r
-\r
- item_class->update = sp_caxonomgrid_update;\r
- item_class->render = sp_caxonomgrid_render;\r
- \r
-}\r
-\r
-static void\r
-sp_caxonomgrid_init (SPCAxonomGrid *grid)\r
-{\r
- grid->origin[NR::X] = grid->origin[NR::Y] = 0.0;\r
-// grid->spacing[X] = grid->spacing[Y] = grid->spacing[Z] = 8.0;\r
- grid->color = 0x0000ff7f;\r
- grid->empcolor = 0x3F3FFF40;\r
- grid->empspacing = 5;\r
-}\r
-\r
-static void\r
-sp_caxonomgrid_destroy (GtkObject *object)\r
-{\r
- g_return_if_fail (object != NULL);\r
- g_return_if_fail (SP_IS_CAXONOMGRID (object));\r
-\r
- if (GTK_OBJECT_CLASS (parent_class)->destroy)\r
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);\r
-}\r
-\r
-static void\r
-sp_caxonomgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)\r
-{\r
- SPCanvasItem *item = SP_CANVAS_ITEM (object);\r
- SPCAxonomGrid *grid = SP_CAXONOMGRID (object);\r
- \r
- switch (arg_id) {\r
- case ARG_ORIGINX:\r
- grid->origin[NR::X] = GTK_VALUE_DOUBLE (* arg);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_ORIGINY:\r
- grid->origin[NR::Y] = GTK_VALUE_DOUBLE (* arg);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_ANGLEX:\r
- grid->angle_deg[X] = GTK_VALUE_DOUBLE (* arg);\r
- if (grid->angle_deg[X] < 0.0) grid->angle_deg[X] = 0.0;\r
- if (grid->angle_deg[X] > 89.0) grid->angle_deg[X] = 89.0;\r
- grid->angle_rad[X] = deg_to_rad(grid->angle_deg[X]);\r
- grid->tan_angle[X] = tan(grid->angle_rad[X]);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_SPACINGY:\r
- grid->lengthy = GTK_VALUE_DOUBLE (* arg);\r
- if (grid->lengthy < 0.01) grid->lengthy = 0.01;\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_ANGLEZ:\r
- grid->angle_deg[Z] = GTK_VALUE_DOUBLE (* arg);\r
- if (grid->angle_deg[Z] < 0.0) grid->angle_deg[Z] = 0.0;\r
- if (grid->angle_deg[X] > 89.0) grid->angle_deg[X] = 89.0;\r
- grid->angle_rad[Z] = deg_to_rad(grid->angle_deg[Z]);\r
- grid->tan_angle[Z] = tan(grid->angle_rad[Z]);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_COLOR:\r
- grid->color = GTK_VALUE_INT (* arg);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_EMPCOLOR:\r
- grid->empcolor = GTK_VALUE_INT (* arg);\r
- sp_canvas_item_request_update (item);\r
- break;\r
- case ARG_EMPSPACING:\r
- grid->empspacing = GTK_VALUE_INT (* arg);\r
- // std::cout << "Emphasis Spacing: " << grid->empspacing << std::endl;\r
- sp_canvas_item_request_update (item);\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-\r
-\r
-/**\r
- \brief This function renders a pixel on a particular buffer.\r
- \r
- The topleft of the buffer equals\r
- ( rect.x0 , rect.y0 ) in screen coordinates\r
- ( 0 , 0 ) in setpixel coordinates\r
- The bottomright of the buffer equals\r
- ( rect.x1 , rect,y1 ) in screen coordinates\r
- ( rect.x1 - rect.x0 , rect.y1 - rect.y0 ) in setpixel coordinates\r
-*/\r
-static void \r
-sp_caxonomgrid_setpixel (SPCanvasBuf *buf, gint x, gint y, guint32 rgba) {\r
-#ifdef SAFE_SETPIXEL\r
- if ( (x >= buf->rect.x0) && (x < buf->rect.x1) && (y >= buf->rect.y0) && (y < buf->rect.y1) ) {\r
-#endif \r
- guint r, g, b, a; \r
- r = NR_RGBA32_R (rgba);\r
- g = NR_RGBA32_G (rgba);\r
- b = NR_RGBA32_B (rgba);\r
- a = NR_RGBA32_A (rgba); \r
- guchar * p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;\r
- p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);\r
- p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);\r
- p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);\r
-#ifdef SAFE_SETPIXEL\r
- }\r
-#endif \r
-}\r
-\r
-/**\r
- \brief This function renders a line on a particular canvas buffer,\r
- using Bresenham's line drawing function.\r
- http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html \r
- Coordinates are interpreted as SCREENcoordinates\r
-*/\r
-static void \r
-sp_caxonomgrid_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba) {\r
- int dy = y1 - y0;\r
- int dx = x1 - x0;\r
- int stepx, stepy;\r
-\r
- if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }\r
- if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }\r
- dy <<= 1; // dy is now 2*dy\r
- dx <<= 1; // dx is now 2*dx\r
-\r
- sp_caxonomgrid_setpixel(buf, x0, y0, rgba);\r
- if (dx > dy) {\r
- int fraction = dy - (dx >> 1); // same as 2*dy - dx\r
- while (x0 != x1) {\r
- if (fraction >= 0) {\r
- y0 += stepy;\r
- fraction -= dx; // same as fraction -= 2*dx\r
- }\r
- x0 += stepx;\r
- fraction += dy; // same as fraction -= 2*dy\r
- sp_caxonomgrid_setpixel(buf, x0, y0, rgba);\r
- }\r
- } else {\r
- int fraction = dx - (dy >> 1);\r
- while (y0 != y1) {\r
- if (fraction >= 0) {\r
- x0 += stepx;\r
- fraction -= dy;\r
- }\r
- y0 += stepy;\r
- fraction += dx;\r
- sp_caxonomgrid_setpixel(buf, x0, y0, rgba);\r
- }\r
- }\r
- \r
-}\r
-\r
-static void\r
-sp_grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba)\r
-{\r
- if ((x >= buf->rect.x0) && (x < buf->rect.x1)) {\r
- guint r, g, b, a;\r
- gint y0, y1, y;\r
- guchar *p;\r
- r = NR_RGBA32_R(rgba);\r
- g = NR_RGBA32_G (rgba);\r
- b = NR_RGBA32_B (rgba);\r
- a = NR_RGBA32_A (rgba);\r
- y0 = MAX (buf->rect.y0, ys);\r
- y1 = MIN (buf->rect.y1, ye + 1);\r
- p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;\r
- for (y = y0; y < y1; y++) {\r
- p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);\r
- p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);\r
- p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);\r
- p += buf->buf_rowstride;\r
- }\r
- }\r
-}\r
-\r
-/**\r
- \brief This function renders the grid on a particular canvas buffer\r
- \param item The grid to render on the buffer\r
- \param buf The buffer to render the grid on\r
- \r
- This function gets called a touch more than you might believe,\r
- about once per tile. This means that it could probably be optimized\r
- and help things out.\r
-\r
- Basically this function has to determine where in the canvas it is,\r
- and how that associates with the grid. It does this first by looking\r
- at the bounding box of the buffer, and then calculates where the grid\r
- starts in that buffer. It will then step through grid lines until\r
- it is outside of the buffer.\r
-\r
- For each grid line it is drawn using the function \c sp_grid_hline\r
- or \c sp_grid_vline. These are convience functions for the sake\r
- of making the function easier to read.\r
-\r
- Also, there are emphasized lines on the grid. While the \c syg and\r
- \c sxg variable track grid positioning, the \c xlinestart and \c\r
- ylinestart variables track the 'count' of what lines they are. If\r
- that count is a multiple of the line seperation between emphasis\r
- lines, then that line is drawn in the emphasis color.\r
-*/\r
-static void\r
-sp_caxonomgrid_render (SPCanvasItem * item, SPCanvasBuf * buf)\r
-{\r
- SPCAxonomGrid *grid = SP_CAXONOMGRID (item);\r
-\r
- sp_canvas_prepare_buffer (buf);\r
- \r
- // gc = gridcoordinates (the coordinates calculated from the grids origin 'grid->ow'.\r
- // sc = screencoordinates ( for example "buf->rect.x0" is in screencoordinates )\r
- // bc = buffer patch coordinates \r
- \r
- // tl = topleft ; br = bottomright\r
- NR::Point buf_tl_gc;\r
- NR::Point buf_br_gc;\r
- buf_tl_gc[NR::X] = buf->rect.x0 - grid->ow[NR::X];\r
- buf_tl_gc[NR::Y] = buf->rect.y0 - grid->ow[NR::Y];\r
- buf_br_gc[NR::X] = buf->rect.x1 - grid->ow[NR::X];\r
- buf_br_gc[NR::Y] = buf->rect.y1 - grid->ow[NR::Y];\r
-\r
-\r
- gdouble x;\r
- gdouble y;\r
-\r
- // render the three separate line groups representing the main-axes:\r
- // x-axis always goes from topleft to bottomright. (0,0) - (1,1) \r
- const gdouble xintercept_y_bc = (buf_tl_gc[NR::X] * grid->tan_angle[X]) - buf_tl_gc[NR::Y] ;\r
- const gdouble xstart_y_sc = ( xintercept_y_bc - floor(xintercept_y_bc/grid->lyw)*grid->lyw ) + buf->rect.y0;\r
- const gint xlinestart = (gint) Inkscape::round( (xstart_y_sc - grid->ow[NR::Y]) / grid->lyw );\r
- gint xlinenum;\r
- // lijnen vanaf linker zijkant.\r
- for (y = xstart_y_sc, xlinenum = xlinestart; y < buf->rect.y1; y += grid->lyw, xlinenum++) {\r
- const gint x0 = buf->rect.x0;\r
- const gint y0 = (gint) Inkscape::round(y);\r
- const gint x1 = x0 + (gint) Inkscape::round( (buf->rect.y1 - y) / grid->tan_angle[X] );\r
- const gint y1 = buf->rect.y1;\r
- \r
- if (!grid->scaled && (xlinenum % grid->empspacing) == 0) {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);\r
- } else {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);\r
- }\r
- }\r
- // lijnen vanaf bovenkant.\r
- const gdouble xstart_x_sc = buf->rect.x0 + (grid->lxw_x - (xstart_y_sc - buf->rect.y0) / grid->tan_angle[X]) ;\r
- for (x = xstart_x_sc, xlinenum = xlinestart; x < buf->rect.x1; x += grid->lxw_x, xlinenum--) {\r
- const gint y0 = buf->rect.y0;\r
- const gint y1 = buf->rect.y1;\r
- const gint x0 = (gint) Inkscape::round(x);\r
- const gint x1 = x0 + (gint) Inkscape::round( (y1 - y0) / grid->tan_angle[X] );\r
- \r
- if (!grid->scaled && (xlinenum % grid->empspacing) == 0) {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);\r
- } else {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);\r
- }\r
- }\r
- \r
-\r
- // y-axis lines (vertical)\r
- const gdouble ystart_x_sc = floor (buf_tl_gc[NR::X] / grid->spacing_ylines) * grid->spacing_ylines + grid->ow[NR::X];\r
- const gint ylinestart = (gint) Inkscape::round((ystart_x_sc - grid->ow[NR::X]) / grid->spacing_ylines);\r
- gint ylinenum;\r
- for (x = ystart_x_sc, ylinenum = ylinestart; x < buf->rect.x1; x += grid->spacing_ylines, ylinenum++) {\r
- const gint x0 = (gint) Inkscape::round(x);\r
-\r
- if (!grid->scaled && (ylinenum % grid->empspacing) == 0) {\r
- sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, grid->empcolor);\r
- } else {\r
- sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, grid->color);\r
- }\r
- }\r
-\r
- // z-axis always goes from bottomleft to topright. (0,1) - (1,0) \r
- const gdouble zintercept_y_bc = (buf_tl_gc[NR::X] * -grid->tan_angle[Z]) - buf_tl_gc[NR::Y] ;\r
- const gdouble zstart_y_sc = ( zintercept_y_bc - floor(zintercept_y_bc/grid->lyw)*grid->lyw ) + buf->rect.y0;\r
- const gint zlinestart = (gint) Inkscape::round( (zstart_y_sc - grid->ow[NR::Y]) / grid->lyw );\r
- gint zlinenum;\r
- // lijnen vanaf linker zijkant.\r
- for (y = zstart_y_sc, zlinenum = zlinestart; y < buf->rect.y1; y += grid->lyw, zlinenum++) {\r
- const gint x0 = buf->rect.x0;\r
- const gint y0 = (gint) Inkscape::round(y);\r
- const gint x1 = x0 + (gint) Inkscape::round( (y - buf->rect.y0 ) / grid->tan_angle[Z] );\r
- const gint y1 = buf->rect.y0;\r
- \r
- if (!grid->scaled && (zlinenum % grid->empspacing) == 0) {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);\r
- } else {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);\r
- }\r
- }\r
- // lijnen vanaf onderkant.\r
- const gdouble zstart_x_sc = buf->rect.x0 + (y - buf->rect.y1) / grid->tan_angle[Z] ;\r
- for (x = zstart_x_sc; x < buf->rect.x1; x += grid->lxw_z, zlinenum--) {\r
- const gint y0 = buf->rect.y1;\r
- const gint y1 = buf->rect.y0;\r
- const gint x0 = (gint) Inkscape::round(x);\r
- const gint x1 = x0 + (gint) Inkscape::round( (buf->rect.y1 - buf->rect.y0) / grid->tan_angle[Z] );\r
- \r
- if (!grid->scaled && (zlinenum % grid->empspacing) == 0) {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);\r
- } else {\r
- sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);\r
- }\r
- }\r
- \r
-}\r
-\r
-static void\r
-sp_caxonomgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)\r
-{\r
- SPCAxonomGrid *grid = SP_CAXONOMGRID (item);\r
-\r
- if (parent_class->update)\r
- (* parent_class->update) (item, affine, flags);\r
-\r
- grid->ow = grid->origin * affine;\r
- grid->sw = NR::Point(fabs(affine[0]),fabs(affine[3]));\r
- \r
- for(int dim = 0; dim < 2; dim++) {\r
- gint scaling_factor = grid->empspacing;\r
-\r
- if (scaling_factor <= 1)\r
- scaling_factor = 5;\r
-\r
- grid->scaled = FALSE;\r
- while (grid->sw[dim] < 8.0) {\r
- grid->scaled = TRUE;\r
- grid->sw[dim] *= scaling_factor;\r
- // First pass, go up to the major line spacing, then\r
- // keep increasing by two.\r
- scaling_factor = 2;\r
- }\r
- }\r
-\r
- grid->spacing_ylines = grid->sw[NR::X] * grid->lengthy /(grid->tan_angle[X] + grid->tan_angle[Z]);\r
- grid->lyw = grid->lengthy * grid->sw[NR::Y];\r
- grid->lxw_x = (grid->lengthy / grid->tan_angle[X]) * grid->sw[NR::X];\r
- grid->lxw_z = (grid->lengthy / grid->tan_angle[Z]) * grid->sw[NR::X];\r
-\r
- if (grid->empspacing == 0) {\r
- grid->scaled = TRUE;\r
- }\r
-\r
- sp_canvas_request_redraw (item->canvas,\r
- -1000000, -1000000,\r
- 1000000, 1000000);\r
- \r
- item->x1 = item->y1 = -1000000;\r
- item->x2 = item->y2 = 1000000;\r
-}\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define SP_CANVAS_AXONOMGRID_C
+
+/*
+ * SPCAxonomGrid
+ *
+ * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
+ * Copyright (C) 2000 Lauris Kaplinski
+ *
+ */
+
+ /*
+ * Current limits are: one axis (y-axis) is always vertical. The other two
+ * axes are bound to a certain range of angles. The z-axis always has an angle
+ * smaller than 90 degrees (measured from horizontal, 0 degrees being a line extending
+ * to the right). The x-axis will always have an angle between 0 and 90 degrees.
+ * When I quickly think about it: all possibilities are probably covered this way. Eg.
+ * a z-axis with negative angle can be replaced with an x-axis, etc.
+ */
+
+ /*
+ * TODO: LOTS LOTS LOTS. Optimization etc.
+ *
+ */
+
+#include "sp-canvas-util.h"
+#include "canvas-axonomgrid.h"
+#include "display-forward.h"
+#include <libnr/nr-pixops.h>
+
+#define SAFE_SETPIXEL //undefine this when it is certain that setpixel is never called with invalid params
+
+enum {
+ ARG_0,
+ ARG_ORIGINX,
+ ARG_ORIGINY,
+ ARG_ANGLEX,
+ ARG_SPACINGY,
+ ARG_ANGLEZ,
+ ARG_COLOR,
+ ARG_EMPCOLOR,
+ ARG_EMPSPACING
+};
+
+enum Dim3 { X=0, Y, Z };
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static double deg_to_rad(double deg) { return deg*M_PI/180.0;}
+
+
+static void sp_caxonomgrid_class_init (SPCAxonomGridClass *klass);
+static void sp_caxonomgrid_init (SPCAxonomGrid *grid);
+static void sp_caxonomgrid_destroy (GtkObject *object);
+static void sp_caxonomgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static void sp_caxonomgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);
+static void sp_caxonomgrid_render (SPCanvasItem *item, SPCanvasBuf *buf);
+
+static SPCanvasItemClass * parent_class;
+
+GtkType
+sp_caxonomgrid_get_type (void)
+{
+ static GtkType caxonomgrid_type = 0;
+
+ if (!caxonomgrid_type) {
+ GtkTypeInfo caxonomgrid_info = {
+ "SPCAxonomGrid",
+ sizeof (SPCAxonomGrid),
+ sizeof (SPCAxonomGridClass),
+ (GtkClassInitFunc) sp_caxonomgrid_class_init,
+ (GtkObjectInitFunc) sp_caxonomgrid_init,
+ NULL, NULL,
+ (GtkClassInitFunc) NULL
+ };
+ caxonomgrid_type = gtk_type_unique (sp_canvas_item_get_type (), &caxonomgrid_info);
+ }
+ return caxonomgrid_type;
+}
+
+static void
+sp_caxonomgrid_class_init (SPCAxonomGridClass *klass)
+{
+
+ GtkObjectClass *object_class;
+ SPCanvasItemClass *item_class;
+
+ object_class = (GtkObjectClass *) klass;
+ item_class = (SPCanvasItemClass *) klass;
+
+ parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ());
+
+ gtk_object_add_arg_type ("SPCAxonomGrid::originx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINX);
+ gtk_object_add_arg_type ("SPCAxonomGrid::originy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINY);
+ gtk_object_add_arg_type ("SPCAxonomGrid::anglex", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ANGLEX);
+ gtk_object_add_arg_type ("SPCAxonomGrid::spacingy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGY);
+ gtk_object_add_arg_type ("SPCAxonomGrid::anglez", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ANGLEZ);
+ gtk_object_add_arg_type ("SPCAxonomGrid::color", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_COLOR);
+ gtk_object_add_arg_type ("SPCAxonomGrid::empcolor", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPCOLOR);
+ gtk_object_add_arg_type ("SPCAxonomGrid::empspacing", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPSPACING);
+
+ object_class->destroy = sp_caxonomgrid_destroy;
+ object_class->set_arg = sp_caxonomgrid_set_arg;
+
+ item_class->update = sp_caxonomgrid_update;
+ item_class->render = sp_caxonomgrid_render;
+
+}
+
+static void
+sp_caxonomgrid_init (SPCAxonomGrid *grid)
+{
+ grid->origin[NR::X] = grid->origin[NR::Y] = 0.0;
+// grid->spacing[X] = grid->spacing[Y] = grid->spacing[Z] = 8.0;
+ grid->color = 0x0000ff7f;
+ grid->empcolor = 0x3F3FFF40;
+ grid->empspacing = 5;
+}
+
+static void
+sp_caxonomgrid_destroy (GtkObject *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (SP_IS_CAXONOMGRID (object));
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+sp_caxonomgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ SPCanvasItem *item = SP_CANVAS_ITEM (object);
+ SPCAxonomGrid *grid = SP_CAXONOMGRID (object);
+
+ switch (arg_id) {
+ case ARG_ORIGINX:
+ grid->origin[NR::X] = GTK_VALUE_DOUBLE (* arg);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_ORIGINY:
+ grid->origin[NR::Y] = GTK_VALUE_DOUBLE (* arg);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_ANGLEX:
+ grid->angle_deg[X] = GTK_VALUE_DOUBLE (* arg);
+ if (grid->angle_deg[X] < 0.0) grid->angle_deg[X] = 0.0;
+ if (grid->angle_deg[X] > 89.0) grid->angle_deg[X] = 89.0;
+ grid->angle_rad[X] = deg_to_rad(grid->angle_deg[X]);
+ grid->tan_angle[X] = tan(grid->angle_rad[X]);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_SPACINGY:
+ grid->lengthy = GTK_VALUE_DOUBLE (* arg);
+ if (grid->lengthy < 0.01) grid->lengthy = 0.01;
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_ANGLEZ:
+ grid->angle_deg[Z] = GTK_VALUE_DOUBLE (* arg);
+ if (grid->angle_deg[Z] < 0.0) grid->angle_deg[Z] = 0.0;
+ if (grid->angle_deg[X] > 89.0) grid->angle_deg[X] = 89.0;
+ grid->angle_rad[Z] = deg_to_rad(grid->angle_deg[Z]);
+ grid->tan_angle[Z] = tan(grid->angle_rad[Z]);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_COLOR:
+ grid->color = GTK_VALUE_INT (* arg);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_EMPCOLOR:
+ grid->empcolor = GTK_VALUE_INT (* arg);
+ sp_canvas_item_request_update (item);
+ break;
+ case ARG_EMPSPACING:
+ grid->empspacing = GTK_VALUE_INT (* arg);
+ // std::cout << "Emphasis Spacing: " << grid->empspacing << std::endl;
+ sp_canvas_item_request_update (item);
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+/**
+ \brief This function renders a pixel on a particular buffer.
+
+ The topleft of the buffer equals
+ ( rect.x0 , rect.y0 ) in screen coordinates
+ ( 0 , 0 ) in setpixel coordinates
+ The bottomright of the buffer equals
+ ( rect.x1 , rect,y1 ) in screen coordinates
+ ( rect.x1 - rect.x0 , rect.y1 - rect.y0 ) in setpixel coordinates
+*/
+static void
+sp_caxonomgrid_setpixel (SPCanvasBuf *buf, gint x, gint y, guint32 rgba) {
+#ifdef SAFE_SETPIXEL
+ if ( (x >= buf->rect.x0) && (x < buf->rect.x1) && (y >= buf->rect.y0) && (y < buf->rect.y1) ) {
+#endif
+ guint r, g, b, a;
+ r = NR_RGBA32_R (rgba);
+ g = NR_RGBA32_G (rgba);
+ b = NR_RGBA32_B (rgba);
+ a = NR_RGBA32_A (rgba);
+ guchar * p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
+ p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
+ p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
+ p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
+#ifdef SAFE_SETPIXEL
+ }
+#endif
+}
+
+/**
+ \brief This function renders a line on a particular canvas buffer,
+ using Bresenham's line drawing function.
+ http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
+ Coordinates are interpreted as SCREENcoordinates
+*/
+static void
+sp_caxonomgrid_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba) {
+ int dy = y1 - y0;
+ int dx = x1 - x0;
+ int stepx, stepy;
+
+ if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
+ if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
+ dy <<= 1; // dy is now 2*dy
+ dx <<= 1; // dx is now 2*dx
+
+ sp_caxonomgrid_setpixel(buf, x0, y0, rgba);
+ if (dx > dy) {
+ int fraction = dy - (dx >> 1); // same as 2*dy - dx
+ while (x0 != x1) {
+ if (fraction >= 0) {
+ y0 += stepy;
+ fraction -= dx; // same as fraction -= 2*dx
+ }
+ x0 += stepx;
+ fraction += dy; // same as fraction -= 2*dy
+ sp_caxonomgrid_setpixel(buf, x0, y0, rgba);
+ }
+ } else {
+ int fraction = dx - (dy >> 1);
+ while (y0 != y1) {
+ if (fraction >= 0) {
+ x0 += stepx;
+ fraction -= dy;
+ }
+ y0 += stepy;
+ fraction += dx;
+ sp_caxonomgrid_setpixel(buf, x0, y0, rgba);
+ }
+ }
+
+}
+
+static void
+sp_grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba)
+{
+ if ((x >= buf->rect.x0) && (x < buf->rect.x1)) {
+ guint r, g, b, a;
+ gint y0, y1, y;
+ guchar *p;
+ r = NR_RGBA32_R(rgba);
+ g = NR_RGBA32_G (rgba);
+ b = NR_RGBA32_B (rgba);
+ a = NR_RGBA32_A (rgba);
+ y0 = MAX (buf->rect.y0, ys);
+ y1 = MIN (buf->rect.y1, ye + 1);
+ p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
+ for (y = y0; y < y1; y++) {
+ p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
+ p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
+ p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
+ p += buf->buf_rowstride;
+ }
+ }
+}
+
+/**
+ \brief This function renders the grid on a particular canvas buffer
+ \param item The grid to render on the buffer
+ \param buf The buffer to render the grid on
+
+ This function gets called a touch more than you might believe,
+ about once per tile. This means that it could probably be optimized
+ and help things out.
+
+ Basically this function has to determine where in the canvas it is,
+ and how that associates with the grid. It does this first by looking
+ at the bounding box of the buffer, and then calculates where the grid
+ starts in that buffer. It will then step through grid lines until
+ it is outside of the buffer.
+
+ For each grid line it is drawn using the function \c sp_grid_hline
+ or \c sp_grid_vline. These are convience functions for the sake
+ of making the function easier to read.
+
+ Also, there are emphasized lines on the grid. While the \c syg and
+ \c sxg variable track grid positioning, the \c xlinestart and \c
+ ylinestart variables track the 'count' of what lines they are. If
+ that count is a multiple of the line seperation between emphasis
+ lines, then that line is drawn in the emphasis color.
+*/
+static void
+sp_caxonomgrid_render (SPCanvasItem * item, SPCanvasBuf * buf)
+{
+ SPCAxonomGrid *grid = SP_CAXONOMGRID (item);
+
+ sp_canvas_prepare_buffer (buf);
+
+ // gc = gridcoordinates (the coordinates calculated from the grids origin 'grid->ow'.
+ // sc = screencoordinates ( for example "buf->rect.x0" is in screencoordinates )
+ // bc = buffer patch coordinates
+
+ // tl = topleft ; br = bottomright
+ NR::Point buf_tl_gc;
+ NR::Point buf_br_gc;
+ buf_tl_gc[NR::X] = buf->rect.x0 - grid->ow[NR::X];
+ buf_tl_gc[NR::Y] = buf->rect.y0 - grid->ow[NR::Y];
+ buf_br_gc[NR::X] = buf->rect.x1 - grid->ow[NR::X];
+ buf_br_gc[NR::Y] = buf->rect.y1 - grid->ow[NR::Y];
+
+
+ gdouble x;
+ gdouble y;
+
+ // render the three separate line groups representing the main-axes:
+ // x-axis always goes from topleft to bottomright. (0,0) - (1,1)
+ const gdouble xintercept_y_bc = (buf_tl_gc[NR::X] * grid->tan_angle[X]) - buf_tl_gc[NR::Y] ;
+ const gdouble xstart_y_sc = ( xintercept_y_bc - floor(xintercept_y_bc/grid->lyw)*grid->lyw ) + buf->rect.y0;
+ const gint xlinestart = (gint) Inkscape::round( (xstart_y_sc - grid->ow[NR::Y]) / grid->lyw );
+ gint xlinenum;
+ // lijnen vanaf linker zijkant.
+ for (y = xstart_y_sc, xlinenum = xlinestart; y < buf->rect.y1; y += grid->lyw, xlinenum++) {
+ const gint x0 = buf->rect.x0;
+ const gint y0 = (gint) Inkscape::round(y);
+ const gint x1 = x0 + (gint) Inkscape::round( (buf->rect.y1 - y) / grid->tan_angle[X] );
+ const gint y1 = buf->rect.y1;
+
+ if (!grid->scaled && (xlinenum % grid->empspacing) == 0) {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);
+ } else {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);
+ }
+ }
+ // lijnen vanaf bovenkant.
+ const gdouble xstart_x_sc = buf->rect.x0 + (grid->lxw_x - (xstart_y_sc - buf->rect.y0) / grid->tan_angle[X]) ;
+ for (x = xstart_x_sc, xlinenum = xlinestart; x < buf->rect.x1; x += grid->lxw_x, xlinenum--) {
+ const gint y0 = buf->rect.y0;
+ const gint y1 = buf->rect.y1;
+ const gint x0 = (gint) Inkscape::round(x);
+ const gint x1 = x0 + (gint) Inkscape::round( (y1 - y0) / grid->tan_angle[X] );
+
+ if (!grid->scaled && (xlinenum % grid->empspacing) == 0) {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);
+ } else {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);
+ }
+ }
+
+
+ // y-axis lines (vertical)
+ const gdouble ystart_x_sc = floor (buf_tl_gc[NR::X] / grid->spacing_ylines) * grid->spacing_ylines + grid->ow[NR::X];
+ const gint ylinestart = (gint) Inkscape::round((ystart_x_sc - grid->ow[NR::X]) / grid->spacing_ylines);
+ gint ylinenum;
+ for (x = ystart_x_sc, ylinenum = ylinestart; x < buf->rect.x1; x += grid->spacing_ylines, ylinenum++) {
+ const gint x0 = (gint) Inkscape::round(x);
+
+ if (!grid->scaled && (ylinenum % grid->empspacing) == 0) {
+ sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, grid->empcolor);
+ } else {
+ sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, grid->color);
+ }
+ }
+
+ // z-axis always goes from bottomleft to topright. (0,1) - (1,0)
+ const gdouble zintercept_y_bc = (buf_tl_gc[NR::X] * -grid->tan_angle[Z]) - buf_tl_gc[NR::Y] ;
+ const gdouble zstart_y_sc = ( zintercept_y_bc - floor(zintercept_y_bc/grid->lyw)*grid->lyw ) + buf->rect.y0;
+ const gint zlinestart = (gint) Inkscape::round( (zstart_y_sc - grid->ow[NR::Y]) / grid->lyw );
+ gint zlinenum;
+ // lijnen vanaf linker zijkant.
+ for (y = zstart_y_sc, zlinenum = zlinestart; y < buf->rect.y1; y += grid->lyw, zlinenum++) {
+ const gint x0 = buf->rect.x0;
+ const gint y0 = (gint) Inkscape::round(y);
+ const gint x1 = x0 + (gint) Inkscape::round( (y - buf->rect.y0 ) / grid->tan_angle[Z] );
+ const gint y1 = buf->rect.y0;
+
+ if (!grid->scaled && (zlinenum % grid->empspacing) == 0) {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);
+ } else {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);
+ }
+ }
+ // lijnen vanaf onderkant.
+ const gdouble zstart_x_sc = buf->rect.x0 + (y - buf->rect.y1) / grid->tan_angle[Z] ;
+ for (x = zstart_x_sc; x < buf->rect.x1; x += grid->lxw_z, zlinenum--) {
+ const gint y0 = buf->rect.y1;
+ const gint y1 = buf->rect.y0;
+ const gint x0 = (gint) Inkscape::round(x);
+ const gint x1 = x0 + (gint) Inkscape::round( (buf->rect.y1 - buf->rect.y0) / grid->tan_angle[Z] );
+
+ if (!grid->scaled && (zlinenum % grid->empspacing) == 0) {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->empcolor);
+ } else {
+ sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, grid->color);
+ }
+ }
+
+}
+
+static void
+sp_caxonomgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)
+{
+ SPCAxonomGrid *grid = SP_CAXONOMGRID (item);
+
+ if (parent_class->update)
+ (* parent_class->update) (item, affine, flags);
+
+ grid->ow = grid->origin * affine;
+ grid->sw = NR::Point(fabs(affine[0]),fabs(affine[3]));
+
+ for(int dim = 0; dim < 2; dim++) {
+ gint scaling_factor = grid->empspacing;
+
+ if (scaling_factor <= 1)
+ scaling_factor = 5;
+
+ grid->scaled = FALSE;
+ while (grid->sw[dim] < 8.0) {
+ grid->scaled = TRUE;
+ grid->sw[dim] *= scaling_factor;
+ // First pass, go up to the major line spacing, then
+ // keep increasing by two.
+ scaling_factor = 2;
+ }
+ }
+
+ grid->spacing_ylines = grid->sw[NR::X] * grid->lengthy /(grid->tan_angle[X] + grid->tan_angle[Z]);
+ grid->lyw = grid->lengthy * grid->sw[NR::Y];
+ grid->lxw_x = (grid->lengthy / grid->tan_angle[X]) * grid->sw[NR::X];
+ grid->lxw_z = (grid->lengthy / grid->tan_angle[Z]) * grid->sw[NR::X];
+
+ if (grid->empspacing == 0) {
+ grid->scaled = TRUE;
+ }
+
+ sp_canvas_request_redraw (item->canvas,
+ -1000000, -1000000,
+ 1000000, 1000000);
+
+ item->x1 = item->y1 = -1000000;
+ item->x2 = item->y2 = 1000000;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 22fceed4473560fc5cf79a09ed0d7375bd80a295..79de72b43340abe7adf65eba7980445207a3f723 100644 (file)
-#ifndef SP_CANVAS_AXONOMGRID_H\r
-#define SP_CANVAS_AXONOMGRID_H\r
-\r
-/*\r
- * SPCAxonomGrid\r
- *\r
- * Generic (and quite unintelligent) modified copy of the grid item for gnome canvas\r
- *\r
- * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>\r
- * Copyright (C) 2000 Lauris Kaplinski 2000\r
- *\r
- */\r
-\r
-#include <display/sp-canvas.h>\r
-#include <libnr/nr-coord.h>\r
-\r
-\r
-#define SP_TYPE_CAXONOMGRID (sp_caxonomgrid_get_type ())\r
-#define SP_CAXONOMGRID(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CAXONOMGRID, SPCAxonomGrid))\r
-#define SP_CAXONOMGRID_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CAXONOMGRID, SPCAxonomGridClass))\r
-#define SP_IS_CAXONOMGRID(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CAXONOMGRID))\r
-#define SP_IS_CAXONOMGRID_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CAXONOMGRID))\r
-\r
-\r
-/** \brief All the variables that are tracked for a axonometric grid specific\r
- canvas item. */\r
-struct SPCAxonomGrid : public SPCanvasItem{\r
- NR::Point origin; /**< Origin of the grid */\r
- double lengthy; /**< The lengths of the primary y-axis */\r
- double angle_deg[3]; /**< Angle of each axis (note that angle[2] == 0) */\r
- double angle_rad[3]; /**< Angle of each axis (note that angle[2] == 0) */\r
- double tan_angle[3]; /**< tan(angle[.]) */\r
- guint32 color; /**< Color for normal lines */\r
- guint32 empcolor; /**< Color for emphasis lines */\r
- gint empspacing; /**< Spacing between emphasis lines */\r
- bool scaled; /**< Whether the grid is in scaled mode */\r
- \r
- NR::Point ow; /**< Transformed origin by the affine for the zoom */\r
- double lyw; /**< Transformed length y by the affine for the zoom */\r
- double lxw_x;\r
- double lxw_z;\r
- double spacing_ylines;\r
- \r
- NR::Point sw; /**< the scaling factors of the affine transform */\r
-};\r
-\r
-struct SPCAxonomGridClass {\r
- SPCanvasItemClass parent_class;\r
-};\r
-\r
-\r
-/* Standard Gtk function */\r
-GtkType sp_caxonomgrid_get_type (void);\r
-\r
-\r
-\r
-#endif \r
-\r
-\r
+#ifndef SP_CANVAS_AXONOMGRID_H
+#define SP_CANVAS_AXONOMGRID_H
+
+/*
+ * SPCAxonomGrid
+ *
+ * Generic (and quite unintelligent) modified copy of the grid item for gnome canvas
+ *
+ * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
+ * Copyright (C) 2000 Lauris Kaplinski 2000
+ *
+ */
+
+#include <display/sp-canvas.h>
+#include <libnr/nr-coord.h>
+
+
+#define SP_TYPE_CAXONOMGRID (sp_caxonomgrid_get_type ())
+#define SP_CAXONOMGRID(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CAXONOMGRID, SPCAxonomGrid))
+#define SP_CAXONOMGRID_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CAXONOMGRID, SPCAxonomGridClass))
+#define SP_IS_CAXONOMGRID(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CAXONOMGRID))
+#define SP_IS_CAXONOMGRID_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CAXONOMGRID))
+
+
+/** \brief All the variables that are tracked for a axonometric grid specific
+ canvas item. */
+struct SPCAxonomGrid : public SPCanvasItem{
+ NR::Point origin; /**< Origin of the grid */
+ double lengthy; /**< The lengths of the primary y-axis */
+ double angle_deg[3]; /**< Angle of each axis (note that angle[2] == 0) */
+ double angle_rad[3]; /**< Angle of each axis (note that angle[2] == 0) */
+ double tan_angle[3]; /**< tan(angle[.]) */
+ guint32 color; /**< Color for normal lines */
+ guint32 empcolor; /**< Color for emphasis lines */
+ gint empspacing; /**< Spacing between emphasis lines */
+ bool scaled; /**< Whether the grid is in scaled mode */
+
+ NR::Point ow; /**< Transformed origin by the affine for the zoom */
+ double lyw; /**< Transformed length y by the affine for the zoom */
+ double lxw_x;
+ double lxw_z;
+ double spacing_ylines;
+
+ NR::Point sw; /**< the scaling factors of the affine transform */
+};
+
+struct SPCAxonomGridClass {
+ SPCanvasItemClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType sp_caxonomgrid_get_type (void);
+
+
+
+#endif
+
+
index be0c9c5be34c7d5a99e1708c33aba02500930a26..7ebeebd88bc6d4e497add35da11882eba21eb159 100644 (file)
int const PC = NR_PIXBLOCK_BPP(in);
// Subsampling constants
- int const quality = prefs_get_int_attribute("options.blurquality", "value", 0);\r
+ int const quality = prefs_get_int_attribute("options.blurquality", "value", 0);
int const x_step_l2 = _effect_subsample_step_log2(deviation_x_org, quality);
int const y_step_l2 = _effect_subsample_step_log2(deviation_y_org, quality);
int const x_step = 1<<x_step_l2;
index 3c30ad58a15ca8d429199e9c40f4c4931f8210aa..f31f0e4f96affd880b9e072efb02709753e848a4 100644 (file)
--- a/src/dom/util/digest.cpp
+++ b/src/dom/util/digest.cpp
-/**\r
- * Secure Hashing Tool\r
- * *\r
- * Authors:\r
- * Bob Jamison\r
- *\r
- * Copyright (C) 2006 Bob Jamison\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
- */\r
-\r
-#include "digest.h"\r
-\r
-\r
-//########################################################################\r
-//## U T I L\r
-//########################################################################\r
-\r
-/**\r
- * Use this to print out a 64-bit int when otherwise difficult\r
- */\r
-/*\r
-static void pl(unsigned long long val)\r
-{\r
- for (int shift=56 ; shift>=0 ; shift-=8)\r
- {\r
- int ch = (val >> shift) & 0xff;\r
- printf("%02x", ch);\r
- }\r
-}\r
-*/\r
-\r
-\r
-static char *hexDigits = "0123456789abcdef";\r
-\r
-static std::string toHex(const std::vector<unsigned char> &bytes)\r
-{\r
- std::string str;\r
- std::vector<unsigned char>::const_iterator iter;\r
- for (iter = bytes.begin() ; iter != bytes.end() ; iter++)\r
- {\r
- unsigned char ch = *iter;\r
- str.push_back(hexDigits[(ch>>4) & 0x0f]);\r
- str.push_back(hexDigits[(ch ) & 0x0f]);\r
- }\r
- return str;\r
-}\r
-\r
-\r
-//########################################################################\r
-//## D I G E S T\r
-//########################################################################\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::string Digest::finishHex()\r
-{\r
- std::vector<unsigned char> hash = finish();\r
- std::string str = toHex(hash);\r
- return str;\r
-}\r
-\r
-\r
-//4.1.1 and 4.1.2\r
-#define SHA_ROTL(X,n) ( ((X) << (n)) | ( ((X) & 0xffffffffL) >> (32-(n))) )\r
-#define SHA_Ch(x,y,z) ((z)^((x)&((y)^(z))))\r
-#define SHA_Maj(x,y,z) (((x)&(y))^((z)&((x)^(y))))\r
-\r
-\r
-//########################################################################\r
-//## S H A 1\r
-//########################################################################\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha1Digest::reset()\r
-{\r
- lenW = 0;\r
- size = 0;\r
-\r
- // Initialize H with the magic constants (see FIPS180 for constants)\r
- H[0] = 0x67452301L;\r
- H[1] = 0xefcdab89L;\r
- H[2] = 0x98badcfeL;\r
- H[3] = 0x10325476L;\r
- H[4] = 0xc3d2e1f0L;\r
-\r
- for (int i = 0 ; i < 80 ; i++)\r
- W[i] = 0;\r
-}\r
-\r
-\r
-\r
-\r
-void Sha1Digest::hashblock()\r
-{\r
- //for (int t = 0; t < 16 ; t++)\r
- // printf("%2d %08lx\n", t, W[t]);\r
-\r
- //see 6.1.2\r
- for (int t = 16; t < 80 ; t++)\r
- W[t] = SHA_ROTL((W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]), 1);\r
-\r
- unsigned long a = H[0];\r
- unsigned long b = H[1];\r
- unsigned long c = H[2];\r
- unsigned long d = H[3];\r
- unsigned long e = H[4];\r
-\r
- unsigned long T;\r
-\r
- int t = 0;\r
- for ( ; t < 20 ; t++)\r
- {\r
- //see 4.1.1 for the boolops on B,C, and D\r
- T = (SHA_ROTL(a,5) + ((b&c)^(~b&d)) + //Ch(b,c,d))\r
- e + 0x5a827999L + W[t]) & 0xffffffffL;\r
- e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
- }\r
- for ( ; t < 40 ; t++)\r
- {\r
- T = (SHA_ROTL(a,5) + (b^c^d) +\r
- e + 0x6ed9eba1L + W[t]) & 0xffffffffL;\r
- e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
- }\r
- for ( ; t < 60 ; t++)\r
- {\r
- T = (SHA_ROTL(a,5) + ((b&c)^(b&d)^(c&d)) +\r
- e + 0x8f1bbcdcL + W[t]) & 0xffffffffL;\r
- e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
- }\r
- for ( ; t < 80 ; t++)\r
- {\r
- T = (SHA_ROTL(a,5) + (b^c^d) +\r
- e + 0xca62c1d6L + W[t]) & 0xffffffffL;\r
- e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
- }\r
-\r
- H[0] += a;\r
- H[1] += b;\r
- H[2] += c;\r
- H[3] += d;\r
- H[4] += e;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha1Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 2;\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 64)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Sha1Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 56-byte buf.\r
- //use mod, so that we will loop around once if already over 56\r
- while (lenW != 56)\r
- update((unsigned char)0x00);\r
- //append 64-bit size\r
- for (int shift = 56 ; shift>=0 ; shift-= 8)\r
- {\r
- unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
- update(ch);\r
- }\r
-\r
- // Output hash\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr < 5 ; wordNr++)\r
- {\r
- ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-\r
-}\r
-\r
-\r
-//########################################################################\r
-//## SHA224\r
-//########################################################################\r
-\r
-\r
-/**\r
- * SHA-224 and SHA-512 share the same operations and constants\r
- */ \r
-\r
-#define SHA_Rot32(x,s) (((x) >> s) | ((x) << (32 - s)))\r
-#define SHA_SIGMA0(x) (SHA_Rot32(x, 2) ^ SHA_Rot32(x, 13) ^ SHA_Rot32(x, 22))\r
-#define SHA_SIGMA1(x) (SHA_Rot32(x, 6) ^ SHA_Rot32(x, 11) ^ SHA_Rot32(x, 25))\r
-#define SHA_sigma0(x) (SHA_Rot32(x, 7) ^ SHA_Rot32(x, 18) ^ ((x) >> 3))\r
-#define SHA_sigma1(x) (SHA_Rot32(x, 17) ^ SHA_Rot32(x, 19) ^ ((x) >> 10))\r
-\r
-\r
-static unsigned long sha256constants[64] =\r
-{\r
-0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,\r
-0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,\r
-0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,\r
-0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,\r
-0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,\r
-0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,\r
-0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,\r
-0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,\r
-0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,\r
-0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,\r
-0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,\r
-0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,\r
-0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,\r
-0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,\r
-0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,\r
-0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL\r
-};\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha224Digest::reset()\r
-{\r
- lenW = 0;\r
- size = 0;\r
-\r
- // Initialize H with the magic constants (see FIPS180 for constants)\r
- H[0] = 0xc1059ed8L;\r
- H[1] = 0x367cd507L;\r
- H[2] = 0x3070dd17L;\r
- H[3] = 0xf70e5939L;\r
- H[4] = 0xffc00b31L;\r
- H[5] = 0x68581511L;\r
- H[6] = 0x64f98fa7L;\r
- H[7] = 0xbefa4fa4L;\r
-\r
- for (int i = 0 ; i < 64 ; i++)\r
- W[i] = 0;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-void Sha224Digest::hashblock()\r
-{\r
- //for (int t = 0; t < 16 ; t++)\r
- // printf("%2d %08lx\n", t, W[t]);\r
-\r
- //see 6.2.2\r
- for (int t = 16; t < 64 ; t++)\r
- W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
-\r
- unsigned long a = H[0];\r
- unsigned long b = H[1];\r
- unsigned long c = H[2];\r
- unsigned long d = H[3];\r
- unsigned long e = H[4];\r
- unsigned long f = H[5];\r
- unsigned long g = H[6];\r
- unsigned long h = H[7];\r
-\r
- for (int t = 0 ; t < 64 ; t++)\r
- {\r
- //see 4.1.1 for the boolops\r
- unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
- sha256constants[t] + W[t];\r
- unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
- h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",\r
- // t, a, b, c, d, e, f, g, h);\r
- }\r
-\r
- H[0] += a;\r
- H[1] += b;\r
- H[2] += c;\r
- H[3] += d;\r
- H[4] += e;\r
- H[5] += f;\r
- H[6] += g;\r
- H[7] += h;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha224Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 2;\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 64)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Sha224Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 56-byte buf.\r
- //use mod, so that we will loop around once if already over 56\r
- while (lenW != 56)\r
- update((unsigned char)0x00);\r
- //append 64-bit size\r
- for (int shift = 56 ; shift>=0 ; shift-= 8)\r
- {\r
- unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
- update(ch);\r
- }\r
-\r
- // Output hash\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr < 7 ; wordNr++)\r
- {\r
- ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-\r
-}\r
-\r
-//########################################################################\r
-//## SHA256\r
-//########################################################################\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha256Digest::reset()\r
-{\r
- lenW = 0;\r
- size = 0;\r
-\r
- // Initialize H with the magic constants (see FIPS180 for constants)\r
- H[0] = 0x6a09e667L;\r
- H[1] = 0xbb67ae85L;\r
- H[2] = 0x3c6ef372L;\r
- H[3] = 0xa54ff53aL;\r
- H[4] = 0x510e527fL;\r
- H[5] = 0x9b05688cL;\r
- H[6] = 0x1f83d9abL;\r
- H[7] = 0x5be0cd19L;\r
-\r
- for (int i = 0 ; i < 64 ; i++)\r
- W[i] = 0;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-void Sha256Digest::hashblock()\r
-{\r
- //for (int t = 0; t < 16 ; t++)\r
- // printf("%2d %08lx\n", t, W[t]);\r
-\r
- //see 6.2.2\r
- for (int t = 16; t < 64 ; t++)\r
- W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
-\r
- unsigned long a = H[0];\r
- unsigned long b = H[1];\r
- unsigned long c = H[2];\r
- unsigned long d = H[3];\r
- unsigned long e = H[4];\r
- unsigned long f = H[5];\r
- unsigned long g = H[6];\r
- unsigned long h = H[7];\r
-\r
- for (int t = 0 ; t < 64 ; t++)\r
- {\r
- //see 4.1.1 for the boolops\r
- unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
- sha256constants[t] + W[t];\r
- unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
- h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
- //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",\r
- // t, a, b, c, d, e, f, g, h);\r
- }\r
-\r
- H[0] += a;\r
- H[1] += b;\r
- H[2] += c;\r
- H[3] += d;\r
- H[4] += e;\r
- H[5] += f;\r
- H[6] += g;\r
- H[7] += h;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha256Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 2;\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 64)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Sha256Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 56-byte buf.\r
- //use mod, so that we will loop around once if already over 56\r
- while (lenW != 56)\r
- update((unsigned char)0x00);\r
- //append 64-bit size\r
- for (int shift = 56 ; shift>=0 ; shift-= 8)\r
- {\r
- unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
- update(ch);\r
- }\r
-\r
- // Output hash\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr < 8 ; wordNr++)\r
- {\r
- ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-\r
-}\r
-\r
-\r
-\r
-//########################################################################\r
-//## SHA384\r
-//########################################################################\r
-\r
-/**\r
- * SHA-384 and SHA-512 share the same operations and constants\r
- */\r
- \r
-#undef SHA_SIGMA0\r
-#undef SHA_SIGMA1\r
-#undef SHA_sigma0\r
-#undef SHA_sigma1\r
-\r
-#define SHA_Rot64(x,s) (((x) >> s) | ((x) << (64 - s)))\r
-#define SHA_SIGMA0(x) (SHA_Rot64(x, 28) ^ SHA_Rot64(x, 34) ^ SHA_Rot64(x, 39))\r
-#define SHA_SIGMA1(x) (SHA_Rot64(x, 14) ^ SHA_Rot64(x, 18) ^ SHA_Rot64(x, 41))\r
-#define SHA_sigma0(x) (SHA_Rot64(x, 1) ^ SHA_Rot64(x, 8) ^ ((x) >> 7))\r
-#define SHA_sigma1(x) (SHA_Rot64(x, 19) ^ SHA_Rot64(x, 61) ^ ((x) >> 6))\r
-\r
-\r
-static unsigned long long sha512constants[80] =\r
-{\r
-0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,\r
-0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\r
-0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,\r
-0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\r
-0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,\r
-0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\r
-0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,\r
-0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\r
-0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,\r
-0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\r
-0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,\r
-0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\r
-0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,\r
-0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\r
-0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,\r
-0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\r
-0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,\r
-0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\r
-0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,\r
-0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\r
-0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,\r
-0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\r
-0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,\r
-0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\r
-0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,\r
-0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\r
-0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,\r
-0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\r
-0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,\r
-0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\r
-0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,\r
-0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\r
-0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,\r
-0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\r
-0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,\r
-0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\r
-0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,\r
-0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\r
-0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,\r
-0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL\r
-};\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha384Digest::reset()\r
-{\r
- lenW = 0;\r
- size = 0;\r
-\r
- // SHA-384 differs from SHA-512 by these constants\r
- H[0] = 0xcbbb9d5dc1059ed8ULL;\r
- H[1] = 0x629a292a367cd507ULL;\r
- H[2] = 0x9159015a3070dd17ULL;\r
- H[3] = 0x152fecd8f70e5939ULL;\r
- H[4] = 0x67332667ffc00b31ULL;\r
- H[5] = 0x8eb44a8768581511ULL;\r
- H[6] = 0xdb0c2e0d64f98fa7ULL;\r
- H[7] = 0x47b5481dbefa4fa4ULL;\r
-\r
- for (int i = 0 ; i < 80 ; i++)\r
- W[i] = 0;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-void Sha384Digest::hashblock()\r
-{\r
- /*\r
- for (int t = 0; t < 16 ; t++)\r
- {\r
- printf("%2d ", t);\r
- pl(W[t]);\r
- printf("\n");\r
- }\r
- */\r
-\r
- //see 6.2.2\r
- for (int t = 16; t < 80 ; t++)\r
- W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
-\r
- unsigned long long a = H[0];\r
- unsigned long long b = H[1];\r
- unsigned long long c = H[2];\r
- unsigned long long d = H[3];\r
- unsigned long long e = H[4];\r
- unsigned long long f = H[5];\r
- unsigned long long g = H[6];\r
- unsigned long long h = H[7];\r
-\r
- for (int t = 0 ; t < 80 ; t++)\r
- {\r
- //see 4.1.1 for the boolops\r
- unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
- sha512constants[t] + W[t];\r
- unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
- h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
- }\r
-\r
- H[0] += a;\r
- H[1] += b;\r
- H[2] += c;\r
- H[3] += d;\r
- H[4] += e;\r
- H[5] += f;\r
- H[6] += g;\r
- H[7] += h;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha384Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 3;\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 128)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Sha384Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 112-byte buf.\r
- //we will loop around once if already over 112\r
- while (lenW != 112)\r
- update((unsigned char)0x00);\r
- \r
- //append 128-bit size\r
- for (int i = 0 ; i < 8 ; i++) //64 upper bits\r
- update((unsigned char)0x00);\r
- for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits\r
- {\r
- unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
- update(ch);\r
- }\r
-\r
- // Output hash\r
- //for SHA-384, we use the left-most 6 64-bit words\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr < 6 ; wordNr++)\r
- {\r
- ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-\r
-}\r
-\r
-\r
-//########################################################################\r
-//## SHA512\r
-//########################################################################\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha512Digest::reset()\r
-{\r
- lenW = 0;\r
- size = 0;\r
-\r
- // Initialize H with the magic constants (see FIPS180 for constants)\r
- H[0] = 0x6a09e667f3bcc908ULL;\r
- H[1] = 0xbb67ae8584caa73bULL;\r
- H[2] = 0x3c6ef372fe94f82bULL;\r
- H[3] = 0xa54ff53a5f1d36f1ULL;\r
- H[4] = 0x510e527fade682d1ULL;\r
- H[5] = 0x9b05688c2b3e6c1fULL;\r
- H[6] = 0x1f83d9abfb41bd6bULL;\r
- H[7] = 0x5be0cd19137e2179ULL;\r
-\r
- for (int i = 0 ; i < 80 ; i++)\r
- W[i] = 0;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-void Sha512Digest::hashblock()\r
-{\r
- /*\r
- for (int t = 0; t < 16 ; t++)\r
- {\r
- printf("%2d ", t);\r
- pl(W[t]);\r
- printf("\n");\r
- }\r
- */\r
-\r
- //see 6.2.2\r
- for (int t = 16; t < 80 ; t++)\r
- W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
-\r
- unsigned long long a = H[0];\r
- unsigned long long b = H[1];\r
- unsigned long long c = H[2];\r
- unsigned long long d = H[3];\r
- unsigned long long e = H[4];\r
- unsigned long long f = H[5];\r
- unsigned long long g = H[6];\r
- unsigned long long h = H[7];\r
-\r
- for (int t = 0 ; t < 80 ; t++)\r
- {\r
- //see 4.1.1 for the boolops\r
- unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
- sha512constants[t] + W[t];\r
- unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
- h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
- }\r
-\r
- H[0] += a;\r
- H[1] += b;\r
- H[2] += c;\r
- H[3] += d;\r
- H[4] += e;\r
- H[5] += f;\r
- H[6] += g;\r
- H[7] += h;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Sha512Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 3;\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 128)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Sha512Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 112-byte buf.\r
- //we will loop around once if already over 112\r
- while (lenW != 112)\r
- update((unsigned char)0x00);\r
- \r
- //append 128-bit size\r
- for (int i = 0 ; i < 8 ; i++) //64 upper bits\r
- update((unsigned char)0x00);\r
- for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits\r
- {\r
- unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
- update(ch);\r
- }\r
-\r
- // Output hash\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr < 8 ; wordNr++)\r
- {\r
- ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
- ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-\r
-}\r
-\r
-\r
-\r
-//########################################################################\r
-//## M D 5\r
-//########################################################################\r
-\r
-static int md5r[64] =\r
-{\r
- 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, \r
- 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,\r
- 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\r
- 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21\r
-};\r
-\r
-static unsigned long md5k[64] =\r
-{\r
-0xd76aa478L, 0xe8c7b756L, 0x242070dbL, 0xc1bdceeeL, \r
-0xf57c0fafL, 0x4787c62aL, 0xa8304613L, 0xfd469501L, \r
-0x698098d8L, 0x8b44f7afL, 0xffff5bb1L, 0x895cd7beL, \r
-0x6b901122L, 0xfd987193L, 0xa679438eL, 0x49b40821L, \r
-0xf61e2562L, 0xc040b340L, 0x265e5a51L, 0xe9b6c7aaL, \r
-0xd62f105dL, 0x02441453L, 0xd8a1e681L, 0xe7d3fbc8L, \r
-0x21e1cde6L, 0xc33707d6L, 0xf4d50d87L, 0x455a14edL, \r
-0xa9e3e905L, 0xfcefa3f8L, 0x676f02d9L, 0x8d2a4c8aL, \r
-0xfffa3942L, 0x8771f681L, 0x6d9d6122L, 0xfde5380cL, \r
-0xa4beea44L, 0x4bdecfa9L, 0xf6bb4b60L, 0xbebfbc70L, \r
-0x289b7ec6L, 0xeaa127faL, 0xd4ef3085L, 0x04881d05L, \r
-0xd9d4d039L, 0xe6db99e5L, 0x1fa27cf8L, 0xc4ac5665L, \r
-0xf4292244L, 0x432aff97L, 0xab9423a7L, 0xfc93a039L, \r
-0x655b59c3L, 0x8f0ccc92L, 0xffeff47dL, 0x85845dd1L, \r
-0x6fa87e4fL, 0xfe2ce6e0L, 0xa3014314L, 0x4e0811a1L, \r
-0xf7537e82L, 0xbd3af235L, 0x2ad7d2bbL, 0xeb86d391L\r
-};\r
-\r
-#define MD5_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Md5Digest::reset()\r
-{\r
- size = 0;\r
- lenW = 0;\r
-\r
- hash[0] = 0x67452301L;\r
- hash[1] = 0xefcdab89L;\r
- hash[2] = 0x98badcfeL;\r
- hash[3] = 0x10325476L;\r
-\r
- for (int i = 0 ; i < 64 ; i++)\r
- W[i] = 0;\r
-\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Md5Digest::hashblock()\r
-{\r
- //for (int t = 0; t < 16 ; t++)\r
- // printf("%2d %08lx\n", t, W[t]);\r
-\r
- unsigned long a = hash[0];\r
- unsigned long b = hash[1];\r
- unsigned long c = hash[2];\r
- unsigned long d = hash[3];\r
-\r
- int t = 0;\r
- for ( ; t < 16 ; t++)\r
- {\r
- unsigned long f = d ^ ( b & ( c ^ d));\r
- unsigned int g = t;\r
- unsigned long temp = d; d = c; c = b;\r
- b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
- a = temp;\r
- //printf("%2d %08lx %08lx %08lx %08lx\n", t, a, b, c, d);\r
- }\r
- for ( ; t < 32 ; t++)\r
- {\r
- unsigned long f = c ^ ( d & ( b ^ c));\r
- unsigned int g = (5 * t + 1) & 0xf;\r
- unsigned long temp = d; d = c; c = b;\r
- b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
- a = temp;\r
- }\r
- for ( ; t < 48 ; t++)\r
- {\r
- unsigned long f = b ^ c ^ d;\r
- unsigned int g = (3 * t + 5) & 0xf;\r
- unsigned long temp = d; d = c; c = b;\r
- b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
- a = temp;\r
- }\r
- for ( ; t < 64 ; t++)\r
- {\r
- unsigned long f = c ^ (b | ~d);\r
- unsigned int g = (7 * t) & 0xf;\r
- unsigned long temp = d; d = c; c = b;\r
- b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
- a = temp;\r
- }\r
-\r
- hash[0] += a;\r
- hash[1] += b;\r
- hash[2] += c;\r
- hash[3] += d;\r
-}\r
-\r
-\r
-/**\r
- *\r
- */\r
-void Md5Digest::update(unsigned char val)\r
-{\r
- int wordNr = lenW >> 2;\r
- /*\r
- W[wordNr] <<= 8;\r
- W[wordNr] |= (unsigned long)val;\r
- */\r
- W[wordNr] = ( (W[wordNr] >> 8) & 0x00ffffff ) |\r
- ( ((unsigned long)val) << 24 );\r
- size += 8;\r
- lenW++;\r
- if (lenW >= 64)\r
- {\r
- hashblock();\r
- lenW = 0;\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- *\r
- */\r
-std::vector<unsigned char> Md5Digest::finish()\r
-{\r
- //save our size before padding\r
- unsigned long long sizeOut = size;\r
- \r
- // Pad with a binary 1 (0x80)\r
- update((unsigned char)0x80);\r
- //append 0's to make a 56-byte buf.\r
- //use mod, so that we will loop around once if already over 56\r
- while (lenW != 56)\r
- update((unsigned char)0x00);\r
-\r
-\r
- //Append the length. Lower 32 bits first\r
- update( (unsigned char) ((sizeOut ) & 0xff));\r
- update( (unsigned char) ((sizeOut>> 8) & 0xff));\r
- update( (unsigned char) ((sizeOut>>16) & 0xff));\r
- update( (unsigned char) ((sizeOut>>24) & 0xff));\r
- update( (unsigned char) ((sizeOut>>32) & 0xff));\r
- update( (unsigned char) ((sizeOut>>40) & 0xff));\r
- update( (unsigned char) ((sizeOut>>48) & 0xff));\r
- update( (unsigned char) ((sizeOut>>56) & 0xff));\r
-\r
- //Output hash\r
- std::vector<unsigned char> ret;\r
- for (int wordNr = 0 ; wordNr<4 ; wordNr++)\r
- {\r
- unsigned long w = hash[wordNr];\r
- ret.push_back( (unsigned char) ((w ) & 0xff) );\r
- ret.push_back( (unsigned char) ((w >> 8) & 0xff) );\r
- ret.push_back( (unsigned char) ((w >> 16) & 0xff) );\r
- ret.push_back( (unsigned char) ((w >> 24) & 0xff) );\r
- }\r
-\r
- // Re-initialize the context (also zeroizes contents)\r
- reset();\r
-\r
- return ret;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-//########################################################################\r
-//## T E S T S\r
-//########################################################################\r
-\r
-/**\r
- * Compile this file alone with -DDIGEST_TEST to run the\r
- * tests below:\r
- * > gcc -DDIGEST_TEST digest.cpp -o digest\r
- * > digest \r
- */\r
- \r
- #ifdef DIGEST_TEST\r
-\r
-\r
-typedef struct\r
-{\r
- char *msg;\r
- char *val;\r
-} TestPair;\r
-\r
-static TestPair md5tests[] =\r
-{\r
- {\r
- "",\r
- "d41d8cd98f00b204e9800998ecf8427e"\r
- },\r
- {\r
- "a",\r
- "0cc175b9c0f1b6a831c399e269772661"\r
- },\r
- {\r
- "abc",\r
- "900150983cd24fb0d6963f7d28e17f72"\r
- },\r
- {\r
- "message digest",\r
- "f96b697d7cb7938d525a2f31aaf161d0"\r
- },\r
- {\r
- "abcdefghijklmnopqrstuvwxyz",\r
- "c3fcd3d76192e4007dfb496cca67e13b"\r
- },\r
- {\r
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",\r
- "d174ab98d277d9f5a5611c2c9f419d9f"\r
- },\r
- {\r
- "12345678901234567890123456789012345678901234567890123456789012345678901234567890",\r
- "57edf4a22be3c955ac49da2e2107b67a"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-\r
-\r
-static TestPair sha1tests[] =\r
-{\r
- {\r
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
- "84983e441c3bd26ebaae4aa1f95129e5e54670f1"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-static TestPair sha224tests[] =\r
-{\r
- {\r
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
- "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-static TestPair sha256tests[] =\r
-{\r
- {\r
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
- "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-static TestPair sha384tests[] =\r
-{\r
- {\r
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"\r
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",\r
- "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"\r
- "fcc7c71a557e2db966c3e9fa91746039"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-static TestPair sha512tests[] =\r
-{\r
- {\r
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"\r
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",\r
- "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"\r
- "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"\r
- },\r
- {\r
- NULL,\r
- NULL\r
- }\r
-};\r
-\r
-\r
-bool hashTests(Digest &digest, TestPair *tp)\r
-{\r
- for (TestPair *pair = tp ; pair->msg ; pair++)\r
- {\r
- digest.reset();\r
- std::string msg = pair->msg;\r
- std::string val = pair->val;\r
- digest.append(msg);\r
- std::string res = digest.finishHex();\r
- printf("### Msg '%s':\n hash '%s'\n exp '%s'\n",\r
- msg.c_str(), res.c_str(), val.c_str());\r
- if (res != val)\r
- {\r
- printf("ERROR: Hash mismatch\n");\r
- return false;\r
- }\r
- }\r
- return true;\r
-}\r
-\r
-\r
-bool millionATest(Digest &digest, const std::string &exp)\r
-{\r
- digest.reset();\r
- for (int i=0 ; i<1000000 ; i++)\r
- digest.append('a');\r
- std::string res = digest.finishHex();\r
- printf("\nHash of 1,000,000 'a'\n calc %s\n exp %s\n",\r
- res.c_str(), exp.c_str());\r
- if (res != exp)\r
- {\r
- printf("ERROR: Mismatch.\n");\r
- return false;\r
- }\r
- return true;\r
-}\r
-\r
-static bool doTests()\r
-{\r
- printf("##########################################\n");\r
- printf("## MD5\n");\r
- printf("##########################################\n");\r
- Md5Digest md5;\r
- if (!hashTests(md5, md5tests))\r
- return false;\r
- if (!millionATest(md5, "7707d6ae4e027c70eea2a935c2296f21"))\r
- return false;\r
- printf("\n\n\n");\r
- printf("##########################################\n");\r
- printf("## SHA1\n");\r
- printf("##########################################\n");\r
- Sha1Digest sha1;\r
- if (!hashTests(sha1, sha1tests))\r
- return false;\r
- if (!millionATest(sha1, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"))\r
- return false;\r
- printf("\n\n\n");\r
- printf("##########################################\n");\r
- printf("## SHA224\n");\r
- printf("##########################################\n");\r
- Sha224Digest sha224;\r
- if (!hashTests(sha224, sha224tests))\r
- return false;\r
- if (!millionATest(sha224,\r
- "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"))\r
- return false;\r
- printf("\n\n\n");\r
- printf("##########################################\n");\r
- printf("## SHA256\n");\r
- printf("##########################################\n");\r
- Sha256Digest sha256;\r
- if (!hashTests(sha256, sha256tests))\r
- return false;\r
- if (!millionATest(sha256,\r
- "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"))\r
- return false;\r
- printf("\n\n\n");\r
- printf("##########################################\n");\r
- printf("## SHA384\n");\r
- printf("##########################################\n");\r
- Sha384Digest sha384;\r
- if (!hashTests(sha384, sha384tests))\r
- return false;\r
- /**/\r
- if (!millionATest(sha384,\r
- "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"\r
- "07b8b3dc38ecc4ebae97ddd87f3d8985"))\r
- return false;\r
- /**/\r
- printf("\n\n\n");\r
- printf("##########################################\n");\r
- printf("## SHA512\n");\r
- printf("##########################################\n");\r
- Sha512Digest sha512;\r
- if (!hashTests(sha512, sha512tests))\r
- return false;\r
- if (!millionATest(sha512,\r
- "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"\r
- "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"))\r
- return false;\r
- return true;\r
-}\r
-\r
-\r
-int main(int argc, char **argv)\r
-{\r
- doTests();\r
- printf("####### done ########\n");\r
- return 0;\r
-}\r
-\r
-\r
-#endif /* DIGEST_TEST */\r
-\r
-//########################################################################\r
-//## E N D O F F I L E\r
-//########################################################################\r
+/**
+ * Secure Hashing Tool
+ * *
+ * Authors:
+ * Bob Jamison
+ *
+ * Copyright (C) 2006 Bob Jamison
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "digest.h"
+
+
+//########################################################################
+//## U T I L
+//########################################################################
+
+/**
+ * Use this to print out a 64-bit int when otherwise difficult
+ */
+/*
+static void pl(unsigned long long val)
+{
+ for (int shift=56 ; shift>=0 ; shift-=8)
+ {
+ int ch = (val >> shift) & 0xff;
+ printf("%02x", ch);
+ }
+}
+*/
+
+
+static char *hexDigits = "0123456789abcdef";
+
+static std::string toHex(const std::vector<unsigned char> &bytes)
+{
+ std::string str;
+ std::vector<unsigned char>::const_iterator iter;
+ for (iter = bytes.begin() ; iter != bytes.end() ; iter++)
+ {
+ unsigned char ch = *iter;
+ str.push_back(hexDigits[(ch>>4) & 0x0f]);
+ str.push_back(hexDigits[(ch ) & 0x0f]);
+ }
+ return str;
+}
+
+
+//########################################################################
+//## D I G E S T
+//########################################################################
+
+
+/**
+ *
+ */
+std::string Digest::finishHex()
+{
+ std::vector<unsigned char> hash = finish();
+ std::string str = toHex(hash);
+ return str;
+}
+
+
+//4.1.1 and 4.1.2
+#define SHA_ROTL(X,n) ( ((X) << (n)) | ( ((X) & 0xffffffffL) >> (32-(n))) )
+#define SHA_Ch(x,y,z) ((z)^((x)&((y)^(z))))
+#define SHA_Maj(x,y,z) (((x)&(y))^((z)&((x)^(y))))
+
+
+//########################################################################
+//## S H A 1
+//########################################################################
+
+
+/**
+ *
+ */
+void Sha1Digest::reset()
+{
+ lenW = 0;
+ size = 0;
+
+ // Initialize H with the magic constants (see FIPS180 for constants)
+ H[0] = 0x67452301L;
+ H[1] = 0xefcdab89L;
+ H[2] = 0x98badcfeL;
+ H[3] = 0x10325476L;
+ H[4] = 0xc3d2e1f0L;
+
+ for (int i = 0 ; i < 80 ; i++)
+ W[i] = 0;
+}
+
+
+
+
+void Sha1Digest::hashblock()
+{
+ //for (int t = 0; t < 16 ; t++)
+ // printf("%2d %08lx\n", t, W[t]);
+
+ //see 6.1.2
+ for (int t = 16; t < 80 ; t++)
+ W[t] = SHA_ROTL((W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]), 1);
+
+ unsigned long a = H[0];
+ unsigned long b = H[1];
+ unsigned long c = H[2];
+ unsigned long d = H[3];
+ unsigned long e = H[4];
+
+ unsigned long T;
+
+ int t = 0;
+ for ( ; t < 20 ; t++)
+ {
+ //see 4.1.1 for the boolops on B,C, and D
+ T = (SHA_ROTL(a,5) + ((b&c)^(~b&d)) + //Ch(b,c,d))
+ e + 0x5a827999L + W[t]) & 0xffffffffL;
+ e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);
+ }
+ for ( ; t < 40 ; t++)
+ {
+ T = (SHA_ROTL(a,5) + (b^c^d) +
+ e + 0x6ed9eba1L + W[t]) & 0xffffffffL;
+ e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);
+ }
+ for ( ; t < 60 ; t++)
+ {
+ T = (SHA_ROTL(a,5) + ((b&c)^(b&d)^(c&d)) +
+ e + 0x8f1bbcdcL + W[t]) & 0xffffffffL;
+ e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);
+ }
+ for ( ; t < 80 ; t++)
+ {
+ T = (SHA_ROTL(a,5) + (b^c^d) +
+ e + 0xca62c1d6L + W[t]) & 0xffffffffL;
+ e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);
+ }
+
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+}
+
+
+/**
+ *
+ */
+void Sha1Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 2;
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ size += 8;
+ lenW++;
+ if (lenW >= 64)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Sha1Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 56-byte buf.
+ //use mod, so that we will loop around once if already over 56
+ while (lenW != 56)
+ update((unsigned char)0x00);
+ //append 64-bit size
+ for (int shift = 56 ; shift>=0 ; shift-= 8)
+ {
+ unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);
+ update(ch);
+ }
+
+ // Output hash
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr < 5 ; wordNr++)
+ {
+ ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] ) & 0xff));
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+
+}
+
+
+//########################################################################
+//## SHA224
+//########################################################################
+
+
+/**
+ * SHA-224 and SHA-512 share the same operations and constants
+ */
+
+#define SHA_Rot32(x,s) (((x) >> s) | ((x) << (32 - s)))
+#define SHA_SIGMA0(x) (SHA_Rot32(x, 2) ^ SHA_Rot32(x, 13) ^ SHA_Rot32(x, 22))
+#define SHA_SIGMA1(x) (SHA_Rot32(x, 6) ^ SHA_Rot32(x, 11) ^ SHA_Rot32(x, 25))
+#define SHA_sigma0(x) (SHA_Rot32(x, 7) ^ SHA_Rot32(x, 18) ^ ((x) >> 3))
+#define SHA_sigma1(x) (SHA_Rot32(x, 17) ^ SHA_Rot32(x, 19) ^ ((x) >> 10))
+
+
+static unsigned long sha256constants[64] =
+{
+0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+
+
+
+
+/**
+ *
+ */
+void Sha224Digest::reset()
+{
+ lenW = 0;
+ size = 0;
+
+ // Initialize H with the magic constants (see FIPS180 for constants)
+ H[0] = 0xc1059ed8L;
+ H[1] = 0x367cd507L;
+ H[2] = 0x3070dd17L;
+ H[3] = 0xf70e5939L;
+ H[4] = 0xffc00b31L;
+ H[5] = 0x68581511L;
+ H[6] = 0x64f98fa7L;
+ H[7] = 0xbefa4fa4L;
+
+ for (int i = 0 ; i < 64 ; i++)
+ W[i] = 0;
+}
+
+
+
+
+
+void Sha224Digest::hashblock()
+{
+ //for (int t = 0; t < 16 ; t++)
+ // printf("%2d %08lx\n", t, W[t]);
+
+ //see 6.2.2
+ for (int t = 16; t < 64 ; t++)
+ W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];
+
+ unsigned long a = H[0];
+ unsigned long b = H[1];
+ unsigned long c = H[2];
+ unsigned long d = H[3];
+ unsigned long e = H[4];
+ unsigned long f = H[5];
+ unsigned long g = H[6];
+ unsigned long h = H[7];
+
+ for (int t = 0 ; t < 64 ; t++)
+ {
+ //see 4.1.1 for the boolops
+ unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +
+ sha256constants[t] + W[t];
+ unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);
+ h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ // t, a, b, c, d, e, f, g, h);
+ }
+
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+ H[5] += f;
+ H[6] += g;
+ H[7] += h;
+}
+
+
+/**
+ *
+ */
+void Sha224Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 2;
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ size += 8;
+ lenW++;
+ if (lenW >= 64)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Sha224Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 56-byte buf.
+ //use mod, so that we will loop around once if already over 56
+ while (lenW != 56)
+ update((unsigned char)0x00);
+ //append 64-bit size
+ for (int shift = 56 ; shift>=0 ; shift-= 8)
+ {
+ unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);
+ update(ch);
+ }
+
+ // Output hash
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr < 7 ; wordNr++)
+ {
+ ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] ) & 0xff));
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+
+}
+
+//########################################################################
+//## SHA256
+//########################################################################
+
+
+
+
+
+/**
+ *
+ */
+void Sha256Digest::reset()
+{
+ lenW = 0;
+ size = 0;
+
+ // Initialize H with the magic constants (see FIPS180 for constants)
+ H[0] = 0x6a09e667L;
+ H[1] = 0xbb67ae85L;
+ H[2] = 0x3c6ef372L;
+ H[3] = 0xa54ff53aL;
+ H[4] = 0x510e527fL;
+ H[5] = 0x9b05688cL;
+ H[6] = 0x1f83d9abL;
+ H[7] = 0x5be0cd19L;
+
+ for (int i = 0 ; i < 64 ; i++)
+ W[i] = 0;
+}
+
+
+
+
+
+void Sha256Digest::hashblock()
+{
+ //for (int t = 0; t < 16 ; t++)
+ // printf("%2d %08lx\n", t, W[t]);
+
+ //see 6.2.2
+ for (int t = 16; t < 64 ; t++)
+ W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];
+
+ unsigned long a = H[0];
+ unsigned long b = H[1];
+ unsigned long c = H[2];
+ unsigned long d = H[3];
+ unsigned long e = H[4];
+ unsigned long f = H[5];
+ unsigned long g = H[6];
+ unsigned long h = H[7];
+
+ for (int t = 0 ; t < 64 ; t++)
+ {
+ //see 4.1.1 for the boolops
+ unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +
+ sha256constants[t] + W[t];
+ unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);
+ h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;
+ //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ // t, a, b, c, d, e, f, g, h);
+ }
+
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+ H[5] += f;
+ H[6] += g;
+ H[7] += h;
+}
+
+
+/**
+ *
+ */
+void Sha256Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 2;
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ size += 8;
+ lenW++;
+ if (lenW >= 64)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Sha256Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 56-byte buf.
+ //use mod, so that we will loop around once if already over 56
+ while (lenW != 56)
+ update((unsigned char)0x00);
+ //append 64-bit size
+ for (int shift = 56 ; shift>=0 ; shift-= 8)
+ {
+ unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);
+ update(ch);
+ }
+
+ // Output hash
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr < 8 ; wordNr++)
+ {
+ ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] ) & 0xff));
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+
+}
+
+
+
+//########################################################################
+//## SHA384
+//########################################################################
+
+/**
+ * SHA-384 and SHA-512 share the same operations and constants
+ */
+
+#undef SHA_SIGMA0
+#undef SHA_SIGMA1
+#undef SHA_sigma0
+#undef SHA_sigma1
+
+#define SHA_Rot64(x,s) (((x) >> s) | ((x) << (64 - s)))
+#define SHA_SIGMA0(x) (SHA_Rot64(x, 28) ^ SHA_Rot64(x, 34) ^ SHA_Rot64(x, 39))
+#define SHA_SIGMA1(x) (SHA_Rot64(x, 14) ^ SHA_Rot64(x, 18) ^ SHA_Rot64(x, 41))
+#define SHA_sigma0(x) (SHA_Rot64(x, 1) ^ SHA_Rot64(x, 8) ^ ((x) >> 7))
+#define SHA_sigma1(x) (SHA_Rot64(x, 19) ^ SHA_Rot64(x, 61) ^ ((x) >> 6))
+
+
+static unsigned long long sha512constants[80] =
+{
+0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+
+
+
+/**
+ *
+ */
+void Sha384Digest::reset()
+{
+ lenW = 0;
+ size = 0;
+
+ // SHA-384 differs from SHA-512 by these constants
+ H[0] = 0xcbbb9d5dc1059ed8ULL;
+ H[1] = 0x629a292a367cd507ULL;
+ H[2] = 0x9159015a3070dd17ULL;
+ H[3] = 0x152fecd8f70e5939ULL;
+ H[4] = 0x67332667ffc00b31ULL;
+ H[5] = 0x8eb44a8768581511ULL;
+ H[6] = 0xdb0c2e0d64f98fa7ULL;
+ H[7] = 0x47b5481dbefa4fa4ULL;
+
+ for (int i = 0 ; i < 80 ; i++)
+ W[i] = 0;
+}
+
+
+
+
+
+void Sha384Digest::hashblock()
+{
+ /*
+ for (int t = 0; t < 16 ; t++)
+ {
+ printf("%2d ", t);
+ pl(W[t]);
+ printf("\n");
+ }
+ */
+
+ //see 6.2.2
+ for (int t = 16; t < 80 ; t++)
+ W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];
+
+ unsigned long long a = H[0];
+ unsigned long long b = H[1];
+ unsigned long long c = H[2];
+ unsigned long long d = H[3];
+ unsigned long long e = H[4];
+ unsigned long long f = H[5];
+ unsigned long long g = H[6];
+ unsigned long long h = H[7];
+
+ for (int t = 0 ; t < 80 ; t++)
+ {
+ //see 4.1.1 for the boolops
+ unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +
+ sha512constants[t] + W[t];
+ unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);
+ h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;
+ }
+
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+ H[5] += f;
+ H[6] += g;
+ H[7] += h;
+}
+
+
+/**
+ *
+ */
+void Sha384Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 3;
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ size += 8;
+ lenW++;
+ if (lenW >= 128)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Sha384Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 112-byte buf.
+ //we will loop around once if already over 112
+ while (lenW != 112)
+ update((unsigned char)0x00);
+
+ //append 128-bit size
+ for (int i = 0 ; i < 8 ; i++) //64 upper bits
+ update((unsigned char)0x00);
+ for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits
+ {
+ unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);
+ update(ch);
+ }
+
+ // Output hash
+ //for SHA-384, we use the left-most 6 64-bit words
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr < 6 ; wordNr++)
+ {
+ ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] ) & 0xff));
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+
+}
+
+
+//########################################################################
+//## SHA512
+//########################################################################
+
+
+
+
+
+/**
+ *
+ */
+void Sha512Digest::reset()
+{
+ lenW = 0;
+ size = 0;
+
+ // Initialize H with the magic constants (see FIPS180 for constants)
+ H[0] = 0x6a09e667f3bcc908ULL;
+ H[1] = 0xbb67ae8584caa73bULL;
+ H[2] = 0x3c6ef372fe94f82bULL;
+ H[3] = 0xa54ff53a5f1d36f1ULL;
+ H[4] = 0x510e527fade682d1ULL;
+ H[5] = 0x9b05688c2b3e6c1fULL;
+ H[6] = 0x1f83d9abfb41bd6bULL;
+ H[7] = 0x5be0cd19137e2179ULL;
+
+ for (int i = 0 ; i < 80 ; i++)
+ W[i] = 0;
+}
+
+
+
+
+
+void Sha512Digest::hashblock()
+{
+ /*
+ for (int t = 0; t < 16 ; t++)
+ {
+ printf("%2d ", t);
+ pl(W[t]);
+ printf("\n");
+ }
+ */
+
+ //see 6.2.2
+ for (int t = 16; t < 80 ; t++)
+ W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];
+
+ unsigned long long a = H[0];
+ unsigned long long b = H[1];
+ unsigned long long c = H[2];
+ unsigned long long d = H[3];
+ unsigned long long e = H[4];
+ unsigned long long f = H[5];
+ unsigned long long g = H[6];
+ unsigned long long h = H[7];
+
+ for (int t = 0 ; t < 80 ; t++)
+ {
+ //see 4.1.1 for the boolops
+ unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +
+ sha512constants[t] + W[t];
+ unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);
+ h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;
+ }
+
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+ H[5] += f;
+ H[6] += g;
+ H[7] += h;
+}
+
+
+/**
+ *
+ */
+void Sha512Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 3;
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ size += 8;
+ lenW++;
+ if (lenW >= 128)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Sha512Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 112-byte buf.
+ //we will loop around once if already over 112
+ while (lenW != 112)
+ update((unsigned char)0x00);
+
+ //append 128-bit size
+ for (int i = 0 ; i < 8 ; i++) //64 upper bits
+ update((unsigned char)0x00);
+ for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits
+ {
+ unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);
+ update(ch);
+ }
+
+ // Output hash
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr < 8 ; wordNr++)
+ {
+ ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));
+ ret.push_back((unsigned char)((H[wordNr] ) & 0xff));
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+
+}
+
+
+
+//########################################################################
+//## M D 5
+//########################################################################
+
+static int md5r[64] =
+{
+ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
+};
+
+static unsigned long md5k[64] =
+{
+0xd76aa478L, 0xe8c7b756L, 0x242070dbL, 0xc1bdceeeL,
+0xf57c0fafL, 0x4787c62aL, 0xa8304613L, 0xfd469501L,
+0x698098d8L, 0x8b44f7afL, 0xffff5bb1L, 0x895cd7beL,
+0x6b901122L, 0xfd987193L, 0xa679438eL, 0x49b40821L,
+0xf61e2562L, 0xc040b340L, 0x265e5a51L, 0xe9b6c7aaL,
+0xd62f105dL, 0x02441453L, 0xd8a1e681L, 0xe7d3fbc8L,
+0x21e1cde6L, 0xc33707d6L, 0xf4d50d87L, 0x455a14edL,
+0xa9e3e905L, 0xfcefa3f8L, 0x676f02d9L, 0x8d2a4c8aL,
+0xfffa3942L, 0x8771f681L, 0x6d9d6122L, 0xfde5380cL,
+0xa4beea44L, 0x4bdecfa9L, 0xf6bb4b60L, 0xbebfbc70L,
+0x289b7ec6L, 0xeaa127faL, 0xd4ef3085L, 0x04881d05L,
+0xd9d4d039L, 0xe6db99e5L, 0x1fa27cf8L, 0xc4ac5665L,
+0xf4292244L, 0x432aff97L, 0xab9423a7L, 0xfc93a039L,
+0x655b59c3L, 0x8f0ccc92L, 0xffeff47dL, 0x85845dd1L,
+0x6fa87e4fL, 0xfe2ce6e0L, 0xa3014314L, 0x4e0811a1L,
+0xf7537e82L, 0xbd3af235L, 0x2ad7d2bbL, 0xeb86d391L
+};
+
+#define MD5_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
+
+
+/**
+ *
+ */
+void Md5Digest::reset()
+{
+ size = 0;
+ lenW = 0;
+
+ hash[0] = 0x67452301L;
+ hash[1] = 0xefcdab89L;
+ hash[2] = 0x98badcfeL;
+ hash[3] = 0x10325476L;
+
+ for (int i = 0 ; i < 64 ; i++)
+ W[i] = 0;
+
+}
+
+
+
+
+
+
+/**
+ *
+ */
+void Md5Digest::hashblock()
+{
+ //for (int t = 0; t < 16 ; t++)
+ // printf("%2d %08lx\n", t, W[t]);
+
+ unsigned long a = hash[0];
+ unsigned long b = hash[1];
+ unsigned long c = hash[2];
+ unsigned long d = hash[3];
+
+ int t = 0;
+ for ( ; t < 16 ; t++)
+ {
+ unsigned long f = d ^ ( b & ( c ^ d));
+ unsigned int g = t;
+ unsigned long temp = d; d = c; c = b;
+ b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);
+ a = temp;
+ //printf("%2d %08lx %08lx %08lx %08lx\n", t, a, b, c, d);
+ }
+ for ( ; t < 32 ; t++)
+ {
+ unsigned long f = c ^ ( d & ( b ^ c));
+ unsigned int g = (5 * t + 1) & 0xf;
+ unsigned long temp = d; d = c; c = b;
+ b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);
+ a = temp;
+ }
+ for ( ; t < 48 ; t++)
+ {
+ unsigned long f = b ^ c ^ d;
+ unsigned int g = (3 * t + 5) & 0xf;
+ unsigned long temp = d; d = c; c = b;
+ b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);
+ a = temp;
+ }
+ for ( ; t < 64 ; t++)
+ {
+ unsigned long f = c ^ (b | ~d);
+ unsigned int g = (7 * t) & 0xf;
+ unsigned long temp = d; d = c; c = b;
+ b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);
+ a = temp;
+ }
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+
+/**
+ *
+ */
+void Md5Digest::update(unsigned char val)
+{
+ int wordNr = lenW >> 2;
+ /*
+ W[wordNr] <<= 8;
+ W[wordNr] |= (unsigned long)val;
+ */
+ W[wordNr] = ( (W[wordNr] >> 8) & 0x00ffffff ) |
+ ( ((unsigned long)val) << 24 );
+ size += 8;
+ lenW++;
+ if (lenW >= 64)
+ {
+ hashblock();
+ lenW = 0;
+ }
+}
+
+
+
+
+/**
+ *
+ */
+std::vector<unsigned char> Md5Digest::finish()
+{
+ //save our size before padding
+ unsigned long long sizeOut = size;
+
+ // Pad with a binary 1 (0x80)
+ update((unsigned char)0x80);
+ //append 0's to make a 56-byte buf.
+ //use mod, so that we will loop around once if already over 56
+ while (lenW != 56)
+ update((unsigned char)0x00);
+
+
+ //Append the length. Lower 32 bits first
+ update( (unsigned char) ((sizeOut ) & 0xff));
+ update( (unsigned char) ((sizeOut>> 8) & 0xff));
+ update( (unsigned char) ((sizeOut>>16) & 0xff));
+ update( (unsigned char) ((sizeOut>>24) & 0xff));
+ update( (unsigned char) ((sizeOut>>32) & 0xff));
+ update( (unsigned char) ((sizeOut>>40) & 0xff));
+ update( (unsigned char) ((sizeOut>>48) & 0xff));
+ update( (unsigned char) ((sizeOut>>56) & 0xff));
+
+ //Output hash
+ std::vector<unsigned char> ret;
+ for (int wordNr = 0 ; wordNr<4 ; wordNr++)
+ {
+ unsigned long w = hash[wordNr];
+ ret.push_back( (unsigned char) ((w ) & 0xff) );
+ ret.push_back( (unsigned char) ((w >> 8) & 0xff) );
+ ret.push_back( (unsigned char) ((w >> 16) & 0xff) );
+ ret.push_back( (unsigned char) ((w >> 24) & 0xff) );
+ }
+
+ // Re-initialize the context (also zeroizes contents)
+ reset();
+
+ return ret;
+}
+
+
+
+
+
+
+//########################################################################
+//## T E S T S
+//########################################################################
+
+/**
+ * Compile this file alone with -DDIGEST_TEST to run the
+ * tests below:
+ * > gcc -DDIGEST_TEST digest.cpp -o digest
+ * > digest
+ */
+
+ #ifdef DIGEST_TEST
+
+
+typedef struct
+{
+ char *msg;
+ char *val;
+} TestPair;
+
+static TestPair md5tests[] =
+{
+ {
+ "",
+ "d41d8cd98f00b204e9800998ecf8427e"
+ },
+ {
+ "a",
+ "0cc175b9c0f1b6a831c399e269772661"
+ },
+ {
+ "abc",
+ "900150983cd24fb0d6963f7d28e17f72"
+ },
+ {
+ "message digest",
+ "f96b697d7cb7938d525a2f31aaf161d0"
+ },
+ {
+ "abcdefghijklmnopqrstuvwxyz",
+ "c3fcd3d76192e4007dfb496cca67e13b"
+ },
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "d174ab98d277d9f5a5611c2c9f419d9f"
+ },
+ {
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "57edf4a22be3c955ac49da2e2107b67a"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+
+
+static TestPair sha1tests[] =
+{
+ {
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static TestPair sha224tests[] =
+{
+ {
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static TestPair sha256tests[] =
+{
+ {
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static TestPair sha384tests[] =
+{
+ {
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
+ "fcc7c71a557e2db966c3e9fa91746039"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static TestPair sha512tests[] =
+{
+ {
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+ "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+
+bool hashTests(Digest &digest, TestPair *tp)
+{
+ for (TestPair *pair = tp ; pair->msg ; pair++)
+ {
+ digest.reset();
+ std::string msg = pair->msg;
+ std::string val = pair->val;
+ digest.append(msg);
+ std::string res = digest.finishHex();
+ printf("### Msg '%s':\n hash '%s'\n exp '%s'\n",
+ msg.c_str(), res.c_str(), val.c_str());
+ if (res != val)
+ {
+ printf("ERROR: Hash mismatch\n");
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool millionATest(Digest &digest, const std::string &exp)
+{
+ digest.reset();
+ for (int i=0 ; i<1000000 ; i++)
+ digest.append('a');
+ std::string res = digest.finishHex();
+ printf("\nHash of 1,000,000 'a'\n calc %s\n exp %s\n",
+ res.c_str(), exp.c_str());
+ if (res != exp)
+ {
+ printf("ERROR: Mismatch.\n");
+ return false;
+ }
+ return true;
+}
+
+static bool doTests()
+{
+ printf("##########################################\n");
+ printf("## MD5\n");
+ printf("##########################################\n");
+ Md5Digest md5;
+ if (!hashTests(md5, md5tests))
+ return false;
+ if (!millionATest(md5, "7707d6ae4e027c70eea2a935c2296f21"))
+ return false;
+ printf("\n\n\n");
+ printf("##########################################\n");
+ printf("## SHA1\n");
+ printf("##########################################\n");
+ Sha1Digest sha1;
+ if (!hashTests(sha1, sha1tests))
+ return false;
+ if (!millionATest(sha1, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"))
+ return false;
+ printf("\n\n\n");
+ printf("##########################################\n");
+ printf("## SHA224\n");
+ printf("##########################################\n");
+ Sha224Digest sha224;
+ if (!hashTests(sha224, sha224tests))
+ return false;
+ if (!millionATest(sha224,
+ "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"))
+ return false;
+ printf("\n\n\n");
+ printf("##########################################\n");
+ printf("## SHA256\n");
+ printf("##########################################\n");
+ Sha256Digest sha256;
+ if (!hashTests(sha256, sha256tests))
+ return false;
+ if (!millionATest(sha256,
+ "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"))
+ return false;
+ printf("\n\n\n");
+ printf("##########################################\n");
+ printf("## SHA384\n");
+ printf("##########################################\n");
+ Sha384Digest sha384;
+ if (!hashTests(sha384, sha384tests))
+ return false;
+ /**/
+ if (!millionATest(sha384,
+ "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"
+ "07b8b3dc38ecc4ebae97ddd87f3d8985"))
+ return false;
+ /**/
+ printf("\n\n\n");
+ printf("##########################################\n");
+ printf("## SHA512\n");
+ printf("##########################################\n");
+ Sha512Digest sha512;
+ if (!hashTests(sha512, sha512tests))
+ return false;
+ if (!millionATest(sha512,
+ "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"))
+ return false;
+ return true;
+}
+
+
+int main(int argc, char **argv)
+{
+ doTests();
+ printf("####### done ########\n");
+ return 0;
+}
+
+
+#endif /* DIGEST_TEST */
+
+//########################################################################
+//## E N D O F F I L E
+//########################################################################
diff --git a/src/dom/util/digest.h b/src/dom/util/digest.h
index 3667a25a912ea98f40e059aebc72fe60e3a234cf..46c60d2a3e5bd1b9b58e71f12103dd34a780aea6 100644 (file)
--- a/src/dom/util/digest.h
+++ b/src/dom/util/digest.h
-#ifndef __DIGEST_H__\r
-#define __DIGEST_H__\r
-/**\r
- * Secure Hashing Tool\r
- * *\r
- * Authors:\r
- * Bob Jamison\r
- *\r
- * Copyright (C) 2006 Bob Jamison\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
- */\r
-\r
-/**\r
- *\r
- * This base class and its subclasses provide an easy API for providing\r
- * several different types of secure hashing functions for whatever use\r
- * a developer might need. This is not intended as a high-performance\r
- * replacement for the fine implementations already available. Rather, it\r
- * is a small and simple (and maybe a bit slow?) tool for moderate common\r
- * hashing requirements, like for communications and authentication.\r
- * \r
- * These hashes are intended to be simple to use. For example:\r
- * Sha256Digest digest;\r
- * digest.append("The quick brown dog");\r
- * std::string result = digest.finishHex();\r
- * \r
- * There are several forms of append() for convenience.\r
- * finish() and finishHex() call reset() for both security and\r
- * to prepare for the next use.\r
- * \r
- */\r
-\r
-#include <vector>\r
-#include <string>\r
-\r
-\r
-/**\r
- * Base class. Do not use this class directly. Rather, use of of the\r
- * subclasses below. \r
- * For all subclasses, overload reset(), update(unsigned char), and finish()\r
- */\r
-class Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Different types of hash algorithms.\r
- */\r
- typedef enum\r
- {\r
- HASH_NONE,\r
- HASH_SHA1,\r
- HASH_SHA224,\r
- HASH_SHA256,\r
- HASH_SHA384,\r
- HASH_SHA512,\r
- HASH_MD5\r
- } HashType;\r
- \r
- /**\r
- * Constructor, with no type\r
- */\r
- Digest() : hashType(HASH_NONE)\r
- { reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Return one of the enumerated hash types above\r
- */\r
- virtual int getType()\r
- { return hashType; }\r
-\r
- /**\r
- * Append a single byte to the hash\r
- */\r
- void append(unsigned char ch)\r
- { update(ch); }\r
-\r
- /**\r
- * Append a string to the hash\r
- */\r
- virtual void append(const std::string &str)\r
- {\r
- for (unsigned int i=0 ; i<str.size() ; i++)\r
- update((unsigned char)str[i]);\r
- }\r
-\r
- /**\r
- * Append a byte buffer to the hash\r
- */\r
- virtual void append(unsigned char *buf, int len)\r
- {\r
- for (int i=0 ; i<len ; i++)\r
- update(buf[i]);\r
- }\r
-\r
- /**\r
- * Append a byte vector to the hash\r
- */\r
- virtual void append(const std::vector<unsigned char> buf)\r
- {\r
- for (unsigned int i=0 ; i<buf.size() ; i++)\r
- update(buf[i]);\r
- }\r
-\r
- /**\r
- * Finish the hash and return a hexidecimal version of the computed\r
- * value \r
- */\r
- virtual std::string finishHex();\r
-\r
- /**\r
- * Initialize the fields of this hash engine to its starting values. \r
- * Overload this in every subclass\r
- */\r
- virtual void reset()\r
- {}\r
-\r
- /**\r
- * Finish the hash and return its computed value \r
- * Overload this in every subclass\r
- */\r
- virtual std::vector<unsigned char> finish()\r
- {\r
- std::vector<unsigned char> ret;\r
- return ret;\r
- }\r
-\r
-protected:\r
-\r
- /**\r
- * Update the hash with a given byte \r
- * Overload this in every subclass\r
- */\r
- virtual void update(unsigned char ch)\r
- {}\r
-\r
- /**\r
- * The enumerated type of the hash\r
- */ \r
- int hashType;\r
-};\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- * SHA-1, \r
- * Section 6.1, SECURE HASH STANDARD\r
- * Federal Information Processing Standards Publication 180-2\r
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf\r
- */\r
-class Sha1Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Sha1Digest()\r
- { hashType = HASH_SHA1; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Sha1Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long H[5];\r
- unsigned long W[80];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- * SHA-224, \r
- * Section 6.1, SECURE HASH STANDARD\r
- * Federal Information Processing Standards Publication 180-2\r
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf\r
- */\r
-class Sha224Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Sha224Digest()\r
- { hashType = HASH_SHA224; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Sha224Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long H[8];\r
- unsigned long W[64];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-\r
-/**\r
- * SHA-256, \r
- * Section 6.1, SECURE HASH STANDARD\r
- * Federal Information Processing Standards Publication 180-2\r
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf\r
- */\r
-class Sha256Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Sha256Digest()\r
- { hashType = HASH_SHA256; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Sha256Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long H[8];\r
- unsigned long W[64];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-/**\r
- * SHA-384,\r
- * Section 6.1, SECURE HASH STANDARD\r
- * Federal Information Processing Standards Publication 180-2\r
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf\r
- */\r
-class Sha384Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Sha384Digest()\r
- { hashType = HASH_SHA384; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Sha384Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long long H[8];\r
- unsigned long long W[80];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-\r
-\r
-/**\r
- * SHA-512, \r
- * Section 6.1, SECURE HASH STANDARD\r
- * Federal Information Processing Standards Publication 180-2\r
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf\r
- */\r
-class Sha512Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Sha512Digest()\r
- { hashType = HASH_SHA512; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Sha512Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long long H[8];\r
- unsigned long long W[80];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- * IETF RFC 1321, MD5 Specification\r
- * http://www.ietf.org/rfc/rfc1321.txt \r
- */\r
-class Md5Digest : public Digest\r
-{\r
-public:\r
-\r
- /**\r
- * Constructor\r
- */\r
- Md5Digest()\r
- { hashType = HASH_MD5; reset(); }\r
-\r
- /**\r
- * Destructor\r
- */\r
- virtual ~Md5Digest()\r
- { reset(); }\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void reset();\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual std::vector<unsigned char> finish();\r
-\r
-protected:\r
-\r
- /**\r
- * Overloaded from Digest\r
- */\r
- virtual void update(unsigned char val);\r
-\r
-private:\r
-\r
- void hashblock();\r
-\r
- unsigned long hash[8];\r
- unsigned long W[64];\r
- unsigned long long size;\r
- int lenW;\r
-\r
-};\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-#endif /* __DIGEST_H__ */\r
-\r
-\r
+#ifndef __DIGEST_H__
+#define __DIGEST_H__
+/**
+ * Secure Hashing Tool
+ * *
+ * Authors:
+ * Bob Jamison
+ *
+ * Copyright (C) 2006 Bob Jamison
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ *
+ * This base class and its subclasses provide an easy API for providing
+ * several different types of secure hashing functions for whatever use
+ * a developer might need. This is not intended as a high-performance
+ * replacement for the fine implementations already available. Rather, it
+ * is a small and simple (and maybe a bit slow?) tool for moderate common
+ * hashing requirements, like for communications and authentication.
+ *
+ * These hashes are intended to be simple to use. For example:
+ * Sha256Digest digest;
+ * digest.append("The quick brown dog");
+ * std::string result = digest.finishHex();
+ *
+ * There are several forms of append() for convenience.
+ * finish() and finishHex() call reset() for both security and
+ * to prepare for the next use.
+ *
+ */
+
+#include <vector>
+#include <string>
+
+
+/**
+ * Base class. Do not use this class directly. Rather, use of of the
+ * subclasses below.
+ * For all subclasses, overload reset(), update(unsigned char), and finish()
+ */
+class Digest
+{
+public:
+
+ /**
+ * Different types of hash algorithms.
+ */
+ typedef enum
+ {
+ HASH_NONE,
+ HASH_SHA1,
+ HASH_SHA224,
+ HASH_SHA256,
+ HASH_SHA384,
+ HASH_SHA512,
+ HASH_MD5
+ } HashType;
+
+ /**
+ * Constructor, with no type
+ */
+ Digest() : hashType(HASH_NONE)
+ { reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Digest()
+ { reset(); }
+
+ /**
+ * Return one of the enumerated hash types above
+ */
+ virtual int getType()
+ { return hashType; }
+
+ /**
+ * Append a single byte to the hash
+ */
+ void append(unsigned char ch)
+ { update(ch); }
+
+ /**
+ * Append a string to the hash
+ */
+ virtual void append(const std::string &str)
+ {
+ for (unsigned int i=0 ; i<str.size() ; i++)
+ update((unsigned char)str[i]);
+ }
+
+ /**
+ * Append a byte buffer to the hash
+ */
+ virtual void append(unsigned char *buf, int len)
+ {
+ for (int i=0 ; i<len ; i++)
+ update(buf[i]);
+ }
+
+ /**
+ * Append a byte vector to the hash
+ */
+ virtual void append(const std::vector<unsigned char> buf)
+ {
+ for (unsigned int i=0 ; i<buf.size() ; i++)
+ update(buf[i]);
+ }
+
+ /**
+ * Finish the hash and return a hexidecimal version of the computed
+ * value
+ */
+ virtual std::string finishHex();
+
+ /**
+ * Initialize the fields of this hash engine to its starting values.
+ * Overload this in every subclass
+ */
+ virtual void reset()
+ {}
+
+ /**
+ * Finish the hash and return its computed value
+ * Overload this in every subclass
+ */
+ virtual std::vector<unsigned char> finish()
+ {
+ std::vector<unsigned char> ret;
+ return ret;
+ }
+
+protected:
+
+ /**
+ * Update the hash with a given byte
+ * Overload this in every subclass
+ */
+ virtual void update(unsigned char ch)
+ {}
+
+ /**
+ * The enumerated type of the hash
+ */
+ int hashType;
+};
+
+
+
+
+
+/**
+ * SHA-1,
+ * Section 6.1, SECURE HASH STANDARD
+ * Federal Information Processing Standards Publication 180-2
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
+ */
+class Sha1Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Sha1Digest()
+ { hashType = HASH_SHA1; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Sha1Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long H[5];
+ unsigned long W[80];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+
+
+
+
+/**
+ * SHA-224,
+ * Section 6.1, SECURE HASH STANDARD
+ * Federal Information Processing Standards Publication 180-2
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
+ */
+class Sha224Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Sha224Digest()
+ { hashType = HASH_SHA224; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Sha224Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long H[8];
+ unsigned long W[64];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+
+/**
+ * SHA-256,
+ * Section 6.1, SECURE HASH STANDARD
+ * Federal Information Processing Standards Publication 180-2
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
+ */
+class Sha256Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Sha256Digest()
+ { hashType = HASH_SHA256; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Sha256Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long H[8];
+ unsigned long W[64];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+/**
+ * SHA-384,
+ * Section 6.1, SECURE HASH STANDARD
+ * Federal Information Processing Standards Publication 180-2
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
+ */
+class Sha384Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Sha384Digest()
+ { hashType = HASH_SHA384; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Sha384Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long long H[8];
+ unsigned long long W[80];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+
+
+/**
+ * SHA-512,
+ * Section 6.1, SECURE HASH STANDARD
+ * Federal Information Processing Standards Publication 180-2
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
+ */
+class Sha512Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Sha512Digest()
+ { hashType = HASH_SHA512; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Sha512Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long long H[8];
+ unsigned long long W[80];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+
+
+
+
+
+
+
+/**
+ * IETF RFC 1321, MD5 Specification
+ * http://www.ietf.org/rfc/rfc1321.txt
+ */
+class Md5Digest : public Digest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Md5Digest()
+ { hashType = HASH_MD5; reset(); }
+
+ /**
+ * Destructor
+ */
+ virtual ~Md5Digest()
+ { reset(); }
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void reset();
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual std::vector<unsigned char> finish();
+
+protected:
+
+ /**
+ * Overloaded from Digest
+ */
+ virtual void update(unsigned char val);
+
+private:
+
+ void hashblock();
+
+ unsigned long hash[8];
+ unsigned long W[64];
+ unsigned long long size;
+ int lenW;
+
+};
+
+
+
+
+
+
+
+
+
+#endif /* __DIGEST_H__ */
+
+
index 9ee1ae32ff1fb98a659fe918839c76cbc332fbc7..88010e686a7e0c1110384c65a3765026a7e20ed9 100644 (file)
-/*\r
- * A quick hack to use the print output to write out a file. This\r
- * then makes 'save as...' PDF.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include <config.h>\r
-#endif\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-#include "cairo-pdf-out.h"\r
-#include <print.h>\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-#include "extension/db.h"\r
-#include "extension/output.h"\r
-#include "display/nr-arena.h"\r
-#include "display/nr-arena-item.h"\r
-#include "sp-path.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-bool\r
-CairoPdfOutput::check (Inkscape::Extension::Extension * module)\r
-{\r
- if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF))\r
- return FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-static unsigned int\r
-pdf_print_document_to_file(SPDocument *doc, gchar const *filename)\r
-{\r
- Inkscape::Extension::Print *mod;\r
- SPPrintContext context;\r
- gchar const *oldconst;\r
- gchar *oldoutput;\r
- unsigned int ret;\r
-\r
- sp_document_ensure_up_to_date(doc);\r
-\r
- mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_CAIRO_PDF);\r
- oldconst = mod->get_param_string("destination");\r
- oldoutput = g_strdup(oldconst);\r
- mod->set_param_string("destination", (gchar *)filename);\r
-\r
-/* Start */\r
- context.module = mod;\r
- /* fixme: This has to go into module constructor somehow */\r
- /* Create new arena */\r
- mod->base = SP_ITEM(sp_document_root(doc));\r
- mod->arena = NRArena::create();\r
- mod->dkey = sp_item_display_key_new(1);\r
- mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);\r
- \r
- /* Print document */\r
- ret = mod->begin(doc);\r
- if (ret) {\r
- sp_item_invoke_print(mod->base, &context);\r
- ret = mod->finish();\r
- }\r
- \r
- /* Release arena */\r
- sp_item_invoke_hide(mod->base, mod->dkey);\r
- mod->base = NULL;\r
- nr_arena_item_unref(mod->root);\r
- mod->root = NULL;\r
- nr_object_unref((NRObject *) mod->arena);\r
- mod->arena = NULL;\r
-/* end */\r
-\r
- mod->set_param_string("destination", oldoutput);\r
- g_free(oldoutput);\r
-\r
- return ret;\r
-}\r
-\r
-\r
-/**\r
- \brief This function calls the print system with the filename\r
- \param mod unused\r
- \param doc Document to be saved\r
- \param uri Filename to save to (probably will end in .pdf)\r
-\r
- The most interesting thing that this function does is just attach\r
- an '>' on the front of the filename. This is the syntax used to\r
- tell the printing system to save to file.\r
-*/\r
-void\r
-CairoPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)\r
-{\r
- Inkscape::Extension::Extension * ext;\r
- unsigned int ret;\r
-\r
- ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF);\r
- if (ext == NULL)\r
- return;\r
-\r
- gchar * final_name;\r
- final_name = g_strdup_printf("> %s", uri);\r
- ret = pdf_print_document_to_file(doc, final_name);\r
- g_free(final_name);\r
- \r
- if (!ret)\r
- throw Inkscape::Extension::Output::save_failed();\r
-\r
- return;\r
-}\r
-\r
-/**\r
- \brief A function allocate a copy of this function.\r
-\r
- This is the definition of PDF out. This function just\r
- calls the extension system with the memory allocated XML that\r
- describes the data.\r
-*/\r
-void\r
-CairoPdfOutput::init (void)\r
-{\r
- Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>Cairo PDF Output</name>\n"\r
- "<id>org.inkscape.output.pdf.cairo</id>\n"\r
- "<output>\n"\r
- "<extension>.pdf</extension>\n"\r
- "<mimetype>application/pdf</mimetype>\n"\r
- "<filetypename>Cairo PDF (*.pdf)</filetypename>\n"\r
- "<filetypetooltip>PDF File</filetypetooltip>\n"\r
- "</output>\n"\r
- "</inkscape-extension>", new CairoPdfOutput());\r
-\r
- return;\r
-}\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
+/*
+ * A quick hack to use the print output to write out a file. This
+ * then makes 'save as...' PDF.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CAIRO_PDF
+
+#include "cairo-pdf-out.h"
+#include <print.h>
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+#include "sp-path.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+bool
+CairoPdfOutput::check (Inkscape::Extension::Extension * module)
+{
+ if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static unsigned int
+pdf_print_document_to_file(SPDocument *doc, gchar const *filename)
+{
+ Inkscape::Extension::Print *mod;
+ SPPrintContext context;
+ gchar const *oldconst;
+ gchar *oldoutput;
+ unsigned int ret;
+
+ sp_document_ensure_up_to_date(doc);
+
+ mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_CAIRO_PDF);
+ oldconst = mod->get_param_string("destination");
+ oldoutput = g_strdup(oldconst);
+ mod->set_param_string("destination", (gchar *)filename);
+
+/* Start */
+ context.module = mod;
+ /* fixme: This has to go into module constructor somehow */
+ /* Create new arena */
+ mod->base = SP_ITEM(sp_document_root(doc));
+ mod->arena = NRArena::create();
+ mod->dkey = sp_item_display_key_new(1);
+ mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
+
+ /* Print document */
+ ret = mod->begin(doc);
+ if (ret) {
+ sp_item_invoke_print(mod->base, &context);
+ ret = mod->finish();
+ }
+
+ /* Release arena */
+ sp_item_invoke_hide(mod->base, mod->dkey);
+ mod->base = NULL;
+ nr_arena_item_unref(mod->root);
+ mod->root = NULL;
+ nr_object_unref((NRObject *) mod->arena);
+ mod->arena = NULL;
+/* end */
+
+ mod->set_param_string("destination", oldoutput);
+ g_free(oldoutput);
+
+ return ret;
+}
+
+
+/**
+ \brief This function calls the print system with the filename
+ \param mod unused
+ \param doc Document to be saved
+ \param uri Filename to save to (probably will end in .pdf)
+
+ The most interesting thing that this function does is just attach
+ an '>' on the front of the filename. This is the syntax used to
+ tell the printing system to save to file.
+*/
+void
+CairoPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+{
+ Inkscape::Extension::Extension * ext;
+ unsigned int ret;
+
+ ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF);
+ if (ext == NULL)
+ return;
+
+ gchar * final_name;
+ final_name = g_strdup_printf("> %s", uri);
+ ret = pdf_print_document_to_file(doc, final_name);
+ g_free(final_name);
+
+ if (!ret)
+ throw Inkscape::Extension::Output::save_failed();
+
+ return;
+}
+
+/**
+ \brief A function allocate a copy of this function.
+
+ This is the definition of PDF out. This function just
+ calls the extension system with the memory allocated XML that
+ describes the data.
+*/
+void
+CairoPdfOutput::init (void)
+{
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>Cairo PDF Output</name>\n"
+ "<id>org.inkscape.output.pdf.cairo</id>\n"
+ "<output>\n"
+ "<extension>.pdf</extension>\n"
+ "<mimetype>application/pdf</mimetype>\n"
+ "<filetypename>Cairo PDF (*.pdf)</filetypename>\n"
+ "<filetypetooltip>PDF File</filetypetooltip>\n"
+ "</output>\n"
+ "</inkscape-extension>", new CairoPdfOutput());
+
+ return;
+}
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
index f0e67f165d4ca0a8c9ddd7524b53a8f5520e05f7..42cd9365c2d4545a0a2d3a86dc30c15c083ed2a0 100644 (file)
-/*\r
- * A quick hack to use the print output to write out a file. This\r
- * then makes 'save as...' PDF.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef EXTENSION_INTERNAL_CAIRO_PDF_OUT_H\r
-#define EXTENSION_INTERNAL_CAIRO_PDF_OUT_H\r
-\r
-#include "extension/implementation/implementation.h"\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class CairoPdfOutput : Inkscape::Extension::Implementation::Implementation {\r
-\r
-public:\r
- bool check(Inkscape::Extension::Extension *module);\r
- void save(Inkscape::Extension::Output *mod,\r
- SPDocument *doc,\r
- gchar const *uri);\r
- static void init();\r
-};\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
-\r
-#endif /* !EXTENSION_INTERNAL_CAIRO_PDF_OUT_H */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+/*
+ * A quick hack to use the print output to write out a file. This
+ * then makes 'save as...' PDF.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef EXTENSION_INTERNAL_CAIRO_PDF_OUT_H
+#define EXTENSION_INTERNAL_CAIRO_PDF_OUT_H
+
+#include "extension/implementation/implementation.h"
+
+#ifdef HAVE_CAIRO_PDF
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class CairoPdfOutput : Inkscape::Extension::Implementation::Implementation {
+
+public:
+ bool check(Inkscape::Extension::Extension *module);
+ void save(Inkscape::Extension::Output *mod,
+ SPDocument *doc,
+ gchar const *uri);
+ static void init();
+};
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
+
+#endif /* !EXTENSION_INTERNAL_CAIRO_PDF_OUT_H */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index f34a90b226960874617b12544e060ef21f47c644..6fd45d0d5a7afbcb31bda2f7eb90bdcfadad77c8 100644 (file)
-/*\r
- * A quick hack to use the Cairo renderer to write out a file. This\r
- * then makes 'save as...' PNG.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include <config.h>\r
-#endif\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-#include "cairo-png-out.h"\r
-#include "cairo-render-context.h"\r
-#include "cairo-renderer.h"\r
-#include <print.h>\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-#include "extension/db.h"\r
-#include "extension/output.h"\r
-#include "display/nr-arena.h"\r
-#include "display/nr-arena-item.h"\r
-\r
-#include <libnr/n-art-bpath.h>\r
-\r
-#include "display/curve.h"\r
-#include "display/canvas-bpath.h"\r
-#include "sp-item.h"\r
-#include "style.h"\r
-#include "sp-root.h"\r
-#include "sp-shape.h"\r
-\r
-#include "io/sys.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-bool\r
-CairoRendererOutput::check (Inkscape::Extension::Extension * module)\r
-{\r
- return TRUE;\r
-}\r
-\r
-static bool\r
-png_render_document_to_file(SPDocument *doc, gchar const *filename)\r
-{\r
- CairoRenderer *renderer;\r
- CairoRenderContext *ctx;\r
-\r
- sp_document_ensure_up_to_date(doc);\r
-\r
-/* Start */\r
- /* Create new arena */\r
- SPItem *base = SP_ITEM(sp_document_root(doc));\r
- NRArena *arena = NRArena::create();\r
- unsigned dkey = sp_item_display_key_new(1);\r
- NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);\r
- \r
- /* Create renderer and context */\r
- renderer = new CairoRenderer();\r
- ctx = renderer->createContext();\r
-\r
- /* Render document */\r
- bool ret = renderer->setupDocument(ctx, doc);\r
- if (ret) {\r
- renderer->renderItem(ctx, base);\r
- ctx->saveAsPng(filename);\r
- ret = ctx->finish();\r
- }\r
- renderer->destroyContext(ctx);\r
-\r
- /* Release arena */\r
- sp_item_invoke_hide(base, dkey);\r
- nr_arena_item_unref(root);\r
- nr_object_unref((NRObject *) arena);\r
-/* end */\r
- delete renderer;\r
-\r
- return ret;\r
-}\r
-\r
-\r
-/**\r
- \brief This function calls the output module with the filename\r
- \param mod unused\r
- \param doc Document to be saved\r
- \param uri Filename to save to (probably will end in .png)\r
-*/\r
-void\r
-CairoRendererOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)\r
-{\r
- if (!png_render_document_to_file(doc, uri))\r
- throw Inkscape::Extension::Output::save_failed();\r
-\r
- return;\r
-}\r
-\r
-/**\r
- \brief A function allocate a copy of this function.\r
-\r
- This is the definition of Cairo PNG out. This function just\r
- calls the extension system with the memory allocated XML that\r
- describes the data.\r
-*/\r
-void\r
-CairoRendererOutput::init (void)\r
-{\r
- Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>Cairo PNG Output</name>\n"\r
- "<id>org.inkscape.output.png.cairo</id>\n"\r
- "<output>\n"\r
- "<extension>.png</extension>\n"\r
- "<mimetype>image/png</mimetype>\n"\r
- "<filetypename>Cairo PNG (*.png)</filetypename>\n"\r
- "<filetypetooltip>PNG File</filetypetooltip>\n"\r
- "</output>\n"\r
- "</inkscape-extension>", new CairoRendererOutput());\r
-\r
- return;\r
-}\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
+/*
+ * A quick hack to use the Cairo renderer to write out a file. This
+ * then makes 'save as...' PNG.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CAIRO_PDF
+
+#include "cairo-png-out.h"
+#include "cairo-render-context.h"
+#include "cairo-renderer.h"
+#include <print.h>
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+
+#include <libnr/n-art-bpath.h>
+
+#include "display/curve.h"
+#include "display/canvas-bpath.h"
+#include "sp-item.h"
+#include "style.h"
+#include "sp-root.h"
+#include "sp-shape.h"
+
+#include "io/sys.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+bool
+CairoRendererOutput::check (Inkscape::Extension::Extension * module)
+{
+ return TRUE;
+}
+
+static bool
+png_render_document_to_file(SPDocument *doc, gchar const *filename)
+{
+ CairoRenderer *renderer;
+ CairoRenderContext *ctx;
+
+ sp_document_ensure_up_to_date(doc);
+
+/* Start */
+ /* Create new arena */
+ SPItem *base = SP_ITEM(sp_document_root(doc));
+ NRArena *arena = NRArena::create();
+ unsigned dkey = sp_item_display_key_new(1);
+ NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
+
+ /* Create renderer and context */
+ renderer = new CairoRenderer();
+ ctx = renderer->createContext();
+
+ /* Render document */
+ bool ret = renderer->setupDocument(ctx, doc);
+ if (ret) {
+ renderer->renderItem(ctx, base);
+ ctx->saveAsPng(filename);
+ ret = ctx->finish();
+ }
+ renderer->destroyContext(ctx);
+
+ /* Release arena */
+ sp_item_invoke_hide(base, dkey);
+ nr_arena_item_unref(root);
+ nr_object_unref((NRObject *) arena);
+/* end */
+ delete renderer;
+
+ return ret;
+}
+
+
+/**
+ \brief This function calls the output module with the filename
+ \param mod unused
+ \param doc Document to be saved
+ \param uri Filename to save to (probably will end in .png)
+*/
+void
+CairoRendererOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+{
+ if (!png_render_document_to_file(doc, uri))
+ throw Inkscape::Extension::Output::save_failed();
+
+ return;
+}
+
+/**
+ \brief A function allocate a copy of this function.
+
+ This is the definition of Cairo PNG out. This function just
+ calls the extension system with the memory allocated XML that
+ describes the data.
+*/
+void
+CairoRendererOutput::init (void)
+{
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>Cairo PNG Output</name>\n"
+ "<id>org.inkscape.output.png.cairo</id>\n"
+ "<output>\n"
+ "<extension>.png</extension>\n"
+ "<mimetype>image/png</mimetype>\n"
+ "<filetypename>Cairo PNG (*.png)</filetypename>\n"
+ "<filetypetooltip>PNG File</filetypetooltip>\n"
+ "</output>\n"
+ "</inkscape-extension>", new CairoRendererOutput());
+
+ return;
+}
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
index 207786c88c765ce4c57eb612052299cde76a2eba..625c53ffcf36dc91f9578cef489e0e26ed56f43b 100644 (file)
-/*\r
- * A quick hack to use the print output to write out a file. This\r
- * then makes 'save as...' PNG.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef EXTENSION_INTERNAL_CAIRO_PNG_OUT_H\r
-#define EXTENSION_INTERNAL_CAIRO_PNG_OUT_H\r
-\r
-#include "extension/implementation/implementation.h"\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class CairoRendererOutput : Inkscape::Extension::Implementation::Implementation {\r
-\r
-public:\r
- bool check(Inkscape::Extension::Extension *module);\r
- void save(Inkscape::Extension::Output *mod,\r
- SPDocument *doc,\r
- gchar const *uri);\r
- static void init();\r
-};\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
-\r
-#endif /* !EXTENSION_INTERNAL_CAIRO_PNG_OUT_H */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+/*
+ * A quick hack to use the print output to write out a file. This
+ * then makes 'save as...' PNG.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef EXTENSION_INTERNAL_CAIRO_PNG_OUT_H
+#define EXTENSION_INTERNAL_CAIRO_PNG_OUT_H
+
+#include "extension/implementation/implementation.h"
+
+#ifdef HAVE_CAIRO_PDF
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class CairoRendererOutput : Inkscape::Extension::Implementation::Implementation {
+
+public:
+ bool check(Inkscape::Extension::Extension *module);
+ void save(Inkscape::Extension::Output *mod,
+ SPDocument *doc,
+ gchar const *uri);
+ static void init();
+};
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
+
+#endif /* !EXTENSION_INTERNAL_CAIRO_PNG_OUT_H */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp
index 5d27656609ab8bcfe34acf8261d1ddfc425691e3..82b736ad26f58b6abe82b5f4409569e9af55e483 100644 (file)
-/*\r
- * A quick hack to use the Cairo renderer to write out a file. This\r
- * then makes 'save as...' PDF.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include <config.h>\r
-#endif\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-#include "cairo-renderer-pdf-out.h"\r
-#include "cairo-render-context.h"\r
-#include "cairo-renderer.h"\r
-#include <print.h>\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-#include "extension/db.h"\r
-#include "extension/output.h"\r
-#include "display/nr-arena.h"\r
-#include "display/nr-arena-item.h"\r
-\r
-#include <libnr/n-art-bpath.h>\r
-\r
-#include "display/curve.h"\r
-#include "display/canvas-bpath.h"\r
-#include "sp-item.h"\r
-#include "sp-root.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-bool\r
-CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)\r
-{\r
- return TRUE;\r
-}\r
-\r
-static bool\r
-pdf_render_document_to_file(SPDocument *doc, gchar const *filename)\r
-{\r
- sp_document_ensure_up_to_date(doc);\r
-\r
-/* Start */\r
- /* Create new arena */\r
- SPItem *base = SP_ITEM(sp_document_root(doc));\r
- NRArena *arena = NRArena::create();\r
- unsigned dkey = sp_item_display_key_new(1);\r
- NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);\r
- \r
- /* Create renderer and context */\r
- CairoRenderer *renderer = new CairoRenderer();\r
- CairoRenderContext *ctx = renderer->createContext();\r
- ctx->setPdfTarget (filename);\r
- bool ret = renderer->setupDocument(ctx, doc);\r
- if (ret) {\r
- renderer->renderItem(ctx, base);\r
- ret = ctx->finish();\r
- }\r
-\r
- /* Release arena */\r
- sp_item_invoke_hide(base, dkey);\r
- nr_arena_item_unref(root);\r
- nr_object_unref((NRObject *) arena);\r
-/* end */\r
- renderer->destroyContext(ctx);\r
- delete renderer;\r
-\r
- return ret;\r
-}\r
-\r
-\r
-/**\r
- \brief This function calls the output module with the filename\r
- \param mod unused\r
- \param doc Document to be saved\r
- \param uri Filename to save to (probably will end in .png)\r
-\r
- The most interesting thing that this function does is just attach\r
- an '>' on the front of the filename. This is the syntax used to\r
- tell the printing system to save to file.\r
-*/\r
-void\r
-CairoRendererPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)\r
-{\r
- gchar * final_name;\r
- final_name = g_strdup_printf("> %s", uri);\r
- bool ret = pdf_render_document_to_file(doc, final_name);\r
- g_free(final_name);\r
-\r
- if (!ret)\r
- throw Inkscape::Extension::Output::save_failed();\r
-\r
- return;\r
-}\r
-\r
-/**\r
- \brief A function allocate a copy of this function.\r
-\r
- This is the definition of Cairo PDF out. This function just\r
- calls the extension system with the memory allocated XML that\r
- describes the data.\r
-*/\r
-void\r
-CairoRendererPdfOutput::init (void)\r
-{\r
- Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>Cairo PDF Output (experimental)</name>\n"\r
- "<id>org.inkscape.output.pdf.cairorenderer</id>\n"\r
- "<output>\n"\r
- "<extension>.pdf</extension>\n"\r
- "<mimetype>application/pdf</mimetype>\n"\r
- "<filetypename>Cairo PDF experimental (*.pdf)</filetypename>\n"\r
- "<filetypetooltip>PDF File</filetypetooltip>\n"\r
- "</output>\n"\r
- "</inkscape-extension>", new CairoRendererPdfOutput());\r
-\r
- return;\r
-}\r
-\r
-} } } /* namespace Inkscape, Extension, Internal */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
+/*
+ * A quick hack to use the Cairo renderer to write out a file. This
+ * then makes 'save as...' PDF.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CAIRO_PDF
+
+#include "cairo-renderer-pdf-out.h"
+#include "cairo-render-context.h"
+#include "cairo-renderer.h"
+#include <print.h>
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+
+#include <libnr/n-art-bpath.h>
+
+#include "display/curve.h"
+#include "display/canvas-bpath.h"
+#include "sp-item.h"
+#include "sp-root.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+bool
+CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)
+{
+ return TRUE;
+}
+
+static bool
+pdf_render_document_to_file(SPDocument *doc, gchar const *filename)
+{
+ sp_document_ensure_up_to_date(doc);
+
+/* Start */
+ /* Create new arena */
+ SPItem *base = SP_ITEM(sp_document_root(doc));
+ NRArena *arena = NRArena::create();
+ unsigned dkey = sp_item_display_key_new(1);
+ NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
+
+ /* Create renderer and context */
+ CairoRenderer *renderer = new CairoRenderer();
+ CairoRenderContext *ctx = renderer->createContext();
+ ctx->setPdfTarget (filename);
+ bool ret = renderer->setupDocument(ctx, doc);
+ if (ret) {
+ renderer->renderItem(ctx, base);
+ ret = ctx->finish();
+ }
+
+ /* Release arena */
+ sp_item_invoke_hide(base, dkey);
+ nr_arena_item_unref(root);
+ nr_object_unref((NRObject *) arena);
+/* end */
+ renderer->destroyContext(ctx);
+ delete renderer;
+
+ return ret;
+}
+
+
+/**
+ \brief This function calls the output module with the filename
+ \param mod unused
+ \param doc Document to be saved
+ \param uri Filename to save to (probably will end in .png)
+
+ The most interesting thing that this function does is just attach
+ an '>' on the front of the filename. This is the syntax used to
+ tell the printing system to save to file.
+*/
+void
+CairoRendererPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+{
+ gchar * final_name;
+ final_name = g_strdup_printf("> %s", uri);
+ bool ret = pdf_render_document_to_file(doc, final_name);
+ g_free(final_name);
+
+ if (!ret)
+ throw Inkscape::Extension::Output::save_failed();
+
+ return;
+}
+
+/**
+ \brief A function allocate a copy of this function.
+
+ This is the definition of Cairo PDF out. This function just
+ calls the extension system with the memory allocated XML that
+ describes the data.
+*/
+void
+CairoRendererPdfOutput::init (void)
+{
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>Cairo PDF Output (experimental)</name>\n"
+ "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
+ "<output>\n"
+ "<extension>.pdf</extension>\n"
+ "<mimetype>application/pdf</mimetype>\n"
+ "<filetypename>Cairo PDF experimental (*.pdf)</filetypename>\n"
+ "<filetypetooltip>PDF File</filetypetooltip>\n"
+ "</output>\n"
+ "</inkscape-extension>", new CairoRendererPdfOutput());
+
+ return;
+}
+
+} } } /* namespace Inkscape, Extension, Internal */
+
+#endif /* HAVE_CAIRO_PDF */
diff --git a/src/extension/internal/cairo-renderer-pdf-out.h b/src/extension/internal/cairo-renderer-pdf-out.h
index d7d5a6681349e76ead8effbba4ec8cd11e44d062..1c18519a0a63ec135330e924b96c167872749874 100644 (file)
-/*\r
- * A quick hack to use the Cairo renderer to write out a file. This\r
- * then makes 'save as...' PDF.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H\r
-#define EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H\r
-\r
-#include "extension/implementation/implementation.h"\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class CairoRendererPdfOutput : Inkscape::Extension::Implementation::Implementation {\r
-\r
-public:\r
- bool check(Inkscape::Extension::Extension *module);\r
- void save(Inkscape::Extension::Output *mod,\r
- SPDocument *doc,\r
- gchar const *uri);\r
- static void init();\r
-};\r
-\r
-} } } /* namespace Inkscape, Extension, Internal */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
-\r
-#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+/*
+ * A quick hack to use the Cairo renderer to write out a file. This
+ * then makes 'save as...' PDF.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H
+#define EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H
+
+#include "extension/implementation/implementation.h"
+
+#ifdef HAVE_CAIRO_PDF
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class CairoRendererPdfOutput : Inkscape::Extension::Implementation::Implementation {
+
+public:
+ bool check(Inkscape::Extension::Extension *module);
+ void save(Inkscape::Extension::Output *mod,
+ SPDocument *doc,
+ gchar const *uri);
+ static void init();
+};
+
+} } } /* namespace Inkscape, Extension, Internal */
+
+#endif /* HAVE_CAIRO_PDF */
+
+#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_PDF_OUT_H */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp
index a39d1fb1dffe6dcf14baaf0b8bd8d96c85414560..b9d65f50cd80409f11549dc44f2dac777b70dd7b 100644 (file)
-/** \file\r
- * Enhanced Metafile Input and Output.\r
- */\r
-/*\r
- * Authors:\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-/*\r
- * References:\r
- * - How to Create & Play Enhanced Metafiles in Win32\r
- * http://support.microsoft.com/kb/q145999/\r
- * - INFO: Windows Metafile Functions & Aldus Placeable Metafiles\r
- * http://support.microsoft.com/kb/q66949/\r
- * - Metafile Functions\r
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp\r
- * - Metafile Structures\r
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp\r
- */\r
-\r
-#ifdef WIN32\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-#include "win32.h"\r
-#include "emf-win32-print.h"\r
-#include "emf-win32-inout.h"\r
-#include "inkscape.h"\r
-#include "sp-path.h"\r
-#include "style.h"\r
-#include "color.h"\r
-#include "display/curve.h"\r
-#include "libnr/n-art-bpath.h"\r
-#include "libnr/nr-point-matrix-ops.h"\r
-#include "gtk/gtk.h"\r
-#include "print.h"\r
-#include "glibmm/i18n.h"\r
-#include "extension/extension.h"\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-#include "extension/db.h"\r
-#include "extension/output.h"\r
-#include "document.h"\r
-#include "display/nr-arena.h"\r
-#include "display/nr-arena-item.h"\r
-\r
-#include "libnr/nr-rect.h"\r
-#include "libnr/nr-matrix.h"\r
-#include "libnr/nr-pixblock.h"\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#include <vector>\r
-#include <string>\r
-\r
-#include "io/sys.h"\r
-\r
-#include "unit-constants.h"\r
-\r
-#include "clear-n_.h"\r
-\r
-\r
-#define PRINT_EMF_WIN32 "org.inkscape.print.emf.win32"\r
-\r
-#ifndef PS_JOIN_MASK\r
-#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)\r
-#endif\r
-\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-\r
-EmfWin32::EmfWin32 (void) // The null constructor\r
-{\r
- return;\r
-}\r
-\r
-\r
-EmfWin32::~EmfWin32 (void) //The destructor\r
-{\r
- return;\r
-}\r
-\r
-\r
-bool\r
-EmfWin32::check (Inkscape::Extension::Extension * module)\r
-{\r
- if (NULL == Inkscape::Extension::db.get(PRINT_EMF_WIN32))\r
- return FALSE;\r
- return TRUE;\r
-}\r
-\r
-\r
-static void\r
-emf_print_document_to_file(SPDocument *doc, gchar const *filename)\r
-{\r
- Inkscape::Extension::Print *mod;\r
- SPPrintContext context;\r
- gchar const *oldconst;\r
- gchar *oldoutput;\r
- unsigned int ret;\r
-\r
- sp_document_ensure_up_to_date(doc);\r
-\r
- mod = Inkscape::Extension::get_print(PRINT_EMF_WIN32);\r
- oldconst = mod->get_param_string("destination");\r
- oldoutput = g_strdup(oldconst);\r
- mod->set_param_string("destination", (gchar *)filename);\r
-\r
-/* Start */\r
- context.module = mod;\r
- /* fixme: This has to go into module constructor somehow */\r
- /* Create new arena */\r
- mod->base = SP_ITEM(sp_document_root(doc));\r
- mod->arena = NRArena::create();\r
- mod->dkey = sp_item_display_key_new(1);\r
- mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);\r
- /* Print document */\r
- ret = mod->begin(doc);\r
- if (ret) {\r
- throw Inkscape::Extension::Output::save_failed();\r
- }\r
- sp_item_invoke_print(mod->base, &context);\r
- ret = mod->finish();\r
- /* Release arena */\r
- sp_item_invoke_hide(mod->base, mod->dkey);\r
- mod->base = NULL;\r
- nr_arena_item_unref(mod->root);\r
- mod->root = NULL;\r
- nr_object_unref((NRObject *) mod->arena);\r
- mod->arena = NULL;\r
-/* end */\r
-\r
- mod->set_param_string("destination", oldoutput);\r
- g_free(oldoutput);\r
-\r
- return;\r
-}\r
-\r
-\r
-void\r
-EmfWin32::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)\r
-{\r
- Inkscape::Extension::Extension * ext;\r
-\r
- ext = Inkscape::Extension::db.get(PRINT_EMF_WIN32);\r
- if (ext == NULL)\r
- return;\r
-\r
-// bool old_textToPath = ext->get_param_bool("textToPath");\r
-// bool new_val = mod->get_param_bool("textToPath");\r
-// ext->set_param_bool("textToPath", new_val);\r
-\r
- gchar * final_name;\r
- final_name = g_strdup_printf("%s", uri);\r
- emf_print_document_to_file(doc, final_name);\r
- g_free(final_name);\r
-\r
-// ext->set_param_bool("textToPath", old_textToPath);\r
-\r
- return;\r
-}\r
-\r
-\r
-\r
-typedef struct {\r
- int type;\r
- ENHMETARECORD *lpEMFR;\r
-} EMF_OBJECT, *PEMF_OBJECT;\r
-\r
-typedef struct emf_callback_data {\r
- Glib::ustring *outsvg;\r
- Glib::ustring *path;\r
- struct SPStyle style;\r
- bool stroke_set;\r
- bool fill_set;\r
- double xDPI, yDPI;\r
-\r
- SIZEL sizeWnd;\r
- SIZEL sizeView;\r
- float PixelsX;\r
- float PixelsY;\r
- float MMX;\r
- float MMY;\r
- float dwInchesX;\r
- float dwInchesY;\r
- POINTL winorg;\r
- POINTL vieworg;\r
- double ScaleX, ScaleY;\r
-\r
- int n_obj;\r
- PEMF_OBJECT emf_obj;\r
-} EMF_CALLBACK_DATA, *PEMF_CALLBACK_DATA;\r
-\r
-\r
-static void\r
-output_style(PEMF_CALLBACK_DATA d, int iType)\r
-{\r
- SVGOStringStream tmp_style;\r
- char tmp[1024] = {0};\r
-\r
- *(d->outsvg) += "\n\tstyle=\"";\r
- if (iType == EMR_STROKEPATH || !d->fill_set) {\r
- tmp_style << "fill:none;";\r
- } else {\r
- float rgb[3];\r
- sp_color_get_rgb_floatv( &(d->style.fill.value.color), rgb );\r
- snprintf(tmp, 1023,\r
- "fill:#%02x%02x%02x;",\r
- SP_COLOR_F_TO_U(rgb[0]),\r
- SP_COLOR_F_TO_U(rgb[1]),\r
- SP_COLOR_F_TO_U(rgb[2]));\r
- tmp_style << tmp;\r
- snprintf(tmp, 1023,\r
- "fill-rule:%s;",\r
- d->style.fill_rule.value != 0 ? "evenodd" : "nonzero");\r
- tmp_style << tmp;\r
- tmp_style << "fill-opacity:1;";\r
- }\r
-\r
- if (iType == EMR_FILLPATH || !d->stroke_set) {\r
- tmp_style << "stroke:none;";\r
- } else {\r
- float rgb[3];\r
- sp_color_get_rgb_floatv(&(d->style.stroke.value.color), rgb);\r
- snprintf(tmp, 1023,\r
- "stroke:#%02x%02x%02x;",\r
- SP_COLOR_F_TO_U(rgb[0]),\r
- SP_COLOR_F_TO_U(rgb[1]),\r
- SP_COLOR_F_TO_U(rgb[2]));\r
- tmp_style << tmp;\r
-\r
- tmp_style << "stroke-width:" <<\r
- MAX( 0.001, d->style.stroke_width.value ) << "px;";\r
-\r
- tmp_style << "stroke-linejoin:" <<\r
- (d->style.stroke_linejoin.computed == 0 ? "miter" :\r
- d->style.stroke_linejoin.computed == 1 ? "round" :\r
- d->style.stroke_linejoin.computed == 2 ? "bevel" :\r
- "unknown") << ";";\r
-\r
- if (d->style.stroke_linejoin.computed == 0) {\r
- tmp_style << "stroke-miterlimit:" <<\r
- MAX( 0.01, d->style.stroke_miterlimit.value ) << ";";\r
- }\r
-\r
- if (d->style.stroke_dasharray_set &&\r
- d->style.stroke_dash.n_dash && d->style.stroke_dash.dash)\r
- {\r
- tmp_style << "stroke-dasharray:";\r
- for (int i=0; i<d->style.stroke_dash.n_dash; i++) {\r
- if (i)\r
- tmp_style << ",";\r
- tmp_style << d->style.stroke_dash.dash[i];\r
- }\r
- tmp_style << ";";\r
- tmp_style << "stroke-dashoffset:0;";\r
- } else {\r
- tmp_style << "stroke-dasharray:none;";\r
- }\r
- tmp_style << "stroke-opacity:1;";\r
- }\r
- tmp_style << "\" ";\r
-\r
- *(d->outsvg) += tmp_style.str().c_str();\r
-}\r
-\r
-\r
-static double\r
-pix_x_to_point(PEMF_CALLBACK_DATA d, double px)\r
-{\r
- double tmp = px - d->winorg.x;\r
- tmp *= (double) PX_PER_IN / d->ScaleX;\r
- tmp += d->vieworg.x;\r
- return tmp;\r
-}\r
-\r
-\r
-static double\r
-pix_y_to_point(PEMF_CALLBACK_DATA d, double px)\r
-{\r
- double tmp = px - d->winorg.y;\r
- tmp *= (double) PX_PER_IN / d->ScaleY;\r
- tmp += d->vieworg.y;\r
- return tmp;\r
-}\r
-\r
-\r
-static double\r
-pix_size_to_point(PEMF_CALLBACK_DATA d, double px)\r
-{\r
- double tmp = px;\r
- tmp *= (double) PX_PER_IN / d->ScaleX;\r
- return tmp;\r
-}\r
-\r
-\r
-static void\r
-select_pen(PEMF_CALLBACK_DATA d, int index)\r
-{\r
- PEMRCREATEPEN pEmr = NULL;\r
-\r
- if (index >= 0 && index < d->n_obj)\r
- pEmr = (PEMRCREATEPEN) d->emf_obj[index].lpEMFR;\r
-\r
- if (!pEmr)\r
- return;\r
-\r
- switch (pEmr->lopn.lopnStyle) {\r
- default:\r
- {\r
- d->style.stroke_dasharray_set = 0;\r
- break;\r
- }\r
- }\r
-\r
- if (pEmr->lopn.lopnWidth.x) {\r
- d->style.stroke_width.value = pix_size_to_point( d, pEmr->lopn.lopnWidth.x );\r
- } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?)\r
- d->style.stroke_width.value = 1.0;\r
- }\r
-\r
- double r, g, b;\r
- r = SP_COLOR_U_TO_F( GetRValue(pEmr->lopn.lopnColor) );\r
- g = SP_COLOR_U_TO_F( GetGValue(pEmr->lopn.lopnColor) );\r
- b = SP_COLOR_U_TO_F( GetBValue(pEmr->lopn.lopnColor) );\r
- sp_color_set_rgb_float( &(d->style.stroke.value.color), r,g,b );\r
-\r
- d->style.stroke_linejoin.computed = 1;\r
-\r
- d->stroke_set = true;\r
-}\r
-\r
-\r
-static void\r
-select_extpen(PEMF_CALLBACK_DATA d, int index)\r
-{\r
- PEMREXTCREATEPEN pEmr = NULL;\r
-\r
- if (index >= 0 && index < d->n_obj)\r
- pEmr = (PEMREXTCREATEPEN) d->emf_obj[index].lpEMFR;\r
-\r
- if (!pEmr)\r
- return;\r
-\r
- switch (pEmr->elp.elpPenStyle & PS_STYLE_MASK) {\r
- case PS_USERSTYLE:\r
- {\r
- if (pEmr->elp.elpNumEntries) {\r
- d->style.stroke_dash.n_dash = pEmr->elp.elpNumEntries;\r
- if (d->style.stroke_dash.dash)\r
- delete[] d->style.stroke_dash.dash;\r
- d->style.stroke_dash.dash = new double[pEmr->elp.elpNumEntries];\r
- for (unsigned int i=0; i<pEmr->elp.elpNumEntries; i++) {\r
- d->style.stroke_dash.dash[i] = pix_size_to_point( d, pEmr->elp.elpStyleEntry[i] );\r
- }\r
- d->style.stroke_dasharray_set = 1;\r
- } else {\r
- d->style.stroke_dasharray_set = 0;\r
- }\r
- break;\r
- }\r
- default:\r
- {\r
- d->style.stroke_dasharray_set = 0;\r
- break;\r
- }\r
- }\r
-\r
- switch (pEmr->elp.elpPenStyle & PS_ENDCAP_MASK) {\r
- case PS_ENDCAP_ROUND:\r
- {\r
- d->style.stroke_linecap.computed = 1;\r
- break;\r
- }\r
- case PS_ENDCAP_SQUARE:\r
- {\r
- d->style.stroke_linecap.computed = 2;\r
- break;\r
- }\r
- case PS_ENDCAP_FLAT:\r
- default:\r
- {\r
- d->style.stroke_linecap.computed = 0;\r
- break;\r
- }\r
- }\r
-\r
- switch (pEmr->elp.elpPenStyle & PS_JOIN_MASK) {\r
- case PS_JOIN_BEVEL:\r
- {\r
- d->style.stroke_linejoin.computed = 2;\r
- break;\r
- }\r
- case PS_JOIN_MITER:\r
- {\r
- d->style.stroke_linejoin.computed = 0;\r
- break;\r
- }\r
- case PS_JOIN_ROUND:\r
- default:\r
- {\r
- d->style.stroke_linejoin.computed = 1;\r
- break;\r
- }\r
- }\r
-\r
- d->style.stroke_width.value = pix_size_to_point( d, pEmr->elp.elpWidth );\r
-\r
- double r, g, b;\r
- r = SP_COLOR_U_TO_F( GetRValue(pEmr->elp.elpColor) );\r
- g = SP_COLOR_U_TO_F( GetGValue(pEmr->elp.elpColor) );\r
- b = SP_COLOR_U_TO_F( GetBValue(pEmr->elp.elpColor) );\r
-\r
- sp_color_set_rgb_float( &(d->style.stroke.value.color), r,g,b );\r
-\r
- d->stroke_set = true;\r
-}\r
-\r
-\r
-static void\r
-select_brush(PEMF_CALLBACK_DATA d, int index)\r
-{\r
- PEMRCREATEBRUSHINDIRECT pEmr = NULL;\r
-\r
- if (index >= 0 && index < d->n_obj)\r
- pEmr = (PEMRCREATEBRUSHINDIRECT) d->emf_obj[index].lpEMFR;\r
-\r
- if (!pEmr)\r
- return;\r
-\r
- if (pEmr->lb.lbStyle == BS_SOLID) {\r
- double r, g, b;\r
- r = SP_COLOR_U_TO_F( GetRValue(pEmr->lb.lbColor) );\r
- g = SP_COLOR_U_TO_F( GetGValue(pEmr->lb.lbColor) );\r
- b = SP_COLOR_U_TO_F( GetBValue(pEmr->lb.lbColor) );\r
- sp_color_set_rgb_float( &(d->style.fill.value.color), r,g,b );\r
- }\r
-\r
- d->fill_set = true;\r
-}\r
-\r
-\r
-static void\r
-delete_object(PEMF_CALLBACK_DATA d, int index)\r
-{\r
- if (index >= 0 && index < d->n_obj) {\r
- d->emf_obj[index].type = 0;\r
- if (d->emf_obj[index].lpEMFR)\r
- free(d->emf_obj[index].lpEMFR);\r
- d->emf_obj[index].lpEMFR = NULL;\r
- }\r
-}\r
-\r
-\r
-static void\r
-insert_object(PEMF_CALLBACK_DATA d, int index, int type, ENHMETARECORD *pObj)\r
-{\r
- if (index >= 0 && index < d->n_obj) {\r
- delete_object(d, index);\r
- d->emf_obj[index].type = type;\r
- d->emf_obj[index].lpEMFR = pObj;\r
- }\r
-}\r
-\r
-\r
-static int CALLBACK\r
-myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)\r
-{\r
- PEMF_CALLBACK_DATA d;\r
- SVGOStringStream tmp_outsvg;\r
- SVGOStringStream tmp_path;\r
- SVGOStringStream tmp_str;\r
-\r
- d = (PEMF_CALLBACK_DATA) lpData;\r
-\r
- switch (lpEMFR->iType)\r
- {\r
- case EMR_HEADER:\r
- {\r
- ENHMETAHEADER *pEmr = (ENHMETAHEADER *) lpEMFR;\r
- tmp_outsvg << "<svg\n";\r
-\r
- d->xDPI = 2540;\r
- d->yDPI = 2540;\r
-\r
- d->PixelsX = pEmr->rclFrame.right - pEmr->rclFrame.left;\r
- d->PixelsY = pEmr->rclFrame.bottom - pEmr->rclFrame.top;\r
-\r
- d->MMX = d->PixelsX / 100.0;\r
- d->MMY = d->PixelsY / 100.0;\r
-\r
- tmp_outsvg <<\r
- " width=\"" << d->MMX << "mm\"\n" <<\r
- " height=\"" << d->MMY << "mm\">\n";\r
-\r
- if (pEmr->nHandles) {\r
- d->n_obj = pEmr->nHandles;\r
- d->emf_obj = new EMF_OBJECT[d->n_obj];\r
- } else {\r
- d->emf_obj = NULL;\r
- }\r
-\r
- break;\r
- }\r
- case EMR_POLYBEZIER:\r
- {\r
- PEMRPOLYBEZIER pEmr = (PEMRPOLYBEZIER) lpEMFR;\r
- DWORD i,j;\r
-\r
- if (pEmr->cptl<4)\r
- break;\r
-\r
- *(d->outsvg) += " <path ";\r
- output_style(d, EMR_STROKEPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- tmp_str <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<\r
- pix_x_to_point( d, pEmr->aptl[0].y) << " ";\r
-\r
- for (i=1; i<pEmr->cptl; ) {\r
- tmp_str << "\n\tC ";\r
- for (j=0; j<3 && i<pEmr->cptl; j++,i++) {\r
- tmp_str <<\r
- pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[i].y ) << " ";\r
- }\r
- }\r
-\r
- *(d->outsvg) += tmp_str.str().c_str();\r
- *(d->outsvg) += " \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYGON:\r
- {\r
- EMRPOLYGON *pEmr = (EMRPOLYGON *) lpEMFR;\r
- DWORD i;\r
-\r
- if (pEmr->cptl < 2)\r
- break;\r
-\r
- *(d->outsvg) += " <path ";\r
- output_style(d, EMR_STROKEANDFILLPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- tmp_str <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[0].y ) << " ";\r
-\r
- for (i=1; i<pEmr->cptl; i++) {\r
- tmp_str <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[i].y ) << " ";\r
- }\r
-\r
- *(d->outsvg) += tmp_str.str().c_str();\r
- *(d->outsvg) += " z \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYLINE:\r
- {\r
- EMRPOLYLINE *pEmr = (EMRPOLYLINE *) lpEMFR;\r
- DWORD i;\r
-\r
- if (pEmr->cptl<2)\r
- break;\r
-\r
- *(d->outsvg) += " <path ";\r
- output_style(d, EMR_STROKEPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- tmp_str <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[0].y ) << " ";\r
-\r
- for (i=1; i<pEmr->cptl; i++) {\r
- tmp_str <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[i].y ) << " ";\r
- }\r
-\r
- *(d->outsvg) += tmp_str.str().c_str();\r
- *(d->outsvg) += " \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYBEZIERTO:\r
- {\r
- PEMRPOLYBEZIERTO pEmr = (PEMRPOLYBEZIERTO) lpEMFR;\r
- DWORD i,j;\r
-\r
- for (i=0; i<pEmr->cptl;) {\r
- tmp_path << "\n\tC ";\r
- for (j=0; j<3 && i<pEmr->cptl; j++,i++) {\r
- tmp_path <<\r
- pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[i].y ) << " ";\r
- }\r
- }\r
-\r
- break;\r
- }\r
- case EMR_POLYLINETO:\r
- {\r
- PEMRPOLYLINETO pEmr = (PEMRPOLYLINETO) lpEMFR;\r
- DWORD i;\r
-\r
- for (i=0; i<pEmr->cptl;i++) {\r
- tmp_path <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->aptl[i].y ) << " ";\r
- }\r
-\r
- break;\r
- }\r
- case EMR_POLYPOLYLINE:\r
- break;\r
- case EMR_POLYPOLYGON:\r
- break;\r
- case EMR_SETWINDOWEXTEX:\r
- {\r
- PEMRSETWINDOWEXTEX pEmr = (PEMRSETWINDOWEXTEX) lpEMFR;\r
-\r
- d->sizeWnd = pEmr->szlExtent;\r
- d->PixelsX = d->sizeWnd.cx;\r
- d->PixelsY = d->sizeWnd.cy;\r
-\r
- d->ScaleX = d->xDPI / (100*d->MMX / d->PixelsX);\r
- d->ScaleY = d->yDPI / (100*d->MMY / d->PixelsY);\r
-\r
- break;\r
- }\r
- case EMR_SETWINDOWORGEX:\r
- {\r
- PEMRSETWINDOWORGEX pEmr = (PEMRSETWINDOWORGEX) lpEMFR;\r
- d->winorg = pEmr->ptlOrigin;\r
- break;\r
- }\r
- case EMR_SETVIEWPORTEXTEX:\r
- {\r
- PEMRSETVIEWPORTEXTEX pEmr = (PEMRSETVIEWPORTEXTEX) lpEMFR;\r
-\r
- d->sizeView = pEmr->szlExtent;\r
-\r
- if (d->sizeWnd.cx && d->sizeWnd.cy) {\r
- HDC hScreenDC = GetDC( NULL );\r
-\r
- float scrPixelsX = (float)GetDeviceCaps( hScreenDC, HORZRES );\r
- float scrPixelsY = (float)GetDeviceCaps( hScreenDC, VERTRES );\r
- float scrMMX = (float)GetDeviceCaps( hScreenDC, HORZSIZE );\r
- float scrMMY = (float)GetDeviceCaps( hScreenDC, VERTSIZE );\r
-\r
- ReleaseDC( NULL, hScreenDC );\r
-\r
- d->dwInchesX = d->sizeView.cx / (25.4f*scrPixelsX/scrMMX);\r
- d->dwInchesY = d->sizeView.cy / (25.4f*scrPixelsY/scrMMY);\r
- d->xDPI = d->sizeWnd.cx / d->dwInchesX;\r
- d->yDPI = d->sizeWnd.cy / d->dwInchesY;\r
-\r
- if (1) {\r
- d->xDPI = 2540;\r
- d->yDPI = 2540;\r
- d->dwInchesX = d->PixelsX / d->xDPI;\r
- d->dwInchesY = d->PixelsY / d->yDPI;\r
- d->ScaleX = d->xDPI;\r
- d->ScaleY = d->yDPI;\r
- }\r
-\r
- d->MMX = d->dwInchesX * MM_PER_IN;\r
- d->MMY = d->dwInchesY * MM_PER_IN;\r
- }\r
-\r
- break;\r
- }\r
- case EMR_SETVIEWPORTORGEX:\r
- {\r
- PEMRSETVIEWPORTORGEX pEmr = (PEMRSETVIEWPORTORGEX) lpEMFR;\r
- d->vieworg = pEmr->ptlOrigin;\r
- break;\r
- }\r
- case EMR_SETBRUSHORGEX:\r
- break;\r
- case EMR_EOF:\r
- {\r
- tmp_outsvg << "</svg>\n";\r
- break;\r
- }\r
- case EMR_SETPIXELV:\r
- break;\r
- case EMR_SETMAPPERFLAGS:\r
- break;\r
- case EMR_SETMAPMODE:\r
- break;\r
- case EMR_SETBKMODE:\r
- break;\r
- case EMR_SETPOLYFILLMODE:\r
- {\r
- PEMRSETPOLYFILLMODE pEmr = (PEMRSETPOLYFILLMODE) lpEMFR;\r
- d->style.fill_rule.value =\r
- (pEmr->iMode == WINDING ? 0 :\r
- pEmr->iMode == ALTERNATE ? 1 : 0);\r
- break;\r
- }\r
- case EMR_SETROP2:\r
- break;\r
- case EMR_SETSTRETCHBLTMODE:\r
- break;\r
- case EMR_SETTEXTALIGN:\r
- break;\r
- case EMR_SETCOLORADJUSTMENT:\r
- break;\r
- case EMR_SETTEXTCOLOR:\r
- break;\r
- case EMR_SETBKCOLOR:\r
- break;\r
- case EMR_OFFSETCLIPRGN:\r
- break;\r
- case EMR_MOVETOEX:\r
- {\r
- PEMRMOVETOEX pEmr = (PEMRMOVETOEX) lpEMFR;\r
- tmp_path <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, pEmr->ptl.x ) << " " <<\r
- pix_y_to_point( d, pEmr->ptl.y ) << " ";\r
- break;\r
- }\r
- case EMR_SETMETARGN:\r
- break;\r
- case EMR_EXCLUDECLIPRECT:\r
- break;\r
- case EMR_INTERSECTCLIPRECT:\r
- break;\r
- case EMR_SCALEVIEWPORTEXTEX:\r
- break;\r
- case EMR_SCALEWINDOWEXTEX:\r
- break;\r
- case EMR_SAVEDC:\r
- break;\r
- case EMR_RESTOREDC:\r
- break;\r
- case EMR_SETWORLDTRANSFORM:\r
- break;\r
- case EMR_MODIFYWORLDTRANSFORM:\r
- break;\r
- case EMR_SELECTOBJECT:\r
- {\r
- PEMRSELECTOBJECT pEmr = (PEMRSELECTOBJECT) lpEMFR;\r
- unsigned int index = pEmr->ihObject;\r
-\r
- if (index >= ENHMETA_STOCK_OBJECT) {\r
- index -= ENHMETA_STOCK_OBJECT;\r
- switch (index) {\r
- case NULL_BRUSH:\r
- d->fill_set = false;\r
- break;\r
- case BLACK_BRUSH:\r
- case DKGRAY_BRUSH:\r
- case GRAY_BRUSH:\r
- case LTGRAY_BRUSH:\r
- case WHITE_BRUSH:\r
- {\r
- float val = 0;\r
- switch (index) {\r
- case BLACK_BRUSH:\r
- val = 0.0 / 255.0;\r
- break;\r
- case DKGRAY_BRUSH:\r
- val = 64.0 / 255.0;\r
- break;\r
- case GRAY_BRUSH:\r
- val = 128.0 / 255.0;\r
- break;\r
- case LTGRAY_BRUSH:\r
- val = 192.0 / 255.0;\r
- break;\r
- case WHITE_BRUSH:\r
- val = 255.0 / 255.0;\r
- break;\r
- }\r
- sp_color_set_rgb_float( &(d->style.fill.value.color), val,val,val );\r
-\r
- d->fill_set = true;\r
- break;\r
- }\r
- case NULL_PEN:\r
- d->stroke_set = false;\r
- break;\r
- case BLACK_PEN:\r
- case WHITE_PEN:\r
- {\r
- float val = index == BLACK_PEN ? 0 : 1;\r
- d->style.stroke_dasharray_set = 0;\r
- d->style.stroke_width.value = 1.0;\r
- sp_color_set_rgb_float( &(d->style.stroke.value.color), val,val,val );\r
-\r
- d->stroke_set = true;\r
-\r
- break;\r
- }\r
- }\r
- } else {\r
- if (index >= 0 && index < d->n_obj) {\r
- switch (d->emf_obj[index].type)\r
- {\r
- case EMR_CREATEPEN:\r
- select_pen(d, index);\r
- break;\r
- case EMR_CREATEBRUSHINDIRECT:\r
- select_brush(d, index);\r
- break;\r
- case EMR_EXTCREATEPEN:\r
- select_extpen(d, index);\r
- break;\r
- }\r
- }\r
- }\r
- break;\r
- }\r
- case EMR_CREATEPEN:\r
- {\r
- PEMRCREATEPEN pEmr = (PEMRCREATEPEN) lpEMFR;\r
- int index = pEmr->ihPen;\r
-\r
- EMRCREATEPEN *pPen =\r
- (EMRCREATEPEN *) malloc( sizeof(EMREXTCREATEPEN) );\r
- pPen->lopn = pEmr->lopn;\r
- insert_object(d, index, EMR_CREATEPEN, (ENHMETARECORD *) pPen);\r
-\r
- break;\r
- }\r
- case EMR_CREATEBRUSHINDIRECT:\r
- {\r
- PEMRCREATEBRUSHINDIRECT pEmr = (PEMRCREATEBRUSHINDIRECT) lpEMFR;\r
- int index = pEmr->ihBrush;\r
-\r
- EMRCREATEBRUSHINDIRECT *pBrush =\r
- (EMRCREATEBRUSHINDIRECT *) malloc( sizeof(EMRCREATEBRUSHINDIRECT) );\r
- pBrush->lb = pEmr->lb;\r
- insert_object(d, index, EMR_CREATEBRUSHINDIRECT, (ENHMETARECORD *) pBrush);\r
-\r
- break;\r
- }\r
- case EMR_DELETEOBJECT:\r
- break;\r
- case EMR_ANGLEARC:\r
- break;\r
- case EMR_ELLIPSE:\r
- break;\r
- case EMR_RECTANGLE:\r
- break;\r
- case EMR_ROUNDRECT:\r
- break;\r
- case EMR_ARC:\r
- break;\r
- case EMR_CHORD:\r
- break;\r
- case EMR_PIE:\r
- break;\r
- case EMR_SELECTPALETTE:\r
- break;\r
- case EMR_CREATEPALETTE:\r
- break;\r
- case EMR_SETPALETTEENTRIES:\r
- break;\r
- case EMR_RESIZEPALETTE:\r
- break;\r
- case EMR_REALIZEPALETTE:\r
- break;\r
- case EMR_EXTFLOODFILL:\r
- break;\r
- case EMR_LINETO:\r
- {\r
- PEMRLINETO pEmr = (PEMRLINETO) lpEMFR;\r
- tmp_path <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, pEmr->ptl.x ) << " " <<\r
- pix_y_to_point( d, pEmr->ptl.y ) << " ";\r
- break;\r
- }\r
- case EMR_ARCTO:\r
- break;\r
- case EMR_POLYDRAW:\r
- break;\r
- case EMR_SETARCDIRECTION:\r
- break;\r
- case EMR_SETMITERLIMIT:\r
- {\r
- PEMRSETMITERLIMIT pEmr = (PEMRSETMITERLIMIT) lpEMFR;\r
- d->style.stroke_miterlimit.value = pix_size_to_point( d, pEmr->eMiterLimit );\r
-\r
- if (d->style.stroke_miterlimit.value < 1)\r
- d->style.stroke_miterlimit.value = 1.0;\r
-\r
- break;\r
- }\r
- case EMR_BEGINPATH:\r
- {\r
- tmp_path << " d=\"";\r
- *(d->path) = "";\r
- break;\r
- }\r
- case EMR_ENDPATH:\r
- {\r
- tmp_path << "\"";\r
- break;\r
- }\r
- case EMR_CLOSEFIGURE:\r
- {\r
- tmp_path << "\n\tz";\r
- break;\r
- }\r
- case EMR_FILLPATH:\r
- case EMR_STROKEANDFILLPATH:\r
- case EMR_STROKEPATH:\r
- {\r
- *(d->outsvg) += " <path ";\r
- output_style(d, lpEMFR->iType);\r
- *(d->outsvg) += "\n\t";\r
- *(d->outsvg) += *(d->path);\r
- *(d->outsvg) += " /> \n";\r
- break;\r
- }\r
- case EMR_FLATTENPATH:\r
- break;\r
- case EMR_WIDENPATH:\r
- break;\r
- case EMR_SELECTCLIPPATH:\r
- break;\r
- case EMR_ABORTPATH:\r
- break;\r
- case EMR_GDICOMMENT:\r
- break;\r
- case EMR_FILLRGN:\r
- break;\r
- case EMR_FRAMERGN:\r
- break;\r
- case EMR_INVERTRGN:\r
- break;\r
- case EMR_PAINTRGN:\r
- break;\r
- case EMR_EXTSELECTCLIPRGN:\r
- break;\r
- case EMR_BITBLT:\r
- break;\r
- case EMR_STRETCHBLT:\r
- break;\r
- case EMR_MASKBLT:\r
- break;\r
- case EMR_PLGBLT:\r
- break;\r
- case EMR_SETDIBITSTODEVICE:\r
- break;\r
- case EMR_STRETCHDIBITS:\r
- break;\r
- case EMR_EXTCREATEFONTINDIRECTW:\r
- break;\r
- case EMR_EXTTEXTOUTA:\r
- break;\r
- case EMR_EXTTEXTOUTW:\r
- break;\r
- case EMR_POLYBEZIER16:\r
- {\r
- PEMRPOLYBEZIER16 pEmr = (PEMRPOLYBEZIER16) lpEMFR;\r
- POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?\r
- DWORD i,j;\r
-\r
- if (pEmr->cpts<4)\r
- break;\r
-\r
- *(d->outsvg) += " <path ";\r
- output_style(d, EMR_STROKEPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- tmp_str <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, apts[0].x ) << " " <<\r
- pix_y_to_point( d, apts[0].y ) << " ";\r
-\r
- for (i=1; i<pEmr->cpts; ) {\r
- tmp_str << "\n\tC ";\r
- for (j=0; j<3 && i<pEmr->cpts; j++,i++) {\r
- tmp_str <<\r
- pix_x_to_point( d, apts[i].x ) << " " <<\r
- pix_y_to_point( d, apts[i].y ) << " ";\r
- }\r
- }\r
-\r
- *(d->outsvg) += tmp_str.str().c_str();\r
- *(d->outsvg) += " \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYGON16:\r
- {\r
- PEMRPOLYGON16 pEmr = (PEMRPOLYGON16) lpEMFR;\r
- POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?\r
- unsigned int i;\r
-\r
- *(d->outsvg) += "<path ";\r
- output_style(d, EMR_STROKEANDFILLPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- // skip the first point?\r
- tmp_path << "\n\tM " <<\r
- pix_x_to_point( d, apts[1].x ) << " " <<\r
- pix_y_to_point( d, apts[1].y ) << " ";\r
-\r
- for (i=2; i<pEmr->cpts; i++) {\r
- tmp_path << "\n\tL " <<\r
- pix_x_to_point( d, apts[i].x ) << " " <<\r
- pix_y_to_point( d, apts[i].y ) << " ";\r
- }\r
-\r
- *(d->outsvg) += tmp_path.str().c_str();\r
- *(d->outsvg) += " z \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYLINE16:\r
- {\r
- EMRPOLYLINE16 *pEmr = (EMRPOLYLINE16 *) lpEMFR;\r
- POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?\r
- DWORD i;\r
-\r
- if (pEmr->cpts<2)\r
- break;\r
-\r
- *(d->outsvg) += " <path ";\r
- output_style(d, EMR_STROKEPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- tmp_str <<\r
- "\n\tM " <<\r
- pix_x_to_point( d, apts[0].x ) << " " <<\r
- pix_y_to_point( d, apts[0].y ) << " ";\r
-\r
- for (i=1; i<pEmr->cpts; i++) {\r
- tmp_str <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, apts[i].x ) << " " <<\r
- pix_y_to_point( d, apts[i].y ) << " ";\r
- }\r
-\r
- *(d->outsvg) += tmp_str.str().c_str();\r
- *(d->outsvg) += " \" /> \n";\r
-\r
- break;\r
- }\r
- case EMR_POLYBEZIERTO16:\r
- {\r
- PEMRPOLYBEZIERTO16 pEmr = (PEMRPOLYBEZIERTO16) lpEMFR;\r
- POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?\r
- DWORD i,j;\r
-\r
- for (i=0; i<pEmr->cpts;) {\r
- tmp_path << "\n\tC ";\r
- for (j=0; j<3 && i<pEmr->cpts; j++,i++) {\r
- tmp_path <<\r
- pix_x_to_point( d, apts[i].x ) << " " <<\r
- pix_y_to_point( d, apts[i].y ) << " ";\r
- }\r
- }\r
-\r
- break;\r
- }\r
- case EMR_POLYLINETO16:\r
- {\r
- PEMRPOLYLINETO16 pEmr = (PEMRPOLYLINETO16) lpEMFR;\r
- POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?\r
- DWORD i;\r
-\r
- for (i=0; i<pEmr->cpts;i++) {\r
- tmp_path <<\r
- "\n\tL " <<\r
- pix_x_to_point( d, apts[i].x ) << " " <<\r
- pix_y_to_point( d, apts[i].y ) << " ";\r
- }\r
-\r
- break;\r
- }\r
- case EMR_POLYPOLYLINE16:\r
- break;\r
- case EMR_POLYPOLYGON16:\r
- {\r
- PEMRPOLYPOLYGON16 pEmr = (PEMRPOLYPOLYGON16) lpEMFR;\r
- unsigned int n, i, j;\r
-\r
- *(d->outsvg) += "<path ";\r
- output_style(d, EMR_STROKEANDFILLPATH);\r
- *(d->outsvg) += "\n\td=\"";\r
-\r
- i = pEmr->nPolys-1; // ???\r
- for (n=0; n<pEmr->nPolys /*&& i<pEmr->cpts*/; n++) {\r
- SVGOStringStream poly_path;\r
-\r
- poly_path << "\n\tM " <<\r
- pix_x_to_point( d, pEmr->apts[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->apts[i].y ) << " ";\r
- i++;\r
-\r
- for (j=1; j<pEmr->aPolyCounts[n] /*&& i<pEmr->cpts*/; j++) {\r
- poly_path << "\n\tL " <<\r
- pix_x_to_point( d, pEmr->apts[i].x ) << " " <<\r
- pix_y_to_point( d, pEmr->apts[i].y ) << " ";\r
- i++;\r
- }\r
-\r
- *(d->outsvg) += poly_path.str().c_str();\r
- *(d->outsvg) += " z \n";\r
- }\r
-\r
- *(d->outsvg) += " \" /> \n";\r
- break;\r
- }\r
- case EMR_POLYDRAW16:\r
- break;\r
- case EMR_CREATEMONOBRUSH:\r
- break;\r
- case EMR_CREATEDIBPATTERNBRUSHPT:\r
- break;\r
- case EMR_EXTCREATEPEN:\r
- {\r
- PEMREXTCREATEPEN pEmr = (PEMREXTCREATEPEN) lpEMFR;\r
- int index = pEmr->ihPen;\r
-\r
- EMREXTCREATEPEN *pPen =\r
- (EMREXTCREATEPEN *) malloc( sizeof(EMREXTCREATEPEN) +\r
- sizeof(DWORD) * pEmr->elp.elpNumEntries );\r
- pPen->ihPen = pEmr->ihPen;\r
- pPen->offBmi = pEmr->offBmi;\r
- pPen->cbBmi = pEmr->cbBmi;\r
- pPen->offBits = pEmr->offBits;\r
- pPen->cbBits = pEmr->cbBits;\r
- pPen->elp = pEmr->elp;\r
- for (unsigned int i=0; i<pEmr->elp.elpNumEntries; i++) {\r
- pPen->elp.elpStyleEntry[i] = pEmr->elp.elpStyleEntry[i];\r
- }\r
- insert_object(d, index, EMR_EXTCREATEPEN, (ENHMETARECORD *) pPen);\r
-\r
- break;\r
- }\r
- case EMR_POLYTEXTOUTA:\r
- break;\r
- case EMR_POLYTEXTOUTW:\r
- break;\r
- case EMR_SETICMMODE:\r
- break;\r
- case EMR_CREATECOLORSPACE:\r
- break;\r
- case EMR_SETCOLORSPACE:\r
- break;\r
- case EMR_DELETECOLORSPACE:\r
- break;\r
- case EMR_GLSRECORD:\r
- break;\r
- case EMR_GLSBOUNDEDRECORD:\r
- break;\r
- case EMR_PIXELFORMAT:\r
- break;\r
- }\r
-\r
- *(d->outsvg) += tmp_outsvg.str().c_str();\r
- *(d->path) += tmp_path.str().c_str();\r
-\r
- return 1;\r
-}\r
-\r
-\r
-// Aldus Placeable Header ===================================================\r
-// Since we are a 32bit app, we have to be sure this structure compiles to\r
-// be identical to a 16 bit app's version. To do this, we use the #pragma\r
-// to adjust packing, we use a WORD for the hmf handle, and a SMALL_RECT\r
-// for the bbox rectangle.\r
-#pragma pack( push )\r
-#pragma pack( 2 )\r
-typedef struct\r
-{\r
- DWORD dwKey;\r
- WORD hmf;\r
- SMALL_RECT bbox;\r
- WORD wInch;\r
- DWORD dwReserved;\r
- WORD wCheckSum;\r
-} APMHEADER, *PAPMHEADER;\r
-#pragma pack( pop )\r
-\r
-\r
-SPDocument *\r
-EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri )\r
-{\r
- EMF_CALLBACK_DATA d = {0};\r
-\r
- gsize bytesRead = 0;\r
- gsize bytesWritten = 0;\r
- GError* error = NULL;\r
- gchar *local_fn =\r
- g_filename_from_utf8( uri, -1, &bytesRead, &bytesWritten, &error );\r
-\r
- if (local_fn == NULL) {\r
- return NULL;\r
- }\r
-\r
- d.outsvg = new Glib::ustring("");\r
- d.path = new Glib::ustring("");\r
-\r
- CHAR *ansi_uri = (CHAR *) local_fn;\r
- gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );\r
- WCHAR *unicode_uri = (WCHAR *) unicode_fn;\r
-\r
- // Try open as Enhanced Metafile\r
- HENHMETAFILE hemf;\r
- if (PrintWin32::is_os_wide())\r
- hemf = GetEnhMetaFileW(unicode_uri);\r
- else\r
- hemf = GetEnhMetaFileA(ansi_uri);\r
-\r
- if (!hemf) {\r
- // Try open as Windows Metafile\r
- HMETAFILE hmf;\r
- if (PrintWin32::is_os_wide())\r
- hmf = GetMetaFileW(unicode_uri);\r
- else\r
- hmf = GetMetaFileA(ansi_uri);\r
-\r
- METAFILEPICT mp;\r
- HDC hDC;\r
-\r
- if (!hmf) {\r
- if (PrintWin32::is_os_wide()) {\r
- WCHAR szTemp[MAX_PATH];\r
-\r
- DWORD dw = GetShortPathNameW( unicode_uri, szTemp, MAX_PATH );\r
- if (dw) {\r
- hmf = GetMetaFileW( szTemp );\r
- }\r
- } else {\r
- CHAR szTemp[MAX_PATH];\r
-\r
- DWORD dw = GetShortPathNameA( ansi_uri, szTemp, MAX_PATH );\r
- if (dw) {\r
- hmf = GetMetaFileA( szTemp );\r
- }\r
- }\r
- }\r
-\r
- if (hmf) {\r
- DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );\r
- if (nSize) {\r
- BYTE *lpvData = new BYTE[nSize];\r
- if (lpvData) {\r
- DWORD dw = GetMetaFileBitsEx( hmf, nSize, lpvData );\r
- if (dw) {\r
- // Fill out a METAFILEPICT structure\r
- mp.mm = MM_ANISOTROPIC;\r
- mp.xExt = 1000;\r
- mp.yExt = 1000;\r
- mp.hMF = NULL;\r
- // Get a reference DC\r
- hDC = GetDC( NULL );\r
- // Make an enhanced metafile from the windows metafile\r
- hemf = SetWinMetaFileBits( nSize, lpvData, hDC, &mp );\r
- // Clean up\r
- ReleaseDC( NULL, hDC );\r
- }\r
- delete[] lpvData;\r
- }\r
- DeleteMetaFile( hmf );\r
- }\r
- } else {\r
- // Try open as Aldus Placeable Metafile\r
- HANDLE hFile;\r
- if (PrintWin32::is_os_wide())\r
- hFile = CreateFileW( unicode_uri, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
- else\r
- hFile = CreateFileA( ansi_uri, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
- if (hFile != INVALID_HANDLE_VALUE) {\r
- DWORD nSize = GetFileSize( hFile, NULL );\r
- if (nSize) {\r
- BYTE *lpvData = new BYTE[nSize];\r
- if (lpvData) {\r
- DWORD dw = ReadFile( hFile, lpvData, nSize, &nSize, NULL );\r
- if (dw) {\r
- if ( ((PAPMHEADER)lpvData)->dwKey == 0x9ac6cdd7l ) {\r
- // Fill out a METAFILEPICT structure\r
- mp.mm = MM_ANISOTROPIC;\r
- mp.xExt = ((PAPMHEADER)lpvData)->bbox.Right - ((PAPMHEADER)lpvData)->bbox.Left;\r
- mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);\r
- mp.yExt = ((PAPMHEADER)lpvData)->bbox.Bottom - ((PAPMHEADER)lpvData)->bbox.Top;\r
- mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);\r
- mp.hMF = NULL;\r
- // Get a reference DC\r
- hDC = GetDC( NULL );\r
- // Create an enhanced metafile from the bits\r
- hemf = SetWinMetaFileBits( nSize, lpvData+sizeof(APMHEADER), hDC, &mp );\r
- // Clean up\r
- ReleaseDC( NULL, hDC );\r
- }\r
- }\r
- delete[] lpvData;\r
- }\r
- }\r
- CloseHandle( hFile );\r
- }\r
- }\r
- }\r
-\r
- if (!hemf || !d.outsvg || !d.path) {\r
- if (d.outsvg)\r
- delete d.outsvg;\r
- if (d.path)\r
- delete d.path;\r
- if (local_fn)\r
- g_free(local_fn);\r
- if (unicode_fn)\r
- g_free(unicode_fn);\r
- return NULL;\r
- }\r
-\r
- EnumEnhMetaFile(NULL, hemf, myEnhMetaFileProc, (LPVOID) &d, NULL);\r
- DeleteEnhMetaFile(hemf);\r
-\r
-// std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl;\r
-\r
- SPDocument *doc = sp_document_new_from_mem(d.outsvg->c_str(), d.outsvg->length(), TRUE);\r
-\r
- delete d.outsvg;\r
- delete d.path;\r
-\r
- if (d.emf_obj) {\r
- int i;\r
- for (i=0; i<d.n_obj; i++)\r
- delete_object(&d, i);\r
- delete[] d.emf_obj;\r
- }\r
- \r
- if (d.style.stroke_dash.dash)\r
- delete[] d.style.stroke_dash.dash;\r
-\r
- if (local_fn)\r
- g_free(local_fn);\r
- if (unicode_fn)\r
- g_free(unicode_fn);\r
-\r
- return doc;\r
-}\r
-\r
-\r
-void\r
-EmfWin32::init (void)\r
-{\r
- Inkscape::Extension::Extension * ext;\r
-\r
- /* EMF in */\r
- ext = Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>" N_("EMF Input") "</name>\n"\r
- "<id>org.inkscape.input.emf.win32</id>\n"\r
- "<input>\n"\r
- "<extension>.emf</extension>\n"\r
- "<mimetype>image/x-emf</mimetype>\n"\r
- "<filetypename>" N_("Enhanced Metafiles (*.emf)") "</filetypename>\n"\r
- "<filetypetooltip>" N_("Enhanced Metafiles") "</filetypetooltip>\n"\r
- "<output_extension>org.inkscape.output.emf.win32</output_extension>\n"\r
- "</input>\n"\r
- "</inkscape-extension>", new EmfWin32());\r
-\r
- /* WMF in */\r
- ext = Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>" N_("WMF Input") "</name>\n"\r
- "<id>org.inkscape.input.wmf.win32</id>\n"\r
- "<input>\n"\r
- "<extension>.wmf</extension>\n"\r
- "<mimetype>image/x-wmf</mimetype>\n"\r
- "<filetypename>" N_("Windows Metafiles (*.wmf)") "</filetypename>\n"\r
- "<filetypetooltip>" N_("Windows Metafiles") "</filetypetooltip>\n"\r
- "<output_extension>org.inkscape.output.emf.win32</output_extension>\n"\r
- "</input>\n"\r
- "</inkscape-extension>", new EmfWin32());\r
-\r
- /* EMF out */\r
- ext = Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>" N_("EMF Output") "</name>\n"\r
- "<id>org.inkscape.output.emf.win32</id>\n"\r
- "<output>\n"\r
- "<extension>.emf</extension>\n"\r
- "<mimetype>image/x-emf</mimetype>\n"\r
- "<filetypename>" N_("Enhanced Metafile (*.emf)") "</filetypename>\n"\r
- "<filetypetooltip>" N_("Enhanced Metafile") "</filetypetooltip>\n"\r
- "</output>\n"\r
- "</inkscape-extension>", new EmfWin32());\r
-\r
- return;\r
-}\r
-\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-\r
-#endif /* WIN32 */\r
-\r
-\r
-/*\r
- Local Variables:\r
- mode:cpp\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+/** \file
+ * Enhanced Metafile Input and Output.
+ */
+/*
+ * Authors:
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+/*
+ * References:
+ * - How to Create & Play Enhanced Metafiles in Win32
+ * http://support.microsoft.com/kb/q145999/
+ * - INFO: Windows Metafile Functions & Aldus Placeable Metafiles
+ * http://support.microsoft.com/kb/q66949/
+ * - Metafile Functions
+ * http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp
+ * - Metafile Structures
+ * http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp
+ */
+
+#ifdef WIN32
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "win32.h"
+#include "emf-win32-print.h"
+#include "emf-win32-inout.h"
+#include "inkscape.h"
+#include "sp-path.h"
+#include "style.h"
+#include "color.h"
+#include "display/curve.h"
+#include "libnr/n-art-bpath.h"
+#include "libnr/nr-point-matrix-ops.h"
+#include "gtk/gtk.h"
+#include "print.h"
+#include "glibmm/i18n.h"
+#include "extension/extension.h"
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "document.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+
+#include "libnr/nr-rect.h"
+#include "libnr/nr-matrix.h"
+#include "libnr/nr-pixblock.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <vector>
+#include <string>
+
+#include "io/sys.h"
+
+#include "unit-constants.h"
+
+#include "clear-n_.h"
+
+
+#define PRINT_EMF_WIN32 "org.inkscape.print.emf.win32"
+
+#ifndef PS_JOIN_MASK
+#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)
+#endif
+
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+
+EmfWin32::EmfWin32 (void) // The null constructor
+{
+ return;
+}
+
+
+EmfWin32::~EmfWin32 (void) //The destructor
+{
+ return;
+}
+
+
+bool
+EmfWin32::check (Inkscape::Extension::Extension * module)
+{
+ if (NULL == Inkscape::Extension::db.get(PRINT_EMF_WIN32))
+ return FALSE;
+ return TRUE;
+}
+
+
+static void
+emf_print_document_to_file(SPDocument *doc, gchar const *filename)
+{
+ Inkscape::Extension::Print *mod;
+ SPPrintContext context;
+ gchar const *oldconst;
+ gchar *oldoutput;
+ unsigned int ret;
+
+ sp_document_ensure_up_to_date(doc);
+
+ mod = Inkscape::Extension::get_print(PRINT_EMF_WIN32);
+ oldconst = mod->get_param_string("destination");
+ oldoutput = g_strdup(oldconst);
+ mod->set_param_string("destination", (gchar *)filename);
+
+/* Start */
+ context.module = mod;
+ /* fixme: This has to go into module constructor somehow */
+ /* Create new arena */
+ mod->base = SP_ITEM(sp_document_root(doc));
+ mod->arena = NRArena::create();
+ mod->dkey = sp_item_display_key_new(1);
+ mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
+ /* Print document */
+ ret = mod->begin(doc);
+ if (ret) {
+ throw Inkscape::Extension::Output::save_failed();
+ }
+ sp_item_invoke_print(mod->base, &context);
+ ret = mod->finish();
+ /* Release arena */
+ sp_item_invoke_hide(mod->base, mod->dkey);
+ mod->base = NULL;
+ nr_arena_item_unref(mod->root);
+ mod->root = NULL;
+ nr_object_unref((NRObject *) mod->arena);
+ mod->arena = NULL;
+/* end */
+
+ mod->set_param_string("destination", oldoutput);
+ g_free(oldoutput);
+
+ return;
+}
+
+
+void
+EmfWin32::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+{
+ Inkscape::Extension::Extension * ext;
+
+ ext = Inkscape::Extension::db.get(PRINT_EMF_WIN32);
+ if (ext == NULL)
+ return;
+
+// bool old_textToPath = ext->get_param_bool("textToPath");
+// bool new_val = mod->get_param_bool("textToPath");
+// ext->set_param_bool("textToPath", new_val);
+
+ gchar * final_name;
+ final_name = g_strdup_printf("%s", uri);
+ emf_print_document_to_file(doc, final_name);
+ g_free(final_name);
+
+// ext->set_param_bool("textToPath", old_textToPath);
+
+ return;
+}
+
+
+
+typedef struct {
+ int type;
+ ENHMETARECORD *lpEMFR;
+} EMF_OBJECT, *PEMF_OBJECT;
+
+typedef struct emf_callback_data {
+ Glib::ustring *outsvg;
+ Glib::ustring *path;
+ struct SPStyle style;
+ bool stroke_set;
+ bool fill_set;
+ double xDPI, yDPI;
+
+ SIZEL sizeWnd;
+ SIZEL sizeView;
+ float PixelsX;
+ float PixelsY;
+ float MMX;
+ float MMY;
+ float dwInchesX;
+ float dwInchesY;
+ POINTL winorg;
+ POINTL vieworg;
+ double ScaleX, ScaleY;
+
+ int n_obj;
+ PEMF_OBJECT emf_obj;
+} EMF_CALLBACK_DATA, *PEMF_CALLBACK_DATA;
+
+
+static void
+output_style(PEMF_CALLBACK_DATA d, int iType)
+{
+ SVGOStringStream tmp_style;
+ char tmp[1024] = {0};
+
+ *(d->outsvg) += "\n\tstyle=\"";
+ if (iType == EMR_STROKEPATH || !d->fill_set) {
+ tmp_style << "fill:none;";
+ } else {
+ float rgb[3];
+ sp_color_get_rgb_floatv( &(d->style.fill.value.color), rgb );
+ snprintf(tmp, 1023,
+ "fill:#%02x%02x%02x;",
+ SP_COLOR_F_TO_U(rgb[0]),
+ SP_COLOR_F_TO_U(rgb[1]),
+ SP_COLOR_F_TO_U(rgb[2]));
+ tmp_style << tmp;
+ snprintf(tmp, 1023,
+ "fill-rule:%s;",
+ d->style.fill_rule.value != 0 ? "evenodd" : "nonzero");
+ tmp_style << tmp;
+ tmp_style << "fill-opacity:1;";
+ }
+
+ if (iType == EMR_FILLPATH || !d->stroke_set) {
+ tmp_style << "stroke:none;";
+ } else {
+ float rgb[3];
+ sp_color_get_rgb_floatv(&(d->style.stroke.value.color), rgb);
+ snprintf(tmp, 1023,
+ "stroke:#%02x%02x%02x;",
+ SP_COLOR_F_TO_U(rgb[0]),
+ SP_COLOR_F_TO_U(rgb[1]),
+ SP_COLOR_F_TO_U(rgb[2]));
+ tmp_style << tmp;
+
+ tmp_style << "stroke-width:" <<
+ MAX( 0.001, d->style.stroke_width.value ) << "px;";
+
+ tmp_style << "stroke-linejoin:" <<
+ (d->style.stroke_linejoin.computed == 0 ? "miter" :
+ d->style.stroke_linejoin.computed == 1 ? "round" :
+ d->style.stroke_linejoin.computed == 2 ? "bevel" :
+ "unknown") << ";";
+
+ if (d->style.stroke_linejoin.computed == 0) {
+ tmp_style << "stroke-miterlimit:" <<
+ MAX( 0.01, d->style.stroke_miterlimit.value ) << ";";
+ }
+
+ if (d->style.stroke_dasharray_set &&
+ d->style.stroke_dash.n_dash && d->style.stroke_dash.dash)
+ {
+ tmp_style << "stroke-dasharray:";
+ for (int i=0; i<d->style.stroke_dash.n_dash; i++) {
+ if (i)
+ tmp_style << ",";
+ tmp_style << d->style.stroke_dash.dash[i];
+ }
+ tmp_style << ";";
+ tmp_style << "stroke-dashoffset:0;";
+ } else {
+ tmp_style << "stroke-dasharray:none;";
+ }
+ tmp_style << "stroke-opacity:1;";
+ }
+ tmp_style << "\" ";
+
+ *(d->outsvg) += tmp_style.str().c_str();
+}
+
+
+static double
+pix_x_to_point(PEMF_CALLBACK_DATA d, double px)
+{
+ double tmp = px - d->winorg.x;
+ tmp *= (double) PX_PER_IN / d->ScaleX;
+ tmp += d->vieworg.x;
+ return tmp;
+}
+
+
+static double
+pix_y_to_point(PEMF_CALLBACK_DATA d, double px)
+{
+ double tmp = px - d->winorg.y;
+ tmp *= (double) PX_PER_IN / d->ScaleY;
+ tmp += d->vieworg.y;
+ return tmp;
+}
+
+
+static double
+pix_size_to_point(PEMF_CALLBACK_DATA d, double px)
+{
+ double tmp = px;
+ tmp *= (double) PX_PER_IN / d->ScaleX;
+ return tmp;
+}
+
+
+static void
+select_pen(PEMF_CALLBACK_DATA d, int index)
+{
+ PEMRCREATEPEN pEmr = NULL;
+
+ if (index >= 0 && index < d->n_obj)
+ pEmr = (PEMRCREATEPEN) d->emf_obj[index].lpEMFR;
+
+ if (!pEmr)
+ return;
+
+ switch (pEmr->lopn.lopnStyle) {
+ default:
+ {
+ d->style.stroke_dasharray_set = 0;
+ break;
+ }
+ }
+
+ if (pEmr->lopn.lopnWidth.x) {
+ d->style.stroke_width.value = pix_size_to_point( d, pEmr->lopn.lopnWidth.x );
+ } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?)
+ d->style.stroke_width.value = 1.0;
+ }
+
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( GetRValue(pEmr->lopn.lopnColor) );
+ g = SP_COLOR_U_TO_F( GetGValue(pEmr->lopn.lopnColor) );
+ b = SP_COLOR_U_TO_F( GetBValue(pEmr->lopn.lopnColor) );
+ sp_color_set_rgb_float( &(d->style.stroke.value.color), r,g,b );
+
+ d->style.stroke_linejoin.computed = 1;
+
+ d->stroke_set = true;
+}
+
+
+static void
+select_extpen(PEMF_CALLBACK_DATA d, int index)
+{
+ PEMREXTCREATEPEN pEmr = NULL;
+
+ if (index >= 0 && index < d->n_obj)
+ pEmr = (PEMREXTCREATEPEN) d->emf_obj[index].lpEMFR;
+
+ if (!pEmr)
+ return;
+
+ switch (pEmr->elp.elpPenStyle & PS_STYLE_MASK) {
+ case PS_USERSTYLE:
+ {
+ if (pEmr->elp.elpNumEntries) {
+ d->style.stroke_dash.n_dash = pEmr->elp.elpNumEntries;
+ if (d->style.stroke_dash.dash)
+ delete[] d->style.stroke_dash.dash;
+ d->style.stroke_dash.dash = new double[pEmr->elp.elpNumEntries];
+ for (unsigned int i=0; i<pEmr->elp.elpNumEntries; i++) {
+ d->style.stroke_dash.dash[i] = pix_size_to_point( d, pEmr->elp.elpStyleEntry[i] );
+ }
+ d->style.stroke_dasharray_set = 1;
+ } else {
+ d->style.stroke_dasharray_set = 0;
+ }
+ break;
+ }
+ default:
+ {
+ d->style.stroke_dasharray_set = 0;
+ break;
+ }
+ }
+
+ switch (pEmr->elp.elpPenStyle & PS_ENDCAP_MASK) {
+ case PS_ENDCAP_ROUND:
+ {
+ d->style.stroke_linecap.computed = 1;
+ break;
+ }
+ case PS_ENDCAP_SQUARE:
+ {
+ d->style.stroke_linecap.computed = 2;
+ break;
+ }
+ case PS_ENDCAP_FLAT:
+ default:
+ {
+ d->style.stroke_linecap.computed = 0;
+ break;
+ }
+ }
+
+ switch (pEmr->elp.elpPenStyle & PS_JOIN_MASK) {
+ case PS_JOIN_BEVEL:
+ {
+ d->style.stroke_linejoin.computed = 2;
+ break;
+ }
+ case PS_JOIN_MITER:
+ {
+ d->style.stroke_linejoin.computed = 0;
+ break;
+ }
+ case PS_JOIN_ROUND:
+ default:
+ {
+ d->style.stroke_linejoin.computed = 1;
+ break;
+ }
+ }
+
+ d->style.stroke_width.value = pix_size_to_point( d, pEmr->elp.elpWidth );
+
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( GetRValue(pEmr->elp.elpColor) );
+ g = SP_COLOR_U_TO_F( GetGValue(pEmr->elp.elpColor) );
+ b = SP_COLOR_U_TO_F( GetBValue(pEmr->elp.elpColor) );
+
+ sp_color_set_rgb_float( &(d->style.stroke.value.color), r,g,b );
+
+ d->stroke_set = true;
+}
+
+
+static void
+select_brush(PEMF_CALLBACK_DATA d, int index)
+{
+ PEMRCREATEBRUSHINDIRECT pEmr = NULL;
+
+ if (index >= 0 && index < d->n_obj)
+ pEmr = (PEMRCREATEBRUSHINDIRECT) d->emf_obj[index].lpEMFR;
+
+ if (!pEmr)
+ return;
+
+ if (pEmr->lb.lbStyle == BS_SOLID) {
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( GetRValue(pEmr->lb.lbColor) );
+ g = SP_COLOR_U_TO_F( GetGValue(pEmr->lb.lbColor) );
+ b = SP_COLOR_U_TO_F( GetBValue(pEmr->lb.lbColor) );
+ sp_color_set_rgb_float( &(d->style.fill.value.color), r,g,b );
+ }
+
+ d->fill_set = true;
+}
+
+
+static void
+delete_object(PEMF_CALLBACK_DATA d, int index)
+{
+ if (index >= 0 && index < d->n_obj) {
+ d->emf_obj[index].type = 0;
+ if (d->emf_obj[index].lpEMFR)
+ free(d->emf_obj[index].lpEMFR);
+ d->emf_obj[index].lpEMFR = NULL;
+ }
+}
+
+
+static void
+insert_object(PEMF_CALLBACK_DATA d, int index, int type, ENHMETARECORD *pObj)
+{
+ if (index >= 0 && index < d->n_obj) {
+ delete_object(d, index);
+ d->emf_obj[index].type = type;
+ d->emf_obj[index].lpEMFR = pObj;
+ }
+}
+
+
+static int CALLBACK
+myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData)
+{
+ PEMF_CALLBACK_DATA d;
+ SVGOStringStream tmp_outsvg;
+ SVGOStringStream tmp_path;
+ SVGOStringStream tmp_str;
+
+ d = (PEMF_CALLBACK_DATA) lpData;
+
+ switch (lpEMFR->iType)
+ {
+ case EMR_HEADER:
+ {
+ ENHMETAHEADER *pEmr = (ENHMETAHEADER *) lpEMFR;
+ tmp_outsvg << "<svg\n";
+
+ d->xDPI = 2540;
+ d->yDPI = 2540;
+
+ d->PixelsX = pEmr->rclFrame.right - pEmr->rclFrame.left;
+ d->PixelsY = pEmr->rclFrame.bottom - pEmr->rclFrame.top;
+
+ d->MMX = d->PixelsX / 100.0;
+ d->MMY = d->PixelsY / 100.0;
+
+ tmp_outsvg <<
+ " width=\"" << d->MMX << "mm\"\n" <<
+ " height=\"" << d->MMY << "mm\">\n";
+
+ if (pEmr->nHandles) {
+ d->n_obj = pEmr->nHandles;
+ d->emf_obj = new EMF_OBJECT[d->n_obj];
+ } else {
+ d->emf_obj = NULL;
+ }
+
+ break;
+ }
+ case EMR_POLYBEZIER:
+ {
+ PEMRPOLYBEZIER pEmr = (PEMRPOLYBEZIER) lpEMFR;
+ DWORD i,j;
+
+ if (pEmr->cptl<4)
+ break;
+
+ *(d->outsvg) += " <path ";
+ output_style(d, EMR_STROKEPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ tmp_str <<
+ "\n\tM " <<
+ pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<
+ pix_x_to_point( d, pEmr->aptl[0].y) << " ";
+
+ for (i=1; i<pEmr->cptl; ) {
+ tmp_str << "\n\tC ";
+ for (j=0; j<3 && i<pEmr->cptl; j++,i++) {
+ tmp_str <<
+ pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[i].y ) << " ";
+ }
+ }
+
+ *(d->outsvg) += tmp_str.str().c_str();
+ *(d->outsvg) += " \" /> \n";
+
+ break;
+ }
+ case EMR_POLYGON:
+ {
+ EMRPOLYGON *pEmr = (EMRPOLYGON *) lpEMFR;
+ DWORD i;
+
+ if (pEmr->cptl < 2)
+ break;
+
+ *(d->outsvg) += " <path ";
+ output_style(d, EMR_STROKEANDFILLPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ tmp_str <<
+ "\n\tM " <<
+ pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[0].y ) << " ";
+
+ for (i=1; i<pEmr->cptl; i++) {
+ tmp_str <<
+ "\n\tL " <<
+ pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[i].y ) << " ";
+ }
+
+ *(d->outsvg) += tmp_str.str().c_str();
+ *(d->outsvg) += " z \" /> \n";
+
+ break;
+ }
+ case EMR_POLYLINE:
+ {
+ EMRPOLYLINE *pEmr = (EMRPOLYLINE *) lpEMFR;
+ DWORD i;
+
+ if (pEmr->cptl<2)
+ break;
+
+ *(d->outsvg) += " <path ";
+ output_style(d, EMR_STROKEPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ tmp_str <<
+ "\n\tM " <<
+ pix_x_to_point( d, pEmr->aptl[0].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[0].y ) << " ";
+
+ for (i=1; i<pEmr->cptl; i++) {
+ tmp_str <<
+ "\n\tL " <<
+ pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[i].y ) << " ";
+ }
+
+ *(d->outsvg) += tmp_str.str().c_str();
+ *(d->outsvg) += " \" /> \n";
+
+ break;
+ }
+ case EMR_POLYBEZIERTO:
+ {
+ PEMRPOLYBEZIERTO pEmr = (PEMRPOLYBEZIERTO) lpEMFR;
+ DWORD i,j;
+
+ for (i=0; i<pEmr->cptl;) {
+ tmp_path << "\n\tC ";
+ for (j=0; j<3 && i<pEmr->cptl; j++,i++) {
+ tmp_path <<
+ pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[i].y ) << " ";
+ }
+ }
+
+ break;
+ }
+ case EMR_POLYLINETO:
+ {
+ PEMRPOLYLINETO pEmr = (PEMRPOLYLINETO) lpEMFR;
+ DWORD i;
+
+ for (i=0; i<pEmr->cptl;i++) {
+ tmp_path <<
+ "\n\tL " <<
+ pix_x_to_point( d, pEmr->aptl[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->aptl[i].y ) << " ";
+ }
+
+ break;
+ }
+ case EMR_POLYPOLYLINE:
+ break;
+ case EMR_POLYPOLYGON:
+ break;
+ case EMR_SETWINDOWEXTEX:
+ {
+ PEMRSETWINDOWEXTEX pEmr = (PEMRSETWINDOWEXTEX) lpEMFR;
+
+ d->sizeWnd = pEmr->szlExtent;
+ d->PixelsX = d->sizeWnd.cx;
+ d->PixelsY = d->sizeWnd.cy;
+
+ d->ScaleX = d->xDPI / (100*d->MMX / d->PixelsX);
+ d->ScaleY = d->yDPI / (100*d->MMY / d->PixelsY);
+
+ break;
+ }
+ case EMR_SETWINDOWORGEX:
+ {
+ PEMRSETWINDOWORGEX pEmr = (PEMRSETWINDOWORGEX) lpEMFR;
+ d->winorg = pEmr->ptlOrigin;
+ break;
+ }
+ case EMR_SETVIEWPORTEXTEX:
+ {
+ PEMRSETVIEWPORTEXTEX pEmr = (PEMRSETVIEWPORTEXTEX) lpEMFR;
+
+ d->sizeView = pEmr->szlExtent;
+
+ if (d->sizeWnd.cx && d->sizeWnd.cy) {
+ HDC hScreenDC = GetDC( NULL );
+
+ float scrPixelsX = (float)GetDeviceCaps( hScreenDC, HORZRES );
+ float scrPixelsY = (float)GetDeviceCaps( hScreenDC, VERTRES );
+ float scrMMX = (float)GetDeviceCaps( hScreenDC, HORZSIZE );
+ float scrMMY = (float)GetDeviceCaps( hScreenDC, VERTSIZE );
+
+ ReleaseDC( NULL, hScreenDC );
+
+ d->dwInchesX = d->sizeView.cx / (25.4f*scrPixelsX/scrMMX);
+ d->dwInchesY = d->sizeView.cy / (25.4f*scrPixelsY/scrMMY);
+ d->xDPI = d->sizeWnd.cx / d->dwInchesX;
+ d->yDPI = d->sizeWnd.cy / d->dwInchesY;
+
+ if (1) {
+ d->xDPI = 2540;
+ d->yDPI = 2540;
+ d->dwInchesX = d->PixelsX / d->xDPI;
+ d->dwInchesY = d->PixelsY / d->yDPI;
+ d->ScaleX = d->xDPI;
+ d->ScaleY = d->yDPI;
+ }
+
+ d->MMX = d->dwInchesX * MM_PER_IN;
+ d->MMY = d->dwInchesY * MM_PER_IN;
+ }
+
+ break;
+ }
+ case EMR_SETVIEWPORTORGEX:
+ {
+ PEMRSETVIEWPORTORGEX pEmr = (PEMRSETVIEWPORTORGEX) lpEMFR;
+ d->vieworg = pEmr->ptlOrigin;
+ break;
+ }
+ case EMR_SETBRUSHORGEX:
+ break;
+ case EMR_EOF:
+ {
+ tmp_outsvg << "</svg>\n";
+ break;
+ }
+ case EMR_SETPIXELV:
+ break;
+ case EMR_SETMAPPERFLAGS:
+ break;
+ case EMR_SETMAPMODE:
+ break;
+ case EMR_SETBKMODE:
+ break;
+ case EMR_SETPOLYFILLMODE:
+ {
+ PEMRSETPOLYFILLMODE pEmr = (PEMRSETPOLYFILLMODE) lpEMFR;
+ d->style.fill_rule.value =
+ (pEmr->iMode == WINDING ? 0 :
+ pEmr->iMode == ALTERNATE ? 1 : 0);
+ break;
+ }
+ case EMR_SETROP2:
+ break;
+ case EMR_SETSTRETCHBLTMODE:
+ break;
+ case EMR_SETTEXTALIGN:
+ break;
+ case EMR_SETCOLORADJUSTMENT:
+ break;
+ case EMR_SETTEXTCOLOR:
+ break;
+ case EMR_SETBKCOLOR:
+ break;
+ case EMR_OFFSETCLIPRGN:
+ break;
+ case EMR_MOVETOEX:
+ {
+ PEMRMOVETOEX pEmr = (PEMRMOVETOEX) lpEMFR;
+ tmp_path <<
+ "\n\tM " <<
+ pix_x_to_point( d, pEmr->ptl.x ) << " " <<
+ pix_y_to_point( d, pEmr->ptl.y ) << " ";
+ break;
+ }
+ case EMR_SETMETARGN:
+ break;
+ case EMR_EXCLUDECLIPRECT:
+ break;
+ case EMR_INTERSECTCLIPRECT:
+ break;
+ case EMR_SCALEVIEWPORTEXTEX:
+ break;
+ case EMR_SCALEWINDOWEXTEX:
+ break;
+ case EMR_SAVEDC:
+ break;
+ case EMR_RESTOREDC:
+ break;
+ case EMR_SETWORLDTRANSFORM:
+ break;
+ case EMR_MODIFYWORLDTRANSFORM:
+ break;
+ case EMR_SELECTOBJECT:
+ {
+ PEMRSELECTOBJECT pEmr = (PEMRSELECTOBJECT) lpEMFR;
+ unsigned int index = pEmr->ihObject;
+
+ if (index >= ENHMETA_STOCK_OBJECT) {
+ index -= ENHMETA_STOCK_OBJECT;
+ switch (index) {
+ case NULL_BRUSH:
+ d->fill_set = false;
+ break;
+ case BLACK_BRUSH:
+ case DKGRAY_BRUSH:
+ case GRAY_BRUSH:
+ case LTGRAY_BRUSH:
+ case WHITE_BRUSH:
+ {
+ float val = 0;
+ switch (index) {
+ case BLACK_BRUSH:
+ val = 0.0 / 255.0;
+ break;
+ case DKGRAY_BRUSH:
+ val = 64.0 / 255.0;
+ break;
+ case GRAY_BRUSH:
+ val = 128.0 / 255.0;
+ break;
+ case LTGRAY_BRUSH:
+ val = 192.0 / 255.0;
+ break;
+ case WHITE_BRUSH:
+ val = 255.0 / 255.0;
+ break;
+ }
+ sp_color_set_rgb_float( &(d->style.fill.value.color), val,val,val );
+
+ d->fill_set = true;
+ break;
+ }
+ case NULL_PEN:
+ d->stroke_set = false;
+ break;
+ case BLACK_PEN:
+ case WHITE_PEN:
+ {
+ float val = index == BLACK_PEN ? 0 : 1;
+ d->style.stroke_dasharray_set = 0;
+ d->style.stroke_width.value = 1.0;
+ sp_color_set_rgb_float( &(d->style.stroke.value.color), val,val,val );
+
+ d->stroke_set = true;
+
+ break;
+ }
+ }
+ } else {
+ if (index >= 0 && index < d->n_obj) {
+ switch (d->emf_obj[index].type)
+ {
+ case EMR_CREATEPEN:
+ select_pen(d, index);
+ break;
+ case EMR_CREATEBRUSHINDIRECT:
+ select_brush(d, index);
+ break;
+ case EMR_EXTCREATEPEN:
+ select_extpen(d, index);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case EMR_CREATEPEN:
+ {
+ PEMRCREATEPEN pEmr = (PEMRCREATEPEN) lpEMFR;
+ int index = pEmr->ihPen;
+
+ EMRCREATEPEN *pPen =
+ (EMRCREATEPEN *) malloc( sizeof(EMREXTCREATEPEN) );
+ pPen->lopn = pEmr->lopn;
+ insert_object(d, index, EMR_CREATEPEN, (ENHMETARECORD *) pPen);
+
+ break;
+ }
+ case EMR_CREATEBRUSHINDIRECT:
+ {
+ PEMRCREATEBRUSHINDIRECT pEmr = (PEMRCREATEBRUSHINDIRECT) lpEMFR;
+ int index = pEmr->ihBrush;
+
+ EMRCREATEBRUSHINDIRECT *pBrush =
+ (EMRCREATEBRUSHINDIRECT *) malloc( sizeof(EMRCREATEBRUSHINDIRECT) );
+ pBrush->lb = pEmr->lb;
+ insert_object(d, index, EMR_CREATEBRUSHINDIRECT, (ENHMETARECORD *) pBrush);
+
+ break;
+ }
+ case EMR_DELETEOBJECT:
+ break;
+ case EMR_ANGLEARC:
+ break;
+ case EMR_ELLIPSE:
+ break;
+ case EMR_RECTANGLE:
+ break;
+ case EMR_ROUNDRECT:
+ break;
+ case EMR_ARC:
+ break;
+ case EMR_CHORD:
+ break;
+ case EMR_PIE:
+ break;
+ case EMR_SELECTPALETTE:
+ break;
+ case EMR_CREATEPALETTE:
+ break;
+ case EMR_SETPALETTEENTRIES:
+ break;
+ case EMR_RESIZEPALETTE:
+ break;
+ case EMR_REALIZEPALETTE:
+ break;
+ case EMR_EXTFLOODFILL:
+ break;
+ case EMR_LINETO:
+ {
+ PEMRLINETO pEmr = (PEMRLINETO) lpEMFR;
+ tmp_path <<
+ "\n\tL " <<
+ pix_x_to_point( d, pEmr->ptl.x ) << " " <<
+ pix_y_to_point( d, pEmr->ptl.y ) << " ";
+ break;
+ }
+ case EMR_ARCTO:
+ break;
+ case EMR_POLYDRAW:
+ break;
+ case EMR_SETARCDIRECTION:
+ break;
+ case EMR_SETMITERLIMIT:
+ {
+ PEMRSETMITERLIMIT pEmr = (PEMRSETMITERLIMIT) lpEMFR;
+ d->style.stroke_miterlimit.value = pix_size_to_point( d, pEmr->eMiterLimit );
+
+ if (d->style.stroke_miterlimit.value < 1)
+ d->style.stroke_miterlimit.value = 1.0;
+
+ break;
+ }
+ case EMR_BEGINPATH:
+ {
+ tmp_path << " d=\"";
+ *(d->path) = "";
+ break;
+ }
+ case EMR_ENDPATH:
+ {
+ tmp_path << "\"";
+ break;
+ }
+ case EMR_CLOSEFIGURE:
+ {
+ tmp_path << "\n\tz";
+ break;
+ }
+ case EMR_FILLPATH:
+ case EMR_STROKEANDFILLPATH:
+ case EMR_STROKEPATH:
+ {
+ *(d->outsvg) += " <path ";
+ output_style(d, lpEMFR->iType);
+ *(d->outsvg) += "\n\t";
+ *(d->outsvg) += *(d->path);
+ *(d->outsvg) += " /> \n";
+ break;
+ }
+ case EMR_FLATTENPATH:
+ break;
+ case EMR_WIDENPATH:
+ break;
+ case EMR_SELECTCLIPPATH:
+ break;
+ case EMR_ABORTPATH:
+ break;
+ case EMR_GDICOMMENT:
+ break;
+ case EMR_FILLRGN:
+ break;
+ case EMR_FRAMERGN:
+ break;
+ case EMR_INVERTRGN:
+ break;
+ case EMR_PAINTRGN:
+ break;
+ case EMR_EXTSELECTCLIPRGN:
+ break;
+ case EMR_BITBLT:
+ break;
+ case EMR_STRETCHBLT:
+ break;
+ case EMR_MASKBLT:
+ break;
+ case EMR_PLGBLT:
+ break;
+ case EMR_SETDIBITSTODEVICE:
+ break;
+ case EMR_STRETCHDIBITS:
+ break;
+ case EMR_EXTCREATEFONTINDIRECTW:
+ break;
+ case EMR_EXTTEXTOUTA:
+ break;
+ case EMR_EXTTEXTOUTW:
+ break;
+ case EMR_POLYBEZIER16:
+ {
+ PEMRPOLYBEZIER16 pEmr = (PEMRPOLYBEZIER16) lpEMFR;
+ POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?
+ DWORD i,j;
+
+ if (pEmr->cpts<4)
+ break;
+
+ *(d->outsvg) += " <path ";
+ output_style(d, EMR_STROKEPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ tmp_str <<
+ "\n\tM " <<
+ pix_x_to_point( d, apts[0].x ) << " " <<
+ pix_y_to_point( d, apts[0].y ) << " ";
+
+ for (i=1; i<pEmr->cpts; ) {
+ tmp_str << "\n\tC ";
+ for (j=0; j<3 && i<pEmr->cpts; j++,i++) {
+ tmp_str <<
+ pix_x_to_point( d, apts[i].x ) << " " <<
+ pix_y_to_point( d, apts[i].y ) << " ";
+ }
+ }
+
+ *(d->outsvg) += tmp_str.str().c_str();
+ *(d->outsvg) += " \" /> \n";
+
+ break;
+ }
+ case EMR_POLYGON16:
+ {
+ PEMRPOLYGON16 pEmr = (PEMRPOLYGON16) lpEMFR;
+ POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?
+ unsigned int i;
+
+ *(d->outsvg) += "<path ";
+ output_style(d, EMR_STROKEANDFILLPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ // skip the first point?
+ tmp_path << "\n\tM " <<
+ pix_x_to_point( d, apts[1].x ) << " " <<
+ pix_y_to_point( d, apts[1].y ) << " ";
+
+ for (i=2; i<pEmr->cpts; i++) {
+ tmp_path << "\n\tL " <<
+ pix_x_to_point( d, apts[i].x ) << " " <<
+ pix_y_to_point( d, apts[i].y ) << " ";
+ }
+
+ *(d->outsvg) += tmp_path.str().c_str();
+ *(d->outsvg) += " z \" /> \n";
+
+ break;
+ }
+ case EMR_POLYLINE16:
+ {
+ EMRPOLYLINE16 *pEmr = (EMRPOLYLINE16 *) lpEMFR;
+ POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?
+ DWORD i;
+
+ if (pEmr->cpts<2)
+ break;
+
+ *(d->outsvg) += " <path ";
+ output_style(d, EMR_STROKEPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ tmp_str <<
+ "\n\tM " <<
+ pix_x_to_point( d, apts[0].x ) << " " <<
+ pix_y_to_point( d, apts[0].y ) << " ";
+
+ for (i=1; i<pEmr->cpts; i++) {
+ tmp_str <<
+ "\n\tL " <<
+ pix_x_to_point( d, apts[i].x ) << " " <<
+ pix_y_to_point( d, apts[i].y ) << " ";
+ }
+
+ *(d->outsvg) += tmp_str.str().c_str();
+ *(d->outsvg) += " \" /> \n";
+
+ break;
+ }
+ case EMR_POLYBEZIERTO16:
+ {
+ PEMRPOLYBEZIERTO16 pEmr = (PEMRPOLYBEZIERTO16) lpEMFR;
+ POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?
+ DWORD i,j;
+
+ for (i=0; i<pEmr->cpts;) {
+ tmp_path << "\n\tC ";
+ for (j=0; j<3 && i<pEmr->cpts; j++,i++) {
+ tmp_path <<
+ pix_x_to_point( d, apts[i].x ) << " " <<
+ pix_y_to_point( d, apts[i].y ) << " ";
+ }
+ }
+
+ break;
+ }
+ case EMR_POLYLINETO16:
+ {
+ PEMRPOLYLINETO16 pEmr = (PEMRPOLYLINETO16) lpEMFR;
+ POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ?
+ DWORD i;
+
+ for (i=0; i<pEmr->cpts;i++) {
+ tmp_path <<
+ "\n\tL " <<
+ pix_x_to_point( d, apts[i].x ) << " " <<
+ pix_y_to_point( d, apts[i].y ) << " ";
+ }
+
+ break;
+ }
+ case EMR_POLYPOLYLINE16:
+ break;
+ case EMR_POLYPOLYGON16:
+ {
+ PEMRPOLYPOLYGON16 pEmr = (PEMRPOLYPOLYGON16) lpEMFR;
+ unsigned int n, i, j;
+
+ *(d->outsvg) += "<path ";
+ output_style(d, EMR_STROKEANDFILLPATH);
+ *(d->outsvg) += "\n\td=\"";
+
+ i = pEmr->nPolys-1; // ???
+ for (n=0; n<pEmr->nPolys /*&& i<pEmr->cpts*/; n++) {
+ SVGOStringStream poly_path;
+
+ poly_path << "\n\tM " <<
+ pix_x_to_point( d, pEmr->apts[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->apts[i].y ) << " ";
+ i++;
+
+ for (j=1; j<pEmr->aPolyCounts[n] /*&& i<pEmr->cpts*/; j++) {
+ poly_path << "\n\tL " <<
+ pix_x_to_point( d, pEmr->apts[i].x ) << " " <<
+ pix_y_to_point( d, pEmr->apts[i].y ) << " ";
+ i++;
+ }
+
+ *(d->outsvg) += poly_path.str().c_str();
+ *(d->outsvg) += " z \n";
+ }
+
+ *(d->outsvg) += " \" /> \n";
+ break;
+ }
+ case EMR_POLYDRAW16:
+ break;
+ case EMR_CREATEMONOBRUSH:
+ break;
+ case EMR_CREATEDIBPATTERNBRUSHPT:
+ break;
+ case EMR_EXTCREATEPEN:
+ {
+ PEMREXTCREATEPEN pEmr = (PEMREXTCREATEPEN) lpEMFR;
+ int index = pEmr->ihPen;
+
+ EMREXTCREATEPEN *pPen =
+ (EMREXTCREATEPEN *) malloc( sizeof(EMREXTCREATEPEN) +
+ sizeof(DWORD) * pEmr->elp.elpNumEntries );
+ pPen->ihPen = pEmr->ihPen;
+ pPen->offBmi = pEmr->offBmi;
+ pPen->cbBmi = pEmr->cbBmi;
+ pPen->offBits = pEmr->offBits;
+ pPen->cbBits = pEmr->cbBits;
+ pPen->elp = pEmr->elp;
+ for (unsigned int i=0; i<pEmr->elp.elpNumEntries; i++) {
+ pPen->elp.elpStyleEntry[i] = pEmr->elp.elpStyleEntry[i];
+ }
+ insert_object(d, index, EMR_EXTCREATEPEN, (ENHMETARECORD *) pPen);
+
+ break;
+ }
+ case EMR_POLYTEXTOUTA:
+ break;
+ case EMR_POLYTEXTOUTW:
+ break;
+ case EMR_SETICMMODE:
+ break;
+ case EMR_CREATECOLORSPACE:
+ break;
+ case EMR_SETCOLORSPACE:
+ break;
+ case EMR_DELETECOLORSPACE:
+ break;
+ case EMR_GLSRECORD:
+ break;
+ case EMR_GLSBOUNDEDRECORD:
+ break;
+ case EMR_PIXELFORMAT:
+ break;
+ }
+
+ *(d->outsvg) += tmp_outsvg.str().c_str();
+ *(d->path) += tmp_path.str().c_str();
+
+ return 1;
+}
+
+
+// Aldus Placeable Header ===================================================
+// Since we are a 32bit app, we have to be sure this structure compiles to
+// be identical to a 16 bit app's version. To do this, we use the #pragma
+// to adjust packing, we use a WORD for the hmf handle, and a SMALL_RECT
+// for the bbox rectangle.
+#pragma pack( push )
+#pragma pack( 2 )
+typedef struct
+{
+ DWORD dwKey;
+ WORD hmf;
+ SMALL_RECT bbox;
+ WORD wInch;
+ DWORD dwReserved;
+ WORD wCheckSum;
+} APMHEADER, *PAPMHEADER;
+#pragma pack( pop )
+
+
+SPDocument *
+EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri )
+{
+ EMF_CALLBACK_DATA d = {0};
+
+ gsize bytesRead = 0;
+ gsize bytesWritten = 0;
+ GError* error = NULL;
+ gchar *local_fn =
+ g_filename_from_utf8( uri, -1, &bytesRead, &bytesWritten, &error );
+
+ if (local_fn == NULL) {
+ return NULL;
+ }
+
+ d.outsvg = new Glib::ustring("");
+ d.path = new Glib::ustring("");
+
+ CHAR *ansi_uri = (CHAR *) local_fn;
+ gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
+ WCHAR *unicode_uri = (WCHAR *) unicode_fn;
+
+ // Try open as Enhanced Metafile
+ HENHMETAFILE hemf;
+ if (PrintWin32::is_os_wide())
+ hemf = GetEnhMetaFileW(unicode_uri);
+ else
+ hemf = GetEnhMetaFileA(ansi_uri);
+
+ if (!hemf) {
+ // Try open as Windows Metafile
+ HMETAFILE hmf;
+ if (PrintWin32::is_os_wide())
+ hmf = GetMetaFileW(unicode_uri);
+ else
+ hmf = GetMetaFileA(ansi_uri);
+
+ METAFILEPICT mp;
+ HDC hDC;
+
+ if (!hmf) {
+ if (PrintWin32::is_os_wide()) {
+ WCHAR szTemp[MAX_PATH];
+
+ DWORD dw = GetShortPathNameW( unicode_uri, szTemp, MAX_PATH );
+ if (dw) {
+ hmf = GetMetaFileW( szTemp );
+ }
+ } else {
+ CHAR szTemp[MAX_PATH];
+
+ DWORD dw = GetShortPathNameA( ansi_uri, szTemp, MAX_PATH );
+ if (dw) {
+ hmf = GetMetaFileA( szTemp );
+ }
+ }
+ }
+
+ if (hmf) {
+ DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
+ if (nSize) {
+ BYTE *lpvData = new BYTE[nSize];
+ if (lpvData) {
+ DWORD dw = GetMetaFileBitsEx( hmf, nSize, lpvData );
+ if (dw) {
+ // Fill out a METAFILEPICT structure
+ mp.mm = MM_ANISOTROPIC;
+ mp.xExt = 1000;
+ mp.yExt = 1000;
+ mp.hMF = NULL;
+ // Get a reference DC
+ hDC = GetDC( NULL );
+ // Make an enhanced metafile from the windows metafile
+ hemf = SetWinMetaFileBits( nSize, lpvData, hDC, &mp );
+ // Clean up
+ ReleaseDC( NULL, hDC );
+ }
+ delete[] lpvData;
+ }
+ DeleteMetaFile( hmf );
+ }
+ } else {
+ // Try open as Aldus Placeable Metafile
+ HANDLE hFile;
+ if (PrintWin32::is_os_wide())
+ hFile = CreateFileW( unicode_uri, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ else
+ hFile = CreateFileA( ansi_uri, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if (hFile != INVALID_HANDLE_VALUE) {
+ DWORD nSize = GetFileSize( hFile, NULL );
+ if (nSize) {
+ BYTE *lpvData = new BYTE[nSize];
+ if (lpvData) {
+ DWORD dw = ReadFile( hFile, lpvData, nSize, &nSize, NULL );
+ if (dw) {
+ if ( ((PAPMHEADER)lpvData)->dwKey == 0x9ac6cdd7l ) {
+ // Fill out a METAFILEPICT structure
+ mp.mm = MM_ANISOTROPIC;
+ mp.xExt = ((PAPMHEADER)lpvData)->bbox.Right - ((PAPMHEADER)lpvData)->bbox.Left;
+ mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);
+ mp.yExt = ((PAPMHEADER)lpvData)->bbox.Bottom - ((PAPMHEADER)lpvData)->bbox.Top;
+ mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);
+ mp.hMF = NULL;
+ // Get a reference DC
+ hDC = GetDC( NULL );
+ // Create an enhanced metafile from the bits
+ hemf = SetWinMetaFileBits( nSize, lpvData+sizeof(APMHEADER), hDC, &mp );
+ // Clean up
+ ReleaseDC( NULL, hDC );
+ }
+ }
+ delete[] lpvData;
+ }
+ }
+ CloseHandle( hFile );
+ }
+ }
+ }
+
+ if (!hemf || !d.outsvg || !d.path) {
+ if (d.outsvg)
+ delete d.outsvg;
+ if (d.path)
+ delete d.path;
+ if (local_fn)
+ g_free(local_fn);
+ if (unicode_fn)
+ g_free(unicode_fn);
+ return NULL;
+ }
+
+ EnumEnhMetaFile(NULL, hemf, myEnhMetaFileProc, (LPVOID) &d, NULL);
+ DeleteEnhMetaFile(hemf);
+
+// std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl;
+
+ SPDocument *doc = sp_document_new_from_mem(d.outsvg->c_str(), d.outsvg->length(), TRUE);
+
+ delete d.outsvg;
+ delete d.path;
+
+ if (d.emf_obj) {
+ int i;
+ for (i=0; i<d.n_obj; i++)
+ delete_object(&d, i);
+ delete[] d.emf_obj;
+ }
+
+ if (d.style.stroke_dash.dash)
+ delete[] d.style.stroke_dash.dash;
+
+ if (local_fn)
+ g_free(local_fn);
+ if (unicode_fn)
+ g_free(unicode_fn);
+
+ return doc;
+}
+
+
+void
+EmfWin32::init (void)
+{
+ Inkscape::Extension::Extension * ext;
+
+ /* EMF in */
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>" N_("EMF Input") "</name>\n"
+ "<id>org.inkscape.input.emf.win32</id>\n"
+ "<input>\n"
+ "<extension>.emf</extension>\n"
+ "<mimetype>image/x-emf</mimetype>\n"
+ "<filetypename>" N_("Enhanced Metafiles (*.emf)") "</filetypename>\n"
+ "<filetypetooltip>" N_("Enhanced Metafiles") "</filetypetooltip>\n"
+ "<output_extension>org.inkscape.output.emf.win32</output_extension>\n"
+ "</input>\n"
+ "</inkscape-extension>", new EmfWin32());
+
+ /* WMF in */
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>" N_("WMF Input") "</name>\n"
+ "<id>org.inkscape.input.wmf.win32</id>\n"
+ "<input>\n"
+ "<extension>.wmf</extension>\n"
+ "<mimetype>image/x-wmf</mimetype>\n"
+ "<filetypename>" N_("Windows Metafiles (*.wmf)") "</filetypename>\n"
+ "<filetypetooltip>" N_("Windows Metafiles") "</filetypetooltip>\n"
+ "<output_extension>org.inkscape.output.emf.win32</output_extension>\n"
+ "</input>\n"
+ "</inkscape-extension>", new EmfWin32());
+
+ /* EMF out */
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>" N_("EMF Output") "</name>\n"
+ "<id>org.inkscape.output.emf.win32</id>\n"
+ "<output>\n"
+ "<extension>.emf</extension>\n"
+ "<mimetype>image/x-emf</mimetype>\n"
+ "<filetypename>" N_("Enhanced Metafile (*.emf)") "</filetypename>\n"
+ "<filetypetooltip>" N_("Enhanced Metafile") "</filetypetooltip>\n"
+ "</output>\n"
+ "</inkscape-extension>", new EmfWin32());
+
+ return;
+}
+
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+
+#endif /* WIN32 */
+
+
+/*
+ Local Variables:
+ mode:cpp
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index eff8500493ef97ef1dda3cd8f9d3312fdb4b9094..3ec81b6b542019d597ad7c2ae41e2f5bb41786e0 100644 (file)
-/*\r
- * Enhanced Metafile Input/Output.\r
- *\r
- * Authors:\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef EXTENSION_INTERNAL_EMF_WIN32_H\r
-#define EXTENSION_INTERNAL_EMF_WIN32_H\r
-\r
-#ifdef WIN32\r
-\r
-#include "extension/implementation/implementation.h"\r
-#include "style.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class EmfWin32 : Inkscape::Extension::Implementation::Implementation { //This is a derived class\r
-\r
-public:\r
- EmfWin32(); // Empty constructor\r
-\r
- virtual ~EmfWin32();//Destructor\r
-\r
- bool check(Inkscape::Extension::Extension *module); //Can this module load (always yes for now)\r
-\r
- void save(Inkscape::Extension::Output *mod, // Save the given document to the given filename\r
- SPDocument *doc,\r
- gchar const *uri);\r
-\r
- virtual SPDocument *open( Inkscape::Extension::Input *mod,\r
- const gchar *uri );\r
-\r
- static void init(void);//Initialize the class\r
-\r
-private:\r
-};\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-#endif /* WIN32 */\r
-\r
-#endif /* EXTENSION_INTERNAL_EMF_WIN32_H */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+/*
+ * Enhanced Metafile Input/Output.
+ *
+ * Authors:
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef EXTENSION_INTERNAL_EMF_WIN32_H
+#define EXTENSION_INTERNAL_EMF_WIN32_H
+
+#ifdef WIN32
+
+#include "extension/implementation/implementation.h"
+#include "style.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class EmfWin32 : Inkscape::Extension::Implementation::Implementation { //This is a derived class
+
+public:
+ EmfWin32(); // Empty constructor
+
+ virtual ~EmfWin32();//Destructor
+
+ bool check(Inkscape::Extension::Extension *module); //Can this module load (always yes for now)
+
+ void save(Inkscape::Extension::Output *mod, // Save the given document to the given filename
+ SPDocument *doc,
+ gchar const *uri);
+
+ virtual SPDocument *open( Inkscape::Extension::Input *mod,
+ const gchar *uri );
+
+ static void init(void);//Initialize the class
+
+private:
+};
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+#endif /* WIN32 */
+
+#endif /* EXTENSION_INTERNAL_EMF_WIN32_H */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp
index b40eec46297f540cddbde7e5764009ac2a066b07..9b1b77f160e08effff9b78c2ea28c6e1059044e5 100644 (file)
-/** \file\r
- * Enhanced Metafile Printing.\r
- */\r
-/*\r
- * Authors:\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-/*\r
- * References:\r
- * - How to Create & Play Enhanced Metafiles in Win32\r
- * http://support.microsoft.com/kb/q145999/\r
- * - INFO: Windows Metafile Functions & Aldus Placeable Metafiles\r
- * http://support.microsoft.com/kb/q66949/\r
- * - Metafile Functions\r
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp\r
- * - Metafile Structures\r
- * http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp\r
- */\r
-\r
-#ifdef WIN32\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-#include <string.h>\r
-#include <signal.h>\r
-#include <errno.h>\r
-\r
-#include "libnr/n-art-bpath.h"\r
-#include "libnr/nr-point-matrix-ops.h"\r
-#include "libnr/nr-rect.h"\r
-#include "libnr/nr-matrix.h"\r
-#include "libnr/nr-matrix-fns.h"\r
-#include "libnr/nr-path.h"\r
-#include "libnr/nr-pixblock.h"\r
-#include "display/canvas-bpath.h"\r
-#include "sp-item.h"\r
-\r
-#include "glib.h"\r
-#include "gtk/gtkdialog.h"\r
-#include "gtk/gtkbox.h"\r
-#include "gtk/gtkstock.h"\r
-\r
-#include "glibmm/i18n.h"\r
-#include "enums.h"\r
-#include "document.h"\r
-#include "style.h"\r
-#include "sp-paint-server.h"\r
-#include "inkscape_version.h"\r
-\r
-#include "win32.h"\r
-#include "emf-win32-print.h"\r
-\r
-#include "unit-constants.h"\r
-\r
-#include "extension/extension.h"\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-\r
-#include "io/sys.h"\r
-\r
-#include "macros.h"\r
-\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-static float dwDPI = 2540;\r
-\r
-\r
-PrintEmfWin32::PrintEmfWin32 (void):\r
- hdc(NULL),\r
- hbrush(NULL),\r
- hpen(NULL),\r
- fill_path(NULL)\r
-{\r
-}\r
-\r
-\r
-PrintEmfWin32::~PrintEmfWin32 (void)\r
-{\r
- if (hdc) {\r
- HENHMETAFILE metafile = CloseEnhMetaFile( hdc );\r
- if ( metafile ) {\r
- DeleteEnhMetaFile( metafile );\r
- }\r
- DeleteDC( hdc );\r
- }\r
-\r
- /* restore default signal handling for SIGPIPE */\r
-#if !defined(_WIN32) && !defined(__WIN32__)\r
- (void) signal(SIGPIPE, SIG_DFL);\r
-#endif\r
- return;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::setup (Inkscape::Extension::Print *mod)\r
-{\r
- return TRUE;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)\r
-{\r
- gchar const *utf8_fn = mod->get_param_string("destination");\r
-\r
- gsize bytesRead = 0;\r
- gsize bytesWritten = 0;\r
- GError* error = NULL;\r
- gchar *local_fn =\r
- g_filename_from_utf8( utf8_fn, -1, &bytesRead, &bytesWritten, &error );\r
-\r
- if (local_fn == NULL) {\r
- return 1;\r
- }\r
-\r
- CHAR *ansi_uri = (CHAR *) local_fn;\r
- gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );\r
- WCHAR *unicode_uri = (WCHAR *) unicode_fn;\r
-\r
- // width and height in px\r
- _width = sp_document_width(doc);\r
- _height = sp_document_height(doc);\r
-\r
- NRRect d;\r
- bool pageBoundingBox;\r
- pageBoundingBox = mod->get_param_bool("pageBoundingBox");\r
- if (pageBoundingBox) {\r
- d.x0 = d.y0 = 0;\r
- d.x1 = _width;\r
- d.y1 = _height;\r
- } else {\r
- SPItem* doc_item = SP_ITEM(sp_document_root(doc));\r
- sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE);\r
- }\r
-\r
- d.x0 *= IN_PER_PX;\r
- d.y0 *= IN_PER_PX;\r
- d.x1 *= IN_PER_PX;\r
- d.y1 *= IN_PER_PX;\r
-\r
- float dwInchesX = (d.x1 - d.x0);\r
- float dwInchesY = (d.y1 - d.y0);\r
-\r
- // dwInchesX x dwInchesY in .01mm units\r
- SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );\r
-\r
- // Get a Reference DC\r
- HDC hScreenDC = GetDC( NULL );\r
-\r
- // Get the physical characteristics of the reference DC\r
- float PixelsX = (float) GetDeviceCaps( hScreenDC, HORZRES );\r
- float PixelsY = (float) GetDeviceCaps( hScreenDC, VERTRES );\r
- float MMX = (float) GetDeviceCaps( hScreenDC, HORZSIZE );\r
- float MMY = (float) GetDeviceCaps( hScreenDC, VERTSIZE );\r
-\r
- // Create the Metafile\r
- if (PrintWin32::is_os_wide())\r
- hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, NULL );\r
- else\r
- hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, NULL );\r
-\r
- // Release the reference DC\r
- ReleaseDC( NULL, hScreenDC );\r
-\r
- // Did we get a good metafile?\r
- if (hdc == NULL)\r
- {\r
- g_free(local_fn);\r
- g_free(unicode_fn);\r
- return 1;\r
- }\r
-\r
- // Anisotropic mapping mode\r
- SetMapMode( hdc, MM_ANISOTROPIC );\r
-\r
- // Set the Windows extent\r
- SetWindowExtEx( hdc, (int) (dwInchesX*dwDPI), (int) (dwInchesY*dwDPI), NULL );\r
-\r
- // Set the viewport extent to reflect\r
- // dwInchesX" x dwInchesY" in device units\r
- SetViewportExtEx( hdc,\r
- (int) ((float) dwInchesX*25.4f*PixelsX/MMX),\r
- (int) ((float) dwInchesY*25.4f*PixelsY/MMY),\r
- NULL );\r
-\r
- SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) );\r
-\r
- g_free(local_fn);\r
- g_free(unicode_fn);\r
-\r
- return 0;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::finish (Inkscape::Extension::Print *mod)\r
-{\r
- if (!hdc) return 0;\r
-\r
- flush_fill(); // flush any pending fills\r
-\r
- HENHMETAFILE metafile = CloseEnhMetaFile( hdc );\r
- if ( metafile ) {\r
- DeleteEnhMetaFile( metafile );\r
- }\r
- DeleteDC( hdc );\r
-\r
- hdc = NULL;\r
-\r
- return 0;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::comment (Inkscape::Extension::Print * module,\r
- const char *comment)\r
-{\r
- if (!hdc) return 0;\r
-\r
- flush_fill(); // flush any pending fills\r
-\r
- return 0;\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::create_brush(SPStyle const *style)\r
-{\r
- float rgb[3];\r
-\r
- if (style) {\r
- sp_color_get_rgb_floatv( &style->fill.value.color, rgb );\r
- hbrush = CreateSolidBrush( RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]) );\r
- hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );\r
-\r
- SetPolyFillMode( hdc,\r
- style->fill_rule.computed == 0 ? WINDING :\r
- style->fill_rule.computed == 2 ? ALTERNATE : ALTERNATE );\r
- } else { // if (!style)\r
- hbrush = CreateSolidBrush( RGB(255, 255, 255) );\r
- hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );\r
- SetPolyFillMode( hdc, ALTERNATE );\r
- }\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::destroy_brush()\r
-{\r
- SelectObject( hdc, hbrushOld );\r
- if (hbrush)\r
- DeleteObject( hbrush );\r
- hbrush = NULL;\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::create_pen(SPStyle const *style)\r
-{\r
- if (style) {\r
- float rgb[3];\r
-\r
- sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);\r
-\r
- LOGBRUSH lb = {0};\r
- lb.lbStyle = BS_SOLID;\r
- lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] );\r
-\r
- int linestyle = PS_SOLID;\r
- int linecap = 0;\r
- int linejoin = 0;\r
- DWORD n_dash = 0;\r
- DWORD *dash = NULL;\r
- float oldmiterlimit;\r
-\r
- DWORD linewidth = MAX( 1, (DWORD) (style->stroke_width.computed * IN_PER_PX * dwDPI) );\r
-\r
- if (style->stroke_linecap.computed == 0) {\r
- linecap = PS_ENDCAP_FLAT;\r
- }\r
- else if (style->stroke_linecap.computed == 1) {\r
- linecap = PS_ENDCAP_ROUND;\r
- }\r
- else if (style->stroke_linecap.computed == 2) {\r
- linecap = PS_ENDCAP_SQUARE;\r
- }\r
-\r
- if (style->stroke_linejoin.computed == 0) {\r
- linejoin = PS_JOIN_MITER;\r
- }\r
- else if (style->stroke_linejoin.computed == 1) {\r
- linejoin = PS_JOIN_ROUND;\r
- }\r
- else if (style->stroke_linejoin.computed == 2) {\r
- linejoin = PS_JOIN_BEVEL;\r
- }\r
-\r
- if (style->stroke_dash.n_dash &&\r
- style->stroke_dash.dash )\r
- {\r
- int i = 0;\r
- while (linestyle != PS_USERSTYLE &&\r
- (i < style->stroke_dash.n_dash)) {\r
- if (style->stroke_dash.dash[i] > 0.00000001)\r
- linestyle = PS_USERSTYLE;\r
- i++;\r
- }\r
-\r
- if (linestyle == PS_USERSTYLE) {\r
- n_dash = style->stroke_dash.n_dash;\r
- dash = new DWORD[n_dash];\r
- for (i = 0; i < style->stroke_dash.n_dash; i++) {\r
- dash[i] = (DWORD) (style->stroke_dash.dash[i] * IN_PER_PX * dwDPI);\r
- }\r
- }\r
- }\r
-\r
- hpen = ExtCreatePen(\r
- PS_GEOMETRIC | linestyle | linecap | linejoin,\r
- linewidth,\r
- &lb,\r
- n_dash,\r
- dash );\r
-\r
- if ( !hpen && linestyle == PS_USERSTYLE ) {\r
- hpen = ExtCreatePen(\r
- PS_GEOMETRIC | PS_SOLID | linecap | linejoin,\r
- linewidth,\r
- &lb,\r
- 0,\r
- NULL );\r
- }\r
-\r
- if ( !hpen ) {\r
- hpen = CreatePen(\r
- PS_SOLID,\r
- linewidth,\r
- lb.lbColor );\r
- }\r
-\r
- hpenOld = (HPEN) SelectObject( hdc, hpen );\r
-\r
- if (linejoin == PS_JOIN_MITER) {\r
- float miterlimit = style->stroke_miterlimit.value;\r
- if (miterlimit < 1)\r
- miterlimit = 4.0;\r
- SetMiterLimit(\r
- hdc,\r
- miterlimit * IN_PER_PX * dwDPI,\r
- &oldmiterlimit );\r
- }\r
-\r
- if (n_dash) {\r
- delete[] dash;\r
- }\r
- }\r
- else { // if (!style)\r
- hpen = CreatePen( PS_SOLID, 1, RGB(0, 0, 0) );\r
- hpenOld = (HPEN) SelectObject( hdc, hpen );\r
- }\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::destroy_pen()\r
-{\r
- SelectObject( hdc, hpenOld );\r
- if (hpen)\r
- DeleteObject( hpen );\r
- hpen = NULL;\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::flush_fill()\r
-{\r
- if (fill_path) {\r
- print_bpath(fill_path, &fill_transform, &fill_pbox);\r
- FillPath( hdc );\r
- destroy_brush();\r
- delete[] fill_path;\r
- fill_path = NULL;\r
- }\r
-}\r
-\r
-\r
-NArtBpath *\r
-PrintEmfWin32::copy_bpath(const NArtBpath *bp)\r
-{\r
- NArtBpath *tmp = (NArtBpath *) bp;\r
- int num = 1;\r
- \r
- while (tmp->code != NR_END) {\r
- num++;\r
- tmp += 1;\r
- }\r
-\r
- tmp = new NArtBpath[num];\r
- while (num--) {\r
- tmp[num] = bp[num];\r
- }\r
-\r
- return tmp;\r
-}\r
-\r
-\r
-int\r
-PrintEmfWin32::cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2)\r
-{\r
- if (!bp1 || !bp2) {\r
- return 1;\r
- }\r
- \r
- while (bp1->code != NR_END && bp2->code != NR_END) {\r
- if (bp1->code != bp2->code) {\r
- return 1;\r
- }\r
-\r
- if ( fabs(bp1->x1 - bp2->x1) > 0.00000001 ||\r
- fabs(bp1->y1 - bp2->y1) > 0.00000001 ||\r
- fabs(bp1->x2 - bp2->x2) > 0.00000001 ||\r
- fabs(bp1->y2 - bp2->y2) > 0.00000001 ||\r
- fabs(bp1->x3 - bp2->x3) > 0.00000001 ||\r
- fabs(bp1->y3 - bp2->y3) > 0.00000001 )\r
- {\r
- return 1;\r
- }\r
- \r
- bp1 += 1;\r
- bp2 += 1;\r
- }\r
- \r
- return bp1->code != NR_END || bp2->code != NR_END;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::fill(Inkscape::Extension::Print *mod,\r
- NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style,\r
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)\r
-{\r
- if (!hdc) return 0;\r
-\r
- flush_fill(); // flush any pending fills\r
-\r
- if (style->fill.type == SP_PAINT_TYPE_COLOR) {\r
- create_brush(style);\r
- } else {\r
- // create_brush(NULL);\r
- return 0;\r
- }\r
-\r
- fill_path = copy_bpath( bpath->path );\r
- fill_transform = *transform;\r
- fill_pbox = *pbox;\r
-\r
- // postpone fill in case of stroke-and-fill\r
-\r
- return 0;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::stroke (Inkscape::Extension::Print *mod,\r
- const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,\r
- const NRRect *pbox, const NRRect *dbox, const NRRect *bbox)\r
-{\r
- if (!hdc) return 0;\r
-\r
- bool stroke_and_fill = ( cmp_bpath( bpath->path, fill_path ) == 0 );\r
-\r
- if (!stroke_and_fill) {\r
- flush_fill(); // flush any pending fills\r
- }\r
-\r
- if (style->stroke.type == SP_PAINT_TYPE_COLOR) {\r
- create_pen(style);\r
- } else {\r
- // create_pen(NULL);\r
- return 0;\r
- }\r
-\r
- print_bpath(bpath->path, transform, pbox);\r
-\r
- if (stroke_and_fill) {\r
- StrokeAndFillPath( hdc );\r
- destroy_brush();\r
- delete[] fill_path;\r
- fill_path = NULL;\r
- } else {\r
- StrokePath( hdc );\r
- }\r
-\r
- destroy_pen();\r
-\r
- return 0;\r
-}\r
-\r
-\r
-unsigned int\r
-PrintEmfWin32::print_bpath(const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox)\r
-{\r
- unsigned int closed;\r
- NR::Matrix tf = *transform;\r
-\r
- BeginPath( hdc );\r
- closed = FALSE;\r
- while (bp->code != NR_END) {\r
- using NR::X;\r
- using NR::Y;\r
-\r
- NR::Point p1(bp->c(1) * tf);\r
- NR::Point p2(bp->c(2) * tf);\r
- NR::Point p3(bp->c(3) * tf);\r
-\r
- p1[X] = (p1[X] * IN_PER_PX * dwDPI);\r
- p2[X] = (p2[X] * IN_PER_PX * dwDPI);\r
- p3[X] = (p3[X] * IN_PER_PX * dwDPI);\r
- p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);\r
- p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);\r
- p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);\r
-\r
- LONG const x1 = (LONG) round(p1[X]);\r
- LONG const y1 = (LONG) round(rc.bottom-p1[Y]);\r
- LONG const x2 = (LONG) round(p2[X]);\r
- LONG const y2 = (LONG) round(rc.bottom-p2[Y]);\r
- LONG const x3 = (LONG) round(p3[X]);\r
- LONG const y3 = (LONG) round(rc.bottom-p3[Y]);\r
-\r
- switch (bp->code) {\r
- case NR_MOVETO:\r
- if (closed) {\r
- CloseFigure( hdc );\r
- }\r
- closed = TRUE;\r
- MoveToEx( hdc, x3, y3, NULL );\r
- break;\r
- case NR_MOVETO_OPEN:\r
- if (closed) {\r
- CloseFigure( hdc );\r
- }\r
- closed = FALSE;\r
- MoveToEx( hdc, x3, y3, NULL );\r
- break;\r
- case NR_LINETO:\r
- LineTo( hdc, x3, y3 );\r
- break;\r
- case NR_CURVETO:\r
- {\r
- POINT pt[3];\r
- pt[0].x = x1;\r
- pt[0].y = y1;\r
- pt[1].x = x2;\r
- pt[1].y = y2;\r
- pt[2].x = x3;\r
- pt[2].y = y3;\r
-\r
- PolyBezierTo( hdc, pt, 3 );\r
- break;\r
- }\r
- default:\r
- break;\r
- }\r
- bp += 1;\r
- }\r
- if (closed) {\r
- CloseFigure( hdc );\r
- }\r
- EndPath( hdc );\r
-\r
- return closed;\r
-}\r
-\r
-\r
-bool\r
-PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext)\r
-{\r
- return ext->get_param_bool("textToPath");\r
-}\r
-\r
-\r
-void\r
-PrintEmfWin32::init (void)\r
-{\r
- Inkscape::Extension::Extension * ext;\r
-\r
- /* EMF print */\r
- ext = Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>Enhanced Metafile Print</name>\n"\r
- "<id>org.inkscape.print.emf.win32</id>\n"\r
- "<param name=\"destination\" type=\"string\"></param>\n"\r
- "<param name=\"textToPath\" type=\"boolean\">TRUE</param>\n"\r
- "<param name=\"pageBoundingBox\" type=\"boolean\">TRUE</param>\n"\r
- "<print/>\n"\r
- "</inkscape-extension>", new PrintEmfWin32());\r
-\r
- return;\r
-}\r
-\r
-\r
-} /* namespace Internal */\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-#endif /* WIN32 */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+/** \file
+ * Enhanced Metafile Printing.
+ */
+/*
+ * Authors:
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+/*
+ * References:
+ * - How to Create & Play Enhanced Metafiles in Win32
+ * http://support.microsoft.com/kb/q145999/
+ * - INFO: Windows Metafile Functions & Aldus Placeable Metafiles
+ * http://support.microsoft.com/kb/q66949/
+ * - Metafile Functions
+ * http://msdn.microsoft.com/library/en-us/gdi/metafile_0whf.asp
+ * - Metafile Structures
+ * http://msdn.microsoft.com/library/en-us/gdi/metafile_5hkj.asp
+ */
+
+#ifdef WIN32
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "libnr/n-art-bpath.h"
+#include "libnr/nr-point-matrix-ops.h"
+#include "libnr/nr-rect.h"
+#include "libnr/nr-matrix.h"
+#include "libnr/nr-matrix-fns.h"
+#include "libnr/nr-path.h"
+#include "libnr/nr-pixblock.h"
+#include "display/canvas-bpath.h"
+#include "sp-item.h"
+
+#include "glib.h"
+#include "gtk/gtkdialog.h"
+#include "gtk/gtkbox.h"
+#include "gtk/gtkstock.h"
+
+#include "glibmm/i18n.h"
+#include "enums.h"
+#include "document.h"
+#include "style.h"
+#include "sp-paint-server.h"
+#include "inkscape_version.h"
+
+#include "win32.h"
+#include "emf-win32-print.h"
+
+#include "unit-constants.h"
+
+#include "extension/extension.h"
+#include "extension/system.h"
+#include "extension/print.h"
+
+#include "io/sys.h"
+
+#include "macros.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+static float dwDPI = 2540;
+
+
+PrintEmfWin32::PrintEmfWin32 (void):
+ hdc(NULL),
+ hbrush(NULL),
+ hpen(NULL),
+ fill_path(NULL)
+{
+}
+
+
+PrintEmfWin32::~PrintEmfWin32 (void)
+{
+ if (hdc) {
+ HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
+ if ( metafile ) {
+ DeleteEnhMetaFile( metafile );
+ }
+ DeleteDC( hdc );
+ }
+
+ /* restore default signal handling for SIGPIPE */
+#if !defined(_WIN32) && !defined(__WIN32__)
+ (void) signal(SIGPIPE, SIG_DFL);
+#endif
+ return;
+}
+
+
+unsigned int
+PrintEmfWin32::setup (Inkscape::Extension::Print *mod)
+{
+ return TRUE;
+}
+
+
+unsigned int
+PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
+{
+ gchar const *utf8_fn = mod->get_param_string("destination");
+
+ gsize bytesRead = 0;
+ gsize bytesWritten = 0;
+ GError* error = NULL;
+ gchar *local_fn =
+ g_filename_from_utf8( utf8_fn, -1, &bytesRead, &bytesWritten, &error );
+
+ if (local_fn == NULL) {
+ return 1;
+ }
+
+ CHAR *ansi_uri = (CHAR *) local_fn;
+ gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
+ WCHAR *unicode_uri = (WCHAR *) unicode_fn;
+
+ // width and height in px
+ _width = sp_document_width(doc);
+ _height = sp_document_height(doc);
+
+ NRRect d;
+ bool pageBoundingBox;
+ pageBoundingBox = mod->get_param_bool("pageBoundingBox");
+ if (pageBoundingBox) {
+ d.x0 = d.y0 = 0;
+ d.x1 = _width;
+ d.y1 = _height;
+ } else {
+ SPItem* doc_item = SP_ITEM(sp_document_root(doc));
+ sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE);
+ }
+
+ d.x0 *= IN_PER_PX;
+ d.y0 *= IN_PER_PX;
+ d.x1 *= IN_PER_PX;
+ d.y1 *= IN_PER_PX;
+
+ float dwInchesX = (d.x1 - d.x0);
+ float dwInchesY = (d.y1 - d.y0);
+
+ // dwInchesX x dwInchesY in .01mm units
+ SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );
+
+ // Get a Reference DC
+ HDC hScreenDC = GetDC( NULL );
+
+ // Get the physical characteristics of the reference DC
+ float PixelsX = (float) GetDeviceCaps( hScreenDC, HORZRES );
+ float PixelsY = (float) GetDeviceCaps( hScreenDC, VERTRES );
+ float MMX = (float) GetDeviceCaps( hScreenDC, HORZSIZE );
+ float MMY = (float) GetDeviceCaps( hScreenDC, VERTSIZE );
+
+ // Create the Metafile
+ if (PrintWin32::is_os_wide())
+ hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, NULL );
+ else
+ hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, NULL );
+
+ // Release the reference DC
+ ReleaseDC( NULL, hScreenDC );
+
+ // Did we get a good metafile?
+ if (hdc == NULL)
+ {
+ g_free(local_fn);
+ g_free(unicode_fn);
+ return 1;
+ }
+
+ // Anisotropic mapping mode
+ SetMapMode( hdc, MM_ANISOTROPIC );
+
+ // Set the Windows extent
+ SetWindowExtEx( hdc, (int) (dwInchesX*dwDPI), (int) (dwInchesY*dwDPI), NULL );
+
+ // Set the viewport extent to reflect
+ // dwInchesX" x dwInchesY" in device units
+ SetViewportExtEx( hdc,
+ (int) ((float) dwInchesX*25.4f*PixelsX/MMX),
+ (int) ((float) dwInchesY*25.4f*PixelsY/MMY),
+ NULL );
+
+ SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) );
+
+ g_free(local_fn);
+ g_free(unicode_fn);
+
+ return 0;
+}
+
+
+unsigned int
+PrintEmfWin32::finish (Inkscape::Extension::Print *mod)
+{
+ if (!hdc) return 0;
+
+ flush_fill(); // flush any pending fills
+
+ HENHMETAFILE metafile = CloseEnhMetaFile( hdc );
+ if ( metafile ) {
+ DeleteEnhMetaFile( metafile );
+ }
+ DeleteDC( hdc );
+
+ hdc = NULL;
+
+ return 0;
+}
+
+
+unsigned int
+PrintEmfWin32::comment (Inkscape::Extension::Print * module,
+ const char *comment)
+{
+ if (!hdc) return 0;
+
+ flush_fill(); // flush any pending fills
+
+ return 0;
+}
+
+
+void
+PrintEmfWin32::create_brush(SPStyle const *style)
+{
+ float rgb[3];
+
+ if (style) {
+ sp_color_get_rgb_floatv( &style->fill.value.color, rgb );
+ hbrush = CreateSolidBrush( RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]) );
+ hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
+
+ SetPolyFillMode( hdc,
+ style->fill_rule.computed == 0 ? WINDING :
+ style->fill_rule.computed == 2 ? ALTERNATE : ALTERNATE );
+ } else { // if (!style)
+ hbrush = CreateSolidBrush( RGB(255, 255, 255) );
+ hbrushOld = (HBRUSH) SelectObject( hdc, hbrush );
+ SetPolyFillMode( hdc, ALTERNATE );
+ }
+}
+
+
+void
+PrintEmfWin32::destroy_brush()
+{
+ SelectObject( hdc, hbrushOld );
+ if (hbrush)
+ DeleteObject( hbrush );
+ hbrush = NULL;
+}
+
+
+void
+PrintEmfWin32::create_pen(SPStyle const *style)
+{
+ if (style) {
+ float rgb[3];
+
+ sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);
+
+ LOGBRUSH lb = {0};
+ lb.lbStyle = BS_SOLID;
+ lb.lbColor = RGB( 255*rgb[0], 255*rgb[1], 255*rgb[2] );
+
+ int linestyle = PS_SOLID;
+ int linecap = 0;
+ int linejoin = 0;
+ DWORD n_dash = 0;
+ DWORD *dash = NULL;
+ float oldmiterlimit;
+
+ DWORD linewidth = MAX( 1, (DWORD) (style->stroke_width.computed * IN_PER_PX * dwDPI) );
+
+ if (style->stroke_linecap.computed == 0) {
+ linecap = PS_ENDCAP_FLAT;
+ }
+ else if (style->stroke_linecap.computed == 1) {
+ linecap = PS_ENDCAP_ROUND;
+ }
+ else if (style->stroke_linecap.computed == 2) {
+ linecap = PS_ENDCAP_SQUARE;
+ }
+
+ if (style->stroke_linejoin.computed == 0) {
+ linejoin = PS_JOIN_MITER;
+ }
+ else if (style->stroke_linejoin.computed == 1) {
+ linejoin = PS_JOIN_ROUND;
+ }
+ else if (style->stroke_linejoin.computed == 2) {
+ linejoin = PS_JOIN_BEVEL;
+ }
+
+ if (style->stroke_dash.n_dash &&
+ style->stroke_dash.dash )
+ {
+ int i = 0;
+ while (linestyle != PS_USERSTYLE &&
+ (i < style->stroke_dash.n_dash)) {
+ if (style->stroke_dash.dash[i] > 0.00000001)
+ linestyle = PS_USERSTYLE;
+ i++;
+ }
+
+ if (linestyle == PS_USERSTYLE) {
+ n_dash = style->stroke_dash.n_dash;
+ dash = new DWORD[n_dash];
+ for (i = 0; i < style->stroke_dash.n_dash; i++) {
+ dash[i] = (DWORD) (style->stroke_dash.dash[i] * IN_PER_PX * dwDPI);
+ }
+ }
+ }
+
+ hpen = ExtCreatePen(
+ PS_GEOMETRIC | linestyle | linecap | linejoin,
+ linewidth,
+ &lb,
+ n_dash,
+ dash );
+
+ if ( !hpen && linestyle == PS_USERSTYLE ) {
+ hpen = ExtCreatePen(
+ PS_GEOMETRIC | PS_SOLID | linecap | linejoin,
+ linewidth,
+ &lb,
+ 0,
+ NULL );
+ }
+
+ if ( !hpen ) {
+ hpen = CreatePen(
+ PS_SOLID,
+ linewidth,
+ lb.lbColor );
+ }
+
+ hpenOld = (HPEN) SelectObject( hdc, hpen );
+
+ if (linejoin == PS_JOIN_MITER) {
+ float miterlimit = style->stroke_miterlimit.value;
+ if (miterlimit < 1)
+ miterlimit = 4.0;
+ SetMiterLimit(
+ hdc,
+ miterlimit * IN_PER_PX * dwDPI,
+ &oldmiterlimit );
+ }
+
+ if (n_dash) {
+ delete[] dash;
+ }
+ }
+ else { // if (!style)
+ hpen = CreatePen( PS_SOLID, 1, RGB(0, 0, 0) );
+ hpenOld = (HPEN) SelectObject( hdc, hpen );
+ }
+}
+
+
+void
+PrintEmfWin32::destroy_pen()
+{
+ SelectObject( hdc, hpenOld );
+ if (hpen)
+ DeleteObject( hpen );
+ hpen = NULL;
+}
+
+
+void
+PrintEmfWin32::flush_fill()
+{
+ if (fill_path) {
+ print_bpath(fill_path, &fill_transform, &fill_pbox);
+ FillPath( hdc );
+ destroy_brush();
+ delete[] fill_path;
+ fill_path = NULL;
+ }
+}
+
+
+NArtBpath *
+PrintEmfWin32::copy_bpath(const NArtBpath *bp)
+{
+ NArtBpath *tmp = (NArtBpath *) bp;
+ int num = 1;
+
+ while (tmp->code != NR_END) {
+ num++;
+ tmp += 1;
+ }
+
+ tmp = new NArtBpath[num];
+ while (num--) {
+ tmp[num] = bp[num];
+ }
+
+ return tmp;
+}
+
+
+int
+PrintEmfWin32::cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2)
+{
+ if (!bp1 || !bp2) {
+ return 1;
+ }
+
+ while (bp1->code != NR_END && bp2->code != NR_END) {
+ if (bp1->code != bp2->code) {
+ return 1;
+ }
+
+ if ( fabs(bp1->x1 - bp2->x1) > 0.00000001 ||
+ fabs(bp1->y1 - bp2->y1) > 0.00000001 ||
+ fabs(bp1->x2 - bp2->x2) > 0.00000001 ||
+ fabs(bp1->y2 - bp2->y2) > 0.00000001 ||
+ fabs(bp1->x3 - bp2->x3) > 0.00000001 ||
+ fabs(bp1->y3 - bp2->y3) > 0.00000001 )
+ {
+ return 1;
+ }
+
+ bp1 += 1;
+ bp2 += 1;
+ }
+
+ return bp1->code != NR_END || bp2->code != NR_END;
+}
+
+
+unsigned int
+PrintEmfWin32::fill(Inkscape::Extension::Print *mod,
+ NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style,
+ NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
+{
+ if (!hdc) return 0;
+
+ flush_fill(); // flush any pending fills
+
+ if (style->fill.type == SP_PAINT_TYPE_COLOR) {
+ create_brush(style);
+ } else {
+ // create_brush(NULL);
+ return 0;
+ }
+
+ fill_path = copy_bpath( bpath->path );
+ fill_transform = *transform;
+ fill_pbox = *pbox;
+
+ // postpone fill in case of stroke-and-fill
+
+ return 0;
+}
+
+
+unsigned int
+PrintEmfWin32::stroke (Inkscape::Extension::Print *mod,
+ const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,
+ const NRRect *pbox, const NRRect *dbox, const NRRect *bbox)
+{
+ if (!hdc) return 0;
+
+ bool stroke_and_fill = ( cmp_bpath( bpath->path, fill_path ) == 0 );
+
+ if (!stroke_and_fill) {
+ flush_fill(); // flush any pending fills
+ }
+
+ if (style->stroke.type == SP_PAINT_TYPE_COLOR) {
+ create_pen(style);
+ } else {
+ // create_pen(NULL);
+ return 0;
+ }
+
+ print_bpath(bpath->path, transform, pbox);
+
+ if (stroke_and_fill) {
+ StrokeAndFillPath( hdc );
+ destroy_brush();
+ delete[] fill_path;
+ fill_path = NULL;
+ } else {
+ StrokePath( hdc );
+ }
+
+ destroy_pen();
+
+ return 0;
+}
+
+
+unsigned int
+PrintEmfWin32::print_bpath(const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox)
+{
+ unsigned int closed;
+ NR::Matrix tf = *transform;
+
+ BeginPath( hdc );
+ closed = FALSE;
+ while (bp->code != NR_END) {
+ using NR::X;
+ using NR::Y;
+
+ NR::Point p1(bp->c(1) * tf);
+ NR::Point p2(bp->c(2) * tf);
+ NR::Point p3(bp->c(3) * tf);
+
+ p1[X] = (p1[X] * IN_PER_PX * dwDPI);
+ p2[X] = (p2[X] * IN_PER_PX * dwDPI);
+ p3[X] = (p3[X] * IN_PER_PX * dwDPI);
+ p1[Y] = (p1[Y] * IN_PER_PX * dwDPI);
+ p2[Y] = (p2[Y] * IN_PER_PX * dwDPI);
+ p3[Y] = (p3[Y] * IN_PER_PX * dwDPI);
+
+ LONG const x1 = (LONG) round(p1[X]);
+ LONG const y1 = (LONG) round(rc.bottom-p1[Y]);
+ LONG const x2 = (LONG) round(p2[X]);
+ LONG const y2 = (LONG) round(rc.bottom-p2[Y]);
+ LONG const x3 = (LONG) round(p3[X]);
+ LONG const y3 = (LONG) round(rc.bottom-p3[Y]);
+
+ switch (bp->code) {
+ case NR_MOVETO:
+ if (closed) {
+ CloseFigure( hdc );
+ }
+ closed = TRUE;
+ MoveToEx( hdc, x3, y3, NULL );
+ break;
+ case NR_MOVETO_OPEN:
+ if (closed) {
+ CloseFigure( hdc );
+ }
+ closed = FALSE;
+ MoveToEx( hdc, x3, y3, NULL );
+ break;
+ case NR_LINETO:
+ LineTo( hdc, x3, y3 );
+ break;
+ case NR_CURVETO:
+ {
+ POINT pt[3];
+ pt[0].x = x1;
+ pt[0].y = y1;
+ pt[1].x = x2;
+ pt[1].y = y2;
+ pt[2].x = x3;
+ pt[2].y = y3;
+
+ PolyBezierTo( hdc, pt, 3 );
+ break;
+ }
+ default:
+ break;
+ }
+ bp += 1;
+ }
+ if (closed) {
+ CloseFigure( hdc );
+ }
+ EndPath( hdc );
+
+ return closed;
+}
+
+
+bool
+PrintEmfWin32::textToPath(Inkscape::Extension::Print * ext)
+{
+ return ext->get_param_bool("textToPath");
+}
+
+
+void
+PrintEmfWin32::init (void)
+{
+ Inkscape::Extension::Extension * ext;
+
+ /* EMF print */
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>Enhanced Metafile Print</name>\n"
+ "<id>org.inkscape.print.emf.win32</id>\n"
+ "<param name=\"destination\" type=\"string\"></param>\n"
+ "<param name=\"textToPath\" type=\"boolean\">TRUE</param>\n"
+ "<param name=\"pageBoundingBox\" type=\"boolean\">TRUE</param>\n"
+ "<print/>\n"
+ "</inkscape-extension>", new PrintEmfWin32());
+
+ return;
+}
+
+
+} /* namespace Internal */
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* WIN32 */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index d1ac819391974087e2bdf1107b09ef8b7d1d148a..305507824226159f969a6892835539a60fe41037 100644 (file)
-#ifndef __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__\r
-#define __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__\r
-\r
-/*\r
- * Enhanced Metafile Printing.\r
- *\r
- * Author:\r
- * Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef WIN32\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-#include "extension/implementation/implementation.h"\r
-#include "extension/extension.h"\r
-\r
-#include "svg/stringstream.h"\r
-#include "libnr/nr-matrix.h"\r
-#include "libnr/nr-rect.h"\r
-\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class PrintEmfWin32 : public Inkscape::Extension::Implementation::Implementation\r
-{\r
- double _width;\r
- double _height;\r
- HDC hdc;\r
- RECT rc;\r
-\r
- HBRUSH hbrush, hbrushOld;\r
- HPEN hpen, hpenOld;\r
-\r
- NArtBpath *fill_path;\r
- NArtBpath *fill_path_copy;\r
- NRMatrix fill_transform;\r
- NRRect fill_pbox;\r
-\r
- unsigned int print_bpath (const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox);\r
-\r
-public:\r
- PrintEmfWin32 (void);\r
- virtual ~PrintEmfWin32 (void);\r
-\r
- /* Print functions */\r
- virtual unsigned int setup (Inkscape::Extension::Print * module);\r
-\r
- virtual unsigned int begin (Inkscape::Extension::Print * module, SPDocument *doc);\r
- virtual unsigned int finish (Inkscape::Extension::Print * module);\r
-\r
- /* Rendering methods */\r
- virtual unsigned int fill (Inkscape::Extension::Print * module,\r
- const NRBPath *bpath, const NRMatrix *ctm, const SPStyle *style,\r
- const NRRect *pbox, const NRRect *dbox, const NRRect *bbox);\r
- virtual unsigned int stroke (Inkscape::Extension::Print * module,\r
- const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,\r
- const NRRect *pbox, const NRRect *dbox, const NRRect *bbox);\r
- virtual unsigned int comment(Inkscape::Extension::Print *module, const char * comment);\r
- bool textToPath (Inkscape::Extension::Print * ext);\r
-\r
- static void init (void);\r
-\r
-protected:\r
- void create_brush(SPStyle const *style);\r
-\r
- void destroy_brush();\r
-\r
- void create_pen(SPStyle const *style);\r
-\r
- void destroy_pen();\r
-\r
- void flush_fill();\r
-\r
- NArtBpath *copy_bpath(const NArtBpath *bp);\r
- int cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2);\r
-\r
-};\r
-\r
-} /* namespace Internal */\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-#endif /* WIN32 */\r
-\r
-#endif /* __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__ */\r
-\r
-/*\r
- Local Variables:\r
- mode:cpp\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#ifndef __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__
+#define __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__
+
+/*
+ * Enhanced Metafile Printing.
+ *
+ * Author:
+ * Ulf Erikson <ulferikson@users.sf.net>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef WIN32
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "extension/implementation/implementation.h"
+#include "extension/extension.h"
+
+#include "svg/stringstream.h"
+#include "libnr/nr-matrix.h"
+#include "libnr/nr-rect.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class PrintEmfWin32 : public Inkscape::Extension::Implementation::Implementation
+{
+ double _width;
+ double _height;
+ HDC hdc;
+ RECT rc;
+
+ HBRUSH hbrush, hbrushOld;
+ HPEN hpen, hpenOld;
+
+ NArtBpath *fill_path;
+ NArtBpath *fill_path_copy;
+ NRMatrix fill_transform;
+ NRRect fill_pbox;
+
+ unsigned int print_bpath (const NArtBpath *bp, const NRMatrix *transform, NRRect const *pbox);
+
+public:
+ PrintEmfWin32 (void);
+ virtual ~PrintEmfWin32 (void);
+
+ /* Print functions */
+ virtual unsigned int setup (Inkscape::Extension::Print * module);
+
+ virtual unsigned int begin (Inkscape::Extension::Print * module, SPDocument *doc);
+ virtual unsigned int finish (Inkscape::Extension::Print * module);
+
+ /* Rendering methods */
+ virtual unsigned int fill (Inkscape::Extension::Print * module,
+ const NRBPath *bpath, const NRMatrix *ctm, const SPStyle *style,
+ const NRRect *pbox, const NRRect *dbox, const NRRect *bbox);
+ virtual unsigned int stroke (Inkscape::Extension::Print * module,
+ const NRBPath *bpath, const NRMatrix *transform, const SPStyle *style,
+ const NRRect *pbox, const NRRect *dbox, const NRRect *bbox);
+ virtual unsigned int comment(Inkscape::Extension::Print *module, const char * comment);
+ bool textToPath (Inkscape::Extension::Print * ext);
+
+ static void init (void);
+
+protected:
+ void create_brush(SPStyle const *style);
+
+ void destroy_brush();
+
+ void create_pen(SPStyle const *style);
+
+ void destroy_pen();
+
+ void flush_fill();
+
+ NArtBpath *copy_bpath(const NArtBpath *bp);
+ int cmp_bpath(const NArtBpath *bp1, const NArtBpath *bp2);
+
+};
+
+} /* namespace Internal */
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* WIN32 */
+
+#endif /* __INKSCAPE_EXTENSION_INTERNAL_PRINT_EMF_WIN32_H__ */
+
+/*
+ Local Variables:
+ mode:cpp
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/internal/libwpg/WPGOLEStream.h b/src/extension/internal/libwpg/WPGOLEStream.h
index 49562bfd6b866addb0fd4e2b0e66a6273cb124af..af4a3d02fec8f87662346480c061e2582482ecc3 100644 (file)
/* POLE - Portable C++ library to access OLE Storage
Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
-\r
- Redistribution and use in source and binary forms, with or without \r
- modification, are permitted provided that the following conditions \r
- are met:\r
- * Redistributions of source code must retain the above copyright notice, \r
- this list of conditions and the following disclaimer.\r
- * Redistributions in binary form must reproduce the above copyright notice, \r
- this list of conditions and the following disclaimer in the documentation \r
- and/or other materials provided with the distribution.\r
- * Neither the name of the authors nor the names of its contributors may be \r
- used to endorse or promote products derived from this software without \r
- specific prior written permission.\r
-\r
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" \r
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF \r
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the authors nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
friend class Stream;
public:
-\r
+
// for Storage::result()
- enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError };\r
- \r
+ enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError };
+
/**
* Constructs a storage with data.
**/
friend class Storage;
friend class StorageIO;
-public:\r
-\r
- /**\r
- * Creates a new stream.\r
- */\r
- // name must be absolute, e.g "/PerfectOffice_MAIN"\r
- Stream( Storage* storage, const std::string& name );\r
-\r
- /**\r
- * Destroys the stream.\r
- */\r
+public:
+
+ /**
+ * Creates a new stream.
+ */
+ // name must be absolute, e.g "/PerfectOffice_MAIN"
+ Stream( Storage* storage, const std::string& name );
+
+ /**
+ * Destroys the stream.
+ */
~Stream();
-\r
+
/**
* Returns the stream size.
**/
/**
* Reads a block of data.
**/
- unsigned long read( unsigned char* data, unsigned long maxlen );\r
- \r
+ unsigned long read( unsigned char* data, unsigned long maxlen );
+
private:
StreamIO* io;
-\r
+
// no copy or assign
Stream( const Stream& );
Stream& operator=( const Stream& );
diff --git a/src/extension/internal/libwpg/WPGXParser.cpp b/src/extension/internal/libwpg/WPGXParser.cpp
index dcdc44c5037af3bff8e78c3bc4d04e29430a02bb..e25b53aabc9d64a7d55999339127a93492b7ed8a 100644 (file)
-/* libwpg\r
- * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
- * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)\r
- * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the \r
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
- * Boston, MA 02111-1301 USA\r
- *\r
- * For further information visit http://libwpg.sourceforge.net\r
- */\r
- \r
-/* "This product is not manufactured, approved, or supported by\r
- * Corel Corporation or Corel Corporation Limited."\r
- */\r
-\r
-#include "WPGXParser.h"\r
-\r
-using namespace libwpg;\r
-\r
-WPGXParser::WPGXParser(WPGInputStream *input, WPGPaintInterface* painter):\r
- m_input(input), m_painter(painter)\r
-{\r
-}\r
-\r
-unsigned char WPGXParser::readU8()\r
-{\r
- return m_input->getc();\r
-}\r
-\r
-unsigned short WPGXParser::readU16()\r
-{\r
- unsigned short p0 = (unsigned short)readU8();\r
- unsigned short p1 = (unsigned short)readU8();\r
- return p0|(p1<<8);\r
-}\r
-\r
-unsigned long WPGXParser::readU32()\r
-{\r
- unsigned long p0 = (unsigned short)readU8();\r
- unsigned long p1 = (unsigned short)readU8();\r
- unsigned long p2 = (unsigned short)readU8();\r
- unsigned long p3 = (unsigned short)readU8();\r
- return p0|(p1<<8)|(p2<<16)|(p3<<24);\r
-}\r
-\r
-char WPGXParser::readS8()\r
-{\r
- return (char)m_input->getc();\r
-}\r
-\r
-short WPGXParser::readS16()\r
-{\r
- short p0 = readU8();\r
- short p1 = readS8();\r
- return p0|(p1<<8);\r
-}\r
-\r
-long WPGXParser::readS32()\r
-{\r
- long p0 = readU8();\r
- long p1 = readU8();\r
- long p2 = readU8();\r
- long p3 = readS8();\r
- return p0|(p1<<8)|(p2<<16)|(p3<<24);\r
-}\r
-\r
-unsigned int WPGXParser::readVariableLengthInteger()\r
-{\r
- // read a byte\r
- unsigned char value8 = readU8();\r
- // if it's in the range 0-0xFE, then we have a 8-bit value\r
- if (value8<=0xFE) {\r
- return (unsigned int)value8;\r
- } else {\r
- // now read a 16 bit value\r
- unsigned short value16 = readU16();\r
- // if the MSB is 1, we have a 32 bit value\r
- if (value16>>15) {\r
- // read the next 16 bit value (LSB part, in value16 resides the MSB part)\r
- unsigned long lvalue16 = readU16();\r
- unsigned long value32 = value16 & 0x7fff; // mask out the MSB\r
- return (value32<<16)+lvalue16;\r
- } else {\r
- // we have a 16 bit value, return it\r
- return (unsigned int)value16;\r
- }\r
- }\r
- \r
- // unreachable\r
- return 0;\r
-}\r
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGXParser.h"
+
+using namespace libwpg;
+
+WPGXParser::WPGXParser(WPGInputStream *input, WPGPaintInterface* painter):
+ m_input(input), m_painter(painter)
+{
+}
+
+unsigned char WPGXParser::readU8()
+{
+ return m_input->getc();
+}
+
+unsigned short WPGXParser::readU16()
+{
+ unsigned short p0 = (unsigned short)readU8();
+ unsigned short p1 = (unsigned short)readU8();
+ return p0|(p1<<8);
+}
+
+unsigned long WPGXParser::readU32()
+{
+ unsigned long p0 = (unsigned short)readU8();
+ unsigned long p1 = (unsigned short)readU8();
+ unsigned long p2 = (unsigned short)readU8();
+ unsigned long p3 = (unsigned short)readU8();
+ return p0|(p1<<8)|(p2<<16)|(p3<<24);
+}
+
+char WPGXParser::readS8()
+{
+ return (char)m_input->getc();
+}
+
+short WPGXParser::readS16()
+{
+ short p0 = readU8();
+ short p1 = readS8();
+ return p0|(p1<<8);
+}
+
+long WPGXParser::readS32()
+{
+ long p0 = readU8();
+ long p1 = readU8();
+ long p2 = readU8();
+ long p3 = readS8();
+ return p0|(p1<<8)|(p2<<16)|(p3<<24);
+}
+
+unsigned int WPGXParser::readVariableLengthInteger()
+{
+ // read a byte
+ unsigned char value8 = readU8();
+ // if it's in the range 0-0xFE, then we have a 8-bit value
+ if (value8<=0xFE) {
+ return (unsigned int)value8;
+ } else {
+ // now read a 16 bit value
+ unsigned short value16 = readU16();
+ // if the MSB is 1, we have a 32 bit value
+ if (value16>>15) {
+ // read the next 16 bit value (LSB part, in value16 resides the MSB part)
+ unsigned long lvalue16 = readU16();
+ unsigned long value32 = value16 & 0x7fff; // mask out the MSB
+ return (value32<<16)+lvalue16;
+ } else {
+ // we have a 16 bit value, return it
+ return (unsigned int)value16;
+ }
+ }
+
+ // unreachable
+ return 0;
+}
diff --git a/src/extension/internal/libwpg/WPGXParser.h b/src/extension/internal/libwpg/WPGXParser.h
index 71c78d2c0c44e1aa55040eefcc8e0d0e25ebf69f..d7fd4cb5af20ef67ec58813b02b04ff42da158a2 100644 (file)
-/* libwpg\r
- * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
- * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)\r
- * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the \r
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
- * Boston, MA 02111-1301 USA\r
- *\r
- * For further information visit http://libwpg.sourceforge.net\r
- */\r
-\r
-/* "This product is not manufactured, approved, or supported by\r
- * Corel Corporation or Corel Corporation Limited."\r
- */\r
-\r
-#ifndef __WPGXPARSER_H__\r
-#define __WPGXPARSER_H__\r
-\r
-#include "WPGPaintInterface.h"\r
-#include "WPGStream.h"\r
-#include "WPGColor.h"\r
-\r
-#include <map>\r
-\r
-using namespace libwpg;\r
-\r
-class WPGXParser\r
-{\r
-public:\r
- WPGXParser(WPGInputStream *input, WPGPaintInterface* painter);\r
- virtual ~WPGXParser() {}\r
- virtual bool parse() = 0;\r
- \r
- unsigned char readU8();\r
- unsigned short readU16(); \r
- unsigned long readU32(); \r
- char readS8();\r
- short readS16(); \r
- long readS32(); \r
- unsigned int readVariableLengthInteger();\r
- \r
-protected:\r
- WPGInputStream* m_input;\r
- WPGPaintInterface* m_painter;\r
- std::map<int,WPGColor> m_colorPalette;\r
-};\r
-\r
-#endif // __WPGXPARSER_H__\r
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGXPARSER_H__
+#define __WPGXPARSER_H__
+
+#include "WPGPaintInterface.h"
+#include "WPGStream.h"
+#include "WPGColor.h"
+
+#include <map>
+
+using namespace libwpg;
+
+class WPGXParser
+{
+public:
+ WPGXParser(WPGInputStream *input, WPGPaintInterface* painter);
+ virtual ~WPGXParser() {}
+ virtual bool parse() = 0;
+
+ unsigned char readU8();
+ unsigned short readU16();
+ unsigned long readU32();
+ char readS8();
+ short readS16();
+ long readS32();
+ unsigned int readVariableLengthInteger();
+
+protected:
+ WPGInputStream* m_input;
+ WPGPaintInterface* m_painter;
+ std::map<int,WPGColor> m_colorPalette;
+};
+
+#endif // __WPGXPARSER_H__
diff --git a/src/extension/internal/libwpg/WPGraphics.cpp b/src/extension/internal/libwpg/WPGraphics.cpp
index a7454d2a10ee7aea6c2bf7831b6fc39d110ee5e6..e120b802e6aee5b17312b7f20e5af8af9613ee7a 100644 (file)
-/* libwpg\r
- * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the \r
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
- * Boston, MA 02111-1301 USA\r
- *\r
- * For further information visit http://libwpg.sourceforge.net\r
- */\r
-\r
-/* "This product is not manufactured, approved, or supported by\r
- * Corel Corporation or Corel Corporation Limited."\r
- */\r
-\r
-#include "WPGraphics.h"\r
-#include "WPGHeader.h"\r
-#include "WPGStream.h"\r
-#include "WPGXParser.h"\r
-#include "WPG1Parser.h"\r
-#include "WPG2Parser.h"\r
-#include "libwpg_utils.h"\r
-\r
-using namespace libwpg;\r
-\r
-bool WPGraphics::isSupported(WPGInputStream* input)\r
-{\r
- WPGHeader header;\r
- if(!header.load(input))\r
- return false;\r
- \r
- return header.isSupported();\r
-}\r
-\r
-bool WPGraphics::parse(WPGInputStream* input, WPGPaintInterface* painter)\r
-{\r
- WPGXParser *parser = 0;\r
- \r
- WPG_DEBUG_MSG(("Loading header...\n"));\r
- WPGHeader header;\r
- if(!header.load(input))\r
- return false;\r
- \r
- if(!header.isSupported())\r
- {\r
- WPG_DEBUG_MSG(("Unsupported file format!\n"));\r
- return false; \r
- }\r
- \r
- // seek to the start of document\r
- input->seek(header.startOfDocument());\r
- \r
- switch (header.majorVersion()) {\r
- case 0x01: // WPG1\r
- WPG_DEBUG_MSG(("Parsing WPG1\n"));\r
- parser = new WPG1Parser(input, painter);\r
- parser->parse();\r
- break;\r
- case 0x02: // WPG2\r
- WPG_DEBUG_MSG(("Parsing WPG2\n"));\r
- parser = new WPG2Parser(input, painter);\r
- parser->parse();\r
- break;\r
- default: // other :-)\r
- WPG_DEBUG_MSG(("Unknown format\n"));\r
- break;\r
- }\r
- \r
- delete parser;\r
- \r
- return false;\r
-}\r
- \r
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGraphics.h"
+#include "WPGHeader.h"
+#include "WPGStream.h"
+#include "WPGXParser.h"
+#include "WPG1Parser.h"
+#include "WPG2Parser.h"
+#include "libwpg_utils.h"
+
+using namespace libwpg;
+
+bool WPGraphics::isSupported(WPGInputStream* input)
+{
+ WPGHeader header;
+ if(!header.load(input))
+ return false;
+
+ return header.isSupported();
+}
+
+bool WPGraphics::parse(WPGInputStream* input, WPGPaintInterface* painter)
+{
+ WPGXParser *parser = 0;
+
+ WPG_DEBUG_MSG(("Loading header...\n"));
+ WPGHeader header;
+ if(!header.load(input))
+ return false;
+
+ if(!header.isSupported())
+ {
+ WPG_DEBUG_MSG(("Unsupported file format!\n"));
+ return false;
+ }
+
+ // seek to the start of document
+ input->seek(header.startOfDocument());
+
+ switch (header.majorVersion()) {
+ case 0x01: // WPG1
+ WPG_DEBUG_MSG(("Parsing WPG1\n"));
+ parser = new WPG1Parser(input, painter);
+ parser->parse();
+ break;
+ case 0x02: // WPG2
+ WPG_DEBUG_MSG(("Parsing WPG2\n"));
+ parser = new WPG2Parser(input, painter);
+ parser->parse();
+ break;
+ default: // other :-)
+ WPG_DEBUG_MSG(("Unknown format\n"));
+ break;
+ }
+
+ delete parser;
+
+ return false;
+}
+
diff --git a/src/extension/internal/libwpg/WPGraphics.h b/src/extension/internal/libwpg/WPGraphics.h
index 3226835cab6ef4555c08832ad6d6bb47170410a1..21abddd1b3efaf9656c25baee526bb023ccf1985 100644 (file)
-/* libwpg\r
- * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the \r
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
- * Boston, MA 02111-1301 USA\r
- *\r
- * For further information visit http://libwpg.sourceforge.net\r
- */\r
-\r
-/* "This product is not manufactured, approved, or supported by\r
- * Corel Corporation or Corel Corporation Limited."\r
- */\r
-\r
-#ifndef __WPGRAPHICS_H__\r
-#define __WPGRAPHICS_H__\r
-\r
-namespace libwpg\r
-{\r
-\r
-class WPGInputStream;\r
-class WPGPaintInterface;\r
-\r
-class WPGraphics\r
-{\r
-public:\r
- \r
- static bool isSupported(WPGInputStream* input);\r
- \r
- static bool parse(WPGInputStream* input, WPGPaintInterface* painter);\r
-};\r
-\r
-} // namespace libwpg\r
-\r
-#endif // __WPGRAPHICS_H__\r
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGRAPHICS_H__
+#define __WPGRAPHICS_H__
+
+namespace libwpg
+{
+
+class WPGInputStream;
+class WPGPaintInterface;
+
+class WPGraphics
+{
+public:
+
+ static bool isSupported(WPGInputStream* input);
+
+ static bool parse(WPGInputStream* input, WPGPaintInterface* painter);
+};
+
+} // namespace libwpg
+
+#endif // __WPGRAPHICS_H__
index 28e9476149c4c3bb736773b4b900c91c13c37fd1..0326b150adc26a6832c6f367a1d1b251f7bd42e0 100644 (file)
-/* \r
- * This file came from libwpg as a source, their utility wpg2svg\r
- * specifically. It has been modified to work as an Inkscape extension.\r
- * The Inkscape extension code is covered by this copyright, but the\r
- * rest is covered by the one bellow.\r
- *\r
- * Authors:\r
- * Ted Gould <ted@gould.cx>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- *\r
- */\r
-\r
-/* libwpg\r
- * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
- * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- *\r
- * For further information visit http://libwpg.sourceforge.net\r
- */\r
-\r
-/* "This product is not manufactured, approved, or supported by\r
- * Corel Corporation or Corel Corporation Limited."\r
- */\r
-\r
-#include <stdio.h>\r
-\r
-#include "wpg-input.h"\r
-#include "extension/system.h"\r
-#include "extension/input.h"\r
-#include "document.h"\r
-\r
-#include "libwpg/libwpg.h"\r
-#include "libwpg/WPGStreamImplementation.h"\r
-\r
-using namespace libwpg;\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-class InkscapePainter : public libwpg::WPGPaintInterface {\r
-public:\r
- InkscapePainter();\r
-\r
- void startDocument(double imageWidth, double imageHeight);\r
- void endDocument();\r
- void startLayer(unsigned int id);\r
- void endLayer(unsigned int id);\r
-\r
- void setPen(const WPGPen& pen);\r
- void setBrush(const WPGBrush& brush);\r
- void setFillRule(FillRule rule);\r
-\r
- void drawRectangle(const WPGRect& rect, double rx, double ry);\r
- void drawEllipse(const WPGPoint& center, double rx, double ry);\r
- void drawPolygon(const WPGPointArray& vertices);\r
- void drawPath(const WPGPath& path);\r
-\r
-private:\r
- WPGPen m_pen;\r
- WPGBrush m_brush;\r
- FillRule m_fillRule;\r
- int m_gradientIndex;\r
- void writeStyle();\r
- void printf (char * fmt, ...) {\r
- va_list args;\r
- va_start(args, fmt);\r
- gchar * buf = g_strdup_vprintf(fmt, args);\r
- va_end(args);\r
- if (buf) {\r
- document += buf;\r
- g_free(buf);\r
- }\r
- }\r
-\r
-public:\r
- Glib::ustring document;\r
-};\r
-\r
-InkscapePainter::InkscapePainter(): m_fillRule(AlternatingFill), m_gradientIndex(1)\r
-{\r
-}\r
-\r
-void InkscapePainter::startDocument(double width, double height) \r
-{\r
- document = "";\r
- printf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");\r
- printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"");\r
- printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");\r
-\r
-// printf("<!-- Created with wpg2svg/libwpg %s -->\n", LIBWPG_VERSION_STRING);\r
-\r
- printf("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" ");\r
- printf("xmlns:xlink=\"http://www.w3.org/1999/xlink\" "); \r
- printf("width=\"%g\" height=\"%f\" >\n", 72*width, 72*height);\r
- \r
- m_gradientIndex = 1;\r
-}\r
-\r
-void InkscapePainter::endDocument()\r
-{\r
- printf("</svg>\n");\r
-}\r
-\r
-void InkscapePainter::setPen(const WPGPen& pen)\r
-{\r
- m_pen = pen;\r
-}\r
-\r
-void InkscapePainter::setBrush(const WPGBrush& brush)\r
-{\r
- m_brush = brush;\r
- \r
- if(m_brush.style == WPGBrush::Gradient)\r
- {\r
- double angle = m_brush.gradient.angle();\r
-\r
- printf("<defs>\n");\r
- printf(" <linearGradient id=\"grad%d\" >\n", m_gradientIndex++);\r
- for(unsigned c = 0; c < m_brush.gradient.count(); c++)\r
- {\r
- // round to nearest percentage\r
- int ofs = (int)(100.0*m_brush.gradient.stopOffset(c)+0.5);\r
-\r
- WPGColor color = m_brush.gradient.stopColor(c);\r
- printf(" <stop offset=\"%d%%\" stop-color=\"#%02x%02x%02x\" />\n",\r
- ofs, color.red, color.green, color.blue);\r
- }\r
- printf(" </linearGradient>\n");\r
- \r
- // not a simple horizontal gradient\r
- if(angle != -90.0)\r
- {\r
- printf(" <linearGradient xlink:href=\"#grad%d\"", m_gradientIndex-1);\r
- printf(" id=\"grad%d\" ", m_gradientIndex++);\r
- printf("x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\" "); \r
- printf("gradientTransform=\"rotate(%f)\" ", angle);\r
- printf("gradientUnits=\"objectBoundingBox\" >\n");\r
- printf(" </linearGradient>\n");\r
- }\r
- \r
- printf("</defs>\n");\r
- }\r
-}\r
-\r
-void InkscapePainter::setFillRule(FillRule rule)\r
-{\r
- m_fillRule = rule;\r
-}\r
-\r
-void InkscapePainter::startLayer(unsigned int id)\r
-{\r
- printf("<g id=\"Layer%d\" >\n", id);\r
-}\r
-\r
-void InkscapePainter::endLayer(unsigned int)\r
-{\r
- printf("</g>\n");\r
-}\r
-\r
-void InkscapePainter::drawRectangle(const WPGRect& rect, double rx, double ry)\r
-{\r
- printf("<rect ");\r
- printf("x=\"%f\" y=\"%f\" ", 72*rect.x1, 72*rect.y1);\r
- printf("width=\"%f\" height=\"%f\" ", 72*rect.width(), 72*rect.height());\r
- if((rx !=0) || (ry !=0))\r
- printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry);\r
- writeStyle();\r
- printf("/>\n");\r
-}\r
-\r
-void InkscapePainter::drawEllipse(const WPGPoint& center, double rx, double ry)\r
-{\r
- printf("<ellipse ");\r
- printf("cx=\"%f\" cy=\"%f\" ", 72*center.x, 72*center.y);\r
- printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry);\r
- writeStyle();\r
- printf("/>\n");\r
-}\r
-\r
-void InkscapePainter::drawPolygon(const WPGPointArray& vertices)\r
-{\r
- if(vertices.count() < 2)\r
- return;\r
-\r
- if(vertices.count() == 2)\r
- {\r
- const WPGPoint& p1 = vertices[0];\r
- const WPGPoint& p2 = vertices[1];\r
- printf("<line ");\r
- printf("x1=\"%f\" y1=\"%f\" ", 72*p1.x, 72*p1.y);\r
- printf("x2=\"%f\" y2=\"%f\"\n", 72*p2.x, 72*p2.y);\r
- writeStyle();\r
- printf("/>\n");\r
- }\r
- else\r
- {\r
- printf("<polyline ");\r
- printf("points=\"");\r
- for(unsigned i = 0; i < vertices.count(); i++)\r
- {\r
- printf("%f %f", 72*vertices[i].x, 72*vertices[i].y);\r
- if(i < vertices.count()-1) printf(", ");\r
- }\r
- printf("\"\n");\r
- writeStyle();\r
- printf("/>\n");\r
- }\r
-}\r
-\r
-void InkscapePainter::drawPath(const WPGPath& path)\r
-{\r
- printf("<path d=\"");\r
- for(unsigned i = 0; i < path.count(); i++)\r
- {\r
- WPGPathElement element = path.element(i);\r
- WPGPoint point = element.point;\r
- switch(element.type)\r
- {\r
- case WPGPathElement::MoveToElement:\r
- printf("\n M%f,%f ", 72*point.x, 72*point.y );\r
- break;\r
- \r
- case WPGPathElement::LineToElement:\r
- printf("\n L%f,%f ", 72*point.x, 72*point.y );\r
- break;\r
- \r
- case WPGPathElement::CurveToElement:\r
- printf("C");\r
- printf("%f,%f ", 72*element.extra1.x, 72*element.extra1.y );\r
- printf("%f,%f ", 72*element.extra2.x, 72*element.extra2.y );\r
- printf("%f,%f", 72*point.x, 72*point.y );\r
- break;\r
- \r
- default:\r
- break;\r
- }\r
- }\r
- \r
- if(path.closed)\r
- printf("Z");\r
-\r
- printf("\" \n");\r
- writeStyle();\r
- printf("/>\n");\r
-}\r
-\r
-// create "style" attribute based on current pen and brush\r
-void InkscapePainter::writeStyle()\r
-{\r
- printf("style=\"");\r
-\r
- const WPGColor& color = m_pen.foreColor;\r
- printf("stroke-width: %f; ", 72*m_pen.width);\r
- if(m_pen.width > 0.0)\r
- {\r
- printf("stroke: rgb(%d,%d,%d); ", color.red, color.green, color.blue);\r
- if(color.alpha != 0)\r
- // alpha = 0 means opacity = 1.0, alpha = 256 means opacity = 0\r
- printf("stroke-opacity: %f; ", 1.0-(color.alpha/256.0));\r
- }\r
-\r
- if(!m_pen.solid)\r
- {\r
- printf("stroke-dasharray: ");\r
- for(unsigned i = 0; i < m_pen.dashArray.count(); i++)\r
- {\r
- printf("%f", 72*m_pen.dashArray.at(i)*m_pen.width);\r
- if(i < m_pen.dashArray.count()-1) \r
- printf(", ");\r
- }\r
- printf("; ");\r
- }\r
- \r
- if(m_brush.style == WPGBrush::NoBrush)\r
- printf("fill: none; ");\r
-\r
- if(m_fillRule == InkscapePainter::WindingFill)\r
- printf("fill-rule: nonzero; ");\r
- else if(m_fillRule == InkscapePainter::AlternatingFill)\r
- printf("fill-rule: evenodd; ");\r
-\r
- if(m_brush.style == WPGBrush::Gradient)\r
- printf("fill: url(#grad%d); ", m_gradientIndex-1);\r
-\r
- if(m_brush.style == WPGBrush::Solid)\r
- printf("fill: rgb(%d,%d,%d); ", m_brush.foreColor.red, \r
- m_brush.foreColor.green, m_brush.foreColor.blue);\r
-\r
- printf("\""); // style\r
-}\r
-\r
-SPDocument *\r
-WpgInput::open(Inkscape::Extension::Input * mod, const gchar * uri) {\r
- WPGInputStream* input = new WPGFileStream(uri);\r
- if (input->isOle()) {\r
- WPGInputStream* olestream = input->getWPGOleStream();\r
- if (olestream) {\r
- delete input;\r
- input = olestream;\r
- }\r
- }\r
-\r
- if (!WPGraphics::isSupported(input)) {\r
- //! \todo Dialog here\r
- // fprintf(stderr, "ERROR: Unsupported file format (unsupported version) or file is encrypted!\n");\r
- // printf("I'm giving up not supported\n");\r
- return NULL;\r
- }\r
-\r
- InkscapePainter painter;\r
- WPGraphics::parse(input, &painter);\r
-\r
- //printf("I've got a doc: \n%s", painter.document.c_str());\r
-\r
- return sp_document_new_from_mem(painter.document.c_str(), strlen(painter.document.c_str()), TRUE);\r
-}\r
-\r
-#include "clear-n_.h"\r
-\r
-void\r
-WpgInput::init(void) {\r
- Inkscape::Extension::Extension * ext;\r
-\r
- ext = Inkscape::Extension::build_from_mem(\r
- "<inkscape-extension>\n"\r
- "<name>" N_("WPG Input") "</name>\n"\r
- "<id>org.inkscape.input.wpg</id>\n"\r
- "<input>\n"\r
- "<extension>.wpg</extension>\n"\r
- "<mimetype>image/x-wpg</mimetype>\n"\r
- "<filetypename>" N_("WordPerfect Graphics (*.wpg)") "</filetypename>\n"\r
- "<filetypetooltip>" N_("Vector graphics format used by Corel WordPerfect") "</filetypetooltip>\n"\r
- "</input>\n"\r
- "</inkscape-extension>", new WpgInput());\r
-} // init\r
-\r
-} } } /* namespace Inkscape, Extension, Implementation */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+/*
+ * This file came from libwpg as a source, their utility wpg2svg
+ * specifically. It has been modified to work as an Inkscape extension.
+ * The Inkscape extension code is covered by this copyright, but the
+ * rest is covered by the one bellow.
+ *
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ *
+ */
+
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include <stdio.h>
+
+#include "wpg-input.h"
+#include "extension/system.h"
+#include "extension/input.h"
+#include "document.h"
+
+#include "libwpg/libwpg.h"
+#include "libwpg/WPGStreamImplementation.h"
+
+using namespace libwpg;
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class InkscapePainter : public libwpg::WPGPaintInterface {
+public:
+ InkscapePainter();
+
+ void startDocument(double imageWidth, double imageHeight);
+ void endDocument();
+ void startLayer(unsigned int id);
+ void endLayer(unsigned int id);
+
+ void setPen(const WPGPen& pen);
+ void setBrush(const WPGBrush& brush);
+ void setFillRule(FillRule rule);
+
+ void drawRectangle(const WPGRect& rect, double rx, double ry);
+ void drawEllipse(const WPGPoint& center, double rx, double ry);
+ void drawPolygon(const WPGPointArray& vertices);
+ void drawPath(const WPGPath& path);
+
+private:
+ WPGPen m_pen;
+ WPGBrush m_brush;
+ FillRule m_fillRule;
+ int m_gradientIndex;
+ void writeStyle();
+ void printf (char * fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ gchar * buf = g_strdup_vprintf(fmt, args);
+ va_end(args);
+ if (buf) {
+ document += buf;
+ g_free(buf);
+ }
+ }
+
+public:
+ Glib::ustring document;
+};
+
+InkscapePainter::InkscapePainter(): m_fillRule(AlternatingFill), m_gradientIndex(1)
+{
+}
+
+void InkscapePainter::startDocument(double width, double height)
+{
+ document = "";
+ printf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+ printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"");
+ printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
+
+// printf("<!-- Created with wpg2svg/libwpg %s -->\n", LIBWPG_VERSION_STRING);
+
+ printf("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" ");
+ printf("xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
+ printf("width=\"%g\" height=\"%f\" >\n", 72*width, 72*height);
+
+ m_gradientIndex = 1;
+}
+
+void InkscapePainter::endDocument()
+{
+ printf("</svg>\n");
+}
+
+void InkscapePainter::setPen(const WPGPen& pen)
+{
+ m_pen = pen;
+}
+
+void InkscapePainter::setBrush(const WPGBrush& brush)
+{
+ m_brush = brush;
+
+ if(m_brush.style == WPGBrush::Gradient)
+ {
+ double angle = m_brush.gradient.angle();
+
+ printf("<defs>\n");
+ printf(" <linearGradient id=\"grad%d\" >\n", m_gradientIndex++);
+ for(unsigned c = 0; c < m_brush.gradient.count(); c++)
+ {
+ // round to nearest percentage
+ int ofs = (int)(100.0*m_brush.gradient.stopOffset(c)+0.5);
+
+ WPGColor color = m_brush.gradient.stopColor(c);
+ printf(" <stop offset=\"%d%%\" stop-color=\"#%02x%02x%02x\" />\n",
+ ofs, color.red, color.green, color.blue);
+ }
+ printf(" </linearGradient>\n");
+
+ // not a simple horizontal gradient
+ if(angle != -90.0)
+ {
+ printf(" <linearGradient xlink:href=\"#grad%d\"", m_gradientIndex-1);
+ printf(" id=\"grad%d\" ", m_gradientIndex++);
+ printf("x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\" ");
+ printf("gradientTransform=\"rotate(%f)\" ", angle);
+ printf("gradientUnits=\"objectBoundingBox\" >\n");
+ printf(" </linearGradient>\n");
+ }
+
+ printf("</defs>\n");
+ }
+}
+
+void InkscapePainter::setFillRule(FillRule rule)
+{
+ m_fillRule = rule;
+}
+
+void InkscapePainter::startLayer(unsigned int id)
+{
+ printf("<g id=\"Layer%d\" >\n", id);
+}
+
+void InkscapePainter::endLayer(unsigned int)
+{
+ printf("</g>\n");
+}
+
+void InkscapePainter::drawRectangle(const WPGRect& rect, double rx, double ry)
+{
+ printf("<rect ");
+ printf("x=\"%f\" y=\"%f\" ", 72*rect.x1, 72*rect.y1);
+ printf("width=\"%f\" height=\"%f\" ", 72*rect.width(), 72*rect.height());
+ if((rx !=0) || (ry !=0))
+ printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry);
+ writeStyle();
+ printf("/>\n");
+}
+
+void InkscapePainter::drawEllipse(const WPGPoint& center, double rx, double ry)
+{
+ printf("<ellipse ");
+ printf("cx=\"%f\" cy=\"%f\" ", 72*center.x, 72*center.y);
+ printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry);
+ writeStyle();
+ printf("/>\n");
+}
+
+void InkscapePainter::drawPolygon(const WPGPointArray& vertices)
+{
+ if(vertices.count() < 2)
+ return;
+
+ if(vertices.count() == 2)
+ {
+ const WPGPoint& p1 = vertices[0];
+ const WPGPoint& p2 = vertices[1];
+ printf("<line ");
+ printf("x1=\"%f\" y1=\"%f\" ", 72*p1.x, 72*p1.y);
+ printf("x2=\"%f\" y2=\"%f\"\n", 72*p2.x, 72*p2.y);
+ writeStyle();
+ printf("/>\n");
+ }
+ else
+ {
+ printf("<polyline ");
+ printf("points=\"");
+ for(unsigned i = 0; i < vertices.count(); i++)
+ {
+ printf("%f %f", 72*vertices[i].x, 72*vertices[i].y);
+ if(i < vertices.count()-1) printf(", ");
+ }
+ printf("\"\n");
+ writeStyle();
+ printf("/>\n");
+ }
+}
+
+void InkscapePainter::drawPath(const WPGPath& path)
+{
+ printf("<path d=\"");
+ for(unsigned i = 0; i < path.count(); i++)
+ {
+ WPGPathElement element = path.element(i);
+ WPGPoint point = element.point;
+ switch(element.type)
+ {
+ case WPGPathElement::MoveToElement:
+ printf("\n M%f,%f ", 72*point.x, 72*point.y );
+ break;
+
+ case WPGPathElement::LineToElement:
+ printf("\n L%f,%f ", 72*point.x, 72*point.y );
+ break;
+
+ case WPGPathElement::CurveToElement:
+ printf("C");
+ printf("%f,%f ", 72*element.extra1.x, 72*element.extra1.y );
+ printf("%f,%f ", 72*element.extra2.x, 72*element.extra2.y );
+ printf("%f,%f", 72*point.x, 72*point.y );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if(path.closed)
+ printf("Z");
+
+ printf("\" \n");
+ writeStyle();
+ printf("/>\n");
+}
+
+// create "style" attribute based on current pen and brush
+void InkscapePainter::writeStyle()
+{
+ printf("style=\"");
+
+ const WPGColor& color = m_pen.foreColor;
+ printf("stroke-width: %f; ", 72*m_pen.width);
+ if(m_pen.width > 0.0)
+ {
+ printf("stroke: rgb(%d,%d,%d); ", color.red, color.green, color.blue);
+ if(color.alpha != 0)
+ // alpha = 0 means opacity = 1.0, alpha = 256 means opacity = 0
+ printf("stroke-opacity: %f; ", 1.0-(color.alpha/256.0));
+ }
+
+ if(!m_pen.solid)
+ {
+ printf("stroke-dasharray: ");
+ for(unsigned i = 0; i < m_pen.dashArray.count(); i++)
+ {
+ printf("%f", 72*m_pen.dashArray.at(i)*m_pen.width);
+ if(i < m_pen.dashArray.count()-1)
+ printf(", ");
+ }
+ printf("; ");
+ }
+
+ if(m_brush.style == WPGBrush::NoBrush)
+ printf("fill: none; ");
+
+ if(m_fillRule == InkscapePainter::WindingFill)
+ printf("fill-rule: nonzero; ");
+ else if(m_fillRule == InkscapePainter::AlternatingFill)
+ printf("fill-rule: evenodd; ");
+
+ if(m_brush.style == WPGBrush::Gradient)
+ printf("fill: url(#grad%d); ", m_gradientIndex-1);
+
+ if(m_brush.style == WPGBrush::Solid)
+ printf("fill: rgb(%d,%d,%d); ", m_brush.foreColor.red,
+ m_brush.foreColor.green, m_brush.foreColor.blue);
+
+ printf("\""); // style
+}
+
+SPDocument *
+WpgInput::open(Inkscape::Extension::Input * mod, const gchar * uri) {
+ WPGInputStream* input = new WPGFileStream(uri);
+ if (input->isOle()) {
+ WPGInputStream* olestream = input->getWPGOleStream();
+ if (olestream) {
+ delete input;
+ input = olestream;
+ }
+ }
+
+ if (!WPGraphics::isSupported(input)) {
+ //! \todo Dialog here
+ // fprintf(stderr, "ERROR: Unsupported file format (unsupported version) or file is encrypted!\n");
+ // printf("I'm giving up not supported\n");
+ return NULL;
+ }
+
+ InkscapePainter painter;
+ WPGraphics::parse(input, &painter);
+
+ //printf("I've got a doc: \n%s", painter.document.c_str());
+
+ return sp_document_new_from_mem(painter.document.c_str(), strlen(painter.document.c_str()), TRUE);
+}
+
+#include "clear-n_.h"
+
+void
+WpgInput::init(void) {
+ Inkscape::Extension::Extension * ext;
+
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>" N_("WPG Input") "</name>\n"
+ "<id>org.inkscape.input.wpg</id>\n"
+ "<input>\n"
+ "<extension>.wpg</extension>\n"
+ "<mimetype>image/x-wpg</mimetype>\n"
+ "<filetypename>" N_("WordPerfect Graphics (*.wpg)") "</filetypename>\n"
+ "<filetypetooltip>" N_("Vector graphics format used by Corel WordPerfect") "</filetypetooltip>\n"
+ "</input>\n"
+ "</inkscape-extension>", new WpgInput());
+} // init
+
+} } } /* namespace Inkscape, Extension, Implementation */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 1e95a18f06bb56fa569440dfc6759c8034ded844..283ef8f5c23ffe30dfc4257a4b39192ff59cdcb1 100644 (file)
-/** \file\r
- * extension parameter for enumerations.\r
- *\r
- * It uses a Gtk:ComboBoxText widget in the extension UI.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006-2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-\r
-#include <gtkmm/box.h>\r
-#include <gtkmm/comboboxtext.h>\r
-#include <gtkmm/tooltips.h>\r
-#include <gtkmm/label.h>\r
-\r
-#include <glibmm/i18n.h>\r
-\r
-#include <xml/node.h>\r
-\r
-#include "extension.h"\r
-#include "prefs-utils.h"\r
-#include "document-private.h"\r
-#include "sp-object.h"\r
-\r
-#include "paramenum.h"\r
-\r
-/** \brief The root directory in the preferences database for extension\r
- related parameters. */\r
-#define PREF_DIR "extensions"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-/* For internal use only.\r
- Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */\r
-class enumentry {\r
-public:\r
- enumentry (Glib::ustring * val, Glib::ustring * text) {\r
- value = val;\r
- guitext = text;\r
- }\r
- ~enumentry() {\r
- delete value;\r
- delete guitext;\r
- }\r
-\r
- Glib::ustring * value;\r
- Glib::ustring * guitext;\r
-};\r
-\r
-\r
-ParamComboBox::ParamComboBox (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
- Parameter(name, guitext, desc, scope, ext)\r
-{\r
- choices = NULL;\r
- _value = NULL;\r
-\r
- // Read XML tree to add enumeration items:\r
- // printf("Extension Constructor: ");\r
- if (xml != NULL) {\r
- Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
- while (child_repr != NULL) {\r
- char const * chname = child_repr->name();\r
- if (!strcmp(chname, "item")) {\r
- Glib::ustring * newguitext = NULL;\r
- Glib::ustring * newvalue = NULL;\r
- const char * contents = sp_repr_children(child_repr)->content();\r
- if (contents != NULL)\r
- newguitext = new Glib::ustring( _(contents) );\r
- const char * val = child_repr->attribute("value");\r
- if (val != NULL)\r
- newvalue = new Glib::ustring(val);\r
- if ( (newguitext) && (newvalue) ) {\r
- choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );\r
- }\r
- }\r
- child_repr = sp_repr_next(child_repr);\r
- }\r
- }\r
-\r
- // Initialize _value with the default value from xml\r
- // for simplicity : default to the contents of the first xml-child\r
- const char * defaultval = NULL;\r
- if (sp_repr_children(sp_repr_children(xml)) != NULL)\r
- defaultval = sp_repr_children(xml)->attribute("value");\r
-\r
- gchar * pref_name = this->pref_name();\r
- const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);\r
- g_free(pref_name);\r
-\r
- if (paramval != NULL)\r
- defaultval = paramval;\r
- if (defaultval != NULL)\r
- _value = g_strdup(defaultval); // allocate space for _value\r
-\r
- return;\r
-}\r
-\r
-ParamComboBox::~ParamComboBox (void)\r
-{\r
- //destroy choice strings\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- delete (reinterpret_cast<enumentry *>(list->data));\r
- }\r
- g_slist_free(choices);\r
-\r
- g_free(_value);\r
-}\r
-\r
-\r
-/** \brief A function to set the \c _value\r
- \param in The value to set\r
- \param doc A document that should be used to set the value.\r
- \param node The node where the value may be placed\r
-\r
- This function sets ONLY the internal value, but it also sets the value\r
- in the preferences structure. To put it in the right place, \c PREF_DIR\r
- and \c pref_name() are used.\r
-\r
- To copy the data into _value the old memory must be free'd first.\r
- It is important to note that \c g_free handles \c NULL just fine. Then\r
- the passed in value is duplicated using \c g_strdup().\r
-*/\r
-const gchar *\r
-ParamComboBox::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- if (in == NULL) return NULL; /* Can't have NULL string */\r
-\r
- Glib::ustring * settext = NULL;\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- enumentry * entr = reinterpret_cast<enumentry *>(list->data);\r
- if ( !entr->guitext->compare(in) ) {\r
- settext = entr->value;\r
- break; // break out of for loop\r
- }\r
- }\r
- if (settext) {\r
- if (_value != NULL) g_free(_value);\r
- _value = g_strdup(settext->c_str());\r
- gchar * prefname = this->pref_name();\r
- prefs_set_string_attribute(PREF_DIR, prefname, _value);\r
- g_free(prefname);\r
- }\r
-\r
- return _value;\r
-}\r
-\r
-\r
-/**\r
- \brief A function to get the value of the parameter in string form\r
- \return A string with the 'value' as command line argument\r
-*/\r
-Glib::ustring *\r
-ParamComboBox::string (void)\r
-{\r
- Glib::ustring * param_string = new Glib::ustring("");\r
-\r
- *param_string += "\"";\r
- *param_string += _value;\r
- *param_string += "\"";\r
-\r
- return param_string;\r
-}\r
-\r
-/** \brief A special category of Gtk::Entry to handle string parameteres */\r
-class ParamComboBoxEntry : public Gtk::ComboBoxText {\r
-private:\r
- ParamComboBox * _pref;\r
- SPDocument * _doc;\r
- Inkscape::XML::Node * _node;\r
-public:\r
- /** \brief Build a string preference for the given parameter\r
- \param pref Where to get the string from, and where to put it\r
- when it changes.\r
- */\r
- ParamComboBoxEntry (ParamComboBox * pref, SPDocument * doc, Inkscape::XML::Node * node) :\r
- Gtk::ComboBoxText(), _pref(pref), _doc(doc), _node(node) {\r
- this->signal_changed().connect(sigc::mem_fun(this, &ParamComboBoxEntry::changed));\r
- };\r
- void changed (void);\r
-};\r
-\r
-/** \brief Respond to the text box changing\r
-\r
- This function responds to the box changing by grabbing the value\r
- from the text box and putting it in the parameter.\r
-*/\r
-void\r
-ParamComboBoxEntry::changed (void)\r
-{\r
- Glib::ustring data = this->get_active_text();\r
- _pref->set(data.c_str(), _doc, _node);\r
- return;\r
-}\r
-\r
-\r
-\r
-/**\r
- \brief Creates a combobox widget for an enumeration parameter\r
-*/\r
-Gtk::Widget *\r
-ParamComboBox::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));\r
-\r
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));\r
- label->show();\r
- hbox->pack_start(*label, false, false);\r
-\r
- ParamComboBoxEntry * combo = Gtk::manage(new ParamComboBoxEntry(this, doc, node));\r
- // add choice strings:\r
- Glib::ustring * settext = 0;\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- enumentry * entr = reinterpret_cast<enumentry *>(list->data);\r
- Glib::ustring * text = entr->guitext;\r
- combo->append_text(*text);\r
- if ( !entr->value->compare(_value) ) {\r
- settext = entr->guitext;\r
- }\r
- }\r
- if (settext) combo->set_active_text(*settext);\r
-\r
- combo->show();\r
- hbox->pack_start(*combo, true, true);\r
-\r
- hbox->show();\r
-\r
- return dynamic_cast<Gtk::Widget *>(hbox);\r
-}\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
+/** \file
+ * extension parameter for enumerations.
+ *
+ * It uses a Gtk:ComboBoxText widget in the extension UI.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/box.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include "extension.h"
+#include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
+
+#include "paramenum.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+/* For internal use only.
+ Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+class enumentry {
+public:
+ enumentry (Glib::ustring * val, Glib::ustring * text) {
+ value = val;
+ guitext = text;
+ }
+ ~enumentry() {
+ delete value;
+ delete guitext;
+ }
+
+ Glib::ustring * value;
+ Glib::ustring * guitext;
+};
+
+
+ParamComboBox::ParamComboBox (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, ext)
+{
+ choices = NULL;
+ _value = NULL;
+
+ // Read XML tree to add enumeration items:
+ // printf("Extension Constructor: ");
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (!strcmp(chname, "item")) {
+ Glib::ustring * newguitext = NULL;
+ Glib::ustring * newvalue = NULL;
+ const char * contents = sp_repr_children(child_repr)->content();
+ if (contents != NULL)
+ newguitext = new Glib::ustring( _(contents) );
+ const char * val = child_repr->attribute("value");
+ if (val != NULL)
+ newvalue = new Glib::ustring(val);
+ if ( (newguitext) && (newvalue) ) {
+ choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );
+ }
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the default value from xml
+ // for simplicity : default to the contents of the first xml-child
+ const char * defaultval = NULL;
+ if (sp_repr_children(sp_repr_children(xml)) != NULL)
+ defaultval = sp_repr_children(xml)->attribute("value");
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamComboBox::~ParamComboBox (void)
+{
+ //destroy choice strings
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ delete (reinterpret_cast<enumentry *>(list->data));
+ }
+ g_slist_free(choices);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The value to set
+ \param doc A document that should be used to set the value.
+ \param node The node where the value may be placed
+
+ This function sets ONLY the internal value, but it also sets the value
+ in the preferences structure. To put it in the right place, \c PREF_DIR
+ and \c pref_name() are used.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamComboBox::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ if (in == NULL) return NULL; /* Can't have NULL string */
+
+ Glib::ustring * settext = NULL;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ enumentry * entr = reinterpret_cast<enumentry *>(list->data);
+ if ( !entr->guitext->compare(in) ) {
+ settext = entr->value;
+ break; // break out of for loop
+ }
+ }
+ if (settext) {
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(settext->c_str());
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+ }
+
+ return _value;
+}
+
+
+/**
+ \brief A function to get the value of the parameter in string form
+ \return A string with the 'value' as command line argument
+*/
+Glib::ustring *
+ParamComboBox::string (void)
+{
+ Glib::ustring * param_string = new Glib::ustring("");
+
+ *param_string += "\"";
+ *param_string += _value;
+ *param_string += "\"";
+
+ return param_string;
+}
+
+/** \brief A special category of Gtk::Entry to handle string parameteres */
+class ParamComboBoxEntry : public Gtk::ComboBoxText {
+private:
+ ParamComboBox * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+public:
+ /** \brief Build a string preference for the given parameter
+ \param pref Where to get the string from, and where to put it
+ when it changes.
+ */
+ ParamComboBoxEntry (ParamComboBox * pref, SPDocument * doc, Inkscape::XML::Node * node) :
+ Gtk::ComboBoxText(), _pref(pref), _doc(doc), _node(node) {
+ this->signal_changed().connect(sigc::mem_fun(this, &ParamComboBoxEntry::changed));
+ };
+ void changed (void);
+};
+
+/** \brief Respond to the text box changing
+
+ This function responds to the box changing by grabbing the value
+ from the text box and putting it in the parameter.
+*/
+void
+ParamComboBoxEntry::changed (void)
+{
+ Glib::ustring data = this->get_active_text();
+ _pref->set(data.c_str(), _doc, _node);
+ return;
+}
+
+
+
+/**
+ \brief Creates a combobox widget for an enumeration parameter
+*/
+Gtk::Widget *
+ParamComboBox::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
+ label->show();
+ hbox->pack_start(*label, false, false);
+
+ ParamComboBoxEntry * combo = Gtk::manage(new ParamComboBoxEntry(this, doc, node));
+ // add choice strings:
+ Glib::ustring * settext = 0;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ enumentry * entr = reinterpret_cast<enumentry *>(list->data);
+ Glib::ustring * text = entr->guitext;
+ combo->append_text(*text);
+ if ( !entr->value->compare(_value) ) {
+ settext = entr->guitext;
+ }
+ }
+ if (settext) combo->set_active_text(*settext);
+
+ combo->show();
+ hbox->pack_start(*combo, true, true);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
index f6fea4e05717f06c2ca566fc631331cf17c32b77..4ad4485496efb3b72d284885088e636bbfd78a6e 100644 (file)
-#ifndef __INK_EXTENSION_PARAMENUM_H__\r
-#define __INK_EXTENSION_PARAMENUM_H__\r
-\r
-/** \file\r
- * Enumeration parameter for extensions.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006-2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <gtkmm/widget.h>\r
-\r
-#include "xml/document.h"\r
-#include "extension-forward.h"\r
-\r
-#include "parameter.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-\r
-\r
-// \brief A class to represent a notebookparameter of an extension\r
-class ParamComboBox : public Parameter {\r
-private:\r
- /** \brief Internal value. This should point to a string that has\r
- been allocated in memory. And should be free'd. \r
- It is the value of the current selected string */\r
- gchar * _value;\r
- \r
- GSList * choices; /**< A table to store the choice strings */\r
- \r
-public:\r
- ParamComboBox(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
- ~ParamComboBox(void);\r
- Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
- Glib::ustring * string (void);\r
- \r
- const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }\r
- const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);\r
-}; /* class ParamComboBox */\r
-\r
-\r
-\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-#endif /* __INK_EXTENSION_PARAMENUM_H__ */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#ifndef __INK_EXTENSION_PARAMENUM_H__
+#define __INK_EXTENSION_PARAMENUM_H__
+
+/** \file
+ * Enumeration parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include "extension-forward.h"
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a notebookparameter of an extension
+class ParamComboBox : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the value of the current selected string */
+ gchar * _value;
+
+ GSList * choices; /**< A table to store the choice strings */
+
+public:
+ ParamComboBox(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ ~ParamComboBox(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
+ Glib::ustring * string (void);
+
+ const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+ const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
+}; /* class ParamComboBox */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMENUM_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index cd8bddcaa0e435ceb59de3bafaa41d08922bd448..e8bd1e902273b6c768a80d20d25b67d3b4010670 100644 (file)
-/** \file\r
- * Notebook and NotebookPage parameters for extensions.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006 Author\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-\r
-#include <gtkmm/adjustment.h>\r
-#include <gtkmm/box.h>\r
-#include <gtkmm/spinbutton.h>\r
-#include <gtkmm/notebook.h>\r
-#include <gtkmm/tooltips.h>\r
-\r
-#include <glibmm/i18n.h>\r
-\r
-#include <xml/node.h>\r
-\r
-#include "extension.h"\r
-#include "prefs-utils.h"\r
-#include "document-private.h"\r
-#include "sp-object.h"\r
-\r
-#include "paramnotebook.h"\r
-\r
-/** \brief The root directory in the preferences database for extension\r
- related parameters. */\r
-#define PREF_DIR "extensions"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-\r
-// \brief A class to represent the pages of a notebookparameter of an extension\r
-class ParamNotebookPage : public Parameter {\r
-private:\r
- GSList * parameters; /**< A table to store the parameters for this page.\r
- This only gets created if there are parameters on this\r
- page */\r
- Gtk::Tooltips * _tooltips;\r
- \r
-public:\r
- static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);\r
-\r
- ParamNotebookPage(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
- ~ParamNotebookPage(void);\r
- Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
- Glib::ustring * paramString (void);\r
- gchar * get_guitext (void) {return _text;};\r
- \r
-}; /* class ParamNotebookPage */\r
-\r
-\r
-ParamNotebookPage::ParamNotebookPage (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
- Parameter(name, guitext, desc, scope, ext)\r
-{\r
- parameters = NULL;\r
- \r
- // Read XML to build page\r
- if (xml != NULL) {\r
- Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
- while (child_repr != NULL) {\r
- char const * chname = child_repr->name();\r
- if (chname[0] == '_') // Allow _ for translation of tags\r
- chname++;\r
- if (!strcmp(chname, "param") || !strcmp(chname, "_param")) {\r
- Parameter * param;\r
- param = Parameter::make(child_repr, ext);\r
- if (param != NULL) parameters = g_slist_append(parameters, param);\r
- }\r
- child_repr = sp_repr_next(child_repr);\r
- }\r
- }\r
- \r
- return;\r
-}\r
-\r
-ParamNotebookPage::~ParamNotebookPage (void)\r
-{\r
- if (_tooltips) delete _tooltips;\r
- //destroy parameters\r
- for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
- Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
- delete param;\r
- }\r
- g_slist_free(parameters);\r
-}\r
-\r
-/** \brief Return the value as a string */\r
-Glib::ustring *\r
-ParamNotebookPage::paramString (void)\r
-{\r
- Glib::ustring * param_string = new Glib::ustring("");\r
-\r
- for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
- Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
-\r
- *param_string += " --";\r
- *param_string += param->name();\r
- *param_string += "=";\r
- Glib::ustring * paramstr = param->string();\r
- *param_string += *paramstr;\r
- delete paramstr;\r
- }\r
-\r
- return param_string;\r
-}\r
-\r
-\r
-/**\r
- \return None\r
- \brief This function creates a page that can be used later. This\r
- is typically done in the creation of the notebook and defined\r
- in the XML file describing the extension (it's private so people\r
- have to use the system) :)\r
- \param in_repr The XML describing the page\r
-\r
- This function first grabs all of the data out of the Repr and puts\r
- it into local variables. Actually, these are just pointers, and the\r
- data is not duplicated so we need to be careful with it. If there\r
- isn't a name in the XML, then no page is created as\r
- the function just returns.\r
-\r
- From this point on, we're pretty committed as we've allocated an\r
- object and we're starting to fill it. The name is set first, and\r
- is created with a strdup to actually allocate memory for it. Then\r
- there is a case statement (roughly because strcmp requires 'ifs')\r
- based on what type of parameter this is. Depending which type it\r
- is, the value is interpreted differently, but they are relatively\r
- straight forward. In all cases the value is set to the default\r
- value from the XML and the type is set to the interpreted type.\r
-*/\r
-ParamNotebookPage *\r
-ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)\r
-{\r
- const char * name;\r
- const char * guitext;\r
- const char * desc;\r
- const char * scope_str;\r
- Parameter::_scope_t scope = Parameter::SCOPE_USER;\r
-\r
- name = in_repr->attribute("name");\r
- guitext = in_repr->attribute("gui-text");\r
- if (guitext == NULL)\r
- guitext = in_repr->attribute("_gui-text");\r
- desc = in_repr->attribute("gui-description");\r
- if (desc == NULL)\r
- desc = in_repr->attribute("_gui-description");\r
- scope_str = in_repr->attribute("scope");\r
-\r
- /* In this case we just don't have enough information */\r
- if (name == NULL) {\r
- return NULL;\r
- }\r
-\r
- if (scope_str != NULL) {\r
- if (!strcmp(scope_str, "user")) {\r
- scope = Parameter::SCOPE_USER;\r
- } else if (!strcmp(scope_str, "document")) {\r
- scope = Parameter::SCOPE_DOCUMENT;\r
- } else if (!strcmp(scope_str, "node")) {\r
- scope = Parameter::SCOPE_NODE;\r
- }\r
- }\r
-\r
- ParamNotebookPage * page = new ParamNotebookPage(name, guitext, desc, scope, in_ext, in_repr);\r
- \r
- /* Note: page could equal NULL */\r
- return page;\r
-}\r
-\r
-\r
-\r
-/**\r
- \brief Creates a notebookpage widget for a notebook\r
-\r
- Builds a notebook page (a vbox) and puts parameters on it.\r
-*/\r
-Gtk::Widget *\r
-ParamNotebookPage::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
-{ \r
- if (!_tooltips) _tooltips = new Gtk::Tooltips();\r
- \r
- Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox);\r
- vbox->set_border_width(5); \r
- \r
- // add parameters onto page (if any) \r
- for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
- Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
- Gtk::Widget * widg = param->get_widget(doc, node);\r
- gchar const * tip = param->get_tooltip();\r
- \r
- vbox->pack_start(*widg, true, true, 2);\r
- if (tip != NULL) {\r
- _tooltips->set_tip(*widg, Glib::ustring(tip));\r
- }\r
- }\r
- \r
- vbox->show();\r
- \r
- return dynamic_cast<Gtk::Widget *>(vbox);\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-ParamNotebook::ParamNotebook (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
- Parameter(name, guitext, desc, scope, ext)\r
-{\r
- pages = NULL;\r
- \r
- // Read XML tree to add pages:\r
- if (xml != NULL) {\r
- Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
- while (child_repr != NULL) {\r
- char const * chname = child_repr->name();\r
- if (chname[0] == '_') // Allow _ for translation of tags\r
- chname++;\r
- if (!strcmp(chname, "page")) {\r
- ParamNotebookPage * page;\r
- page = ParamNotebookPage::makepage(child_repr, ext);\r
- if (page != NULL) pages = g_slist_append(pages, page);\r
- }\r
- child_repr = sp_repr_next(child_repr);\r
- }\r
- }\r
- \r
- // Initialize _value with the current page\r
- const char * defaultval = NULL;\r
- // set first page as default\r
- if (pages != NULL) {\r
- ParamNotebookPage * defpage = reinterpret_cast<ParamNotebookPage *>(pages->data);\r
- defaultval = defpage->name();\r
- }\r
-\r
- gchar * pref_name = this->pref_name();\r
- const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);\r
- g_free(pref_name);\r
-\r
- if (paramval != NULL)\r
- defaultval = paramval;\r
- if (defaultval != NULL)\r
- _value = g_strdup(defaultval); // allocate space for _value\r
- \r
- return;\r
-}\r
-\r
-ParamNotebook::~ParamNotebook (void)\r
-{\r
- //destroy pages\r
- for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
- ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
- delete page;\r
- }\r
- g_slist_free(pages);\r
-\r
- g_free(_value);\r
-}\r
-\r
-\r
-/** \brief A function to set the \c _value\r
- \param in The number of the page which value must be set\r
- \param doc A document that should be used to set the value.\r
- \param node The node where the value may be placed\r
-\r
- This function sets the internal value, but it also sets the value\r
- in the preferences structure. To put it in the right place, \c PREF_DIR\r
- and \c pref_name() are used.\r
-\r
- To copy the data into _value the old memory must be free'd first.\r
- It is important to note that \c g_free handles \c NULL just fine. Then\r
- the passed in value is duplicated using \c g_strdup().\r
-*/\r
-const gchar *\r
-ParamNotebook::set (const int in, SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- ParamNotebookPage * page = NULL;\r
- int i = 0;\r
- for (GSList * list = pages; (list != NULL) && (i <= in); list = g_slist_next(list)) {\r
- page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
- i++;\r
- }\r
- \r
- if (page == NULL) return _value;\r
- \r
- if (_value != NULL) g_free(_value);\r
- _value = g_strdup(page->name());\r
-\r
- gchar * prefname = this->pref_name();\r
- prefs_set_string_attribute(PREF_DIR, prefname, _value);\r
- g_free(prefname);\r
-\r
- return _value;\r
-}\r
-\r
-\r
-/**\r
- \brief A function to get the currentpage and the parameters in a string form\r
- \return A string with the 'value' and all the parameters on all pages as command line arguments\r
-\r
- This is really a hack. The function is called by Extension::paramString() to build\r
- the commandline string like: '--param1name=\"param1value\" --param2name=\"param2value\" ...'\r
- Extension::paramString expects this function to return '\"param1value\"'; but instead, \r
- this function returns: '\"param1value\" --page1param1name=\"page1param1value\" ...'\r
-\r
- \TODO Do this better. For example, make Parameter::paramString() that returns '--name=\"value\"'\r
- instead of just returning '\"value\"'.\r
-*/\r
-Glib::ustring *\r
-ParamNotebook::string (void)\r
-{\r
- Glib::ustring * param_string = new Glib::ustring("");\r
-\r
- *param_string += "\"";\r
- *param_string += _value; // the name of the current page\r
- *param_string += "\"";\r
-\r
- for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
- ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
-\r
- Glib::ustring * pageparamstr = page->paramString();\r
- *param_string += *pageparamstr;\r
- delete pageparamstr;\r
- }\r
-\r
- return param_string;\r
-}\r
-\r
-/** \brief A special category of Gtk::Notebook to handle notebook parameters */\r
-class ParamNotebookWdg : public Gtk::Notebook {\r
-private:\r
- ParamNotebook * _pref;\r
- SPDocument * _doc;\r
- Inkscape::XML::Node * _node;\r
-public:\r
- /** \brief Build a notebookpage preference for the given parameter\r
- \param pref Where to get the string (pagename) from, and where to put it\r
- when it changes.\r
- */\r
- ParamNotebookWdg (ParamNotebook * pref, SPDocument * doc, Inkscape::XML::Node * node) :\r
- Gtk::Notebook(), _pref(pref), _doc(doc), _node(node), activated(false) {\r
- // don't have to set the correct page: this is done in ParamNotebook::get_widget.\r
- // hook function\r
- this->signal_switch_page().connect(sigc::mem_fun(this, &ParamNotebookWdg::changed_page));\r
- return;\r
- };\r
- void changed_page(GtkNotebookPage *page, guint pagenum);\r
- bool activated;\r
-};\r
-\r
-/** \brief Respond to the selected page of notebook changing\r
- This function responds to the changing by reporting it to\r
- ParamNotebook. The change is only reported when the notebook\r
- is actually visible. This to exclude 'fake' changes when the\r
- notebookpages are added or removed.\r
-*/\r
-void\r
-ParamNotebookWdg::changed_page(GtkNotebookPage *page,\r
- guint pagenum)\r
-{\r
- if (is_visible()) {\r
- _pref->set((int)pagenum, _doc, _node);\r
- }\r
- return;\r
-}\r
-\r
-\r
-\r
-/**\r
- \brief Creates a Notebook widget for a notebook parameter\r
-\r
- Builds a notebook and puts pages in it.\r
-*/\r
-Gtk::Widget *\r
-ParamNotebook::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node));\r
-\r
- // add pages (if any) \r
- int i = -1;\r
- int pagenr = i;\r
- for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
- i++; \r
- ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
- Gtk::Widget * widg = page->get_widget(doc, node);\r
- nb->append_page(*widg, _(page->get_guitext()));\r
- if (!strcmp(_value, page->name())) {\r
- pagenr = i; // this is the page to be displayed?\r
- }\r
- }\r
-\r
- nb->show();\r
- \r
- if (pagenr >= 0) nb->set_current_page(pagenr);\r
-\r
- return dynamic_cast<Gtk::Widget *>(nb);\r
-}\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+/** \file
+ * Notebook and NotebookPage parameters for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/tooltips.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include "extension.h"
+#include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
+
+#include "paramnotebook.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+
+// \brief A class to represent the pages of a notebookparameter of an extension
+class ParamNotebookPage : public Parameter {
+private:
+ GSList * parameters; /**< A table to store the parameters for this page.
+ This only gets created if there are parameters on this
+ page */
+ Gtk::Tooltips * _tooltips;
+
+public:
+ static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);
+
+ ParamNotebookPage(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ ~ParamNotebookPage(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
+ Glib::ustring * paramString (void);
+ gchar * get_guitext (void) {return _text;};
+
+}; /* class ParamNotebookPage */
+
+
+ParamNotebookPage::ParamNotebookPage (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, ext)
+{
+ parameters = NULL;
+
+ // Read XML to build page
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (chname[0] == '_') // Allow _ for translation of tags
+ chname++;
+ if (!strcmp(chname, "param") || !strcmp(chname, "_param")) {
+ Parameter * param;
+ param = Parameter::make(child_repr, ext);
+ if (param != NULL) parameters = g_slist_append(parameters, param);
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ return;
+}
+
+ParamNotebookPage::~ParamNotebookPage (void)
+{
+ if (_tooltips) delete _tooltips;
+ //destroy parameters
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);
+ delete param;
+ }
+ g_slist_free(parameters);
+}
+
+/** \brief Return the value as a string */
+Glib::ustring *
+ParamNotebookPage::paramString (void)
+{
+ Glib::ustring * param_string = new Glib::ustring("");
+
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);
+
+ *param_string += " --";
+ *param_string += param->name();
+ *param_string += "=";
+ Glib::ustring * paramstr = param->string();
+ *param_string += *paramstr;
+ delete paramstr;
+ }
+
+ return param_string;
+}
+
+
+/**
+ \return None
+ \brief This function creates a page that can be used later. This
+ is typically done in the creation of the notebook and defined
+ in the XML file describing the extension (it's private so people
+ have to use the system) :)
+ \param in_repr The XML describing the page
+
+ This function first grabs all of the data out of the Repr and puts
+ it into local variables. Actually, these are just pointers, and the
+ data is not duplicated so we need to be careful with it. If there
+ isn't a name in the XML, then no page is created as
+ the function just returns.
+
+ From this point on, we're pretty committed as we've allocated an
+ object and we're starting to fill it. The name is set first, and
+ is created with a strdup to actually allocate memory for it. Then
+ there is a case statement (roughly because strcmp requires 'ifs')
+ based on what type of parameter this is. Depending which type it
+ is, the value is interpreted differently, but they are relatively
+ straight forward. In all cases the value is set to the default
+ value from the XML and the type is set to the interpreted type.
+*/
+ParamNotebookPage *
+ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
+{
+ const char * name;
+ const char * guitext;
+ const char * desc;
+ const char * scope_str;
+ Parameter::_scope_t scope = Parameter::SCOPE_USER;
+
+ name = in_repr->attribute("name");
+ guitext = in_repr->attribute("gui-text");
+ if (guitext == NULL)
+ guitext = in_repr->attribute("_gui-text");
+ desc = in_repr->attribute("gui-description");
+ if (desc == NULL)
+ desc = in_repr->attribute("_gui-description");
+ scope_str = in_repr->attribute("scope");
+
+ /* In this case we just don't have enough information */
+ if (name == NULL) {
+ return NULL;
+ }
+
+ if (scope_str != NULL) {
+ if (!strcmp(scope_str, "user")) {
+ scope = Parameter::SCOPE_USER;
+ } else if (!strcmp(scope_str, "document")) {
+ scope = Parameter::SCOPE_DOCUMENT;
+ } else if (!strcmp(scope_str, "node")) {
+ scope = Parameter::SCOPE_NODE;
+ }
+ }
+
+ ParamNotebookPage * page = new ParamNotebookPage(name, guitext, desc, scope, in_ext, in_repr);
+
+ /* Note: page could equal NULL */
+ return page;
+}
+
+
+
+/**
+ \brief Creates a notebookpage widget for a notebook
+
+ Builds a notebook page (a vbox) and puts parameters on it.
+*/
+Gtk::Widget *
+ParamNotebookPage::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+ if (!_tooltips) _tooltips = new Gtk::Tooltips();
+
+ Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox);
+ vbox->set_border_width(5);
+
+ // add parameters onto page (if any)
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);
+ Gtk::Widget * widg = param->get_widget(doc, node);
+ gchar const * tip = param->get_tooltip();
+
+ vbox->pack_start(*widg, true, true, 2);
+ if (tip != NULL) {
+ _tooltips->set_tip(*widg, Glib::ustring(tip));
+ }
+ }
+
+ vbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+
+
+
+
+
+
+
+
+ParamNotebook::ParamNotebook (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, ext)
+{
+ pages = NULL;
+
+ // Read XML tree to add pages:
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (chname[0] == '_') // Allow _ for translation of tags
+ chname++;
+ if (!strcmp(chname, "page")) {
+ ParamNotebookPage * page;
+ page = ParamNotebookPage::makepage(child_repr, ext);
+ if (page != NULL) pages = g_slist_append(pages, page);
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the current page
+ const char * defaultval = NULL;
+ // set first page as default
+ if (pages != NULL) {
+ ParamNotebookPage * defpage = reinterpret_cast<ParamNotebookPage *>(pages->data);
+ defaultval = defpage->name();
+ }
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamNotebook::~ParamNotebook (void)
+{
+ //destroy pages
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ delete page;
+ }
+ g_slist_free(pages);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The number of the page which value must be set
+ \param doc A document that should be used to set the value.
+ \param node The node where the value may be placed
+
+ This function sets the internal value, but it also sets the value
+ in the preferences structure. To put it in the right place, \c PREF_DIR
+ and \c pref_name() are used.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamNotebook::set (const int in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamNotebookPage * page = NULL;
+ int i = 0;
+ for (GSList * list = pages; (list != NULL) && (i <= in); list = g_slist_next(list)) {
+ page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ i++;
+ }
+
+ if (page == NULL) return _value;
+
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(page->name());
+
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+
+ return _value;
+}
+
+
+/**
+ \brief A function to get the currentpage and the parameters in a string form
+ \return A string with the 'value' and all the parameters on all pages as command line arguments
+
+ This is really a hack. The function is called by Extension::paramString() to build
+ the commandline string like: '--param1name=\"param1value\" --param2name=\"param2value\" ...'
+ Extension::paramString expects this function to return '\"param1value\"'; but instead,
+ this function returns: '\"param1value\" --page1param1name=\"page1param1value\" ...'
+
+ \TODO Do this better. For example, make Parameter::paramString() that returns '--name=\"value\"'
+ instead of just returning '\"value\"'.
+*/
+Glib::ustring *
+ParamNotebook::string (void)
+{
+ Glib::ustring * param_string = new Glib::ustring("");
+
+ *param_string += "\"";
+ *param_string += _value; // the name of the current page
+ *param_string += "\"";
+
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
+
+ Glib::ustring * pageparamstr = page->paramString();
+ *param_string += *pageparamstr;
+ delete pageparamstr;
+ }
+
+ return param_string;
+}
+
+/** \brief A special category of Gtk::Notebook to handle notebook parameters */
+class ParamNotebookWdg : public Gtk::Notebook {
+private:
+ ParamNotebook * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+public:
+ /** \brief Build a notebookpage preference for the given parameter
+ \param pref Where to get the string (pagename) from, and where to put it
+ when it changes.
+ */
+ ParamNotebookWdg (ParamNotebook * pref, SPDocument * doc, Inkscape::XML::Node * node) :
+ Gtk::Notebook(), _pref(pref), _doc(doc), _node(node), activated(false) {
+ // don't have to set the correct page: this is done in ParamNotebook::get_widget.
+ // hook function
+ this->signal_switch_page().connect(sigc::mem_fun(this, &ParamNotebookWdg::changed_page));
+ return;
+ };
+ void changed_page(GtkNotebookPage *page, guint pagenum);
+ bool activated;
+};
+
+/** \brief Respond to the selected page of notebook changing
+ This function responds to the changing by reporting it to
+ ParamNotebook. The change is only reported when the notebook
+ is actually visible. This to exclude 'fake' changes when the
+ notebookpages are added or removed.
+*/
+void
+ParamNotebookWdg::changed_page(GtkNotebookPage *page,
+ guint pagenum)
+{
+ if (is_visible()) {
+ _pref->set((int)pagenum, _doc, _node);
+ }
+ return;
+}
+
+
+
+/**
+ \brief Creates a Notebook widget for a notebook parameter
+
+ Builds a notebook and puts pages in it.
+*/
+Gtk::Widget *
+ParamNotebook::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node));
+
+ // add pages (if any)
+ int i = -1;
+ int pagenr = i;
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {
+ i++;
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ Gtk::Widget * widg = page->get_widget(doc, node);
+ nb->append_page(*widg, _(page->get_guitext()));
+ if (!strcmp(_value, page->name())) {
+ pagenr = i; // this is the page to be displayed?
+ }
+ }
+
+ nb->show();
+
+ if (pagenr >= 0) nb->set_current_page(pagenr);
+
+ return dynamic_cast<Gtk::Widget *>(nb);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index a7811576e69f6553b18761737be37961b36c412d..f0ab15f5744ca9f9e6c4cff15f0485c5bdf7321d 100644 (file)
-#ifndef __INK_EXTENSION_PARAMNOTEBOOK_H__\r
-#define __INK_EXTENSION_PARAMNOTEBOOK_H__\r
-\r
-/** \file\r
- * Notebook parameter for extensions.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006 Author\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <gtkmm/widget.h>\r
-\r
-#include "xml/document.h"\r
-#include "extension-forward.h"\r
-\r
-#include "parameter.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-\r
-\r
-// \brief A class to represent a notebookparameter of an extension\r
-class ParamNotebook : public Parameter {\r
-private:\r
- /** \brief Internal value. This should point to a string that has\r
- been allocated in memory. And should be free'd. \r
- It is the name of the current page. */\r
- gchar * _value;\r
- \r
- GSList * pages; /**< A table to store the pages with parameters for this notebook.\r
- This only gets created if there are pages in this\r
- notebook */\r
-public:\r
- ParamNotebook(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
- ~ParamNotebook(void);\r
- Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
- Glib::ustring * string (void);\r
- \r
- const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }\r
- const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node);\r
-}; /* class ParamNotebook */\r
-\r
-\r
-\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-#endif /* __INK_EXTENSION_PARAMNOTEBOOK_H__ */\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#ifndef __INK_EXTENSION_PARAMNOTEBOOK_H__
+#define __INK_EXTENSION_PARAMNOTEBOOK_H__
+
+/** \file
+ * Notebook parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include "extension-forward.h"
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a notebookparameter of an extension
+class ParamNotebook : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the name of the current page. */
+ gchar * _value;
+
+ GSList * pages; /**< A table to store the pages with parameters for this notebook.
+ This only gets created if there are pages in this
+ notebook */
+public:
+ ParamNotebook(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ ~ParamNotebook(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
+ Glib::ustring * string (void);
+
+ const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+ const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node);
+}; /* class ParamNotebook */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMNOTEBOOK_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 794abed94ac6e30157a4eb9f8d7696551e489fd2..3ca051f14733dd30974b8222f407385b3d4be5a7 100644 (file)
-/** \file\r
- * extension parameter for radiobuttons.\r
- *\r
- * It uses a Gtk:ComboBoxText widget in the extension UI.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006-2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-\r
-#include <gtkmm/box.h>\r
-#include <gtkmm/radiobutton.h>\r
-#include <gtkmm/radiobuttongroup.h>\r
-#include <gtkmm/tooltips.h>\r
-#include <gtkmm/label.h>\r
-\r
-#include <glibmm/i18n.h>\r
-\r
-#include <xml/node.h>\r
-\r
-#include "extension.h"\r
-#include "prefs-utils.h"\r
-#include "document-private.h"\r
-#include "sp-object.h"\r
-\r
-#include "paramradiobutton.h"\r
-\r
-/** \brief The root directory in the preferences database for extension\r
- related parameters. */\r
-#define PREF_DIR "extensions"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-/* For internal use only.\r
- Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */\r
-class optionentry {\r
-public:\r
- optionentry (Glib::ustring * val, Glib::ustring * text) {\r
- value = val;\r
- guitext = text;\r
- }\r
- ~optionentry() {\r
- delete value;\r
- delete guitext;\r
- }\r
-\r
- Glib::ustring * value;\r
- Glib::ustring * guitext;\r
-};\r
-\r
-ParamRadioButton::ParamRadioButton (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
- Parameter(name, guitext, desc, scope, ext)\r
-{\r
- choices = NULL;\r
- _value = NULL;\r
-\r
- // Read XML tree to add enumeration items:\r
- // printf("Extension Constructor: ");\r
- if (xml != NULL) {\r
- Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
- while (child_repr != NULL) {\r
- char const * chname = child_repr->name();\r
- if (!strcmp(chname, "option")) {\r
- Glib::ustring * newguitext = NULL;\r
- Glib::ustring * newvalue = NULL;\r
- const char * contents = sp_repr_children(child_repr)->content();\r
- if (contents != NULL)\r
- newguitext = new Glib::ustring(contents);\r
- const char * val = child_repr->attribute("value");\r
- if (val != NULL)\r
- newvalue = new Glib::ustring(val);\r
- if ( (newguitext) && (newvalue) ) {\r
- choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );\r
- }\r
- }\r
- child_repr = sp_repr_next(child_repr);\r
- }\r
- }\r
-\r
- // Initialize _value with the default value from xml\r
- // for simplicity : default to the contents of the first xml-child\r
- const char * defaultval = NULL;\r
- if (sp_repr_children(sp_repr_children(xml)) != NULL)\r
- defaultval = sp_repr_children(xml)->attribute("value");\r
-\r
- gchar * pref_name = this->pref_name();\r
- const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);\r
- g_free(pref_name);\r
-\r
- if (paramval != NULL)\r
- defaultval = paramval;\r
- if (defaultval != NULL)\r
- _value = g_strdup(defaultval); // allocate space for _value\r
-\r
- return;\r
-}\r
-\r
-ParamRadioButton::~ParamRadioButton (void)\r
-{\r
- //destroy choice strings\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- delete (reinterpret_cast<optionentry *>(list->data));\r
- }\r
- g_slist_free(choices);\r
-\r
- g_free(_value);\r
-}\r
-\r
-\r
-/** \brief A function to set the \c _value\r
- \param in The value to set\r
- \param doc A document that should be used to set the value.\r
- \param node The node where the value may be placed\r
-\r
- This function sets ONLY the internal value, but it also sets the value\r
- in the preferences structure. To put it in the right place, \c PREF_DIR\r
- and \c pref_name() are used.\r
-\r
- To copy the data into _value the old memory must be free'd first.\r
- It is important to note that \c g_free handles \c NULL just fine. Then\r
- the passed in value is duplicated using \c g_strdup().\r
-*/\r
-const gchar *\r
-ParamRadioButton::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- if (in == NULL) return NULL; /* Can't have NULL string */\r
-\r
- Glib::ustring * settext = NULL;\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- optionentry * entr = reinterpret_cast<optionentry *>(list->data);\r
- if ( !entr->guitext->compare(in) ) {\r
- settext = entr->value;\r
- break; // break out of for loop\r
- }\r
- }\r
- if (settext) {\r
- if (_value != NULL) g_free(_value);\r
- _value = g_strdup(settext->c_str());\r
- gchar * prefname = this->pref_name();\r
- prefs_set_string_attribute(PREF_DIR, prefname, _value);\r
- g_free(prefname);\r
- }\r
-\r
- return _value;\r
-}\r
-\r
-\r
-/**\r
- \brief A function to get the current value of the parameter in a string form\r
- \return A string with the 'value' as command line argument\r
-*/\r
-Glib::ustring *\r
-ParamRadioButton::string (void)\r
-{\r
- Glib::ustring * param_string = new Glib::ustring("");\r
-\r
- *param_string += "\"";\r
- *param_string += _value;\r
- *param_string += "\"";\r
-\r
- return param_string;\r
-}\r
-\r
-/** \brief A special radiobutton class to use in ParamRadioButton */\r
-class ParamRadioButtonWdg : public Gtk::RadioButton {\r
-private:\r
- ParamRadioButton * _pref;\r
- SPDocument * _doc;\r
- Inkscape::XML::Node * _node;\r
-public:\r
- /** \brief Build a string preference for the given parameter\r
- \param pref Where to put the radiobutton's string when it is selected.\r
- */\r
- ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,\r
- ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :\r
- Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node) {\r
- add_changesignal();\r
- };\r
- ParamRadioButtonWdg ( const Glib::ustring& label,\r
- ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :\r
- Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node) {\r
- add_changesignal();\r
- };\r
- void add_changesignal() {\r
- this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));\r
- };\r
- void changed (void);\r
-};\r
-\r
-/** \brief Respond to the selected radiobutton changing\r
-\r
- This function responds to the radiobutton selection changing by grabbing the value\r
- from the text box and putting it in the parameter.\r
-*/\r
-void\r
-ParamRadioButtonWdg::changed (void)\r
-{\r
- if (this->get_active()) {\r
- Glib::ustring data = this->get_label();\r
- _pref->set(data.c_str(), _doc, _node);\r
- }\r
-}\r
-\r
-\r
-\r
-/**\r
- \brief Creates a combobox widget for an enumeration parameter\r
-*/\r
-Gtk::Widget *\r
-ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
-{\r
- Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));\r
- Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));\r
-\r
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));\r
- label->show();\r
- hbox->pack_start(*label, false, false);\r
-\r
- // add choice strings as radiobuttons\r
- // and select last selected option (_value)\r
- bool first = true;\r
- ParamRadioButtonWdg * radio;\r
- Gtk::RadioButtonGroup group;\r
- for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {\r
- optionentry * entr = reinterpret_cast<optionentry *>(list->data);\r
- Glib::ustring * text = entr->guitext;\r
- if (first) {\r
- radio = Gtk::manage(new ParamRadioButtonWdg(*text, this, doc, node));\r
- group = radio->get_group();\r
- first = false;\r
- } else {\r
- radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node));\r
- }\r
- radio->show();\r
- vbox->pack_start(*radio, true, true);\r
- if (!entr->value->compare(_value)) {\r
- radio->set_active();\r
- }\r
- }\r
-\r
- vbox->show();\r
- hbox->pack_end(*vbox, false, false);\r
- hbox->show();\r
-\r
-\r
- return dynamic_cast<Gtk::Widget *>(hbox);\r
-}\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
+/** \file
+ * extension parameter for radiobuttons.
+ *
+ * It uses a Gtk:ComboBoxText widget in the extension UI.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/box.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/radiobuttongroup.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include "extension.h"
+#include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
+
+#include "paramradiobutton.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+/* For internal use only.
+ Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+class optionentry {
+public:
+ optionentry (Glib::ustring * val, Glib::ustring * text) {
+ value = val;
+ guitext = text;
+ }
+ ~optionentry() {
+ delete value;
+ delete guitext;
+ }
+
+ Glib::ustring * value;
+ Glib::ustring * guitext;
+};
+
+ParamRadioButton::ParamRadioButton (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, ext)
+{
+ choices = NULL;
+ _value = NULL;
+
+ // Read XML tree to add enumeration items:
+ // printf("Extension Constructor: ");
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (!strcmp(chname, "option")) {
+ Glib::ustring * newguitext = NULL;
+ Glib::ustring * newvalue = NULL;
+ const char * contents = sp_repr_children(child_repr)->content();
+ if (contents != NULL)
+ newguitext = new Glib::ustring(contents);
+ const char * val = child_repr->attribute("value");
+ if (val != NULL)
+ newvalue = new Glib::ustring(val);
+ if ( (newguitext) && (newvalue) ) {
+ choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
+ }
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the default value from xml
+ // for simplicity : default to the contents of the first xml-child
+ const char * defaultval = NULL;
+ if (sp_repr_children(sp_repr_children(xml)) != NULL)
+ defaultval = sp_repr_children(xml)->attribute("value");
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamRadioButton::~ParamRadioButton (void)
+{
+ //destroy choice strings
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ delete (reinterpret_cast<optionentry *>(list->data));
+ }
+ g_slist_free(choices);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The value to set
+ \param doc A document that should be used to set the value.
+ \param node The node where the value may be placed
+
+ This function sets ONLY the internal value, but it also sets the value
+ in the preferences structure. To put it in the right place, \c PREF_DIR
+ and \c pref_name() are used.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamRadioButton::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ if (in == NULL) return NULL; /* Can't have NULL string */
+
+ Glib::ustring * settext = NULL;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ optionentry * entr = reinterpret_cast<optionentry *>(list->data);
+ if ( !entr->guitext->compare(in) ) {
+ settext = entr->value;
+ break; // break out of for loop
+ }
+ }
+ if (settext) {
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(settext->c_str());
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+ }
+
+ return _value;
+}
+
+
+/**
+ \brief A function to get the current value of the parameter in a string form
+ \return A string with the 'value' as command line argument
+*/
+Glib::ustring *
+ParamRadioButton::string (void)
+{
+ Glib::ustring * param_string = new Glib::ustring("");
+
+ *param_string += "\"";
+ *param_string += _value;
+ *param_string += "\"";
+
+ return param_string;
+}
+
+/** \brief A special radiobutton class to use in ParamRadioButton */
+class ParamRadioButtonWdg : public Gtk::RadioButton {
+private:
+ ParamRadioButton * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+public:
+ /** \brief Build a string preference for the given parameter
+ \param pref Where to put the radiobutton's string when it is selected.
+ */
+ ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,
+ ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :
+ Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node) {
+ add_changesignal();
+ };
+ ParamRadioButtonWdg ( const Glib::ustring& label,
+ ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :
+ Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node) {
+ add_changesignal();
+ };
+ void add_changesignal() {
+ this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));
+ };
+ void changed (void);
+};
+
+/** \brief Respond to the selected radiobutton changing
+
+ This function responds to the radiobutton selection changing by grabbing the value
+ from the text box and putting it in the parameter.
+*/
+void
+ParamRadioButtonWdg::changed (void)
+{
+ if (this->get_active()) {
+ Glib::ustring data = this->get_label();
+ _pref->set(data.c_str(), _doc, _node);
+ }
+}
+
+
+
+/**
+ \brief Creates a combobox widget for an enumeration parameter
+*/
+Gtk::Widget *
+ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+ Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
+ label->show();
+ hbox->pack_start(*label, false, false);
+
+ // add choice strings as radiobuttons
+ // and select last selected option (_value)
+ bool first = true;
+ ParamRadioButtonWdg * radio;
+ Gtk::RadioButtonGroup group;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ optionentry * entr = reinterpret_cast<optionentry *>(list->data);
+ Glib::ustring * text = entr->guitext;
+ if (first) {
+ radio = Gtk::manage(new ParamRadioButtonWdg(*text, this, doc, node));
+ group = radio->get_group();
+ first = false;
+ } else {
+ radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node));
+ }
+ radio->show();
+ vbox->pack_start(*radio, true, true);
+ if (!entr->value->compare(_value)) {
+ radio->set_active();
+ }
+ }
+
+ vbox->show();
+ hbox->pack_end(*vbox, false, false);
+ hbox->show();
+
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
index 04c4e58468baf04833a528efd11ff6350f260743..8e1edf5b8f5f91d187d16b9f25c596cccbd9b5b5 100644 (file)
-#ifndef __INK_EXTENSION_PARAMRADIOBUTTON_H__\r
-#define __INK_EXTENSION_PARAMRADIOBUTTON_H__\r
-\r
-/** \file\r
- * Radiobutton parameter for extensions.\r
- */\r
-\r
-/*\r
- * Author:\r
- * Johan Engelen <johan@shouraizou.nl>\r
- *\r
- * Copyright (C) 2006-2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <gtkmm/widget.h>\r
-\r
-#include "xml/document.h"\r
-#include "extension-forward.h"\r
-\r
-#include "parameter.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-\r
-\r
-\r
-// \brief A class to represent a radiobutton parameter of an extension\r
-class ParamRadioButton : public Parameter {\r
-private:\r
- /** \brief Internal value. This should point to a string that has\r
- been allocated in memory. And should be free'd. \r
- It is the value of the current selected string */\r
- gchar * _value;\r
- \r
- GSList * choices; /**< A table to store the choice strings */\r
- \r
-public:\r
- ParamRadioButton(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
- ~ParamRadioButton(void);\r
- Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
- Glib::ustring * string (void);\r
- \r
- const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }\r
- const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);\r
-}; /* class ParamRadioButton */\r
-\r
-\r
-\r
-\r
-\r
-} /* namespace Extension */\r
-} /* namespace Inkscape */\r
-\r
-#endif /* __INK_EXTENSION_PARAMRADIOBUTTON_H__ */\r
-\r
+#ifndef __INK_EXTENSION_PARAMRADIOBUTTON_H__
+#define __INK_EXTENSION_PARAMRADIOBUTTON_H__
+
+/** \file
+ * Radiobutton parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include "extension-forward.h"
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a radiobutton parameter of an extension
+class ParamRadioButton : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the value of the current selected string */
+ gchar * _value;
+
+ GSList * choices; /**< A table to store the choice strings */
+
+public:
+ ParamRadioButton(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ ~ParamRadioButton(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
+ Glib::ustring * string (void);
+
+ const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+ const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
+}; /* class ParamRadioButton */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMRADIOBUTTON_H__ */
+
index 1f33bc65930490cfc392ac6222a31ada9c51dd72..a019b9f7d90280f369193711dc85d1ff20491f64 100644 (file)
-/* XPM */\r
-static char * cursor_gradient_add_xpm[] = {\r
-"32 32 3 1",\r
-" c None",\r
-". c #FFFFFF",\r
-"+ c #000000",\r
-" ... ",\r
-" .+. ",\r
-" .+. ",\r
-"....+.... ",\r
-".+++ +++. ",\r
-"....+.... ",\r
-" .+. ",\r
-" .+. ..... ",\r
-" ... .+++. ",\r
-" .+.+. ",\r
-" .+++. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+++. ",\r
-" .+.+. ",\r
-" .+++. ",\r
-" ..... ",\r
-" ... ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" ......+...... ",\r
-" .+++++++++++. ",\r
-" ......+...... ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" ... "};\r
+/* XPM */
+static char * cursor_gradient_add_xpm[] = {
+"32 32 3 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+" ... ",
+" .+. ",
+" .+. ",
+"....+.... ",
+".+++ +++. ",
+"....+.... ",
+" .+. ",
+" .+. ..... ",
+" ... .+++. ",
+" .+.+. ",
+" .+++. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+++. ",
+" .+.+. ",
+" .+++. ",
+" ..... ",
+" ... ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" ......+...... ",
+" .+++++++++++. ",
+" ......+...... ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" ... "};
index 9832aa5255f8a18d9a77e196e9b79f1c3d9e70c4..da70c95259d8d88649a866904dd94cda70cf8218 100644 (file)
-/* XPM */\r
-static char * cursor_gradient_delete_xpm[] = {\r
-"32 32 3 1",\r
-" c None",\r
-". c #FFFFFF",\r
-"+ c #000000",\r
-" ... ",\r
-" .+. ",\r
-" .+. ",\r
-"....+.... ",\r
-".+++ +++. ",\r
-"....+.... ",\r
-" .+. ",\r
-" .+. ..... ",\r
-" ... .+++. ",\r
-" .+.+. ",\r
-" .+++. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+. ",\r
-" .+++. ",\r
-" .+.+. ",\r
-" .+++. ",\r
-" ..... ",\r
-" ",\r
-" ",\r
-" ",\r
-" ",\r
-" ",\r
-" ",\r
-" ............. ",\r
-" .+++++++++++. ",\r
-" ............. ",\r
-" ",\r
-" ",\r
-" ",\r
-" "};\r
+/* XPM */
+static char * cursor_gradient_delete_xpm[] = {
+"32 32 3 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+" ... ",
+" .+. ",
+" .+. ",
+"....+.... ",
+".+++ +++. ",
+"....+.... ",
+" .+. ",
+" .+. ..... ",
+" ... .+++. ",
+" .+.+. ",
+" .+++. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+++. ",
+" .+.+. ",
+" .+++. ",
+" ..... ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ............. ",
+" .+++++++++++. ",
+" ............. ",
+" ",
+" ",
+" ",
+" "};
index 8a098de12383c944898898025038345a25f72484..c0027e7c38346484a128f6001af12291ca911ee5 100644 (file)
-#define __SP_FILTER_PRIMITIVE_CPP__\r
-\r
-/** \file\r
- * Superclass for all the filter primitives\r
- *\r
- */\r
-/*\r
- * Authors:\r
- * Kees Cook <kees@outflux.net>\r
- *\r
- * Copyright (C) 2004 Kees Cook\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-#include "attributes.h"\r
-#include "sp-filter-primitive.h"\r
-#include "xml/repr.h"\r
-#include "sp-filter.h"\r
-\r
-/* FilterPrimitive base class */\r
-\r
-static void sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass);\r
-static void sp_filter_primitive_init(SPFilterPrimitive *filter_primitive);\r
-\r
-static void sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);\r
-static void sp_filter_primitive_release(SPObject *object);\r
-static void sp_filter_primitive_set(SPObject *object, unsigned int key, gchar const *value);\r
-static void sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags);\r
-static Inkscape::XML::Node *sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);\r
-\r
-static SPObjectClass *filter_primitive_parent_class;\r
-\r
-GType\r
-sp_filter_primitive_get_type()\r
-{\r
- static GType filter_primitive_type = 0;\r
-\r
- if (!filter_primitive_type) {\r
- GTypeInfo filter_primitive_info = {\r
- sizeof(SPFilterPrimitiveClass),\r
- NULL, NULL,\r
- (GClassInitFunc) sp_filter_primitive_class_init,\r
- NULL, NULL,\r
- sizeof(SPFilterPrimitive),\r
- 16,\r
- (GInstanceInitFunc) sp_filter_primitive_init,\r
- NULL, /* value_table */\r
- };\r
- filter_primitive_type = g_type_register_static(SP_TYPE_OBJECT, "SPFilterPrimitive", &filter_primitive_info, (GTypeFlags)0);\r
- }\r
- return filter_primitive_type;\r
-}\r
-\r
-static void\r
-sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass)\r
-{\r
- //GObjectClass *gobject_class = (GObjectClass *)klass;\r
- SPObjectClass *sp_object_class = (SPObjectClass *)klass;\r
-\r
- filter_primitive_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);\r
-\r
- sp_object_class->build = sp_filter_primitive_build;\r
- sp_object_class->release = sp_filter_primitive_release;\r
- sp_object_class->write = sp_filter_primitive_write;\r
- sp_object_class->set = sp_filter_primitive_set;\r
- sp_object_class->update = sp_filter_primitive_update;\r
-}\r
-\r
-static void\r
-sp_filter_primitive_init(SPFilterPrimitive *filter_primitive)\r
-{\r
-}\r
-\r
-/**\r
- * Reads the Inkscape::XML::Node, and initializes SPFilterPrimitive variables. For this to get called,\r
- * our name must be associated with a repr via "sp_object_type_register". Best done through\r
- * sp-object-repr.cpp's repr_name_entries array.\r
- */\r
-static void\r
-sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)\r
-{\r
- if (((SPObjectClass *) filter_primitive_parent_class)->build) {\r
- ((SPObjectClass *) filter_primitive_parent_class)->build(object, document, repr);\r
- }\r
-\r
- if (object->parent)\r
- add_primitive((SPFilter*)object->parent, (SPFilterPrimitive*)object);\r
-}\r
-\r
-/**\r
- * Drops any allocated memory.\r
- */\r
-static void\r
-sp_filter_primitive_release(SPObject *object)\r
-{\r
- /* deal with our children and our selves here */\r
- if (((SPObjectClass *) filter_primitive_parent_class)->release)\r
- ((SPObjectClass *) filter_primitive_parent_class)->release(object);\r
-}\r
-\r
-/**\r
- * Sets a specific value in the SPFilterPrimitive.\r
- */\r
-static void\r
-sp_filter_primitive_set(SPObject *object, unsigned int key, gchar const *value)\r
-{\r
- SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object);\r
- (void)filter_primitive;\r
-\r
- /* See if any parents need this value. */\r
- if (((SPObjectClass *) filter_primitive_parent_class)->set) {\r
- ((SPObjectClass *) filter_primitive_parent_class)->set(object, key, value);\r
- }\r
-}\r
-\r
-/**\r
- * Receives update notifications.\r
- */\r
-static void\r
-sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags)\r
-{\r
- //SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object);\r
-\r
- if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |\r
- SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {\r
-\r
- /* do something to trigger redisplay, updates? */\r
- }\r
-\r
- if (((SPObjectClass *) filter_primitive_parent_class)->update) {\r
- ((SPObjectClass *) filter_primitive_parent_class)->update(object, ctx, flags);\r
- }\r
-}\r
-\r
-/**\r
- * Writes its settings to an incoming repr object, if any.\r
- */\r
-static Inkscape::XML::Node *\r
-sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)\r
-{\r
- //SPFilterPrimitive *filterPrimitive = SP_FILTER_PRIMITIVE(object);\r
-\r
- // Inkscape-only object, not copied during an "plain SVG" dump:\r
- if (flags & SP_OBJECT_WRITE_EXT) {\r
- if (repr) {\r
- // is this sane?\r
- //repr->mergeFrom(SP_OBJECT_REPR(object), "id");\r
- } else {\r
- repr = SP_OBJECT_REPR(object)->duplicate();\r
- }\r
- }\r
-\r
- if (((SPObjectClass *) filter_primitive_parent_class)->write) {\r
- ((SPObjectClass *) filter_primitive_parent_class)->write(object, repr, flags);\r
- }\r
-\r
- return repr;\r
-}\r
-\r
-\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+#define __SP_FILTER_PRIMITIVE_CPP__
+
+/** \file
+ * Superclass for all the filter primitives
+ *
+ */
+/*
+ * Authors:
+ * Kees Cook <kees@outflux.net>
+ *
+ * Copyright (C) 2004 Kees Cook
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "attributes.h"
+#include "sp-filter-primitive.h"
+#include "xml/repr.h"
+#include "sp-filter.h"
+
+/* FilterPrimitive base class */
+
+static void sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass);
+static void sp_filter_primitive_init(SPFilterPrimitive *filter_primitive);
+
+static void sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_filter_primitive_release(SPObject *object);
+static void sp_filter_primitive_set(SPObject *object, unsigned int key, gchar const *value);
+static void sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags);
+static Inkscape::XML::Node *sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static SPObjectClass *filter_primitive_parent_class;
+
+GType
+sp_filter_primitive_get_type()
+{
+ static GType filter_primitive_type = 0;
+
+ if (!filter_primitive_type) {
+ GTypeInfo filter_primitive_info = {
+ sizeof(SPFilterPrimitiveClass),
+ NULL, NULL,
+ (GClassInitFunc) sp_filter_primitive_class_init,
+ NULL, NULL,
+ sizeof(SPFilterPrimitive),
+ 16,
+ (GInstanceInitFunc) sp_filter_primitive_init,
+ NULL, /* value_table */
+ };
+ filter_primitive_type = g_type_register_static(SP_TYPE_OBJECT, "SPFilterPrimitive", &filter_primitive_info, (GTypeFlags)0);
+ }
+ return filter_primitive_type;
+}
+
+static void
+sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass)
+{
+ //GObjectClass *gobject_class = (GObjectClass *)klass;
+ SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+
+ filter_primitive_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
+
+ sp_object_class->build = sp_filter_primitive_build;
+ sp_object_class->release = sp_filter_primitive_release;
+ sp_object_class->write = sp_filter_primitive_write;
+ sp_object_class->set = sp_filter_primitive_set;
+ sp_object_class->update = sp_filter_primitive_update;
+}
+
+static void
+sp_filter_primitive_init(SPFilterPrimitive *filter_primitive)
+{
+}
+
+/**
+ * Reads the Inkscape::XML::Node, and initializes SPFilterPrimitive variables. For this to get called,
+ * our name must be associated with a repr via "sp_object_type_register". Best done through
+ * sp-object-repr.cpp's repr_name_entries array.
+ */
+static void
+sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+ if (((SPObjectClass *) filter_primitive_parent_class)->build) {
+ ((SPObjectClass *) filter_primitive_parent_class)->build(object, document, repr);
+ }
+
+ if (object->parent)
+ add_primitive((SPFilter*)object->parent, (SPFilterPrimitive*)object);
+}
+
+/**
+ * Drops any allocated memory.
+ */
+static void
+sp_filter_primitive_release(SPObject *object)
+{
+ /* deal with our children and our selves here */
+ if (((SPObjectClass *) filter_primitive_parent_class)->release)
+ ((SPObjectClass *) filter_primitive_parent_class)->release(object);
+}
+
+/**
+ * Sets a specific value in the SPFilterPrimitive.
+ */
+static void
+sp_filter_primitive_set(SPObject *object, unsigned int key, gchar const *value)
+{
+ SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object);
+ (void)filter_primitive;
+
+ /* See if any parents need this value. */
+ if (((SPObjectClass *) filter_primitive_parent_class)->set) {
+ ((SPObjectClass *) filter_primitive_parent_class)->set(object, key, value);
+ }
+}
+
+/**
+ * Receives update notifications.
+ */
+static void
+sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags)
+{
+ //SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object);
+
+ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
+ SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
+
+ /* do something to trigger redisplay, updates? */
+ }
+
+ if (((SPObjectClass *) filter_primitive_parent_class)->update) {
+ ((SPObjectClass *) filter_primitive_parent_class)->update(object, ctx, flags);
+ }
+}
+
+/**
+ * Writes its settings to an incoming repr object, if any.
+ */
+static Inkscape::XML::Node *
+sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ //SPFilterPrimitive *filterPrimitive = SP_FILTER_PRIMITIVE(object);
+
+ // Inkscape-only object, not copied during an "plain SVG" dump:
+ if (flags & SP_OBJECT_WRITE_EXT) {
+ if (repr) {
+ // is this sane?
+ //repr->mergeFrom(SP_OBJECT_REPR(object), "id");
+ } else {
+ repr = SP_OBJECT_REPR(object)->duplicate();
+ }
+ }
+
+ if (((SPObjectClass *) filter_primitive_parent_class)->write) {
+ ((SPObjectClass *) filter_primitive_parent_class)->write(object, repr, flags);
+ }
+
+ return repr;
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 9fa628aa5c484c63103433a2d791ff001a8223a7..3a41f52de08fdfd25463b9f728b529c3e78caea3 100644 (file)
-#ifndef __SP_FILTER_PRIMITIVE_H__\r
-#define __SP_FILTER_PRIMITIVE_H__\r
-\r
-\r
-#include "sp-object.h"\r
-\r
-\r
-#define SP_TYPE_FILTER_PRIMITIVE (sp_filter_primitive_get_type ())\r
-#define SP_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitive))\r
-#define SP_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitiveClass))\r
-#define SP_IS_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FILTER_PRIMITIVE))\r
-#define SP_IS_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FILTER_PRIMITIVE))\r
-\r
-class SPFilterPrimitive;\r
-class SPFilterPrimitiveClass;\r
-\r
-struct SPFilterPrimitive : public SPObject {\r
-};\r
-\r
-struct SPFilterPrimitiveClass {\r
- SPObjectClass sp_object_class;\r
-};\r
-\r
-GType sp_filter_primitive_get_type (void);\r
-\r
-#endif\r
+#ifndef __SP_FILTER_PRIMITIVE_H__
+#define __SP_FILTER_PRIMITIVE_H__
+
+
+#include "sp-object.h"
+
+
+#define SP_TYPE_FILTER_PRIMITIVE (sp_filter_primitive_get_type ())
+#define SP_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitive))
+#define SP_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitiveClass))
+#define SP_IS_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FILTER_PRIMITIVE))
+#define SP_IS_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FILTER_PRIMITIVE))
+
+class SPFilterPrimitive;
+class SPFilterPrimitiveClass;
+
+struct SPFilterPrimitive : public SPObject {
+};
+
+struct SPFilterPrimitiveClass {
+ SPObjectClass sp_object_class;
+};
+
+GType sp_filter_primitive_get_type (void);
+
+#endif
diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp
index c60ffb44f7c60cf30822804cfe52f294c45f841b..729e13d4aec5a453d16d64ed230744eea8c5d03b 100644 (file)
--- a/src/sp-filter.cpp
+++ b/src/sp-filter.cpp
static void sp_filter_release(SPObject *object);
static void sp_filter_set(SPObject *object, unsigned int key, gchar const *value);
static void sp_filter_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_filter_child_added(SPObject *object,\r
- Inkscape::XML::Node *child,\r
- Inkscape::XML::Node *ref);\r
+static void sp_filter_child_added(SPObject *object,
+ Inkscape::XML::Node *child,
+ Inkscape::XML::Node *ref);
static void sp_filter_remove_child(SPObject *object, Inkscape::XML::Node *child);
static Inkscape::XML::Node *sp_filter_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
sp_object_class->write = sp_filter_write;
sp_object_class->set = sp_filter_set;
sp_object_class->update = sp_filter_update;
- sp_object_class->child_added = sp_filter_child_added;\r
+ sp_object_class->child_added = sp_filter_child_added;
sp_object_class->remove_child = sp_filter_remove_child;
}
index 6159b4fe52f4238d14e1dee45eab6de6c65f4f0a..7b19ac861e3227c90e68df92793e591345867f0b 100644 (file)
--- a/src/ui/widget/entry.cpp
+++ b/src/ui/widget/entry.cpp
-/** \file\r
- *\r
- * \brief Helperclass for Gtk::Entry widgets\r
- *\r
- * Authors:\r
- * Johan Engelen <goejendaagh@zonnet.nl>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL. Read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include <config.h>\r
-#endif\r
-\r
-#include "entry.h"\r
-\r
-namespace Inkscape {\r
-namespace UI {\r
-namespace Widget {\r
-\r
-Entry::Entry( Glib::ustring const &label, Glib::ustring const &tooltip,\r
- Glib::ustring const &suffix,\r
- Glib::ustring const &icon,\r
- bool mnemonic)\r
- : Labelled(label, tooltip, new Gtk::Entry(), suffix, icon, mnemonic)\r
-{\r
-}\r
- \r
-\r
-} // namespace Widget\r
-} // namespace UI\r
-} // namespace Inkscape\r
-\r
+/** \file
+ *
+ * \brief Helperclass for Gtk::Entry widgets
+ *
+ * Authors:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "entry.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+Entry::Entry( Glib::ustring const &label, Glib::ustring const &tooltip,
+ Glib::ustring const &suffix,
+ Glib::ustring const &icon,
+ bool mnemonic)
+ : Labelled(label, tooltip, new Gtk::Entry(), suffix, icon, mnemonic)
+{
+}
+
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h
index 06cb19bef19d6593321f3f5b0e0dfada6b6f5a8f..bb6c1321a63b60c63ffa89a77af06c73f4eb1661 100644 (file)
--- a/src/ui/widget/entry.h
+++ b/src/ui/widget/entry.h
-/** \file \r
- *\r
- * \brief Helperclass for Gtk::Entry widgets\r
- *\r
- * Authors:\r
- * Johan Engelen <goejendaagh@zonnet.nl>\r
- *\r
- * Copyright (C) 2006 Authors\r
- *\r
- * Released under GNU GPL. Read the file 'COPYING' for more information.\r
- */\r
-\r
-#ifndef INKSCAPE_UI_WIDGET_ENTRY__H\r
-#define INKSCAPE_UI_WIDGET_ENTRY__H\r
-\r
-#include <gtkmm/entry.h>\r
-#include <gtkmm/tooltips.h>\r
-#include <gtkmm/label.h>\r
-#include <gtkmm/box.h>\r
-#include "labelled.h"\r
-\r
-namespace Inkscape {\r
-namespace UI {\r
-namespace Widget {\r
-\r
-class Entry : public Labelled\r
-{\r
-public:\r
- Entry( Glib::ustring const &label,\r
- Glib::ustring const &tooltip,\r
- Glib::ustring const &suffix = "",\r
- Glib::ustring const &icon = "",\r
- bool mnemonic = true);\r
-\r
- // TO DO: add methods to access Gtk::Entry widget\r
- \r
- Gtk::Entry* getEntry() {return (Gtk::Entry*)(_widget);}; \r
-};\r
-\r
-} // namespace Widget\r
-} // namespace UI\r
-} // namespace Inkscape\r
-\r
-#endif // INKSCAPE_UI_WIDGET_ENTRY__H\r
+/** \file
+ *
+ * \brief Helperclass for Gtk::Entry widgets
+ *
+ * Authors:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2006 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_ENTRY__H
+#define INKSCAPE_UI_WIDGET_ENTRY__H
+
+#include <gtkmm/entry.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+#include <gtkmm/box.h>
+#include "labelled.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class Entry : public Labelled
+{
+public:
+ Entry( Glib::ustring const &label,
+ Glib::ustring const &tooltip,
+ Glib::ustring const &suffix = "",
+ Glib::ustring const &icon = "",
+ bool mnemonic = true);
+
+ // TO DO: add methods to access Gtk::Entry widget
+
+ Gtk::Entry* getEntry() {return (Gtk::Entry*)(_widget);};
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_ENTRY__H
diff --git a/src/util/fixed_point.h b/src/util/fixed_point.h
index bea891742e7253c2cfc7b43c2dde5e5abeac86a2..6afec5e3cb1effebc61ab291a0f4a5b27382ca77 100644 (file)
--- a/src/util/fixed_point.h
+++ b/src/util/fixed_point.h
-/*\r
- * Inkscape::Util::FixedPoint - fixed point type\r
- *\r
- * Authors:\r
- * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
- *\r
- * Copyright (C) 2006 Jasper van de Gronde\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-\r
-#include "traits/reference.h"\r
-#include <math.h>\r
-#include <algorithm>\r
-#include <limits>\r
-\r
-namespace Inkscape {\r
-\r
-namespace Util {\r
-\r
-template <typename T, unsigned int precision>\r
-class FixedPoint {\r
-public:\r
- FixedPoint() {}\r
- FixedPoint(const FixedPoint& value) : v(value.v) {}\r
- FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
-\r
- FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
- FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
- FixedPoint& operator*=(FixedPoint val) {\r
- const unsigned int half_size = 8*sizeof(T)/2;\r
- const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
- const T ah = v>>half_size, bh = val.v>>half_size;\r
- v = static_cast<unsigned int>(al*bl)>>precision;\r
- if ( half_size >= precision ) {\r
- v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
- } else {\r
- v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
- v += (ah*bh)<<(2*half_size-precision);\r
- }\r
- return *this;\r
- }\r
-\r
- FixedPoint& operator*=(char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(int val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
-\r
- FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
- FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
- FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- float operator*(float val) const { return static_cast<float>(*this)*val; }\r
- double operator*(double val) const { return static_cast<double>(*this)*val; }\r
-\r
- operator char() const { return v>>precision; }\r
- operator unsigned char() const { return v>>precision; }\r
- operator short() const { return v>>precision; }\r
- operator unsigned short() const { return v>>precision; }\r
- operator int() const { return v>>precision; }\r
- operator unsigned int() const { return v>>precision; }\r
-\r
- operator float() const { return ldexpf(v,-precision); }\r
- operator double() const { return ldexp(v,-precision); }\r
-private:\r
- T v;\r
-};\r
-\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
-\r
-template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
-template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
-\r
-}\r
-\r
-}\r
-\r
-#endif\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
-/*\r
- * Inkscape::Util::FixedPoint - fixed point type\r
- *\r
- * Authors:\r
- * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
- *\r
- * Copyright (C) 2006 Jasper van de Gronde\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-\r
-#include "traits/reference.h"\r
-#include <math.h>\r
-#include <algorithm>\r
-#include <limits>\r
-\r
-namespace Inkscape {\r
-\r
-namespace Util {\r
-\r
-template <typename T, unsigned int precision>\r
-class FixedPoint {\r
-public:\r
- FixedPoint() {}\r
- FixedPoint(const FixedPoint& value) : v(value.v) {}\r
- FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
-\r
- FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
- FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
- FixedPoint& operator*=(FixedPoint val) {\r
- const unsigned int half_size = 8*sizeof(T)/2;\r
- const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
- const T ah = v>>half_size, bh = val.v>>half_size;\r
- v = static_cast<unsigned int>(al*bl)>>precision;\r
- if ( half_size >= precision ) {\r
- v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
- } else {\r
- v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
- v += (ah*bh)<<(2*half_size-precision);\r
- }\r
- return *this;\r
- }\r
-\r
- FixedPoint& operator*=(char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(int val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
-\r
- FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
- FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
- FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- float operator*(float val) const { return static_cast<float>(*this)*val; }\r
- double operator*(double val) const { return static_cast<double>(*this)*val; }\r
-\r
- operator char() const { return v>>precision; }\r
- operator unsigned char() const { return v>>precision; }\r
- operator short() const { return v>>precision; }\r
- operator unsigned short() const { return v>>precision; }\r
- operator int() const { return v>>precision; }\r
- operator unsigned int() const { return v>>precision; }\r
-\r
- operator float() const { return ldexpf(v,-precision); }\r
- operator double() const { return ldexp(v,-precision); }\r
-private:\r
- T v;\r
-};\r
-\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
-\r
-template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
-template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
-\r
-}\r
-\r
-}\r
-\r
-#endif\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
-/*\r
- * Inkscape::Util::FixedPoint - fixed point type\r
- *\r
- * Authors:\r
- * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
- *\r
- * Copyright (C) 2006 Jasper van de Gronde\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
-\r
-#include "traits/reference.h"\r
-#include <math.h>\r
-#include <algorithm>\r
-#include <limits>\r
-\r
-namespace Inkscape {\r
-\r
-namespace Util {\r
-\r
-template <typename T, unsigned int precision>\r
-class FixedPoint {\r
-public:\r
- FixedPoint() {}\r
- FixedPoint(const FixedPoint& value) : v(value.v) {}\r
- FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
- FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
-\r
- FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
- FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
- FixedPoint& operator*=(FixedPoint val) {\r
- const unsigned int half_size = 8*sizeof(T)/2;\r
- const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
- const T ah = v>>half_size, bh = val.v>>half_size;\r
- v = static_cast<unsigned int>(al*bl)>>precision;\r
- if ( half_size >= precision ) {\r
- v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
- } else {\r
- v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
- v += (ah*bh)<<(2*half_size-precision);\r
- }\r
- return *this;\r
- }\r
-\r
- FixedPoint& operator*=(char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
- FixedPoint& operator*=(short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
- FixedPoint& operator*=(int val) { v *= val; return *this; }\r
- FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
-\r
- FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
- FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
- FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
- FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
-\r
- float operator*(float val) const { return static_cast<float>(*this)*val; }\r
- double operator*(double val) const { return static_cast<double>(*this)*val; }\r
-\r
- operator char() const { return v>>precision; }\r
- operator unsigned char() const { return v>>precision; }\r
- operator short() const { return v>>precision; }\r
- operator unsigned short() const { return v>>precision; }\r
- operator int() const { return v>>precision; }\r
- operator unsigned int() const { return v>>precision; }\r
-\r
- operator float() const { return ldexpf(v,-precision); }\r
- operator double() const { return ldexp(v,-precision); }\r
-private:\r
- T v;\r
-};\r
-\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
-template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
-\r
-template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
-template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
-\r
-}\r
-\r
-}\r
-\r
-#endif\r
-/*\r
- Local Variables:\r
- mode:c++\r
- c-file-style:"stroustrup"\r
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
- indent-tabs-mode:nil\r
- fill-column:99\r
- End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+/*
+ * Inkscape::Util::FixedPoint - fixed point type
+ *
+ * Authors:
+ * Jasper van de Gronde <th.v.d.gronde@hccnet.net>
+ *
+ * Copyright (C) 2006 Jasper van de Gronde
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+
+#include "traits/reference.h"
+#include <math.h>
+#include <algorithm>
+#include <limits>
+
+namespace Inkscape {
+
+namespace Util {
+
+template <typename T, unsigned int precision>
+class FixedPoint {
+public:
+ FixedPoint() {}
+ FixedPoint(const FixedPoint& value) : v(value.v) {}
+ FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}
+
+ FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }
+ FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }
+ FixedPoint& operator*=(FixedPoint val) {
+ const unsigned int half_size = 8*sizeof(T)/2;
+ const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);
+ const T ah = v>>half_size, bh = val.v>>half_size;
+ v = static_cast<unsigned int>(al*bl)>>precision;
+ if ( half_size >= precision ) {
+ v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);
+ } else {
+ v += ((al*bh)+(ah*bl))>>(precision-half_size);
+ v += (ah*bh)<<(2*half_size-precision);
+ }
+ return *this;
+ }
+
+ FixedPoint& operator*=(char val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }
+ FixedPoint& operator*=(short val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }
+ FixedPoint& operator*=(int val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }
+
+ FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }
+ FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }
+ FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }
+
+ FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }
+
+ float operator*(float val) const { return static_cast<float>(*this)*val; }
+ double operator*(double val) const { return static_cast<double>(*this)*val; }
+
+ operator char() const { return v>>precision; }
+ operator unsigned char() const { return v>>precision; }
+ operator short() const { return v>>precision; }
+ operator unsigned short() const { return v>>precision; }
+ operator int() const { return v>>precision; }
+ operator unsigned int() const { return v>>precision; }
+
+ operator float() const { return ldexpf(v,-precision); }
+ operator double() const { return ldexp(v,-precision); }
+private:
+ T v;
+};
+
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }
+
+template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }
+template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }
+
+}
+
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+/*
+ * Inkscape::Util::FixedPoint - fixed point type
+ *
+ * Authors:
+ * Jasper van de Gronde <th.v.d.gronde@hccnet.net>
+ *
+ * Copyright (C) 2006 Jasper van de Gronde
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+
+#include "traits/reference.h"
+#include <math.h>
+#include <algorithm>
+#include <limits>
+
+namespace Inkscape {
+
+namespace Util {
+
+template <typename T, unsigned int precision>
+class FixedPoint {
+public:
+ FixedPoint() {}
+ FixedPoint(const FixedPoint& value) : v(value.v) {}
+ FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}
+
+ FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }
+ FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }
+ FixedPoint& operator*=(FixedPoint val) {
+ const unsigned int half_size = 8*sizeof(T)/2;
+ const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);
+ const T ah = v>>half_size, bh = val.v>>half_size;
+ v = static_cast<unsigned int>(al*bl)>>precision;
+ if ( half_size >= precision ) {
+ v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);
+ } else {
+ v += ((al*bh)+(ah*bl))>>(precision-half_size);
+ v += (ah*bh)<<(2*half_size-precision);
+ }
+ return *this;
+ }
+
+ FixedPoint& operator*=(char val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }
+ FixedPoint& operator*=(short val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }
+ FixedPoint& operator*=(int val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }
+
+ FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }
+ FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }
+ FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }
+
+ FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }
+
+ float operator*(float val) const { return static_cast<float>(*this)*val; }
+ double operator*(double val) const { return static_cast<double>(*this)*val; }
+
+ operator char() const { return v>>precision; }
+ operator unsigned char() const { return v>>precision; }
+ operator short() const { return v>>precision; }
+ operator unsigned short() const { return v>>precision; }
+ operator int() const { return v>>precision; }
+ operator unsigned int() const { return v>>precision; }
+
+ operator float() const { return ldexpf(v,-precision); }
+ operator double() const { return ldexp(v,-precision); }
+private:
+ T v;
+};
+
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }
+
+template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }
+template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }
+
+}
+
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+/*
+ * Inkscape::Util::FixedPoint - fixed point type
+ *
+ * Authors:
+ * Jasper van de Gronde <th.v.d.gronde@hccnet.net>
+ *
+ * Copyright (C) 2006 Jasper van de Gronde
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+#define SEEN_INKSCAPE_UTIL_FIXED_POINT_H
+
+#include "traits/reference.h"
+#include <math.h>
+#include <algorithm>
+#include <limits>
+
+namespace Inkscape {
+
+namespace Util {
+
+template <typename T, unsigned int precision>
+class FixedPoint {
+public:
+ FixedPoint() {}
+ FixedPoint(const FixedPoint& value) : v(value.v) {}
+ FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}
+ FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}
+
+ FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }
+ FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }
+ FixedPoint& operator*=(FixedPoint val) {
+ const unsigned int half_size = 8*sizeof(T)/2;
+ const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);
+ const T ah = v>>half_size, bh = val.v>>half_size;
+ v = static_cast<unsigned int>(al*bl)>>precision;
+ if ( half_size >= precision ) {
+ v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);
+ } else {
+ v += ((al*bh)+(ah*bl))>>(precision-half_size);
+ v += (ah*bh)<<(2*half_size-precision);
+ }
+ return *this;
+ }
+
+ FixedPoint& operator*=(char val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }
+ FixedPoint& operator*=(short val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }
+ FixedPoint& operator*=(int val) { v *= val; return *this; }
+ FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }
+
+ FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }
+ FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }
+ FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }
+
+ FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }
+ FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }
+
+ float operator*(float val) const { return static_cast<float>(*this)*val; }
+ double operator*(double val) const { return static_cast<double>(*this)*val; }
+
+ operator char() const { return v>>precision; }
+ operator unsigned char() const { return v>>precision; }
+ operator short() const { return v>>precision; }
+ operator unsigned short() const { return v>>precision; }
+ operator int() const { return v>>precision; }
+ operator unsigned int() const { return v>>precision; }
+
+ operator float() const { return ldexpf(v,-precision); }
+ operator double() const { return ldexp(v,-precision); }
+private:
+ T v;
+};
+
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }
+template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }
+
+template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }
+template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }
+
+}
+
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :