mirror of https://github.com/GNOME/gimp.git
346 lines
8.0 KiB
C
346 lines
8.0 KiB
C
/*
|
|
* "$Id$"
|
|
*
|
|
* Print plug-in for the GIMP.
|
|
*
|
|
* Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
|
|
* Robert Krawitz (rlk@alum.mit.edu)
|
|
* Copyright 2000 Charles Briscoe-Smith <cpbs@debian.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gimp-print/gimp-print.h>
|
|
|
|
#include "libgimp/gimp.h"
|
|
#include "libgimp/gimpui.h"
|
|
|
|
#include "print_gimp.h"
|
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
|
/*
|
|
* "Image" ADT
|
|
*
|
|
* This file defines an abstract data type called "Image". An Image wraps
|
|
* a Gimp drawable (or some other application-level image representation)
|
|
* for presentation to the low-level printer drivers (which do CMYK
|
|
* separation, dithering and weaving). The Image ADT has the ability
|
|
* to perform any combination of flips and rotations on the image,
|
|
* and then deliver individual rows to the driver code.
|
|
*
|
|
* Stuff which might be useful to do in this layer:
|
|
*
|
|
* - Scaling, optionally with interpolation/filtering.
|
|
*
|
|
* - Colour-adjustment.
|
|
*
|
|
* - Multiple-image composition.
|
|
*
|
|
* Also useful might be to break off a thin application-dependent
|
|
* sublayer leaving this layer (which does the interesting stuff)
|
|
* application-independent.
|
|
*/
|
|
|
|
|
|
/* Concrete type to represent image */
|
|
typedef struct
|
|
{
|
|
GimpDrawable *drawable;
|
|
GimpPixelRgn rgn;
|
|
|
|
/*
|
|
* Transformations we can impose on the image. The transformations
|
|
* are considered to be performed in the order given here.
|
|
*/
|
|
|
|
/* 1: Transpose the x and y axes (flip image over its leading diagonal) */
|
|
int columns; /* Set if returning columns instead of rows. */
|
|
|
|
/* 2: Translate (ox,oy) to the origin */
|
|
int ox, oy; /* Origin of image */
|
|
|
|
/* 3: Flip vertically about the x axis */
|
|
int increment; /* +1 or -1 for offset of row n+1 from row n. */
|
|
|
|
/* 4: Crop to width w, height h */
|
|
int w, h; /* Width and height of output image */
|
|
|
|
/* 5: Flip horizontally about the vertical centre-line of the image */
|
|
int mirror; /* Set if mirroring rows end-for-end. */
|
|
|
|
} Gimp_Image_t;
|
|
|
|
static const char *Image_get_appname(stp_image_t *image);
|
|
static void Image_progress_conclude(stp_image_t *image);
|
|
static void Image_note_progress(stp_image_t *image,
|
|
double current, double total);
|
|
static void Image_progress_init(stp_image_t *image);
|
|
static stp_image_status_t Image_get_row(stp_image_t *image,
|
|
unsigned char *data, int row);
|
|
static int Image_height(stp_image_t *image);
|
|
static int Image_width(stp_image_t *image);
|
|
static int Image_bpp(stp_image_t *image);
|
|
static void Image_rotate_180(stp_image_t *image);
|
|
static void Image_rotate_cw(stp_image_t *image);
|
|
static void Image_rotate_ccw(stp_image_t *image);
|
|
static void Image_crop(stp_image_t *image,
|
|
int left, int top, int right, int bottom);
|
|
static void Image_vflip(stp_image_t *image);
|
|
static void Image_hflip(stp_image_t *image);
|
|
static void Image_transpose(stp_image_t *image);
|
|
static void Image_reset(stp_image_t *image);
|
|
static void Image_init(stp_image_t *image);
|
|
|
|
static stp_image_t theImage =
|
|
{
|
|
Image_init,
|
|
Image_reset,
|
|
Image_transpose,
|
|
Image_hflip,
|
|
Image_vflip,
|
|
Image_crop,
|
|
Image_rotate_ccw,
|
|
Image_rotate_cw,
|
|
Image_rotate_180,
|
|
Image_bpp,
|
|
Image_width,
|
|
Image_height,
|
|
Image_get_row,
|
|
Image_get_appname,
|
|
Image_progress_init,
|
|
Image_note_progress,
|
|
Image_progress_conclude,
|
|
NULL
|
|
};
|
|
|
|
stp_image_t *
|
|
Image_GimpDrawable_new(GimpDrawable *drawable)
|
|
{
|
|
Gimp_Image_t *i = g_malloc(sizeof(Gimp_Image_t));
|
|
i->drawable = drawable;
|
|
gimp_pixel_rgn_init(&(i->rgn), drawable, 0, 0,
|
|
drawable->width, drawable->height, FALSE, FALSE);
|
|
theImage.rep = i;
|
|
theImage.reset(&theImage);
|
|
return &theImage;
|
|
}
|
|
|
|
static void
|
|
Image_init(stp_image_t *image)
|
|
{
|
|
/* Nothing to do. */
|
|
}
|
|
|
|
static void
|
|
Image_reset(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
i->columns = FALSE;
|
|
i->ox = 0;
|
|
i->oy = 0;
|
|
i->increment = 1;
|
|
i->w = i->drawable->width;
|
|
i->h = i->drawable->height;
|
|
i->mirror = FALSE;
|
|
}
|
|
|
|
static void
|
|
Image_transpose(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
int tmp;
|
|
|
|
if (i->mirror) i->ox += i->w - 1;
|
|
|
|
i->columns = !i->columns;
|
|
|
|
tmp = i->ox;
|
|
i->ox = i->oy;
|
|
i->oy = tmp;
|
|
|
|
tmp = i->mirror;
|
|
i->mirror = i->increment < 0;
|
|
i->increment = tmp ? -1 : 1;
|
|
|
|
tmp = i->w;
|
|
i->w = i->h;
|
|
i->h = tmp;
|
|
|
|
if (i->mirror) i->ox -= i->w - 1;
|
|
}
|
|
|
|
static void
|
|
Image_hflip(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
i->mirror = !i->mirror;
|
|
}
|
|
|
|
static void
|
|
Image_vflip(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
i->oy += (i->h-1) * i->increment;
|
|
i->increment = -i->increment;
|
|
}
|
|
|
|
/*
|
|
* Image_crop:
|
|
*
|
|
* Crop the given number of pixels off the LEFT, TOP, RIGHT and BOTTOM
|
|
* of the image.
|
|
*/
|
|
|
|
static void
|
|
Image_crop(stp_image_t *image, int left, int top, int right, int bottom)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
int xmax = (i->columns ? i->drawable->height : i->drawable->width) - 1;
|
|
int ymax = (i->columns ? i->drawable->width : i->drawable->height) - 1;
|
|
|
|
int nx = i->ox + i->mirror ? right : left;
|
|
int ny = i->oy + top * (i->increment);
|
|
|
|
int nw = i->w - left - right;
|
|
int nh = i->h - top - bottom;
|
|
|
|
int wmax, hmax;
|
|
|
|
if (nx < 0) nx = 0;
|
|
else if (nx > xmax) nx = xmax;
|
|
|
|
if (ny < 0) ny = 0;
|
|
else if (ny > ymax) ny = ymax;
|
|
|
|
wmax = xmax - nx + 1;
|
|
hmax = i->increment ? ny + 1 : ymax - ny + 1;
|
|
|
|
if (nw < 1) nw = 1;
|
|
else if (nw > wmax) nw = wmax;
|
|
|
|
if (nh < 1) nh = 1;
|
|
else if (nh > hmax) nh = hmax;
|
|
|
|
i->ox = nx;
|
|
i->oy = ny;
|
|
i->w = nw;
|
|
i->h = nh;
|
|
}
|
|
|
|
static void
|
|
Image_rotate_ccw(stp_image_t *image)
|
|
{
|
|
Image_transpose(image);
|
|
Image_vflip(image);
|
|
}
|
|
|
|
static void
|
|
Image_rotate_cw(stp_image_t *image)
|
|
{
|
|
Image_transpose(image);
|
|
Image_hflip(image);
|
|
}
|
|
|
|
static void
|
|
Image_rotate_180(stp_image_t *image)
|
|
{
|
|
Image_vflip(image);
|
|
Image_hflip(image);
|
|
}
|
|
|
|
static int
|
|
Image_bpp(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
return i->drawable->bpp;
|
|
}
|
|
|
|
static int
|
|
Image_width(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
return i->w;
|
|
}
|
|
|
|
static int
|
|
Image_height(stp_image_t *image)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
return i->h;
|
|
}
|
|
|
|
static stp_image_status_t
|
|
Image_get_row(stp_image_t *image, unsigned char *data, int row)
|
|
{
|
|
Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
|
|
if (i->columns)
|
|
gimp_pixel_rgn_get_col(&(i->rgn), data,
|
|
i->oy + row * i->increment, i->ox, i->w);
|
|
else
|
|
gimp_pixel_rgn_get_row(&(i->rgn), data,
|
|
i->ox, i->oy + row * i->increment, i->w);
|
|
if (i->mirror)
|
|
{
|
|
/* Flip row -- probably inefficiently */
|
|
int f, l, b = i->drawable->bpp;
|
|
for (f = 0, l = i->w - 1; f < l; f++, l--)
|
|
{
|
|
int c;
|
|
unsigned char tmp;
|
|
for (c = 0; c < b; c++)
|
|
{
|
|
tmp = data[f*b+c];
|
|
data[f*b+c] = data[l*b+c];
|
|
data[l*b+c] = tmp;
|
|
}
|
|
}
|
|
}
|
|
return STP_IMAGE_OK;
|
|
}
|
|
|
|
static void
|
|
Image_progress_init(stp_image_t *image)
|
|
{
|
|
gimp_progress_init(_("Printing..."));
|
|
}
|
|
|
|
static void
|
|
Image_note_progress(stp_image_t *image, double current, double total)
|
|
{
|
|
gimp_progress_update(current / total);
|
|
}
|
|
|
|
static void
|
|
Image_progress_conclude(stp_image_t *image)
|
|
{
|
|
gimp_progress_update(1);
|
|
}
|
|
|
|
static const char *
|
|
Image_get_appname(stp_image_t *image)
|
|
{
|
|
static char pluginname[] = PLUG_IN_NAME " plug-in V" PLUG_IN_VERSION
|
|
" for GIMP";
|
|
return pluginname;
|
|
}
|
|
|
|
/*
|
|
* End of "$Id$".
|
|
*/
|