gfxstate.cc

来自「将pdf文档转换为高质量的html文档」· CC 代码 · 共 2,662 行 · 第 1/5 页

CC
2,662
字号
//========================================================================//// GfxState.cc//// Copyright 1996-2003 Glyph & Cog, LLC////========================================================================#include <config.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stddef.h>#include <math.h>#include <string.h>#include "goo/gmem.h"#include "Error.h"#include "Object.h"#include "Array.h"#include "Page.h"#include "GfxState.h"#include "GString.h"//------------------------------------------------------------------------static inline GfxColorComp clip01(GfxColorComp x) {  return (x < 0) ? 0 : (x > gfxColorComp1) ? gfxColorComp1 : x;}static inline double clip01(double x) {  return (x < 0) ? 0 : (x > 1) ? 1 : x;}GBool Matrix::invertTo(Matrix *other){  double det;  det = 1 / (m[0] * m[3] - m[1] * m[2]);  other->m[0] = m[3] * det;  other->m[1] = -m[1] * det;  other->m[2] = -m[2] * det;  other->m[3] = m[0] * det;  other->m[4] = (m[2] * m[5] - m[3] * m[4]) * det;  other->m[5] = (m[1] * m[4] - m[0] * m[5]) * det;  return gTrue;}void Matrix::transform(double x, double y, double *tx, double *ty){  double temp_x, temp_y;  temp_x = m[0] * x + m[2] * y + m[4];  temp_y = m[1] * x + m[3] * y + m[5];  *tx = temp_x;  *ty = temp_y;}//------------------------------------------------------------------------static struct { char *name; GfxBlendMode mode;} gfxBlendModeNames[] = {  { "Normal",     gfxBlendNormal },  { "Compatible", gfxBlendNormal },  { "Multiply",   gfxBlendMultiply },  { "Screen",     gfxBlendScreen },  { "Overlay",    gfxBlendOverlay },  { "Darken",     gfxBlendDarken },  { "Lighten",    gfxBlendLighten },  { "ColorDodge", gfxBlendColorDodge },  { "ColorBurn",  gfxBlendColorBurn },  { "HardLight",  gfxBlendHardLight },  { "SoftLight",  gfxBlendSoftLight },  { "Difference", gfxBlendDifference },  { "Exclusion",  gfxBlendExclusion },  { "Hue",        gfxBlendHue },  { "Saturation", gfxBlendSaturation },  { "Color",      gfxBlendColor },  { "Luminosity", gfxBlendLuminosity }};#define nGfxBlendModeNames \          ((int)((sizeof(gfxBlendModeNames) / sizeof(char *))))	 //------------------------------------------------------------------------// // NB: This must match the GfxColorSpaceMode enum defined in// GfxState.hstatic char *gfxColorSpaceModeNames[] = {  "DeviceGray",  "CalGray",  "DeviceRGB",  "CalRGB",  "DeviceCMYK",  "Lab",  "ICCBased",  "Indexed",  "Separation",  "DeviceN",  "Pattern"};#define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *)))//------------------------------------------------------------------------// GfxColorSpace//------------------------------------------------------------------------GfxColorSpace::GfxColorSpace() {}GfxColorSpace::~GfxColorSpace() {}GfxColorSpace *GfxColorSpace::parse(Object *csObj) {  GfxColorSpace *cs;  Object obj1;  cs = NULL;  if (csObj->isName()) {    if (csObj->isName("DeviceGray") || csObj->isName("G")) {      cs = new GfxDeviceGrayColorSpace();    } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {      cs = new GfxDeviceRGBColorSpace();    } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {      cs = new GfxDeviceCMYKColorSpace();    } else if (csObj->isName("Pattern")) {      cs = new GfxPatternColorSpace(NULL);    } else {      error(-1, "Bad color space '%s'", csObj->getName());    }  } else if (csObj->isArray()) {    csObj->arrayGet(0, &obj1);    if (obj1.isName("DeviceGray") || obj1.isName("G")) {      cs = new GfxDeviceGrayColorSpace();    } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {      cs = new GfxDeviceRGBColorSpace();    } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {      cs = new GfxDeviceCMYKColorSpace();    } else if (obj1.isName("CalGray")) {      cs = GfxCalGrayColorSpace::parse(csObj->getArray());    } else if (obj1.isName("CalRGB")) {      cs = GfxCalRGBColorSpace::parse(csObj->getArray());    } else if (obj1.isName("Lab")) {      cs = GfxLabColorSpace::parse(csObj->getArray());    } else if (obj1.isName("ICCBased")) {      cs = GfxICCBasedColorSpace::parse(csObj->getArray());    } else if (obj1.isName("Indexed") || obj1.isName("I")) {      cs = GfxIndexedColorSpace::parse(csObj->getArray());    } else if (obj1.isName("Separation")) {      cs = GfxSeparationColorSpace::parse(csObj->getArray());    } else if (obj1.isName("DeviceN")) {      cs = GfxDeviceNColorSpace::parse(csObj->getArray());    } else if (obj1.isName("Pattern")) {      cs = GfxPatternColorSpace::parse(csObj->getArray());    } else {      error(-1, "Bad color space");    }    obj1.free();  } else {    error(-1, "Bad color space - expected name or array");  }  return cs;}void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,				     int maxImgPixel) {  int i;  for (i = 0; i < getNComps(); ++i) {    decodeLow[i] = 0;    decodeRange[i] = 1;  }}int GfxColorSpace::getNumColorSpaceModes() {  return nGfxColorSpaceModes;}char *GfxColorSpace::getColorSpaceModeName(int idx) {  return gfxColorSpaceModeNames[idx];}void GfxColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) {  int i, j, n;  GfxColor color;  GfxRGB rgb;  n = getNComps();  for (i = 0; i < length; i++) {        for (j = 0; j < n; j++)      color.c[j] = in[i * n + j] * 256;    getRGB (&color, &rgb);    out[i] =	((int) colToByte(rgb.r) << 16) |	((int) colToByte(rgb.g) << 8) |	((int) colToByte(rgb.b) << 0);  }}void GfxColorSpace::getGrayLine(Guchar *in, unsigned char *out, int length) {  int i, j, n;  GfxColor color;  GfxGray gray;  n = getNComps();  for (i = 0; i < length; i++) {        for (j = 0; j < n; j++)      color.c[j] = in[i * n + j] * 256;    getGray (&color, &gray);    out[i] = colToByte(gray);  }}//------------------------------------------------------------------------// GfxDeviceGrayColorSpace//------------------------------------------------------------------------GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {}GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {}GfxColorSpace *GfxDeviceGrayColorSpace::copy() {  return new GfxDeviceGrayColorSpace();}void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {  *gray = clip01(color->c[0]);}void GfxDeviceGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {  memcpy (out, in, length);}void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {  rgb->r = rgb->g = rgb->b = clip01(color->c[0]);}void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out,					 int length) {  int i;  for (i = 0; i < length; i++)    out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);}void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {  cmyk->c = cmyk->m = cmyk->y = 0;  cmyk->k = clip01(gfxColorComp1 - color->c[0]);}//------------------------------------------------------------------------// GfxCalGrayColorSpace//------------------------------------------------------------------------GfxCalGrayColorSpace::GfxCalGrayColorSpace() {  whiteX = whiteY = whiteZ = 1;  blackX = blackY = blackZ = 0;  gamma = 1;}GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {}GfxColorSpace *GfxCalGrayColorSpace::copy() {  GfxCalGrayColorSpace *cs;  cs = new GfxCalGrayColorSpace();  cs->whiteX = whiteX;  cs->whiteY = whiteY;  cs->whiteZ = whiteZ;  cs->blackX = blackX;  cs->blackY = blackY;  cs->blackZ = blackZ;  cs->gamma = gamma;  return cs;}GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {  GfxCalGrayColorSpace *cs;  Object obj1, obj2, obj3;  arr->get(1, &obj1);  if (!obj1.isDict()) {    error(-1, "Bad CalGray color space");    obj1.free();    return NULL;  }  cs = new GfxCalGrayColorSpace();  if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&      obj2.arrayGetLength() == 3) {    obj2.arrayGet(0, &obj3);    cs->whiteX = obj3.getNum();    obj3.free();    obj2.arrayGet(1, &obj3);    cs->whiteY = obj3.getNum();    obj3.free();    obj2.arrayGet(2, &obj3);    cs->whiteZ = obj3.getNum();    obj3.free();  }  obj2.free();  if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&      obj2.arrayGetLength() == 3) {    obj2.arrayGet(0, &obj3);    cs->blackX = obj3.getNum();    obj3.free();    obj2.arrayGet(1, &obj3);    cs->blackY = obj3.getNum();    obj3.free();    obj2.arrayGet(2, &obj3);    cs->blackZ = obj3.getNum();    obj3.free();  }  obj2.free();  if (obj1.dictLookup("Gamma", &obj2)->isNum()) {    cs->gamma = obj2.getNum();  }  obj2.free();  obj1.free();  return cs;}void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {  *gray = clip01(color->c[0]);}void GfxCalGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {  memcpy (out, in, length);}void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {  rgb->r = rgb->g = rgb->b = clip01(color->c[0]);}void GfxCalGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out,				      int length) {  int i;  for (i = 0; i < length; i++)    out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);}void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {  cmyk->c = cmyk->m = cmyk->y = 0;  cmyk->k = clip01(gfxColorComp1 - color->c[0]);}//------------------------------------------------------------------------// GfxDeviceRGBColorSpace//------------------------------------------------------------------------GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {}GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {}GfxColorSpace *GfxDeviceRGBColorSpace::copy() {  return new GfxDeviceRGBColorSpace();}void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {  *gray = clip01((GfxColorComp)(0.3 * color->c[0] +		 0.59 * color->c[1] +		 0.11 * color->c[2] + 0.5));}void GfxDeviceRGBColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {  int i;  for (i = 0; i < length; i++) {    out[i] =       (in[i * 3 + 0] * 19595 +        in[i * 3 + 1] * 38469 +        in[i * 3 + 2] * 7472) / 65536;  }}void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {  rgb->r = clip01(color->c[0]);  rgb->g = clip01(color->c[1]);  rgb->b = clip01(color->c[2]);}void GfxDeviceRGBColorSpace::getRGBLine(Guchar *in, unsigned int *out,					int length) {  Guchar *p;  int i;  for (i = 0, p = in; i < length; i++, p += 3)    out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);}void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {  GfxColorComp c, m, y, k;  c = clip01(gfxColorComp1 - color->c[0]);  m = clip01(gfxColorComp1 - color->c[1]);  y = clip01(gfxColorComp1 - color->c[2]);  k = c;  if (m < k) {    k = m;  }  if (y < k) {    k = y;  }  cmyk->c = c - k;  cmyk->m = m - k;  cmyk->y = y - k;  cmyk->k = k;}//------------------------------------------------------------------------// GfxCalRGBColorSpace//------------------------------------------------------------------------GfxCalRGBColorSpace::GfxCalRGBColorSpace() {  whiteX = whiteY = whiteZ = 1;  blackX = blackY = blackZ = 0;  gammaR = gammaG = gammaB = 1;  mat[0] = 1; mat[1] = 0; mat[2] = 0;  mat[3] = 0; mat[4] = 1; mat[5] = 0;  mat[6] = 0; mat[7] = 0; mat[8] = 1;}GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {}GfxColorSpace *GfxCalRGBColorSpace::copy() {  GfxCalRGBColorSpace *cs;  int i;  cs = new GfxCalRGBColorSpace();  cs->whiteX = whiteX;  cs->whiteY = whiteY;  cs->whiteZ = whiteZ;  cs->blackX = blackX;  cs->blackY = blackY;  cs->blackZ = blackZ;  cs->gammaR = gammaR;  cs->gammaG = gammaG;  cs->gammaB = gammaB;  for (i = 0; i < 9; ++i) {    cs->mat[i] = mat[i];  }  return cs;}GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {  GfxCalRGBColorSpace *cs;  Object obj1, obj2, obj3;  int i;  arr->get(1, &obj1);  if (!obj1.isDict()) {    error(-1, "Bad CalRGB color space");    obj1.free();    return NULL;  }  cs = new GfxCalRGBColorSpace();  if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&      obj2.arrayGetLength() == 3) {    obj2.arrayGet(0, &obj3);    cs->whiteX = obj3.getNum();    obj3.free();    obj2.arrayGet(1, &obj3);    cs->whiteY = obj3.getNum();    obj3.free();    obj2.arrayGet(2, &obj3);    cs->whiteZ = obj3.getNum();    obj3.free();  }  obj2.free();  if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&      obj2.arrayGetLength() == 3) {    obj2.arrayGet(0, &obj3);    cs->blackX = obj3.getNum();    obj3.free();    obj2.arrayGet(1, &obj3);    cs->blackY = obj3.getNum();    obj3.free();    obj2.arrayGet(2, &obj3);    cs->blackZ = obj3.getNum();    obj3.free();  }  obj2.free();  if (obj1.dictLookup("Gamma", &obj2)->isArray() &&      obj2.arrayGetLength() == 3) {    obj2.arrayGet(0, &obj3);    cs->gammaR = obj3.getNum();    obj3.free();    obj2.arrayGet(1, &obj3);    cs->gammaG = obj3.getNum();    obj3.free();    obj2.arrayGet(2, &obj3);    cs->gammaB = obj3.getNum();    obj3.free();  }  obj2.free();  if (obj1.dictLookup("Matrix", &obj2)->isArray() &&      obj2.arrayGetLength() == 9) {    for (i = 0; i < 9; ++i) {      obj2.arrayGet(i, &obj3);      cs->mat[i] = obj3.getNum();      obj3.free();    }  }  obj2.free();  obj1.free();  return cs;}void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {  *gray = clip01((GfxColorComp)(0.299 * color->c[0] +		 0.587 * color->c[1] +		 0.114 * color->c[2] + 0.5));}void GfxCalRGBColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {  int i;

⌨️ 快捷键说明

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