⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eprnrend.c

📁 openmeetings组件之GS openmeetings组件之GS openmeetings组件之GS
💻 C
📖 第 1 页 / 共 3 页
字号:
  Function: eprn_map_color_rgb  This function is a 'map_color_rgb' method.  Such a method should return an RGB triple for the specified 'color'. This is  apparently intended for devices supporting colour maps.  The function param_HWColorMap() in gsdparam.c tries to compile such a  colour map by calling this method repeatedly for all values from 0 to  2^color_info.depth - 1, provided the depth is less than or equal to 8 and  the process colour model is not DeviceCMYK. If the function for one of these  values returns a negative code, the assumption seems to be that there is no  such colour map. Because there is a default method which always returns zero,  such a colour map is always constructed if a device does not implement its  own 'map_color_rgb' method. This can be seen in the appearance of the  "HWColorMap" page device parameter.  The key purpose of this function is therefore to return a negative code.******************************************************************************/int eprn_map_color_rgb(gx_device *device, gx_color_index color,  gx_color_value rgb[]){#ifdef EPRN_TRACE  if_debug1(EPRN_TRACE_CHAR,    "! eprn_map_color_rgb() called for 0x%lX.\n", (unsigned long)color);#endif  /* Just to be safe we return defined values (white) */  if (((eprn_Device *)device)->eprn.colour_model == eprn_DeviceRGB)    rgb[0] = rgb[1] = rgb[2] = gx_max_color_value;  else    rgb[0] = rgb[1] = rgb[2] = 0;  return -1;}/******************************************************************************  Function: eprn_map_cmyk_color  Colour mapping function for a process colour model of 'DeviceCMYK' with  2 intensity levels for all colorants.******************************************************************************/gx_color_index eprn_map_cmyk_color(gx_device *device,  const gx_color_value cv[]){  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];  gx_color_index value = 0;  static const gx_color_value threshold = gx_max_color_value/2;#ifdef EPRN_TRACE  if_debug4(EPRN_TRACE_CHAR,    "! eprn_map_cmyk_color() called for CMYK = (%hu, %hu, %hu, %hu),\n",      cyan, magenta, yellow, black);#endif  if (cyan    > threshold) value |= CYAN_BIT;  if (magenta > threshold) value |= MAGENTA_BIT;  if (yellow  > threshold) value |= YELLOW_BIT;  if (black   > threshold) value |= BLACK_BIT;#ifdef EPRN_TRACE  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%lX.\n", (unsigned long)value);#endif  return value;}/******************************************************************************  Function: eprn_map_cmyk_color_flex  This is a 'map_cmyk_color' method supporting arbitrary numbers of intensity  levels. It may be called for every colour model except DeviceRGB. Colorants  not present in the model will be ignored.******************************************************************************/gx_color_index eprn_map_cmyk_color_flex(gx_device *device,  const gx_color_value cv[]){  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];  gx_color_index value = 0;  gx_color_value step;  unsigned int level;  const eprn_Eprn *eprn = &((eprn_Device *)device)->eprn;#ifdef EPRN_TRACE  if_debug4(EPRN_TRACE_CHAR,    "! eprn_map_cmyk_color_flex() called for CMYK = (%hu, %hu, %hu, %hu),\n",      cyan, magenta, yellow, black);#endif  /*  I can think of three linear methods to extract discrete values from a      continuous intensity in the range [0, 1]:      (a) multiply by the number of levels minus 1 and truncate,      (b) multiply by the number of levels minus 1 and round, and      (c) multiply by the number of levels and truncate, except for an	  intensity of 1 in which case one returns the number of levels minus 1.      For intensity values which can be represented exactly, i.e.,	intensity = i/(levels-1)	for some non-negative i < levels,      these three methods are identical. (a) is however inappropriate here      because for less than 32 levels ghostscript already provides intensity      values which have been adjusted to a representable level. A rounding      error could now result in a level which is too small by one. I prefer (c)      because it gives equal shares to all levels.      I'm using integer arithmetic here although floating point numbers would      be more accurate. This routine may, however, be called quite frequently,      and the loss in accuray is acceptable as long as the values determined      for 'step' are large compared to the number of levels. If you consider      "large" as meaning "10 times as large", the critical boundary is at about      81 levels. The highest number of intensity levels at present supported by      HP DeskJets is apparently 4.      A more accurate implementation would determine 'step' as a floating point      value, divide the intensity by it, and take the floor (entier) of the      result as the component intensity.  */  /* The order has to be (YMC)(K) from left to right */  if (eprn->colour_model != eprn_DeviceGray) {    step = gx_max_color_value/eprn->non_black_levels;    level = yellow/step;    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;    value = level << eprn->bits_per_colorant;    level = magenta/step;    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;    value = (value | level) << eprn->bits_per_colorant;    level = cyan/step;    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;    value = (value | level) << eprn->bits_per_colorant;  }  if (eprn->colour_model != eprn_DeviceCMY) {    step = gx_max_color_value/eprn->black_levels;    level = black/step;    if (level >= eprn->black_levels) level = eprn->black_levels - 1;    value |= level;  }#ifdef EPRN_TRACE  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%lX.\n", (unsigned long)value);#endif  return value;}/******************************************************************************  Function: eprn_map_cmyk_color_max  This is a 'map_cmyk_color' method retaining as much colour information as  possible. The reduction to the printer's capabilities must happen in the  output routine.******************************************************************************/gx_color_index eprn_map_cmyk_color_max(gx_device *device,  const gx_color_value cv[]){  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];  gx_color_index value;#ifdef EPRN_TRACE  if_debug4(EPRN_TRACE_CHAR,    "! eprn_map_cmyk_color_max() called for CMYK = (%hu, %hu, %hu, %hu),\n",      cyan, magenta, yellow, black);#endif  value = dominant_8bits(black);  value |= dominant_8bits(cyan)    <<  8;  value |= dominant_8bits(magenta) << 16;  value |= dominant_8bits(yellow)  << 24;#ifdef EPRN_TRACE  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%08lX.\n", (unsigned long)value);#endif  return value;}/******************************************************************************  Function: eprn_map_cmyk_color_glob  Global eprn_map_cmyk_color for all cases handled above used to  be able to work together with ghostscript 8.15 and CMYK model.******************************************************************************/gx_color_index eprn_map_cmyk_color_glob(gx_device *device, const gx_color_value cv[]){  const eprn_Eprn *eprn = &((eprn_Device *)device)->eprn;  if (eprn->intensity_rendering == eprn_IR_FloydSteinberg)    return eprn_map_cmyk_color_max(device, cv);  else if (device->color_info.max_gray > 1 || device->color_info.max_color > 1)    return eprn_map_cmyk_color_flex(device, cv);  else    return eprn_map_cmyk_color(device, cv);}/******************************************************************************  Function: eprn_finalize  This function fills the last octet in a set of bit planes with white if  needed and sets the lengths of all these planes.  'is_RGB' denotes whether the colour model is eprn_DeviceRGB,  'non_black_levels' is the number of intensity levels for non-black colorants,  'planes' the number of bit planes,  'plane' points to an array of at least 'planes' bit planes,  'ptr' points to an array of at least 'planes' pointers into the bit planes,  'pixels' is the number of pixels written to the group of bit planes.  If 'pixels' is divisible by 8, the 'ptr' pointers point to octets after  the last completely written octets. Otherwise, they point to the last  incompletely written octet in which the pixels written so far occupy the  least significant bits.******************************************************************************/void eprn_finalize(bool is_RGB, unsigned int non_black_levels,  int planes, eprn_OctetString *plane, eprn_Octet **ptr, int pixels){  int j;  /* Execute remaining left shifts in the last octet of the output planes when     the number of pixels is not a multiple of 8, and fill with white on the     right */  if (pixels % 8 != 0) {    int shift = 8 - pixels % 8;    if (is_RGB) {      /* White may be any intensity, but it's the same for all three colorants,	 and it's the highest. */      eprn_Octet imax = non_black_levels - 1;      int c, rgb_planes = eprn_bits_for_levels(non_black_levels);      j = 0;	/* next output plane */      /* Loop over RGB */      for (c = 0; c < 3; c++) {	eprn_Octet value = imax;	int m;	/* Loop over all planes for this colorant */	for (m = 0; m < rgb_planes; m++, j++) {	  eprn_Octet bit = value & 1;	  int p;	  value = value >> 1;	  /* Put the bit into all remaining pixels for this plane */	  for (p = 0; p < shift; p++)	    *ptr[j] = (*ptr[j] << 1) | bit;	}      }    }    else /* White is zero */      for (j = 0; j < planes; j++)	*ptr[j] = *ptr[j] << shift;    /* Advance all plane pointers by 1 */    for (j = 0; j < planes; j++) ptr[j]++;  }  /* Set the lengths of the bit plane strings */  for (j = 0; j < planes; j++) {    if (pixels == 0) plane[j].length = 0;    else plane[j].length = ptr[j] - plane[j].str;  }  return;}/******************************************************************************  Function: split_line_le8  This is the first of the "split_line implementations". See the body of  eprn_get_planes() for the calling conventions common to them.  This particular implementation has the following restrictions:  - The pixmap depth must be a divisor of 8.******************************************************************************/static void split_line_le8(eprn_Device *dev, const eprn_Octet *line,  int length, eprn_OctetString plane[]){  gx_color_index    pixel;  int    black_planes,	/* number of planes to send for black */    non_black_planes,	/* number of planes to send for each of CMY/RGB */    j,    k,    pixels,		/* number of pixels transferred to bit planes */    planes;		/* number of planes to send */  eprn_Octet    comp_mask = 0,	/* 'bits_per_component' 1s in the lowest part */    pixel_mask = 0,	/* 'depth' 1s in the lowest part */    *ptr[8];		/* pointers into planes (next octet to write to) */  /* Number of planes to send */  black_planes = eprn_bits_for_levels(dev->eprn.black_levels);  non_black_planes = eprn_bits_for_levels(dev->eprn.non_black_levels);  planes = black_planes + 3*non_black_planes;  /* Initialize the bit plane pointers */  for (j = 0; j < planes; j++) ptr[j] = plane[j].str;  /* Determine some bit masks */  for (j = 0; j < dev->color_info.depth; j++)    pixel_mask = (pixel_mask << 1) | 1;  for (j = 0; j < dev->eprn.bits_per_colorant; j++)    comp_mask = (comp_mask << 1) | 1;  /* Copy from 'line' to 'plane[]', converting Z format to XY format */  pixels = 0;  k = 0; /* Next octet index in the input line */  while (k < length) {    int l, m, p;    /* Initialize plane storage if it's a new output octet */    if (pixels % 8 == 0) for (j = 0; j < planes; j++) *ptr[j] = 0;    /* Loop over pixels within the input octet, starting at the leftmost       pixel (highest-order bits) */    p = 8/dev->color_info.depth - 1;    do {      eprn_Octet comp;      /* Extract pixel */      pixel = (line[k] >> p*dev->color_info.depth) & pixel_mask;      /* Extract components from the pixel and distribute each over its planes       */      comp = pixel & comp_mask;	/* black */      for (j = 0; j < black_planes; j++) {	*ptr[j] = (*ptr[j] << 1) | comp & 1;	comp >>= 1;      }      if (non_black_planes > 0) for (l = 1; l < 4; l++) {	comp = (pixel >> l*dev->eprn.bits_per_colorant) & comp_mask;	for (m = 0; m < non_black_planes; m++, j++) {	  *ptr[j] = (*ptr[j] << 1) | comp & 1;	  comp >>= 1;	}      }      pixels++;      p--;    } while (p >= 0);    k++;    /* Increase plane pointers if an output octet boundary has been reached */    if (pixels % 8 == 0) for (j = 0; j < planes; j++) ptr[j]++;  }  eprn_finalize(dev->eprn.colour_model == eprn_DeviceRGB,    dev->eprn.non_black_levels, planes, plane, ptr, pixels);  return;}/******************************************************************************  Function: split_line_ge8  This split_line function has the following restrictions:  - The pixmap depth must be a multiple of 8.  - There may be at most 8 bits per colorant.    (Hence the depth is at most 32.)  - 'length' must be divisible by depth/8.******************************************************************************/static void split_line_ge8(eprn_Device *dev, const eprn_Octet *line,  int length, eprn_OctetString plane[]){  gx_color_index

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -