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