1 /*
2  * << Haru Free PDF Library >> -- hpdf_page_operator.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8  *
9  * Permission to use, copy, modify, distribute and sell this software
10  * and its documentation for any purpose is hereby granted without fee,
11  * provided that the above copyright notice appear in all copies and
12  * that both that copyright notice and this permission notice appear
13  * in supporting documentation.
14  * It is provided "as is" without express or implied warranty.
15  *
16  */
17 
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
20 #include "hpdf_pages.h"
21 #include "hpdf.h"
22 
23 static const HPDF_Point INIT_POS = {0, 0};
24 static const HPDF_DashMode INIT_MODE = {{0, 0, 0, 0, 0, 0, 0, 0}, 0, 0};
25 
26 
27 static HPDF_STATUS
28 InternalWriteText  (HPDF_PageAttr    attr,
29                     const char      *text);
30 
31 
32 static HPDF_STATUS
33 InternalArc  (HPDF_Page    page,
34               HPDF_REAL    x,
35               HPDF_REAL    y,
36               HPDF_REAL    ray,
37               HPDF_REAL    ang1,
38               HPDF_REAL    ang2,
39               HPDF_BOOL    cont_flg);
40 
41 
42 static HPDF_STATUS
43 InternalShowTextNextLine  (HPDF_Page    page,
44                            const char  *text,
45                            HPDF_UINT    len);
46 
47 
48 
49 /*--- General graphics state ---------------------------------------------*/
50 
51 /* w */
52 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetLineWidth(HPDF_Page page,HPDF_REAL line_width)53 HPDF_Page_SetLineWidth  (HPDF_Page  page,
54                          HPDF_REAL  line_width)
55 {
56     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
57                     HPDF_GMODE_TEXT_OBJECT);
58     HPDF_PageAttr attr;
59 
60     HPDF_PTRACE ((" HPDF_Page_SetLineWidth\n"));
61 
62     if (ret != HPDF_OK)
63         return ret;
64 
65     attr = (HPDF_PageAttr)page->attr;
66 
67     if (line_width < 0)
68         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
69 
70     if (HPDF_Stream_WriteReal (attr->stream, line_width) != HPDF_OK)
71         return HPDF_CheckError (page->error);
72 
73     if (HPDF_Stream_WriteStr (attr->stream, " w\012") != HPDF_OK)
74         return HPDF_CheckError (page->error);
75 
76     attr->gstate->line_width = line_width;
77 
78     return ret;
79 }
80 
81 /* J */
82 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetLineCap(HPDF_Page page,HPDF_LineCap line_cap)83 HPDF_Page_SetLineCap  (HPDF_Page     page,
84                        HPDF_LineCap  line_cap)
85 {
86     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
87                     HPDF_GMODE_TEXT_OBJECT);
88     HPDF_PageAttr attr;
89 
90     HPDF_PTRACE ((" HPDF_Page_SetLineCap\n"));
91 
92     if (ret != HPDF_OK)
93         return ret;
94 
95     if (line_cap >= HPDF_LINECAP_EOF)
96         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE,
97                 (HPDF_STATUS)line_cap);
98 
99     attr = (HPDF_PageAttr)page->attr;
100 
101     if ((ret = HPDF_Stream_WriteInt (attr->stream,
102                 (HPDF_UINT)line_cap)) != HPDF_OK)
103         return ret;
104 
105     if ((ret = HPDF_Stream_WriteStr (attr->stream,
106                 " J\012")) != HPDF_OK)
107         return HPDF_CheckError (page->error);
108 
109     attr->gstate->line_cap = line_cap;
110 
111     return ret;
112 }
113 
114 /* j */
115 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetLineJoin(HPDF_Page page,HPDF_LineJoin line_join)116 HPDF_Page_SetLineJoin  (HPDF_Page      page,
117                         HPDF_LineJoin  line_join)
118 {
119     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
120                     HPDF_GMODE_TEXT_OBJECT);
121     HPDF_PageAttr attr;
122 
123     HPDF_PTRACE ((" HPDF_Page_SetLineJoin\n"));
124 
125     if (ret != HPDF_OK)
126         return ret;
127 
128     if (line_join >= HPDF_LINEJOIN_EOF)
129         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE,
130                 (HPDF_STATUS)line_join);
131 
132     attr = (HPDF_PageAttr)page->attr;
133 
134     if (HPDF_Stream_WriteInt (attr->stream, (HPDF_UINT)line_join) != HPDF_OK)
135         return HPDF_CheckError (page->error);
136 
137     if (HPDF_Stream_WriteStr (attr->stream, " j\012") != HPDF_OK)
138         return HPDF_CheckError (page->error);
139 
140     attr->gstate->line_join = line_join;
141 
142     return ret;
143 }
144 
145 /* M */
146 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetMiterLimit(HPDF_Page page,HPDF_REAL miter_limit)147 HPDF_Page_SetMiterLimit  (HPDF_Page  page,
148                           HPDF_REAL  miter_limit)
149 {
150     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
151                     HPDF_GMODE_TEXT_OBJECT);
152     HPDF_PageAttr attr;
153 
154     HPDF_PTRACE ((" HPDF_Page_SetMitterLimit\n"));
155 
156     if (ret != HPDF_OK)
157         return ret;
158 
159     attr = (HPDF_PageAttr)page->attr;
160 
161     if (miter_limit < 1)
162         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
163 
164     if (HPDF_Stream_WriteReal (attr->stream, miter_limit) != HPDF_OK)
165         return HPDF_CheckError (page->error);
166 
167     if (HPDF_Stream_WriteStr (attr->stream, " M\012") != HPDF_OK)
168         return HPDF_CheckError (page->error);
169 
170     attr->gstate->miter_limit = miter_limit;
171 
172     return ret;
173 }
174 
175 /* d */
176 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetDash(HPDF_Page page,const HPDF_UINT16 * dash_ptn,HPDF_UINT num_param,HPDF_UINT phase)177 HPDF_Page_SetDash  (HPDF_Page           page,
178                     const HPDF_UINT16  *dash_ptn,
179                     HPDF_UINT           num_param,
180                     HPDF_UINT           phase)
181 {
182     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
183                     HPDF_GMODE_TEXT_OBJECT);
184     char buf[HPDF_TMP_BUF_SIZ];
185     char *pbuf = buf;
186     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
187     const HPDF_UINT16 *pdash_ptn = dash_ptn;
188     HPDF_PageAttr attr;
189     HPDF_UINT i;
190 
191     HPDF_PTRACE ((" HPDF_Page_SetDash\n"));
192 
193     if (ret != HPDF_OK)
194         return ret;
195 
196     if (num_param != 1 && (num_param / 2) * 2 != num_param)
197         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_PARAM_COUNT,
198                 num_param);
199 
200     if (num_param == 0 && phase > 0)
201         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE,
202                 phase);
203 
204     if (!dash_ptn && num_param > 0)
205         return HPDF_RaiseError (page->error, HPDF_INVALID_PARAMETER,
206                 phase);
207 
208     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
209     *pbuf++ = '[';
210 
211     for (i = 0; i < num_param; i++) {
212         if (*pdash_ptn == 0 || *pdash_ptn > HPDF_MAX_DASH_PATTERN)
213             return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
214 
215         pbuf = HPDF_IToA (pbuf, *pdash_ptn, eptr);
216         *pbuf++ = ' ';
217         pdash_ptn++;
218     }
219 
220     *pbuf++ = ']';
221     *pbuf++ = ' ';
222 
223     pbuf = HPDF_IToA (pbuf, phase, eptr);
224     HPDF_StrCpy (pbuf, " d\012", eptr);
225 
226     attr = (HPDF_PageAttr)page->attr;
227 
228     if ((ret = HPDF_Stream_WriteStr (attr->stream, buf)) != HPDF_OK)
229         return HPDF_CheckError (page->error);
230 
231     attr->gstate->dash_mode = INIT_MODE;
232     attr->gstate->dash_mode.num_ptn = num_param;
233     attr->gstate->dash_mode.phase = phase;
234 
235     pdash_ptn = dash_ptn;
236     for (i = 0; i < num_param; i++) {
237         attr->gstate->dash_mode.ptn[i] = *pdash_ptn;
238         pdash_ptn++;
239     }
240 
241     return ret;
242 }
243 
244 
245 /* ri --not implemented yet */
246 
247 /* i */
248 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetFlat(HPDF_Page page,HPDF_REAL flatness)249 HPDF_Page_SetFlat  (HPDF_Page  page,
250                     HPDF_REAL  flatness)
251 {
252     HPDF_PageAttr attr;
253     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
254                     HPDF_GMODE_TEXT_OBJECT);
255 
256     HPDF_PTRACE ((" HPDF_Page_SetFlat\n"));
257 
258     if (ret != HPDF_OK)
259         return ret;
260 
261     attr = (HPDF_PageAttr)page->attr;
262 
263     if (flatness > 100 || flatness < 0)
264         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
265 
266     if (HPDF_Stream_WriteReal (attr->stream, flatness) != HPDF_OK)
267         return HPDF_CheckError (page->error);
268 
269     if (HPDF_Stream_WriteStr (attr->stream, " i\012") != HPDF_OK)
270         return HPDF_CheckError (page->error);
271 
272     attr->gstate->flatness = flatness;
273 
274     return ret;
275 }
276 
277 /* gs */
278 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetExtGState(HPDF_Page page,HPDF_ExtGState ext_gstate)279 HPDF_Page_SetExtGState  (HPDF_Page        page,
280                          HPDF_ExtGState   ext_gstate)
281 {
282     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
283     HPDF_PageAttr attr;
284     const char *local_name;
285 
286     HPDF_PTRACE ((" HPDF_Page_SetExtGState\n"));
287 
288     if (ret != HPDF_OK)
289         return ret;
290 
291     if (!HPDF_ExtGState_Validate (ext_gstate))
292         return HPDF_RaiseError (page->error, HPDF_INVALID_OBJECT, 0);
293 
294     if (page->mmgr != ext_gstate->mmgr)
295         return HPDF_RaiseError (page->error, HPDF_INVALID_EXT_GSTATE, 0);
296 
297     attr = (HPDF_PageAttr)page->attr;
298     local_name = HPDF_Page_GetExtGStateName (page, ext_gstate);
299 
300     if (!local_name)
301         return HPDF_CheckError (page->error);
302 
303     if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
304         return HPDF_CheckError (page->error);
305 
306     if (HPDF_Stream_WriteStr (attr->stream, " gs\012") != HPDF_OK)
307         return HPDF_CheckError (page->error);
308 
309     /* change objct class to read only. */
310     ext_gstate->header.obj_class = (HPDF_OSUBCLASS_EXT_GSTATE_R | HPDF_OCLASS_DICT);
311 
312     return ret;
313 }
314 
315 /* sh */
316 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetShading(HPDF_Page page,HPDF_Shading shading)317 HPDF_Page_SetShading  (HPDF_Page    page,
318                        HPDF_Shading shading)
319 {
320     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
321     HPDF_PageAttr attr;
322     const char *local_name;
323 
324     HPDF_PTRACE ((" HPDF_Page_SetShading\n"));
325 
326     if (ret != HPDF_OK)
327         return ret;
328 
329     if (page->mmgr != shading->mmgr)
330         return HPDF_RaiseError (page->error, HPDF_INVALID_OBJECT, 0);
331 
332     attr = (HPDF_PageAttr)page->attr;
333     local_name = HPDF_Page_GetShadingName (page, shading);
334 
335     if (!local_name)
336         return HPDF_CheckError (page->error);
337 
338     if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
339         return HPDF_CheckError (page->error);
340 
341     if (HPDF_Stream_WriteStr (attr->stream, " sh\012") != HPDF_OK)
342         return HPDF_CheckError (page->error);
343 
344     return ret;
345 }
346 
347 /*--- Special graphic state operator --------------------------------------*/
348 
349 /* q */
350 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_GSave(HPDF_Page page)351 HPDF_Page_GSave  (HPDF_Page  page)
352 {
353     HPDF_GState new_gstate;
354     HPDF_PageAttr attr;
355     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
356 
357     HPDF_PTRACE ((" HPDF_Page_GSave\n"));
358 
359     if (ret != HPDF_OK)
360         return ret;
361 
362     attr = (HPDF_PageAttr)page->attr;
363 
364     new_gstate = HPDF_GState_New (page->mmgr, attr->gstate);
365     if (!new_gstate)
366         return HPDF_CheckError (page->error);
367 
368     if (HPDF_Stream_WriteStr (attr->stream, "q\012") != HPDF_OK)
369         return HPDF_CheckError (page->error);
370 
371     attr->gstate = new_gstate;
372 
373     return ret;
374 }
375 
376 /* Q */
377 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_GRestore(HPDF_Page page)378 HPDF_Page_GRestore  (HPDF_Page  page)
379 {
380     HPDF_GState new_gstate;
381     HPDF_PageAttr attr;
382     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
383 
384     HPDF_PTRACE ((" HPDF_Page_GRestore\n"));
385 
386     if (ret != HPDF_OK)
387         return ret;
388 
389     attr = (HPDF_PageAttr)page->attr;
390 
391     if (!attr->gstate->prev)
392         return HPDF_RaiseError (page->error, HPDF_PAGE_CANNOT_RESTORE_GSTATE,
393                 0);
394 
395     new_gstate = HPDF_GState_Free (page->mmgr, attr->gstate);
396 
397     attr->gstate = new_gstate;
398 
399     if (HPDF_Stream_WriteStr (attr->stream, "Q\012") != HPDF_OK)
400         return HPDF_CheckError (page->error);
401 
402     return ret;
403 }
404 
405 /* cm */
406 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Concat(HPDF_Page page,HPDF_REAL a,HPDF_REAL b,HPDF_REAL c,HPDF_REAL d,HPDF_REAL x,HPDF_REAL y)407 HPDF_Page_Concat  (HPDF_Page         page,
408                    HPDF_REAL         a,
409                    HPDF_REAL         b,
410                    HPDF_REAL         c,
411                    HPDF_REAL         d,
412                    HPDF_REAL         x,
413                    HPDF_REAL         y)
414 {
415     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
416     char buf[HPDF_TMP_BUF_SIZ];
417     char *pbuf = buf;
418     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
419     HPDF_PageAttr attr;
420     HPDF_TransMatrix tm;
421 
422     HPDF_PTRACE ((" HPDF_Page_Concat\n"));
423 
424     if (ret != HPDF_OK)
425         return ret;
426 
427     attr = (HPDF_PageAttr)page->attr;
428 
429     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
430 
431     pbuf = HPDF_FToA (pbuf, a, eptr);
432     *pbuf++ = ' ';
433     pbuf = HPDF_FToA (pbuf, b, eptr);
434     *pbuf++ = ' ';
435     pbuf = HPDF_FToA (pbuf, c, eptr);
436     *pbuf++ = ' ';
437     pbuf = HPDF_FToA (pbuf, d, eptr);
438     *pbuf++ = ' ';
439     pbuf = HPDF_FToA (pbuf, x, eptr);
440     *pbuf++ = ' ';
441     pbuf = HPDF_FToA (pbuf, y, eptr);
442     HPDF_StrCpy (pbuf, " cm\012", eptr);
443 
444     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
445         return HPDF_CheckError (page->error);
446 
447     tm = attr->gstate->trans_matrix;
448 
449     attr->gstate->trans_matrix.a = tm.a * a + tm.b * c;
450     attr->gstate->trans_matrix.b = tm.a * b + tm.b * d;
451     attr->gstate->trans_matrix.c = tm.c * a + tm.d * c;
452     attr->gstate->trans_matrix.d = tm.c * b + tm.d * d;
453     attr->gstate->trans_matrix.x = tm.x + x * tm.a + y * tm.c;
454     attr->gstate->trans_matrix.y = tm.y + x * tm.b + y * tm.d;
455 
456     return ret;
457 }
458 
459 /*--- Path construction operator ------------------------------------------*/
460 
461 /* m */
462 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_MoveTo(HPDF_Page page,HPDF_REAL x,HPDF_REAL y)463 HPDF_Page_MoveTo  (HPDF_Page  page,
464                    HPDF_REAL  x,
465                    HPDF_REAL  y)
466 {
467     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
468                     HPDF_GMODE_PATH_OBJECT);
469     char buf[HPDF_TMP_BUF_SIZ];
470     char *pbuf = buf;
471     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
472     HPDF_PageAttr attr;
473 
474     HPDF_PTRACE ((" HPDF_Page_MoveTo\n"));
475 
476     if (ret != HPDF_OK)
477         return ret;
478 
479     attr = (HPDF_PageAttr)page->attr;
480 
481     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
482 
483     pbuf = HPDF_FToA (pbuf, x, eptr);
484     *pbuf++ = ' ';
485     pbuf = HPDF_FToA (pbuf, y, eptr);
486     HPDF_StrCpy (pbuf, " m\012", eptr);
487 
488     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
489         return HPDF_CheckError (page->error);
490 
491     attr->cur_pos.x = x;
492     attr->cur_pos.y = y;
493     attr->str_pos = attr->cur_pos;
494     attr->gmode = HPDF_GMODE_PATH_OBJECT;
495 
496     return ret;
497 }
498 
499 /* l */
500 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_LineTo(HPDF_Page page,HPDF_REAL x,HPDF_REAL y)501 HPDF_Page_LineTo  (HPDF_Page  page,
502                    HPDF_REAL  x,
503                    HPDF_REAL  y)
504 {
505     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
506     char buf[HPDF_TMP_BUF_SIZ];
507     char *pbuf = buf;
508     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
509     HPDF_PageAttr attr;
510 
511     HPDF_PTRACE ((" HPDF_Page_LineTo\n"));
512 
513     if (ret != HPDF_OK)
514         return ret;
515 
516     attr = (HPDF_PageAttr)page->attr;
517 
518     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
519 
520     pbuf = HPDF_FToA (pbuf, x, eptr);
521     *pbuf++ = ' ';
522     pbuf = HPDF_FToA (pbuf, y, eptr);
523     HPDF_StrCpy (pbuf, " l\012", eptr);
524 
525     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
526         return HPDF_CheckError (page->error);
527 
528     attr->cur_pos.x = x;
529     attr->cur_pos.y = y;
530 
531     return ret;
532 }
533 
534 /* c */
535 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_CurveTo(HPDF_Page page,HPDF_REAL x1,HPDF_REAL y1,HPDF_REAL x2,HPDF_REAL y2,HPDF_REAL x3,HPDF_REAL y3)536 HPDF_Page_CurveTo  (HPDF_Page  page,
537                     HPDF_REAL  x1,
538                     HPDF_REAL  y1,
539                     HPDF_REAL  x2,
540                     HPDF_REAL  y2,
541                     HPDF_REAL  x3,
542                     HPDF_REAL  y3)
543 {
544     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
545     char buf[HPDF_TMP_BUF_SIZ];
546     char *pbuf = buf;
547     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
548     HPDF_PageAttr attr;
549 
550     HPDF_PTRACE ((" HPDF_Page_CurveTo\n"));
551 
552     if (ret != HPDF_OK)
553         return ret;
554 
555     attr = (HPDF_PageAttr)page->attr;
556 
557     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
558 
559     pbuf = HPDF_FToA (pbuf, x1, eptr);
560     *pbuf++ = ' ';
561     pbuf = HPDF_FToA (pbuf, y1, eptr);
562     *pbuf++ = ' ';
563     pbuf = HPDF_FToA (pbuf, x2, eptr);
564     *pbuf++ = ' ';
565     pbuf = HPDF_FToA (pbuf, y2, eptr);
566     *pbuf++ = ' ';
567     pbuf = HPDF_FToA (pbuf, x3, eptr);
568     *pbuf++ = ' ';
569     pbuf = HPDF_FToA (pbuf, y3, eptr);
570     HPDF_StrCpy (pbuf, " c\012", eptr);
571 
572     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
573         return HPDF_CheckError (page->error);
574 
575     attr->cur_pos.x = x3;
576     attr->cur_pos.y = y3;
577 
578     return ret;
579 }
580 
581 /* v */
582 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_CurveTo2(HPDF_Page page,HPDF_REAL x2,HPDF_REAL y2,HPDF_REAL x3,HPDF_REAL y3)583 HPDF_Page_CurveTo2  (HPDF_Page  page,
584                      HPDF_REAL  x2,
585                      HPDF_REAL  y2,
586                      HPDF_REAL  x3,
587                      HPDF_REAL  y3)
588 {
589     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
590     char buf[HPDF_TMP_BUF_SIZ];
591     char *pbuf = buf;
592     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
593     HPDF_PageAttr attr;
594 
595     HPDF_PTRACE ((" HPDF_Page_CurveTo2\n"));
596 
597     if (ret != HPDF_OK)
598         return ret;
599 
600     attr = (HPDF_PageAttr)page->attr;
601 
602     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
603 
604     pbuf = HPDF_FToA (pbuf, x2, eptr);
605     *pbuf++ = ' ';
606     pbuf = HPDF_FToA (pbuf, y2, eptr);
607     *pbuf++ = ' ';
608     pbuf = HPDF_FToA (pbuf, x3, eptr);
609     *pbuf++ = ' ';
610     pbuf = HPDF_FToA (pbuf, y3, eptr);
611     HPDF_StrCpy (pbuf, " v\012", eptr);
612 
613     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
614         return HPDF_CheckError (page->error);
615 
616     attr->cur_pos.x = x3;
617     attr->cur_pos.y = y3;
618 
619     return ret;
620 }
621 
622 /* y */
623 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_CurveTo3(HPDF_Page page,HPDF_REAL x1,HPDF_REAL y1,HPDF_REAL x3,HPDF_REAL y3)624 HPDF_Page_CurveTo3  (HPDF_Page  page,
625                      HPDF_REAL  x1,
626                      HPDF_REAL  y1,
627                      HPDF_REAL  x3,
628                      HPDF_REAL  y3)
629 {
630     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
631     char buf[HPDF_TMP_BUF_SIZ];
632     char *pbuf = buf;
633     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
634     HPDF_PageAttr attr;
635 
636     HPDF_PTRACE ((" HPDF_Page_CurveTo3\n"));
637 
638     if (ret != HPDF_OK)
639         return ret;
640 
641     attr = (HPDF_PageAttr)page->attr;
642 
643     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
644 
645     pbuf = HPDF_FToA (pbuf, x1, eptr);
646     *pbuf++ = ' ';
647     pbuf = HPDF_FToA (pbuf, y1, eptr);
648     *pbuf++ = ' ';
649     pbuf = HPDF_FToA (pbuf, x3, eptr);
650     *pbuf++ = ' ';
651     pbuf = HPDF_FToA (pbuf, y3, eptr);
652     HPDF_StrCpy (pbuf, " y\012", eptr);
653 
654     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
655         return HPDF_CheckError (page->error);
656 
657     attr->cur_pos.x = x3;
658     attr->cur_pos.y = y3;
659 
660     return ret;
661 }
662 
663 /* h */
664 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ClosePath(HPDF_Page page)665 HPDF_Page_ClosePath  (HPDF_Page  page)
666 {
667     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
668     HPDF_PageAttr attr;
669 
670     HPDF_PTRACE ((" HPDF_Page_ClosePath\n"));
671 
672     if (ret != HPDF_OK)
673         return ret;
674 
675     attr = (HPDF_PageAttr)page->attr;
676 
677     if (HPDF_Stream_WriteStr (attr->stream, "h\012") != HPDF_OK)
678         return HPDF_CheckError (page->error);
679 
680     attr->cur_pos = attr->str_pos;
681 
682     return ret;
683 }
684 
685 /* re */
686 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Rectangle(HPDF_Page page,HPDF_REAL x,HPDF_REAL y,HPDF_REAL width,HPDF_REAL height)687 HPDF_Page_Rectangle  (HPDF_Page  page,
688                       HPDF_REAL  x,
689                       HPDF_REAL  y,
690                       HPDF_REAL  width,
691                       HPDF_REAL  height)
692 {
693     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
694                     HPDF_GMODE_PATH_OBJECT);
695     char buf[HPDF_TMP_BUF_SIZ];
696     char *pbuf = buf;
697     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
698     HPDF_PageAttr attr;
699 
700     HPDF_PTRACE ((" HPDF_Page_Rectangle\n"));
701 
702     if (ret != HPDF_OK)
703         return ret;
704 
705     attr = (HPDF_PageAttr)page->attr;
706 
707     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
708 
709     pbuf = HPDF_FToA (pbuf, x, eptr);
710     *pbuf++ = ' ';
711     pbuf = HPDF_FToA (pbuf, y, eptr);
712     *pbuf++ = ' ';
713     pbuf = HPDF_FToA (pbuf, width, eptr);
714     *pbuf++ = ' ';
715     pbuf = HPDF_FToA (pbuf, height, eptr);
716     HPDF_StrCpy (pbuf, " re\012", eptr);
717 
718     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
719         return HPDF_CheckError (page->error);
720 
721     attr->cur_pos.x = x;
722     attr->cur_pos.y = y;
723     attr->str_pos = attr->cur_pos;
724     attr->gmode = HPDF_GMODE_PATH_OBJECT;
725 
726     return ret;
727 }
728 
729 
730 /*--- Path painting operator ---------------------------------------------*/
731 
732 /* S */
733 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Stroke(HPDF_Page page)734 HPDF_Page_Stroke  (HPDF_Page  page)
735 {
736     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
737         HPDF_GMODE_CLIPPING_PATH);
738     HPDF_PageAttr attr;
739 
740     HPDF_PTRACE ((" HPDF_Page_Stroke\n"));
741 
742     if (ret != HPDF_OK)
743         return ret;
744 
745     attr = (HPDF_PageAttr)page->attr;
746 
747     if (HPDF_Stream_WriteStr (attr->stream, "S\012") != HPDF_OK)
748         return HPDF_CheckError (page->error);
749 
750     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
751     attr->cur_pos = INIT_POS;
752 
753     return ret;
754 }
755 
756 /* s */
757 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ClosePathStroke(HPDF_Page page)758 HPDF_Page_ClosePathStroke  (HPDF_Page  page)
759 {
760     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
761             HPDF_GMODE_CLIPPING_PATH);
762     HPDF_PageAttr attr;
763 
764     HPDF_PTRACE ((" HPDF_Page_ClosePathStroke\n"));
765 
766     if (ret != HPDF_OK)
767         return ret;
768 
769     attr = (HPDF_PageAttr)page->attr;
770 
771     if (HPDF_Stream_WriteStr (attr->stream, "s\012") != HPDF_OK)
772         return HPDF_CheckError (page->error);
773 
774     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
775     attr->cur_pos = INIT_POS;
776 
777     return ret;
778 }
779 
780 /* f */
781 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Fill(HPDF_Page page)782 HPDF_Page_Fill  (HPDF_Page  page)
783 {
784     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
785             HPDF_GMODE_CLIPPING_PATH);
786     HPDF_PageAttr attr;
787 
788     HPDF_PTRACE ((" HPDF_Page_Fill\n"));
789 
790     if (ret != HPDF_OK)
791         return ret;
792 
793     attr = (HPDF_PageAttr)page->attr;
794 
795     if (HPDF_Stream_WriteStr (attr->stream, "f\012") != HPDF_OK)
796         return HPDF_CheckError (page->error);
797 
798     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
799     attr->cur_pos = INIT_POS;
800 
801     return ret;
802 }
803 
804 /* f* */
805 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Eofill(HPDF_Page page)806 HPDF_Page_Eofill  (HPDF_Page  page)
807 {
808     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
809             HPDF_GMODE_CLIPPING_PATH);
810     HPDF_PageAttr attr;
811 
812     HPDF_PTRACE ((" HPDF_Page_Eofill\n"));
813 
814     if (ret != HPDF_OK)
815         return ret;
816 
817     attr = (HPDF_PageAttr)page->attr;
818 
819     if (HPDF_Stream_WriteStr (attr->stream, "f*\012") != HPDF_OK)
820         return HPDF_CheckError (page->error);
821 
822     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
823     attr->cur_pos = INIT_POS;
824 
825     return ret;
826 }
827 
828 /* B */
829 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_FillStroke(HPDF_Page page)830 HPDF_Page_FillStroke  (HPDF_Page  page)
831 {
832     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
833             HPDF_GMODE_CLIPPING_PATH);
834     HPDF_PageAttr attr;
835 
836     HPDF_PTRACE ((" HPDF_Page_FillStroke\n"));
837 
838     if (ret != HPDF_OK)
839         return ret;
840 
841     attr = (HPDF_PageAttr)page->attr;
842 
843     if (HPDF_Stream_WriteStr (attr->stream, "B\012") != HPDF_OK)
844         return HPDF_CheckError (page->error);
845 
846     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
847     attr->cur_pos = INIT_POS;
848 
849     return ret;
850 }
851 
852 /* B* */
853 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_EofillStroke(HPDF_Page page)854 HPDF_Page_EofillStroke  (HPDF_Page  page)
855 {
856     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
857             HPDF_GMODE_CLIPPING_PATH);
858     HPDF_PageAttr attr;
859 
860     HPDF_PTRACE ((" HPDF_Page_EofillStroke\n"));
861 
862     if (ret != HPDF_OK)
863         return ret;
864 
865     attr = (HPDF_PageAttr)page->attr;
866 
867     if (HPDF_Stream_WriteStr (attr->stream, "B*\012") != HPDF_OK)
868         return HPDF_CheckError (page->error);
869 
870     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
871 
872     return ret;
873 }
874 
875 /* b */
876 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ClosePathFillStroke(HPDF_Page page)877 HPDF_Page_ClosePathFillStroke  (HPDF_Page  page)
878 {
879     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
880             HPDF_GMODE_CLIPPING_PATH);
881     HPDF_PageAttr attr;
882 
883     HPDF_PTRACE ((" HPDF_Page_ClosePathFillStroke\n"));
884 
885     if (ret != HPDF_OK)
886         return ret;
887 
888     attr = (HPDF_PageAttr)page->attr;
889 
890     if (HPDF_Stream_WriteStr (attr->stream, "b\012") != HPDF_OK)
891         return HPDF_CheckError (page->error);
892 
893     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
894     attr->cur_pos = INIT_POS;
895 
896     return ret;
897 }
898 
899 /* b* */
900 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ClosePathEofillStroke(HPDF_Page page)901 HPDF_Page_ClosePathEofillStroke  (HPDF_Page  page)
902 {
903     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
904             HPDF_GMODE_CLIPPING_PATH);
905     HPDF_PageAttr attr;
906 
907     HPDF_PTRACE ((" HPDF_Page_ClosePathEofillStroke\n"));
908 
909     if (ret != HPDF_OK)
910         return ret;
911 
912     attr = (HPDF_PageAttr)page->attr;
913 
914     if (HPDF_Stream_WriteStr (attr->stream, "b*\012") != HPDF_OK)
915         return HPDF_CheckError (page->error);
916 
917     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
918     attr->cur_pos = INIT_POS;
919 
920     return ret;
921 }
922 
923 /* n */
924 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_EndPath(HPDF_Page page)925 HPDF_Page_EndPath  (HPDF_Page  page)
926 {
927     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT |
928             HPDF_GMODE_CLIPPING_PATH);
929     HPDF_PageAttr attr;
930 
931     HPDF_PTRACE ((" HPDF_PageEndPath\n"));
932 
933     if (ret != HPDF_OK)
934         return ret;
935 
936     attr = (HPDF_PageAttr)page->attr;
937 
938     if (HPDF_Stream_WriteStr (attr->stream, "n\012") != HPDF_OK)
939         return HPDF_CheckError (page->error);
940 
941     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
942     attr->cur_pos = INIT_POS;
943 
944     return ret;
945 }
946 
947 
948 /*--- Clipping paths operator --------------------------------------------*/
949 
950 /* W */
951 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Clip(HPDF_Page page)952 HPDF_Page_Clip  (HPDF_Page  page)
953 {
954     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
955     HPDF_PageAttr attr;
956 
957     HPDF_PTRACE ((" HPDF_Page_Clip\n"));
958 
959     if (ret != HPDF_OK)
960         return ret;
961 
962     attr = (HPDF_PageAttr)page->attr;
963 
964     if (HPDF_Stream_WriteStr (attr->stream, "W\012") != HPDF_OK)
965         return HPDF_CheckError (page->error);
966 
967     attr->gmode = HPDF_GMODE_CLIPPING_PATH;
968 
969     return ret;
970 }
971 
972 /* W* */
973 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Eoclip(HPDF_Page page)974 HPDF_Page_Eoclip  (HPDF_Page  page)
975 {
976     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PATH_OBJECT);
977     HPDF_PageAttr attr;
978 
979     HPDF_PTRACE ((" HPDF_Page_Eoclip\n"));
980 
981     if (ret != HPDF_OK)
982         return ret;
983 
984     attr = (HPDF_PageAttr)page->attr;
985 
986     if (HPDF_Stream_WriteStr (attr->stream, "W*\012") != HPDF_OK)
987         return HPDF_CheckError (page->error);
988 
989     attr->gmode = HPDF_GMODE_CLIPPING_PATH;
990 
991     return ret;
992 }
993 
994 
995 /*--- Text object operator -----------------------------------------------*/
996 
997 /* BT */
998 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_BeginText(HPDF_Page page)999 HPDF_Page_BeginText  (HPDF_Page  page)
1000 {
1001     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
1002     HPDF_PageAttr attr;
1003     const HPDF_TransMatrix INIT_MATRIX = {1, 0, 0, 1, 0, 0};
1004 
1005     HPDF_PTRACE ((" HPDF_Page_BeginText\n"));
1006 
1007     if (ret != HPDF_OK)
1008         return ret;
1009 
1010     attr = (HPDF_PageAttr)page->attr;
1011 
1012     if (HPDF_Stream_WriteStr (attr->stream, "BT\012") != HPDF_OK)
1013         return HPDF_CheckError (page->error);
1014 
1015     attr->gmode = HPDF_GMODE_TEXT_OBJECT;
1016     attr->text_pos = INIT_POS;
1017     attr->text_matrix = INIT_MATRIX;
1018 
1019     return ret;
1020 }
1021 
1022 /* ET */
1023 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_EndText(HPDF_Page page)1024 HPDF_Page_EndText  (HPDF_Page  page)
1025 {
1026     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1027     HPDF_PageAttr attr;
1028 
1029     HPDF_PTRACE ((" HPDF_Page_EndText\n"));
1030 
1031     if (ret != HPDF_OK)
1032         return ret;
1033 
1034     attr = (HPDF_PageAttr)page->attr;
1035 
1036     if (HPDF_Stream_WriteStr (attr->stream, "ET\012") != HPDF_OK)
1037         return HPDF_CheckError (page->error);
1038 
1039     attr->text_pos = INIT_POS;
1040     attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION;
1041 
1042     return ret;
1043 }
1044 
1045 /*--- Text state ---------------------------------------------------------*/
1046 
1047 /* Tc */
1048 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetCharSpace(HPDF_Page page,HPDF_REAL value)1049 HPDF_Page_SetCharSpace  (HPDF_Page  page,
1050                          HPDF_REAL  value)
1051 {
1052     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1053                     HPDF_GMODE_TEXT_OBJECT);
1054     HPDF_PageAttr attr;
1055 
1056     HPDF_PTRACE ((" HPDF_Page_SetCharSpace\n"));
1057 
1058     if (ret != HPDF_OK)
1059         return ret;
1060 
1061     attr = (HPDF_PageAttr)page->attr;
1062 
1063     if (value < HPDF_MIN_CHARSPACE || value > HPDF_MAX_CHARSPACE)
1064         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1065 
1066     if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
1067         return HPDF_CheckError (page->error);
1068 
1069     if (HPDF_Stream_WriteStr (attr->stream, " Tc\012") != HPDF_OK)
1070         return HPDF_CheckError (page->error);
1071 
1072     attr->gstate->char_space = value;
1073 
1074     return ret;
1075 }
1076 
1077 /* Tw */
1078 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetWordSpace(HPDF_Page page,HPDF_REAL value)1079 HPDF_Page_SetWordSpace  (HPDF_Page  page,
1080                          HPDF_REAL  value)
1081 {
1082     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1083                     HPDF_GMODE_TEXT_OBJECT);
1084     HPDF_PageAttr attr;
1085 
1086     HPDF_PTRACE ((" HPDF_Page_SetWordSpace\n"));
1087 
1088     if (ret != HPDF_OK)
1089         return ret;
1090 
1091     attr = (HPDF_PageAttr)page->attr;
1092 
1093     if (value < HPDF_MIN_WORDSPACE || value > HPDF_MAX_WORDSPACE)
1094         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1095 
1096     if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
1097         return HPDF_CheckError (page->error);
1098 
1099     if (HPDF_Stream_WriteStr (attr->stream, " Tw\012") != HPDF_OK)
1100         return HPDF_CheckError (page->error);
1101 
1102     attr->gstate->word_space = value;
1103 
1104     return ret;
1105 }
1106 
1107 /* Tz */
1108 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetHorizontalScalling(HPDF_Page page,HPDF_REAL value)1109 HPDF_Page_SetHorizontalScalling  (HPDF_Page  page,
1110                                   HPDF_REAL  value)
1111 {
1112     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1113                     HPDF_GMODE_TEXT_OBJECT);
1114     HPDF_PageAttr attr;
1115 
1116     HPDF_PTRACE ((" HPDF_Page_SetHorizontalScalling\n"));
1117 
1118     if (ret != HPDF_OK)
1119         return ret;
1120 
1121     attr = (HPDF_PageAttr)page->attr;
1122 
1123     if (value < HPDF_MIN_HORIZONTALSCALING ||
1124             value > HPDF_MAX_HORIZONTALSCALING)
1125         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1126 
1127     if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
1128         return HPDF_CheckError (page->error);
1129 
1130     if (HPDF_Stream_WriteStr (attr->stream, " Tz\012") != HPDF_OK)
1131         return HPDF_CheckError (page->error);
1132 
1133     attr->gstate->h_scalling = value;
1134 
1135     return ret;
1136 }
1137 
1138 /* TL */
1139 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextLeading(HPDF_Page page,HPDF_REAL value)1140 HPDF_Page_SetTextLeading  (HPDF_Page  page,
1141                            HPDF_REAL  value)
1142 {
1143     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1144                     HPDF_GMODE_TEXT_OBJECT);
1145     HPDF_PageAttr attr;
1146 
1147     HPDF_PTRACE ((" HPDF_Page_SetTextLeading\n"));
1148 
1149     if (ret != HPDF_OK)
1150         return ret;
1151 
1152     attr = (HPDF_PageAttr)page->attr;
1153 
1154     if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
1155         return HPDF_CheckError (page->error);
1156 
1157     if (HPDF_Stream_WriteStr (attr->stream, " TL\012") != HPDF_OK)
1158         return HPDF_CheckError (page->error);
1159 
1160     attr->gstate->text_leading = value;
1161 
1162     return ret;
1163 }
1164 
1165 /* Tf */
1166 
1167 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetFontAndSize(HPDF_Page page,HPDF_Font font,HPDF_REAL size)1168 HPDF_Page_SetFontAndSize  (HPDF_Page  page,
1169                            HPDF_Font  font,
1170                            HPDF_REAL  size)
1171 {
1172     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1173                     HPDF_GMODE_TEXT_OBJECT);
1174     char buf[HPDF_TMP_BUF_SIZ];
1175     char *pbuf = buf;
1176     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1177     const char *local_name;
1178     HPDF_PageAttr attr;
1179 
1180     HPDF_PTRACE ((" HPDF_Page_SetFontAndSize\n"));
1181 
1182     if (ret != HPDF_OK)
1183         return ret;
1184 
1185     if (!HPDF_Font_Validate (font))
1186         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
1187 
1188     if (size <= 0 || size > HPDF_MAX_FONTSIZE)
1189         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT_SIZE, size);
1190 
1191     if (page->mmgr != font->mmgr)
1192         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
1193 
1194     attr = (HPDF_PageAttr)page->attr;
1195     local_name = HPDF_Page_GetLocalFontName (page, font);
1196 
1197     if (!local_name)
1198         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
1199 
1200     if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
1201         return HPDF_CheckError (page->error);
1202 
1203     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1204     *pbuf++ = ' ';
1205     pbuf = HPDF_FToA (pbuf, size, eptr);
1206     HPDF_StrCpy (pbuf, " Tf\012", eptr);
1207 
1208     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1209         return HPDF_CheckError (page->error);
1210 
1211     attr->gstate->font = font;
1212     attr->gstate->font_size = size;
1213     attr->gstate->writing_mode = ((HPDF_FontAttr)font->attr)->writing_mode;
1214 
1215     return ret;
1216 }
1217 
1218 /* Tr */
1219 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextRenderingMode(HPDF_Page page,HPDF_TextRenderingMode mode)1220 HPDF_Page_SetTextRenderingMode  (HPDF_Page               page,
1221                                  HPDF_TextRenderingMode  mode)
1222 {
1223     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1224                     HPDF_GMODE_TEXT_OBJECT);
1225     HPDF_PageAttr attr;
1226 
1227     HPDF_PTRACE ((" HPDF_Page_SetTextRenderingMode\n"));
1228 
1229     if (ret != HPDF_OK)
1230         return ret;
1231 
1232     if (mode >= HPDF_RENDERING_MODE_EOF)
1233         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE,
1234                 (HPDF_STATUS)mode);
1235 
1236     attr = (HPDF_PageAttr)page->attr;
1237 
1238     if (HPDF_Stream_WriteInt (attr->stream, (HPDF_INT)mode) != HPDF_OK)
1239         return HPDF_CheckError (page->error);
1240 
1241     if (HPDF_Stream_WriteStr (attr->stream, " Tr\012") != HPDF_OK)
1242         return HPDF_CheckError (page->error);
1243 
1244     attr->gstate->rendering_mode = mode;
1245 
1246     return ret;
1247 }
1248 
1249 /* Ts */
1250 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextRaise(HPDF_Page page,HPDF_REAL value)1251 HPDF_Page_SetTextRaise  (HPDF_Page  page,
1252                          HPDF_REAL  value)
1253 {
1254     return HPDF_Page_SetTextRise (page, value);
1255 }
1256 
1257 
1258 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextRise(HPDF_Page page,HPDF_REAL value)1259 HPDF_Page_SetTextRise  (HPDF_Page  page,
1260                         HPDF_REAL  value)
1261 {
1262     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1263                     HPDF_GMODE_TEXT_OBJECT);
1264     HPDF_PageAttr attr;
1265 
1266     HPDF_PTRACE ((" HPDF_Page_SetTextRaise\n"));
1267 
1268     if (ret != HPDF_OK)
1269         return ret;
1270 
1271     attr = (HPDF_PageAttr)page->attr;
1272 
1273     if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
1274         return HPDF_CheckError (page->error);
1275 
1276     if (HPDF_Stream_WriteStr (attr->stream, " Ts\012") != HPDF_OK)
1277         return HPDF_CheckError (page->error);
1278 
1279     attr->gstate->text_rise = value;
1280 
1281     return ret;
1282 }
1283 
1284 /*--- Text positioning ---------------------------------------------------*/
1285 
1286 /* Td */
1287 
1288 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_MoveTextPos(HPDF_Page page,HPDF_REAL x,HPDF_REAL y)1289 HPDF_Page_MoveTextPos  (HPDF_Page  page,
1290                         HPDF_REAL  x,
1291                         HPDF_REAL  y)
1292 {
1293     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1294     char buf[HPDF_TMP_BUF_SIZ];
1295     char *pbuf = buf;
1296     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1297     HPDF_PageAttr attr;
1298 
1299     HPDF_PTRACE ((" HPDF_Page_MoveTextPos\n"));
1300 
1301     if (ret != HPDF_OK)
1302         return ret;
1303 
1304     attr = (HPDF_PageAttr)page->attr;
1305 
1306     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1307 
1308     pbuf = HPDF_FToA (pbuf, x, eptr);
1309     *pbuf++ = ' ';
1310     pbuf = HPDF_FToA (pbuf, y, eptr);
1311     HPDF_StrCpy (pbuf, " Td\012", eptr);
1312 
1313     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1314         return HPDF_CheckError (page->error);
1315 
1316     attr->text_matrix.x += x * attr->text_matrix.a + y * attr->text_matrix.c;
1317     attr->text_matrix.y += y * attr->text_matrix.d + x * attr->text_matrix.b;
1318     attr->text_pos.x = attr->text_matrix.x;
1319     attr->text_pos.y = attr->text_matrix.y;
1320 
1321     return ret;
1322 }
1323 
1324 /* TD */
1325 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_MoveTextPos2(HPDF_Page page,HPDF_REAL x,HPDF_REAL y)1326 HPDF_Page_MoveTextPos2  (HPDF_Page  page,
1327                          HPDF_REAL  x,
1328                          HPDF_REAL  y)
1329 {
1330     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1331     char buf[HPDF_TMP_BUF_SIZ];
1332     char *pbuf = buf;
1333     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1334     HPDF_PageAttr attr;
1335 
1336     HPDF_PTRACE ((" HPDF_Page_MoveTextPos2\n"));
1337 
1338     if (ret != HPDF_OK)
1339         return ret;
1340 
1341     attr = (HPDF_PageAttr)page->attr;
1342 
1343     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1344 
1345     pbuf = HPDF_FToA (pbuf, x, eptr);
1346     *pbuf++ = ' ';
1347     pbuf = HPDF_FToA (pbuf, y, eptr);
1348     HPDF_StrCpy (pbuf, " TD\012", eptr);
1349 
1350     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1351         return HPDF_CheckError (page->error);
1352 
1353     attr->text_matrix.x += x * attr->text_matrix.a + y * attr->text_matrix.c;
1354     attr->text_matrix.y += y * attr->text_matrix.d + x * attr->text_matrix.b;
1355     attr->text_pos.x = attr->text_matrix.x;
1356     attr->text_pos.y = attr->text_matrix.y;
1357     attr->gstate->text_leading = -y;
1358 
1359     return ret;
1360 }
1361 
1362 /* Tm */
1363 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextMatrix(HPDF_Page page,HPDF_REAL a,HPDF_REAL b,HPDF_REAL c,HPDF_REAL d,HPDF_REAL x,HPDF_REAL y)1364 HPDF_Page_SetTextMatrix  (HPDF_Page         page,
1365                           HPDF_REAL    a,
1366                           HPDF_REAL    b,
1367                           HPDF_REAL    c,
1368                           HPDF_REAL    d,
1369                           HPDF_REAL    x,
1370                           HPDF_REAL    y)
1371 {
1372     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1373     char buf[HPDF_TMP_BUF_SIZ];
1374     char *pbuf = buf;
1375     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1376     HPDF_PageAttr attr;
1377 
1378     HPDF_PTRACE ((" HPDF_Page_SetTextMatrix\n"));
1379 
1380     if (ret != HPDF_OK)
1381         return ret;
1382 
1383     attr = (HPDF_PageAttr)page->attr;
1384 
1385     if ((a == 0 || d == 0) && (b == 0 || c == 0))
1386         return HPDF_RaiseError (page->error, HPDF_INVALID_PARAMETER, 0);
1387 
1388     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1389 
1390     pbuf = HPDF_FToA (pbuf, a, eptr);
1391     *pbuf++ = ' ';
1392     pbuf = HPDF_FToA (pbuf, b, eptr);
1393     *pbuf++ = ' ';
1394     pbuf = HPDF_FToA (pbuf, c, eptr);
1395     *pbuf++ = ' ';
1396     pbuf = HPDF_FToA (pbuf, d, eptr);
1397     *pbuf++ = ' ';
1398     pbuf = HPDF_FToA (pbuf, x, eptr);
1399     *pbuf++ = ' ';
1400     pbuf = HPDF_FToA (pbuf, y, eptr);
1401     HPDF_StrCpy (pbuf, " Tm\012", eptr);
1402 
1403     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1404         return HPDF_CheckError (page->error);
1405 
1406     attr->text_matrix.a = a;
1407     attr->text_matrix.b = b;
1408     attr->text_matrix.c = c;
1409     attr->text_matrix.d = d;
1410     attr->text_matrix.x = x;
1411     attr->text_matrix.y = y;
1412     attr->text_pos.x = attr->text_matrix.x;
1413     attr->text_pos.y = attr->text_matrix.y;
1414 
1415     return ret;
1416 }
1417 
1418 
1419 /* T* */
1420 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_MoveToNextLine(HPDF_Page page)1421 HPDF_Page_MoveToNextLine  (HPDF_Page  page)
1422 {
1423     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1424     HPDF_PageAttr attr;
1425 
1426     HPDF_PTRACE ((" HPDF_Page_MoveToNextLine\n"));
1427 
1428     if (ret != HPDF_OK)
1429         return ret;
1430 
1431     attr = (HPDF_PageAttr)page->attr;
1432 
1433     if (HPDF_Stream_WriteStr (attr->stream, "T*\012") != HPDF_OK)
1434         return HPDF_CheckError (page->error);
1435 
1436     /* calculate the reference point of text */
1437     attr->text_matrix.x -= attr->gstate->text_leading * attr->text_matrix.c;
1438     attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.d;
1439 
1440     attr->text_pos.x = attr->text_matrix.x;
1441     attr->text_pos.y = attr->text_matrix.y;
1442 
1443     return ret;
1444 }
1445 
1446 /*--- Text showing -------------------------------------------------------*/
1447 
1448 /* Tj */
1449 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ShowText(HPDF_Page page,const char * text)1450 HPDF_Page_ShowText  (HPDF_Page    page,
1451                      const char  *text)
1452 {
1453     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1454     HPDF_PageAttr attr;
1455     HPDF_REAL tw;
1456 
1457     HPDF_PTRACE ((" HPDF_Page_ShowText\n"));
1458 
1459     if (ret != HPDF_OK || text == NULL || text[0] == 0)
1460         return ret;
1461 
1462     attr = (HPDF_PageAttr)page->attr;
1463 
1464     /* no font exists */
1465     if (!attr->gstate->font)
1466         return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
1467 
1468     tw = HPDF_Page_TextWidth (page, text);
1469     if (!tw)
1470         return ret;
1471 
1472     if (InternalWriteText (attr, text) != HPDF_OK)
1473         return HPDF_CheckError (page->error);
1474 
1475     if (HPDF_Stream_WriteStr (attr->stream, " Tj\012") != HPDF_OK)
1476         return HPDF_CheckError (page->error);
1477 
1478     /* calculate the reference point of text */
1479     if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
1480         attr->text_pos.x += tw * attr->text_matrix.a;
1481         attr->text_pos.y += tw * attr->text_matrix.b;
1482     } else {
1483         attr->text_pos.x -= tw * attr->text_matrix.b;
1484         attr->text_pos.y -= tw * attr->text_matrix.a;
1485     }
1486 
1487     return ret;
1488 }
1489 
1490 /* TJ */
1491 /* ' */
1492 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ShowTextNextLine(HPDF_Page page,const char * text)1493 HPDF_Page_ShowTextNextLine  (HPDF_Page    page,
1494                              const char  *text)
1495 {
1496     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1497     HPDF_PageAttr attr;
1498     HPDF_REAL tw;
1499 
1500     HPDF_PTRACE ((" HPDF_Page_ShowTextNextLine\n"));
1501 
1502     if (ret != HPDF_OK)
1503         return ret;
1504 
1505     attr = (HPDF_PageAttr)page->attr;
1506 
1507     /* no font exists */
1508     if (!attr->gstate->font)
1509         return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
1510 
1511     if (text == NULL || text[0] == 0)
1512         return HPDF_Page_MoveToNextLine(page);
1513 
1514     if (InternalWriteText (attr, text) != HPDF_OK)
1515         return HPDF_CheckError (page->error);
1516 
1517     if (HPDF_Stream_WriteStr (attr->stream, " \'\012") != HPDF_OK)
1518         return HPDF_CheckError (page->error);
1519 
1520     tw = HPDF_Page_TextWidth (page, text);
1521 
1522     /* calculate the reference point of text */
1523     attr->text_matrix.x -= attr->gstate->text_leading * attr->text_matrix.c;
1524     attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.d;
1525 
1526     attr->text_pos.x = attr->text_matrix.x;
1527     attr->text_pos.y = attr->text_matrix.y;
1528 
1529     if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
1530         attr->text_pos.x += tw * attr->text_matrix.a;
1531         attr->text_pos.y += tw * attr->text_matrix.b;
1532     } else {
1533         attr->text_pos.x -= tw * attr->text_matrix.b;
1534         attr->text_pos.y -= tw * attr->text_matrix.a;
1535     }
1536 
1537     return ret;
1538 }
1539 
1540 /* " */
1541 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ShowTextNextLineEx(HPDF_Page page,HPDF_REAL word_space,HPDF_REAL char_space,const char * text)1542 HPDF_Page_ShowTextNextLineEx  (HPDF_Page    page,
1543                                HPDF_REAL    word_space,
1544                                HPDF_REAL    char_space,
1545                                const char  *text)
1546 {
1547     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
1548     HPDF_PageAttr attr;
1549     HPDF_REAL tw;
1550     char buf[HPDF_TMP_BUF_SIZ];
1551     char *pbuf = buf;
1552     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1553 
1554     HPDF_PTRACE ((" HPDF_Page_ShowTextNextLineEX\n"));
1555 
1556     if (ret != HPDF_OK)
1557         return ret;
1558 
1559     if (word_space < HPDF_MIN_WORDSPACE || word_space > HPDF_MAX_WORDSPACE)
1560         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1561 
1562     if (char_space < HPDF_MIN_CHARSPACE || char_space > HPDF_MAX_CHARSPACE)
1563         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1564 
1565     attr = (HPDF_PageAttr)page->attr;
1566 
1567     /* no font exists */
1568     if (!attr->gstate->font)
1569         return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
1570 
1571     if (text == NULL || text[0] == 0)
1572         return HPDF_Page_MoveToNextLine(page);
1573 
1574     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1575     pbuf = HPDF_FToA (pbuf, word_space, eptr);
1576     *pbuf++ = ' ';
1577     pbuf = HPDF_FToA (pbuf, char_space, eptr);
1578     *pbuf = ' ';
1579 
1580     if (InternalWriteText (attr, buf) != HPDF_OK)
1581         return HPDF_CheckError (page->error);
1582 
1583     if (InternalWriteText (attr, text) != HPDF_OK)
1584         return HPDF_CheckError (page->error);
1585 
1586     if (HPDF_Stream_WriteStr (attr->stream, " \"\012") != HPDF_OK)
1587         return HPDF_CheckError (page->error);
1588 
1589     attr->gstate->word_space = word_space;
1590     attr->gstate->char_space = char_space;
1591 
1592     tw = HPDF_Page_TextWidth (page, text);
1593 
1594     /* calculate the reference point of text */
1595     attr->text_matrix.x += attr->gstate->text_leading * attr->text_matrix.b;
1596     attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.a;
1597 
1598     attr->text_pos.x = attr->text_matrix.x;
1599     attr->text_pos.y = attr->text_matrix.y;
1600 
1601     if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
1602         attr->text_pos.x += tw * attr->text_matrix.a;
1603         attr->text_pos.y += tw * attr->text_matrix.b;
1604     } else {
1605         attr->text_pos.x -= tw * attr->text_matrix.b;
1606         attr->text_pos.y -= tw * attr->text_matrix.a;
1607     }
1608 
1609     return ret;
1610 }
1611 
1612 
1613 /*--- Color showing ------------------------------------------------------*/
1614 
1615 /* cs --not implemented yet */
1616 /* CS --not implemented yet */
1617 /* sc --not implemented yet */
1618 /* scn --not implemented yet */
1619 /* SC --not implemented yet */
1620 /* SCN --not implemented yet */
1621 
1622 /* g */
1623 
1624 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetGrayFill(HPDF_Page page,HPDF_REAL gray)1625 HPDF_Page_SetGrayFill  (HPDF_Page  page,
1626                         HPDF_REAL  gray)
1627 {
1628     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1629                     HPDF_GMODE_TEXT_OBJECT);
1630     HPDF_PageAttr attr;
1631 
1632     HPDF_PTRACE ((" HPDF_Page_SetGrayFill\n"));
1633 
1634     if (ret != HPDF_OK)
1635         return ret;
1636 
1637     attr = (HPDF_PageAttr)page->attr;
1638 
1639     if (gray < 0 || gray > 1)
1640         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1641 
1642     if (HPDF_Stream_WriteReal (attr->stream, gray) != HPDF_OK)
1643         return HPDF_CheckError (page->error);
1644 
1645     if (HPDF_Stream_WriteStr (attr->stream, " g\012") != HPDF_OK)
1646         return HPDF_CheckError (page->error);
1647 
1648     attr->gstate->gray_fill = gray;
1649     attr->gstate->cs_fill = HPDF_CS_DEVICE_GRAY;
1650 
1651     return ret;
1652 }
1653 
1654 /* G */
1655 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetGrayStroke(HPDF_Page page,HPDF_REAL gray)1656 HPDF_Page_SetGrayStroke  (HPDF_Page  page,
1657                           HPDF_REAL  gray)
1658 {
1659     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
1660                     HPDF_GMODE_TEXT_OBJECT);
1661     HPDF_PageAttr attr;
1662 
1663     HPDF_PTRACE ((" HPDF_Page_SetGrayStroke\n"));
1664 
1665     if (ret != HPDF_OK)
1666         return ret;
1667 
1668     attr = (HPDF_PageAttr)page->attr;
1669 
1670     if (gray < 0 || gray > 1)
1671         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1672 
1673     if (HPDF_Stream_WriteReal (attr->stream, gray) != HPDF_OK)
1674         return HPDF_CheckError (page->error);
1675 
1676     if (HPDF_Stream_WriteStr (attr->stream, " G\012") != HPDF_OK)
1677         return HPDF_CheckError (page->error);
1678 
1679     attr->gstate->gray_stroke = gray;
1680     attr->gstate->cs_stroke = HPDF_CS_DEVICE_GRAY;
1681 
1682     return ret;
1683 }
1684 
1685 /* rg */
1686 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetRGBFill(HPDF_Page page,HPDF_REAL r,HPDF_REAL g,HPDF_REAL b)1687 HPDF_Page_SetRGBFill  (HPDF_Page  page,
1688                        HPDF_REAL  r,
1689                        HPDF_REAL  g,
1690                        HPDF_REAL  b)
1691 {
1692     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT |
1693                     HPDF_GMODE_PAGE_DESCRIPTION);
1694     char buf[HPDF_TMP_BUF_SIZ];
1695     char *pbuf = buf;
1696     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1697     HPDF_PageAttr attr;
1698 
1699     HPDF_PTRACE ((" HPDF_Page_SetRGBFill\n"));
1700 
1701     if (ret != HPDF_OK)
1702         return ret;
1703 
1704     if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1)
1705         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1706 
1707     attr = (HPDF_PageAttr)page->attr;
1708 
1709     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1710 
1711     pbuf = HPDF_FToA (pbuf, r, eptr);
1712     *pbuf++ = ' ';
1713     pbuf = HPDF_FToA (pbuf, g, eptr);
1714     *pbuf++ = ' ';
1715     pbuf = HPDF_FToA (pbuf, b, eptr);
1716     HPDF_StrCpy (pbuf, " rg\012", eptr);
1717 
1718     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1719         return HPDF_CheckError (page->error);
1720 
1721     attr->gstate->rgb_fill.r = r;
1722     attr->gstate->rgb_fill.g = g;
1723     attr->gstate->rgb_fill.b = b;
1724     attr->gstate->cs_fill = HPDF_CS_DEVICE_RGB;
1725 
1726     return ret;
1727 }
1728 
1729 /* RG */
1730 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetRGBStroke(HPDF_Page page,HPDF_REAL r,HPDF_REAL g,HPDF_REAL b)1731 HPDF_Page_SetRGBStroke  (HPDF_Page  page,
1732                          HPDF_REAL  r,
1733                          HPDF_REAL  g,
1734                          HPDF_REAL  b)
1735 {
1736     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT |
1737                     HPDF_GMODE_PAGE_DESCRIPTION);
1738     char buf[HPDF_TMP_BUF_SIZ];
1739     char *pbuf = buf;
1740     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1741     HPDF_PageAttr attr;
1742 
1743     HPDF_PTRACE ((" HPDF_Page_SetRGBStroke\n"));
1744 
1745     if (ret != HPDF_OK)
1746         return ret;
1747 
1748     if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1)
1749         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1750 
1751     attr = (HPDF_PageAttr)page->attr;
1752 
1753     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1754 
1755     pbuf = HPDF_FToA (pbuf, r, eptr);
1756     *pbuf++ = ' ';
1757     pbuf = HPDF_FToA (pbuf, g, eptr);
1758     *pbuf++ = ' ';
1759     pbuf = HPDF_FToA (pbuf, b, eptr);
1760     HPDF_StrCpy (pbuf, " RG\012", eptr);
1761 
1762     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1763         return HPDF_CheckError (page->error);
1764 
1765     attr->gstate->rgb_stroke.r = r;
1766     attr->gstate->rgb_stroke.g = g;
1767     attr->gstate->rgb_stroke.b = b;
1768     attr->gstate->cs_stroke = HPDF_CS_DEVICE_RGB;
1769 
1770     return ret;
1771 }
1772 
1773 /* k */
1774 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetCMYKFill(HPDF_Page page,HPDF_REAL c,HPDF_REAL m,HPDF_REAL y,HPDF_REAL k)1775 HPDF_Page_SetCMYKFill  (HPDF_Page  page,
1776                         HPDF_REAL  c,
1777                         HPDF_REAL  m,
1778                         HPDF_REAL  y,
1779                         HPDF_REAL  k)
1780 {
1781     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT |
1782                     HPDF_GMODE_PAGE_DESCRIPTION);
1783     char buf[HPDF_TMP_BUF_SIZ];
1784     char *pbuf = buf;
1785     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1786     HPDF_PageAttr attr;
1787 
1788     HPDF_PTRACE ((" HPDF_Page_SetCMYKFill\n"));
1789 
1790     if (ret != HPDF_OK)
1791         return ret;
1792 
1793     if (c < 0 || c > 1 || m < 0 || m > 1 || y < 0 || y > 1 || k < 0 || k > 1)
1794         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1795 
1796     attr = (HPDF_PageAttr)page->attr;
1797 
1798     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1799 
1800     pbuf = HPDF_FToA (pbuf, c, eptr);
1801     *pbuf++ = ' ';
1802     pbuf = HPDF_FToA (pbuf, m, eptr);
1803     *pbuf++ = ' ';
1804     pbuf = HPDF_FToA (pbuf, y, eptr);
1805     *pbuf++ = ' ';
1806     pbuf = HPDF_FToA (pbuf, k, eptr);
1807     HPDF_StrCpy (pbuf, " k\012", eptr);
1808 
1809     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1810         return HPDF_CheckError (page->error);
1811 
1812     attr->gstate->cmyk_fill.c = c;
1813     attr->gstate->cmyk_fill.m = m;
1814     attr->gstate->cmyk_fill.y = y;
1815     attr->gstate->cmyk_fill.k = k;
1816     attr->gstate->cs_fill = HPDF_CS_DEVICE_CMYK;
1817 
1818     return ret;
1819 }
1820 
1821 /* K */
1822 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetCMYKStroke(HPDF_Page page,HPDF_REAL c,HPDF_REAL m,HPDF_REAL y,HPDF_REAL k)1823 HPDF_Page_SetCMYKStroke  (HPDF_Page  page,
1824                           HPDF_REAL  c,
1825                           HPDF_REAL  m,
1826                           HPDF_REAL  y,
1827                           HPDF_REAL  k)
1828 {
1829     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT |
1830                     HPDF_GMODE_PAGE_DESCRIPTION);
1831     char buf[HPDF_TMP_BUF_SIZ];
1832     char *pbuf = buf;
1833     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
1834     HPDF_PageAttr attr;
1835 
1836     HPDF_PTRACE ((" HPDF_Page_SetCMYKStroke\n"));
1837 
1838     if (ret != HPDF_OK)
1839         return ret;
1840 
1841     if (c < 0 || c > 1 || m < 0 || m > 1 || y < 0 || y > 1 || k < 0 || k > 1)
1842         return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
1843 
1844     attr = (HPDF_PageAttr)page->attr;
1845 
1846     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
1847 
1848     pbuf = HPDF_FToA (pbuf, c, eptr);
1849     *pbuf++ = ' ';
1850     pbuf = HPDF_FToA (pbuf, m, eptr);
1851     *pbuf++ = ' ';
1852     pbuf = HPDF_FToA (pbuf, y, eptr);
1853     *pbuf++ = ' ';
1854     pbuf = HPDF_FToA (pbuf, k, eptr);
1855     HPDF_StrCpy (pbuf, " K\012", eptr);
1856 
1857     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
1858         return HPDF_CheckError (page->error);
1859 
1860     attr->gstate->cmyk_stroke.c = c;
1861     attr->gstate->cmyk_stroke.m = m;
1862     attr->gstate->cmyk_stroke.y = y;
1863     attr->gstate->cmyk_stroke.k = k;
1864     attr->gstate->cs_stroke = HPDF_CS_DEVICE_CMYK;
1865 
1866     return ret;
1867 }
1868 
1869 /*--- Shading patterns ---------------------------------------------------*/
1870 
1871 /* sh --not implemented yet */
1872 
1873 /*--- In-line images -----------------------------------------------------*/
1874 
1875 /* BI --not implemented yet */
1876 /* ID --not implemented yet */
1877 /* EI --not implemented yet */
1878 
1879 /*--- XObjects -----------------------------------------------------------*/
1880 
1881 /* Do */
1882 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ExecuteXObject(HPDF_Page page,HPDF_XObject obj)1883 HPDF_Page_ExecuteXObject  (HPDF_Page     page,
1884                            HPDF_XObject  obj)
1885 {
1886     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION);
1887     HPDF_PageAttr attr;
1888     const char *local_name;
1889 
1890     HPDF_PTRACE ((" HPDF_Page_ExecuteXObject\n"));
1891 
1892     if (ret != HPDF_OK)
1893         return ret;
1894 
1895     if (!obj || obj->header.obj_class != (HPDF_OSUBCLASS_XOBJECT |
1896             HPDF_OCLASS_DICT))
1897         return HPDF_RaiseError (page->error, HPDF_INVALID_OBJECT, 0);
1898 
1899     if (page->mmgr != obj->mmgr)
1900         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_XOBJECT, 0);
1901 
1902     attr = (HPDF_PageAttr)page->attr;
1903     local_name = HPDF_Page_GetXObjectName (page, obj);
1904 
1905     if (!local_name)
1906         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_XOBJECT, 0);
1907 
1908     if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
1909         return HPDF_CheckError (page->error);
1910 
1911     if (HPDF_Stream_WriteStr (attr->stream, " Do\012") != HPDF_OK)
1912         return HPDF_CheckError (page->error);
1913 
1914     return ret;
1915 }
1916 
1917 /*--- Marked content -----------------------------------------------------*/
1918 
1919 /* BMC --not implemented yet */
1920 /* BDC --not implemented yet */
1921 /* EMC --not implemented yet */
1922 /* MP --not implemented yet */
1923 /* DP --not implemented yet */
1924 
1925 /*--- Compatibility ------------------------------------------------------*/
1926 
1927 /* BX --not implemented yet */
1928 /* EX --not implemented yet */
1929 
1930 
1931 /*--- combined function --------------------------------------------------*/
1932 
1933 static const HPDF_REAL KAPPA = 0.552F;
1934 
1935 static char*
QuarterCircleA(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray)1936 QuarterCircleA  (char   *pbuf,
1937                  char   *eptr,
1938                  HPDF_REAL    x,
1939                  HPDF_REAL    y,
1940                  HPDF_REAL    ray)
1941 {
1942     pbuf = HPDF_FToA (pbuf, x -ray, eptr);
1943     *pbuf++ = ' ';
1944     pbuf = HPDF_FToA (pbuf, y + ray * KAPPA, eptr);
1945     *pbuf++ = ' ';
1946     pbuf = HPDF_FToA (pbuf, x -ray * KAPPA, eptr);
1947     *pbuf++ = ' ';
1948     pbuf = HPDF_FToA (pbuf, y + ray, eptr);
1949     *pbuf++ = ' ';
1950     pbuf = HPDF_FToA (pbuf, x, eptr);
1951     *pbuf++ = ' ';
1952     pbuf = HPDF_FToA (pbuf, y + ray, eptr);
1953     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
1954 }
1955 
1956 static char*
QuarterCircleB(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray)1957 QuarterCircleB  (char   *pbuf,
1958                  char   *eptr,
1959                  HPDF_REAL    x,
1960                  HPDF_REAL    y,
1961                  HPDF_REAL    ray)
1962 {
1963     pbuf = HPDF_FToA (pbuf, x + ray * KAPPA, eptr);
1964     *pbuf++ = ' ';
1965     pbuf = HPDF_FToA (pbuf, y + ray, eptr);
1966     *pbuf++ = ' ';
1967     pbuf = HPDF_FToA (pbuf, x + ray, eptr);
1968     *pbuf++ = ' ';
1969     pbuf = HPDF_FToA (pbuf, y + ray * KAPPA, eptr);
1970     *pbuf++ = ' ';
1971     pbuf = HPDF_FToA (pbuf, x + ray, eptr);
1972     *pbuf++ = ' ';
1973     pbuf = HPDF_FToA (pbuf, y, eptr);
1974     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
1975 }
1976 
1977 static char*
QuarterCircleC(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray)1978 QuarterCircleC  (char   *pbuf,
1979                  char   *eptr,
1980                  HPDF_REAL    x,
1981                  HPDF_REAL    y,
1982                  HPDF_REAL    ray)
1983 {
1984     pbuf = HPDF_FToA (pbuf, x + ray, eptr);
1985     *pbuf++ = ' ';
1986     pbuf = HPDF_FToA (pbuf, y - ray * KAPPA, eptr);
1987     *pbuf++ = ' ';
1988     pbuf = HPDF_FToA (pbuf, x + ray * KAPPA, eptr);
1989     *pbuf++ = ' ';
1990     pbuf = HPDF_FToA (pbuf, y - ray, eptr);
1991     *pbuf++ = ' ';
1992     pbuf = HPDF_FToA (pbuf, x, eptr);
1993     *pbuf++ = ' ';
1994     pbuf = HPDF_FToA (pbuf, y - ray, eptr);
1995     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
1996 }
1997 
1998 static char*
QuarterCircleD(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray)1999 QuarterCircleD  (char   *pbuf,
2000                  char   *eptr,
2001                  HPDF_REAL    x,
2002                  HPDF_REAL    y,
2003                  HPDF_REAL    ray)
2004 {
2005     pbuf = HPDF_FToA (pbuf, x - ray * KAPPA, eptr);
2006     *pbuf++ = ' ';
2007     pbuf = HPDF_FToA (pbuf, y - ray, eptr);
2008     *pbuf++ = ' ';
2009     pbuf = HPDF_FToA (pbuf, x - ray, eptr);
2010     *pbuf++ = ' ';
2011     pbuf = HPDF_FToA (pbuf, y - ray * KAPPA, eptr);
2012     *pbuf++ = ' ';
2013     pbuf = HPDF_FToA (pbuf, x - ray, eptr);
2014     *pbuf++ = ' ';
2015     pbuf = HPDF_FToA (pbuf, y, eptr);
2016     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
2017 }
2018 
2019 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Circle(HPDF_Page page,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray)2020 HPDF_Page_Circle  (HPDF_Page     page,
2021                    HPDF_REAL     x,
2022                    HPDF_REAL     y,
2023                    HPDF_REAL     ray)
2024 {
2025     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
2026             HPDF_GMODE_PATH_OBJECT);
2027     char buf[HPDF_TMP_BUF_SIZ * 2];
2028     char *pbuf = buf;
2029     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
2030     HPDF_PageAttr attr;
2031 
2032     HPDF_PTRACE ((" HPDF_Page_Circle\n"));
2033 
2034     if (ret != HPDF_OK)
2035         return ret;
2036 
2037     attr = (HPDF_PageAttr)page->attr;
2038 
2039     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
2040 
2041     pbuf = HPDF_FToA (pbuf, x - ray, eptr);
2042     *pbuf++ = ' ';
2043     pbuf = HPDF_FToA (pbuf, y, eptr);
2044     pbuf = (char *)HPDF_StrCpy (pbuf, " m\012", eptr);
2045 
2046     pbuf = QuarterCircleA (pbuf, eptr, x, y, ray);
2047     pbuf = QuarterCircleB (pbuf, eptr, x, y, ray);
2048     pbuf = QuarterCircleC (pbuf, eptr, x, y, ray);
2049     QuarterCircleD (pbuf, eptr, x, y, ray);
2050 
2051     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
2052         return HPDF_CheckError (page->error);
2053 
2054     attr->cur_pos.x = x - ray;
2055     attr->cur_pos.y = y;
2056     attr->str_pos = attr->cur_pos;
2057     attr->gmode = HPDF_GMODE_PATH_OBJECT;
2058 
2059     return ret;
2060 }
2061 
2062 
2063 static char*
QuarterEllipseA(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL xray,HPDF_REAL yray)2064 QuarterEllipseA  (char      *pbuf,
2065                   char      *eptr,
2066                   HPDF_REAL  x,
2067                   HPDF_REAL  y,
2068                   HPDF_REAL  xray,
2069                   HPDF_REAL  yray)
2070 {
2071     pbuf = HPDF_FToA (pbuf, x - xray, eptr);
2072     *pbuf++ = ' ';
2073     pbuf = HPDF_FToA (pbuf, y + yray * KAPPA, eptr);
2074     *pbuf++ = ' ';
2075     pbuf = HPDF_FToA (pbuf, x -xray * KAPPA, eptr);
2076     *pbuf++ = ' ';
2077     pbuf = HPDF_FToA (pbuf, y + yray, eptr);
2078     *pbuf++ = ' ';
2079     pbuf = HPDF_FToA (pbuf, x, eptr);
2080     *pbuf++ = ' ';
2081     pbuf = HPDF_FToA (pbuf, y + yray, eptr);
2082     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
2083 }
2084 
2085 static char*
QuarterEllipseB(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL xray,HPDF_REAL yray)2086 QuarterEllipseB  (char      *pbuf,
2087                   char      *eptr,
2088                   HPDF_REAL  x,
2089                   HPDF_REAL  y,
2090                   HPDF_REAL  xray,
2091                   HPDF_REAL  yray)
2092 {
2093     pbuf = HPDF_FToA (pbuf, x + xray * KAPPA, eptr);
2094     *pbuf++ = ' ';
2095     pbuf = HPDF_FToA (pbuf, y + yray, eptr);
2096     *pbuf++ = ' ';
2097     pbuf = HPDF_FToA (pbuf, x + xray, eptr);
2098     *pbuf++ = ' ';
2099     pbuf = HPDF_FToA (pbuf, y + yray * KAPPA, eptr);
2100     *pbuf++ = ' ';
2101     pbuf = HPDF_FToA (pbuf, x + xray, eptr);
2102     *pbuf++ = ' ';
2103     pbuf = HPDF_FToA (pbuf, y, eptr);
2104     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
2105 }
2106 
2107 static char*
QuarterEllipseC(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL xray,HPDF_REAL yray)2108 QuarterEllipseC  (char      *pbuf,
2109                   char      *eptr,
2110                   HPDF_REAL  x,
2111                   HPDF_REAL  y,
2112                   HPDF_REAL  xray,
2113                   HPDF_REAL  yray)
2114 {
2115     pbuf = HPDF_FToA (pbuf, x + xray, eptr);
2116     *pbuf++ = ' ';
2117     pbuf = HPDF_FToA (pbuf, y - yray * KAPPA, eptr);
2118     *pbuf++ = ' ';
2119     pbuf = HPDF_FToA (pbuf, x + xray * KAPPA, eptr);
2120     *pbuf++ = ' ';
2121     pbuf = HPDF_FToA (pbuf, y - yray, eptr);
2122     *pbuf++ = ' ';
2123     pbuf = HPDF_FToA (pbuf, x, eptr);
2124     *pbuf++ = ' ';
2125     pbuf = HPDF_FToA (pbuf, y - yray, eptr);
2126     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
2127 }
2128 
2129 static char*
QuarterEllipseD(char * pbuf,char * eptr,HPDF_REAL x,HPDF_REAL y,HPDF_REAL xray,HPDF_REAL yray)2130 QuarterEllipseD  (char      *pbuf,
2131                   char      *eptr,
2132                   HPDF_REAL  x,
2133                   HPDF_REAL  y,
2134                   HPDF_REAL  xray,
2135                   HPDF_REAL  yray)
2136 {
2137     pbuf = HPDF_FToA (pbuf, x - xray * KAPPA, eptr);
2138     *pbuf++ = ' ';
2139     pbuf = HPDF_FToA (pbuf, y - yray, eptr);
2140     *pbuf++ = ' ';
2141     pbuf = HPDF_FToA (pbuf, x - xray, eptr);
2142     *pbuf++ = ' ';
2143     pbuf = HPDF_FToA (pbuf, y - yray * KAPPA, eptr);
2144     *pbuf++ = ' ';
2145     pbuf = HPDF_FToA (pbuf, x - xray, eptr);
2146     *pbuf++ = ' ';
2147     pbuf = HPDF_FToA (pbuf, y, eptr);
2148     return (char *)HPDF_StrCpy (pbuf, " c\012", eptr);
2149 }
2150 
2151 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Ellipse(HPDF_Page page,HPDF_REAL x,HPDF_REAL y,HPDF_REAL xray,HPDF_REAL yray)2152 HPDF_Page_Ellipse  (HPDF_Page   page,
2153                     HPDF_REAL   x,
2154                     HPDF_REAL   y,
2155                     HPDF_REAL  xray,
2156                     HPDF_REAL  yray)
2157 {
2158     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
2159             HPDF_GMODE_PATH_OBJECT);
2160     char buf[HPDF_TMP_BUF_SIZ];
2161     char *pbuf = buf;
2162     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
2163     HPDF_PageAttr attr;
2164 
2165     HPDF_PTRACE ((" HPDF_Page_Ellipse\n"));
2166 
2167     if (ret != HPDF_OK)
2168         return ret;
2169 
2170     attr = (HPDF_PageAttr)page->attr;
2171 
2172     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
2173 
2174     pbuf = HPDF_FToA (pbuf, x - xray, eptr);
2175     *pbuf++ = ' ';
2176     pbuf = HPDF_FToA (pbuf, y, eptr);
2177     pbuf = (char *)HPDF_StrCpy (pbuf, " m\012", eptr);
2178 
2179     pbuf = QuarterEllipseA (pbuf, eptr, x, y, xray, yray);
2180     pbuf = QuarterEllipseB (pbuf, eptr, x, y, xray, yray);
2181     pbuf = QuarterEllipseC (pbuf, eptr, x, y, xray, yray);
2182     QuarterEllipseD (pbuf, eptr, x, y, xray, yray);
2183 
2184     if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
2185         return HPDF_CheckError (page->error);
2186 
2187     attr->cur_pos.x = x - xray;
2188     attr->cur_pos.y = y;
2189     attr->str_pos = attr->cur_pos;
2190     attr->gmode = HPDF_GMODE_PATH_OBJECT;
2191 
2192     return ret;
2193 }
2194 
2195 
2196 /*
2197  * this function is based on the code which is contributed by Riccardo Cohen.
2198  *
2199  * from http://www.tinaja.com/glib/bezarc1.pdf coming from
2200  * http://www.whizkidtech.redprince.net/bezier/circle/
2201  */
2202 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Arc(HPDF_Page page,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray,HPDF_REAL ang1,HPDF_REAL ang2)2203 HPDF_Page_Arc  (HPDF_Page    page,
2204                 HPDF_REAL    x,
2205                 HPDF_REAL    y,
2206                 HPDF_REAL    ray,
2207                 HPDF_REAL    ang1,
2208                 HPDF_REAL    ang2)
2209 {
2210     HPDF_BOOL cont_flg = HPDF_FALSE;
2211 
2212     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
2213                     HPDF_GMODE_PATH_OBJECT);
2214 
2215     HPDF_PTRACE ((" HPDF_Page_Arc\n"));
2216 
2217     if (fabs(ang2 - ang1) >= 360)
2218         HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
2219 
2220     if (ret != HPDF_OK)
2221         return ret;
2222 
2223     while (ang1 < 0 || ang2 < 0) {
2224         ang1 = ang1 + 360;
2225         ang2 = ang2 + 360;
2226     }
2227 
2228 
2229     for (;;) {
2230         if (fabs(ang2 - ang1) <= 90)
2231             return InternalArc (page, x, y, ray, ang1, ang2, cont_flg);
2232         else {
2233 	    HPDF_REAL tmp_ang = (ang2 > ang1 ? ang1 + 90 : ang1 - 90);
2234 
2235             if ((ret = InternalArc (page, x, y, ray, ang1, tmp_ang, cont_flg))
2236                     != HPDF_OK)
2237                 return ret;
2238 
2239             ang1 = tmp_ang;
2240         }
2241 
2242         if (fabs(ang1 - ang2) < 0.1)
2243             break;
2244 
2245         cont_flg = HPDF_TRUE;
2246     }
2247 
2248     return HPDF_OK;
2249 }
2250 
2251 
2252 static HPDF_STATUS
InternalArc(HPDF_Page page,HPDF_REAL x,HPDF_REAL y,HPDF_REAL ray,HPDF_REAL ang1,HPDF_REAL ang2,HPDF_BOOL cont_flg)2253 InternalArc  (HPDF_Page    page,
2254               HPDF_REAL    x,
2255               HPDF_REAL    y,
2256               HPDF_REAL    ray,
2257               HPDF_REAL    ang1,
2258               HPDF_REAL    ang2,
2259               HPDF_BOOL    cont_flg)
2260 {
2261     const HPDF_REAL PIE = 3.14159F;
2262 
2263     char buf[HPDF_TMP_BUF_SIZ];
2264     char *pbuf = buf;
2265     char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
2266     HPDF_PageAttr attr;
2267     HPDF_STATUS ret;
2268 
2269     HPDF_DOUBLE rx0, ry0, rx1, ry1, rx2, ry2, rx3, ry3;
2270     HPDF_DOUBLE x0, y0, x1, y1, x2, y2, x3, y3;
2271     HPDF_DOUBLE delta_angle;
2272     HPDF_DOUBLE new_angle;
2273 
2274     HPDF_PTRACE ((" HPDF_Page_InternalArc\n"));
2275 
2276     attr = (HPDF_PageAttr)page->attr;
2277 
2278     HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
2279 
2280     delta_angle = (90 - (HPDF_DOUBLE)(ang1 + ang2) / 2) / 180 * PIE;
2281     new_angle = (HPDF_DOUBLE)(ang2 - ang1) / 2 / 180 * PIE;
2282 
2283     rx0 = ray * HPDF_COS (new_angle);
2284     ry0 = ray * HPDF_SIN (new_angle);
2285     rx2 = (ray * 4.0 - rx0) / 3.0;
2286     ry2 = ((ray * 1.0 - rx0) * (rx0 - ray * 3.0)) / (3.0 * ry0);
2287     rx1 = rx2;
2288     ry1 = -ry2;
2289     rx3 = rx0;
2290     ry3 = -ry0;
2291 
2292     x0 = rx0 * HPDF_COS (delta_angle) - ry0 * HPDF_SIN (delta_angle) + x;
2293     y0 = rx0 * HPDF_SIN (delta_angle) + ry0 * HPDF_COS (delta_angle) + y;
2294     x1 = rx1 * HPDF_COS (delta_angle) - ry1 * HPDF_SIN (delta_angle) + x;
2295     y1 = rx1 * HPDF_SIN (delta_angle) + ry1 * HPDF_COS (delta_angle) + y;
2296     x2 = rx2 * HPDF_COS (delta_angle) - ry2 * HPDF_SIN (delta_angle) + x;
2297     y2 = rx2 * HPDF_SIN (delta_angle) + ry2 * HPDF_COS (delta_angle) + y;
2298     x3 = rx3 * HPDF_COS (delta_angle) - ry3 * HPDF_SIN (delta_angle) + x;
2299     y3 = rx3 * HPDF_SIN (delta_angle) + ry3 * HPDF_COS (delta_angle) + y;
2300 
2301     if (!cont_flg) {
2302         pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x0, eptr);
2303         *pbuf++ = ' ';
2304         pbuf = HPDF_FToA (pbuf, (HPDF_REAL)y0, eptr);
2305 
2306 	if (attr->gmode == HPDF_GMODE_PATH_OBJECT)
2307 	  pbuf = (char *)HPDF_StrCpy (pbuf, " l\012", eptr);
2308 	else
2309 	  pbuf = (char *)HPDF_StrCpy (pbuf, " m\012", eptr);
2310     }
2311 
2312     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x1, eptr);
2313     *pbuf++ = ' ';
2314     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)y1, eptr);
2315     *pbuf++ = ' ';
2316     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x2, eptr);
2317     *pbuf++ = ' ';
2318     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)y2, eptr);
2319     *pbuf++ = ' ';
2320     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)x3, eptr);
2321     *pbuf++ = ' ';
2322     pbuf = HPDF_FToA (pbuf, (HPDF_REAL)y3, eptr);
2323     HPDF_StrCpy (pbuf, " c\012", eptr);
2324 
2325     if ((ret = HPDF_Stream_WriteStr (attr->stream, buf)) != HPDF_OK)
2326         return HPDF_CheckError (page->error);
2327 
2328     attr->cur_pos.x = (HPDF_REAL)x3;
2329     attr->cur_pos.y = (HPDF_REAL)y3;
2330     attr->str_pos = attr->cur_pos;
2331     attr->gmode = HPDF_GMODE_PATH_OBJECT;
2332 
2333     return ret;
2334 }
2335 
2336 
2337 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_DrawImage(HPDF_Page page,HPDF_Image image,HPDF_REAL x,HPDF_REAL y,HPDF_REAL width,HPDF_REAL height)2338 HPDF_Page_DrawImage  (HPDF_Page    page,
2339                       HPDF_Image   image,
2340                       HPDF_REAL    x,
2341                       HPDF_REAL    y,
2342                       HPDF_REAL    width,
2343                       HPDF_REAL    height)
2344 {
2345     HPDF_STATUS ret;
2346 
2347     if ((ret = HPDF_Page_GSave (page)) != HPDF_OK)
2348         return ret;
2349 
2350     if ((ret = HPDF_Page_Concat (page, width, 0, 0, height, x, y)) != HPDF_OK)
2351         return ret;
2352 
2353     if ((ret = HPDF_Page_ExecuteXObject (page, image)) != HPDF_OK)
2354         return ret;
2355 
2356     return HPDF_Page_GRestore (page);
2357 }
2358 
2359 
2360 static HPDF_STATUS
InternalWriteText(HPDF_PageAttr attr,const char * text)2361 InternalWriteText  (HPDF_PageAttr      attr,
2362                     const char        *text)
2363 {
2364     HPDF_FontAttr font_attr = (HPDF_FontAttr)attr->gstate->font->attr;
2365     HPDF_STATUS ret;
2366 
2367     HPDF_PTRACE ((" InternalWriteText\n"));
2368 
2369     if (font_attr->type == HPDF_FONT_TYPE0_TT ||
2370             font_attr->type == HPDF_FONT_TYPE0_CID) {
2371         HPDF_Encoder encoder;
2372 	HPDF_UINT len;
2373 
2374         if ((ret = HPDF_Stream_WriteStr (attr->stream, "<")) != HPDF_OK)
2375             return ret;
2376 
2377         encoder = font_attr->encoder;
2378         len = HPDF_StrLen (text, HPDF_LIMIT_MAX_STRING_LEN);
2379 
2380         if (encoder->encode_text_fn == NULL) {
2381 	    if ((ret = HPDF_Stream_WriteBinary (attr->stream, (HPDF_BYTE *)text,
2382 						len, NULL))
2383 		!= HPDF_OK)
2384 	        return ret;
2385         } else {
2386 	    char *encoded;
2387 	    HPDF_UINT length;
2388 
2389 	    encoded = (encoder->encode_text_fn)(encoder, text, len, &length);
2390 
2391 	    ret = HPDF_Stream_WriteBinary (attr->stream, (HPDF_BYTE *)encoded,
2392 					   length, NULL);
2393 
2394 	    free(encoded);
2395 
2396 	    if (ret != HPDF_OK)
2397                 return ret;
2398         }
2399 
2400         return HPDF_Stream_WriteStr (attr->stream, ">");
2401     }
2402 
2403     return HPDF_Stream_WriteEscapeText (attr->stream, text);
2404 }
2405 
2406 
2407 /*
2408  * Convert a user space text position from absolute to relative coordinates.
2409  * Absolute values are passed in xAbs and yAbs, relative values are returned
2410  * to xRel and yRel. The latter two must not be NULL.
2411  */
2412 static void
TextPos_AbsToRel(HPDF_TransMatrix text_matrix,HPDF_REAL xAbs,HPDF_REAL yAbs,HPDF_REAL * xRel,HPDF_REAL * yRel)2413 TextPos_AbsToRel (HPDF_TransMatrix text_matrix,
2414                   HPDF_REAL xAbs,
2415                   HPDF_REAL yAbs,
2416                   HPDF_REAL *xRel,
2417                   HPDF_REAL *yRel)
2418 {
2419     if (text_matrix.a == 0) {
2420         *xRel = (yAbs - text_matrix.y - (xAbs - text_matrix.x) *
2421             text_matrix.d / text_matrix.c) / text_matrix.b;
2422         *yRel  = (xAbs - text_matrix.x) / text_matrix.c;
2423     } else {
2424         HPDF_REAL y = (yAbs - text_matrix.y - (xAbs - text_matrix.x) *
2425             text_matrix.b / text_matrix.a) / (text_matrix.d -
2426             text_matrix.c * text_matrix.b / text_matrix.a);
2427         *xRel = (xAbs - text_matrix.x - y * text_matrix.c) /
2428             text_matrix.a;
2429         *yRel = y;
2430     }
2431 }
2432 
2433 
2434 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_TextOut(HPDF_Page page,HPDF_REAL xpos,HPDF_REAL ypos,const char * text)2435 HPDF_Page_TextOut  (HPDF_Page    page,
2436                     HPDF_REAL    xpos,
2437                     HPDF_REAL    ypos,
2438                     const char  *text)
2439 {
2440     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
2441     HPDF_REAL x;
2442     HPDF_REAL y;
2443     HPDF_PageAttr attr;
2444 
2445     HPDF_PTRACE ((" HPDF_Page_TextOut\n"));
2446 
2447     if (ret != HPDF_OK)
2448         return ret;
2449 
2450     attr = (HPDF_PageAttr)page->attr;
2451     TextPos_AbsToRel (attr->text_matrix, xpos, ypos, &x, &y);
2452     if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
2453         return ret;
2454 
2455     return  HPDF_Page_ShowText (page, text);
2456 }
2457 
2458 
2459 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_TextRect(HPDF_Page page,HPDF_REAL left,HPDF_REAL top,HPDF_REAL right,HPDF_REAL bottom,const char * text,HPDF_TextAlignment align,HPDF_UINT * len)2460 HPDF_Page_TextRect  (HPDF_Page            page,
2461                      HPDF_REAL            left,
2462                      HPDF_REAL            top,
2463                      HPDF_REAL            right,
2464                      HPDF_REAL            bottom,
2465                      const char          *text,
2466                      HPDF_TextAlignment   align,
2467                      HPDF_UINT           *len
2468                      )
2469 {
2470     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
2471     HPDF_PageAttr attr;
2472     const char *ptr = text;
2473     HPDF_BOOL pos_initialized = HPDF_FALSE;
2474     HPDF_REAL save_char_space = 0;
2475     HPDF_BOOL is_insufficient_space = HPDF_FALSE;
2476     HPDF_UINT num_rest;
2477     HPDF_Box bbox;
2478     HPDF_BOOL char_space_changed = HPDF_FALSE;
2479 
2480     HPDF_PTRACE ((" HPDF_Page_TextRect\n"));
2481 
2482     if (ret != HPDF_OK)
2483         return ret;
2484 
2485     attr = (HPDF_PageAttr )page->attr;
2486 
2487     /* no font exists */
2488     if (!attr->gstate->font) {
2489         return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
2490     }
2491 
2492     bbox = HPDF_Font_GetBBox (attr->gstate->font);
2493 
2494     if (len)
2495         *len = 0;
2496     num_rest = HPDF_StrLen (text, HPDF_LIMIT_MAX_STRING_LEN + 1);
2497 
2498     if (num_rest > HPDF_LIMIT_MAX_STRING_LEN) {
2499         return HPDF_RaiseError (page->error, HPDF_STRING_OUT_OF_RANGE, 0);
2500     } else if (!num_rest)
2501         return HPDF_OK;
2502 
2503     if (attr->gstate->text_leading == 0)
2504         HPDF_Page_SetTextLeading (page, (bbox.top - bbox.bottom) / 1000 *
2505                 attr->gstate->font_size);
2506 
2507     top = top - bbox.top / 1000 * attr->gstate->font_size +
2508                 attr->gstate->text_leading;
2509     bottom = bottom - bbox.bottom / 1000 * attr->gstate->font_size;
2510 
2511     if (align == HPDF_TALIGN_JUSTIFY) {
2512         save_char_space = attr->gstate->char_space;
2513         attr->gstate->char_space = 0;
2514     }
2515 
2516     for (;;) {
2517         HPDF_REAL x, y;
2518         HPDF_UINT line_len, tmp_len;
2519         HPDF_REAL rw;
2520         HPDF_BOOL LineBreak;
2521 
2522         attr->gstate->char_space = 0;
2523         line_len = tmp_len = HPDF_Page_MeasureText (page, ptr, right - left, HPDF_TRUE, &rw);
2524         if (line_len == 0) {
2525             is_insufficient_space = HPDF_TRUE;
2526             break;
2527         }
2528 
2529         if (len)
2530             *len += line_len;
2531         num_rest -= line_len;
2532 
2533         /* Shorten tmp_len by trailing whitespace and control characters. */
2534         LineBreak = HPDF_FALSE;
2535         while (tmp_len > 0 && HPDF_IS_WHITE_SPACE(ptr[tmp_len - 1])) {
2536             tmp_len--;
2537             if (ptr[tmp_len] == 0x0A || ptr[tmp_len] == 0x0D) {
2538                 LineBreak = HPDF_TRUE;
2539             }
2540         }
2541 
2542         switch (align) {
2543 
2544             case HPDF_TALIGN_RIGHT:
2545                 TextPos_AbsToRel (attr->text_matrix, right - rw, top, &x, &y);
2546                 if (!pos_initialized) {
2547                     pos_initialized = HPDF_TRUE;
2548                 } else {
2549                     y = 0;
2550                 }
2551                 if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
2552                     return ret;
2553                 break;
2554 
2555             case HPDF_TALIGN_CENTER:
2556                 TextPos_AbsToRel (attr->text_matrix, left + (right - left - rw) / 2, top, &x, &y);
2557                 if (!pos_initialized) {
2558                     pos_initialized = HPDF_TRUE;
2559                 } else {
2560                     y = 0;
2561                 }
2562                 if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
2563                     return ret;
2564                 break;
2565 
2566             case HPDF_TALIGN_JUSTIFY:
2567                 if (!pos_initialized) {
2568                     pos_initialized = HPDF_TRUE;
2569                     TextPos_AbsToRel (attr->text_matrix, left, top, &x, &y);
2570                     if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
2571                         return ret;
2572                 }
2573 
2574                 /* Do not justify last line of paragraph or text. */
2575                 if (LineBreak || num_rest <= 0) {
2576                     if ((ret = HPDF_Page_SetCharSpace (page, save_char_space))
2577                                     != HPDF_OK)
2578                         return ret;
2579                     char_space_changed = HPDF_FALSE;
2580                 } else {
2581                     HPDF_REAL x_adjust;
2582                     HPDF_ParseText_Rec state;
2583                     HPDF_UINT i = 0;
2584                     HPDF_UINT num_char = 0;
2585                     HPDF_Encoder encoder = ((HPDF_FontAttr)attr->gstate->font->attr)->encoder;
2586                     const char *tmp_ptr = ptr;
2587                     HPDF_Encoder_SetParseText (encoder, &state, (HPDF_BYTE *)tmp_ptr, tmp_len);
2588                     while (*tmp_ptr) {
2589                         HPDF_ByteType btype = HPDF_Encoder_ByteType (encoder, &state);
2590                         if (btype != HPDF_BYTE_TYPE_TRIAL)
2591                             num_char++;
2592                         i++;
2593                         if (i >= tmp_len)
2594                             break;
2595                         tmp_ptr++;
2596                     }
2597 
2598                     x_adjust = num_char == 0 ? 0 : (right - left - rw) / (num_char - 1);
2599                     if ((ret = HPDF_Page_SetCharSpace (page, x_adjust)) != HPDF_OK)
2600                         return ret;
2601                     char_space_changed = HPDF_TRUE;
2602                 }
2603                 break;
2604 
2605             default:
2606                 if (!pos_initialized) {
2607                     pos_initialized = HPDF_TRUE;
2608                     TextPos_AbsToRel (attr->text_matrix, left, top, &x, &y);
2609                     if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
2610                         return ret;
2611                 }
2612         }
2613 
2614         if (InternalShowTextNextLine (page, ptr, tmp_len) != HPDF_OK)
2615             return HPDF_CheckError (page->error);
2616 
2617         if (num_rest <= 0)
2618             break;
2619 
2620         if (attr->text_pos.y - attr->gstate->text_leading < bottom) {
2621             is_insufficient_space = HPDF_TRUE;
2622             break;
2623         }
2624 
2625         ptr += line_len;
2626     }
2627 
2628     if (char_space_changed && save_char_space != attr->gstate->char_space) {
2629         if ((ret = HPDF_Page_SetCharSpace (page, save_char_space)) != HPDF_OK)
2630             return ret;
2631     }
2632 
2633     if (is_insufficient_space)
2634         return HPDF_PAGE_INSUFFICIENT_SPACE;
2635     else
2636         return HPDF_OK;
2637 }
2638 
2639 
2640 static HPDF_STATUS
InternalShowTextNextLine(HPDF_Page page,const char * text,HPDF_UINT len)2641 InternalShowTextNextLine  (HPDF_Page    page,
2642                            const char  *text,
2643                            HPDF_UINT    len)
2644 {
2645     HPDF_STATUS ret;
2646     HPDF_PageAttr attr;
2647     HPDF_REAL tw;
2648     HPDF_FontAttr font_attr;
2649 
2650     HPDF_PTRACE ((" ShowTextNextLine\n"));
2651 
2652     attr = (HPDF_PageAttr)page->attr;
2653     font_attr = (HPDF_FontAttr)attr->gstate->font->attr;
2654 
2655     if (font_attr->type == HPDF_FONT_TYPE0_TT ||
2656             font_attr->type == HPDF_FONT_TYPE0_CID) {
2657         HPDF_Encoder encoder = font_attr->encoder;
2658 
2659         if ((ret = HPDF_Stream_WriteStr (attr->stream, "<")) != HPDF_OK)
2660             return ret;
2661 
2662         if (encoder->encode_text_fn == NULL) {
2663 	    if ((ret = HPDF_Stream_WriteBinary (attr->stream, (HPDF_BYTE *)text,
2664 						len, NULL))
2665 		!= HPDF_OK)
2666 	        return ret;
2667         } else {
2668 	    char *encoded;
2669 	    HPDF_UINT length;
2670 
2671 	    encoded = (encoder->encode_text_fn)(encoder, text, len, &length);
2672 	    ret = HPDF_Stream_WriteBinary (attr->stream, (HPDF_BYTE *)encoded,
2673 					   length, NULL);
2674 	    free(encoded);
2675 
2676 	    if (ret != HPDF_OK)
2677 	        return ret;
2678         }
2679 
2680         if ((ret = HPDF_Stream_WriteStr (attr->stream, ">")) != HPDF_OK)
2681             return ret;
2682     } else  if ((ret = HPDF_Stream_WriteEscapeText2 (attr->stream, text,
2683                 len)) != HPDF_OK)
2684         return ret;
2685 
2686     if ((ret = HPDF_Stream_WriteStr (attr->stream, " \'\012")) != HPDF_OK)
2687         return ret;
2688 
2689     tw = HPDF_Page_TextWidth (page, text);
2690 
2691     /* calculate the reference point of text */
2692     attr->text_matrix.x -= attr->gstate->text_leading * attr->text_matrix.c;
2693     attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.d;
2694 
2695     attr->text_pos.x = attr->text_matrix.x;
2696     attr->text_pos.y = attr->text_matrix.y;
2697 
2698     if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
2699         attr->text_pos.x += tw * attr->text_matrix.a;
2700         attr->text_pos.y += tw * attr->text_matrix.b;
2701     } else {
2702         attr->text_pos.x -= tw * attr->text_matrix.b;
2703         attr->text_pos.y -= tw * attr->text_matrix.a;
2704     }
2705 
2706     return ret;
2707 }
2708 
2709 
2710 /*
2711  *  This function is contributed by Adrian Nelson (adenelson).
2712  */
2713 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetSlideShow(HPDF_Page page,HPDF_TransitionStyle type,HPDF_REAL disp_time,HPDF_REAL trans_time)2714 HPDF_Page_SetSlideShow  (HPDF_Page            page,
2715                          HPDF_TransitionStyle   type,
2716                          HPDF_REAL            disp_time,
2717                          HPDF_REAL            trans_time)
2718     {
2719     HPDF_STATUS ret = HPDF_OK;
2720     HPDF_Dict dict;
2721 
2722     HPDF_PTRACE((" HPDF_Page_SetSlideShow\n"));
2723 
2724     if (!HPDF_Page_Validate (page))
2725         return HPDF_INVALID_PAGE;
2726 
2727     if (disp_time < 0)
2728         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_DISPLAY_TIME,
2729                     (HPDF_STATUS)disp_time);
2730 
2731     if (trans_time < 0)
2732         return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_TRANSITION_TIME,
2733                     (HPDF_STATUS)trans_time);
2734 
2735     dict = HPDF_Dict_New(page->mmgr);
2736 
2737     if (!dict)
2738         return HPDF_Error_GetCode (page->error);
2739 
2740     if (HPDF_Dict_AddName (dict, "Type", "Trans") != HPDF_OK)
2741         goto Fail;
2742 
2743     if (HPDF_Dict_AddReal (dict, "D", trans_time) != HPDF_OK)
2744         goto Fail;
2745 
2746     switch (type) {
2747         case HPDF_TS_WIPE_RIGHT:
2748             ret += HPDF_Dict_AddName (dict, "S", "Wipe");
2749             ret += HPDF_Dict_AddNumber (dict, "Di", 0);
2750             break;
2751         case HPDF_TS_WIPE_UP:
2752             ret += HPDF_Dict_AddName (dict, "S", "Wipe");
2753             ret += HPDF_Dict_AddNumber (dict, "Di", 90);
2754             break;
2755         case HPDF_TS_WIPE_LEFT:
2756             ret += HPDF_Dict_AddName (dict, "S", "Wipe");
2757             ret += HPDF_Dict_AddNumber (dict, "Di", 180);
2758             break;
2759         case HPDF_TS_WIPE_DOWN:
2760             ret += HPDF_Dict_AddName (dict, "S", "Wipe");
2761             ret += HPDF_Dict_AddNumber    (dict, "Di", 270);
2762             break;
2763         case HPDF_TS_BARN_DOORS_HORIZONTAL_OUT:
2764             ret += HPDF_Dict_AddName (dict, "S", "Split");
2765             ret += HPDF_Dict_AddName (dict, "Dm", "H");
2766             ret += HPDF_Dict_AddName (dict, "M", "O");
2767             break;
2768         case HPDF_TS_BARN_DOORS_HORIZONTAL_IN:
2769             ret += HPDF_Dict_AddName (dict, "S", "Split");
2770             ret += HPDF_Dict_AddName (dict, "Dm", "H");
2771             ret += HPDF_Dict_AddName (dict, "M", "I");
2772             break;
2773         case HPDF_TS_BARN_DOORS_VERTICAL_OUT:
2774             ret += HPDF_Dict_AddName (dict, "S", "Split");
2775             ret += HPDF_Dict_AddName (dict, "Dm", "V");
2776             ret += HPDF_Dict_AddName (dict, "M", "O");
2777             break;
2778         case HPDF_TS_BARN_DOORS_VERTICAL_IN:
2779             ret += HPDF_Dict_AddName (dict, "S", "Split");
2780             ret += HPDF_Dict_AddName (dict, "Dm", "V");
2781             ret += HPDF_Dict_AddName (dict, "M", "I");
2782             break;
2783         case HPDF_TS_BOX_OUT:
2784             ret += HPDF_Dict_AddName (dict, "S", "Box");
2785             ret += HPDF_Dict_AddName (dict, "M", "O");
2786             break;
2787         case HPDF_TS_BOX_IN:
2788             ret += HPDF_Dict_AddName (dict, "S", "Box");
2789             ret += HPDF_Dict_AddName (dict, "M", "I");
2790             break;
2791         case HPDF_TS_BLINDS_HORIZONTAL:
2792             ret += HPDF_Dict_AddName (dict, "S", "Blinds");
2793             ret += HPDF_Dict_AddName (dict, "Dm", "H");
2794             break;
2795         case HPDF_TS_BLINDS_VERTICAL:
2796             ret += HPDF_Dict_AddName (dict, "S", "Blinds");
2797             ret += HPDF_Dict_AddName (dict, "Dm", "V");
2798             break;
2799         case HPDF_TS_DISSOLVE:
2800             ret += HPDF_Dict_AddName (dict, "S", "Dissolve");
2801             break;
2802         case HPDF_TS_GLITTER_RIGHT:
2803             ret += HPDF_Dict_AddName (dict, "S", "Glitter");
2804             ret += HPDF_Dict_AddNumber (dict, "Di", 0);
2805             break;
2806         case HPDF_TS_GLITTER_DOWN:
2807             ret += HPDF_Dict_AddName (dict, "S", "Glitter");
2808             ret += HPDF_Dict_AddNumber (dict, "Di", 270);
2809             break;
2810         case HPDF_TS_GLITTER_TOP_LEFT_TO_BOTTOM_RIGHT:
2811             ret += HPDF_Dict_AddName (dict, "S", "Glitter");
2812             ret += HPDF_Dict_AddNumber (dict, "Di", 315);
2813             break;
2814         case HPDF_TS_REPLACE:
2815             ret += HPDF_Dict_AddName  (dict, "S", "R");
2816             break;
2817         default:
2818             ret += HPDF_SetError(page->error, HPDF_INVALID_PAGE_SLIDESHOW_TYPE, 0);
2819     }
2820 
2821     if (ret != HPDF_OK)
2822         goto Fail;
2823 
2824     if (HPDF_Dict_AddReal (page, "Dur", disp_time) != HPDF_OK)
2825         goto Fail;
2826 
2827     if ((ret = HPDF_Dict_Add (page, "Trans", dict)) != HPDF_OK)
2828         return ret;
2829 
2830     return HPDF_OK;
2831 
2832 Fail:
2833     HPDF_Dict_Free (dict);
2834     return HPDF_Error_GetCode (page->error);
2835 }
2836 
2837 
2838 /*
2839  *  This function is contributed by Finn Arildsen.
2840  */
2841 
2842 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_New_Content_Stream(HPDF_Page page,HPDF_Dict * new_stream)2843 HPDF_Page_New_Content_Stream  (HPDF_Page page,
2844                                HPDF_Dict* new_stream)
2845 {
2846     /* Call this function to start a new content stream on a page. The
2847        handle is returned to new_stream.
2848        new_stream can later be used on other pages as a shared content stream;
2849        insert using HPDF_Page_Insert_Shared_Content_Stream */
2850 
2851     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
2852                     HPDF_GMODE_TEXT_OBJECT);
2853     HPDF_PageAttr attr;
2854     HPDF_UINT filter;
2855     HPDF_Array contents_array;
2856 
2857     HPDF_PTRACE((" HPDF_Page_New_Content_Stream\n"));
2858 
2859     attr = (HPDF_PageAttr)page->attr;
2860     filter = attr->contents->filter;
2861 
2862     /* check if there is already an array of contents */
2863     contents_array = (HPDF_Array) HPDF_Dict_GetItem(page,"Contents", HPDF_OCLASS_ARRAY);
2864     if (!contents_array) {
2865         HPDF_Error_Reset (page->error);
2866         /* no contents_array already -- create one
2867            and replace current single contents item */
2868         contents_array = HPDF_Array_New(page->mmgr);
2869         if (!contents_array)
2870             return HPDF_Error_GetCode (page->error);
2871         ret += HPDF_Array_Add(contents_array,attr->contents);
2872         ret += HPDF_Dict_Add (page, "Contents", contents_array);
2873     }
2874 
2875     /* create new contents stream and add it to the page's contents array */
2876     attr->contents = HPDF_DictStream_New (page->mmgr, attr->xref);
2877     attr->contents->filter = filter;
2878     attr->stream = attr->contents->stream;
2879 
2880     if (!attr->contents)
2881         return HPDF_Error_GetCode (page->error);
2882 
2883     ret += HPDF_Array_Add (contents_array,attr->contents);
2884 
2885     /* return the value of the new stream, so that
2886        the application can use it as a shared contents stream */
2887     if (ret == HPDF_OK && new_stream != NULL)
2888         *new_stream = attr->contents;
2889 
2890     return ret;
2891 }
2892 
2893 
2894 /*
2895  *  This function is contributed by Finn Arildsen.
2896  */
2897 
2898 HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_Insert_Shared_Content_Stream(HPDF_Page page,HPDF_Dict shared_stream)2899 HPDF_Page_Insert_Shared_Content_Stream  (HPDF_Page page,
2900                                HPDF_Dict shared_stream)
2901 {
2902     /* Call this function to insert a previously (with HPDF_New_Content_Stream) created content stream
2903        as a shared content stream on this page */
2904 
2905     HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
2906                     HPDF_GMODE_TEXT_OBJECT);
2907     HPDF_Array contents_array;
2908 
2909     HPDF_PTRACE((" HPDF_Page_Insert_Shared_Content_Stream\n"));
2910 
2911     /* check if there is already an array of contents */
2912     contents_array = (HPDF_Array) HPDF_Dict_GetItem(page,"Contents", HPDF_OCLASS_ARRAY);
2913     if (!contents_array) {
2914         HPDF_PageAttr attr;
2915         HPDF_Error_Reset (page->error);
2916         /* no contents_array already -- create one
2917            and replace current single contents item */
2918         contents_array = HPDF_Array_New(page->mmgr);
2919         if (!contents_array)
2920             return HPDF_Error_GetCode (page->error);
2921         attr = (HPDF_PageAttr)page->attr;
2922         ret += HPDF_Array_Add(contents_array,attr->contents);
2923         ret += HPDF_Dict_Add (page, "Contents", contents_array);
2924     }
2925 
2926     ret += HPDF_Array_Add (contents_array,shared_stream);
2927 
2928     /* Continue with a new stream */
2929     ret += HPDF_Page_New_Content_Stream (page, NULL);
2930 
2931     return ret;
2932 }
2933