Commit 104f9286 authored by Thomas Freitag's avatar Thomas Freitag Committed by Albert Astals Cid

Support colorizing text in pattern colorspace

This implements commits the final patches for bug 19670 and 19994
Also fixes bugs 15819 and 2807
Also implements blending for SPLASH_CMYK in Splash
It's a quite big change but i've done regression testing over my whole
pdf suite and did not fit anything that went worse, just improvements
Missing the Cairo support
parent d3e45631
......@@ -287,6 +287,7 @@ if(ENABLE_XPDF_HEADERS)
poppler/Gfx.h
poppler/GfxFont.h
poppler/GfxState.h
poppler/GfxState_helpers.h
poppler/GlobalParams.h
poppler/JArithmeticDecoder.h
poppler/JBIG2Stream.h
......
......@@ -28,6 +28,7 @@
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2009 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
// Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// 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
......@@ -498,6 +499,9 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, Catalog *cata
subPage = gFalse;
printCommands = globalParams->getPrintCommands();
profileCommands = globalParams->getProfileCommands();
textHaveCSPattern = gFalse;
drawText = gFalse;
maskHaveCSPattern = gFalse;
mcStack = NULL;
// start the resource stack
......@@ -542,6 +546,9 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, Catalog *catalogA,
catalog = catalogA;
subPage = gTrue;
printCommands = globalParams->getPrintCommands();
textHaveCSPattern = gFalse;
drawText = gFalse;
maskHaveCSPattern = gFalse;
mcStack = NULL;
// start the resource stack
......@@ -1230,12 +1237,32 @@ void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
void Gfx::opSetFillGray(Object args[], int numArgs) {
GfxColor color;
if (textHaveCSPattern) {
GBool needFill = out->deviceHasTextClip(state);
out->endTextObject(state);
if (needFill) {
doPatternFill(gTrue);
}
out->restoreState(state);
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
out->updateFillColorSpace(state);
color.c[0] = dblToCol(args[0].getNum());
state->setFillColor(&color);
out->updateFillColor(state);
out->beginTextObject(state);
out->updateRender(state);
out->updateTextMat(state);
out->updateTextPos(state);
textHaveCSPattern = gFalse;
} else {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
out->updateFillColorSpace(state);
color.c[0] = dblToCol(args[0].getNum());
state->setFillColor(&color);
out->updateFillColor(state);
}
}
void Gfx::opSetStrokeGray(Object args[], int numArgs) {
......@@ -1253,6 +1280,12 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
GfxColor color;
int i;
if (textHaveCSPattern) {
colorSpaceText = new GfxDeviceCMYKColorSpace();
for (i = 0; i < 4; ++i) {
colorText.c[i] = dblToCol(args[i].getNum());
}
} else {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
out->updateFillColorSpace(state);
......@@ -1261,6 +1294,7 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
}
state->setFillColor(&color);
out->updateFillColor(state);
}
}
void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) {
......@@ -1281,6 +1315,12 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
GfxColor color;
int i;
if (textHaveCSPattern) {
colorSpaceText = new GfxDeviceRGBColorSpace();
for (i = 0; i < 3; ++i) {
colorText.c[i] = dblToCol(args[i].getNum());
}
} else {
state->setFillPattern(NULL);
state->setFillColorSpace(new GfxDeviceRGBColorSpace());
out->updateFillColorSpace(state);
......@@ -1289,6 +1329,7 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
}
state->setFillColor(&color);
out->updateFillColor(state);
}
}
void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) {
......@@ -1324,6 +1365,24 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
colorSpace->getDefaultColor(&color);
state->setFillColor(&color);
out->updateFillColor(state);
if (drawText) {
if (colorSpace->getMode() == csPattern) {
colorSpaceText = NULL;
textHaveCSPattern = gTrue;
out->beginTextObject(state);
} else if (textHaveCSPattern) {
GBool needFill = out->deviceHasTextClip(state);
out->endTextObject(state);
if (needFill) {
doPatternFill(gTrue);
}
out->beginTextObject(state);
out->updateRender(state);
out->updateTextMat(state);
out->updateTextPos(state);
textHaveCSPattern = gFalse;
}
}
} else {
error(getPos(), "Bad color space (fill)");
}
......@@ -1847,7 +1906,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
if (stroke) {
state->clipToStrokePath();
out->clipToStrokePath(state);
} else {
} else if (!textHaveCSPattern && !maskHaveCSPattern) {
state->clip();
if (eoFill) {
out->eoClip(state);
......@@ -1975,7 +2034,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat,
if (stroke) {
state->clipToStrokePath();
out->clipToStrokePath(state);
} else {
} else if (!textHaveCSPattern && !maskHaveCSPattern) {
state->clip();
if (eoFill) {
out->eoClip(state);
......@@ -3121,15 +3180,38 @@ void Gfx::opEOClip(Object args[], int numArgs) {
//------------------------------------------------------------------------
void Gfx::opBeginText(Object args[], int numArgs) {
out->beginTextObject(state);
drawText = gTrue;
state->setTextMat(1, 0, 0, 1, 0, 0);
state->textMoveTo(0, 0);
out->updateTextMat(state);
out->updateTextPos(state);
fontChanged = gTrue;
if (out->supportTextCSPattern(state)) {
colorSpaceText = NULL;
textHaveCSPattern = gTrue;
}
}
void Gfx::opEndText(Object args[], int numArgs) {
GBool needFill = out->deviceHasTextClip(state);
out->endTextObject(state);
drawText = gFalse;
if (out->supportTextCSPattern(state) && textHaveCSPattern) {
if (needFill) {
doPatternFill(gTrue);
}
out->restoreState(state);
if (colorSpaceText != NULL) {
state->setFillPattern(NULL);
state->setFillColorSpace(colorSpaceText);
out->updateFillColorSpace(state);
state->setFillColor(&colorText);
out->updateFillColor(state);
colorSpaceText = NULL;
}
}
textHaveCSPattern = gFalse;
}
//------------------------------------------------------------------------
......@@ -3170,6 +3252,9 @@ void Gfx::opSetTextLeading(Object args[], int numArgs) {
void Gfx::opSetTextRender(Object args[], int numArgs) {
state->setRender(args[0].getInt());
if (args[0].getInt() == 7) {
textHaveCSPattern = gFalse;
}
out->updateRender(state);
}
......@@ -3695,6 +3780,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
// draw it
if (!contentIsHidden())
out->drawImageMask(state, ref, str, width, height, invert, inlineImg);
if (out->fillMaskCSPattern(state)) {
maskHaveCSPattern = gTrue;
doPatternFill(gTrue);
out->endMaskClip(state);
maskHaveCSPattern = gFalse;
}
} else {
......
......@@ -18,6 +18,7 @@
// Copyright (C) 2008 Brad Hards <bradh@kde.org>
// Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// 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
......@@ -33,6 +34,7 @@
#include "goo/gtypes.h"
#include "goo/GooList.h"
#include "GfxState.h"
#include "Object.h"
class GooString;
......@@ -175,6 +177,11 @@ private:
GBool subPage; // is this a sub-page object?
GBool printCommands; // print the drawing commands (for debugging)
GBool profileCommands; // profile the drawing commands (for debugging)
GBool textHaveCSPattern; // in text drawing and text has pattern colorspace
GBool drawText; // in text drawing
GBool maskHaveCSPattern; // in mask drawing and mask has pattern colorspace
GfxColorSpace *colorSpaceText;// colorspace after text has filled with pattern
GfxColor colorText; // fill color after after text has filled with pattern
GfxResources *res; // resource stack
int updateLevel;
......
......@@ -40,19 +40,12 @@
#include "Array.h"
#include "Page.h"
#include "GfxState.h"
#include "GfxState_helpers.h"
#include "GfxFont.h"
#include "GlobalParams.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;
......@@ -1077,7 +1070,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;
double c, m, y, k, c1, m1, y1, k1, r, g, b;
c = colToDbl(color->c[0]);
m = colToDbl(color->c[1]);
......@@ -1087,52 +1080,7 @@ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
m1 = 1 - m;
y1 = 1 - y;
k1 = 1 - k;
// this is a matrix multiplication, unrolled for performance
// C M Y K
x = c1 * m1 * y1 * k1; // 0 0 0 0
r = g = b = x;
x = c1 * m1 * y1 * k; // 0 0 0 1
r += 0.1373 * x;
g += 0.1216 * x;
b += 0.1255 * x;
x = c1 * m1 * y * k1; // 0 0 1 0
r += x;
g += 0.9490 * x;
x = c1 * m1 * y * k; // 0 0 1 1
r += 0.1098 * x;
g += 0.1020 * x;
x = c1 * m * y1 * k1; // 0 1 0 0
r += 0.9255 * x;
b += 0.5490 * x;
x = c1 * m * y1 * k; // 0 1 0 1
r += 0.1412 * x;
x = c1 * m * y * k1; // 0 1 1 0
r += 0.9294 * x;
g += 0.1098 * x;
b += 0.1412 * x;
x = c1 * m * y * k; // 0 1 1 1
r += 0.1333 * x;
x = c * m1 * y1 * k1; // 1 0 0 0
g += 0.6784 * x;
b += 0.9373 * x;
x = c * m1 * y1 * k; // 1 0 0 1
g += 0.0588 * x;
b += 0.1412 * x;
x = c * m1 * y * k1; // 1 0 1 0
g += 0.6510 * x;
b += 0.3137 * x;
x = c * m1 * y * k; // 1 0 1 1
g += 0.0745 * x;
x = c * m * y1 * k1; // 1 1 0 0
r += 0.1804 * x;
g += 0.1922 * x;
b += 0.5725 * x;
x = c * m * y1 * k; // 1 1 0 1
b += 0.0078 * x;
x = c * m * y * k1; // 1 1 1 0
r += 0.2118 * x;
g += 0.2119 * x;
b += 0.2235 * x;
cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
rgb->r = clip01(dblToCol(r));
rgb->g = clip01(dblToCol(g));
rgb->b = clip01(dblToCol(b));
......
//========================================================================
//
// GfxState.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
//
// 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
//
//========================================================================
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;
}
static inline void cmykToRGBMatrixMultiplication(const double &c, const double &m, const double &y, const double &k, const double &c1, const double &m1, const double &y1, const double &k1, double &r, double &g, double &b)
{
double x;
// this is a matrix multiplication, unrolled for performance
// C M Y K
x = c1 * m1 * y1 * k1; // 0 0 0 0
r = g = b = x;
x = c1 * m1 * y1 * k; // 0 0 0 1
r += 0.1373 * x;
g += 0.1216 * x;
b += 0.1255 * x;
x = c1 * m1 * y * k1; // 0 0 1 0
r += x;
g += 0.9490 * x;
x = c1 * m1 * y * k; // 0 0 1 1
r += 0.1098 * x;
g += 0.1020 * x;
x = c1 * m * y1 * k1; // 0 1 0 0
r += 0.9255 * x;
b += 0.5490 * x;
x = c1 * m * y1 * k; // 0 1 0 1
r += 0.1412 * x;
x = c1 * m * y * k1; // 0 1 1 0
r += 0.9294 * x;
g += 0.1098 * x;
b += 0.1412 * x;
x = c1 * m * y * k; // 0 1 1 1
r += 0.1333 * x;
x = c * m1 * y1 * k1; // 1 0 0 0
g += 0.6784 * x;
b += 0.9373 * x;
x = c * m1 * y1 * k; // 1 0 0 1
g += 0.0588 * x;
b += 0.1412 * x;
x = c * m1 * y * k1; // 1 0 1 0
g += 0.6510 * x;
b += 0.3137 * x;
x = c * m1 * y * k; // 1 0 1 1
g += 0.0745 * x;
x = c * m * y1 * k1; // 1 1 0 0
r += 0.1804 * x;
g += 0.1922 * x;
b += 0.5725 * x;
x = c * m * y1 * k; // 1 1 0 1
b += 0.0078 * x;
x = c * m * y * k1; // 1 1 1 0
r += 0.2118 * x;
g += 0.2119 * x;
b += 0.2235 * x;
}
......@@ -169,6 +169,7 @@ poppler_include_HEADERS = \
Gfx.h \
GfxFont.h \
GfxState.h \
GfxState_helpers.h \
GlobalParams.h \
JArithmeticDecoder.h \
JBIG2Stream.h \
......
......@@ -17,6 +17,7 @@
// Copyright (C) 2006 Thorkild Stray <thorkild@ifi.uio.no>
// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2007 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// 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
......@@ -94,6 +95,17 @@ public:
// Does this device need non-text content?
virtual GBool needNonText() { return gTrue; }
// If current colorspace ist pattern,
// does this device support text in pattern colorspace?
// Default is false
virtual GBool supportTextCSPattern(GfxState * /*state*/) { return gFalse; }
// If current colorspace ist pattern,
// need this device special handling for masks in pattern colorspace?
// Default is false
virtual GBool fillMaskCSPattern(GfxState * /*state*/) { return gFalse; }
virtual void endMaskClip(GfxState * /*state*/) {}
//----- initialization and control
// Set default transform matrix.
......@@ -204,6 +216,8 @@ public:
double /*dx*/, double /*dy*/,
CharCode /*code*/, Unicode * /*u*/, int /*uLen*/);
virtual void endType3Char(GfxState * /*state*/) {}
virtual void beginTextObject(GfxState * /*state*/) {}
virtual GBool deviceHasTextClip(GfxState * /*state*/) { return gFalse; }
virtual void endTextObject(GfxState * /*state*/) {}
//----- image drawing
......
This diff is collapsed.
......@@ -17,6 +17,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006-2008 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007 Brad Hards <bradh@kde.org>
// Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// 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
......@@ -33,6 +34,7 @@
#include <poppler-config.h>
#include <stddef.h>
#include "Object.h"
#include "GfxState.h"
#include "GlobalParams.h"
#include "OutputDev.h"
......@@ -125,6 +127,10 @@ public:
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gFalse; }
// This device now supports text in pattern colorspace!
virtual GBool supportTextCSPattern(GfxState *state)
{ return state->getFillColorSpace()->getMode() == csPattern; }
//----- header/trailer (used only if manualCtrl is true)
// Write the document-level header.
......@@ -216,6 +222,8 @@ public:
//----- text drawing
virtual void drawString(GfxState *state, GooString *s);
virtual void beginTextObject(GfxState *state);
virtual GBool deviceHasTextClip(GfxState *state) { return haveTextClip && haveCSPattern; }
virtual void endTextObject(GfxState *state);
//----- image drawing
......@@ -230,6 +238,12 @@ public:
GfxImageColorMap *colorMap,
Stream *maskStr, int maskWidth, int maskHeight,
GBool maskInvert);
// If current colorspace ist pattern,
// need this device special handling for masks in pattern colorspace?
// Default is false
virtual GBool fillMaskCSPattern(GfxState * state)
{ return state->getFillColorSpace()->getMode() == csPattern && (level != psLevel1 && level != psLevel1Sep); }
virtual void endMaskClip(GfxState * /*state*/);
#if OPI_SUPPORT
//----- OPI functions
......@@ -295,6 +309,7 @@ private:
void addProcessColor(double c, double m, double y, double k);
void addCustomColor(GfxSeparationColorSpace *sepCS);
void doPath(GfxPath *path);
void maskToClippingPath(Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert);
void doImageL1(Object *ref, GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len);
......@@ -400,6 +415,9 @@ private:
GBool haveTextClip; // set if text has been drawn with a
// clipping render mode
GBool haveCSPattern; // set if text has been drawn with a
// clipping render mode because of pattern colorspace
int savedRender; // use if pattern colorspace
GBool inType3Char; // inside a Type 3 CharProc
GooString *t3String; // Type 3 content string
......
This diff is collapsed.
......@@ -14,6 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Takashi Iwai <tiwai@suse.de>
// Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// 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
......@@ -79,6 +80,10 @@ public:
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gTrue; }
// This device now supports text in pattern colorspace!
virtual GBool supportTextCSPattern(GfxState *state)
{ return state->getFillColorSpace()->getMode() == csPattern; }
//----- initialization and control
// Start a page.
......@@ -110,6 +115,7 @@ public:
//----- update text state
virtual void updateFont(GfxState *state);
virtual void updateRender(GfxState *state);
//----- path painting
virtual void stroke(GfxState *state);
......@@ -130,6 +136,8 @@ public:
double dx, double dy,
CharCode code, Unicode *u, int uLen);
virtual void endType3Char(GfxState *state);
virtual void beginTextObject(GfxState *state);
virtual GBool deviceHasTextClip(GfxState *state) { return textClipPath && haveCSPattern; }
virtual void endTextObject(GfxState *state);
//----- image drawing
......@@ -150,6 +158,12 @@ public:
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap);
// If current colorspace ist pattern,
// need this device special handling for masks in pattern colorspace?
// Default is false
virtual GBool fillMaskCSPattern(GfxState * state)
{ return state->getFillColorSpace()->getMode() == csPattern; }
virtual void endMaskClip(GfxState * /*state*/);
//----- Type 3 font operators
virtual void type3D0(GfxState *state, double wx, double wy);
......@@ -225,6 +239,11 @@ private:
static GBool maskedImageSrc(void *data, SplashColorPtr line,
Guchar *alphaLine);
GBool haveCSPattern; // set if text has been drawn with a
// clipping render mode because of pattern colorspace
int savedRender; // use if pattern colorspace
GBool keepAlphaChannel; // don't fill with paper color, keep alpha channel
SplashColorMode colorMode;
int bitmapRowPad;
GBool bitmapTopDown;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment