LCOV - code coverage report
Current view: top level - sdext/source/pdfimport/xpdfwrapper - pdfioutdev_gpl.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 269 434 62.0 %
Date: 2014-11-03 Functions: 41 54 75.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "pdfioutdev_gpl.hxx"
      21             : #include "pnghelper.hxx"
      22             : 
      23             : #include <stdlib.h>
      24             : #include <stdio.h>
      25             : #include <assert.h>
      26             : #include <math.h>
      27             : 
      28             : #include <boost/shared_array.hpp>
      29             : 
      30             : #if defined _MSC_VER
      31             : #pragma warning(push, 1)
      32             : #endif
      33             : 
      34             : // sigh, UTF8.h was removed in poppler-0.21.0 and put back in 0.21.1
      35             : // FIXME: we can't use #if POPPLER_CHECK_VERSION(0, 21, 0) && !POPPLER_CHECK_VERSION(0, 21, 1)
      36             : //        because the internal poppler does not provide poppler-version.h and the macro always returns 0
      37             : #if POPPLER_CHECK_VERSION(0, 21, 1)
      38             : #include "UTF8.h"
      39             : #elif POPPLER_CHECK_VERSION(0, 21, 0)
      40             : #include "UTF.h"
      41             : #else
      42             : #include "UTF8.h"
      43             : #endif
      44             : 
      45             : #if defined _MSC_VER
      46             : #pragma warning(pop)
      47             : #endif
      48             : 
      49             : #ifdef WNT
      50             : # define snprintf _snprintf
      51             : 
      52             : #if defined __GNUC__
      53             : #pragma GCC diagnostic warning "-Wformat"
      54             : #pragma GCC diagnostic warning "-Wformat-extra-args"
      55             : #endif
      56             : #endif
      57             : 
      58             : /* SYNC STREAMS
      59             :    ============
      60             : 
      61             :    We stream human-readble tokens to stdout, and binary data (fonts,
      62             :    bitmaps) to g_binary_out. Another process reads from those pipes, and
      63             :    there lies the rub: things can deadlock, if the two involved
      64             :    processes access the pipes in different order. At any point in
      65             :    time, both processes must access the same pipe. To ensure this,
      66             :    data must be flushed to the OS before writing to a different pipe,
      67             :    otherwise not-yet-written data will leave the reading process
      68             :    waiting on the wrong pipe.
      69             :  */
      70             : 
      71             : namespace pdfi
      72             : {
      73             : 
      74             : /// cut off very small numbers & clamp value to zero
      75        6606 : inline double normalize( double val )
      76             : {
      77        6606 :     return fabs(val) < 0.0000001 ? 0.0 : val;
      78             : }
      79             : 
      80             : namespace
      81             : {
      82             : 
      83             : /** Escapes line-ending characters (\n and \r) in input string.
      84             :   */
      85         696 : boost::shared_array<char> lcl_escapeLineFeeds(const char* const i_pStr)
      86             : {
      87         696 :     size_t nLength(strlen(i_pStr));
      88         696 :     char* pBuffer = new char[2*nLength+1];
      89             : 
      90         696 :     const char* pRead = i_pStr;
      91         696 :     char* pWrite = pBuffer;
      92        3168 :     while( nLength-- )
      93             :     {
      94        1776 :         if( *pRead == '\r' )
      95             :         {
      96           0 :             *pWrite++ = '\\';
      97           0 :             *pWrite++ = 'r';
      98             :         }
      99        1776 :         else if( *pRead == '\n' )
     100             :         {
     101           0 :             *pWrite++ = '\\';
     102           0 :             *pWrite++ = 'n';
     103             :         }
     104        1776 :         else if( *pRead == '\\' )
     105             :         {
     106           0 :             *pWrite++ = '\\';
     107           0 :             *pWrite++ = '\\';
     108             :         }
     109             :         else
     110        1776 :             *pWrite++ = *pRead;
     111        1776 :         pRead++;
     112             :     }
     113         696 :     *pWrite++ = 0;
     114             : 
     115         696 :     return boost::shared_array<char>(pBuffer);
     116             : }
     117             : 
     118             : }
     119             : 
     120             : /// for the temp char buffer the header gets snprintfed in
     121             : #define WRITE_BUFFER_SIZE 1024
     122             : 
     123             : /// for the initial std::vector capacity when copying stream from xpdf
     124             : #define WRITE_BUFFER_INITIAL_CAPACITY (1024*100)
     125             : 
     126           6 : void initBuf(OutputBuffer& io_rBuffer)
     127             : {
     128           6 :     io_rBuffer.reserve(WRITE_BUFFER_INITIAL_CAPACITY);
     129           6 : }
     130             : 
     131          12 : void writeBinaryBuffer( const OutputBuffer& rBuffer )
     132             : {
     133             :     // ---sync point--- see SYNC STREAMS above
     134          12 :     fflush(stdout);
     135             : 
     136             :     // put buffer to stderr
     137          12 :     if( !rBuffer.empty() )
     138          12 :         if( fwrite(&rBuffer[0], sizeof(char),
     139          12 :                    rBuffer.size(), g_binary_out) != (size_t)rBuffer.size() )
     140           0 :             exit(1); // error
     141             : 
     142             :     // ---sync point--- see SYNC STREAMS above
     143          12 :     fflush(g_binary_out);
     144          12 : }
     145             : 
     146           6 : bool ExtractJpegData(Stream* str, OutputBuffer& outBuf)
     147             : {
     148           6 :     int bytesToMarker = 0;
     149           6 :     int bytesToLen = -1;
     150           6 :     bool collectBytes = false;
     151           6 :     int startOfScan = 0;
     152           6 :     int b2 = -1;
     153           6 :     int b1 = -1;
     154             :     for (; ; )
     155             :     {
     156      264774 :         b2 = b1;
     157      264774 :         b1 = str->getChar();
     158             : 
     159      264774 :         if (b1 == -1)
     160           0 :             return false;
     161             : 
     162      264774 :         if (collectBytes)
     163             :         {
     164      264762 :             outBuf.push_back((Output_t)b1);
     165             : 
     166      264762 :             bytesToMarker--;
     167      264762 :             bytesToLen--;
     168             :         }
     169             : 
     170      264774 :         if (bytesToMarker == 0)
     171             :         {
     172          60 :             if (startOfScan == 1)
     173             :             {
     174           6 :                 bytesToMarker = -1;
     175           6 :                 startOfScan = 2;
     176             :             }
     177          54 :             else if (b2 == 0xFF)
     178             :             {
     179          48 :                 if (b1 == 0xD8)
     180             :                 {
     181           6 :                     collectBytes = true;
     182           6 :                     bytesToMarker = 2;
     183             : 
     184           6 :                     outBuf.push_back((Output_t)0xFF);
     185           6 :                     outBuf.push_back((Output_t)0xD8);
     186             :                 }
     187             :                 else
     188             :                 {
     189          42 :                     bytesToLen = 2;
     190             :                 }
     191          48 :                 if (b1 == 0xDA)
     192             :                 {
     193           6 :                     startOfScan = 1;
     194             :                 }
     195             :             }
     196           6 :             else if (collectBytes)
     197             :             {
     198           0 :                 return false;
     199             :             }
     200             :         }
     201             : 
     202      264774 :         if (bytesToLen == 0)
     203             :         {
     204          42 :             bytesToMarker = b2 * 256 + b1;
     205             :         }
     206             : 
     207      264774 :         if (startOfScan == 2)
     208      263262 :             if ((b2 == 0xFF) && (b1 == 0xD9))
     209           6 :                 return true;
     210      264768 :     }
     211             : }
     212             : 
     213           6 : void writeJpeg_( OutputBuffer& o_rOutputBuf, Stream* str, bool bWithLinefeed )
     214             : {
     215             :     // dump JPEG file as-is
     216             : #if POPPLER_CHECK_VERSION(0, 17, 3)
     217           6 :     str = str->getNextStream();
     218             : #else
     219             :     str = ((DCTStream *)str)->getRawStream();
     220             : #endif
     221           6 :     str->reset();
     222             : 
     223           6 :     o_rOutputBuf.clear();
     224           6 :     ExtractJpegData(str, o_rOutputBuf);
     225             : 
     226           6 :     printf( " JPEG %d", (int)o_rOutputBuf.size() );
     227           6 :     if( bWithLinefeed )
     228           6 :         printf("\n");
     229             : 
     230           6 :     str->close();
     231           6 : }
     232             : 
     233           0 : void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
     234             : {
     235             :     // write as PBM (char by char, to avoid stdlib lineend messing)
     236           0 :     o_rOutputBuf.clear();
     237           0 :     o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
     238           0 :     o_rOutputBuf[0] = 'P';
     239           0 :     o_rOutputBuf[1] = '4';
     240           0 :     o_rOutputBuf[2] = 0x0A;
     241           0 :     char *pAsCharPtr = reinterpret_cast<char *>(&o_rOutputBuf[3]);
     242           0 :     int nOutLen = snprintf(pAsCharPtr, WRITE_BUFFER_SIZE-10, "%d %d", width, height);
     243           0 :     if( nOutLen < 0 )
     244           0 :         nOutLen = WRITE_BUFFER_SIZE-10;
     245           0 :     o_rOutputBuf[3+nOutLen]  =0x0A;
     246           0 :     o_rOutputBuf[3+nOutLen+1]=0;
     247             : 
     248           0 :     const int header_size = 3+nOutLen+1;
     249           0 :     const int size = height * ((width + 7) / 8);
     250             : 
     251           0 :     printf( " PBM %d", size + header_size );
     252           0 :     if( bWithLinefeed )
     253           0 :         printf("\n");
     254             : 
     255             :     // trim buffer to exact header length
     256           0 :     o_rOutputBuf.resize(header_size);
     257             : 
     258             :     // initialize stream
     259           0 :     str->reset();
     260             : 
     261             :     // copy the raw stream
     262           0 :     if( bInvert )
     263             :     {
     264           0 :         for( int i=0; i<size; ++i)
     265           0 :             o_rOutputBuf.push_back(static_cast<char>(str->getChar() ^ 0xff));
     266             :     }
     267             :     else
     268             :     {
     269           0 :         for( int i=0; i<size; ++i)
     270           0 :             o_rOutputBuf.push_back(static_cast<char>(str->getChar()));
     271             :     }
     272             : 
     273           0 :     str->close();
     274           0 : }
     275             : 
     276           0 : void writePpm_( OutputBuffer&     o_rOutputBuf,
     277             :                 Stream*           str,
     278             :                 int               width,
     279             :                 int               height,
     280             :                 GfxImageColorMap* colorMap,
     281             :                 bool              bWithLinefeed )
     282             : {
     283             :     // write as PPM (char by char, to avoid stdlib lineend messing)
     284           0 :     o_rOutputBuf.clear();
     285           0 :     o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
     286           0 :     o_rOutputBuf[0] = 'P';
     287           0 :     o_rOutputBuf[1] = '6';
     288           0 :     o_rOutputBuf[2] = '\n';
     289           0 :     char *pAsCharPtr = reinterpret_cast<char *>(&o_rOutputBuf[3]);
     290           0 :     int nOutLen = snprintf(pAsCharPtr, WRITE_BUFFER_SIZE-10, "%d %d", width, height);
     291           0 :     if( nOutLen < 0 )
     292           0 :         nOutLen = WRITE_BUFFER_SIZE-10;
     293           0 :     o_rOutputBuf[3+nOutLen]  ='\n';
     294           0 :     o_rOutputBuf[3+nOutLen+1]='2';
     295           0 :     o_rOutputBuf[3+nOutLen+2]='5';
     296           0 :     o_rOutputBuf[3+nOutLen+3]='5';
     297           0 :     o_rOutputBuf[3+nOutLen+4]='\n';
     298           0 :     o_rOutputBuf[3+nOutLen+5]=0;
     299             : 
     300           0 :     const int header_size = 3+nOutLen+5;
     301           0 :     const int size = width*height*3 + header_size;
     302             : 
     303           0 :     printf( " PPM %d", size );
     304           0 :     if( bWithLinefeed )
     305           0 :         printf("\n");
     306             : 
     307             :     // trim buffer to exact header size
     308           0 :     o_rOutputBuf.resize(header_size);
     309             : 
     310             :     // initialize stream
     311             :     Guchar *p;
     312             :     GfxRGB rgb;
     313             :     ImageStream* imgStr =
     314             :         new ImageStream(str,
     315             :                         width,
     316             :                         colorMap->getNumPixelComps(),
     317           0 :                         colorMap->getBits());
     318           0 :     imgStr->reset();
     319             : 
     320           0 :     for( int y=0; y<height; ++y)
     321             :     {
     322           0 :         p = imgStr->getLine();
     323           0 :         for( int x=0; x<width; ++x)
     324             :         {
     325           0 :             colorMap->getRGB(p, &rgb);
     326           0 :             o_rOutputBuf.push_back(colToByte(rgb.r));
     327           0 :             o_rOutputBuf.push_back(colToByte(rgb.g));
     328           0 :             o_rOutputBuf.push_back(colToByte(rgb.b));
     329             : 
     330           0 :             p +=colorMap->getNumPixelComps();
     331             :         }
     332             :     }
     333             : 
     334           0 :     delete imgStr;
     335             : 
     336           0 : }
     337             : 
     338             : // call this only for 1 bit image streams !
     339           0 : void writePng_( OutputBuffer&     o_rOutputBuf,
     340             :                 Stream*           str,
     341             :                 int               width,
     342             :                 int               height,
     343             :                 GfxRGB&           zeroColor,
     344             :                 GfxRGB&           oneColor,
     345             :                 bool              bIsMask,
     346             :                 bool              bWithLinefeed )
     347             : {
     348           0 :     o_rOutputBuf.clear();
     349             : 
     350             :     // get png image
     351           0 :     PngHelper::createPng( o_rOutputBuf, str, width, height, zeroColor, oneColor, bIsMask );
     352             : 
     353           0 :     printf( " PNG %d", (int)o_rOutputBuf.size() );
     354           0 :     if( bWithLinefeed )
     355           0 :         printf("\n");
     356           0 : }
     357             : 
     358           0 : void writePng_( OutputBuffer& o_rOutputBuf,
     359             :                 Stream* str,
     360             :                 int width, int height, GfxImageColorMap* colorMap,
     361             :                 Stream* maskStr,
     362             :                 int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap,
     363             :                 bool bWithLinefeed )
     364             : {
     365           0 :     o_rOutputBuf.clear();
     366             : 
     367             :     // get png image
     368           0 :     PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap );
     369             : 
     370           0 :     printf( " PNG %d", (int)o_rOutputBuf.size() );
     371           0 :     if( bWithLinefeed )
     372           0 :         printf("\n");
     373           0 : }
     374             : 
     375           0 : void writePng_( OutputBuffer& o_rOutputBuf,
     376             :                 Stream* str,
     377             :                 int width, int height, GfxImageColorMap* colorMap,
     378             :                 Stream* maskStr,
     379             :                 int maskWidth, int maskHeight, bool maskInvert,
     380             :                 bool bWithLinefeed )
     381             : {
     382           0 :     o_rOutputBuf.clear();
     383             : 
     384             :     // get png image
     385           0 :     PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert );
     386             : 
     387           0 :     printf( " PNG %d", (int)o_rOutputBuf.size() );
     388           0 :     if( bWithLinefeed )
     389           0 :         printf("\n");
     390           0 : }
     391             : 
     392             : // stolen from ImageOutputDev.cc
     393           0 : void writeMask_( OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
     394             : {
     395           0 :     if( str->getKind() == strDCT )
     396           0 :         writeJpeg_(o_rOutputBuf, str, bWithLinefeed);
     397             :     else
     398           0 :         writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed, bInvert );
     399           0 : }
     400             : 
     401           6 : void writeImage_( OutputBuffer&     o_rOutputBuf,
     402             :                   Stream*           str,
     403             :                   int               width,
     404             :                   int               height,
     405             :                   GfxImageColorMap* colorMap,
     406             :                   bool              bWithLinefeed )
     407             : {
     408             :     // dump JPEG file
     409          18 :     if( str->getKind() == strDCT &&
     410          12 :         (colorMap->getNumPixelComps() == 1 ||
     411           6 :          colorMap->getNumPixelComps() == 3) )
     412             :     {
     413           6 :         writeJpeg_(o_rOutputBuf, str, bWithLinefeed);
     414             :     }
     415           0 :     else if (colorMap->getNumPixelComps() == 1 &&
     416           0 :              colorMap->getBits() == 1)
     417             :     {
     418             :         // this is a two color bitmap, write a png
     419             :         // provide default colors
     420           0 :         GfxRGB zeroColor = { 0, 0, 0 },
     421           0 :                 oneColor = { byteToCol( 0xff ), byteToCol( 0xff ), byteToCol( 0xff ) };
     422           0 :         if( colorMap->getColorSpace()->getMode() == csIndexed || colorMap->getColorSpace()->getMode() == csDeviceGray )
     423             :         {
     424           0 :             Guchar nIndex = 0;
     425           0 :             colorMap->getRGB( &nIndex, &zeroColor );
     426           0 :             nIndex = 1;
     427           0 :             colorMap->getRGB( &nIndex, &oneColor );
     428             :         }
     429           0 :         writePng_( o_rOutputBuf, str, width, height, zeroColor, oneColor, false, bWithLinefeed );
     430             :     }
     431             :     else
     432           0 :         writePpm_( o_rOutputBuf, str, width, height, colorMap, bWithLinefeed );
     433           6 : }
     434             : 
     435             : // forwarders
     436             : 
     437             : 
     438           6 : inline void writeImageLF( OutputBuffer&     o_rOutputBuf,
     439             :                           Stream*           str,
     440             :                           int               width,
     441             :                           int               height,
     442           6 :                           GfxImageColorMap* colorMap ) { writeImage_(o_rOutputBuf,str,width,height,colorMap,true); }
     443           0 : inline void writeMaskLF( OutputBuffer&     o_rOutputBuf,
     444             :                          Stream*           str,
     445             :                          int               width,
     446             :                          int               height,
     447           0 :                          bool              bInvert ) { writeMask_(o_rOutputBuf,str,width,height,true,bInvert); }
     448             : 
     449             : 
     450             : 
     451             : 
     452          18 : int PDFOutDev::parseFont( long long nNewId, GfxFont* gfxFont, GfxState* state ) const
     453             : {
     454          18 :     FontAttributes aNewFont;
     455          18 :     int nSize = 0;
     456             : 
     457          18 :     GooString* pFamily = gfxFont->getName();
     458          18 :     if( pFamily )
     459             :     {
     460          18 :         aNewFont.familyName.clear();
     461          18 :         aNewFont.familyName.append( gfxFont->getName() );
     462             :     }
     463             :     else
     464             :     {
     465           0 :         aNewFont.familyName.clear();
     466           0 :         aNewFont.familyName.append( "Arial" );
     467             :     }
     468             : 
     469          18 :     aNewFont.isBold        = gfxFont->isBold();
     470          18 :     aNewFont.isItalic      = gfxFont->isItalic();
     471          18 :     aNewFont.size          = state->getTransformedFontSize();
     472          18 :     aNewFont.isUnderline   = false;
     473             : 
     474          18 :     if( gfxFont->getType() == fontTrueType || gfxFont->getType() == fontType1 )
     475             :     {
     476             :         // TODO(P3): Unfortunately, need to read stream twice, since
     477             :         // we must write byte count to stdout before
     478          18 :         char* pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef(), &nSize );
     479          18 :         if( pBuf )
     480             :         {
     481          18 :             aNewFont.isEmbedded = true;
     482          18 :             gfree(pBuf);
     483             :         }
     484             :     }
     485             : 
     486          18 :     m_aFontMap[ nNewId ] = aNewFont;
     487          18 :     return nSize;
     488             : }
     489             : 
     490          18 : void PDFOutDev::writeFontFile( GfxFont* gfxFont ) const
     491             : {
     492          18 :     if( gfxFont->getType() != fontTrueType && gfxFont->getType() != fontType1 )
     493           0 :         return;
     494             : 
     495          18 :     int nSize = 0;
     496          18 :     char* pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef(), &nSize );
     497          18 :     if( !pBuf )
     498           0 :         return;
     499             : 
     500             :     // ---sync point--- see SYNC STREAMS above
     501          18 :     fflush(stdout);
     502             : 
     503          18 :     if( fwrite(pBuf, sizeof(char), nSize, g_binary_out) != (size_t)nSize )
     504             :     {
     505           0 :         gfree(pBuf);
     506           0 :         exit(1); // error
     507             :     }
     508             :     // ---sync point--- see SYNC STREAMS above
     509          18 :     fflush(g_binary_out);
     510          18 :     gfree(pBuf);
     511             : }
     512             : 
     513          30 : void PDFOutDev::printPath( GfxPath* pPath ) const
     514             : {
     515          30 :     int nSubPaths = pPath ? pPath->getNumSubpaths() : 0;
     516          60 :     for( int i=0; i<nSubPaths; i++ )
     517             :     {
     518          30 :         GfxSubpath* pSub  = pPath->getSubpath( i );
     519          30 :         const int nPoints = pSub->getNumPoints();
     520             : 
     521          30 :         printf( " subpath %d", pSub->isClosed() );
     522             : 
     523         192 :         for( int n=0; n<nPoints; ++n )
     524             :         {
     525             :             printf( " %f %f %d",
     526             :                     normalize(pSub->getX(n)),
     527             :                     normalize(pSub->getY(n)),
     528         162 :                     pSub->getCurve(n) );
     529             :         }
     530             :     }
     531          30 : }
     532             : 
     533           6 : PDFOutDev::PDFOutDev( PDFDoc* pDoc ) :
     534             :     m_pDoc( pDoc ),
     535             :     m_aFontMap(),
     536           6 :     m_pUtf8Map( new UnicodeMap((char*)"UTF-8", gTrue, &mapUTF8) )
     537             : {
     538           6 : }
     539          18 : PDFOutDev::~PDFOutDev()
     540             : {
     541           6 :     delete m_pUtf8Map;
     542          12 : }
     543             : 
     544           6 : void PDFOutDev::startPage(int /*pageNum*/, GfxState* state
     545             : #if POPPLER_CHECK_VERSION(0, 23, 0) ||  POPPLER_CHECK_VERSION(0, 24, 0)
     546             :                           , XRef* /*xref*/
     547             : #endif
     548             : )
     549             : {
     550             :     assert(state);
     551             :     printf("startPage %f %f\n",
     552             :            normalize(state->getPageWidth()),
     553           6 :            normalize(state->getPageHeight()));
     554           6 : }
     555             : 
     556           6 : void PDFOutDev::endPage()
     557             : {
     558           6 :     printf("endPage\n");
     559           6 : }
     560             : 
     561             : #if POPPLER_CHECK_VERSION(0, 19, 0)
     562           6 : void PDFOutDev::processLink(AnnotLink *link)
     563             : #elif POPPLER_CHECK_VERSION(0, 17, 0)
     564             : void PDFOutDev::processLink(AnnotLink *link, Catalog *)
     565             : #else
     566             : void PDFOutDev::processLink(Link* link, Catalog*)
     567             : #endif
     568             : {
     569             :     assert(link);
     570             : 
     571             :     double x1,x2,y1,y2;
     572           6 :     link->getRect( &x1, &y1, &x2, &y2 );
     573             : 
     574           6 :     LinkAction* pAction = link->getAction();
     575           6 :     if (pAction && pAction->getKind() == actionURI)
     576             :     {
     577           6 :         const char* pURI = static_cast<LinkURI*>(pAction)->getURI()->getCString();
     578             : 
     579           6 :         boost::shared_array<char> pEsc( lcl_escapeLineFeeds(pURI) );
     580             : 
     581             :         printf( "drawLink %f %f %f %f %s\n",
     582             :                 normalize(x1),
     583             :                 normalize(y1),
     584             :                 normalize(x2),
     585             :                 normalize(y2),
     586           6 :                 pEsc.get() );
     587             :     }
     588           6 : }
     589             : 
     590          96 : void PDFOutDev::saveState(GfxState*)
     591             : {
     592          96 :     printf( "saveState\n" );
     593          96 : }
     594             : 
     595          96 : void PDFOutDev::restoreState(GfxState*)
     596             : {
     597          96 :     printf( "restoreState\n" );
     598          96 : }
     599             : 
     600           6 : void PDFOutDev::setDefaultCTM(double *pMat)
     601             : {
     602             :     assert(pMat);
     603             : 
     604           6 :     OutputDev::setDefaultCTM(pMat);
     605             : 
     606             :     printf( "updateCtm %f %f %f %f %f %f\n",
     607             :             normalize(pMat[0]),
     608           6 :             normalize(pMat[1]),
     609           6 :             normalize(pMat[2]),
     610           6 :             normalize(pMat[3]),
     611           6 :             normalize(pMat[4]),
     612          30 :             normalize(pMat[5]) );
     613           6 : }
     614             : 
     615           6 : void PDFOutDev::updateCTM(GfxState* state,
     616             :                           double, double,
     617             :                           double, double,
     618             :                           double, double)
     619             : {
     620             :     assert(state);
     621             : 
     622           6 :     const double* const pMat = state->getCTM();
     623             :     assert(pMat);
     624             : 
     625             :     printf( "updateCtm %f %f %f %f %f %f\n",
     626             :             normalize(pMat[0]),
     627           6 :             normalize(pMat[1]),
     628           6 :             normalize(pMat[2]),
     629           6 :             normalize(pMat[3]),
     630           6 :             normalize(pMat[4]),
     631          30 :             normalize(pMat[5]) );
     632           6 : }
     633             : 
     634          12 : void PDFOutDev::updateLineDash(GfxState *state)
     635             : {
     636             :     assert(state);
     637             : 
     638             :     double* dashArray; int arrayLen; double startOffset;
     639          12 :     state->getLineDash(&dashArray, &arrayLen, &startOffset);
     640             : 
     641          12 :     printf( "updateLineDash" );
     642          12 :     if( arrayLen && dashArray )
     643             :     {
     644           6 :         printf( " %f %d", normalize(startOffset), arrayLen );
     645          30 :         for( int i=0; i<arrayLen; ++i )
     646          24 :             printf( " %f", normalize(*dashArray++) );
     647             :     }
     648          12 :     printf( "\n" );
     649          12 : }
     650             : 
     651           6 : void PDFOutDev::updateFlatness(GfxState *state)
     652             : {
     653             :     assert(state);
     654           6 :     printf( "updateFlatness %d\n", state->getFlatness() );
     655           6 : }
     656             : 
     657          18 : void PDFOutDev::updateLineJoin(GfxState *state)
     658             : {
     659             :     assert(state);
     660          18 :     printf( "updateLineJoin %d\n", state->getLineJoin() );
     661          18 : }
     662             : 
     663          18 : void PDFOutDev::updateLineCap(GfxState *state)
     664             : {
     665             :     assert(state);
     666          18 :     printf( "updateLineCap %d\n", state->getLineCap() );
     667          18 : }
     668             : 
     669           6 : void PDFOutDev::updateMiterLimit(GfxState *state)
     670             : {
     671             :     assert(state);
     672           6 :     printf( "updateMiterLimit %f\n", normalize(state->getMiterLimit()) );
     673           6 : }
     674             : 
     675          24 : void PDFOutDev::updateLineWidth(GfxState *state)
     676             : {
     677             :     assert(state);
     678          24 :     printf( "updateLineWidth %f\n", normalize(state->getLineWidth()) );
     679          24 : }
     680             : 
     681          84 : void PDFOutDev::updateFillColor(GfxState *state)
     682             : {
     683             :     assert(state);
     684             : 
     685             :     GfxRGB aRGB;
     686          84 :     state->getFillRGB( &aRGB );
     687             : 
     688             :     printf( "updateFillColor %f %f %f %f\n",
     689             :             normalize(colToDbl(aRGB.r)),
     690             :             normalize(colToDbl(aRGB.g)),
     691             :             normalize(colToDbl(aRGB.b)),
     692          84 :             normalize(state->getFillOpacity()) );
     693          84 : }
     694             : 
     695          24 : void PDFOutDev::updateStrokeColor(GfxState *state)
     696             : {
     697             :     assert(state);
     698             : 
     699             :     GfxRGB aRGB;
     700          24 :     state->getStrokeRGB( &aRGB );
     701             : 
     702             :     printf( "updateStrokeColor %f %f %f %f\n",
     703             :             normalize(colToDbl(aRGB.r)),
     704             :             normalize(colToDbl(aRGB.g)),
     705             :             normalize(colToDbl(aRGB.b)),
     706          24 :             normalize(state->getFillOpacity()) );
     707          24 : }
     708             : 
     709           6 : void PDFOutDev::updateFillOpacity(GfxState *state)
     710             : {
     711           6 :     updateFillColor(state);
     712           6 : }
     713             : 
     714           6 : void PDFOutDev::updateStrokeOpacity(GfxState *state)
     715             : {
     716           6 :     updateStrokeColor(state);
     717           6 : }
     718             : 
     719           6 : void PDFOutDev::updateBlendMode(GfxState*)
     720             : {
     721           6 : }
     722             : 
     723          72 : void PDFOutDev::updateFont(GfxState *state)
     724             : {
     725             :     assert(state);
     726             : 
     727          72 :     GfxFont *gfxFont = state->getFont();
     728          72 :     if( gfxFont )
     729             :     {
     730          66 :         FontAttributes aFont;
     731          66 :         int nEmbedSize=0;
     732             : 
     733          66 :         Ref* pID = gfxFont->getID();
     734             :         // TODO(Q3): Portability problem
     735          66 :         long long fontID = (long long)pID->gen << 32 | (long long)pID->num;
     736             :         boost::unordered_map< long long, FontAttributes >::const_iterator it =
     737          66 :             m_aFontMap.find( fontID );
     738          66 :         if( it == m_aFontMap.end() )
     739             :         {
     740          18 :             nEmbedSize = parseFont( fontID, gfxFont, state );
     741          18 :             it = m_aFontMap.find( fontID );
     742             :         }
     743             : 
     744          66 :         printf( "updateFont" );
     745          66 :         if( it != m_aFontMap.end() )
     746             :         {
     747             :             // conflating this with printf below crashes under Windoze
     748          66 :             printf( " %lld", fontID );
     749             : 
     750          66 :             aFont = it->second;
     751             : 
     752          66 :             boost::shared_array<char> pEsc( lcl_escapeLineFeeds(aFont.familyName.getCString()) );
     753             :             printf( " %d %d %d %d %f %d %s",
     754             :                     aFont.isEmbedded,
     755             :                     aFont.isBold,
     756             :                     aFont.isItalic,
     757             :                     aFont.isUnderline,
     758             :                     normalize(state->getTransformedFontSize()),
     759             :                     nEmbedSize,
     760          66 :                     pEsc.get() );
     761             :         }
     762          66 :         printf( "\n" );
     763             : 
     764          66 :         if( nEmbedSize )
     765          18 :             writeFontFile(gfxFont);
     766             :     }
     767          72 : }
     768             : 
     769           0 : void PDFOutDev::updateRender(GfxState *state)
     770             : {
     771             :     assert(state);
     772             : 
     773           0 :     printf( "setTextRenderMode %d\n", state->getRender() );
     774           0 : }
     775             : 
     776          12 : void PDFOutDev::stroke(GfxState *state)
     777             : {
     778             :     assert(state);
     779             : 
     780          12 :     printf( "strokePath" );
     781          12 :     printPath( state->getPath() );
     782          12 :     printf( "\n" );
     783          12 : }
     784             : 
     785           0 : void PDFOutDev::fill(GfxState *state)
     786             : {
     787             :     assert(state);
     788             : 
     789           0 :     printf( "fillPath" );
     790           0 :     printPath( state->getPath() );
     791           0 :     printf( "\n" );
     792           0 : }
     793             : 
     794           6 : void PDFOutDev::eoFill(GfxState *state)
     795             : {
     796             :     assert(state);
     797             : 
     798           6 :     printf( "eoFillPath" );
     799           6 :     printPath( state->getPath() );
     800           6 :     printf( "\n" );
     801           6 : }
     802             : 
     803           6 : void PDFOutDev::clip(GfxState *state)
     804             : {
     805             :     assert(state);
     806             : 
     807           6 :     printf( "clipPath" );
     808           6 :     printPath( state->getPath() );
     809           6 :     printf( "\n" );
     810           6 : }
     811             : 
     812           6 : void PDFOutDev::eoClip(GfxState *state)
     813             : {
     814             :     assert(state);
     815             : 
     816           6 :     printf( "eoClipPath" );
     817           6 :     printPath( state->getPath() );
     818           6 :     printf( "\n" );
     819           6 : }
     820             : 
     821             : /** Output one glyph
     822             : 
     823             : 
     824             :     @param dx
     825             :     horizontal skip for character (already scaled with font size) +
     826             :     inter-char space: cursor is shifted by this amount for next char
     827             : 
     828             :     @param dy
     829             :     vertical skip for character (zero for horizontal writing mode):
     830             :     cursor is shifted by this amount for next char
     831             : 
     832             :     @param originX
     833             :     local offset of character (zero for horizontal writing mode). not
     834             :     taken into account for output pos updates. Used for vertical writing.
     835             : 
     836             :     @param originY
     837             :     local offset of character (zero for horizontal writing mode). not
     838             :     taken into account for output pos updates. Used for vertical writing.
     839             :  */
     840         624 : void PDFOutDev::drawChar(GfxState *state, double x, double y,
     841             :                          double dx, double dy,
     842             :                          double originX, double originY,
     843             :                          CharCode, int /*nBytes*/, Unicode *u, int uLen)
     844             : {
     845             :     assert(state);
     846             : 
     847         624 :     if( u == NULL )
     848         624 :         return;
     849             : 
     850         624 :     const double fontSize = state->getFontSize();
     851             : 
     852         624 :     const double aPositionX(x-originX);
     853         624 :     const double aPositionY(y-originY);
     854             : 
     855         624 :     const double* pTextMat=state->getTextMat();
     856             :     printf( "drawChar %f %f %f %f %f %f %f %f %f ",
     857             :             normalize(aPositionX),
     858             :             normalize(aPositionY),
     859             :             normalize(aPositionX + dx),
     860             :             normalize(aPositionY + dy),
     861             :             normalize(pTextMat[0]),
     862         624 :             normalize(pTextMat[2]),
     863         624 :             normalize(pTextMat[1]),
     864         624 :             normalize(pTextMat[3]),
     865             :             normalize(fontSize)
     866        2496 :             );
     867             : 
     868             :     // silence spurious warning
     869             :     (void)&mapUCS2;
     870             : 
     871             :     char buf[9];
     872        1248 :     for( int i=0; i<uLen; ++i )
     873             :     {
     874         624 :         buf[ m_pUtf8Map->mapUnicode(u[i], buf, sizeof(buf)-1) ] = 0;
     875         624 :         boost::shared_array<char> pEsc( lcl_escapeLineFeeds(buf) );
     876         624 :         printf( "%s", pEsc.get() );
     877         624 :     }
     878             : 
     879         624 :     printf( "\n" );
     880             : }
     881             : 
     882           0 : void PDFOutDev::drawString(GfxState*, GooString* /*s*/)
     883             : {
     884             :     // TODO(F3): NYI
     885           0 : }
     886             : 
     887          66 : void PDFOutDev::endTextObject(GfxState*)
     888             : {
     889          66 :     printf( "endTextObject\n" );
     890          66 : }
     891             : 
     892           0 : void PDFOutDev::drawImageMask(GfxState* pState, Object*, Stream* str,
     893             :                               int width, int height, GBool invert,
     894             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     895             :                               GBool /*interpolate*/,
     896             : #endif
     897             :                               GBool /*inlineImg*/ )
     898             : {
     899           0 :     OutputBuffer aBuf; initBuf(aBuf);
     900             : 
     901           0 :     printf( "drawMask %d %d %d", width, height, invert );
     902             : 
     903           0 :     int bitsPerComponent = 1;
     904           0 :     StreamColorSpaceMode csMode = streamCSNone;
     905           0 :     str->getImageParams( &bitsPerComponent, &csMode );
     906           0 :     if( bitsPerComponent == 1 && (csMode == streamCSNone || csMode == streamCSDeviceGray) )
     907             :     {
     908           0 :         GfxRGB oneColor = { dblToCol( 1.0 ), dblToCol( 1.0 ), dblToCol( 1.0 ) };
     909           0 :         GfxRGB zeroColor = { dblToCol( 0.0 ), dblToCol( 0.0 ), dblToCol( 0.0 ) };
     910           0 :         pState->getFillColorSpace()->getRGB( pState->getFillColor(), &zeroColor );
     911           0 :         if( invert )
     912           0 :             writePng_( aBuf, str, width, height, oneColor, zeroColor, true, true );
     913             :         else
     914           0 :             writePng_( aBuf, str, width, height, zeroColor, oneColor, true, true );
     915             :     }
     916             :     else
     917           0 :         writeMaskLF(aBuf, str, width, height, invert);
     918           0 :     writeBinaryBuffer(aBuf);
     919           0 : }
     920             : 
     921           6 : void PDFOutDev::drawImage(GfxState*, Object*, Stream* str,
     922             :                           int width, int height, GfxImageColorMap* colorMap,
     923             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     924             :                           GBool /*interpolate*/,
     925             : #endif
     926             :                           int* maskColors, GBool /*inlineImg*/ )
     927             : {
     928           6 :     OutputBuffer aBuf; initBuf(aBuf);
     929          12 :     OutputBuffer aMaskBuf;
     930             : 
     931           6 :     printf( "drawImage %d %d", width, height );
     932             : 
     933           6 :     if( maskColors )
     934             :     {
     935             :         // write mask colors. nBytes must be even - first half is
     936             :         // lower bound values, second half upper bound values
     937           0 :         if( colorMap->getColorSpace()->getMode() == csIndexed )
     938             :         {
     939           0 :             aMaskBuf.push_back( (char)maskColors[0] );
     940           0 :             aMaskBuf.push_back( (char)maskColors[gfxColorMaxComps] );
     941             :         }
     942             :         else
     943             :         {
     944             :             GfxRGB aMinRGB;
     945           0 :             colorMap->getColorSpace()->getRGB(
     946             :                 (GfxColor*)maskColors,
     947           0 :                 &aMinRGB );
     948             : 
     949             :             GfxRGB aMaxRGB;
     950           0 :             colorMap->getColorSpace()->getRGB(
     951             :                 (GfxColor*)maskColors+gfxColorMaxComps,
     952           0 :                 &aMaxRGB );
     953             : 
     954           0 :             aMaskBuf.push_back( colToByte(aMinRGB.r) );
     955           0 :             aMaskBuf.push_back( colToByte(aMinRGB.g) );
     956           0 :             aMaskBuf.push_back( colToByte(aMinRGB.b) );
     957           0 :             aMaskBuf.push_back( colToByte(aMaxRGB.r) );
     958           0 :             aMaskBuf.push_back( colToByte(aMaxRGB.g) );
     959           0 :             aMaskBuf.push_back( colToByte(aMaxRGB.b) );
     960             :         }
     961             :     }
     962             : 
     963           6 :     printf( " %d", (int)aMaskBuf.size() );
     964           6 :     writeImageLF( aBuf, str, width, height, colorMap );
     965           6 :     writeBinaryBuffer(aBuf);
     966          12 :     writeBinaryBuffer(aMaskBuf);
     967           6 : }
     968             : 
     969           0 : void PDFOutDev::drawMaskedImage(GfxState*, Object*, Stream* str,
     970             :                                 int width, int height,
     971             :                                 GfxImageColorMap* colorMap,
     972             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     973             :                                 GBool /*interpolate*/,
     974             : #endif
     975             :                                 Stream* maskStr,
     976             :                                 int maskWidth, int maskHeight,
     977             :                                 GBool maskInvert
     978             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     979             :                                 , GBool /*maskInterpolate*/
     980             : #endif
     981             :                                )
     982             : {
     983           0 :     OutputBuffer aBuf;     initBuf(aBuf);
     984           0 :     printf( "drawImage %d %d 0", width, height );
     985           0 :     writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert, true );
     986           0 :     writeBinaryBuffer( aBuf );
     987           0 : }
     988             : 
     989           0 : void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
     990             :                                     int width, int height,
     991             :                                     GfxImageColorMap* colorMap,
     992             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     993             :                                     GBool /*interpolate*/,
     994             : #endif
     995             :                                     Stream* maskStr,
     996             :                                     int maskWidth, int maskHeight,
     997             :                                     GfxImageColorMap* maskColorMap
     998             : #if POPPLER_CHECK_VERSION(0, 12, 0)
     999             :                                     , GBool /*maskInterpolate*/
    1000             : #endif
    1001             :                                    )
    1002             : {
    1003           0 :     OutputBuffer aBuf;     initBuf(aBuf);
    1004           0 :     printf( "drawImage %d %d 0", width, height );
    1005           0 :     writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap, true );
    1006           0 :     writeBinaryBuffer( aBuf );
    1007           0 : }
    1008             : 
    1009           6 : void PDFOutDev::setPageNum( int nNumPages )
    1010             : {
    1011             :     // TODO(F3): printf might format int locale-dependent!
    1012           6 :     printf("setPageNum %d\n", nNumPages);
    1013           6 : }
    1014             : 
    1015             : }
    1016             : 
    1017             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10