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&lt;panda/constants.h&gt;
43 #include&lt;panda/functions.h&gt;
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&lt;panda/constants.h&gt;
53 #include&lt;panda/functions.h&gt;
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&lt;panda/constants.h&gt;
105 #include&lt;panda/functions.h&gt;
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&lt;panda/constants.h&gt;
115 #include&lt;panda/functions.h&gt;
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&lt;panda/constants.h&gt;
148 #include&lt;panda/functions.h&gt;
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&lt;panda/constants.h&gt;
158 #include&lt;panda/functions.h&gt;
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