From c7bacaeadb20a9baf6b2404e8ea1cb3d45ce3640 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Wed, 23 Feb 2000 13:52:42 +0000 Subject: [PATCH] bumped print plug-in to version 3.0.9 --Sven --- ChangeLog | 11 + plug-ins/print/print-escp2.c | 44 +- plug-ins/print/print-pcl.c | 4 +- plug-ins/print/print-util.c | 807 ++++++++++++----------------------- plug-ins/print/print.c | 421 +++++++++++++----- 5 files changed, 643 insertions(+), 644 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10037738e1..9478e2aa25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Wed Feb 23 14:50:09 CET 2000 Sven Neumann + + * plug-ins/print/print-escp2.c + * plug-ins/print/print-pcl.c + * plug-ins/print/print-util.c + * plug-ins/print/print.c: + Applied patch from Robert L Krawitz . + Bumps print plug-in version to 3.0.9 and adds a few nifty + little features. Now all we need is a facelift for the + dialog... + Wed Feb 23 01:15:12 CET 2000 Sven Neumann * plug-ins/common/gtm.c: added a warning in the case the user diff --git a/plug-ins/print/print-escp2.c b/plug-ins/print/print-escp2.c index a996605010..5198a4baa5 100644 --- a/plug-ins/print/print-escp2.c +++ b/plug-ins/print/print-escp2.c @@ -466,6 +466,17 @@ escp2_print(int model, /* I - Model */ return; } } + if (!use_softweave) + { + /* + * In microweave mode, correct for the loss of page height that + * would happen in softweave mode. The divide by 10 is to convert + * lines into points (Epson printers all have 720 ydpi); + */ + int extra_points = ((escp2_nozzles(model) - 1) * + escp2_nozzle_separation(model) + 5) / 10; + top += extra_points; + } /* * Compute the output size... @@ -577,11 +588,13 @@ escp2_print(int model, /* I - Model */ x = top; top = left; - left = x; + left = page_width - x - out_width; } if (left < 0) left = (page_width - out_width) / 2 + page_left; + else + left = left + page_left; if (top < 0) top = (page_height + out_height) / 2 + page_bottom; @@ -770,11 +783,11 @@ escp2_print(int model, /* I - Model */ if (output_type == OUTPUT_GRAY) { dither_black(out, x, image_height, out_width, black); - if (use_softweave) - escp2_write_weave(prn, length, ydpi, model, out_width, left, xdpi, - cyan, magenta, yellow, black, lcyan, lmagenta); - else - escp2_write(prn, black, length, 0, 0, ydpi, model, out_width, left); + if (use_softweave) + escp2_write_weave(prn, length, ydpi, model, out_width, left, xdpi, + cyan, magenta, yellow, black, lcyan, lmagenta); + else + escp2_write(prn, black, length, 0, 0, ydpi, model, out_width, left); } else if (escp2_has_cap(model, MODEL_6COLOR_MASK, MODEL_6COLOR_YES)) { @@ -862,11 +875,11 @@ escp2_print(int model, /* I - Model */ if (output_type == OUTPUT_GRAY) { dither_black(out, y, image_width, out_width, black); - if (use_softweave) - escp2_write_weave(prn, length, ydpi, model, out_width, left, xdpi, - cyan, magenta, yellow, black, lcyan, lmagenta); - else - escp2_write(prn, black, length, 0, 0, ydpi, model, out_width, left); + if (use_softweave) + escp2_write_weave(prn, length, ydpi, model, out_width, left, xdpi, + cyan, magenta, yellow, black, lcyan, lmagenta); + else + escp2_write(prn, black, length, 0, 0, ydpi, model, out_width, left); } else if (escp2_has_cap(model, MODEL_6COLOR_MASK, MODEL_6COLOR_YES)) { @@ -1635,14 +1648,13 @@ flush_pass(int passno, int model, int width, int hoffset, int ydpi, fwrite("\033.\001\012\012\001", 6, 1, prn); break; case 720 : - if (escp2_has_cap(model, MODEL_6COLOR_MASK, MODEL_6COLOR_YES)) + if (escp2_has_cap(model, MODEL_720DPI_MODE_MASK, + MODEL_720DPI_600)) fprintf(prn, "\033.%c%c%c%c", 1, 8 * 5, 5, *linecount + pass->missingstartrows); - else if (escp2_has_cap(model, MODEL_720DPI_MODE_MASK, - MODEL_720DPI_600)) - fwrite("\033.\001\050\005\001", 6, 1, prn); else - fwrite("\033.\001\005\005\001", 6, 1, prn); + fprintf(prn, "\033.%c%c%c%c", 1, 5, 5, + *linecount + pass->missingstartrows); break; } diff --git a/plug-ins/print/print-pcl.c b/plug-ins/print/print-pcl.c index 18b02955e4..83cd27b6e1 100644 --- a/plug-ins/print/print-pcl.c +++ b/plug-ins/print/print-pcl.c @@ -429,11 +429,13 @@ pcl_print(int model, /* I - Model */ x = top; top = left; - left = x; + left = page_width - x - out_width; } if (left < 0) left = (page_width - out_width) / 2 + page_left; + else + left = left + page_left; if (top < 0) top = (page_height + out_height) / 2 + page_bottom; diff --git a/plug-ins/print/print-util.c b/plug-ins/print/print-util.c index d3a69394c2..e6d8d941d5 100644 --- a/plug-ins/print/print-util.c +++ b/plug-ins/print/print-util.c @@ -44,8 +44,6 @@ #include "print.h" -#include -#include "libgimp/gimpcolorspace.h" #include /* @@ -126,18 +124,24 @@ dither_black(unsigned short *gray, /* I - Grayscale pixels */ if (k > 32767) { *kptr |= bit; - k -= 65535; + k -= 65536; } if (ditherbit & bit) { - kerror1[0] = 5 * k; - ditherk = kerror0[1] + 3 * k; + int tmpk = k; + if (tmpk > 65535) + tmpk = 65535; + kerror1[0] = 5 * tmpk; + ditherk = kerror0[1] + 3 * tmpk; } else { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + 5 * k; + int tmpk = k; + if (tmpk > 65535) + tmpk = 65535; + kerror1[0] = 3 * tmpk; + ditherk = kerror0[1] + 5 * tmpk; } if (bit == 1) @@ -185,11 +189,11 @@ dither_black(unsigned short *gray, /* I - Grayscale pixels */ */ #define NU_C 1 -#define DE_C 1 +#define DE_C 2 #define NU_M 1 -#define DE_M 1 +#define DE_M 2 #define NU_Y 1 -#define DE_Y 1 +#define DE_Y 2 #define I_RATIO_C NU_C / DE_C #define I_RATIO_C1 NU_C / (DE_C + NU_C) @@ -311,7 +315,7 @@ do { \ { \ PRINT_D1(r, R, d1, d2); \ DO_PRINT_COLOR(r); \ - r -= 65535; \ + r -= 65536; \ } \ } \ else \ @@ -348,52 +352,41 @@ do { \ if (sub < R##_CONST_0) \ r -= R##_CONST_0; \ else if (sub > 65535) \ - r -= 65535; \ + r -= 65536; \ else \ r -= sub; \ } \ } \ } while (0) -#if 1 -#define UPDATE_DITHER(r, d2, x, width) \ -do { \ - int offset = (15 - (((o##r & 0xf000) >> 12)) * horizontal_overdensity) \ - >> 1; \ - if (x < offset) \ - offset = x; \ - else if (x > dst_width - offset - 1) \ - offset = dst_width - x - 1; \ - if (ditherbit##d2 & bit) \ - { \ - r##error1[-offset] += r; \ - r##error1[0] += 3 * r; \ - r##error1[offset] += r; \ - dither##r = r##error0[direction] + 3 * r; \ - } \ - else \ - { \ - r##error1[-offset] += r; \ - r##error1[0] += r; \ - r##error1[offset] += r; \ - dither##r = r##error0[direction] + 5 * r; \ - } \ -} while (0) -#else -#define UPDATE_DITHER(r, d2, x, width) \ -do { \ - if (ditherbit##d2 & bit) \ - { \ - r##error1[0] = 5 * r; \ - dither##r = r##error0[direction] + 3 * r; \ - } \ - else \ - { \ - r##error1[0] = 3 * r; \ - dither##r = r##error0[direction] + 5 * r; \ - } \ -} while (0) -#endif +#define UPDATE_DITHER(r, d2, x, width) \ +do { \ + int offset = ((15 - (((o##r & 0xf000) >> 12))) * horizontal_overdensity) \ + >> 1; \ + int tmp##r = r; \ + if (tmp##r > 65535) \ + tmp##r = 65535; \ + if (x < offset) \ + offset = x; \ + else if (x > dst_width - offset - 1) \ + offset = dst_width - x - 1; \ + if (ditherbit##d2 & bit) \ + { \ + r##error1[-offset] += tmp##r; \ + r##error1[0] += 3 * tmp##r; \ + r##error1[offset] += tmp##r; \ + if (x > 0 && x < (dst_width - 1)) \ + dither##r = r##error0[direction] + 3 * tmp##r; \ + } \ + else \ + { \ + r##error1[-offset] += tmp##r; \ + r##error1[0] += tmp##r; \ + r##error1[offset] += tmp##r; \ + if (x > 0 && x < (dst_width - 1)) \ + dither##r = r##error0[direction] + 5 * tmp##r; \ + } \ + } while (0) void dither_cmyk(unsigned short *rgb, /* I - RGB pixels */ @@ -731,7 +724,7 @@ dither_cmyk(unsigned short *rgb, /* I - RGB pixels */ (32768 >> K_RANDOMIZER)))) { DO_PRINT_COLOR(k); - k -= 65535; + k -= 65536; } UPDATE_DITHER(k, 1, x, src_width); @@ -936,13 +929,19 @@ dither_black4(unsigned short *gray, /* I - Grayscale pixels */ if (ditherbit & bit) { - kerror1[0] = 5 * k; - ditherk = kerror0[1] + 3 * k; + int tmpk = k; + if (tmpk > 65535) + tmpk = 65535; + kerror1[0] = 5 * tmpk; + ditherk = kerror0[1] + 3 * tmpk; } else { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + 5 * k; + int tmpk = k; + if (tmpk > 65535) + tmpk = 65535; + kerror1[0] = 3 * tmpk; + ditherk = kerror0[1] + 5 * tmpk; } if (bit == 1) @@ -1210,6 +1209,156 @@ dither_cmyk4(unsigned short *rgb, /* I - RGB pixels */ } } +/* rgb/hsv conversions taken from Gimp common/autostretch_hsv.c */ +/* The version in libgimp IS NOT SUITABLE FOR THIS TASK. That version is */ +/* 8 bits. We need the 16 bit version! */ + + +static void +calc_rgb_to_hsv(unsigned short *rgb, double *hue, double *sat, double *val) +{ + double red, green, blue; + double h, s, v; + double min, max; + double delta; + + red = rgb[0] / 65535.0; + green = rgb[1] / 65535.0; + blue = rgb[2] / 65535.0; + + h = 0.0; /* Shut up -Wall */ + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + + v = max; + + if (max != 0.0) + s = (max - min) / max; + else + s = 0.0; + + if (s == 0.0) + h = 0.0; + else + { + delta = max - min; + + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h /= 6.0; + + if (h < 0.0) + h += 1.0; + else if (h > 1.0) + h -= 1.0; + } + + *hue = h; + *sat = s; + *val = v; +} + +static void +calc_hsv_to_rgb(unsigned short *rgb, double h, double s, double v) +{ + double hue, saturation, value; + double f, p, q, t; + + if (s == 0.0) + { + h = v; + s = v; + v = v; /* heh */ + } + else + { + hue = h * 6.0; + saturation = s; + value = v; + + if (hue == 6.0) + hue = 0.0; + + f = hue - (int) hue; + p = value * (1.0 - saturation); + q = value * (1.0 - saturation * f); + t = value * (1.0 - saturation * (1.0 - f)); + + switch ((int) hue) + { + case 0: + h = value; + s = t; + v = p; + break; + + case 1: + h = q; + s = value; + v = p; + break; + + case 2: + h = p; + s = value; + v = t; + break; + + case 3: + h = p; + s = q; + v = value; + break; + + case 4: + h = t; + s = p; + v = value; + break; + + case 5: + h = value; + s = p; + v = q; + break; + } + } + + rgb[0] = h*65535; + rgb[1] = s*65535; + rgb[2] = v*65535; + +} + + /* * 'gray_to_gray()' - Convert grayscale image data to grayscale (brightness * adjusted). @@ -1234,7 +1383,14 @@ gray_to_gray(unsigned char *grayin, /* I - RGB pixels */ while (width > 0) { *grayout = lut->composite[*grayin]; - + if (vars->density != 1.0) + { + float t = ((float) *grayout) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + *grayout = (unsigned short) (t * 65536.0); + } grayin ++; grayout ++; width --; @@ -1248,8 +1404,15 @@ gray_to_gray(unsigned char *grayin, /* I - RGB pixels */ while (width > 0) { - *grayout = lut->composite[grayin[0] * grayin[1] / 255] + 255 - grayin[1]; - + *grayout = lut->composite[grayin[0] * grayin[1] / 255 + 255 - grayin[1]]; + if (vars->density != 1.0) + { + float t = ((float) *grayout) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + *grayout = (unsigned short) (t * 65536.0); + } grayin += bpp; grayout ++; width --; @@ -1290,6 +1453,14 @@ indexed_to_gray(unsigned char *indexed, /* I - Indexed pixels */ while (width > 0) { *gray = lut->composite[gray_cmap[*indexed]]; + if (vars->density != 1.0) + { + float t = ((float) *gray) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + *gray = (unsigned short) (t * 65536.0); + } indexed ++; gray ++; width --; @@ -1305,6 +1476,14 @@ indexed_to_gray(unsigned char *indexed, /* I - Indexed pixels */ { *gray = lut->composite[gray_cmap[indexed[0] * indexed[1] / 255] + 255 - indexed[1]]; + if (vars->density != 1.0) + { + float t = ((float) *gray) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + *gray = (unsigned short) (t * 65536.0); + } indexed += bpp; gray ++; width --; @@ -1331,22 +1510,28 @@ indexed_to_rgb(unsigned char *indexed, /* I - Indexed pixels */ while (width > 0) { + double h, s, v; rgb[0] = lut->red[cmap[*indexed * 3 + 0]]; rgb[1] = lut->green[cmap[*indexed * 3 + 1]]; rgb[2] = lut->blue[cmap[*indexed * 3 + 2]]; if (vars->saturation != 1.0) { - double h, s, v; - unsigned char rgb1[3]; - rgb1[0] = rgb[0]; - rgb1[1] = rgb[1]; - rgb1[2] = rgb[2]; - gimp_rgb_to_hsv4 (rgb1, &h, &s, &v); + calc_rgb_to_hsv(rgb, &h, &s, &v); s = pow(s, 1.0 / vars->saturation); - gimp_hsv_to_rgb4 (rgb1, h, s, v); - rgb[0] = rgb1[0]; - rgb[1] = rgb1[1]; - rgb[2] = rgb1[2]; + calc_hsv_to_rgb(rgb, h, s, v); + } + if (vars->density != 1.0) + { + float t; + int i; + for (i = 0; i < 3; i++) + { + t = ((float) rgb[i]) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + rgb[i] = (unsigned short) (t * 65536.0); + } } rgb += 3; indexed ++; @@ -1361,6 +1546,7 @@ indexed_to_rgb(unsigned char *indexed, /* I - Indexed pixels */ while (width > 0) { + double h, s, v; rgb[0] = lut->red[cmap[indexed[0] * 3 + 0] * indexed[1] / 255 + 255 - indexed[1]]; rgb[1] = lut->green[cmap[indexed[0] * 3 + 1] * indexed[1] / 255 + @@ -1369,17 +1555,22 @@ indexed_to_rgb(unsigned char *indexed, /* I - Indexed pixels */ 255 - indexed[1]]; if (vars->saturation != 1.0) { - double h, s, v; - unsigned char rgb1[3]; - rgb1[0] = rgb[0]; - rgb1[1] = rgb[1]; - rgb1[2] = rgb[2]; - gimp_rgb_to_hsv4 (rgb1, &h, &s, &v); + calc_rgb_to_hsv(rgb, &h, &s, &v); s = pow(s, 1.0 / vars->saturation); - gimp_hsv_to_rgb4 (rgb1, h, s, v); - rgb[0] = rgb1[0]; - rgb[1] = rgb1[1]; - rgb[2] = rgb1[2]; + calc_hsv_to_rgb(rgb, h, s, v); + } + if (vars->density != 1.0) + { + float t; + int i; + for (i = 0; i < 3; i++) + { + t = ((float) rgb[i]) / 65536.0; + t = (1.0 + ((t - 1.0) * vars->density)); + if (t < 0.0) + t = 0.0; + rgb[i] = (unsigned short) (t * 65536.0); + } } rgb += 3; indexed += bpp; @@ -1431,7 +1622,7 @@ rgb_to_gray(unsigned char *rgb, /* I - RGB pixels */ *gray = lut->composite[((rgb[0] * LUM_RED + rgb[1] * LUM_GREEN + rgb[2] * LUM_BLUE) * - rgb[3] / 25500 + 255 - rgb[3])]; + rgb[3] / 255 + 255 - rgb[3])]; gray ++; rgb += bpp; width --; @@ -1461,17 +1652,13 @@ rgb_to_rgb(unsigned char *rgbin, /* I - RGB pixels */ while (width > 0) { + double h, s, v; rgbout[0] = lut->red[rgbin[0]]; rgbout[1] = lut->green[rgbin[1]]; rgbout[2] = lut->blue[rgbin[2]]; if (vars->saturation != 1.0 || vars->contrast != 100) { - double h, s, v; - unsigned char rgb1[3]; - rgb1[0] = rgbout[0]; - rgb1[1] = rgbout[1]; - rgb1[2] = rgbout[2]; - gimp_rgb_to_hsv4 (rgb1, &h, &s, &v); + calc_rgb_to_hsv(rgbout, &h, &s, &v); if (vars->saturation != 1.0) s = pow(s, 1.0 / vars->saturation); #if 0 @@ -1485,10 +1672,7 @@ rgb_to_rgb(unsigned char *rgbin, /* I - RGB pixels */ v = (tv / 2.0) + .5; } #endif - gimp_hsv_to_rgb4 (rgb1, h, s, v); - rgbout[0] = rgb1[0]; - rgbout[1] = rgb1[1]; - rgbout[2] = rgb1[2]; + calc_hsv_to_rgb(rgbout, h, s, v); } if (vars->density != 1.0) { @@ -1516,18 +1700,13 @@ rgb_to_rgb(unsigned char *rgbin, /* I - RGB pixels */ while (width > 0) { + double h, s, v; rgbout[0] = lut->red[rgbin[0] * rgbin[3] / 255 + 255 - rgbin[3]]; rgbout[1] = lut->green[rgbin[1] * rgbin[3] / 255 + 255 - rgbin[3]]; rgbout[2] = lut->blue[rgbin[2] * rgbin[3] / 255 + 255 - rgbin[3]]; - if (vars->saturation != 1.0 || vars->contrast != 100 || - vars->density != 1.0) + if (vars->saturation != 1.0 || vars->contrast != 100) { - double h, s, v; - unsigned char rgb1[3]; - rgb1[0] = rgbout[0]; - rgb1[1] = rgbout[1]; - rgb1[2] = rgbout[2]; - gimp_rgb_to_hsv4 (rgb1, &h, &s, &v); + calc_rgb_to_hsv(rgbout, &h, &s, &v); if (vars->saturation != 1.0) s = pow(s, 1.0 / vars->saturation); #if 0 @@ -1541,10 +1720,7 @@ rgb_to_rgb(unsigned char *rgbin, /* I - RGB pixels */ v = (tv / 2.0) + .5; } #endif - gimp_hsv_to_rgb4 (rgb1, h, s, v); - rgbout[0] = rgb1[0]; - rgbout[1] = rgb1[1]; - rgbout[2] = rgb1[2]; + calc_hsv_to_rgb(rgbout, h, s, v); } if (vars->density != 1.0) { @@ -1779,433 +1955,6 @@ default_media_size(int model, /* I - Printer model */ } } - - -#ifdef LEFTOVER_8_BIT -/* - * Everything here and below goes away when this is tested on all printers. - */ - -#define LEVEL_3 255 -#define LEVEL_2 213 -#define LEVEL_1 127 -#define LEVEL_0 0 - -void -dither_black4(unsigned char *gray, /* I - Grayscale pixels */ - int row, /* I - Current Y coordinate */ - int src_width, /* I - Width of input row */ - int dst_width, /* I - Width of output rows */ - unsigned char *black) /* O - Black bitmap pixels */ -{ - int x, /* Current X coordinate */ - xerror, /* X error count */ - xstep, /* X step */ - xmod, /* X error modulus */ - length; /* Length of output bitmap in bytes */ - unsigned char bit, /* Current bit */ - *kptr; /* Current black pixel */ - int k, /* Current black value */ - ditherk, /* Next error value in buffer */ - *kerror0, /* Pointer to current error row */ - *kerror1; /* Pointer to next error row */ - int ditherbit; /* Random dither bitmask */ - - - xstep = src_width / dst_width; - xmod = src_width % dst_width; - length = (dst_width + 7) / 8; - - kerror0 = error[row & 1][3]; - kerror1 = error[1 - (row & 1)][3]; - - memset(black, 0, length * 2); - - for (x = 0, bit = 128, kptr = black, xerror = 0, ditherbit = rand(), - ditherk = kerror0[0]; - x < dst_width; - x ++, kerror0 ++, kerror1 ++) - { - k = 255 - *gray + ditherk / 8; - - if (k > ((LEVEL_2 + LEVEL_3) / 2)) - { - kptr[0] |= bit; - kptr[length] |= bit; - k -= LEVEL_3; - } - else if (k > ((LEVEL_1 + LEVEL_2) / 2)) - { - kptr[length] |= bit; - k -= LEVEL_2; - } - else if (k > ((LEVEL_0 + LEVEL_1) / 2)) - { - kptr[0] |= bit; - k -= LEVEL_1; - } - - if (ditherbit & bit) - { - kerror1[0] = 5 * k; - ditherk = kerror0[1] + 3 * k; - } - else - { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + 5 * k; - } - - if (bit == 1) - { - kptr ++; - - bit = 128; - ditherbit = rand(); - } - else - bit >>= 1; - - gray += xstep; - xerror += xmod; - if (xerror >= dst_width) - { - xerror -= dst_width; - gray ++; - } - } -} - -void -dither_cmyk4(unsigned char *rgb, /* I - RGB pixels */ - int row, /* I - Current Y coordinate */ - int src_width, /* I - Width of input row */ - int dst_width, /* I - Width of output rows */ - unsigned char *cyan, /* O - Cyan bitmap pixels */ - unsigned char *magenta, /* O - Magenta bitmap pixels */ - unsigned char *yellow, /* O - Yellow bitmap pixels */ - unsigned char *black) /* O - Black bitmap pixels */ -{ - int x, /* Current X coordinate */ - xerror, /* X error count */ - xstep, /* X step */ - xmod, /* X error modulus */ - length; /* Length of output bitmap in bytes */ - int c, m, y, k, /* CMYK values */ - divk, /* Inverse of K */ - diff; /* Average color difference */ - unsigned char bit, /* Current bit */ - *cptr, /* Current cyan pixel */ - *mptr, /* Current magenta pixel */ - *yptr, /* Current yellow pixel */ - *kptr; /* Current black pixel */ - int ditherc, /* Next error value in buffer */ - *cerror0, /* Pointer to current error row */ - *cerror1; /* Pointer to next error row */ - int dithery, /* Next error value in buffer */ - *yerror0, /* Pointer to current error row */ - *yerror1; /* Pointer to next error row */ - int ditherm, /* Next error value in buffer */ - *merror0, /* Pointer to current error row */ - *merror1; /* Pointer to next error row */ - int ditherk, /* Next error value in buffer */ - *kerror0, /* Pointer to current error row */ - *kerror1; /* Pointer to next error row */ - int ditherbit; /* Random dither bitmask */ - - - xstep = 3 * (src_width / dst_width); - xmod = src_width % dst_width; - length = (dst_width + 7) / 8; - - cerror0 = error[row & 1][0]; - cerror1 = error[1 - (row & 1)][0]; - - merror0 = error[row & 1][1]; - merror1 = error[1 - (row & 1)][1]; - - yerror0 = error[row & 1][2]; - yerror1 = error[1 - (row & 1)][2]; - - kerror0 = error[row & 1][3]; - kerror1 = error[1 - (row & 1)][3]; - - memset(cyan, 0, length * 2); - memset(magenta, 0, length * 2); - memset(yellow, 0, length * 2); - memset(black, 0, length * 2); - - for (x = 0, bit = 128, cptr = cyan, mptr = magenta, yptr = yellow, - kptr = black, xerror = 0, ditherbit = rand(), ditherc = cerror0[0], - ditherm = merror0[0], dithery = yerror0[0], ditherk = kerror0[0]; - x < dst_width; - x ++, cerror0 ++, cerror1 ++, merror0 ++, merror1 ++, yerror0 ++, - yerror1 ++, kerror0 ++, kerror1 ++) - { - /* - * First compute the standard CMYK separation color values... - */ - - c = 255 - rgb[0]; - m = 255 - rgb[1]; - y = 255 - rgb[2]; - k = MIN(c, MIN(m, y)); - - /* - * Since we're printing black, adjust the black level based upon - * the amount of color in the pixel (colorful pixels get less black)... - */ - - diff = 255 - (abs(c - m) + abs(c - y) + abs(m - y)) / 3; - diff = diff * diff * diff / 65025; /* diff = diff^3 */ - k = diff * k / 255; - divk = 255 - k; - - if (divk == 0) - c = m = y = 0; /* Grayscale */ - else - { - /* - * Full color; update the CMY values for the black value and reduce - * CMY as necessary to give better blues, greens, and reds... :) - */ - - c = (255 - rgb[1] / 4) * (c - k) / divk; - m = (255 - rgb[2] / 4) * (m - k) / divk; - y = (255 - rgb[0] / 4) * (y - k) / divk; - } - - k += ditherk / 8; - if (k > ((LEVEL_2 + LEVEL_3) / 2)) - { - kptr[0] |= bit; - kptr[length] |= bit; - k -= LEVEL_3; - } - else if (k > ((LEVEL_1 + LEVEL_2) / 2)) - { - kptr[length] |= bit; - k -= LEVEL_2; - } - else if (k > ((LEVEL_0 + LEVEL_1) / 2)) - { - kptr[0] |= bit; - k -= LEVEL_1; - } - - if (ditherbit & bit) - { - kerror1[0] = 5 * k; - ditherk = kerror0[1] + 3 * k; - } - else - { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + 5 * k; - } - - c += ditherc / 8; - if (c > ((LEVEL_2 + LEVEL_3) / 2)) - { - cptr[0] |= bit; - cptr[length] |= bit; - c -= LEVEL_3; - } - else if (c > ((LEVEL_1 + LEVEL_2) / 2)) - { - cptr[length] |= bit; - c -= LEVEL_2; - } - else if (c > ((LEVEL_0 + LEVEL_1) / 2)) - { - cptr[0] |= bit; - c -= LEVEL_1; - } - - if (ditherbit & bit) - { - cerror1[0] = 5 * c; - ditherc = cerror0[1] + 3 * c; - } - else - { - cerror1[0] = 3 * c; - ditherc = cerror0[1] + 5 * c; - } - - m += ditherm / 8; - if (m > ((LEVEL_2 + LEVEL_3) / 2)) - { - mptr[0] |= bit; - mptr[length] |= bit; - m -= LEVEL_3; - } - else if (m > ((LEVEL_1 + LEVEL_2) / 2)) - { - mptr[length] |= bit; - m -= LEVEL_2; - } - else if (m > ((LEVEL_0 + LEVEL_1) / 2)) - { - mptr[0] |= bit; - m -= LEVEL_1; - } - - if (ditherbit & bit) - { - merror1[0] = 5 * m; - ditherm = merror0[1] + 3 * m; - } - else - { - merror1[0] = 3 * m; - ditherm = merror0[1] + 5 * m; - } - - y += dithery / 8; - if (y > ((LEVEL_2 + LEVEL_3) / 2)) - { - yptr[0] |= bit; - yptr[length] |= bit; - y -= LEVEL_3; - } - else if (y > ((LEVEL_1 + LEVEL_2) / 2)) - { - yptr[length] |= bit; - y -= LEVEL_2; - } - else if (y > ((LEVEL_0 + LEVEL_1) / 2)) - { - yptr[0] |= bit; - y -= LEVEL_1; - } - - if (ditherbit & bit) - { - yerror1[0] = 5 * y; - dithery = yerror0[1] + 3 * y; - } - else - { - yerror1[0] = 3 * y; - dithery = yerror0[1] + 5 * y; - } - - if (bit == 1) - { - cptr ++; - mptr ++; - yptr ++; - kptr ++; - - bit = 128; - ditherbit = rand(); - } - else - bit >>= 1; - - rgb += xstep; - xerror += xmod; - if (xerror >= dst_width) - { - xerror -= dst_width; - rgb += 3; - } - } -} - -void -gray_to_gray(unsigned char *grayin, /* I - RGB pixels */ - unsigned char *grayout, /* O - RGB pixels */ - int width, /* I - Width of row */ - int bpp, /* I - Bytes-per-pixel in grayin */ - unsigned char *cmap, /* I - Colormap (unused) */ - float saturation /* I - Saturation */ - ) -{ - if (bpp == 1) - { - /* - * No alpha in image... - */ - - while (width > 0) - { - *grayout = lut->composite[*grayin]; - - grayin ++; - grayout ++; - width --; - } - } - else - { - /* - * Handle alpha in image... - */ - - while (width > 0) - { - *grayout = lut->composite[grayin[0] * grayin[1] / 255] + 255 - grayin[1]; - - grayin += bpp; - grayout ++; - width --; - } - } -} - -void -indexed_to_gray(unsigned char *indexed, /* I - Indexed pixels */ - unsigned char *gray, /* O - Grayscale pixels */ - int width, /* I - Width of row */ - int bpp, /* I - Bytes/pix in indexed */ - unsigned char *cmap, /* I - Colormap */ - float saturation /* I - Saturation */ - ) -{ - int i; /* Looping var */ - unsigned char gray_cmap[256]; /* Grayscale colormap */ - - - for (i = 0; i < 256; i ++, cmap += 3) - gray_cmap[i] = (cmap[0] * LUM_RED + - cmap[1] * LUM_GREEN + - cmap[2] * LUM_BLUE) / 100; - - if (bpp == 1) - { - /* - * No alpha in image... - */ - - while (width > 0) - { - *gray = lut->composite[gray_cmap[*indexed]]; - indexed ++; - gray ++; - width --; - } - } - else - { - /* - * Handle alpha in image... - */ - - while (width > 0) - { - *gray = lut->composite[gray_cmap[indexed[0] * indexed[1] / 255] + - 255 - indexed[1]]; - indexed += bpp; - gray ++; - width --; - } - } -} - -#endif - /* * End of "$Id$". */ diff --git a/plug-ins/print/print.c b/plug-ins/print/print.c index 5a29c86851..0fd73c0e16 100644 --- a/plug-ins/print/print.c +++ b/plug-ins/print/print.c @@ -59,7 +59,7 @@ #include #include -#define PLUG_IN_VERSION "3.0.6 - 11 Feb 2000" +#define PLUG_IN_VERSION "3.0.9 - 23 Feb 2000" #define PLUG_IN_NAME "Print" @@ -69,7 +69,7 @@ #define SCALE_WIDTH 64 #define ENTRY_WIDTH 64 -#define PREVIEW_SIZE 220 /* Assuming max media size of 22" */ +#define PREVIEW_SIZE 240 /* Assuming max media size of 24" */ #define MAX_PLIST 100 @@ -124,7 +124,9 @@ static void resolution_callback(GtkWidget *, gint); static void output_type_callback(GtkWidget *, gint); static void linear_callback(GtkWidget *, gint); static void orientation_callback(GtkWidget *, gint); +static void printandsave_callback(void); static void print_callback(void); +static void save_callback(void); static void cancel_callback(void); static void close_callback(void); @@ -142,7 +144,8 @@ static void file_cancel_callback(void); static void preview_update(void); static void preview_button_callback(GtkWidget *, GdkEventButton *); static void preview_motion_callback(GtkWidget *, GdkEventMotion *); - +static void top_callback(GtkWidget *); +static void left_callback(GtkWidget *); /* * Globals... @@ -240,7 +243,7 @@ printer_t printers[] = /* List of supported printer types */ escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, { N_("EPSON Stylus Photo EX"), "escp2-ex", 1, 7, 0.585, 0.646, escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, - { N_("EPSON Stylus Photo EX"), "escp2-photo", 1, 8, 0.585, 0.646, + { N_("EPSON Stylus Photo"), "escp2-photo", 1, 8, 0.585, 0.646, escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, }; @@ -257,6 +260,7 @@ GtkWidget *print_dialog, /* Print dialog window */ *scaling_entry, /* Text entry widget for scaling */ *scaling_percent, /* Scale by percent */ *scaling_ppi, /* Scale by pixels-per-inch */ + *scaling_image, /* Scale to the image */ *brightness_scale, /* Scale for brightness */ *brightness_entry, /* Text entry widget for brightness */ *saturation_scale, /* Scale for saturation */ @@ -283,7 +287,12 @@ GtkWidget *print_dialog, /* Print dialog window */ *ppd_button, /* PPD file browse button */ *output_cmd, /* Output command text entry */ *ppd_browser, /* File selection dialog for PPD files */ - *file_browser; /* FSD for print files */ + *file_browser, /* FSD for print files */ + *left_entry, + *right_entry, + *top_entry, + *bottom_entry, + *printandsave_button; GtkObject *scaling_adjustment, /* Adjustment object for scaling */ *brightness_adjustment, /* Adjustment object for brightness */ @@ -320,8 +329,10 @@ int plist_current = 0, /* Current system printer */ plist_count = 0; /* Number of system printers */ plist_t plist[MAX_PLIST]; /* System printers */ +int saveme = FALSE; /* True if print should proceed */ int runme = FALSE, /* True if print should proceed */ current_printer = 0; /* Current printer index */ +gint32 image_ID; /* image ID */ /* * 'main()' - Main entry - just call gimp_main()... @@ -365,10 +376,10 @@ query(void) { PARAM_INT32, "left", "Left offset (points, -1 = centered)" }, { PARAM_INT32, "top", "Top offset (points, -1 = centered)" }, { PARAM_FLOAT, "gamma", "Output gamma (0.1 - 3.0)" }, - { PARAM_INT32, "contrast", "Top offset (points, -1 = centered)" }, - { PARAM_INT32, "red", "Top offset (points, -1 = centered)" }, - { PARAM_INT32, "green", "Top offset (points, -1 = centered)" }, - { PARAM_INT32, "blue", "Top offset (points, -1 = centered)" }, + { PARAM_INT32, "contrast", "Contrast" }, + { PARAM_INT32, "red", "Red level" }, + { PARAM_INT32, "green", "Green level" }, + { PARAM_INT32, "blue", "Blue level" }, { PARAM_INT32, "linear", "Linear output (0 = normal, 1 = linear)" }, { PARAM_FLOAT, "saturation", "Saturation (0-1000%)" }, { PARAM_FLOAT, "density", "Density (0-200%)" }, @@ -379,10 +390,10 @@ query(void) gimp_install_procedure( "file_print", - "This plug-in prints images from The GIMP.", - "Prints images to PostScript, PCL, or ESC/P2 printers.", + _("This plug-in prints images from The GIMP."), + _("Prints images to PostScript, PCL, or ESC/P2 printers."), "Michael Sweet and Robert Krawitz ", - "Copyright 1997-1999 by Michael Sweet and Robert Krawitz", + "Copyright 1997-2000 by Michael Sweet and Robert Krawitz", PLUG_IN_VERSION, N_("/File/Print..."), "RGB*,GRAY*,INDEXED*", @@ -438,7 +449,6 @@ run(char *name, /* I - Name of print program. */ #ifdef __EMX__ char *tmpfile; /* temp filename */ #endif - gint32 image_ID; /* image ID */ gint32 drawable_ID; /* drawable ID */ GimpExportReturnType export = EXPORT_CANCEL; /* return value of gimp_export_image() */ @@ -801,7 +811,7 @@ do_print_dialog(void) * Top-level table for dialog... */ - table = gtk_table_new(17, 4, FALSE); + table = gtk_table_new(20, 4, FALSE); gtk_container_border_width(GTK_CONTAINER(table), 6); gtk_table_set_col_spacings(GTK_TABLE(table), 4); gtk_table_set_row_spacings(GTK_TABLE(table), 8); @@ -833,6 +843,71 @@ do_print_dialog(void) gtk_widget_set_events((GtkWidget *)preview, GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + label = gtk_label_new(_("Left:")); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 1, 2, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + left_entry = entry = gtk_entry_new(); + sprintf(s, "%.3f", fabs(vars.left)); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_signal_connect(GTK_OBJECT(entry), "activate", + (GtkSignalFunc)left_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 60, 0); + gtk_widget_show(entry); + + + label = gtk_label_new(_("Top:")); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + top_entry = entry = gtk_entry_new(); + sprintf(s, "%.3f", fabs(vars.top)); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_signal_connect(GTK_OBJECT(entry), "activate", + (GtkSignalFunc)top_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 60, 0); + gtk_widget_show(entry); + + + label = gtk_label_new(_("Right:")); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 1, 2, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + right_entry = entry = gtk_entry_new(); + sprintf(s, "%.3f", fabs(vars.left)); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_entry_set_editable(GTK_ENTRY(entry), FALSE); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 60, 0); + gtk_widget_show(entry); + + + label = gtk_label_new(_("Bottom:")); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + bottom_entry = entry = gtk_entry_new(); + sprintf(s, "%.3f", fabs(vars.left)); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_entry_set_editable(GTK_ENTRY(entry), FALSE); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 60, 0); + gtk_widget_show(entry); + /* * Media size option menu... @@ -934,11 +1009,11 @@ do_print_dialog(void) label = gtk_label_new(_("Output Type:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 2, 3, 6, 7, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 7, 8, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 3, 4, 6, 7, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 7, 8, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); output_gray = button = gtk_radio_button_new_with_label(NULL, _("B&W")); @@ -960,13 +1035,13 @@ do_print_dialog(void) gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); gtk_widget_show(button); - label = gtk_label_new(_("Density:")); + label = gtk_label_new(_("Output Level:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 2, 3, 7, 8, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 10, 11, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 3, 4, 7, 8, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 10, 11, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); linear_off = button = gtk_radio_button_new_with_label(NULL, _("Normal scale")); @@ -994,16 +1069,16 @@ do_print_dialog(void) label = gtk_label_new(_("Scaling:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 11, 12, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 11, 12, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); if (vars.scaling < 0.0) scaling_adjustment = scale_data = - gtk_adjustment_new(-vars.scaling, 50.0, 1201.0, 1.0, 1.0, 1.0); + gtk_adjustment_new(-vars.scaling, 36.0, 1201.0, 1.0, 1.0, 1.0); else scaling_adjustment = scale_data = gtk_adjustment_new(vars.scaling, 5.0, 101.0, 1.0, 1.0, 1.0); @@ -1044,17 +1119,24 @@ do_print_dialog(void) gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); gtk_widget_show(button); + scaling_image = button = gtk_toggle_button_new_with_label(_("Set Image Scale")); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + (GtkSignalFunc)scaling_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + /* * Brightness slider... */ label = gtk_label_new(_("Brightness:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 12, 13, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 9, 10, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 12, 13, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); brightness_adjustment = scale_data = @@ -1085,11 +1167,11 @@ do_print_dialog(void) label = gtk_label_new(_("Gamma:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 10, 11, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 13, 14, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 10, 11, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 13, 14, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); gamma_adjustment = scale_data = @@ -1128,10 +1210,10 @@ do_print_dialog(void) label = gtk_label_new(_("Contrast:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 11, 12, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 14, 15, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 11, 12, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 14, 15, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); contrast_adjustment = scale_data = @@ -1162,11 +1244,11 @@ do_print_dialog(void) label = gtk_label_new(_("Red:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 12, 13, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 15, 16, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 12, 13, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 15, 16, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); red_adjustment = scale_data = @@ -1197,11 +1279,11 @@ do_print_dialog(void) label = gtk_label_new(_("Green:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 13, 14, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 16, 17, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 13, 14, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 16, 17, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); green_adjustment = scale_data = @@ -1232,11 +1314,11 @@ do_print_dialog(void) label = gtk_label_new(_("Blue:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 14, 15, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 17, 18, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 14, 15, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 17, 18, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); blue_adjustment = scale_data = @@ -1267,15 +1349,15 @@ do_print_dialog(void) label = gtk_label_new(_("Saturation:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 15, 16, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 18, 19, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 15, 16, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 18, 19, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); saturation_adjustment = scale_data = - gtk_adjustment_new((float)vars.saturation, 0.1, 10.0, 0.001, 0.01, 1.0); + gtk_adjustment_new((float)vars.saturation, 0.001, 10.0, 0.001, 0.01, 1.0); gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed", (GtkSignalFunc)saturation_update, NULL); @@ -1302,11 +1384,11 @@ do_print_dialog(void) label = gtk_label_new(_("Density:")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 16, 17, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 19, 20, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); box = gtk_hbox_new(FALSE, 8); - gtk_table_attach(GTK_TABLE(table), box, 1, 4, 16, 17, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 19, 20, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(box); density_adjustment = scale_data = @@ -1383,13 +1465,30 @@ do_print_dialog(void) gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(dialog)->action_area), FALSE); gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->action_area), 0); + button = printandsave_button = + gtk_button_new_with_label (_("Print And Save Settings")); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + (GtkSignalFunc) printandsave_callback, + NULL); + gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0); + gtk_widget_grab_default (button); + gtk_widget_show (button); + button = gtk_button_new_with_label (_("Print")); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) print_callback, NULL); gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0); - gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Save Current Settings")); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + (GtkSignalFunc) save_callback, + NULL); + gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0); gtk_widget_show (button); button = gtk_button_new_with_label (_("Cancel")); @@ -1546,7 +1645,8 @@ do_print_dialog(void) * Set printrc options... */ - printrc_save(); + if (saveme) + printrc_save(); /* * Return ok/cancel... @@ -2005,7 +2105,7 @@ scaling_callback(GtkWidget *widget) /* I - Entry widget */ } else if (widget == scaling_ppi) { - GTK_ADJUSTMENT(scaling_adjustment)->lower = 50.0; + GTK_ADJUSTMENT(scaling_adjustment)->lower = 36.0; GTK_ADJUSTMENT(scaling_adjustment)->upper = 1201.0; GTK_ADJUSTMENT(scaling_adjustment)->value = 72.0; vars.scaling = 0.0; @@ -2021,8 +2121,48 @@ scaling_callback(GtkWidget *widget) /* I - Entry widget */ plist[plist_current].v.scaling = vars.scaling; gtk_signal_emit_by_name(scaling_adjustment, "value_changed"); } + else if (widget == scaling_image) + { + double xres, yres; + gimp_image_get_resolution(image_ID, &xres, &yres); + GTK_ADJUSTMENT(scaling_adjustment)->lower = 36.0; + GTK_ADJUSTMENT(scaling_adjustment)->upper = 1201.0; + GTK_ADJUSTMENT(scaling_adjustment)->value = yres; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_ppi), TRUE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_image), FALSE); + vars.scaling = 0.0; + plist[plist_current].v.scaling = vars.scaling; + gtk_signal_emit_by_name(scaling_adjustment, "value_changed"); + } } +static void +top_callback(GtkWidget *widget) +{ + gfloat new_value = atof(gtk_entry_get_text(GTK_ENTRY(widget))); + if (vars.top != new_value) + { + vars.top = new_value * 72; + if (vars.top < 0) + vars.top = 0; + plist[plist_current].v.top = vars.top; + preview_update(); + } +} + +static void +left_callback(GtkWidget *widget) +{ + gfloat new_value = atof(gtk_entry_get_text(GTK_ENTRY(widget))); + if (vars.left != new_value) + { + vars.left = new_value * 72; + if (vars.left < 0) + vars.left = 0; + plist[plist_current].v.left = vars.left; + preview_update(); + } +} /* * 'plist_build_menu()' - Build an option menu for the given parameters... @@ -2109,7 +2249,7 @@ do_misc_updates() float tmp = -plist[plist_current].v.scaling; plist[plist_current].v.scaling = -plist[plist_current].v.scaling; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_ppi), TRUE); - GTK_ADJUSTMENT(scaling_adjustment)->lower = 50.0; + GTK_ADJUSTMENT(scaling_adjustment)->lower = 36.0; GTK_ADJUSTMENT(scaling_adjustment)->upper = 1201.0; sprintf(s, "%.1f", tmp); GTK_ADJUSTMENT(scaling_adjustment)->value = tmp; @@ -2398,6 +2538,26 @@ print_callback(void) gtk_widget_show(file_browser); } +static void +printandsave_callback(void) +{ + runme = TRUE; + saveme = TRUE; + if (plist_current > 0) + { + gtk_widget_destroy(print_dialog); + } + else + gtk_widget_show(file_browser); +} + +static void +save_callback(void) +{ + printrc_save(); + gtk_widget_grab_default(printandsave_button); +} + /* * 'cancel_callback()' - Cancel the print... */ @@ -2560,6 +2720,7 @@ preview_update(void) width, length; /* Physical width */ static GdkGC *gc = NULL; /* Graphics context */ printer_t *p; /* Current printer driver */ + char s[255]; if (preview->widget.window == NULL) @@ -2575,37 +2736,36 @@ preview_update(void) (*p->imageable_area)(p->model, vars.ppd_file, vars.media_size, &left, &right, &bottom, &top); - page_width = 10 * (right - left) / 72; - page_height = 10 * (top - bottom) / 72; + page_width = right - left; + page_height = top - bottom; (*p->media_size)(p->model, vars.ppd_file, vars.media_size, &width, &length); - width = 10 * width / 72; - length = 10 * length / 72; - if (vars.scaling < 0) { - tw0 = -image_width * 10 / vars.scaling; + tw0 = 72 * -image_width / vars.scaling; th0 = tw0 * image_height / image_width; tw1 = tw0; th1 = th0; } else { + /* Portrait */ tw0 = page_width * vars.scaling / 100; th0 = tw0 * image_height / image_width; - if (th0 > page_height) + if (th0 > page_height * vars.scaling / 100) { - th0 = page_height; + th0 = page_height * vars.scaling / 100; tw0 = th0 * image_width / image_height; } ta0 = tw0 * th0; + /* Landscape */ tw1 = page_height * vars.scaling / 100; th1 = tw1 * image_height / image_width; - if (th1 > page_width) + if (th1 > page_width * vars.scaling / 100) { - th1 = page_width; + th1 = page_width * vars.scaling / 100; tw1 = th1 * image_width / image_height; } ta1 = tw1 * th1; @@ -2615,18 +2775,42 @@ preview_update(void) { if (vars.scaling < 0) { - if ((th0 > page_height && tw0 <= page_height) || - (tw0 > page_width && th0 <= page_width)) - orient = ORIENT_LANDSCAPE; - else + if ((page_width > page_height && tw0 > th0) || + (page_height > page_width && th0 > tw0)) + { orient = ORIENT_PORTRAIT; + if (tw0 > page_width) + { + vars.scaling *= (double) page_width / (double) tw0; + th0 = th0 * page_width / tw0; + } + if (th0 > page_height) + { + vars.scaling *= (double) page_height / (double) th0; + tw0 = tw0 * page_height / th0; + } + } + else + { + orient = ORIENT_LANDSCAPE; + if (tw1 > page_height) + { + vars.scaling *= (double) page_height / (double) tw1; + th1 = th1 * page_height / tw1; + } + if (th1 > page_width) + { + vars.scaling *= (double) page_width / (double) th1; + tw1 = tw1 * page_width / th1; + } + } } else { if (ta0 >= ta1) - orient = ORIENT_PORTRAIT; + orient = ORIENT_PORTRAIT; else - orient = ORIENT_LANDSCAPE; + orient = ORIENT_LANDSCAPE; } } else @@ -2649,46 +2833,65 @@ preview_update(void) print_height = th0; } - page_left = (PREVIEW_SIZE - page_width) / 2; - page_top = (PREVIEW_SIZE - page_height) / 2; + page_left = (PREVIEW_SIZE - 10 * page_width / 72) / 2; + page_top = (PREVIEW_SIZE - 10 * page_height / 72) / 2; gdk_draw_rectangle(preview->widget.window, gc, 0, - (PREVIEW_SIZE - width) / 2, - (PREVIEW_SIZE - length) / 2, - width, length); + (PREVIEW_SIZE - (10 * width / 72)) / 2, + (PREVIEW_SIZE - (10 * length / 72)) / 2, + 10 * width / 72, 10 * length / 72); if (vars.left < 0) - left = (page_width - print_width) / 2; - else - { - left = 10 * vars.left / 72; + vars.left = (page_width - print_width) / 2; - if (left > (page_width - print_width)) + left = vars.left; + + if (left > (page_width - print_width)) { left = page_width - print_width; - vars.left = 72 * left / 10; + vars.left = left; plist[plist_current].v.left = vars.left; } - } if (vars.top < 0) - top = (page_height - print_height) / 2; - else - { - top = 10 * vars.top / 72; + vars.top = (page_height - print_height) / 2; + top = vars.top; - if (top > (page_height - print_height)) + if (top > (page_height - print_height)) { top = page_height - print_height; - vars.top = 72 * top / 10; + vars.top = top; plist[plist_current].v.top = vars.top; } - } + + sprintf(s, "%.3f", vars.top / 72.0); + gtk_signal_handler_block_by_data(GTK_OBJECT(top_entry), NULL); + gtk_entry_set_text(GTK_ENTRY(top_entry), s); + gtk_signal_handler_unblock_by_data(GTK_OBJECT(top_entry), NULL); + + sprintf(s, "%.3f", vars.left / 72.0); + gtk_signal_handler_block_by_data(GTK_OBJECT(left_entry), NULL); + gtk_entry_set_text(GTK_ENTRY(left_entry), s); + gtk_signal_handler_unblock_by_data(GTK_OBJECT(left_entry), NULL); + + if (vars.scaling < 0) + sprintf(s, "%.3f", + (vars.top + (image_height * -72.0 / vars.scaling)) / 72.0); + else + sprintf(s, "%.3f", (vars.top + print_height) / 72.0); + gtk_entry_set_text(GTK_ENTRY(bottom_entry), s); + + if (vars.scaling < 0) + sprintf(s, "%.3f", + (vars.left + (image_width * -72.0 / vars.scaling)) / 72.0); + else + sprintf(s, "%.3f", (vars.left + print_width) / 72.0); + gtk_entry_set_text(GTK_ENTRY(right_entry), s); gdk_draw_rectangle(preview->widget.window, gc, 1, - page_left + left, page_top + top, - print_width, print_height); + page_left + 10 * left / 72, page_top + 10 * top / 72, + 10 * print_width / 72, 10 * print_height / 72); gdk_flush(); } @@ -2798,7 +3001,7 @@ printrc_load(void) int keepgoing = 1; if (line[0] == '#') continue; /* Comment */ - + initialize_printer(&key); /* * Read the command-delimited printer definition data. Note that * we can't use sscanf because %[^,] fails if the string is empty... @@ -3003,18 +3206,40 @@ printrc_load(void) lineptr = commaptr + 1; } - if ((p = bsearch(&key, plist + 1, plist_count - 1, sizeof(plist_t), - (int (*)(const void *, const void *))compare_printers)) != NULL) +/* + * The format of the list is the File printer followed by a qsort'ed list + * of system printers. So, if we want to update the file printer, it is + * always first in the list, else call bsearch. + */ + if ((strcmp(key.name, _("File")) == 0) && (strcmp(plist[0].name, + _("File")) == 0)) { +#ifdef DEBUG + printf("Updated File printer directly\n"); +#endif + p = &plist[0]; memcpy(p, &key, sizeof(plist_t)); p->active = 1; } - else if (plist_count < MAX_PLIST - 1) + else { - p = plist + plist_count; - memcpy(p, &key, sizeof(plist_t)); - p->active = 0; - plist_count++; + if ((p = bsearch(&key, plist + 1, plist_count - 1, sizeof(plist_t), + (int (*)(const void *, const void *))compare_printers)) + != NULL) + { +#ifdef DEBUG + printf("Updating printer %s.\n", key.name); +#endif + memcpy(p, &key, sizeof(plist_t)); + p->active = 1; + } + else if (plist_count < MAX_PLIST - 1) + { + p = plist + plist_count; + memcpy(p, &key, sizeof(plist_t)); + p->active = 0; + plist_count++; + } } } @@ -3056,7 +3281,6 @@ printrc_save(void) * Generate the filename for the current user... */ - filename = gimp_personal_rc_file ("printrc"); #ifdef __EMX__ _fnslashify(filename); @@ -3074,7 +3298,7 @@ printrc_save(void) fputs("#PRINTRC " PLUG_IN_VERSION "\n", fp); - for (i = 1, p = plist + 1; i < plist_count; i ++, p ++) + for (i = 0, p = plist; i < plist_count; i ++, p ++) fprintf(fp, "%s,%s,%s,%s,%d,%s,%s,%s,%s,%d,%.3f,%d,%d,%d,%.3f,%d,%d,%d,%d,%d,%.3f,%.3f\n", p->name, p->v.output_to, p->v.driver, p->v.ppd_file, p->v.output_type, p->v.resolution, p->v.media_size, @@ -3109,9 +3333,11 @@ static void get_printers(void) { int i; + char defname[17]; +#if defined(LPC_COMMAND) || defined(LPSTAT_COMMAND) FILE *pfile; - char line[129], - defname[17]; + char line[129], name[17]; +#endif #ifdef __EMX__ BYTE pnum; #endif @@ -3120,18 +3346,19 @@ get_printers(void) defname[0] = '\0'; memset(plist, 0, sizeof(plist)); + plist_count = 1; strcpy(plist[0].name, _("File")); plist[0].v.output_to[0] = '\0'; strcpy(plist[0].v.driver, "ps2"); - initialize_printer(&plist[0]); - plist_count = 1; + plist[0].v.output_type = OUTPUT_COLOR; #ifdef LPC_COMMAND - if ((pfile = popen(LPC_COMMAND " status", "r")) != NULL) + if ((pfile = popen(LPC_COMMAND " status < /dev/null", "r")) != NULL) { while (fgets(line, sizeof(line), pfile) != NULL && plist_count < MAX_PLIST) - if (strchr(line, ':') != NULL && line[0] != ' ' && line[0] != '\t') + if (strchr(line, ':') != NULL && line[0] != ' ' && + line[0] != '\t' && strncmp(line,"Press RETURN to continue",24)) { *strchr(line, ':') = '\0'; strcpy(plist[plist_count].name, line); @@ -3148,8 +3375,6 @@ get_printers(void) #ifdef LPSTAT_COMMAND if ((pfile = popen(LPSTAT_COMMAND " -d -p", "r")) != NULL) { - char name[17]; - while (fgets(line, sizeof(line), pfile) != NULL && plist_count < MAX_PLIST) {