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