1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "pdfioutdev_gpl.hxx"
21 #include "pnghelper.hxx"
31 // sigh, UTF8.h was removed in poppler-0.21.0 and put back in 0.21.1, then renamed to UnicodeMapFuncs.h in 0.62.0
32 // FIXME: we can't use #if POPPLER_CHECK_VERSION(0, 21, 0) && !POPPLER_CHECK_VERSION(0, 21, 1)
33 // because the internal poppler does not provide poppler-version.h and the macro always returns 0
34 #if POPPLER_CHECK_VERSION(0, 62, 0)
35 #include <UnicodeMapFuncs.h>
36 #elif POPPLER_CHECK_VERSION(0, 21, 1)
38 #elif POPPLER_CHECK_VERSION(0, 21, 0)
45 # define snprintf _snprintf
48 #pragma GCC diagnostic warning "-Wformat"
49 #pragma GCC diagnostic warning "-Wformat-extra-args"
56 We stream human-readable tokens to stdout, and binary data (fonts,
57 bitmaps) to g_binary_out. Another process reads from those pipes, and
58 there lies the rub: things can deadlock, if the two involved
59 processes access the pipes in different order. At any point in
60 time, both processes must access the same pipe. To ensure this,
61 data must be flushed to the OS before writing to a different pipe,
62 otherwise not-yet-written data will leave the reading process
63 waiting on the wrong pipe.
69 /// cut off very small numbers & clamp value to zero
70 static double normalize( double val
)
72 return fabs(val
) < 0.0000001 ? 0.0 : val
;
78 /** Escapes line-ending characters (\n and \r) in input string.
80 std::vector
<char> lcl_escapeLineFeeds(const char* const i_pStr
)
82 size_t nLength(strlen(i_pStr
));
83 std::vector
<char> aBuffer
;
84 aBuffer
.reserve(2*nLength
+1);
86 const char* pRead
= i_pStr
;
91 aBuffer
.push_back('\\');
92 aBuffer
.push_back('r');
94 else if( *pRead
== '\n' )
96 aBuffer
.push_back('\\');
97 aBuffer
.push_back('n');
99 else if( *pRead
== '\\' )
101 aBuffer
.push_back('\\');
102 aBuffer
.push_back('\\');
105 aBuffer
.push_back(*pRead
);
108 aBuffer
.push_back(0);
115 /// for the temp char buffer the header gets snprintfed in
116 #define WRITE_BUFFER_SIZE 1024
118 /// for the initial std::vector capacity when copying stream from xpdf
119 #define WRITE_BUFFER_INITIAL_CAPACITY (1024*100)
121 static void initBuf(OutputBuffer
& io_rBuffer
)
123 io_rBuffer
.reserve(WRITE_BUFFER_INITIAL_CAPACITY
);
126 static void writeBinaryBuffer( const OutputBuffer
& rBuffer
)
128 // ---sync point--- see SYNC STREAMS above
131 // put buffer to stderr
132 if( !rBuffer
.empty() )
133 if( fwrite(rBuffer
.data(), sizeof(char),
134 rBuffer
.size(), g_binary_out
) != static_cast<size_t>(rBuffer
.size()) )
137 // ---sync point--- see SYNC STREAMS above
138 fflush(g_binary_out
);
141 static bool ExtractJpegData(Stream
* str
, OutputBuffer
& outBuf
)
143 int bytesToMarker
= 0;
145 bool collectBytes
= false;
158 outBuf
.push_back(static_cast<Output_t
>(b1
));
164 if (bytesToMarker
== 0)
166 if (startOfScan
== 1)
178 outBuf
.push_back(Output_t(0xFF));
179 outBuf
.push_back(Output_t(0xD8));
190 else if (collectBytes
)
198 bytesToMarker
= b2
* 256 + b1
;
201 if (startOfScan
== 2)
202 if ((b2
== 0xFF) && (b1
== 0xD9))
207 static void writeJpeg_( OutputBuffer
& o_rOutputBuf
, Stream
* str
)
209 // dump JPEG file as-is
210 #if POPPLER_CHECK_VERSION(0, 17, 3)
211 str
= str
->getNextStream();
213 str
= ((DCTStream
*)str
)->getRawStream();
217 o_rOutputBuf
.clear();
218 ExtractJpegData(str
, o_rOutputBuf
);
220 printf( " JPEG %d", static_cast<int>(o_rOutputBuf
.size()) );
226 static void writePbm_(OutputBuffer
& o_rOutputBuf
, Stream
* str
, int width
, int height
, bool bInvert
)
228 // write as PBM (char by char, to avoid stdlib lineend messing)
229 o_rOutputBuf
.clear();
230 o_rOutputBuf
.resize(WRITE_BUFFER_SIZE
);
231 o_rOutputBuf
[0] = 'P';
232 o_rOutputBuf
[1] = '4';
233 o_rOutputBuf
[2] = 0x0A;
234 char *pAsCharPtr
= reinterpret_cast<char *>(&o_rOutputBuf
[3]);
235 int nOutLen
= snprintf(pAsCharPtr
, WRITE_BUFFER_SIZE
-10, "%d %d", width
, height
);
237 nOutLen
= WRITE_BUFFER_SIZE
-10;
238 o_rOutputBuf
[3+nOutLen
] =0x0A;
239 o_rOutputBuf
[3+nOutLen
+1]=0;
241 const int header_size
= 3+nOutLen
+1;
242 const int size
= height
* ((width
+ 7) / 8);
244 printf( " PBM %d", size
+ header_size
);
247 // trim buffer to exact header length
248 o_rOutputBuf
.resize(header_size
);
253 // copy the raw stream
256 for( int i
=0; i
<size
; ++i
)
257 o_rOutputBuf
.push_back(static_cast<char>(str
->getChar() ^ 0xff));
261 for( int i
=0; i
<size
; ++i
)
262 o_rOutputBuf
.push_back(static_cast<char>(str
->getChar()));
268 static void writePpm_( OutputBuffer
& o_rOutputBuf
,
272 GfxImageColorMap
* colorMap
)
274 // write as PPM (char by char, to avoid stdlib lineend messing)
275 o_rOutputBuf
.clear();
276 o_rOutputBuf
.resize(WRITE_BUFFER_SIZE
);
277 o_rOutputBuf
[0] = 'P';
278 o_rOutputBuf
[1] = '6';
279 o_rOutputBuf
[2] = '\n';
280 char *pAsCharPtr
= reinterpret_cast<char *>(&o_rOutputBuf
[3]);
281 int nOutLen
= snprintf(pAsCharPtr
, WRITE_BUFFER_SIZE
-10, "%d %d", width
, height
);
283 nOutLen
= WRITE_BUFFER_SIZE
-10;
284 o_rOutputBuf
[3+nOutLen
] ='\n';
285 o_rOutputBuf
[3+nOutLen
+1]='2';
286 o_rOutputBuf
[3+nOutLen
+2]='5';
287 o_rOutputBuf
[3+nOutLen
+3]='5';
288 o_rOutputBuf
[3+nOutLen
+4]='\n';
289 o_rOutputBuf
[3+nOutLen
+5]=0;
291 const int header_size
= 3+nOutLen
+5;
292 const int size
= width
*height
*3 + header_size
;
294 printf( " PPM %d", size
);
297 // trim buffer to exact header size
298 o_rOutputBuf
.resize(header_size
);
303 std::unique_ptr
<ImageStream
> imgStr(
306 colorMap
->getNumPixelComps(),
307 colorMap
->getBits()));
310 for( int y
=0; y
<height
; ++y
)
312 p
= imgStr
->getLine();
313 for( int x
=0; x
<width
; ++x
)
315 colorMap
->getRGB(p
, &rgb
);
316 o_rOutputBuf
.push_back(colToByte(rgb
.r
));
317 o_rOutputBuf
.push_back(colToByte(rgb
.g
));
318 o_rOutputBuf
.push_back(colToByte(rgb
.b
));
320 p
+=colorMap
->getNumPixelComps();
325 // call this only for 1 bit image streams !
326 static void writePng_( OutputBuffer
& o_rOutputBuf
,
330 GfxRGB
const & zeroColor
,
331 GfxRGB
const & oneColor
,
334 o_rOutputBuf
.clear();
337 PngHelper::createPng( o_rOutputBuf
, str
, width
, height
, zeroColor
, oneColor
, bIsMask
);
339 printf( " PNG %d", static_cast<int>(o_rOutputBuf
.size()) );
343 static void writePng_( OutputBuffer
& o_rOutputBuf
,
345 int width
, int height
, GfxImageColorMap
* colorMap
,
347 int maskWidth
, int maskHeight
, GfxImageColorMap
* maskColorMap
)
349 o_rOutputBuf
.clear();
352 PngHelper::createPng( o_rOutputBuf
, str
, width
, height
, colorMap
, maskStr
, maskWidth
, maskHeight
, maskColorMap
);
354 printf( " PNG %d", static_cast<int>(o_rOutputBuf
.size()) );
358 static void writePng_( OutputBuffer
& o_rOutputBuf
,
360 int width
, int height
, GfxImageColorMap
* colorMap
,
362 int maskWidth
, int maskHeight
, bool maskInvert
)
364 o_rOutputBuf
.clear();
367 PngHelper::createPng( o_rOutputBuf
, str
, width
, height
, colorMap
, maskStr
, maskWidth
, maskHeight
, maskInvert
);
369 printf( " PNG %d", static_cast<int>(o_rOutputBuf
.size()) );
373 // stolen from ImageOutputDev.cc
374 static void writeMask_( OutputBuffer
& o_rOutputBuf
, Stream
* str
, int width
, int height
, bool bInvert
)
376 if( str
->getKind() == strDCT
)
377 writeJpeg_(o_rOutputBuf
, str
);
379 writePbm_(o_rOutputBuf
, str
, width
, height
, bInvert
);
382 static void writeImage_( OutputBuffer
& o_rOutputBuf
,
386 GfxImageColorMap
* colorMap
)
389 if( str
->getKind() == strDCT
&&
390 (colorMap
->getNumPixelComps() == 1 ||
391 colorMap
->getNumPixelComps() == 3) )
393 writeJpeg_(o_rOutputBuf
, str
);
395 else if (colorMap
->getNumPixelComps() == 1 &&
396 colorMap
->getBits() == 1)
398 // this is a two color bitmap, write a png
399 // provide default colors
400 GfxRGB zeroColor
= { 0, 0, 0 },
401 oneColor
= { byteToCol( 0xff ), byteToCol( 0xff ), byteToCol( 0xff ) };
402 if( colorMap
->getColorSpace()->getMode() == csIndexed
|| colorMap
->getColorSpace()->getMode() == csDeviceGray
)
404 unsigned char nIndex
= 0;
405 colorMap
->getRGB( &nIndex
, &zeroColor
);
407 colorMap
->getRGB( &nIndex
, &oneColor
);
409 writePng_( o_rOutputBuf
, str
, width
, height
, zeroColor
, oneColor
, false);
412 writePpm_( o_rOutputBuf
, str
, width
, height
, colorMap
);
418 static void writeImageLF( OutputBuffer
& o_rOutputBuf
,
422 GfxImageColorMap
* colorMap
) { writeImage_(o_rOutputBuf
,str
,width
,height
,colorMap
); }
423 static void writeMaskLF( OutputBuffer
& o_rOutputBuf
,
427 bool bInvert
) { writeMask_(o_rOutputBuf
,str
,width
,height
,bInvert
); }
430 int PDFOutDev::parseFont( long long nNewId
, GfxFont
* gfxFont
, const GfxState
* state
) const
432 FontAttributes aNewFont
;
435 #if POPPLER_CHECK_VERSION(20, 12, 0)
436 std::string familyName
= gfxFont
->getNameWithoutSubsetTag();
438 #if POPPLER_CHECK_VERSION(0, 71, 0) // GooString::toStr()
439 std::string familyName
= gfxFont
->getName()->toStr();
441 const GooString
* gooString
= gfxFont
->getName();
442 std::string familyName
= std::string(gooString
->getCString(), gooString
->getLength());
444 if (familyName
.length() > 7 && familyName
.at(6) == '+')
446 familyName
= familyName
.substr(7);
449 if( familyName
!= "" )
451 aNewFont
.familyName
.clear();
452 #if POPPLER_CHECK_VERSION(0, 83, 0) // GooString::append(const std::string&)
453 aNewFont
.familyName
.append( familyName
);
455 aNewFont
.familyName
.append( familyName
.c_str() );
460 aNewFont
.familyName
.clear();
461 aNewFont
.familyName
.append( "Arial" );
464 aNewFont
.maFontWeight
= gfxFont
->getWeight();
465 aNewFont
.isItalic
= gfxFont
->isItalic();
466 #if POPPLER_CHECK_VERSION(0, 83, 0) // const added to getTransformedFontSize
467 aNewFont
.size
= state
->getTransformedFontSize();
469 aNewFont
.size
= const_cast<GfxState
*>(state
)->getTransformedFontSize();
471 aNewFont
.isUnderline
= false;
473 if( gfxFont
->getType() == fontTrueType
|| gfxFont
->getType() == fontType1
)
475 // TODO(P3): Unfortunately, need to read stream twice, since
476 // we must write byte count to stdout before
477 #if POPPLER_CHECK_VERSION(22, 6, 0)
478 std::optional
<std::vector
<unsigned char>> pBuf
= gfxFont
->readEmbFontFile( m_pDoc
->getXRef() );
481 aNewFont
.isEmbedded
= true;
482 nSize
= pBuf
->size();
485 char* pBuf
= gfxFont
->readEmbFontFile( m_pDoc
->getXRef(), &nSize
);
488 aNewFont
.isEmbedded
= true;
494 m_aFontMap
[ nNewId
] = aNewFont
;
498 void PDFOutDev::writeFontFile( GfxFont
* gfxFont
) const
500 if( gfxFont
->getType() != fontTrueType
&& gfxFont
->getType() != fontType1
)
504 #if POPPLER_CHECK_VERSION(22, 6, 0)
505 std::optional
<std::vector
<unsigned char>> pBuf
= gfxFont
->readEmbFontFile( m_pDoc
->getXRef() );
507 nSize
= pBuf
->size();
511 char* pBuf
= gfxFont
->readEmbFontFile( m_pDoc
->getXRef(), &nSize
);
516 // ---sync point--- see SYNC STREAMS above
519 #if POPPLER_CHECK_VERSION(22, 6, 0)
520 if( fwrite(pBuf
->data(), sizeof(*pBuf
->data()), nSize
, g_binary_out
) != static_cast<size_t>(nSize
) )
524 // ---sync point--- see SYNC STREAMS above
525 fflush(g_binary_out
);
527 if( fwrite(pBuf
, sizeof(char), nSize
, g_binary_out
) != static_cast<size_t>(nSize
) )
532 // ---sync point--- see SYNC STREAMS above
533 fflush(g_binary_out
);
538 #if POPPLER_CHECK_VERSION(0, 83, 0)
539 void PDFOutDev::printPath( const GfxPath
* pPath
)
541 void PDFOutDev::printPath( GfxPath
* pPath
)
544 int nSubPaths
= pPath
? pPath
->getNumSubpaths() : 0;
545 for( int i
=0; i
<nSubPaths
; i
++ )
547 #if POPPLER_CHECK_VERSION(0, 83, 0)
550 GfxSubpath
* pSub
= pPath
->getSubpath( i
);
551 const int nPoints
= pSub
->getNumPoints();
553 printf( " subpath %d", pSub
->isClosed() );
555 for( int n
=0; n
<nPoints
; ++n
)
558 normalize(pSub
->getX(n
)),
559 normalize(pSub
->getY(n
)),
565 PDFOutDev::PDFOutDev( PDFDoc
* pDoc
) :
567 m_pUtf8Map( new UnicodeMap("UTF-8", true, &mapUTF8
) ),
571 PDFOutDev::~PDFOutDev()
575 void PDFOutDev::startPage(int /*pageNum*/, GfxState
* state
576 #if POPPLER_CHECK_VERSION(0, 23, 0) || POPPLER_CHECK_VERSION(0, 24, 0)
582 printf("startPage %f %f\n",
583 normalize(state
->getPageWidth()),
584 normalize(state
->getPageHeight()));
587 void PDFOutDev::endPage()
592 #if POPPLER_CHECK_VERSION(0, 19, 0)
593 void PDFOutDev::processLink(AnnotLink
*link
)
594 #elif POPPLER_CHECK_VERSION(0, 17, 0)
595 void PDFOutDev::processLink(AnnotLink
*link
, Catalog
*)
597 void PDFOutDev::processLink(Link
* link
, Catalog
*)
603 link
->getRect( &x1
, &y1
, &x2
, &y2
);
605 LinkAction
* pAction
= link
->getAction();
606 if (!(pAction
&& pAction
->getKind() == actionURI
))
609 #if POPPLER_CHECK_VERSION(0, 86, 0)
610 const char* pURI
= static_cast<LinkURI
*>(pAction
)->getURI().c_str();
611 #elif POPPLER_CHECK_VERSION(0, 72, 0)
612 const char* pURI
= static_cast<LinkURI
*>(pAction
)->getURI()->c_str();
614 const char* pURI
= static_cast<LinkURI
*>(pAction
)->getURI()->getCString();
617 std::vector
<char> aEsc( lcl_escapeLineFeeds(pURI
) );
619 printf( "drawLink %f %f %f %f %s\n",
627 void PDFOutDev::saveState(GfxState
*)
629 printf( "saveState\n" );
632 void PDFOutDev::restoreState(GfxState
*)
634 printf( "restoreState\n" );
637 #if POPPLER_CHECK_VERSION(0, 71, 0)
638 void PDFOutDev::setDefaultCTM(const double *pMat
)
640 void PDFOutDev::setDefaultCTM(double *pMat
)
645 OutputDev::setDefaultCTM(pMat
);
647 printf( "updateCtm %f %f %f %f %f %f\n",
653 normalize(pMat
[5]) );
656 void PDFOutDev::updateCTM(GfxState
* state
,
663 const double* const pMat
= state
->getCTM();
666 printf( "updateCtm %f %f %f %f %f %f\n",
672 normalize(pMat
[5]) );
675 void PDFOutDev::updateLineDash(GfxState
*state
)
681 int arrayLen
; double startOffset
;
682 #if POPPLER_CHECK_VERSION(22, 9, 0)
683 const std::vector
<double> &dash
= state
->getLineDash(&startOffset
);
684 const double* dashArray
= dash
.data();
685 arrayLen
= dash
.size();
688 state
->getLineDash(&dashArray
, &arrayLen
, &startOffset
);
691 printf( "updateLineDash" );
692 if( arrayLen
&& dashArray
)
694 printf( " %f %d", normalize(startOffset
), arrayLen
);
695 for( int i
=0; i
<arrayLen
; ++i
)
696 printf( " %f", normalize(*dashArray
++) );
701 void PDFOutDev::updateFlatness(GfxState
*state
)
706 printf( "updateFlatness %d\n", state
->getFlatness() );
709 void PDFOutDev::updateLineJoin(GfxState
*state
)
714 printf( "updateLineJoin %d\n", state
->getLineJoin() );
717 void PDFOutDev::updateLineCap(GfxState
*state
)
722 printf( "updateLineCap %d\n", state
->getLineCap() );
725 void PDFOutDev::updateMiterLimit(GfxState
*state
)
730 printf( "updateMiterLimit %f\n", normalize(state
->getMiterLimit()) );
733 void PDFOutDev::updateLineWidth(GfxState
*state
)
738 printf( "updateLineWidth %f\n", normalize(state
->getLineWidth()) );
741 void PDFOutDev::updateFillColor(GfxState
*state
)
748 state
->getFillRGB( &aRGB
);
750 printf( "updateFillColor %f %f %f %f\n",
751 normalize(colToDbl(aRGB
.r
)),
752 normalize(colToDbl(aRGB
.g
)),
753 normalize(colToDbl(aRGB
.b
)),
754 normalize(state
->getFillOpacity()) );
757 void PDFOutDev::updateStrokeColor(GfxState
*state
)
764 state
->getStrokeRGB( &aRGB
);
766 printf( "updateStrokeColor %f %f %f %f\n",
767 normalize(colToDbl(aRGB
.r
)),
768 normalize(colToDbl(aRGB
.g
)),
769 normalize(colToDbl(aRGB
.b
)),
770 normalize(state
->getFillOpacity()) );
773 void PDFOutDev::updateFillOpacity(GfxState
*state
)
777 updateFillColor(state
);
780 void PDFOutDev::updateStrokeOpacity(GfxState
*state
)
784 updateStrokeColor(state
);
787 void PDFOutDev::updateBlendMode(GfxState
*)
791 void PDFOutDev::updateFont(GfxState
*state
)
795 #if POPPLER_CHECK_VERSION(22, 6, 0)
796 GfxFont
*gfxFont
= state
->getFont().get();
798 GfxFont
*gfxFont
= state
->getFont();
803 FontAttributes aFont
;
806 #if POPPLER_CHECK_VERSION(0, 64, 0)
809 Ref
* pID
= gfxFont
->getID();
810 // TODO(Q3): Portability problem
811 long long fontID
= static_cast<long long>(pID
->gen
) << 32 | static_cast<long long>(pID
->num
);
812 std::unordered_map
< long long, FontAttributes
>::const_iterator it
=
813 m_aFontMap
.find( fontID
);
814 if( it
== m_aFontMap
.end() )
816 nEmbedSize
= parseFont( fontID
, gfxFont
, state
);
817 it
= m_aFontMap
.find( fontID
);
820 printf( "updateFont" );
821 if( it
!= m_aFontMap
.end() )
823 // conflating this with printf below crashes under Windoze
824 printf( " %lld", fontID
);
828 #if POPPLER_CHECK_VERSION(0, 72, 0)
829 std::vector
<char> aEsc( lcl_escapeLineFeeds(aFont
.familyName
.c_str()) );
831 std::vector
<char> aEsc( lcl_escapeLineFeeds(aFont
.familyName
.getCString()) );
833 printf( " %d %d %d %d %f %d %s",
838 normalize(state
->getTransformedFontSize()),
846 writeFontFile(gfxFont
);
850 void PDFOutDev::updateRender(GfxState
*state
)
854 printf( "setTextRenderMode %d\n", state
->getRender() );
857 void PDFOutDev::stroke(GfxState
*state
)
863 printf( "strokePath" );
864 printPath( state
->getPath() );
868 void PDFOutDev::fill(GfxState
*state
)
874 printf( "fillPath" );
875 printPath( state
->getPath() );
879 void PDFOutDev::eoFill(GfxState
*state
)
885 printf( "eoFillPath" );
886 printPath( state
->getPath() );
890 void PDFOutDev::clip(GfxState
*state
)
896 printf( "clipPath" );
897 printPath( state
->getPath() );
901 void PDFOutDev::eoClip(GfxState
*state
)
907 printf( "eoClipPath" );
908 printPath( state
->getPath() );
916 horizontal skip for character (already scaled with font size) +
917 inter-char space: cursor is shifted by this amount for next char
920 vertical skip for character (zero for horizontal writing mode):
921 cursor is shifted by this amount for next char
924 local offset of character (zero for horizontal writing mode). not
925 taken into account for output pos updates. Used for vertical writing.
928 local offset of character (zero for horizontal writing mode). not
929 taken into account for output pos updates. Used for vertical writing.
932 #if POPPLER_CHECK_VERSION(0, 82, 0)
933 void PDFOutDev::drawChar(GfxState
*state
, double x
, double y
,
934 double dx
, double dy
,
935 double originX
, double originY
,
936 CharCode
, int /*nBytes*/, const Unicode
*u
, int uLen
)
939 void PDFOutDev::drawChar(GfxState
*state
, double x
, double y
,
940 double dx
, double dy
,
941 double originX
, double originY
,
942 CharCode
, int /*nBytes*/, Unicode
*u
, int uLen
)
951 if (uLen
== 4 && u
[0] == '\t' && u
[1] == '\r' && u
[2] == ' ' && u
[3] == 0xA0)
959 if (state
->getFont()->getWMode())
961 csdy
= state
->getCharSpace();
963 csdy
+= state
->getWordSpace();
967 csdx
= state
->getCharSpace();
969 csdx
+= state
->getWordSpace();
970 csdx
*= state
->getHorizScaling();
975 state
->textTransformDelta(csdx
, csdy
, &cstdx
, &cstdy
);
977 const double fontSize
= state
->getFontSize();
979 const double aPositionX(x
-originX
);
980 const double aPositionY(y
-originY
);
982 const double* pTextMat
=state
->getTextMat();
983 printf( "drawChar %f %f %f %f %f %f %f %f %f ",
984 normalize(aPositionX
),
985 normalize(aPositionY
),
986 normalize(aPositionX
+ dx
- cstdx
),
987 normalize(aPositionY
+ dy
- cstdy
),
988 normalize(pTextMat
[0]),
989 normalize(pTextMat
[2]),
990 normalize(pTextMat
[1]),
991 normalize(pTextMat
[3]),
995 // silence spurious warning
996 #if POPPLER_CHECK_VERSION(0, 62, 0)
1003 for( int i
=0; i
<uLen
; ++i
)
1005 buf
[ m_pUtf8Map
->mapUnicode(u
[i
], buf
, sizeof(buf
)-1) ] = 0;
1006 std::vector
<char> aEsc( lcl_escapeLineFeeds(buf
) );
1007 printf( "%s", aEsc
.data() );
1013 #if POPPLER_CHECK_VERSION(0, 64, 0)
1014 void PDFOutDev::drawString(GfxState
*, const GooString
* /*s*/)
1016 void PDFOutDev::drawString(GfxState
*, GooString
* /*s*/)
1022 void PDFOutDev::endTextObject(GfxState
*)
1024 printf( "endTextObject\n" );
1027 void PDFOutDev::drawImageMask(GfxState
* pState
, Object
*, Stream
* str
,
1028 int width
, int height
, poppler_bool invert
,
1029 poppler_bool
/*interpolate*/,
1030 poppler_bool
/*inlineImg*/ )
1034 OutputBuffer aBuf
; initBuf(aBuf
);
1036 printf( "drawMask %d %d %d", width
, height
, invert
);
1038 int bitsPerComponent
= 1;
1039 StreamColorSpaceMode csMode
= streamCSNone
;
1040 str
->getImageParams( &bitsPerComponent
, &csMode
);
1041 if( bitsPerComponent
== 1 && (csMode
== streamCSNone
|| csMode
== streamCSDeviceGray
) )
1043 GfxRGB oneColor
= { dblToCol( 1.0 ), dblToCol( 1.0 ), dblToCol( 1.0 ) };
1044 GfxRGB zeroColor
= { dblToCol( 0.0 ), dblToCol( 0.0 ), dblToCol( 0.0 ) };
1045 pState
->getFillColorSpace()->getRGB( pState
->getFillColor(), &zeroColor
);
1047 writePng_( aBuf
, str
, width
, height
, oneColor
, zeroColor
, true );
1049 writePng_( aBuf
, str
, width
, height
, zeroColor
, oneColor
, true );
1052 writeMaskLF(aBuf
, str
, width
, height
, invert
);
1053 writeBinaryBuffer(aBuf
);
1056 #if POPPLER_CHECK_VERSION(0, 82, 0)
1057 void PDFOutDev::drawImage(GfxState
*, Object
*, Stream
* str
,
1058 int width
, int height
, GfxImageColorMap
* colorMap
,
1059 poppler_bool
/*interpolate*/,
1060 const int* maskColors
, poppler_bool
/*inlineImg*/ )
1063 void PDFOutDev::drawImage(GfxState
*, Object
*, Stream
* str
,
1064 int width
, int height
, GfxImageColorMap
* colorMap
,
1065 poppler_bool
/*interpolate*/,
1066 int* maskColors
, poppler_bool
/*inlineImg*/ )
1071 OutputBuffer aBuf
; initBuf(aBuf
);
1072 OutputBuffer aMaskBuf
;
1074 printf( "drawImage %d %d", width
, height
);
1078 // write mask colors. nBytes must be even - first half is
1079 // lower bound values, second half upper bound values
1080 if( colorMap
->getColorSpace()->getMode() == csIndexed
)
1082 aMaskBuf
.push_back( static_cast<char>(maskColors
[0]) );
1083 aMaskBuf
.push_back( static_cast<char>(maskColors
[gfxColorMaxComps
]) );
1088 colorMap
->getColorSpace()->getRGB(
1089 #if POPPLER_CHECK_VERSION(0, 82, 0)
1090 reinterpret_cast<const GfxColor
*>(maskColors
),
1092 reinterpret_cast<GfxColor
*>(maskColors
),
1097 colorMap
->getColorSpace()->getRGB(
1098 #if POPPLER_CHECK_VERSION(0, 82, 0)
1099 reinterpret_cast<const GfxColor
*>(maskColors
)+gfxColorMaxComps
,
1101 reinterpret_cast<GfxColor
*>(maskColors
)+gfxColorMaxComps
,
1105 aMaskBuf
.push_back( colToByte(aMinRGB
.r
) );
1106 aMaskBuf
.push_back( colToByte(aMinRGB
.g
) );
1107 aMaskBuf
.push_back( colToByte(aMinRGB
.b
) );
1108 aMaskBuf
.push_back( colToByte(aMaxRGB
.r
) );
1109 aMaskBuf
.push_back( colToByte(aMaxRGB
.g
) );
1110 aMaskBuf
.push_back( colToByte(aMaxRGB
.b
) );
1114 printf( " %d", static_cast<int>(aMaskBuf
.size()) );
1115 writeImageLF( aBuf
, str
, width
, height
, colorMap
);
1116 writeBinaryBuffer(aBuf
);
1117 writeBinaryBuffer(aMaskBuf
);
1120 void PDFOutDev::drawMaskedImage(GfxState
*, Object
*, Stream
* str
,
1121 int width
, int height
,
1122 GfxImageColorMap
* colorMap
,
1123 poppler_bool
/*interpolate*/,
1125 int maskWidth
, int maskHeight
,
1126 poppler_bool maskInvert
, poppler_bool
/*maskInterpolate*/
1131 OutputBuffer aBuf
; initBuf(aBuf
);
1132 printf( "drawImage %d %d 0", width
, height
);
1133 writePng_( aBuf
, str
, width
, height
, colorMap
, maskStr
, maskWidth
, maskHeight
, maskInvert
);
1134 writeBinaryBuffer( aBuf
);
1137 void PDFOutDev::drawSoftMaskedImage(GfxState
*, Object
*, Stream
* str
,
1138 int width
, int height
,
1139 GfxImageColorMap
* colorMap
,
1140 poppler_bool
/*interpolate*/,
1142 int maskWidth
, int maskHeight
,
1143 GfxImageColorMap
* maskColorMap
1144 , poppler_bool
/*maskInterpolate*/
1149 OutputBuffer aBuf
; initBuf(aBuf
);
1150 printf( "drawImage %d %d 0", width
, height
);
1151 writePng_( aBuf
, str
, width
, height
, colorMap
, maskStr
, maskWidth
, maskHeight
, maskColorMap
);
1152 writeBinaryBuffer( aBuf
);
1155 void PDFOutDev::setPageNum( int nNumPages
)
1157 // TODO(F3): printf might format int locale-dependent!
1158 printf("setPageNum %d\n", nNumPages
);
1161 void PDFOutDev::setSkipImages( bool bSkipImages
)
1163 m_bSkipImages
= bSkipImages
;
1168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */