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

Generated by: LCOV version 1.10