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"
72 return fabs(val) < 0.0000001 ? 0.0 : val;
80std::vector<char> lcl_escapeLineFeeds(
const char*
const i_pStr)
86 const char* pRead = i_pStr;
94 else if( *pRead ==
'\n' )
99 else if( *pRead ==
'\\' )
116#define WRITE_BUFFER_SIZE 1024
119#define WRITE_BUFFER_INITIAL_CAPACITY (1024*100)
132 if( !rBuffer.empty() )
133 if( fwrite(rBuffer.data(),
sizeof(
char),
134 rBuffer.size(),
g_binary_out) !=
static_cast<size_t>(rBuffer.size()) )
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)
190 else if (collectBytes)
198 bytesToMarker = b2 * 256 + b1;
201 if (startOfScan == 2)
202 if ((b2 == 0xFF) && (b1 == 0xD9))
210#if POPPLER_CHECK_VERSION(0, 17, 3)
211 str = str->getNextStream();
213 str = ((DCTStream *)str)->getRawStream();
217 o_rOutputBuf.clear();
220 printf(
" JPEG %d",
static_cast<int>(o_rOutputBuf.size()) );
229 o_rOutputBuf.clear();
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);
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 );
248 o_rOutputBuf.resize(header_size);
257 o_rOutputBuf.push_back(
static_cast<char>(str->getChar() ^ 0xff));
262 o_rOutputBuf.push_back(
static_cast<char>(str->getChar()));
272 GfxImageColorMap* colorMap )
275 o_rOutputBuf.clear();
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);
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 );
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();
330 GfxRGB
const & zeroColor,
331 GfxRGB
const & oneColor,
334 o_rOutputBuf.clear();
339 printf(
" PNG %d",
static_cast<int>(o_rOutputBuf.size()) );
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()) );
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()) );
376 if( str->getKind() == strDCT )
379 writePbm_(o_rOutputBuf, str, width, height, bInvert );
386 GfxImageColorMap* colorMap )
389 if( str->getKind() == strDCT &&
390 (colorMap->getNumPixelComps() == 1 ||
391 colorMap->getNumPixelComps() == 3) )
395 else if (colorMap->getNumPixelComps() == 1 &&
396 colorMap->getBits() == 1)
400 GfxRGB zeroColor = { 0, 0, 0 },
401 oneColor = { byteToCol( 0xff ), byteToCol( 0xff ), byteToCol( 0xff ) };
402 if( colorMap->getColorSpace()->getMode() == csIndexed || colorMap->getColorSpace()->getMode() == csDeviceGray )
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 );
422 GfxImageColorMap* colorMap ) {
writeImage_(o_rOutputBuf,str,width,height,colorMap); }
427 bool bInvert ) {
writeMask_(o_rOutputBuf,str,width,height,bInvert); }
435#if POPPLER_CHECK_VERSION(20, 12, 0)
436 std::string familyName = gfxFont->getNameWithoutSubsetTag();
438#if POPPLER_CHECK_VERSION(0, 71, 0)
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 !=
"" )
452#if POPPLER_CHECK_VERSION(0, 83, 0)
455 aNewFont.
familyName.append( familyName.c_str() );
465 aNewFont.
isItalic = gfxFont->isItalic();
466#if POPPLER_CHECK_VERSION(0, 83, 0)
467 aNewFont.
size = state->getTransformedFontSize();
469 aNewFont.
size =
const_cast<GfxState*
>(state)->getTransformedFontSize();
473 if( gfxFont->getType() == fontTrueType || gfxFont->getType() == fontType1 )
477#if POPPLER_CHECK_VERSION(22, 6, 0)
478 std::optional<std::vector<unsigned char>> pBuf = gfxFont->readEmbFontFile(
m_pDoc->getXRef() );
482 nSize = pBuf->size();
485 char* pBuf = gfxFont->readEmbFontFile(
m_pDoc->getXRef(), &nSize );
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 );
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) )
527 if( fwrite(pBuf,
sizeof(
char), nSize,
g_binary_out) !=
static_cast<size_t>(nSize) )
538#if POPPLER_CHECK_VERSION(0, 83, 0)
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 )
567 m_pUtf8Map( new UnicodeMap(
"UTF-8", true, &mapUTF8) ),
582 printf(
"startPage %f %f\n",
592#if POPPLER_CHECK_VERSION(0, 19, 0)
594#elif POPPLER_CHECK_VERSION(0, 17, 0)
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",
629 printf(
"saveState\n" );
634 printf(
"restoreState\n" );
637#if POPPLER_CHECK_VERSION(0, 71, 0)
645 OutputDev::setDefaultCTM(pMat);
647 printf(
"updateCtm %f %f %f %f %f %f\n",
663 const double*
const pMat = state->getCTM();
666 printf(
"updateCtm %f %f %f %f %f %f\n",
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++) );
706 printf(
"updateFlatness %d\n", state->getFlatness() );
714 printf(
"updateLineJoin %d\n", state->getLineJoin() );
722 printf(
"updateLineCap %d\n", state->getLineCap() );
730 printf(
"updateMiterLimit %f\n",
normalize(state->getMiterLimit()) );
738 printf(
"updateLineWidth %f\n",
normalize(state->getLineWidth()) );
748 state->getFillRGB( &aRGB );
750 printf(
"updateFillColor %f %f %f %f\n",
764 state->getStrokeRGB( &aRGB );
766 printf(
"updateStrokeColor %f %f %f %f\n",
795#if POPPLER_CHECK_VERSION(22, 6, 0)
796 GfxFont *gfxFont = state->getFont().get();
798 GfxFont *gfxFont = state->getFont();
806#if POPPLER_CHECK_VERSION(0, 64, 0)
809 Ref* pID = gfxFont->getID();
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 =
820 printf(
"updateFont" );
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()),
854 printf(
"setTextRenderMode %d\n", state->getRender() );
863 printf(
"strokePath" );
874 printf(
"fillPath" );
885 printf(
"eoFillPath" );
896 printf(
"clipPath" );
907 printf(
"eoClipPath" );
932#if POPPLER_CHECK_VERSION(0, 82, 0)
934 double dx,
double dy,
935 double originX,
double originY,
936 CharCode,
int ,
const Unicode *u,
int uLen)
940 double dx,
double dy,
941 double originX,
double originY,
942 CharCode,
int , 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 ",
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)
1024 printf(
"endTextObject\n" );
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 );
1056#if POPPLER_CHECK_VERSION(0, 82, 0)
1058 int width,
int height, GfxImageColorMap* colorMap,
1064 int width,
int height, GfxImageColorMap* colorMap,
1074 printf(
"drawImage %d %d", width, height );
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(
1090 reinterpret_cast<const GfxColor*
>(maskColors),
1092 reinterpret_cast<GfxColor*
>(maskColors),
1097 colorMap->getColorSpace()->getRGB(
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()) );
1121 int width,
int height,
1122 GfxImageColorMap* colorMap,
1125 int maskWidth,
int maskHeight,
1132 printf(
"drawImage %d %d 0", width, height );
1133 writePng_(
aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert );
1138 int width,
int height,
1139 GfxImageColorMap* colorMap,
1142 int maskWidth,
int maskHeight,
1143 GfxImageColorMap* maskColorMap
1150 printf(
"drawImage %d %d 0", width, height );
1151 writePng_(
aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap );
1158 printf(
"setPageNum %d\n", nNumPages);
virtual void endPage() override
virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, poppler_bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, poppler_bool maskInvert, poppler_bool maskInterpolate) override
virtual void updateRender(GfxState *state) override
virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, poppler_bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap, poppler_bool maskInterpolate) override
virtual void endTextObject(GfxState *state) override
virtual void clip(GfxState *state) override
virtual void updateLineWidth(GfxState *state) override
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, poppler_bool invert, poppler_bool interpolate, poppler_bool inlineImg) override
std::unique_ptr< UnicodeMap > m_pUtf8Map
void setSkipImages(bool bSkipImages)
virtual void updateLineJoin(GfxState *state) override
virtual void updateLineDash(GfxState *state) override
virtual void saveState(GfxState *state) override
int parseFont(long long nNewId, GfxFont *pFont, const GfxState *state) const
virtual void updateBlendMode(GfxState *state) override
void writeFontFile(GfxFont *gfxFont) const
virtual void eoClip(GfxState *state) override
static void printPath(GfxPath *pPath)
virtual void setDefaultCTM(double *ctm) override
virtual void drawString(GfxState *state, GooString *s) override
virtual void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, poppler_bool interpolate, int *maskColors, poppler_bool inlineImg) override
virtual void processLink(Link *link, Catalog *catalog) override
virtual void updateFillColor(GfxState *state) override
virtual void fill(GfxState *state) override
virtual void stroke(GfxState *state) override
virtual void restoreState(GfxState *state) override
virtual void eoFill(GfxState *state) override
virtual void updateStrokeColor(GfxState *state) override
static void setPageNum(int nNumPages)
virtual void updateLineCap(GfxState *state) override
virtual void updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) override
virtual ~PDFOutDev() override
virtual void updateFont(GfxState *state) override
virtual void updateStrokeOpacity(GfxState *state) override
std::unordered_map< long long, FontAttributes > m_aFontMap
virtual void updateFlatness(GfxState *state) override
virtual void updateFillOpacity(GfxState *state) override
virtual void updateMiterLimit(GfxState *state) override
virtual void startPage(int pageNum, GfxState *state) override
virtual void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, Unicode *u, int uLen) override
Output one glyph.
static void createPng(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxRGB const &zeroColor, GfxRGB const &oneColor, bool bIsMask)
static void writePbm_(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, bool bInvert)
static void writeBinaryBuffer(const OutputBuffer &rBuffer)
static void writeMask_(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, bool bInvert)
static double normalize(double val)
cut off very small numbers & clamp value to zero
static void writePpm_(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxImageColorMap *colorMap)
static void writePng_(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxRGB const &zeroColor, GfxRGB const &oneColor, bool bIsMask)
static void writeImageLF(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxImageColorMap *colorMap)
static void writeMaskLF(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, bool bInvert)
static void writeJpeg_(OutputBuffer &o_rOutputBuf, Stream *str)
static bool ExtractJpegData(Stream *str, OutputBuffer &outBuf)
static void initBuf(OutputBuffer &io_rBuffer)
static void writeImage_(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxImageColorMap *colorMap)
#define WRITE_BUFFER_SIZE
for the temp char buffer the header gets snprintfed in
#define WRITE_BUFFER_INITIAL_CAPACITY
for the initial std::vector capacity when copying stream from xpdf
std::vector< Output_t > OutputBuffer
#define POPPLER_CHECK_VERSION(major, minor, micro)
GfxFont::Weight maFontWeight
std::unique_ptr< char[]> aBuffer