diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc index 0de4840..eb86838 100644 --- a/poppler/GfxState.cc +++ b/poppler/GfxState.cc @@ -18,6 +18,7 @@ // Copyright (C) 2006 Carlos Garcia Campos // Copyright (C) 2006-2008 Albert Astals Cid // Copyright (C) 2009 Koji Otani +// Copyright (C) 2009 Thomas Freitag // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -107,9 +108,9 @@ static const GfxBlendModeInfo gfxBlendModeNames[] = { #define nGfxBlendModeNames \ ((int)((sizeof(gfxBlendModeNames) / sizeof(GfxBlendModeInfo)))) - + //------------------------------------------------------------------------ -// +// // NB: This must match the GfxColorSpaceMode enum defined in // GfxState.h static char *gfxColorSpaceModeNames[] = { @@ -214,7 +215,7 @@ void GfxColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) { n = getNComps(); for (i = 0; i < length; i++) { - + for (j = 0; j < n; j++) color.c[j] = in[i * n + j] * 256; @@ -311,7 +312,7 @@ int GfxColorSpace::setupColorProfiles() // create transform from XYZ cmsHPROFILE XYZProfile = cmsCreateXYZProfile(); if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL, - displayProfile, + displayProfile, COLORSPACE_SH(displayPixelType) | CHANNELS_SH(nChannels) | BYTES_SH(1), INTENT_RELATIVE_COLORIMETRIC,0)) == 0) { @@ -452,7 +453,7 @@ void GfxColorSpace::getGrayLine(Guchar *in, unsigned char *out, int length) { n = getNComps(); for (i = 0; i < length; i++) { - + for (j = 0; j < n; j++) color.c[j] = in[i * n + j] * 256; @@ -598,7 +599,7 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) { // convert CalGray to media XYZ color space // (not multiply by the white point) -void GfxCalGrayColorSpace::getXYZ(GfxColor *color, +void GfxCalGrayColorSpace::getXYZ(GfxColor *color, double *pX, double *pY, double *pZ) { double A; @@ -616,7 +617,7 @@ void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; double X, Y, Z; - + getXYZ(color,&X,&Y,&Z); in[0] = clip01(X); in[1] = clip01(Y); @@ -641,7 +642,7 @@ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; - + in[0] = clip01(X); in[1] = clip01(Y); in[2] = clip01(Z); @@ -674,12 +675,12 @@ void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; double X, Y, Z; - + getXYZ(color,&X,&Y,&Z); in[0] = clip01(X); in[1] = clip01(Y); in[2] = clip01(Z); - + XYZ2DisplayTransform->doTransform(in,out,1); cmyk->c = byteToCol(out[0]); cmyk->m = byteToCol(out[1]); @@ -733,9 +734,9 @@ 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 + + out[i] = + (in[i * 3 + 0] * 19595 + + in[i * 3 + 1] * 38469 + in[i * 3 + 2] * 7472) / 65536; } } @@ -892,7 +893,7 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { } // convert CalRGB to XYZ color space -void GfxCalRGBColorSpace::getXYZ(GfxColor *color, +void GfxCalRGBColorSpace::getXYZ(GfxColor *color, double *pX, double *pY, double *pZ) { double A, B, C; @@ -912,7 +913,7 @@ void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; double X, Y, Z; - + getXYZ(color,&X,&Y,&Z); in[0] = clip01(X); in[1] = clip01(Y); @@ -937,7 +938,7 @@ void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; - + in[0] = clip01(X/whiteX); in[1] = clip01(Y/whiteY); in[2] = clip01(Z/whiteZ); @@ -966,7 +967,7 @@ void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; double X, Y, Z; - + getXYZ(color,&X,&Y,&Z); in[0] = clip01(X); in[1] = clip01(Y); @@ -1025,7 +1026,7 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) { void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { double c, m, y, k, c1, m1, y1, k1, r, g, b, x; - + c = colToDbl(color->c[0]); m = colToDbl(color->c[1]); y = colToDbl(color->c[2]); @@ -1208,7 +1209,7 @@ void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) { if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; - + getXYZ(color, &in[0], &in[1], &in[2]); XYZ2DisplayTransform->doTransform(in,out,1); *gray = byteToCol(out[0]); @@ -1223,7 +1224,7 @@ void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) { // convert L*a*b* to media XYZ color space // (not multiply by the white point) -void GfxLabColorSpace::getXYZ(GfxColor *color, +void GfxLabColorSpace::getXYZ(GfxColor *color, double *pX, double *pY, double *pZ) { double X, Y, Z; double t1, t2; @@ -1260,7 +1261,7 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) { Guchar out[gfxColorMaxComps]; double in[gfxColorMaxComps]; - + in[0] = clip01(X); in[1] = clip01(Y); in[2] = clip01(Z); @@ -1291,7 +1292,7 @@ void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) { double in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; - + getXYZ(color, &in[0], &in[1], &in[2]); XYZ2DisplayTransform->doTransform(in,out,1); cmyk->c = byteToCol(out[0]); @@ -1511,7 +1512,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { } cs->transform = new GfxColorTransform(transform); if (dcst == PT_RGB) { - // create line transform only when the display is RGB type color space + // create line transform only when the display is RGB type color space if ((transform = cmsCreateTransform(hp, CHANNELS_SH(nCompsA) | BYTES_SH(1),dhp, TYPE_RGB_8,INTENT_RELATIVE_COLORIMETRIC,0)) == 0) { @@ -1535,7 +1536,7 @@ void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) { if (transform != 0 && displayPixelType == PT_GRAY) { Guchar in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; - + for (int i = 0;i < nComps;i++) { in[i] = colToByte(color->c[i]); } @@ -1559,7 +1560,7 @@ void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { && (displayProfile == NULL || displayPixelType == PT_RGB)) { Guchar in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; - + for (int i = 0;i < nComps;i++) { in[i] = colToByte(color->c[i]); } @@ -1599,7 +1600,7 @@ void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { if (transform != NULL && displayPixelType == PT_CMYK) { Guchar in[gfxColorMaxComps]; Guchar out[gfxColorMaxComps]; - + for (int i = 0;i < nComps;i++) { in[i] = colToByte(color->c[i]); } @@ -3300,9 +3301,11 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA, break; } if (nVerticesA == vertSize) { + int oldVertSize = vertSize; vertSize = (vertSize == 0) ? 16 : 2 * vertSize; verticesA = (GfxGouraudVertex *) greallocn(verticesA, vertSize, sizeof(GfxGouraudVertex)); + memset(verticesA + oldVertSize, 0, (vertSize - oldVertSize) * sizeof(GfxGouraudVertex)); } verticesA[nVerticesA].x = xMin + xMul * (double)x; verticesA[nVerticesA].y = yMin + yMul * (double)y; @@ -3622,9 +3625,11 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict, break; } if (nPatchesA == patchesSize) { + int oldPatchesSize = patchesSize; patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize; patchesA = (GfxPatch *)greallocn(patchesA, patchesSize, sizeof(GfxPatch)); + memset(patchesA + oldPatchesSize, 0, (patchesSize - oldPatchesSize) * sizeof(GfxPatch)); } p = &patchesA[nPatchesA]; if (typeA == 6) { @@ -4114,11 +4119,11 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, mapped = decodeLow[k] + (i * decodeRange[k]) / maxPixel; lookup[k][i] = dblToCol(mapped); byte = (int) (mapped * 255.0 + 0.5); - if (byte < 0) - byte = 0; - else if (byte > 255) - byte = 255; - byte_lookup[i * nComps + k] = byte; + if (byte < 0) + byte = 0; + else if (byte > 255) + byte = 255; + byte_lookup[i * nComps + k] = byte; } } } @@ -4438,7 +4443,7 @@ void GfxPath::curveTo(double x1, double y1, double x2, double y2, if (justMoved) { if (n >= size) { size += 16; - subpaths = (GfxSubpath **) + subpaths = (GfxSubpath **) greallocn(subpaths, size, sizeof(GfxSubpath *)); } subpaths[n] = new GfxSubpath(firstX, firstY); @@ -4978,6 +4983,10 @@ void GfxState::textShift(double tx, double ty) { void GfxState::shift(double dx, double dy) { curX += dx; curY += dy; + if (curX < tx1) tx1 = curX; + if (ty1 > 0 && curY - fontSize / 4 < ty1) ty1 = curY - fontSize / 4; + if (curX > tx2) tx2 = curX; + if (curY + fontSize > ty2) ty2 = curY + fontSize; } GfxState *GfxState::save() { diff --git a/poppler/GfxState.h b/poppler/GfxState.h index ad5fae6..2336daf 100644 --- a/poppler/GfxState.h +++ b/poppler/GfxState.h @@ -17,6 +17,7 @@ // Copyright (C) 2006, 2007 Jeff Muizelaar // Copyright (C) 2006 Carlos Garcia Campos // Copyright (C) 2009 Koji Otani +// Copyright (C) 2009 Thomas Freitag // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -53,7 +54,7 @@ public: //------------------------------------------------------------------------ // GfxBlendMode //------------------------------------------------------------------------ - + enum GfxBlendMode { gfxBlendNormal, gfxBlendMultiply, @@ -233,7 +234,7 @@ protected: static cmsHPROFILE displayProfile; // display profile static unsigned int displayPixelType; static GfxColorTransform *XYZ2DisplayTransform; - // convert color space signature to cmsColor type + // convert color space signature to cmsColor type static unsigned int getCMSColorSpaceType(icColorSpaceSignature cs); static unsigned int getCMSNChannels(icColorSpaceSignature cs); static cmsHPROFILE loadColorProfile(const char *fileName); @@ -1264,6 +1265,8 @@ public: double d, double e, double f) { textMat[0] = a; textMat[1] = b; textMat[2] = c; textMat[3] = d; textMat[4] = e; textMat[5] = f; } + void clearTextCorners() + { tx1 = 0; ty1 = 0; tx2 = 0; ty2 = 0; } void setCharSpace(double space) { charSpace = space; } void setWordSpace(double space) @@ -1294,9 +1297,24 @@ public: void clipToStrokePath(); // Text position. - void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; } + void textSetPos(double tx, double ty) + { lineX = tx; lineY = ty; + if (tx1 == 0) tx1 = curX; + if (ty1 == 0) ty1 = curY; + if (curX < tx1) tx1 = curX; + if (ty1 > 0 && curY - fontSize / 4 < ty1) ty1 = curY - fontSize / 4; + if (curX > tx2) tx2 = curX; + if (curY + fontSize > ty2) ty2 = curY + fontSize; + } void textMoveTo(double tx, double ty) - { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } + { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); + if (tx1 == 0) tx1 = curX; + if (ty1 == 0) ty1 = curY; + if (curX < tx1) tx1 = curX; + if (ty1 > 0 && curY - fontSize / 4 < ty1) ty1 = curY - fontSize / 4; + if (curX > tx2) tx2 = curX; + if (curY + fontSize > ty2) ty2 = curY + fontSize; + } void textShift(double tx, double ty); void shift(double dx, double dy); @@ -1313,6 +1331,7 @@ private: double hDPI, vDPI; // resolution double ctm[6]; // coord transform matrix double px1, py1, px2, py2; // page corners (user coords) + double tx1, ty1, tx2, ty2; // text corners (user coords) double pageWidth, pageHeight; // page size (pixels) int rotate; // page rotation angle