📄 gfxstate.cc
字号:
//========================================================================//// GfxState.cc//// Copyright 1996-2002 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stddef.h>#include <math.h>#include <string.h> // for memcpy()#include "gmem.h"#include "Error.h"#include "Object.h"#include "Array.h"#include "Page.h"#include "GfxState.h"//------------------------------------------------------------------------static inline double clip01(double x) { return (x < 0) ? 0 : ((x > 1) ? 1 : x);}//------------------------------------------------------------------------static 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 '%s'", csObj->getName()); } 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];}//------------------------------------------------------------------------// GfxDeviceGrayColorSpace//------------------------------------------------------------------------GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {}GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {}GfxColorSpace *GfxDeviceGrayColorSpace::copy() { return new GfxDeviceGrayColorSpace();}void GfxDeviceGrayColorSpace::getGray(GfxColor *color, double *gray) { *gray = clip01(color->c[0]);}void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = rgb->g = rgb->b = clip01(color->c[0]);}void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; cmyk->k = clip01(1 - 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, double *gray) { *gray = clip01(color->c[0]);}void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = rgb->g = rgb->b = clip01(color->c[0]);}void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; cmyk->k = clip01(1 - color->c[0]);}//------------------------------------------------------------------------// GfxDeviceRGBColorSpace//------------------------------------------------------------------------GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {}GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {}GfxColorSpace *GfxDeviceRGBColorSpace::copy() { return new GfxDeviceRGBColorSpace();}void GfxDeviceRGBColorSpace::getGray(GfxColor *color, double *gray) { *gray = clip01(0.299 * color->c[0] + 0.587 * color->c[1] + 0.114 * color->c[2]);}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::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double c, m, y, k; c = clip01(1 - color->c[0]); m = clip01(1 - color->c[1]); y = clip01(1 - 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, double *gray) { *gray = clip01(0.299 * color->c[0] + 0.587 * color->c[1] + 0.114 * color->c[2]);}void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = clip01(color->c[0]); rgb->g = clip01(color->c[1]); rgb->b = clip01(color->c[2]);}void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double c, m, y, k; c = clip01(1 - color->c[0]); m = clip01(1 - color->c[1]); y = clip01(1 - 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;}//------------------------------------------------------------------------// GfxDeviceCMYKColorSpace//------------------------------------------------------------------------GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {}GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {}GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { return new GfxDeviceCMYKColorSpace();}void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, double *gray) { *gray = clip01(1 - color->c[3] - 0.299 * color->c[0] - 0.587 * color->c[1] - 0.114 * color->c[2]);}void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { double c, m, y, aw, ac, am, ay, ar, ag, ab; c = clip01(color->c[0] + color->c[3]); m = clip01(color->c[1] + color->c[3]); y = clip01(color->c[2] + color->c[3]); aw = (1-c) * (1-m) * (1-y); ac = c * (1-m) * (1-y); am = (1-c) * m * (1-y); ay = (1-c) * (1-m) * y; ar = (1-c) * m * y; ag = c * (1-m) * y; ab = c * m * (1-y); rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar); rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag); rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag + 0.4863*ab);}void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = clip01(color->c[0]); cmyk->m = clip01(color->c[1]); cmyk->y = clip01(color->c[2]); cmyk->k = clip01(color->c[3]);}//------------------------------------------------------------------------// GfxLabColorSpace//------------------------------------------------------------------------// This is the inverse of MatrixLMN in Example 4.10 from the PostScript// Language Reference, Third Edition.static double xyzrgb[3][3] = { { 3.240449, -1.537136, -0.498531 }, { -0.969265, 1.876011, 0.041556 }, { 0.055643, -0.204026, 1.057229 }};GfxLabColorSpace::GfxLabColorSpace() { whiteX = whiteY = whiteZ = 1; blackX = blackY = blackZ = 0; aMin = bMin = -100; aMax = bMax = 100;}GfxLabColorSpace::~GfxLabColorSpace() {}GfxColorSpace *GfxLabColorSpace::copy() { GfxLabColorSpace *cs; cs = new GfxLabColorSpace(); cs->whiteX = whiteX; cs->whiteY = whiteY; cs->whiteZ = whiteZ; cs->blackX = blackX; cs->blackY = blackY; cs->blackZ = blackZ; cs->aMin = aMin; cs->aMax = aMax; cs->bMin = bMin; cs->bMax = bMax; cs->kr = kr; cs->kg = kg; cs->kb = kb; return cs;}GfxColorSpace *GfxLabColorSpace::parse(Array *arr) { GfxLabColorSpace *cs; Object obj1, obj2, obj3; arr->get(1, &obj1); if (!obj1.isDict()) { error(-1, "Bad Lab color space"); obj1.free(); return NULL; } cs = new GfxLabColorSpace(); 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("Range", &obj2)->isArray() && obj2.arrayGetLength() == 4) { obj2.arrayGet(0, &obj3); cs->aMin = obj3.getNum(); obj3.free(); obj2.arrayGet(1, &obj3); cs->aMax = obj3.getNum(); obj3.free(); obj2.arrayGet(2, &obj3); cs->bMin = obj3.getNum(); obj3.free(); obj2.arrayGet(3, &obj3); cs->bMax = obj3.getNum(); obj3.free(); } obj2.free(); obj1.free(); cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX + xyzrgb[0][1] * cs->whiteY + xyzrgb[0][2] * cs->whiteZ); cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX + xyzrgb[1][1] * cs->whiteY + xyzrgb[1][2] * cs->whiteZ); cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX + xyzrgb[2][1] * cs->whiteY + xyzrgb[2][2] * cs->whiteZ); return cs;}void GfxLabColorSpace::getGray(GfxColor *color, double *gray) { GfxRGB rgb; getRGB(color, &rgb); *gray = clip01(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b);}void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { double X, Y, Z; double t1, t2; double r, g, b; // convert L*a*b* to CIE 1931 XYZ color space t1 = (color->c[0] + 16) / 116;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -