beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / PreScanOutputDev.cc
blobb2af18d86b871e8e4611869ff9c07cd2e1f3b007
1 //========================================================================
2 //
3 // PreScanOutputDev.cc
4 //
5 // Copyright 2005 Glyph & Cog, LLC
6 //
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
17 // Copyright (C) 2010, 2011 Albert Astals Cid <aacid@kde.org>
18 // Copyright (C) 2011, 2014 William Bader <williambader@hotmail.com>
19 // Copyright (C) 2011, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
20 // Copyright (C) 2011 Adrian Johnson <ajohnson@redneon.com>
22 // To see a description of the changes please see the Changelog file that
23 // came with your tarball or type make ChangeLog if you are building from git
25 //========================================================================
27 #include <config.h>
29 #ifdef USE_GCC_PRAGMAS
30 #pragma implementation
31 #endif
33 #include <math.h>
34 #include "GlobalParams.h"
35 #include "Gfx.h"
36 #include "GfxFont.h"
37 #include "Link.h"
38 #include "Catalog.h"
39 #include "Page.h"
40 #include "PreScanOutputDev.h"
42 //------------------------------------------------------------------------
43 // PreScanOutputDev
44 //------------------------------------------------------------------------
46 PreScanOutputDev::PreScanOutputDev(PDFDoc *docA) {
47 level = globalParams->getPSLevel();
48 doc = docA;
49 clearStats();
52 PreScanOutputDev::~PreScanOutputDev() {
55 void PreScanOutputDev::startPage(int /*pageNum*/, GfxState * /*state*/, XRef * /*xref*/) {
58 void PreScanOutputDev::endPage() {
61 void PreScanOutputDev::stroke(GfxState *state) {
62 double *dash;
63 int dashLen;
64 double dashStart;
66 check(state->getStrokeColorSpace(), state->getStrokeColor(),
67 state->getStrokeOpacity(), state->getBlendMode());
68 state->getLineDash(&dash, &dashLen, &dashStart);
69 if (dashLen != 0) {
70 gdi = gFalse;
74 void PreScanOutputDev::fill(GfxState *state) {
75 check(state->getFillColorSpace(), state->getFillColor(),
76 state->getFillOpacity(), state->getBlendMode());
79 void PreScanOutputDev::eoFill(GfxState *state) {
80 check(state->getFillColorSpace(), state->getFillColor(),
81 state->getFillOpacity(), state->getBlendMode());
84 GBool PreScanOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *catalog, Object *str,
85 double *pmat, int paintType, int /*tilingType*/, Dict *resDict,
86 double *mat, double *bbox,
87 int x0, int y0, int x1, int y1,
88 double xStep, double yStep) {
89 if (paintType == 1) {
90 GBool tilingNeeded = (x1 - x0 != 1 || y1 - y0 != 1);
91 if (tilingNeeded) {
92 inTilingPatternFill++;
94 gfx->drawForm(str, resDict, mat, bbox);
95 if (tilingNeeded) {
96 inTilingPatternFill--;
98 } else {
99 check(state->getFillColorSpace(), state->getFillColor(),
100 state->getFillOpacity(), state->getBlendMode());
102 return gTrue;
105 GBool PreScanOutputDev::functionShadedFill(GfxState *state,
106 GfxFunctionShading *shading) {
107 if (shading->getColorSpace()->getMode() != csDeviceGray &&
108 shading->getColorSpace()->getMode() != csCalGray) {
109 gray = gFalse;
111 mono = gFalse;
112 if (state->getFillOpacity() != 1 ||
113 state->getBlendMode() != gfxBlendNormal) {
114 transparency = gTrue;
116 return gTrue;
119 GBool PreScanOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/) {
120 if (shading->getColorSpace()->getMode() != csDeviceGray &&
121 shading->getColorSpace()->getMode() != csCalGray) {
122 gray = gFalse;
124 mono = gFalse;
125 if (state->getFillOpacity() != 1 ||
126 state->getBlendMode() != gfxBlendNormal) {
127 transparency = gTrue;
129 return gTrue;
132 GBool PreScanOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double /*sMin*/, double /*sMax*/) {
133 if (shading->getColorSpace()->getMode() != csDeviceGray &&
134 shading->getColorSpace()->getMode() != csCalGray) {
135 gray = gFalse;
137 mono = gFalse;
138 if (state->getFillOpacity() != 1 ||
139 state->getBlendMode() != gfxBlendNormal) {
140 transparency = gTrue;
142 return gTrue;
145 void PreScanOutputDev::clip(GfxState * /*state*/) {
146 //~ check for a rectangle "near" the edge of the page;
147 //~ else set gdi to false
150 void PreScanOutputDev::eoClip(GfxState * /*state*/) {
151 //~ see clip()
154 void PreScanOutputDev::beginStringOp(GfxState *state) {
155 int render;
156 GfxFont *font;
157 double m11, m12, m21, m22;
158 GBool simpleTTF;
160 render = state->getRender();
161 if (!(render & 1)) {
162 check(state->getFillColorSpace(), state->getFillColor(),
163 state->getFillOpacity(), state->getBlendMode());
165 if ((render & 3) == 1 || (render & 3) == 2) {
166 check(state->getStrokeColorSpace(), state->getStrokeColor(),
167 state->getStrokeOpacity(), state->getBlendMode());
170 font = state->getFont();
171 state->getFontTransMat(&m11, &m12, &m21, &m22);
172 //~ this should check for external fonts that are non-TrueType
173 simpleTTF = fabs(m11 + m22) < 0.01 &&
174 m11 > 0 &&
175 fabs(m12) < 0.01 &&
176 fabs(m21) < 0.01 &&
177 fabs(state->getHorizScaling() - 1) < 0.001 &&
178 (font->getType() == fontTrueType ||
179 font->getType() == fontTrueTypeOT);
180 if (simpleTTF) {
181 //~ need to create a FoFiTrueType object, and check for a Unicode cmap
183 if (state->getRender() != 0 || !simpleTTF) {
184 gdi = gFalse;
188 void PreScanOutputDev::endStringOp(GfxState * /*state*/) {
191 GBool PreScanOutputDev::beginType3Char(GfxState * /*state*/, double /*x*/, double /*y*/,
192 double /*dx*/, double /*dy*/,
193 CharCode /*code*/, Unicode * /*u*/, int /*uLen*/) {
194 // return false so all Type 3 chars get rendered (no caching)
195 return gFalse;
198 void PreScanOutputDev::endType3Char(GfxState * /*state*/) {
201 void PreScanOutputDev::drawImageMask(GfxState *state, Object * /*ref*/, Stream *str,
202 int width, int height, GBool /*invert*/,
203 GBool /*interpolate*/, GBool inlineImg) {
204 int i, j;
206 check(state->getFillColorSpace(), state->getFillColor(),
207 state->getFillOpacity(), state->getBlendMode());
208 gdi = gFalse;
209 if ((level == psLevel1 || level == psLevel1Sep) &&
210 (state->getFillColorSpace()->getMode() == csPattern || inTilingPatternFill > 0)) {
211 patternImgMask = gTrue;
214 if (inlineImg) {
215 str->reset();
216 j = height * ((width + 7) / 8);
217 for (i = 0; i < j; ++i)
218 str->getChar();
219 str->close();
223 void PreScanOutputDev::drawImage(GfxState *state, Object * /*ref*/, Stream *str,
224 int width, int height,
225 GfxImageColorMap *colorMap,
226 GBool /*interpolate*/, int * /*maskColors*/, GBool inlineImg) {
227 GfxColorSpace *colorSpace;
228 int i, j;
230 colorSpace = colorMap->getColorSpace();
231 if (colorSpace->getMode() == csIndexed) {
232 colorSpace = ((GfxIndexedColorSpace *)colorSpace)->getBase();
234 if (colorSpace->getMode() == csDeviceGray ||
235 colorSpace->getMode() == csCalGray) {
236 if (colorMap->getBits() > 1) {
237 mono = gFalse;
239 } else {
240 gray = gFalse;
241 mono = gFalse;
243 if (state->getFillOpacity() != 1 ||
244 state->getBlendMode() != gfxBlendNormal) {
245 transparency = gTrue;
247 gdi = gFalse;
248 if ((level == psLevel1 || level == psLevel1Sep) &&
249 inTilingPatternFill > 0) {
250 patternImgMask = gTrue;
253 if (inlineImg) {
254 str->reset();
255 j = height * ((width * colorMap->getNumPixelComps() *
256 colorMap->getBits() + 7) / 8);
257 for (i = 0; i < j; ++i)
258 str->getChar();
259 str->close();
263 void PreScanOutputDev::drawMaskedImage(GfxState *state, Object * /*ref*/,
264 Stream * /*str*/,
265 int /*width*/, int /*height*/,
266 GfxImageColorMap *colorMap,
267 GBool /*interpolate*/,
268 Stream * /*maskStr*/,
269 int /*maskWidth*/, int /*maskHeight*/,
270 GBool /*maskInvert*/, GBool /*maskInterpolate*/) {
271 GfxColorSpace *colorSpace;
273 colorSpace = colorMap->getColorSpace();
274 if (colorSpace->getMode() == csIndexed) {
275 colorSpace = ((GfxIndexedColorSpace *)colorSpace)->getBase();
277 if (colorSpace->getMode() == csDeviceGray ||
278 colorSpace->getMode() == csCalGray) {
279 if (colorMap->getBits() > 1) {
280 mono = gFalse;
282 } else {
283 gray = gFalse;
284 mono = gFalse;
286 if (state->getFillOpacity() != 1 ||
287 state->getBlendMode() != gfxBlendNormal) {
288 transparency = gTrue;
290 gdi = gFalse;
293 void PreScanOutputDev::drawSoftMaskedImage(GfxState * /*state*/, Object * /*ref*/,
294 Stream * /*str*/,
295 int /*width*/, int /*height*/,
296 GfxImageColorMap *colorMap,
297 GBool /*interpolate*/,
298 Stream * /*maskStr*/,
299 int /*maskWidth*/, int /*maskHeight*/,
300 GfxImageColorMap * /*maskColorMap*/,
301 GBool /*maskInterpolate*/) {
302 GfxColorSpace *colorSpace;
304 colorSpace = colorMap->getColorSpace();
305 if (colorSpace->getMode() == csIndexed) {
306 colorSpace = ((GfxIndexedColorSpace *)colorSpace)->getBase();
308 if (colorSpace->getMode() != csDeviceGray &&
309 colorSpace->getMode() != csCalGray) {
310 gray = gFalse;
312 mono = gFalse;
313 transparency = gTrue;
314 gdi = gFalse;
317 void PreScanOutputDev::beginTransparencyGroup(
318 GfxState * /*state*/, double * /*bbox*/,
319 GfxColorSpace * /*blendingColorSpace*/,
320 GBool /*isolated*/, GBool /*knockout*/,
321 GBool /*forSoftMask*/) {
322 gdi = gFalse;
325 void PreScanOutputDev::paintTransparencyGroup(GfxState *state, double * /*bbox*/)
327 check(state->getFillColorSpace(), state->getFillColor(),
328 state->getFillOpacity(), state->getBlendMode());
331 void PreScanOutputDev::setSoftMask(GfxState * /*state*/, double * /*bbox*/, GBool /*alpha*/,
332 Function * /*transferFunc*/, GfxColor * /*backdropColor*/)
334 transparency = gTrue;
337 void PreScanOutputDev::check(GfxColorSpace *colorSpace, GfxColor *color,
338 double opacity, GfxBlendMode blendMode) {
339 GfxRGB rgb;
341 if (colorSpace->getMode() == csPattern) {
342 mono = gFalse;
343 gray = gFalse;
344 gdi = gFalse;
345 } else {
346 colorSpace->getRGB(color, &rgb);
347 if (rgb.r != rgb.g || rgb.g != rgb.b || rgb.b != rgb.r) {
348 mono = gFalse;
349 gray = gFalse;
350 } else if (!((rgb.r == 0 && rgb.g == 0 && rgb.b == 0) ||
351 (rgb.r == gfxColorComp1 &&
352 rgb.g == gfxColorComp1 &&
353 rgb.b == gfxColorComp1))) {
354 mono = gFalse;
357 if (opacity != 1 || blendMode != gfxBlendNormal) {
358 transparency = gTrue;
362 void PreScanOutputDev::clearStats() {
363 mono = gTrue;
364 gray = gTrue;
365 transparency = gFalse;
366 gdi = gTrue;
367 patternImgMask = gFalse;
368 inTilingPatternFill = 0;