diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2007-02-19 20:48:09 +0000 |
|---|---|---|
| committer | joncruz <joncruz@users.sourceforge.net> | 2007-02-19 20:48:09 +0000 |
| commit | 6e272e78c148590660e3443caefce378800260c3 (patch) | |
| tree | 6440f0b74ad32266110af6ae030f2823b12b898e /src | |
| parent | Fixed unintialized variables and minor misc warnings (diff) | |
| download | inkscape-6e272e78c148590660e3443caefce378800260c3.tar.gz inkscape-6e272e78c148590660e3443caefce378800260c3.zip | |
Cleaned up DOS line ends that had snuck in.
(bzr r2399)
Diffstat (limited to 'src')
35 files changed, 7618 insertions, 7618 deletions
diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 2f986f16f..9dfbed925 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -1,469 +1,469 @@ -#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 :
+#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 : diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index 22fceed44..79de72b43 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -1,59 +1,59 @@ -#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
-
-
+#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 + + diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index be0c9c5be..7ebeebd88 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -501,7 +501,7 @@ int FilterGaussian::render(FilterSlot &slot, Matrix const &trans) int const PC = NR_PIXBLOCK_BPP(in); // Subsampling constants - int const quality = prefs_get_int_attribute("options.blurquality", "value", 0);
+ 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; diff --git a/src/dom/util/digest.cpp b/src/dom/util/digest.cpp index 3c30ad58a..f31f0e4f9 100644 --- a/src/dom/util/digest.cpp +++ b/src/dom/util/digest.cpp @@ -1,1287 +1,1287 @@ -/**
- * 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
-//########################################################################
+/** + * 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 3667a25a9..46c60d2a3 100644 --- a/src/dom/util/digest.h +++ b/src/dom/util/digest.h @@ -1,493 +1,493 @@ -#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__ */
-
-
+#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__ */ + + diff --git a/src/extension/internal/cairo-pdf-out.cpp b/src/extension/internal/cairo-pdf-out.cpp index 9ee1ae32f..88010e686 100644 --- a/src/extension/internal/cairo-pdf-out.cpp +++ b/src/extension/internal/cairo-pdf-out.cpp @@ -1,150 +1,150 @@ -/*
- * 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 */
+/* + * 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 */ diff --git a/src/extension/internal/cairo-pdf-out.h b/src/extension/internal/cairo-pdf-out.h index f0e67f165..42cd9365c 100644 --- a/src/extension/internal/cairo-pdf-out.h +++ b/src/extension/internal/cairo-pdf-out.h @@ -1,50 +1,50 @@ -/*
- * 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 :
+/* + * 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 : diff --git a/src/extension/internal/cairo-png-out.cpp b/src/extension/internal/cairo-png-out.cpp index f34a90b22..6fd45d0d5 100644 --- a/src/extension/internal/cairo-png-out.cpp +++ b/src/extension/internal/cairo-png-out.cpp @@ -1,133 +1,133 @@ -/*
- * 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 */
+/* + * 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 */ diff --git a/src/extension/internal/cairo-png-out.h b/src/extension/internal/cairo-png-out.h index 207786c88..625c53ffc 100644 --- a/src/extension/internal/cairo-png-out.h +++ b/src/extension/internal/cairo-png-out.h @@ -1,50 +1,50 @@ -/*
- * 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 :
+/* + * 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 5d2765660..82b736ad2 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -1,133 +1,133 @@ -/*
- * 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 */
+/* + * 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 d7d5a6681..1c18519a0 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.h +++ b/src/extension/internal/cairo-renderer-pdf-out.h @@ -1,50 +1,50 @@ -/*
- * 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 :
+/* + * 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 a39d1fb1d..b9d65f50c 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -1,1430 +1,1430 @@ -/** \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 :
+/** \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 : diff --git a/src/extension/internal/emf-win32-inout.h b/src/extension/internal/emf-win32-inout.h index eff850049..3ec81b6b5 100644 --- a/src/extension/internal/emf-win32-inout.h +++ b/src/extension/internal/emf-win32-inout.h @@ -1,60 +1,60 @@ -/*
- * 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 :
+/* + * 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 b40eec462..9b1b77f16 100644 --- a/src/extension/internal/emf-win32-print.cpp +++ b/src/extension/internal/emf-win32-print.cpp @@ -1,629 +1,629 @@ -/** \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 :
+/** \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 : diff --git a/src/extension/internal/emf-win32-print.h b/src/extension/internal/emf-win32-print.h index d1ac81939..305507824 100644 --- a/src/extension/internal/emf-win32-print.h +++ b/src/extension/internal/emf-win32-print.h @@ -1,107 +1,107 @@ -#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 :
+#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 49562bfd6..af4a3d02f 100644 --- a/src/extension/internal/libwpg/WPGOLEStream.h +++ b/src/extension/internal/libwpg/WPGOLEStream.h @@ -1,28 +1,28 @@ /* POLE - Portable C++ library to access OLE Storage Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org> -
- 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
+ + 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. */ @@ -46,10 +46,10 @@ class Storage friend class Stream; public: -
+ // for Storage::result() - enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError };
-
+ enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError }; + /** * Constructs a storage with data. **/ @@ -84,19 +84,19 @@ class Stream friend class Storage; friend class StorageIO; -public:
-
- /**
- * Creates a new stream.
- */
- // name must be absolute, e.g "/PerfectOffice_MAIN"
- Stream( Storage* storage, const std::string& name );
-
- /**
- * Destroys the stream.
- */
+public: + + /** + * Creates a new stream. + */ + // name must be absolute, e.g "/PerfectOffice_MAIN" + Stream( Storage* storage, const std::string& name ); + + /** + * Destroys the stream. + */ ~Stream(); -
+ /** * Returns the stream size. **/ @@ -105,11 +105,11 @@ public: /** * Reads a block of data. **/ - unsigned long read( unsigned char* data, unsigned long maxlen );
-
+ unsigned long read( unsigned char* data, unsigned long maxlen ); + private: StreamIO* io; -
+ // 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 dcdc44c50..e25b53aab 100644 --- a/src/extension/internal/libwpg/WPGXParser.cpp +++ b/src/extension/internal/libwpg/WPGXParser.cpp @@ -1,103 +1,103 @@ -/* 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;
-}
+/* 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 71c78d2c0..d7fd4cb5a 100644 --- a/src/extension/internal/libwpg/WPGXParser.h +++ b/src/extension/internal/libwpg/WPGXParser.h @@ -1,60 +1,60 @@ -/* 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__
+/* 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 a7454d2a1..e120b802e 100644 --- a/src/extension/internal/libwpg/WPGraphics.cpp +++ b/src/extension/internal/libwpg/WPGraphics.cpp @@ -1,83 +1,83 @@ -/* 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;
-}
-
+/* 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 3226835ca..21abddd1b 100644 --- a/src/extension/internal/libwpg/WPGraphics.h +++ b/src/extension/internal/libwpg/WPGraphics.h @@ -1,46 +1,46 @@ -/* 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__
+/* 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__ diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index 28e947614..0326b150a 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -1,365 +1,365 @@ -/*
- * 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 :
+/* + * 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 : diff --git a/src/extension/paramenum.cpp b/src/extension/paramenum.cpp index 1e95a18f0..283ef8f5c 100644 --- a/src/extension/paramenum.cpp +++ b/src/extension/paramenum.cpp @@ -1,244 +1,244 @@ -/** \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 */
-
+/** \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 */ + diff --git a/src/extension/paramenum.h b/src/extension/paramenum.h index f6fea4e05..4ad448549 100644 --- a/src/extension/paramenum.h +++ b/src/extension/paramenum.h @@ -1,67 +1,67 @@ -#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 :
+#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 : diff --git a/src/extension/paramnotebook.cpp b/src/extension/paramnotebook.cpp index cd8bddcaa..e8bd1e902 100644 --- a/src/extension/paramnotebook.cpp +++ b/src/extension/paramnotebook.cpp @@ -1,427 +1,427 @@ -/** \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 :
+/** \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 : diff --git a/src/extension/paramnotebook.h b/src/extension/paramnotebook.h index a7811576e..f0ab15f57 100644 --- a/src/extension/paramnotebook.h +++ b/src/extension/paramnotebook.h @@ -1,68 +1,68 @@ -#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 :
+#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 : diff --git a/src/extension/paramradiobutton.cpp b/src/extension/paramradiobutton.cpp index 794abed94..3ca051f14 100644 --- a/src/extension/paramradiobutton.cpp +++ b/src/extension/paramradiobutton.cpp @@ -1,263 +1,263 @@ -/** \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 */
-
+/** \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 */ + diff --git a/src/extension/paramradiobutton.h b/src/extension/paramradiobutton.h index 04c4e5846..8e1edf5b8 100644 --- a/src/extension/paramradiobutton.h +++ b/src/extension/paramradiobutton.h @@ -1,57 +1,57 @@ -#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__ */
-
+#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__ */ + diff --git a/src/pixmaps/cursor-gradient-add.xpm b/src/pixmaps/cursor-gradient-add.xpm index 1f33bc659..a019b9f7d 100644 --- a/src/pixmaps/cursor-gradient-add.xpm +++ b/src/pixmaps/cursor-gradient-add.xpm @@ -1,38 +1,38 @@ -/* XPM */
-static char * cursor_gradient_add_xpm[] = {
-"32 32 3 1",
-" c None",
-". c #FFFFFF",
-"+ c #000000",
-" ... ",
-" .+. ",
-" .+. ",
-"....+.... ",
-".+++ +++. ",
-"....+.... ",
-" .+. ",
-" .+. ..... ",
-" ... .+++. ",
-" .+.+. ",
-" .+++. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+++. ",
-" .+.+. ",
-" .+++. ",
-" ..... ",
-" ... ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" ......+...... ",
-" .+++++++++++. ",
-" ......+...... ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" ... "};
+/* XPM */ +static char * cursor_gradient_add_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ..... ", +" ... .+++. ", +" .+.+. ", +" .+++. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+++. ", +" .+.+. ", +" .+++. ", +" ..... ", +" ... ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" ......+...... ", +" .+++++++++++. ", +" ......+...... ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" ... "}; diff --git a/src/pixmaps/cursor-gradient-delete.xpm b/src/pixmaps/cursor-gradient-delete.xpm index 9832aa525..da70c9525 100644 --- a/src/pixmaps/cursor-gradient-delete.xpm +++ b/src/pixmaps/cursor-gradient-delete.xpm @@ -1,38 +1,38 @@ -/* XPM */
-static char * cursor_gradient_delete_xpm[] = {
-"32 32 3 1",
-" c None",
-". c #FFFFFF",
-"+ c #000000",
-" ... ",
-" .+. ",
-" .+. ",
-"....+.... ",
-".+++ +++. ",
-"....+.... ",
-" .+. ",
-" .+. ..... ",
-" ... .+++. ",
-" .+.+. ",
-" .+++. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+. ",
-" .+++. ",
-" .+.+. ",
-" .+++. ",
-" ..... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ............. ",
-" .+++++++++++. ",
-" ............. ",
-" ",
-" ",
-" ",
-" "};
+/* XPM */ +static char * cursor_gradient_delete_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ..... ", +" ... .+++. ", +" .+.+. ", +" .+++. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+++. ", +" .+.+. ", +" .+++. ", +" ..... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ............. ", +" .+++++++++++. ", +" ............. ", +" ", +" ", +" ", +" "}; diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 8a098de12..c0027e7c3 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -1,175 +1,175 @@ -#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 :
+#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 : diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index 9fa628aa5..3a41f52de 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -1,26 +1,26 @@ -#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
+#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 c60ffb44f..729e13d4a 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -36,9 +36,9 @@ static void sp_filter_build(SPObject *object, SPDocument *document, Inkscape::XM 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,
- Inkscape::XML::Node *child,
- Inkscape::XML::Node *ref);
+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); @@ -81,7 +81,7 @@ sp_filter_class_init(SPFilterClass *klass) 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;
+ sp_object_class->child_added = sp_filter_child_added; sp_object_class->remove_child = sp_filter_remove_child; } diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 6159b4fe5..7b19ac861 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -1,35 +1,35 @@ -/** \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
-
+/** \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 06cb19bef..bb6c1321a 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -1,44 +1,44 @@ -/** \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
+/** \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 bea891742..6afec5e3c 100644 --- a/src/util/fixed_point.h +++ b/src/util/fixed_point.h @@ -1,333 +1,333 @@ -/*
- * 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 :
+/* + * 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 : |
