1 /******************************************************************************
2 internal.c
3
4 Change Control: DDMMYYYY
5 Michael Still File created 18012001
6
7 Purpose:
8 These are calls that are internal, but more generally useful than those
9 found in some of the functionality specific code files...
10
11 Copyright (C) Michael Still 2000 - 2002
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 ******************************************************************************/
27
28 #if defined _WINDOWS
29 #include "stdafx.h"
30 #else
31 #include <panda/constants.h>
32 #include <panda/functions.h>
33 #endif
34
35 /******************************************************************************
36 DOCBOOK START
37
38 FUNCTION panda_entergraphicsmode
39 PURPOSE make sure the page description stream is in graphics mode
40
41 SYNOPSIS START
42 #include<panda/constants.h>
43 #include<panda/functions.h>
44 void panda_entergraphicsmode (panda_page * target);
45 SYNOPSIS END
46
47 DESCRIPTION <command>PANDA INTERNAL</command>. PDF pages are described with a text stream full of commands. Many of these commands are similar to those used within Postscript. This function call ensures that the text stream is in a graphics state.
48
49 RETURNS Nothing
50
51 EXAMPLE START
52 #include<panda/constants.h>
53 #include<panda/functions.h>
54
55 panda_pdf *document;
56 panda_page *page;
57
58 panda_init();
59
60 document = panda_open("filename.pdf", "w");
61 page = panda_newpage (document, panda_pagesize_a4);
62 panda_entergraphicsmode (page);
63 EXAMPLE END
64 SEEALSO panda_exitgraphicsmode
65 DOCBOOK END
66 ******************************************************************************/
67
68 void
panda_entergraphicsmode(panda_page * target)69 panda_entergraphicsmode (panda_page * target)
70 {
71 // - save the current graphics state (q operator, p 386 of spec)
72 // - setup the current transformation matrix (ctm, s 3.2 and p 323 of spec)
73 // such that the image is scaled correctly (cm operator)
74 // - modify the ctm to shift the image to where it is meant to be on the
75 // the page
76 // - use the image xobject we have created (Do operator, p 348 of spec)
77 // - restore the graphics state to the way it was previously (Q operator,
78 // p 386 of spec)
79 if (target->contents->textmode == panda_true)
80 {
81 target->contents->layoutstream =
82 panda_streamprintf (target->contents->layoutstream, "ET\nq\n");
83 target->contents->textmode = panda_false;
84
85 #if defined DEBUG
86 printf ("Ended textmode for object %d\n", target->contents->number);
87 #endif
88 }
89 else if (target->contents->insidegraphicsblock == panda_false)
90 {
91 target->contents->layoutstream =
92 panda_streamprintf (target->contents->layoutstream, "q\n");
93 target->contents->insidegraphicsblock = panda_true;
94 }
95 }
96
97 /******************************************************************************
98 DOCBOOK START
99
100 FUNCTION panda_exitgraphicsmode
101 PURPOSE make sure the page description stream is out of graphics mode
102
103 SYNOPSIS START
104 #include<panda/constants.h>
105 #include<panda/functions.h>
106 void panda_exitgraphicsmode (panda_page * target);
107 SYNOPSIS END
108
109 DESCRIPTION <command>PANDA INTERNAL</command>. PDF pages are described with a text stream full of commands. Many of these commands are similar to those used within Postscript. This function call ensures that the text stream is not in a graphics state.
110
111 RETURNS Nothing
112
113 EXAMPLE START
114 #include<panda/constants.h>
115 #include<panda/functions.h>
116
117 panda_pdf *document;
118 panda_page *page;
119
120 panda_init();
121
122 document = panda_open("filename.pdf", "w");
123 page = panda_newpage (document, panda_pagesize_a4);
124 panda_entergraphicsmode (page);
125 ...
126 panda_exitgraphicsmode (page);
127 EXAMPLE END
128 SEEALSO panda_entergraphicsmode
129 DOCBOOK END
130 ******************************************************************************/
131
132 void
panda_exitgraphicsmode(panda_page * target)133 panda_exitgraphicsmode (panda_page * target)
134 {
135 target->contents->layoutstream =
136 panda_streamprintf (target->contents->layoutstream, "Q\n\n");
137 target->contents->insidegraphicsblock = panda_false;
138 }
139
140 /******************************************************************************
141 DOCBOOK START
142
143 FUNCTION panda_createandinsertpage
144 PURPOSE create a page within the PDF document
145
146 SYNOPSIS START
147 #include<panda/constants.h>
148 #include<panda/functions.h>
149 void panda_createandinsertpage (panda_pdf *output);
150 SYNOPSIS END
151
152 DESCRIPTION <command>PANDA INTERNAL</command>. This function creates the objects required for a page to exist within <command>Panda</command>. This function is wrappered by other <command>Panda</command> function calls.
153
154 RETURNS A pointer to a panda_page object
155
156 EXAMPLE START
157 #include<panda/constants.h>
158 #include<panda/functions.h>
159
160 panda_pdf *document;
161 panda_page *page;
162
163 panda_init();
164
165 document = panda_open("filename.pdf", "w");
166 page = panda_createandinsertpage(document);
167 EXAMPLE END
168 DOCBOOK END
169 ******************************************************************************/
170
171 panda_page *
panda_createandinsertpage(panda_pdf * output)172 panda_createandinsertpage (panda_pdf * output)
173 {
174 panda_page *newPage;
175 panda_pagelist *lastPage, *prevPage;
176
177 // Make some space for the object
178 newPage = (panda_page *) panda_xmalloc (sizeof (panda_page));
179
180 // Store the page in the pagelist
181 lastPage = output->pageholders;
182 while (lastPage->next != NULL)
183 {
184 lastPage = lastPage->next;
185 }
186
187 // Add the page to the list
188 lastPage->me = newPage;
189 lastPage->next = panda_xmalloc (sizeof (panda_pagelist));
190 lastPage->next->next = NULL;
191
192 // Make the new page object
193 newPage->obj = (panda_object *) panda_newobject (output, panda_normal);
194
195 // Add it to the object tree
196 panda_addchild (output->pages, newPage->obj);
197
198 // We also need to do the same sort of thing for the contents object
199 // that each page owns
200 newPage->contents = (panda_object *) panda_newobject (output, panda_normal);
201 panda_addchild (newPage->obj, newPage->contents);
202 panda_adddictitem (output, newPage->obj, "Contents", panda_objectvalue,
203 newPage->contents);
204 newPage->contents->isContents = panda_true;
205
206 // Setup some stuff in the contents object that we need later
207 newPage->contents->textmode = panda_false;
208 newPage->contents->insidegraphicsblock = panda_false;
209
210 // Increment the page count for the PDF
211 output->pageCount++;
212
213 return newPage;
214 }
215