1 //========================================================================
5 // Copyright 2005 Glyph & Cog, LLC
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 //========================================================================
29 #ifdef USE_GCC_PRAGMAS
30 #pragma implementation
34 #include "GlobalParams.h"
40 #include "PreScanOutputDev.h"
42 //------------------------------------------------------------------------
44 //------------------------------------------------------------------------
46 PreScanOutputDev::PreScanOutputDev(PDFDoc
*docA
) {
47 level
= globalParams
->getPSLevel();
52 PreScanOutputDev::~PreScanOutputDev() {
55 void PreScanOutputDev::startPage(int /*pageNum*/, GfxState
* /*state*/, XRef
* /*xref*/) {
58 void PreScanOutputDev::endPage() {
61 void PreScanOutputDev::stroke(GfxState
*state
) {
66 check(state
->getStrokeColorSpace(), state
->getStrokeColor(),
67 state
->getStrokeOpacity(), state
->getBlendMode());
68 state
->getLineDash(&dash
, &dashLen
, &dashStart
);
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
) {
90 GBool tilingNeeded
= (x1
- x0
!= 1 || y1
- y0
!= 1);
92 inTilingPatternFill
++;
94 gfx
->drawForm(str
, resDict
, mat
, bbox
);
96 inTilingPatternFill
--;
99 check(state
->getFillColorSpace(), state
->getFillColor(),
100 state
->getFillOpacity(), state
->getBlendMode());
105 GBool
PreScanOutputDev::functionShadedFill(GfxState
*state
,
106 GfxFunctionShading
*shading
) {
107 if (shading
->getColorSpace()->getMode() != csDeviceGray
&&
108 shading
->getColorSpace()->getMode() != csCalGray
) {
112 if (state
->getFillOpacity() != 1 ||
113 state
->getBlendMode() != gfxBlendNormal
) {
114 transparency
= gTrue
;
119 GBool
PreScanOutputDev::axialShadedFill(GfxState
*state
, GfxAxialShading
*shading
, double /*tMin*/, double /*tMax*/) {
120 if (shading
->getColorSpace()->getMode() != csDeviceGray
&&
121 shading
->getColorSpace()->getMode() != csCalGray
) {
125 if (state
->getFillOpacity() != 1 ||
126 state
->getBlendMode() != gfxBlendNormal
) {
127 transparency
= gTrue
;
132 GBool
PreScanOutputDev::radialShadedFill(GfxState
*state
, GfxRadialShading
*shading
, double /*sMin*/, double /*sMax*/) {
133 if (shading
->getColorSpace()->getMode() != csDeviceGray
&&
134 shading
->getColorSpace()->getMode() != csCalGray
) {
138 if (state
->getFillOpacity() != 1 ||
139 state
->getBlendMode() != gfxBlendNormal
) {
140 transparency
= 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*/) {
154 void PreScanOutputDev::beginStringOp(GfxState
*state
) {
157 double m11
, m12
, m21
, m22
;
160 render
= state
->getRender();
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 &&
177 fabs(state
->getHorizScaling() - 1) < 0.001 &&
178 (font
->getType() == fontTrueType
||
179 font
->getType() == fontTrueTypeOT
);
181 //~ need to create a FoFiTrueType object, and check for a Unicode cmap
183 if (state
->getRender() != 0 || !simpleTTF
) {
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)
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
) {
206 check(state
->getFillColorSpace(), state
->getFillColor(),
207 state
->getFillOpacity(), state
->getBlendMode());
209 if ((level
== psLevel1
|| level
== psLevel1Sep
) &&
210 (state
->getFillColorSpace()->getMode() == csPattern
|| inTilingPatternFill
> 0)) {
211 patternImgMask
= gTrue
;
216 j
= height
* ((width
+ 7) / 8);
217 for (i
= 0; i
< j
; ++i
)
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
;
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) {
243 if (state
->getFillOpacity() != 1 ||
244 state
->getBlendMode() != gfxBlendNormal
) {
245 transparency
= gTrue
;
248 if ((level
== psLevel1
|| level
== psLevel1Sep
) &&
249 inTilingPatternFill
> 0) {
250 patternImgMask
= gTrue
;
255 j
= height
* ((width
* colorMap
->getNumPixelComps() *
256 colorMap
->getBits() + 7) / 8);
257 for (i
= 0; i
< j
; ++i
)
263 void PreScanOutputDev::drawMaskedImage(GfxState
*state
, Object
* /*ref*/,
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) {
286 if (state
->getFillOpacity() != 1 ||
287 state
->getBlendMode() != gfxBlendNormal
) {
288 transparency
= gTrue
;
293 void PreScanOutputDev::drawSoftMaskedImage(GfxState
* /*state*/, Object
* /*ref*/,
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
) {
313 transparency
= gTrue
;
317 void PreScanOutputDev::beginTransparencyGroup(
318 GfxState
* /*state*/, double * /*bbox*/,
319 GfxColorSpace
* /*blendingColorSpace*/,
320 GBool
/*isolated*/, GBool
/*knockout*/,
321 GBool
/*forSoftMask*/) {
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
) {
341 if (colorSpace
->getMode() == csPattern
) {
346 colorSpace
->getRGB(color
, &rgb
);
347 if (rgb
.r
!= rgb
.g
|| rgb
.g
!= rgb
.b
|| rgb
.b
!= rgb
.r
) {
350 } else if (!((rgb
.r
== 0 && rgb
.g
== 0 && rgb
.b
== 0) ||
351 (rgb
.r
== gfxColorComp1
&&
352 rgb
.g
== gfxColorComp1
&&
353 rgb
.b
== gfxColorComp1
))) {
357 if (opacity
!= 1 || blendMode
!= gfxBlendNormal
) {
358 transparency
= gTrue
;
362 void PreScanOutputDev::clearStats() {
365 transparency
= gFalse
;
367 patternImgMask
= gFalse
;
368 inTilingPatternFill
= 0;