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