hpdf 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. data/History +57 -0
  2. data/License +25 -0
  3. data/README +165 -0
  4. data/examples/arc_demo.rb +82 -0
  5. data/examples/demo.rb +92 -0
  6. data/examples/encryption.rb +41 -0
  7. data/examples/ext_gstater_demo.rb +171 -0
  8. data/examples/font_demo.rb +67 -0
  9. data/examples/jpfont_demo.rb +122 -0
  10. data/examples/line_demo.rb +301 -0
  11. data/examples/slide_show_demo.rb +139 -0
  12. data/examples/text_demo2.rb +189 -0
  13. data/examples/ttfont_demo.rb +106 -0
  14. data/ext/extconf.rb +6 -0
  15. data/ext/hpdf.c +3779 -0
  16. data/ext/hpdf_annotation.c +415 -0
  17. data/ext/hpdf_array.c +344 -0
  18. data/ext/hpdf_binary.c +117 -0
  19. data/ext/hpdf_boolean.c +47 -0
  20. data/ext/hpdf_catalog.c +354 -0
  21. data/ext/hpdf_destination.c +339 -0
  22. data/ext/hpdf_dict.c +488 -0
  23. data/ext/hpdf_doc.c +2020 -0
  24. data/ext/hpdf_doc_png.c +137 -0
  25. data/ext/hpdf_encoder.c +2991 -0
  26. data/ext/hpdf_encoder_cns.c +36359 -0
  27. data/ext/hpdf_encoder_cnt.c +15307 -0
  28. data/ext/hpdf_encoder_jp.c +16125 -0
  29. data/ext/hpdf_encoder_kr.c +27978 -0
  30. data/ext/hpdf_encrypt.c +632 -0
  31. data/ext/hpdf_encryptdict.c +240 -0
  32. data/ext/hpdf_error.c +114 -0
  33. data/ext/hpdf_ext_gstate.c +150 -0
  34. data/ext/hpdf_font.c +229 -0
  35. data/ext/hpdf_font_cid.c +1030 -0
  36. data/ext/hpdf_font_tt.c +406 -0
  37. data/ext/hpdf_font_type1.c +391 -0
  38. data/ext/hpdf_fontdef.c +56 -0
  39. data/ext/hpdf_fontdef_base14.c +4506 -0
  40. data/ext/hpdf_fontdef_cid.c +194 -0
  41. data/ext/hpdf_fontdef_cns.c +471 -0
  42. data/ext/hpdf_fontdef_cnt.c +250 -0
  43. data/ext/hpdf_fontdef_jp.c +1904 -0
  44. data/ext/hpdf_fontdef_kr.c +1572 -0
  45. data/ext/hpdf_fontdef_tt.c +2230 -0
  46. data/ext/hpdf_fontdef_type1.c +524 -0
  47. data/ext/hpdf_gstate.c +119 -0
  48. data/ext/hpdf_image.c +568 -0
  49. data/ext/hpdf_image_png.c +424 -0
  50. data/ext/hpdf_info.c +164 -0
  51. data/ext/hpdf_list.c +333 -0
  52. data/ext/hpdf_mmgr.c +243 -0
  53. data/ext/hpdf_name.c +71 -0
  54. data/ext/hpdf_null.c +31 -0
  55. data/ext/hpdf_number.c +49 -0
  56. data/ext/hpdf_objects.c +172 -0
  57. data/ext/hpdf_outline.c +329 -0
  58. data/ext/hpdf_page_label.c +74 -0
  59. data/ext/hpdf_page_operator.c +2764 -0
  60. data/ext/hpdf_pages.c +1508 -0
  61. data/ext/hpdf_real.c +61 -0
  62. data/ext/hpdf_streams.c +1435 -0
  63. data/ext/hpdf_string.c +189 -0
  64. data/ext/hpdf_utils.c +438 -0
  65. data/ext/hpdf_xref.c +348 -0
  66. data/ext/include/hpdf.h +1227 -0
  67. data/ext/include/hpdf_annotation.h +74 -0
  68. data/ext/include/hpdf_catalog.h +81 -0
  69. data/ext/include/hpdf_conf.h +76 -0
  70. data/ext/include/hpdf_consts.h +549 -0
  71. data/ext/include/hpdf_destination.h +41 -0
  72. data/ext/include/hpdf_doc.h +159 -0
  73. data/ext/include/hpdf_encoder.h +311 -0
  74. data/ext/include/hpdf_encrypt.h +156 -0
  75. data/ext/include/hpdf_encryptdict.h +66 -0
  76. data/ext/include/hpdf_error.h +201 -0
  77. data/ext/include/hpdf_ext_gstate.h +38 -0
  78. data/ext/include/hpdf_font.h +112 -0
  79. data/ext/include/hpdf_fontdef.h +403 -0
  80. data/ext/include/hpdf_gstate.h +80 -0
  81. data/ext/include/hpdf_image.h +72 -0
  82. data/ext/include/hpdf_info.h +48 -0
  83. data/ext/include/hpdf_list.h +85 -0
  84. data/ext/include/hpdf_mmgr.h +82 -0
  85. data/ext/include/hpdf_objects.h +587 -0
  86. data/ext/include/hpdf_outline.h +74 -0
  87. data/ext/include/hpdf_page_label.h +35 -0
  88. data/ext/include/hpdf_pages.h +128 -0
  89. data/ext/include/hpdf_streams.h +276 -0
  90. data/ext/include/hpdf_types.h +488 -0
  91. data/ext/include/hpdf_utils.h +161 -0
  92. data/tests/arc_demo.rb +82 -0
  93. data/tests/demo.rb +91 -0
  94. data/tests/encryption.rb +41 -0
  95. data/tests/ext_gstater_demo.rb +171 -0
  96. data/tests/font_demo.rb +67 -0
  97. data/tests/line_demo.rb +301 -0
  98. data/tests/slide_show_demo.rb +139 -0
  99. data/tests/test_all_examples.rb +31 -0
  100. data/tests/text_demo2.rb +189 -0
  101. metadata +147 -0
