Skip to content

Commit 166e5f7

Browse files
authored
Merge pull request #173 from zgdump/fix-combinematrix-on-arm
Fix CurTransMat::combine_matrix for arm-unknown-linux-gnueabi
2 parents 13b5aa5 + df65784 commit 166e5f7

File tree

1 file changed

+132
-32
lines changed

1 file changed

+132
-32
lines changed

src/ctm.rs

Lines changed: 132 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,75 +43,155 @@ impl CurTransMat {
4343

4444
let result = [
4545
[
46-
a[0][0].mul_add(
46+
mul_add(
47+
a[0][0],
4748
b[0][0],
48-
a[0][1].mul_add(b[1][0], a[0][2].mul_add(b[2][0], a[0][3] * b[3][0])),
49+
mul_add(
50+
a[0][1],
51+
b[1][0],
52+
mul_add(a[0][2], b[2][0], a[0][3] * b[3][0]),
53+
),
4954
),
50-
a[0][0].mul_add(
55+
mul_add(
56+
a[0][0],
5157
b[0][1],
52-
a[0][1].mul_add(b[1][1], a[0][2].mul_add(b[2][1], a[0][3] * b[3][1])),
58+
mul_add(
59+
a[0][1],
60+
b[1][1],
61+
mul_add(a[0][2], b[2][1], a[0][3] * b[3][1]),
62+
),
5363
),
54-
a[0][0].mul_add(
64+
mul_add(
65+
a[0][0],
5566
b[0][2],
56-
a[0][1].mul_add(b[1][2], a[0][2].mul_add(b[2][2], a[0][3] * b[3][2])),
67+
mul_add(
68+
a[0][1],
69+
b[1][2],
70+
mul_add(a[0][2], b[2][2], a[0][3] * b[3][2]),
71+
),
5772
),
58-
a[0][0].mul_add(
73+
mul_add(
74+
a[0][0],
5975
b[0][3],
60-
a[0][1].mul_add(b[1][3], a[0][2].mul_add(b[2][3], a[0][3] * b[3][3])),
76+
mul_add(
77+
a[0][1],
78+
b[1][3],
79+
mul_add(a[0][2], b[2][3], a[0][3] * b[3][3]),
80+
),
6181
),
6282
],
6383
[
64-
a[1][0].mul_add(
84+
mul_add(
85+
a[1][0],
6586
b[0][0],
66-
a[1][1].mul_add(b[1][0], a[1][2].mul_add(b[2][0], a[1][3] * b[3][0])),
87+
mul_add(
88+
a[1][1],
89+
b[1][0],
90+
mul_add(a[1][2], b[2][0], a[1][3] * b[3][0]),
91+
),
6792
),
68-
a[1][0].mul_add(
93+
mul_add(
94+
a[1][0],
6995
b[0][1],
70-
a[1][1].mul_add(b[1][1], a[1][2].mul_add(b[2][1], a[1][3] * b[3][1])),
96+
mul_add(
97+
a[1][1],
98+
b[1][1],
99+
mul_add(a[1][2], b[2][1], a[1][3] * b[3][1]),
100+
),
71101
),
72-
a[1][0].mul_add(
102+
mul_add(
103+
a[1][0],
73104
b[0][2],
74-
a[1][1].mul_add(b[1][2], a[1][2].mul_add(b[2][2], a[1][3] * b[3][2])),
105+
mul_add(
106+
a[1][1],
107+
b[1][2],
108+
mul_add(a[1][2], b[2][2], a[1][3] * b[3][2]),
109+
),
75110
),
76-
a[1][0].mul_add(
111+
mul_add(
112+
a[1][0],
77113
b[0][3],
78-
a[1][1].mul_add(b[1][3], a[1][2].mul_add(b[2][3], a[1][3] * b[3][3])),
114+
mul_add(
115+
a[1][1],
116+
b[1][3],
117+
mul_add(a[1][2], b[2][3], a[1][3] * b[3][3]),
118+
),
79119
),
80120
],
81121
[
82-
a[2][0].mul_add(
122+
mul_add(
123+
a[2][0],
83124
b[0][0],
84-
a[2][1].mul_add(b[1][0], a[2][2].mul_add(b[2][0], a[2][3] * b[3][0])),
125+
mul_add(
126+
a[2][1],
127+
b[1][0],
128+
mul_add(a[2][2], b[2][0], a[2][3] * b[3][0]),
129+
),
85130
),
86-
a[2][0].mul_add(
131+
mul_add(
132+
a[2][0],
87133
b[0][1],
88-
a[2][1].mul_add(b[1][1], a[2][2].mul_add(b[2][1], a[2][3] * b[3][1])),
134+
mul_add(
135+
a[2][1],
136+
b[1][1],
137+
mul_add(a[2][2], b[2][1], a[2][3] * b[3][1]),
138+
),
89139
),
90-
a[2][0].mul_add(
140+
mul_add(
141+
a[2][0],
91142
b[0][2],
92-
a[2][1].mul_add(b[1][2], a[2][2].mul_add(b[2][2], a[2][3] * b[3][2])),
143+
mul_add(
144+
a[2][1],
145+
b[1][2],
146+
mul_add(a[2][2], b[2][2], a[2][3] * b[3][2]),
147+
),
93148
),
94-
a[2][0].mul_add(
149+
mul_add(
150+
a[2][0],
95151
b[0][3],
96-
a[2][1].mul_add(b[1][3], a[2][2].mul_add(b[2][3], a[2][3] * b[3][3])),
152+
mul_add(
153+
a[2][1],
154+
b[1][3],
155+
mul_add(a[2][2], b[2][3], a[2][3] * b[3][3]),
156+
),
97157
),
98158
],
99159
[
100-
a[3][0].mul_add(
160+
mul_add(
161+
a[3][0],
101162
b[0][0],
102-
a[3][1].mul_add(b[1][0], a[3][2].mul_add(b[2][0], a[3][3] * b[3][0])),
163+
mul_add(
164+
a[3][1],
165+
b[1][0],
166+
mul_add(a[3][2], b[2][0], a[3][3] * b[3][0]),
167+
),
103168
),
104-
a[3][0].mul_add(
169+
mul_add(
170+
a[3][0],
105171
b[0][1],
106-
a[3][1].mul_add(b[1][1], a[3][2].mul_add(b[2][1], a[3][3] * b[3][1])),
172+
mul_add(
173+
a[3][1],
174+
b[1][1],
175+
mul_add(a[3][2], b[2][1], a[3][3] * b[3][1]),
176+
),
107177
),
108-
a[3][0].mul_add(
178+
mul_add(
179+
a[3][0],
109180
b[0][2],
110-
a[3][1].mul_add(b[1][2], a[3][2].mul_add(b[2][2], a[3][3] * b[3][2])),
181+
mul_add(
182+
a[3][1],
183+
b[1][2],
184+
mul_add(a[3][2], b[2][2], a[3][3] * b[3][2]),
185+
),
111186
),
112-
a[3][0].mul_add(
187+
mul_add(
188+
a[3][0],
113189
b[0][3],
114-
a[3][1].mul_add(b[1][3], a[3][2].mul_add(b[2][3], a[3][3] * b[3][3])),
190+
mul_add(
191+
a[3][1],
192+
b[1][3],
193+
mul_add(a[3][2], b[2][3], a[3][3] * b[3][3]),
194+
),
115195
),
116196
],
117197
];
@@ -127,6 +207,26 @@ impl CurTransMat {
127207
}
128208
}
129209

210+
/// Multiply add. Computes `(self * a) + b` with workaround for
211+
/// arm-unknown-linux-gnueabi.
212+
///
213+
/// `{f32, f64}::mul_add` is completly broken on arm-unknown-linux-gnueabi.
214+
/// See issue https://github.com/rust-lang/rust/issues/46950.
215+
#[inline(always)]
216+
fn mul_add(a: f32, b: f32, c: f32) -> f32 {
217+
if cfg!(all(
218+
target_arch = "arm",
219+
target_os = "linux",
220+
target_env = "gnu"
221+
)) {
222+
// Workaround has two rounding errors and less accurate result,
223+
// but for PDF it doesn't matter much.
224+
(a * b) + c
225+
} else {
226+
a.mul_add(b, c)
227+
}
228+
}
229+
130230
/// Text matrix. Text placement is a bit different, but uses the same
131231
/// concepts as a CTM that's why it's merged here
132232
///

0 commit comments

Comments
 (0)