3 % Copyright
2009 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
/>.
24 @ stack for \.
{\\pdfextension setmatrix
}
27 matrix_entry
*matrix_stack
= NULL;
28 int matrix_stack_size
= 0;
29 int matrix_stack_used
= 0;
32 boolean matrixused
(void
)
34 return matrix_stack_used
> 0;
37 static void matrix_stack_room
(void
)
39 matrix_entry
*new_stack
;
40 if
(matrix_stack_used
>= matrix_stack_size
) {
41 matrix_stack_size
+= STACK_INCREMENT
;
42 new_stack
= xtalloc
((unsigned
) matrix_stack_size
, matrix_entry
);
43 memcpy
((void
*) new_stack
, (void
*) matrix_stack
, (unsigned
) matrix_stack_used
* sizeof
(matrix_entry
));
45 matrix_stack
= new_stack
;
49 @ \.
{\\pdfextension setmatrix
{a b c d
}}
55 |M_top|
: current active matrix at the top of the matrix stack
57 The origin of \.
{\\pdfextension setmatrix
} is the current point. The annotation
58 coordinate system is the original page coordinate system. When pdfTeX calculates
59 annotation rectangles it does not take into account this transformations
, it uses
60 the original coordinate system. To get the corrected values
, first we go back to
61 the origin
, perform the transformation and go back
:
63 {\obeylines\obeyspaces\tt
64 ( 1 0 0 ) ( a b
0 ) ( 1 0 0 )
65 ( 0 1 0 ) x
( c d
0 ) x
( 0 1 0 ) x M\_top
66 ( -e
-f
1 ) ( 0 0 1 ) ( e f
1 )
69 = ( 0 1 0 ) x
( c d
0 ) x M\_top
74 ( e
(1-a
)-fc f
(1-d
)-eb
1 )
78 static void pdfsetmatrix
(const char
*in
, scaledpos pos
)
81 Argument of \.
{\\pdfextension setmatrix
} starts with |str_pool
[in
]| and ends
82 before |str_pool
[pool_ptr
]|.
84 matrix_entry x
, *y
, *z
;
85 if
(global_shipping_mode
== SHIPPING_PAGE
) {
86 if
(sscanf
((const char
*) in
, " %lf %lf %lf %lf ", &x.a, &x.b, &x.c, &x.d) != 4) {
87 formatted_warning
("pdf backend","unrecognized format of setmatrix: %s", in
);
90 /* calculate this transformation matrix
*/
91 x.e
= (double
) pos.h
* (1.0 - x.a
) - (double
) pos.v
* x.c
;
92 x.f
= (double
) pos.v
* (1.0 - x.d
) - (double
) pos.h
* x.b
;
94 z
= &matrix_stack[matrix_stack_used];
95 if
(matrix_stack_used
> 0) {
96 y
= &matrix_stack[matrix_stack_used - 1];
97 z-
>a
= x.a
* y-
>a
+ x.b
* y-
>c
;
98 z-
>b
= x.a
* y-
>b
+ x.b
* y-
>d
;
99 z-
>c
= x.c
* y-
>a
+ x.d
* y-
>c
;
100 z-
>d
= x.c
* y-
>b
+ x.d
* y-
>d
;
101 z-
>e
= x.e
* y-
>a
+ x.f
* y-
>c
+ y-
>e
;
102 z-
>f
= x.e
* y-
>b
+ x.f
* y-
>d
+ y-
>f
;
115 @ Apply matrix to point
(x
,y
)
117 {\obeylines\obeyspaces\tt
119 ( x y
1 ) x
( c d
0 ) = ( xa
+yc
+e xb
+yd
+f
1 )
123 If \.
{\\pdfextension setmatrix
} wasn't used
, then return the value unchanged.
125 @ Return values for matrix tranform functions
:
128 static scaled ret_llx
;
129 static scaled ret_lly
;
130 static scaled ret_urx
;
131 static scaled ret_ury
;
159 #define DO_ROUND
(x
) ((x
> 0) ?
(x
+ .5) : (x
- .5))
160 #define DO_MIN
(a
, b
) ((a
< b
) ? a
: b
)
161 #define DO_MAX
(a
, b
) ((a
> b
) ? a
: b
)
163 static void do_matrixtransform
(scaled x
, scaled y
, scaled
* retx
, scaled
* rety
)
165 matrix_entry
*m
= &matrix_stack[matrix_stack_used - 1];
168 double x_new
= x_old
* m-
>a
+ y_old
* m-
>c
+ m-
>e
;
169 double y_new
= x_old
* m-
>b
+ y_old
* m-
>d
+ m-
>f
;
170 *retx
= (scaled
) DO_ROUND
(x_new
);
171 *rety
= (scaled
) DO_ROUND
(y_new
);
174 void matrixtransformrect
(scaled llx
, scaled lly
, scaled urx
, scaled ury
)
176 scaled x1
, x2
, x3
, x4
, y1
, y2
, y3
, y4
;
177 if
(global_shipping_mode
== SHIPPING_PAGE
&& matrix_stack_used > 0) {
182 do_matrixtransform
(llx
, lly
, &x1, &y1);
183 do_matrixtransform
(llx
, ury
, &x2, &y2);
184 do_matrixtransform
(urx
, lly
, &x3, &y3);
185 do_matrixtransform
(urx
, ury
, &x4, &y4);
186 ret_llx
= DO_MIN
(DO_MIN
(x1
, x2
), DO_MIN
(x3
, x4
));
187 ret_lly
= DO_MIN
(DO_MIN
(y1
, y2
), DO_MIN
(y3
, y4
));
188 ret_urx
= DO_MAX
(DO_MAX
(x1
, x2
), DO_MAX
(x3
, x4
));
189 ret_ury
= DO_MAX
(DO_MAX
(y1
, y2
), DO_MAX
(y3
, y4
));
198 void matrixtransformpoint
(scaled x
, scaled y
)
200 if
(global_shipping_mode
== SHIPPING_PAGE
&& matrix_stack_used > 0) {
201 do_matrixtransform
(x
, y
, &ret_llx, &ret_lly);
208 void matrixrecalculate
(scaled urx
)
210 matrixtransformrect
(last_llx
, last_lly
, urx
, last_ury
);
214 void pdf_out_setmatrix
(PDF pdf
, halfword p
)
216 scaledpos pos
= pdf-
>posstruct-
>pos
;
217 int old_setting
; /* holds print |selector|
*/
219 old_setting
= selector
;
220 selector
= new_string
;
221 show_token_list
(token_link
(pdf_setmatrix_data
(p
)), null
, -1);
222 pdfsetmatrix
((char
*) cur_string
, pos
);
224 selector
= old_setting
;
226 pdf_literal
(pdf
, s
, set_origin
, false
);