This file is part of Aladdin Ghostscript.
Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
or distributor accepts any responsibility for the consequences of using it,
or for whether it serves any particular purpose or works at all, unless he
or she says so in writing. Refer to the Aladdin Ghostscript Free Public
License (the "License") for full details.
Every copy of Aladdin Ghostscript must include a copy of the License,
normally in a plain ASCII text file named PUBLIC. The License grants you
the right to copy, modify and redistribute Aladdin Ghostscript, but only
under certain conditions described in the License. Among other things, the
License requires that the copyright notice and this notice be preserved on
all copies.
*/
* 1999-04-18 Ver. 0.1 Masakazu Higaki <higamasa@dd.mbn.or.jp>
* 1999-05-02 Ver. 0.2a
*/
#include "gdevprn.h"
#include "gsparam.h"
#include <stdlib.h>
#include <limits.h>
#define MM_PER_INCH 25.4f
#define TOP_MARGIN 12.f / MM_PER_INCH
#define BOTTOM_MARGIN 15.f / MM_PER_INCH
#define LEFT_MARGIN 3.4f / MM_PER_INCH
#define RIGHT_MARGIN 3.4f / MM_PER_INCH
static dev_proc_open_device(alps_open);
static dev_proc_get_params(alps_get_params);
static dev_proc_put_params(alps_put_params);
static dev_proc_print_page(md2k_print_page);
static dev_proc_print_page(md5k_print_page);
static dev_proc_map_cmyk_color(alps_map_cmyk_color);
static dev_proc_map_cmyk_color(alps_map_cmy_color);
static dev_proc_map_rgb_color(alps_map_rgb_color);
static dev_proc_map_color_rgb(alps_map_color_rgb);
struct gx_device_alps_s {
gx_device_common;
gx_prn_device_common;
bool color;
bool dither;
bool manualFeed;
bool reverseSide;
bool ecoBlack;
int mediaType;
int cyan;
int magenta;
int yellow;
int black;
};
typedef struct gx_device_alps_s gx_device_alps;
#define dev_alps ((gx_device_alps *) pdev)
static void
alps_initialize_device_procs(gx_device *dev)
{
gdev_prn_initialize_device_procs(dev);
set_dev_proc(dev, open_device, alps_open);
set_dev_proc(dev, map_color_rgb, alps_map_color_rgb);
set_dev_proc(dev, get_params, alps_get_params);
set_dev_proc(dev, put_params, alps_put_params);
set_dev_proc(dev, map_cmyk_color, alps_map_cmyk_color);
* encode_color and decode_color set to NULL (which are then rewritten
* by the system to the default. For compatibility we do the same. */
set_dev_proc(dev, encode_color, NULL);
set_dev_proc(dev, decode_color, NULL);
}
#define alps_device(dname, print_page) \
{\
prn_device_body(gx_device_alps, alps_initialize_device_procs, dname,\
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,\
600, 600,\
0, 0, 0, 0, \
4, 0, 0, 0, 0, 0, print_page),\
true, false, false, false, false, 0, 1024, 1024, 1024, 1024\
}
gx_device_alps far_data gs_md2k_device = alps_device("md2k", md2k_print_page);
gx_device_alps far_data gs_md5k_device = alps_device("md5k", md5k_print_page);
typedef enum {
MD2000,
MD1000,
MD5000
} alps_printer_type;
static int
alps_open(gx_device *pdev)
{
int xdpi = (int)pdev->x_pixels_per_inch;
int ydpi = (int)pdev->y_pixels_per_inch;
const float margins[4] = {
LEFT_MARGIN,
BOTTOM_MARGIN,
RIGHT_MARGIN,
TOP_MARGIN
};
float density;
gx_device_set_margins(pdev, margins, true);
if ((ydpi != 300 || xdpi != 300)
&& (ydpi != 600 || xdpi != 600)
&& (ydpi != 600 || xdpi != 1200))
return_error(gs_error_rangecheck);
density = (xdpi == 300 ? 0.75 : xdpi == 600 ? 0.44 : 0.4);
dev_alps->cyan = (int)(dev_alps->cyan * density);
dev_alps->magenta = (int)(dev_alps->magenta * density);
dev_alps->yellow = (int)(dev_alps->yellow * density);
dev_alps->black = (int)(dev_alps->black * density);
return gdev_prn_open(pdev);
}
static int
alps_get_params(gx_device *pdev, gs_param_list *plist)
{
gs_param_string mediaType = { (unsigned char *)"", 1, false };
int code = gdev_prn_get_params(pdev, plist);
if (code < 0 ||
(code = param_write_bool(plist, "Color", &dev_alps->color)) < 0 ||
(code = param_write_bool(plist, "Dither", &dev_alps->dither)) < 0 ||
(code = param_write_bool(plist, "ManualFeed",
&dev_alps->manualFeed)) < 0 ||
(code = param_write_bool(plist, "ReverseSide",
&dev_alps->reverseSide)) < 0 ||
(code = param_write_bool(plist, "EcoBlack",
&dev_alps->ecoBlack)) < 0 ||
(code = param_write_int (plist, "Cyan", &dev_alps->cyan)) < 0 ||
(code = param_write_int (plist, "Magenta", &dev_alps->magenta)) < 0 ||
(code = param_write_int (plist, "Yellow", &dev_alps->yellow)) < 0 ||
(code = param_write_int (plist, "Black", &dev_alps->black)) < 0 ||
(code = param_write_string(plist, "MediaType", &mediaType)) < 0)
return code;
return code;
}
static int
alps_put_param_bool(gs_param_list *plist, gs_param_name pname, int *pvalue,
int ecode)
{
int code, value;
switch (code = param_read_bool(plist, pname, &value)) {
default:
return code;
case 1:
return ecode;
case 0:
*pvalue = value;
return (ecode < 0 ? ecode : 1);
}
}
static int
alps_put_param_int(gs_param_list *plist, gs_param_name pname, int *pvalue,
int minval, int maxval, int ecode)
{
int code, value;
switch (code = param_read_int(plist, pname, &value)) {
default:
return code;
case 1:
return ecode;
case 0:
if (value < minval || value > maxval)
param_signal_error(plist, pname, gs_error_rangecheck);
*pvalue = value;
return (ecode < 0 ? ecode : 1);
}
}
static int
alps_put_params(gx_device *pdev, gs_param_list *plist)
{
int code = 0;
int bpp = dev_alps->color_info.depth;
bool color = dev_alps->color;
bool dither = dev_alps->dither;
bool manualFeed = dev_alps->manualFeed;
bool reverseSide = dev_alps->reverseSide;
bool ecoBlack = dev_alps->ecoBlack;
int cyan = dev_alps->cyan;
int magenta = dev_alps->magenta;
int yellow = dev_alps->yellow;
int black = dev_alps->black;
gs_param_string mediaType;
code = alps_put_param_bool(plist, "Color", &color, code);
code = alps_put_param_bool(plist, "Dither", &dither, code);
code = alps_put_param_bool(plist, "ManualFeed", &manualFeed, code);
code = alps_put_param_bool(plist, "ReverseSide", &reverseSide, code);
code = alps_put_param_bool(plist, "EcoBlack", &ecoBlack, code);
code = alps_put_param_int (plist, "BitsPerPixel", &bpp, 1, 32, code);
code = alps_put_param_int (plist, "Cyan", &cyan, 0, 2048, code);
code = alps_put_param_int (plist, "Magenta", &magenta, 0, 2048, code);
code = alps_put_param_int (plist, "Yellow", &yellow, 0, 2048, code);
code = alps_put_param_int (plist, "Black", &black, 0, 2048, code);
#define mediaTypeCmp(mname) strncmp((const char *)mediaType.data, mname, mediaType.size)
if (param_read_string(plist, "MediaType", &mediaType) == 0) {
dev_alps->mediaType
= (! mediaTypeCmp("PlainPaper" ) ? 0
: ! mediaTypeCmp("OHP_MD2000" ) ? 1
: ! mediaTypeCmp("IronSeal" ) ? 2
: ! mediaTypeCmp("RebecaFree" ) ? 3
: ! mediaTypeCmp("CardBoard" ) ? 5
: ! mediaTypeCmp("PostCard" ) ? 6
: ! mediaTypeCmp("FinePaper" ) ? 7
: ! mediaTypeCmp("CoatedFilm" ) ? 9
: ! mediaTypeCmp("GlossyPaper" ) ? 15
: ! mediaTypeCmp("TransparencyFilm") ? 0x108
: ! mediaTypeCmp("OHP" ) ? 0x108 : -1);
switch (dev_alps->mediaType) {
case -1:
param_signal_error(plist, "MediaType", code = gs_error_rangecheck);
break;
case 1:
dev_proc(pdev, map_cmyk_color) = alps_map_cmy_color;
break;
case 6:
pdev->MediaSize[0] = 284;
pdev->MediaSize[1] = 419;
default:
break;
}
}
if (code < 0)
return code;
dev_alps->color = color;
dev_alps->dither = dither;
dev_alps->manualFeed = manualFeed;
dev_alps->reverseSide = reverseSide;
dev_alps->ecoBlack = ecoBlack;
dev_alps->cyan = cyan;
dev_alps->magenta = magenta;
dev_alps->yellow = yellow;
dev_alps->black = black;
if (bpp)
bpp = (bpp < 4 ? 1 : bpp < 8 ? 4 : bpp > 8 ? 32 : 8);
else
bpp = (color ? 4 : 1) * (dither ? 8 : 1);
if (ecoBlack && ! strcmp(pdev->dname, "md5k"))
bpp = 1;
if (bpp == 1 || bpp == 8)
dev_proc(pdev, map_rgb_color) = alps_map_rgb_color;
pdev->color_info.depth = bpp;
pdev->color_info.num_components = (bpp == 1 || bpp == 8 ? 1 : 4);
pdev->color_info.max_gray = (bpp >= 8 ? 255 : 1);
pdev->color_info.max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
pdev->color_info.dither_grays = (bpp >= 8 ? 5 : 2);
pdev->color_info.dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
gdev_prn_put_params(pdev, plist);
return 0;
}
* these F/S dithering macros are based on gdevcdj.c
*/
* subjective image quality, but can also produce dramatic increases in
* amount of printer data generated and actual printing time!! Mode 9 2D
* compression is still useful for fairly flat color or blank areas but its
* compression is much less effective in areas where the dithering has
* effectively randomised the dot distribution. */
#define I sizeof(int)
#define SHIFT ((I * 8) - 13)
#define RSHIFT ((I * 8) - 16)
#define RANDOM() (((rand() << RSHIFT) % (MAXVALUE / 2)) - MAXVALUE / 4);
#define MINVALUE 0
#define MAXVALUE (255 << SHIFT)
#define THRESHOLD (128 << SHIFT)
#define C 8
#define FSdither(inP, out, errP, Err, Bit, Offset)\
oldErr = Err;\
Err = (*errP + ((Err * 7 + C) >> 4) + (*inP << SHIFT));\
inP += Offset;\
if (Err > THRESHOLD) {\
out |= Bit;\
Err -= MAXVALUE;\
}\
errP[-Offset] += ((Err * 3 + C) >> 4);\
*errP++ = ((Err * 5 + oldErr + C) >> 4);
#define FSDline(i, j, len, outP, n)\
{\
byte c, bitmask;\
int Err = 0, oldErr;\
for (i = 0; i < len; i++) {\
bitmask = 0x80;\
for (c = j = 0; j < 8; j++) {\
FSdither(dp, c, ep, Err, bitmask, n);\
bitmask >>= 1;\
}\
*outP++ = c;\
}\
}
* get a component of CMYK from raster data
*/
static int
cmyk_to_bit(byte *out, byte *in, int length, int c_comp)
{
byte *p_in = in, *p_out = out, *p_end;
byte in_data, out_data;
byte mask1, mask2;
p_end = in + length;
mask1 = 0x80 >> c_comp;
mask2 = mask1 >> 4;
while(p_in < p_end) {
int i;
out_data = 0;
for(i = 0; i < 4; i ++) {
in_data = (p_in < p_end ? *p_in++ : 0);
out_data <<= 2;
out_data |= (in_data & mask1) >> (6-c_comp)
| (in_data & mask2) >> (3-c_comp);
}
*p_out ++ = out_data;
}
return p_out - out;
}
* run-length compression
*/
static int
runlength(byte *out, byte *in, int length)
{
byte *p_in = in, *p_out = out, *p_end;
int count, climit, contflag;
p_end = p_in + length;
while(p_in < p_end) {
count = 0;
climit = min(128, p_end - p_in);
for( ; count < climit; count++, p_in ++) {
contflag = (*p_in == *(p_in+1) && *p_in == *(p_in+2));
if (contflag)
break;
}
if (count > 0) {
*p_out ++ = count - 1;
memcpy(p_out, p_in - count, count);
p_out += count;
}
if (contflag) {
climit = min(129, p_end - p_in);
p_in += 3;
count = 3;
for( ; count < climit && *(p_in-1) == *p_in; count++, p_in++);
*p_out ++ = (byte) (0x101 - count);
*p_out ++ = *(p_in-1);
}
}
return p_out - out;
}
static void write_short(unsigned data, gp_file* stream)
{
gp_fputc((unsigned char) (data), stream);
gp_fputc((unsigned short) (data) >> 8, stream);
}
static void alps_cmd(const char* cmd1, unsigned data, int cmd2, gp_file* stream)
{
gp_fwrite(cmd1, 1, 3, stream);
write_short(data, stream);
gp_fputc(cmd2, stream);
}
static void
alps_init(gx_device_printer *pdev, gp_file *prn_stream, alps_printer_type ptype)
{
short height;
gp_fwrite("\033\145"
"\033\045\200\101"
"\033\032\0\0\114", 1, 11, prn_stream);
alps_cmd("\033\046\154", (dev_alps->manualFeed ? 2 : 1), 0110, prn_stream);
alps_cmd("\033\046\154", dev_alps->mediaType, 0115, prn_stream);
alps_cmd("\033\046\154", (pdev->MediaSize[0] == 612) ? 2 :
(pdev->MediaSize[0] >= 595 &&
pdev->MediaSize[0] <= 598) ? 4 :
(pdev->MediaSize[0] == 516 ||
pdev->MediaSize[0] == 501) ? 5 :
(pdev->MediaSize[0] == 284) ? 6 : 0,
0101, prn_stream);
gp_fwrite("\033\052\162", 1, 3, prn_stream);
gp_fputc((dev_alps->mediaType == 1 ? 4 :
pdev->color_info.num_components == 1 ? dev_alps->ecoBlack ? 1 : 0
: ptype == MD5000 ? 8 : 4),
prn_stream);
gp_fputc(0125, prn_stream);
gp_fwrite("\033\052\164", 1, 3, prn_stream);
gp_fputc((pdev->x_pixels_per_inch == 300 ? 2
: pdev->x_pixels_per_inch == 600 ? 3 : 4), prn_stream);
gp_fputc(0122, prn_stream);
height = (short)((pdev->MediaSize[1] - pdev->HWMargins[1] - pdev->HWMargins[3])
* pdev->y_pixels_per_inch / 72.);
alps_cmd("\033\046\154", height, 0120, prn_stream);
gp_fwrite("\033\032", 1, 2, prn_stream);
gp_fputc (dev_alps->reverseSide, prn_stream);
gp_fwrite("\0\101", 1, 2, prn_stream);
if (ptype == MD5000) {
if (dev_alps->ecoBlack) {
gp_fwrite("\033\032\001\0\103", 1, 5, prn_stream);
gp_fwrite("\033\046\154\001\0\103\027", 1, 7, prn_stream);
} else if (pdev->color_info.num_components == 1)
gp_fwrite("\033\046\154\001\0\103\0", 1, 7, prn_stream);
else
gp_fwrite("\033\046\154\004\0\103\003\002\001\0", 1, 10, prn_stream);
gp_fwrite("\033\032\0\0\125", 1, 5, prn_stream);
gp_fwrite("\033\052\162\1\101", 1, 5, prn_stream);
gp_fwrite("\033\052\142\0\0\115", 1, 6, prn_stream);
} else {
gp_fwrite("\033\052\162\0\101", 1, 5, prn_stream);
gp_fwrite("\033\052\142\2\0\115", 1, 6, prn_stream);
}
}
static int
alps_print_page(gx_device_printer *pdev, gp_file *prn_stream,
alps_printer_type ptype)
{
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
byte *in, *out, *work, *dp, *outP;
int y, y_height = pdev->height;
int c_comp, num_comp = pdev->color_info.num_components;
int n_comp = (dev_alps->mediaType == 1 ? 3 : num_comp);
int *error, *ep;
int i, j, code = 0;
work = (byte *)gs_malloc(pdev->memory->non_gc_memory, 3+sizeof(int), line_size,
"alps_print_page(work)");
if (work == 0)
return_error(gs_error_VMerror);
in = work + line_size;
out = in + line_size;
error = (int *)(out + line_size);
alps_init(pdev, prn_stream, ptype);
for(c_comp = 0; c_comp < n_comp; c_comp ++) {
int yskip = 0;
int color_weight;
for(i = 0; i < line_size; i ++)
error[i] = RANDOM();
if (n_comp == 1)
color_weight = dev_alps->black;
else
color_weight = (c_comp < 2
? c_comp == 0 ? dev_alps->cyan : dev_alps->magenta
: c_comp == 2 ? dev_alps->yellow : dev_alps->black);
gold=4, metalic red=5, metalic blue=6, silver=7,
rebeca black=8, rebeca red=9, rebeca blue=10,
white=11, glossy=14) */
gp_fwrite("\033\032", 1, 2, prn_stream);
gp_fputc((n_comp == 1 ? dev_alps->ecoBlack ? 026 : 0 : (c_comp+1) % 4),
prn_stream);
gp_fputc((c_comp == n_comp-1 && ptype == MD5000 ? 0200 : 0),
prn_stream);
gp_fputc(0162, prn_stream);
for(y = 0; y < y_height; y ++) {
uint len = line_size;
code = gdev_prn_get_bits(pdev, y, in, &dp);
if (code < 0)
return code;
switch (pdev->color_info.depth) {
case 4:
len = cmyk_to_bit(work, dp, len, c_comp);
dp = work;
case 1:
for( ; len > 0 && dp[len-1] == 0; len --);
break;
case 32:
dp += c_comp;
case 8:
outP = work;
ep = error;
for( ; len > 0 && dp[len-num_comp] == 0; len -= num_comp);
for(i = 0; i < len; i += num_comp)
dp[i] = (dp[i] * color_weight) >> 10;
len = (len / num_comp + 7) >> 3;
FSDline(i, j, len, outP, num_comp);
dp = work;
break;
}
if (len == 0)
yskip ++;
else {
if (yskip) {
alps_cmd("\033\052\142", yskip, 0131, prn_stream);
yskip = 0;
}
if (ptype == MD5000) {
int xskip = 0;
for( ; len > 0 && *dp == 0; len --, dp ++, xskip ++)
{}
alps_cmd("\033\052\142", len, 0124, prn_stream);
write_short(xskip, prn_stream);
gp_fwrite(dp, 1, len, prn_stream);
} else {
len = runlength(out, dp, len);
alps_cmd("\033\052\142", len, 0127, prn_stream);
gp_fwrite(out, 1, len, prn_stream);
}
}
}
if (c_comp + 1 < n_comp)
gp_fwrite("\033\032\0\0\014", 1, 5, prn_stream);
}
gp_fwrite("\014"
"\033\052\162\103"
"\033\045\0\130", 1, 9, prn_stream);
gs_free(pdev->memory->non_gc_memory, (char *)work, 3+sizeof(int), line_size, "alps_print_page(work)");
return 0;
}
static int
md2k_print_page(gx_device_printer *pdev, gp_file *prn_stream)
{
return alps_print_page(pdev, prn_stream, MD2000);
}
static int
md5k_print_page(gx_device_printer *pdev, gp_file *prn_stream)
{
return alps_print_page(pdev, prn_stream, MD5000);
}
* Map a CMYK color to a color index. We just use depth / 4 bits per color
* to produce the color index.
*/
#define gx_color_value_to_bits(cv, b) \
((cv) >> (gx_color_value_bits - (b)))
#define gx_bits_to_color_value(cv, b) \
((cv) << (gx_color_value_bits - (b)))
#define gx_cmyk_value_bits(c, m, y, k, b) \
((gx_color_value_to_bits((c), (b)) << (3 * (b))) | \
(gx_color_value_to_bits((m), (b)) << (2 * (b))) | \
(gx_color_value_to_bits((y), (b)) << (b)) | \
(gx_color_value_to_bits((k), (b))))
#define gx_value_cmyk_bits(v, c, m, y, k, b) \
(c) = gx_bits_to_color_value(((v) >> (3 * (b))) & ((1 << (b)) - 1), (b)), \
(m) = gx_bits_to_color_value(((v) >> (2 * (b))) & ((1 << (b)) - 1), (b)), \
(y) = gx_bits_to_color_value(((v) >> (b)) & ((1 << (b)) - 1), (b)), \
(k) = gx_bits_to_color_value((v) & ((1 << (b)) - 1), (b))
static gx_color_index
alps_map_cmyk_color(gx_device* pdev,
const gx_color_value cv[])
{
gx_color_index color;
gx_color_value c, m, y, k;
c = cv[0]; m = cv[1]; y = cv[2]; k = cv[3];
switch (pdev->color_info.depth) {
case 1:
color = ((c | m | y | k) > gx_max_color_value / 2 ?
(gx_color_index) 1 : (gx_color_index) 0);
break;
default:
{
int nbits = pdev->color_info.depth;
ulong weight;
ulong black = (c <= y ? c <= m ? c : m : m <= y ? m : y);
weight = (black < gx_max_color_value
? (gx_max_color_value << 10) / (gx_max_color_value - black)
: 0);
c = ((c - black) * weight) >> 10;
m = ((m - black) * weight) >> 10;
y = ((y - black) * weight) >> 10;
black += k;
k = (gx_color_index) (black <= gx_max_color_value
? black : gx_max_color_value);
color = gx_cmyk_value_bits(c, m, y, k, nbits >> 2);
}
}
return color;
}
static gx_color_index
alps_map_cmy_color(gx_device* pdev,
const gx_color_value cv[])
{
int nbits = pdev->color_info.depth;
gx_color_value c = cv[0], m = cv[1], y = cv[2], k = cv[3];
ulong weight = ((gx_max_color_value - k) << 10) / gx_max_color_value;
c = ((c * weight) >> 10) + k;
m = ((m * weight) >> 10) + k;
y = ((y * weight) >> 10) + k;
if (c > gx_max_color_value) c = gx_max_color_value;
if (m > gx_max_color_value) m = gx_max_color_value;
if (y > gx_max_color_value) y = gx_max_color_value;
return gx_cmyk_value_bits(c, m, y, 0, nbits >> 2);
}
static gx_color_index
alps_map_rgb_color(gx_device *pdev,
const gx_color_value cv[])
{
gx_color_value r, g, b;
r = cv[0]; g = cv[1]; b = cv[2];
if (gx_color_value_to_byte(r & g & b) == 0xff) {
return (gx_color_index) 0;
} else {
gx_color_value c = gx_max_color_value - r;
gx_color_value m = gx_max_color_value - g;
gx_color_value y = gx_max_color_value - b;
switch (pdev->color_info.depth) {
case 1:
return ((c | m | y) > gx_max_color_value / 2 ?
(gx_color_index) 1 : (gx_color_index) 0);
break;
case 8:
#define red_weight 306
#define green_weight 601
#define blue_weight 117
return ((ulong)c * red_weight
+ (ulong)m * green_weight
+ (ulong)y * blue_weight)
>> (gx_color_value_bits + 2);
break;
}
}
return (gx_color_index) 0;
}
static int
alps_map_color_rgb(gx_device *pdev,
gx_color_index color, gx_color_value prgb[3])
{
switch (pdev->color_info.depth) {
case 1:
prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color);
break;
case 8:
if (pdev->color_info.num_components == 1) {
gx_color_value value = (gx_color_value) color ^ 0xff;
prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
break;
}
default:
{
unsigned long bcyan, bmagenta, byellow, black;
int nbits = pdev->color_info.depth;
gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black,
nbits >> 2);
#ifdef USE_ADOBE_CMYK_RGB
bcyan += black, bmagenta += black, byellow += black;
prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 :
gx_max_color_value - bcyan);
prgb[1] = (bmagenta > gx_max_color_value ? (gx_color_value) 0 :
gx_max_color_value - bmagenta);
prgb[2] = (byellow > gx_max_color_value ? (gx_color_value) 0 :
gx_max_color_value - byellow);
#else
prgb[0] = (gx_color_value)
((ulong)(gx_max_color_value - bcyan) *
(gx_max_color_value - black) / gx_max_color_value);
prgb[1] = (gx_color_value)
((ulong)(gx_max_color_value - bmagenta) *
(gx_max_color_value - black) / gx_max_color_value);
prgb[2] = (gx_color_value)
((ulong)(gx_max_color_value - byellow) *
(gx_max_color_value - black) / gx_max_color_value);
#endif
}
}
return 0;
}