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

Generated by: LCOV version 1.10