3 % Copyright
2009-2011 Taco Hoekwater
<taco@@luatex.org
>
5 % This file is part of LuaTeX.
7 % LuaTeX is free software
; you can redistribute it and
/or modify it under
8 % the terms of the GNU General Public License as published by the Free
9 % Software Foundation
; either version
2 of the License
, or
(at your
10 % option
) any later version.
12 % LuaTeX is distributed in the hope that it will be useful
, but WITHOUT
13 % ANY WARRANTY
; without even the implied warranty of MERCHANTABILITY or
14 % FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 % License for more details.
17 % You should have received a copy of the GNU General Public License along
18 % with LuaTeX
; if not
, see
<http
://www.gnu.org
/licenses
/>.
23 #include
"pdf/pdfpage.h"
25 #define pdf2double
(a
) ((double
) (a
).m
/ ten_pow
[(a
).e
])
30 #define one_bp
((double
) 65536 * (double
) 72.27 / 72) /* number of sp per
1bp
*/
31 #define e_tj
3 /* must be
3; movements in
[]TJ are in fontsize
/$
10^
3$ units
*/
34 static int64_t pdf_char_width
(pdfstructure
* p
, internal_font_number f
, int i
)
36 /* use exactly this formula also for calculating the
/Width array values
*/
37 return i64round
((double
) char_width
(f
, i
) / font_size
(f
) * ten_pow
[e_tj
+ p-
>cw.e
]);
41 void pdf_print_charwidth
(PDF pdf
, internal_font_number f
, int i
)
44 pdfstructure
*p
= pdf-
>pstruct
;
45 cw.m
= pdf_char_width
(p
, f
, i
);
47 print_pdffloat
(pdf
, cw
);
51 static void setup_fontparameters
(PDF pdf
, internal_font_number f
, int ex_glyph
)
53 float slant
, extend
, expand
, scale
= 1.0;
55 pdfstructure
*p
= pdf-
>pstruct
;
56 /* fix mantis bug \#
0000200 (acroread
"feature") */
57 if
((font_format
(f
) == opentype_format ||
(font_format
(f
) == type1_format
&& font_encodingbytes(f) == 2)) && font_units_per_em(f) > 0)
58 u
= font_units_per_em
(f
) / 1000.0;
60 p-
>f_pdf
= pdf_set_font
(pdf
, f
);
61 p-
>fs.m
= i64round
(font_size
(f
) / u
/ one_bp
* ten_pow
[p-
>fs.e
]);
62 slant
= font_slant
(f
) / 1000.0;
63 extend
= font_extend
(f
) / 1000.0;
64 expand
= 1.0 + (ex_glyph
/1) / 1000.0;
65 p-
>tj_delta.e
= p-
>cw.e
- 1; /* "- 1" makes less corrections inside
[]TJ
*/
66 /* no need to be more precise than TeX
(1sp
) */
67 while
(p-
>tj_delta.e
> 0 && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5)
68 p-
>tj_delta.e--
; /* happens for very tiny fonts
*/
69 p-
>tm
[0].m
= i64round
(scale
* expand
* extend
* ten_pow
[p-
>tm
[0].e
]);
70 p-
>tm
[2].m
= i64round
(slant
* ten_pow
[p-
>tm
[2].e
]);
71 p-
>tm
[3].m
= i64round
(scale
* ten_pow
[p-
>tm
[3].e
]);
72 p-
>k2
= ten_pow
[e_tj
+ p-
>cw.e
] * scale
/ (ten_pow
[p-
>pdf.h.e
] * pdf2double
(p-
>fs
) * pdf2double
(p-
>tm
[0]));
73 p-
>cur_ex
= ex_glyph
; /* we keep track of the state of ex
*/
78 static void set_font
(PDF pdf
)
80 pdfstructure
*p
= pdf-
>pstruct
;
81 pdf_printf
(pdf
, "/F%d", (int
) p-
>f_pdf
);
82 pdf_print_resname_prefix
(pdf
);
84 print_pdffloat
(pdf
, p-
>fs
);
85 pdf_puts
(pdf
, " Tf ");
86 p-
>f_pdf_cur
= p-
>f_pdf
;
87 p-
>fs_cur.m
= p-
>fs.m
;
89 p-
>need_tm
= true
; /* always follow Tf by Tm
*/
93 static void set_textmatrix
(PDF pdf
, scaledpos pos
)
96 pdfstructure
*p
= pdf-
>pstruct
;
98 normal_error
("pdf backend","text mode expected in set_textmatrix");
99 move
= calc_pdfpos
(p
, pos
);
100 if
(p-
>need_tm || move
) {
101 print_pdf_matrix
(pdf
, p-
>tm
);
102 pdf_puts
(pdf
, " Tm ");
103 p-
>pdf.h.m
= p-
>pdf_bt_pos.h.m
+ p-
>tm
[4].m
; /* Tm replaces
*/
104 p-
>pdf.v.m
= p-
>pdf_bt_pos.v.m
+ p-
>tm
[5].m
;
107 p-
>tm0_cur.m
= p-
>tm
[0].m
;
110 @ Print out a character to PDF buffer
; the character will be printed in octal
111 form in the following cases
: chars
<= 32, backslash
(92), left parenthesis
112 (40), and right parenthesis
(41).
115 static void pdf_print_char
(PDF pdf
, int c
)
119 /* pdf_print_escaped
(c
) */
120 if
(c
<= 32 || c
== '\\' || c
== '
(' || c
== '
)' || c
> 127) {
122 pdf_quick_out
(pdf
, '\\'
);
123 pdf_quick_out
(pdf
, (unsigned char
) ('
0'
+ ((c
>> 6) & 0x3)));
124 pdf_quick_out
(pdf
, (unsigned char
) ('
0'
+ ((c
>> 3) & 0x7)));
125 pdf_quick_out
(pdf
, (unsigned char
) ('
0'
+ (c
& 0x7)));
130 static void pdf_print_wide_char
(PDF pdf
, int c
)
133 snprintf
(hex
, 5, "%04X", c
);
134 pdf_out_block
(pdf
, (const char
*) hex
, 4);
138 static void begin_charmode
(PDF pdf
, internal_font_number f
, pdfstructure
* p
)
140 if
(!is_chararraymode
(p
))
141 normal_error
("pdf backend","char array mode expected in begin_char_mode");
142 if
(font_encodingbytes
(f
) == 2) {
149 p-
>mode
= PMODE_CHAR
;
153 void end_charmode
(PDF pdf
)
155 pdfstructure
*p
= pdf-
>pstruct
;
157 normal_error
("pdf backend","char mode expected in end_char_mode");
164 p-
>mode
= PMODE_CHARARRAY
;
168 static void begin_chararray
(PDF pdf
)
170 pdfstructure
*p
= pdf-
>pstruct
;
172 normal_error
("pdf backend","text mode expected in begin_char_array");
173 p-
>pdf_tj_pos
= p-
>pdf
;
176 p-
>mode
= PMODE_CHARARRAY
;
180 void end_chararray
(PDF pdf
)
182 pdfstructure
*p
= pdf-
>pstruct
;
183 if
(!is_chararraymode
(p
))
184 normal_error
("pdf backend","char array mode expected in end_char_array");
185 pdf_puts
(pdf
, "]TJ\n");
186 p-
>pdf
= p-
>pdf_tj_pos
;
187 p-
>mode
= PMODE_TEXT
;
190 @ We need to adapt the tm when a font changes. A change can be a change in id
191 (frontend
) or pdf reference
(backend
, as we share font resources
). At such a
192 change we also need to adapt to the slant and extend. Initially we also need to
193 take the exfactor of a glyph into account. When the font is unchanged
, we still
194 need to check each glyph for a change in exfactor. We store the current one on
195 the state record so that we can minimize testing.
198 void pdf_place_glyph
(PDF pdf
, internal_font_number f
, int c
, int ex
)
201 pdfstructure
*p
= pdf-
>pstruct
;
202 scaledpos pos
= pdf-
>posstruct-
>pos
;
203 if
(!char_exists
(f
, c
))
205 if
(p-
>need_tf || f
!= pdf-
>f_cur || p-
>f_pdf
!= p-
>f_pdf_cur || p-
>fs.m
!= p-
>fs_cur.m || is_pagemode
(p
)) {
206 pdf_goto_textmode
(pdf
);
207 setup_fontparameters
(pdf
, f
, ex
);
209 } else if
(p-
>tm0_cur.m
!= p-
>tm
[0].m || p-
>cur_ex
!= ex
) {
210 setup_fontparameters
(pdf
, f
, ex
);
214 move
= calc_pdfpos
(p
, pos
); /* within text or chararray or char mode
*/
215 if
(move || p-
>need_tm
) {
216 if
(p-
>need_tm ||
(p-
>wmode
== WMODE_H
&& (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m)
217 ||
(p-
>wmode
== WMODE_V
&& (p->pdf_bt_pos.h.m + p->tm[4].m) != p->pdf.h.m)
218 || abs
(p-
>tj_delta.m
) >= 1000000) {
219 pdf_goto_textmode
(pdf
);
220 set_textmatrix
(pdf
, pos
);
221 begin_chararray
(pdf
);
222 move
= calc_pdfpos
(p
, pos
); /* for fine adjustment
*/
227 print_pdffloat
(pdf
, p-
>tj_delta
);
228 p-
>cw.m
-= p-
>tj_delta.m
* ten_pow
[p-
>cw.e
- p-
>tj_delta.e
];
232 if
(is_chararraymode
(p
))
233 begin_charmode
(pdf
, f
, p
);
234 else if
(!is_charmode
(p
))
235 normal_error
("pdf backend","char (array) mode expected in place_glyph");
237 if
(font_encodingbytes
(f
) == 2)
238 pdf_print_wide_char
(pdf
, char_index
(f
, c
));
240 pdf_print_char
(pdf
, c
);
241 p-
>cw.m
+= pdf_char_width
(p
, p-
>f_pdf
, c
); /* aka |adv_char_width
()|
*/