1 /***************************************************************************
2 * Copyright (C) 2006 by Dominik Seichter *
3 * domseichter@web.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #include <podofo.h>
22 #include <fontconfig/fontconfig.h>
23 #include <cstdio>
24
25 using namespace PoDoFo;
26
27 #define MIN_PAGES 100
28
29 bool writeImmediately = true;
30
AddPage(PdfDocument * pDoc,const char * pszFontName,const char * pszImagePath)31 void AddPage( PdfDocument* pDoc, const char* pszFontName, const char* pszImagePath )
32 {
33 PdfPainter painter;
34 PdfPage* pPage;
35 PdfFont* pFont;
36 PdfFont* pArial;
37 PdfImage* pImage;
38 PdfRect rect;
39
40 try {
41 pFont = pDoc->CreateFont( pszFontName );
42 } catch ( PdfError & e ) {
43 e.PrintErrorMsg();
44 return;
45 }
46 pPage = pDoc->CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) );
47 pArial = pDoc->CreateFont( "Arial" );
48 pImage = new PdfImage( pDoc );
49
50 rect = pPage->GetMediaBox();
51
52 const char* pszText = "The red brown fox jumps over the lazy dog!";
53 double dX = rect.GetLeft() + 20.0;
54 double dY = rect.GetBottom() + rect.GetHeight() - 20.0;
55 double dW, dH;
56
57 pFont->SetFontSize( 16.0 );
58 pArial->SetFontSize( 24.0 );
59
60 painter.SetPage( pPage );
61 painter.SetFont( pFont );
62
63 dW = pFont->GetFontMetrics()->StringWidth( pszText );
64 dH = -pFont->GetFontMetrics()->GetDescent(); // GetDescent is usually negative!
65
66 pFont->SetFontSize( 24.0 );
67 dH += pFont->GetFontMetrics()->GetLineSpacing() * 2.0;
68
69 painter.Rectangle( dX, dY, dW, dH );
70 painter.Stroke();
71
72 dY -= pFont->GetFontMetrics()->GetLineSpacing();
73 painter.DrawText( dX, dY, "Hello World!" );
74 dY -= pFont->GetFontMetrics()->GetLineSpacing();
75 pFont->SetFontSize( 16.0 );
76 painter.DrawText( dX, dY, pszText );
77
78 painter.SetFont( pArial );
79 dY -= pArial->GetFontMetrics()->GetLineSpacing();
80 painter.DrawText( dX, dY, "The font used in this example is:" );
81 dY -= pArial->GetFontMetrics()->GetLineSpacing();
82 painter.DrawText( dX, dY, pszFontName );
83 dY -= pArial->GetFontMetrics()->GetLineSpacing();
84
85 #if defined PODOFO_HAVE_JPEG_LIB || defined PODOFO_HAVE_TIFF_LIB
86 try {
87 pImage->LoadFromFile( pszImagePath );
88 }
89 catch( PdfError & e )
90 {
91 e.PrintErrorMsg();
92 }
93
94 dY -= (pImage->GetHeight() * 0.5);
95 dX = ((rect.GetWidth() - (pImage->GetWidth()*0.5))/2.0);
96 painter.DrawImage( dX, dY, pImage, 0.5, 0.5 );
97 delete pImage; // delete image right after drawing
98 #endif
99
100 painter.FinishPage();
101 }
102
CreateLargePdf(const char * pszFilename,const char * pszImagePath)103 void CreateLargePdf( const char* pszFilename, const char* pszImagePath )
104 {
105 PdfDocument* pDoc = NULL;
106 FcObjectSet* pObjectSet;
107 FcFontSet* pFontSet;
108 FcPattern* pPattern;
109
110 if( !FcInit() )
111 {
112 fprintf( stderr, "Cannot load fontconfig!\n");
113 return;
114 }
115
116 pPattern = FcPatternCreate();
117 pObjectSet = FcObjectSetBuild( FC_FAMILY, FC_STYLE, NULL );
118 pFontSet = FcFontList( 0, pPattern, pObjectSet );
119
120 FcObjectSetDestroy( pObjectSet );
121 FcPatternDestroy( pPattern );
122
123 if( writeImmediately )
124 pDoc = new PdfStreamedDocument( pszFilename );
125 else
126 pDoc = new PdfMemDocument();
127
128 if( pFontSet )
129 {
130 for( int i=0; i< (pFontSet->nfont > MIN_PAGES ? MIN_PAGES : pFontSet->nfont );i++ )
131 {
132 FcValue v;
133
134 //FcPatternPrint( pFontSet->fonts[i] );
135 FcPatternGet( pFontSet->fonts[i], FC_FAMILY, 0, &v );
136 //font = FcNameUnparse( pFontSet->fonts[i] );
137 printf(" -> Drawing with font: %s\n", reinterpret_cast<const char*>(v.u.s) );
138 AddPage( pDoc, reinterpret_cast<const char*>(v.u.s), pszImagePath );
139 }
140
141 FcFontSetDestroy( pFontSet );
142 }
143
144
145 if( writeImmediately )
146 static_cast<PdfStreamedDocument*>(pDoc)->Close();
147 else
148 static_cast<PdfMemDocument*>(pDoc)->Write( pszFilename );
149 delete pDoc;
150 }
151
usage()152 void usage()
153 {
154 printf("Usage: LargetTest [-m] output_filename image_file\n"
155 " output_filename: filename to write produced pdf to\n"
156 " image_file: An image to embed in the PDF file\n"
157 "Options:\n"
158 " -m Build entire document in memory before writing\n"
159 "\n"
160 "Note that output should be the same with and without the -m option.\n");
161 }
162
main(int argc,char * argv[])163 int main( int argc, char* argv[] )
164 {
165 if( argc < 3 || argc > 4 )
166 {
167 usage();
168 return 1;
169 }
170 else if ( argc == 4)
171 {
172 // Handle options
173 // Is this argument an option?
174 if (argv[1][0] != '-')
175 {
176 usage();
177 return 1;
178 }
179 // Is it a recognised option?
180 if (argv[1][1] == 'm')
181 {
182 // User wants us to build the whole doc in RAM before writing it out.
183 writeImmediately = false;
184 ++argv;
185 }
186 else
187 {
188 printf("Unrecognised argument: %s", argv[1]);
189 usage();
190 return 1;
191 }
192 }
193
194 try {
195 CreateLargePdf( argv[1], argv[2] );
196
197 printf("\nWrote the PDF file %s successfully\n", argv[1] );
198
199 } catch( PdfError & e ) {
200 e.PrintErrorMsg();
201 return e.GetError();
202 }
203
204 return 0;
205 }
206