@@ -0,0 +1,406 @@
1
+ /*
2
+ * << Haru Free PDF Library 2.0.3 >> -- hpdf_font_tt.c
3
+ *
4
+ * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
5
+ *
6
+ * Permission to use, copy, modify, distribute and sell this software
7
+ * and its documentation for any purpose is hereby granted without fee,
8
+ * provided that the above copyright notice appear in all copies and
9
+ * that both that copyright notice and this permission notice appear
10
+ * in supporting documentation.
11
+ * It is provided "as is" without express or implied warranty.
12
+ *
13
+ */
14
+
15
+ #include "hpdf_conf.h"
16
+ #include "hpdf_utils.h"
17
+ #include "hpdf_font.h"
18
+
19
+ static HPDF_STATUS
20
+ OnWrite (HPDF_Dict obj,
21
+ HPDF_Stream stream);
22
+
23
+ static HPDF_STATUS
24
+ BeforeWrite (HPDF_Dict obj);
25
+
26
+
27
+ static void
28
+ OnFree (HPDF_Dict obj);
29
+
30
+
31
+ static HPDF_INT
32
+ CharWidth (HPDF_Font font,
33
+ HPDF_BYTE code);
34
+
35
+ static HPDF_TextWidth
36
+ TextWidth (HPDF_Font font,
37
+ const HPDF_BYTE *text,
38
+ HPDF_UINT len);
39
+
40
+
41
+ static HPDF_STATUS
42
+ CreateDescriptor (HPDF_Font font);
43
+
44
+
45
+ static HPDF_UINT
46
+ MeasureText (HPDF_Font font,
47
+ const HPDF_BYTE *text,
48
+ HPDF_UINT len,
49
+ HPDF_REAL width,
50
+ HPDF_REAL font_size,
51
+ HPDF_REAL char_space,
52
+ HPDF_REAL word_space,
53
+ HPDF_BOOL wordwrap,
54
+ HPDF_REAL *real_width);
55
+
56
+
57
+ HPDF_Font
58
+ HPDF_TTFont_New (HPDF_MMgr mmgr,
59
+ HPDF_FontDef fontdef,
60
+ HPDF_Encoder encoder,
61
+ HPDF_Xref xref)
62
+ {
63
+ HPDF_Dict font;
64
+ HPDF_FontAttr attr;
65
+ HPDF_TTFontDefAttr fontdef_attr;
66
+ HPDF_BasicEncoderAttr encoder_attr;
67
+ HPDF_STATUS ret = 0;
68
+
69
+ HPDF_PTRACE ((" HPDF_TTFont_New\n"));
70
+
71
+ font = HPDF_Dict_New (mmgr);
72
+ if (!font)
73
+ return NULL;
74
+
75
+ font->header.obj_class |= HPDF_OSUBCLASS_FONT;
76
+
77
+ /* check whether the fontdef object and the encoder object is valid. */
78
+ if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) {
79
+ HPDF_SetError(font->error, HPDF_INVALID_ENCODER_TYPE, 0);
80
+ return NULL;
81
+ }
82
+
83
+ if (fontdef->type != HPDF_FONTDEF_TYPE_TRUETYPE) {
84
+ HPDF_SetError(font->error, HPDF_INVALID_FONTDEF_TYPE, 0);
85
+ return NULL;
86
+ }
87
+
88
+ attr = HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec));
89
+ if (!attr) {
90
+ HPDF_Dict_Free (font);
91
+ return NULL;
92
+ }
93
+
94
+ HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec));
95
+
96
+ font->header.obj_class |= HPDF_OSUBCLASS_FONT;
97
+ font->write_fn = OnWrite;
98
+ font->before_write_fn = BeforeWrite;
99
+ font->free_fn = OnFree;
100
+ font->attr = attr;
101
+
102
+ attr->type = HPDF_FONT_TRUETYPE;
103
+ attr->writing_mode = HPDF_WMODE_HORIZONTAL;
104
+ attr->text_width_fn = TextWidth;
105
+ attr->measure_text_fn = MeasureText;
106
+ attr->fontdef = fontdef;
107
+ attr->encoder = encoder;
108
+ attr->xref = xref;
109
+
110
+ /* singlebyte-font has a widths-array which is an array of 256 signed
111
+ * short integer.
112
+ * in the case of type1-font, widths-array for all letters is made in
113
+ * constructer. but in the case of true-type-font, the array is
114
+ * initialized at 0, and set when the corresponding character was used
115
+ * for the first time.
116
+ */
117
+ attr->widths = HPDF_GetMem (mmgr, sizeof(HPDF_INT16) * 256);
118
+ if (!attr->widths) {
119
+ HPDF_Dict_Free (font);
120
+ return NULL;
121
+ }
122
+
123
+ HPDF_MemSet (attr->widths, 0, sizeof(HPDF_INT16) * 256);
124
+
125
+ attr->used = HPDF_GetMem (mmgr, sizeof(HPDF_BYTE) * 256);
126
+ if (!attr->used) {
127
+ HPDF_Dict_Free (font);
128
+ return NULL;
129
+ }
130
+
131
+ HPDF_MemSet (attr->used, 0, sizeof(HPDF_BYTE) * 256);
132
+
133
+ fontdef_attr = (HPDF_TTFontDefAttr)fontdef->attr;
134
+
135
+ ret += HPDF_Dict_AddName (font, "Type", "Font");
136
+ ret += HPDF_Dict_AddName (font, "BaseFont", fontdef_attr->base_font);
137
+ ret += HPDF_Dict_AddName (font, "Subtype", "TrueType");
138
+
139
+ encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr;
140
+
141
+ ret += HPDF_Dict_AddNumber (font, "FirstChar", encoder_attr->first_char);
142
+ ret += HPDF_Dict_AddNumber (font, "LastChar", encoder_attr->last_char);
143
+ if (fontdef->missing_width != 0)
144
+ ret += HPDF_Dict_AddNumber (font, "MissingWidth",
145
+ fontdef->missing_width);
146
+
147
+ if (ret != HPDF_OK) {
148
+ HPDF_Dict_Free (font);
149
+ return NULL;
150
+ }
151
+
152
+ if (HPDF_Xref_Add (xref, font) != HPDF_OK)
153
+ return NULL;
154
+
155
+ return font;
156
+ }
157
+
158
+
159
+ static HPDF_STATUS
160
+ CreateDescriptor (HPDF_Font font)
161
+ {
162
+ HPDF_FontAttr font_attr = (HPDF_FontAttr)font->attr;
163
+ HPDF_FontDef def = font_attr->fontdef;
164
+ HPDF_TTFontDefAttr def_attr = (HPDF_TTFontDefAttr)def->attr;
165
+
166
+ HPDF_PTRACE ((" HPDF_TTFont_CreateDescriptor\n"));
167
+
168
+ if (!font_attr->fontdef->descriptor) {
169
+ HPDF_Dict descriptor = HPDF_Dict_New (font->mmgr);
170
+ HPDF_STATUS ret = 0;
171
+ HPDF_Array array;
172
+
173
+ if (!descriptor)
174
+ return HPDF_Error_GetCode (font->error);
175
+
176
+ ret += HPDF_Xref_Add (font_attr->xref, descriptor);
177
+ ret += HPDF_Dict_AddName (descriptor, "Type", "FontDescriptor");
178
+ ret += HPDF_Dict_AddNumber (descriptor, "Ascent", def->ascent);
179
+ ret += HPDF_Dict_AddNumber (descriptor, "Descent", def->descent);
180
+ ret += HPDF_Dict_AddNumber (descriptor, "Flags", def->flags);
181
+
182
+ array = HPDF_Box_Array_New (font->mmgr, def->font_bbox);
183
+ ret += HPDF_Dict_Add (descriptor, "FontBBox", array);
184
+
185
+ ret += HPDF_Dict_AddName (descriptor, "FontName", def_attr->base_font);
186
+ ret += HPDF_Dict_AddNumber (descriptor, "ItalicAngle",
187
+ def->italic_angle);
188
+ ret += HPDF_Dict_AddNumber (descriptor, "StemV", def->stemv);
189
+ ret += HPDF_Dict_AddNumber (descriptor, "XHeight", def->x_height);
190
+
191
+ if (def_attr->char_set)
192
+ ret += HPDF_Dict_AddName (descriptor, "CharSet",
193
+ def_attr->char_set);
194
+
195
+ if (ret != HPDF_OK)
196
+ return HPDF_Error_GetCode (font->error);
197
+
198
+ if (def_attr->embedding) {
199
+ HPDF_Dict font_data = HPDF_DictStream_New (font->mmgr,
200
+ font_attr->xref);
201
+
202
+ if (!font_data)
203
+ return HPDF_Error_GetCode (font->error);
204
+
205
+ if (HPDF_TTFontDef_SaveFontData (font_attr->fontdef,
206
+ font_data->stream) != HPDF_OK)
207
+ return HPDF_Error_GetCode (font->error);
208
+
209
+ ret += HPDF_Dict_Add (descriptor, "FontFile2", font_data);
210
+ ret += HPDF_Dict_AddNumber (font_data, "Length1",
211
+ def_attr->length1);
212
+ ret += HPDF_Dict_AddNumber (font_data, "Length2", 0);
213
+ ret += HPDF_Dict_AddNumber (font_data, "Length3", 0);
214
+
215
+ font_data->filter = font->filter;
216
+ }
217
+
218
+ if (ret != HPDF_OK)
219
+ return HPDF_Error_GetCode (font->error);
220
+
221
+ font_attr->fontdef->descriptor = descriptor;
222
+ }
223
+
224
+ return HPDF_Dict_Add (font, "FontDescriptor",
225
+ font_attr->fontdef->descriptor);
226
+ }
227
+
228
+
229
+ static HPDF_INT
230
+ CharWidth (HPDF_Font font,
231
+ HPDF_BYTE code)
232
+ {
233
+ HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
234
+
235
+ if (attr->used[code] == 0) {
236
+ HPDF_UNICODE unicode = HPDF_Encoder_ToUnicode (attr->encoder, code);
237
+
238
+ attr->used[code] = 1;
239
+ attr->widths[code] = HPDF_TTFontDef_GetCharWidth(attr->fontdef,
240
+ unicode);
241
+ }
242
+
243
+ return attr->widths[code];
244
+ }
245
+
246
+
247
+ HPDF_TextWidth
248
+ TextWidth (HPDF_Font font,
249
+ const HPDF_BYTE *text,
250
+ HPDF_UINT len)
251
+ {
252
+ HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
253
+ HPDF_TextWidth ret = {0, 0, 0, 0};
254
+ HPDF_UINT i;
255
+ HPDF_BYTE b = 0;
256
+
257
+ HPDF_PTRACE ((" HPDF_TTFont_TextWidth\n"));
258
+
259
+ if (attr->widths) {
260
+ for (i = 0; i < len; i++) {
261
+ b = text[i];
262
+ ret.numchars++;
263
+ ret.width += CharWidth (font, b);
264
+
265
+ if (HPDF_IS_WHITE_SPACE(b)) {
266
+ ret.numspace++;
267
+ ret.numwords++;
268
+ }
269
+ }
270
+ } else
271
+ HPDF_SetError (font->error, HPDF_FONT_INVALID_WIDTHS_TABLE, 0);
272
+
273
+ /* 2006.08.19 add. */
274
+ if (HPDF_IS_WHITE_SPACE(b))
275
+ ; /* do nothing. */
276
+ else
277
+ ret.numwords++;
278
+
279
+ return ret;
280
+ }
281
+
282
+
283
+ HPDF_UINT
284
+ MeasureText (HPDF_Font font,
285
+ const HPDF_BYTE *text,
286
+ HPDF_UINT len,
287
+ HPDF_REAL width,
288
+ HPDF_REAL font_size,
289
+ HPDF_REAL char_space,
290
+ HPDF_REAL word_space,
291
+ HPDF_BOOL wordwrap,
292
+ HPDF_REAL *real_width)
293
+ {
294
+ HPDF_DOUBLE w = 0;
295
+ HPDF_UINT tmp_len = 0;
296
+ HPDF_UINT i;
297
+
298
+ HPDF_PTRACE ((" HPDF_TTFont_MeasureText\n"));
299
+
300
+ for (i = 0; i < len; i++) {
301
+ HPDF_BYTE b = text[i];
302
+
303
+ if (HPDF_IS_WHITE_SPACE(b)) {
304
+ tmp_len = i + 1;
305
+
306
+ if (real_width)
307
+ *real_width = w;
308
+
309
+ w += word_space;
310
+ } else if (!wordwrap) {
311
+ tmp_len = i;
312
+
313
+ if (real_width)
314
+ *real_width = w;
315
+ }
316
+
317
+ w += (HPDF_DOUBLE)CharWidth (font, b) * font_size / 1000;
318
+
319
+ /* 2006.08.04 break when it encountered line feed */
320
+ if (w > width || b == 0x0A)
321
+ return tmp_len;
322
+
323
+ if (i > 0)
324
+ w += char_space;
325
+ }
326
+
327
+ /* all of text can be put in the specified width */
328
+ if (real_width)
329
+ *real_width = w;
330
+ return len;
331
+ }
332
+
333
+
334
+ static HPDF_STATUS
335
+ OnWrite (HPDF_Dict obj,
336
+ HPDF_Stream stream)
337
+ {
338
+ HPDF_FontAttr attr = (HPDF_FontAttr)obj->attr;
339
+ HPDF_BasicEncoderAttr encoder_attr =
340
+ (HPDF_BasicEncoderAttr)attr->encoder->attr;
341
+ HPDF_UINT i;
342
+ HPDF_STATUS ret;
343
+ char buf[128];
344
+ char *pbuf = buf;
345
+ char *eptr = buf + 127;
346
+
347
+ HPDF_PTRACE ((" HPDF_Font_OnWrite\n"));
348
+
349
+ /* Widths entry */
350
+ if ((ret = HPDF_Stream_WriteEscapeName (stream, "Widths")) != HPDF_OK)
351
+ return ret;
352
+
353
+ if ((ret = HPDF_Stream_WriteStr (stream, " [\012")) != HPDF_OK)
354
+ return ret;
355
+
356
+ for (i = encoder_attr->first_char; i <= encoder_attr->last_char; i++) {
357
+
358
+ pbuf = HPDF_IToA (pbuf, attr->widths[i], eptr);
359
+ *pbuf++ = ' ';
360
+
361
+ if ((i + 1) % 16 == 0) {
362
+ HPDF_StrCpy(pbuf, "\012", eptr);
363
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
364
+ return ret;
365
+ pbuf = buf;
366
+ }
367
+
368
+ }
369
+
370
+ HPDF_StrCpy (pbuf, "]\012", eptr);
371
+
372
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
373
+ return ret;
374
+
375
+ return attr->encoder->write_fn (attr->encoder, stream);
376
+ }
377
+
378
+ static HPDF_STATUS
379
+ BeforeWrite (HPDF_Dict obj)
380
+ {
381
+ HPDF_PTRACE ((" HPDF_TTFont_BeforeWrite\n"));
382
+
383
+ return CreateDescriptor (obj);
384
+ }
385
+
386
+ static void
387
+ OnFree (HPDF_Dict obj)
388
+ {
389
+ HPDF_FontAttr attr = (HPDF_FontAttr)obj->attr;
390
+
391
+ HPDF_PTRACE ((" HPDF_TTFont_OnFree\n"));
392
+
393
+ if (attr) {
394
+ if (attr->widths) {
395
+ HPDF_FreeMem (obj->mmgr, attr->widths);
396
+ }
397
+
398
+ if (attr->used) {
399
+ HPDF_FreeMem (obj->mmgr, attr->used);
400
+ }
401
+
402
+ HPDF_FreeMem (obj->mmgr, attr);
403
+ }
404
+ }
405
+
406
+
@@ -0,0 +1,391 @@
1
+ /*
2
+ * << Haru Free PDF Library 2.0.3 >> -- hpdf_font_type1.c
3
+ *
4
+ * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
5
+ *
6
+ * Permission to use, copy, modify, distribute and sell this software
7
+ * and its documentation for any purpose is hereby granted without fee,
8
+ * provided that the above copyright notice appear in all copies and
9
+ * that both that copyright notice and this permission notice appear
10
+ * in supporting documentation.
11
+ * It is provided "as is" without express or implied warranty.
12
+ *
13
+ */
14
+
15
+ #include "hpdf_conf.h"
16
+ #include "hpdf_utils.h"
17
+ #include "hpdf_font.h"
18
+
19
+ static HPDF_STATUS
20
+ Type1Font_OnWrite (HPDF_Dict obj,
21
+ HPDF_Stream stream);
22
+
23
+
24
+ static void
25
+ Type1Font_OnFree (HPDF_Dict obj);
26
+
27
+
28
+ static HPDF_TextWidth
29
+ Type1Font_TextWidth (HPDF_Font font,
30
+ const HPDF_BYTE *text,
31
+ HPDF_UINT len);
32
+
33
+
34
+ static HPDF_UINT
35
+ Type1Font_MeasureText (HPDF_Font font,
36
+ const HPDF_BYTE *text,
37
+ HPDF_UINT len,
38
+ HPDF_REAL width,
39
+ HPDF_REAL font_size,
40
+ HPDF_REAL char_space,
41
+ HPDF_REAL word_space,
42
+ HPDF_BOOL wordwrap,
43
+ HPDF_REAL *real_width);
44
+
45
+
46
+ static HPDF_STATUS
47
+ Type1Font_CreateDescriptor (HPDF_MMgr mmgr,
48
+ HPDF_Font font,
49
+ HPDF_Xref xref);
50
+
51
+
52
+ HPDF_Font
53
+ HPDF_Type1Font_New (HPDF_MMgr mmgr,
54
+ HPDF_FontDef fontdef,
55
+ HPDF_Encoder encoder,
56
+ HPDF_Xref xref)
57
+ {
58
+ HPDF_Dict font;
59
+ HPDF_FontAttr attr;
60
+ HPDF_Type1FontDefAttr fontdef_attr;
61
+ HPDF_BasicEncoderAttr encoder_attr;
62
+ HPDF_STATUS ret = 0;
63
+ HPDF_UINT i;
64
+
65
+ HPDF_PTRACE ((" HPDF_Type1Font_New\n"));
66
+
67
+ /* check whether the fontdef object and the encoder object is valid. */
68
+ if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) {
69
+ HPDF_SetError(mmgr->error, HPDF_INVALID_ENCODER_TYPE, 0);
70
+ return NULL;
71
+ }
72
+
73
+ if (fontdef->type != HPDF_FONTDEF_TYPE_TYPE1) {
74
+ HPDF_SetError(mmgr->error, HPDF_INVALID_FONTDEF_TYPE, 0);
75
+ return NULL;
76
+ }
77
+
78
+ font = HPDF_Dict_New (mmgr);
79
+ if (!font)
80
+ return NULL;
81
+
82
+ font->header.obj_class |= HPDF_OSUBCLASS_FONT;
83
+
84
+ attr = HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec));
85
+ if (!attr) {
86
+ HPDF_Dict_Free (font);
87
+ return NULL;
88
+ }
89
+
90
+ font->header.obj_class |= HPDF_OSUBCLASS_FONT;
91
+ font->write_fn = Type1Font_OnWrite;
92
+ font->free_fn = Type1Font_OnFree;
93
+
94
+ HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec));
95
+
96
+ font->attr = attr;
97
+ attr->type = HPDF_FONT_TYPE1;
98
+ attr->writing_mode = HPDF_WMODE_HORIZONTAL;
99
+ attr->text_width_fn = Type1Font_TextWidth;
100
+ attr->measure_text_fn = Type1Font_MeasureText;
101
+ attr->fontdef = fontdef;
102
+ attr->encoder = encoder;
103
+ attr->xref = xref;
104
+
105
+ /* singlebyte-font has a widths-array which is an array of 256 signed
106
+ * short integer.
107
+ */
108
+ attr->widths = HPDF_GetMem (mmgr, sizeof(HPDF_INT16) * 256);
109
+ if (!attr->widths) {
110
+ HPDF_Dict_Free (font);
111
+ return NULL;
112
+ }
113
+
114
+ encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr;
115
+
116
+ HPDF_MemSet (attr->widths, 0, sizeof(HPDF_INT16) * 256);
117
+ for (i = encoder_attr->first_char; i <= encoder_attr->last_char; i++) {
118
+ HPDF_UNICODE u = encoder_attr->unicode_map[i];
119
+
120
+ HPDF_UINT16 w = HPDF_Type1FontDef_GetWidth (fontdef, u);
121
+ attr->widths[i] = w;
122
+ }
123
+
124
+ fontdef_attr = (HPDF_Type1FontDefAttr)fontdef->attr;
125
+
126
+ ret += HPDF_Dict_AddName (font, "Type", "Font");
127
+ ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font);
128
+ ret += HPDF_Dict_AddName (font, "Subtype", "Type1");
129
+
130
+ if (!fontdef_attr->is_base14font) {
131
+ if (fontdef->missing_width != 0)
132
+ ret += HPDF_Dict_AddNumber (font, "MissingWidth",
133
+ fontdef->missing_width);
134
+
135
+ ret += Type1Font_CreateDescriptor (mmgr, font, xref);
136
+ }
137
+
138
+ if (ret != HPDF_OK) {
139
+ HPDF_Dict_Free (font);
140
+ return NULL;
141
+ }
142
+
143
+ if (HPDF_Xref_Add (xref, font) != HPDF_OK)
144
+ return NULL;
145
+
146
+ return font;
147
+ }
148
+
149
+
150
+ static HPDF_STATUS
151
+ Type1Font_CreateDescriptor (HPDF_MMgr mmgr,
152
+ HPDF_Font font,
153
+ HPDF_Xref xref)
154
+ {
155
+ HPDF_FontAttr font_attr = (HPDF_FontAttr)font->attr;
156
+ HPDF_FontDef def = font_attr->fontdef;
157
+ HPDF_Type1FontDefAttr def_attr = (HPDF_Type1FontDefAttr)def->attr;
158
+
159
+ HPDF_PTRACE ((" HPDF_Type1Font_CreateDescriptor\n"));
160
+
161
+ if (!font_attr->fontdef->descriptor) {
162
+ HPDF_Dict descriptor = HPDF_Dict_New (mmgr);
163
+ HPDF_STATUS ret = 0;
164
+ HPDF_Array array;
165
+
166
+ if (!descriptor)
167
+ return HPDF_Error_GetCode (font->error);
168
+
169
+ ret += HPDF_Xref_Add (xref, descriptor);
170
+ ret += HPDF_Dict_AddName (descriptor, "Type", "FontDescriptor");
171
+ ret += HPDF_Dict_AddNumber (descriptor, "Ascent", def->ascent);
172
+ ret += HPDF_Dict_AddNumber (descriptor, "Descent", def->descent);
173
+ ret += HPDF_Dict_AddNumber (descriptor, "Flags", def->flags);
174
+
175
+ array = HPDF_Box_Array_New (mmgr, def->font_bbox);
176
+ ret += HPDF_Dict_Add (descriptor, "FontBBox", array);
177
+
178
+ ret += HPDF_Dict_AddName (descriptor, "FontName",
179
+ font_attr->fontdef->base_font);
180
+ ret += HPDF_Dict_AddNumber (descriptor, "ItalicAngle",
181
+ def->italic_angle);
182
+ ret += HPDF_Dict_AddNumber (descriptor, "StemV", def->stemv);
183
+ ret += HPDF_Dict_AddNumber (descriptor, "XHeight", def->x_height);
184
+
185
+ if (def_attr->char_set)
186
+ ret += HPDF_Dict_AddName (descriptor, "CharSet",
187
+ def_attr->char_set);
188
+
189
+ if (ret != HPDF_OK)
190
+ return HPDF_Error_GetCode (font->error);
191
+
192
+ if (def_attr->font_data) {
193
+ HPDF_Dict font_data = HPDF_DictStream_New (mmgr, xref);
194
+
195
+ if (!font_data)
196
+ return HPDF_Error_GetCode (font->error);
197
+
198
+ if (HPDF_Stream_WriteToStream (def_attr->font_data,
199
+ font_data->stream, HPDF_STREAM_FILTER_NONE, NULL) != HPDF_OK)
200
+ return HPDF_Error_GetCode (font->error);
201
+
202
+ ret += HPDF_Dict_Add (descriptor, "FontFile", font_data);
203
+ ret += HPDF_Dict_AddNumber (font_data, "Length1",
204
+ def_attr->length1);
205
+ ret += HPDF_Dict_AddNumber (font_data, "Length2",
206
+ def_attr->length2);
207
+ ret += HPDF_Dict_AddNumber (font_data, "Length3",
208
+ def_attr->length3);
209
+
210
+ font_data->filter = font->filter;
211
+ }
212
+
213
+ if (ret != HPDF_OK)
214
+ return HPDF_Error_GetCode (font->error);
215
+
216
+ font_attr->fontdef->descriptor = descriptor;
217
+ }
218
+
219
+ return HPDF_Dict_Add (font, "FontDescriptor",
220
+ font_attr->fontdef->descriptor);
221
+ }
222
+
223
+
224
+ static HPDF_TextWidth
225
+ Type1Font_TextWidth (HPDF_Font font,
226
+ const HPDF_BYTE *text,
227
+ HPDF_UINT len)
228
+ {
229
+ HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
230
+ HPDF_TextWidth ret = {0, 0, 0, 0};
231
+ HPDF_UINT i;
232
+ HPDF_BYTE b = 0;
233
+
234
+ HPDF_PTRACE ((" HPDF_Type1Font_TextWidth\n"));
235
+
236
+ if (attr->widths) {
237
+ for (i = 0; i < len; i++) {
238
+ b = text[i];
239
+ ret.numchars++;
240
+ ret.width += attr->widths[b];
241
+
242
+ if (HPDF_IS_WHITE_SPACE(b)) {
243
+ ret.numspace++;
244
+ ret.numwords++;
245
+ }
246
+ }
247
+ } else
248
+ HPDF_SetError (font->error, HPDF_FONT_INVALID_WIDTHS_TABLE, 0);
249
+
250
+ /* 2006.08.19 add. */
251
+ if (HPDF_IS_WHITE_SPACE(b))
252
+ ; /* do nothing. */
253
+ else
254
+ ret.numwords++;
255
+
256
+ return ret;
257
+ }
258
+
259
+
260
+ static HPDF_UINT
261
+ Type1Font_MeasureText (HPDF_Font font,
262
+ const HPDF_BYTE *text,
263
+ HPDF_UINT len,
264
+ HPDF_REAL width,
265
+ HPDF_REAL font_size,
266
+ HPDF_REAL char_space,
267
+ HPDF_REAL word_space,
268
+ HPDF_BOOL wordwrap,
269
+ HPDF_REAL *real_width)
270
+ {
271
+ HPDF_REAL w = 0;
272
+ HPDF_UINT tmp_len = 0;
273
+ HPDF_UINT i;
274
+ HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
275
+
276
+ HPDF_PTRACE ((" HPDF_Type1Font_MeasureText\n"));
277
+
278
+ for (i = 0; i < len; i++) {
279
+ HPDF_BYTE b = text[i];
280
+
281
+ if (HPDF_IS_WHITE_SPACE(b)) {
282
+ tmp_len = i + 1;
283
+
284
+ if (real_width)
285
+ *real_width = w;
286
+
287
+ w += word_space;
288
+ } else if (!wordwrap) {
289
+ tmp_len = i;
290
+
291
+ if (real_width)
292
+ *real_width = w;
293
+ }
294
+
295
+ w += attr->widths[b] * font_size / 1000;
296
+
297
+ /* 2006.08.04 break when it encountered line feed */
298
+ if (w > width || b == 0x0A)
299
+ return tmp_len;
300
+
301
+ if (i > 0)
302
+ w += char_space;
303
+ }
304
+
305
+ /* all of text can be put in the specified width */
306
+ if (real_width)
307
+ *real_width = w;
308
+
309
+ return len;
310
+ }
311
+
312
+
313
+ static HPDF_STATUS
314
+ Type1Font_OnWrite (HPDF_Dict obj,
315
+ HPDF_Stream stream)
316
+ {
317
+ HPDF_FontAttr attr = (HPDF_FontAttr)obj->attr;
318
+ HPDF_Type1FontDefAttr fontdef_attr =
319
+ (HPDF_Type1FontDefAttr)attr->fontdef->attr;
320
+ HPDF_BasicEncoderAttr encoder_attr =
321
+ (HPDF_BasicEncoderAttr)attr->encoder->attr;
322
+ HPDF_UINT i;
323
+ HPDF_STATUS ret;
324
+ char buf[HPDF_TMP_BUF_SIZ];
325
+ char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
326
+
327
+ HPDF_PTRACE ((" HPDF_Font_Type1Font_OnWrite\n"));
328
+
329
+ /* if font is base14-font these entries is not required */
330
+ if (!fontdef_attr->is_base14font || encoder_attr->has_differences) {
331
+ char *pbuf;
332
+
333
+ pbuf = HPDF_StrCpy (buf, "/FirstChar ", eptr);
334
+ pbuf = HPDF_IToA (pbuf, encoder_attr->first_char, eptr);
335
+ HPDF_StrCpy (pbuf, "\012", eptr);
336
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
337
+ return ret;
338
+
339
+ pbuf = HPDF_StrCpy (buf, "/LastChar ", eptr);
340
+ pbuf = HPDF_IToA (pbuf, encoder_attr->last_char, eptr);
341
+ HPDF_StrCpy (pbuf, "\012", eptr);
342
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
343
+ return ret;
344
+
345
+ /* Widths entry */
346
+ if ((ret = HPDF_Stream_WriteEscapeName (stream, "Widths")) != HPDF_OK)
347
+ return ret;
348
+
349
+ if ((ret = HPDF_Stream_WriteStr (stream, " [\012")) != HPDF_OK)
350
+ return ret;
351
+
352
+ pbuf = buf;
353
+ for (i = encoder_attr->first_char; i <= encoder_attr->last_char; i++) {
354
+
355
+ pbuf = HPDF_IToA (pbuf, attr->widths[i], eptr);
356
+ *pbuf++ = ' ';
357
+
358
+ if ((i + 1) % 16 == 0) {
359
+ HPDF_StrCpy(pbuf, "\012", eptr);
360
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
361
+ return ret;
362
+ pbuf = buf;
363
+ }
364
+ }
365
+
366
+ HPDF_StrCpy (pbuf, "]\012", eptr);
367
+
368
+ if ((ret = HPDF_Stream_WriteStr (stream, buf)) != HPDF_OK)
369
+ return ret;
370
+ }
371
+
372
+ return attr->encoder->write_fn (attr->encoder, stream);
373
+ }
374
+
375
+
376
+ static void
377
+ Type1Font_OnFree (HPDF_Dict obj)
378
+ {
379
+ HPDF_FontAttr attr = (HPDF_FontAttr)obj->attr;
380
+
381
+ HPDF_PTRACE ((" HPDF_Type1Font_OnFree\n"));
382
+
383
+ if (attr) {
384
+ if (attr->widths) {
385
+ HPDF_FreeMem (obj->mmgr, attr->widths);
386
+ }
387
+ HPDF_FreeMem (obj->mmgr, attr);
388
+ }
389
+ }
390
+
391
+