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