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 + -
显示快捷键?