Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / test-subset-instancer-solver.cc
1 /*
2  * Copyright © 2023  Google, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Google Author(s): Qunxin Liu
25  */
26
27 #include "hb-subset-instancer-solver.hh"
28
29 static inline bool approx (Triple a, Triple b)
30 {
31   return fabsf (a.minimum - b.minimum) < 0.000001f &&
32          fabsf (a.middle - b.middle) < 0.000001f &&
33          fabsf (a.maximum - b.maximum) < 0.000001f;
34 }
35
36 static inline bool approx (float a, float b)
37 { return fabsf (a - b) < 0.000001f; }
38
39 /* tests ported from
40  * https://github.com/fonttools/fonttools/blob/main/Tests/varLib/instancer/solver_test.py */
41 int
42 main (int argc, char **argv)
43 {
44   TripleDistances default_axis_distances{1.f, 1.f};
45   /* Case 1 */
46   {
47     /* pin axis*/
48     Triple tent (0.f, 1.f, 1.f);
49     Triple axis_range (0.f, 0.f, 0.f);
50     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
51     assert (out.length == 0);
52   }
53
54   {
55     /* pin axis*/
56     Triple tent (0.f, 1.f, 1.f);
57     Triple axis_range (0.5f, 0.5f, 0.5f);
58     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
59     assert (out.length == 1);
60     assert (out[0].first == 0.5f);
61     assert (out[0].second == Triple ());
62   }
63
64   {
65     /* tent falls outside the new axis range */
66     Triple tent (0.3f, 0.5f, 0.8f);
67     Triple axis_range (0.1f, 0.2f, 0.3f);
68     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
69     assert (out.length == 0);
70   }
71
72   /* Case 2 */
73   {
74     Triple tent (0.f, 1.f, 1.f);
75     Triple axis_range (-1.f, 0.f, 0.5f);
76     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
77     assert (out.length == 1);
78     assert (out[0].first == 0.5f);
79     assert (out[0].second == Triple (0.f, 1.f, 1.f));
80   }
81
82   /* Case 2 */
83   {
84     Triple tent (0.f, 1.f, 1.f);
85     Triple axis_range (-1.f, 0.f, 0.75f);
86     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
87     assert (out.length == 1);
88     assert (out[0].first == 0.75f);
89     assert (out[0].second == Triple (0.f, 1.f, 1.f));
90   }
91
92   /* Without gain: */
93   /* Case 3 */
94   {
95     Triple tent (0.f, 0.2f, 1.f);
96     Triple axis_range (-1.f, 0.f, 0.8f);
97     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
98     assert (out.length == 1);
99     assert (out[0].first == 1.f);
100     assert (out[0].second == Triple (0.f, 0.25f, 1.25f));
101   }
102
103   /* Case 3 boundary */
104   {
105     Triple tent (0.f, 0.4f, 1.f);
106     Triple axis_range (-1.f, 0.f, 0.5f);
107     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
108     assert (out.length == 1);
109     assert (out[0].first == 1.f);
110     assert (out[0].second == Triple (0.f, 0.8f, 32767/(float) (1 << 14)));
111   }
112
113   /* Case 4 */
114   {
115     Triple tent (0.f, 0.25f, 1.f);
116     Triple axis_range (-1.f, 0.f, 0.4f);
117     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
118     assert (out.length == 2);
119     assert (out[0].first == 1.f);
120     assert (out[0].second == Triple (0.f, 0.625f, 1.f));
121     assert (approx (out[1].first, 0.8f));
122     assert (out[1].second == Triple (0.625f, 1.f, 1.f));
123   }
124
125   /* Case 4 */
126   {
127     Triple tent (0.25f, 0.3f, 1.05f);
128     Triple axis_range (0.f, 0.2f, 0.4f);
129     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
130     assert (out.length == 2);
131     assert (out[0].first == 1.f);
132     assert (approx (out[0].second, Triple (0.25f, 0.5f, 1.f)));
133     assert (approx (out[1].first, 2.6f/3));
134     assert (approx (out[1].second, Triple (0.5f, 1.f, 1.f)));
135   }
136
137   /* Case 4 boundary */
138   {
139     Triple tent (0.25f, 0.5f, 1.f);
140     Triple axis_range (0.f, 0.25f, 0.5f);
141     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
142     assert (out.length == 1);
143     assert (out[0].first == 1.f);
144     assert (out[0].second == Triple (0.f, 1.f, 1.f));
145   }
146
147   /* With gain */
148   /* Case 3a/1neg */
149   {
150     Triple tent (0.f, 0.5f, 1.f);
151     Triple axis_range (0.f, 0.5f, 1.f);
152     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
153     assert (out.length == 3);
154     assert (out[0].first == 1.f);
155     assert (out[0].second == Triple ());
156     assert (out[1].first == -1.f);
157     assert (out[1].second == Triple (0.f, 1.f, 1.f));
158     assert (out[2].first == -1.f);
159     assert (out[2].second == Triple (-1.f, -1.f, 0.f));
160   }
161
162   {
163     Triple tent (0.f, 0.5f, 1.f);
164     Triple axis_range (0.f, 0.5f, 0.75f);
165     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
166     assert (out.length == 3);
167     assert (out[0].first == 1.f);
168     assert (out[0].second == Triple ());
169     assert (out[1].first == -0.5f);
170     assert (out[1].second == Triple (0.f, 1.f, 1.f));
171     assert (out[2].first == -1.f);
172     assert (out[2].second == Triple (-1.f, -1.f, 0.f));
173   }
174
175   {
176     Triple tent (0.f, 0.5f, 1.f);
177     Triple axis_range (0.f, 0.25f, 0.8f);
178     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
179     assert (out.length == 4);
180     assert (out[0].first == 0.5f);
181     assert (out[0].second == Triple ());
182     assert (out[1].first == 0.5f);
183     assert (approx (out[1].second, Triple (0.f, 0.454545f, 0.909091f)));
184     assert (approx (out[2].first, -0.1f));
185     assert (approx (out[2].second, Triple (0.909091f, 1.f, 1.f)));
186     assert (out[3].first == -0.5f);
187     assert (out[3].second == Triple (-1.f, -1.f, 0.f));
188   }
189
190   /* Case 3a/1neg */
191   {
192     Triple tent (0.f, 0.5f, 2.f);
193     Triple axis_range (0.2f, 0.5f, 0.8f);
194     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
195     assert (out.length == 3);
196     assert (out[0].first == 1.f);
197     assert (out[0].second == Triple ());
198     assert (approx (out[1].first, -0.2f));
199     assert (out[1].second == Triple (0.f, 1.f, 1.f));
200     assert (approx (out[2].first, -0.6f));
201     assert (out[2].second == Triple (-1.f, -1.f, 0.f));
202   }
203
204   /* Case 3a/1neg */
205   {
206     Triple tent (0.f, 0.5f, 2.f);
207     Triple axis_range (0.2f, 0.5f, 1.f);
208     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
209     assert (out.length == 3);
210     assert (out[0].first == 1.f);
211     assert (out[0].second == Triple ());
212     assert (approx (out[1].first, -1.f/3));
213     assert (out[1].second == Triple (0.f, 1.f, 1.f));
214     assert (approx (out[2].first, -0.6f));
215     assert (out[2].second == Triple (-1.f, -1.f, 0.f));
216   }
217
218   /* Case 3 */
219   {
220     Triple tent (0.f, 0.5f, 1.f);
221     Triple axis_range (0.25f, 0.25f, 0.75f);
222     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
223     assert (out.length == 2);
224     assert (out[0].first == 0.5f);
225     assert (out[0].second == Triple ());
226     assert (out[1].first == 0.5f);
227     assert (out[1].second == Triple (0.f, 0.5f, 1.0f));
228   }
229
230   /* Case 1neg */
231   {
232     Triple tent (0.f, 0.5f, 1.f);
233     Triple axis_range (0.f, 0.25f, 0.5f);
234     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
235     assert (out.length == 3);
236     assert (out[0].first == 0.5f);
237     assert (out[0].second == Triple ());
238     assert (out[1].first == 0.5f);
239     assert (out[1].second == Triple (0.f, 1.f, 1.f));
240     assert (out[2].first == -0.5f);
241     assert (out[2].second == Triple (-1.f, -1.f, 0.f));
242   }
243
244   /* Case 2neg */
245   {
246     Triple tent (0.05f, 0.55f, 1.f);
247     Triple axis_range (0.f, 0.25f, 0.5f);
248     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
249     assert (out.length == 4);
250     assert (approx (out[0].first, 0.4f));
251     assert (out[0].second == Triple ());
252     assert (approx (out[1].first, 0.5f));
253     assert (out[1].second == Triple (0.f, 1.f, 1.f));
254     assert (approx (out[2].first, -0.4f));
255     assert (out[2].second == Triple (-1.f, -0.8f, 0.f));
256     assert (approx (out[3].first, -0.4f));
257     assert (out[3].second == Triple (-1.f, -1.f, -0.8f));
258   }
259
260   /* Case 2neg, other side */
261   {
262     Triple tent (-1.f, -0.55f, -0.05f);
263     Triple axis_range (-0.5f, -0.25f, 0.f);
264     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
265     assert (out.length == 4);
266     assert (approx (out[0].first, 0.4f));
267     assert (out[0].second == Triple ());
268     assert (approx (out[1].first, 0.5f));
269     assert (out[1].second == Triple (-1.f, -1.f, 0.f));
270     assert (approx (out[2].first, -0.4f));
271     assert (out[2].second == Triple (0.f, 0.8f, 1.f));
272     assert (approx (out[3].first, -0.4f));
273     assert (out[3].second == Triple (0.8f, 1.f, 1.f));
274   }
275
276   /* Misc corner cases */
277   {
278     Triple tent (0.5f, 0.5f, 0.5f);
279     Triple axis_range (0.5f, 0.5f, 0.5f);
280     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
281     assert (out.length == 1);
282     assert (out[0].first == 1.f);
283     assert (out[0].second == Triple ());
284   }
285
286   {
287     Triple tent (0.3f, 0.5f, 0.7f);
288     Triple axis_range (0.1f, 0.5f, 0.9f);
289     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
290     assert (out.length == 5);
291     assert (out[0].first == 1.f);
292     assert (out[0].second == Triple ());
293     assert (out[1].first == -1.f);
294     assert (out[1].second == Triple (0.f, 0.5f, 1.f));
295     assert (out[2].first == -1.f);
296     assert (out[2].second == Triple (0.5f, 1.f, 1.f));
297     assert (out[3].first == -1.f);
298     assert (approx (out[3].second, Triple (-1.f, -0.5f, 0.f)));
299     assert (out[4].first == -1.f);
300     assert (approx (out[4].second, Triple (-1.f, -1.f, -0.5f)));
301   }
302
303   {
304     Triple tent (0.5f, 0.5f, 0.5f);
305     Triple axis_range (0.25f, 0.25f, 0.5f);
306     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
307     assert (out.length == 1);
308     assert (out[0].first == 1.f);
309     assert (out[0].second == Triple (1.f, 1.f, 1.f));
310   }
311
312   {
313     Triple tent (0.5f, 0.5f, 0.5f);
314     Triple axis_range (0.25f, 0.35f, 0.5f);
315     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
316     assert (out.length == 1);
317     assert (out[0].first == 1.f);
318     assert (out[0].second == Triple (1.f, 1.f, 1.f));
319   }
320
321   {
322     Triple tent (0.5f, 0.5f, 0.55f);
323     Triple axis_range (0.25f, 0.35f, 0.5f);
324     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
325     assert (out.length == 1);
326     assert (out[0].first == 1.f);
327     assert (out[0].second == Triple (1.f, 1.f, 1.f));
328   }
329
330   {
331     Triple tent (0.5f, 0.5f, 1.f);
332     Triple axis_range (0.5f, 0.5f, 1.f);
333     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
334     assert (out.length == 2);
335     assert (out[0].first == 1.f);
336     assert (out[0].second == Triple ());
337     assert (out[1].first == -1.f);
338     assert (out[1].second == Triple (0.f, 1.f, 1.f));
339   }
340
341   {
342     Triple tent (0.25f, 0.5f, 1.f);
343     Triple axis_range (0.5f, 0.5f, 1.f);
344     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
345     assert (out.length == 2);
346     assert (out[0].first == 1.f);
347     assert (out[0].second == Triple ());
348     assert (out[1].first == -1.f);
349     assert (out[1].second == Triple (0.f, 1.f, 1.f));
350   }
351
352   {
353     Triple tent (0.f, 0.2f, 1.f);
354     Triple axis_range (0.f, 0.f, 0.5f);
355     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
356     assert (out.length == 1);
357     assert (out[0].first == 1.f);
358     assert (out[0].second == Triple (0.f, 0.4f, 32767/(float) (1 << 14)));
359   }
360
361
362   {
363     Triple tent (0.f, 0.5f, 1.f);
364     Triple axis_range (-1.f, 0.25f, 1.f);
365     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
366     assert (out.length == 5);
367     assert (out[0].first == 0.5f);
368     assert (out[0].second == Triple ());
369     assert (out[1].first == 0.5f);
370     assert (out[1].second == Triple (0.f, 1.f/3, 2.f/3));
371     assert (out[2].first == -0.5f);
372     assert (out[2].second == Triple (2.f/3, 1.f, 1.f));
373     assert (out[3].first == -0.5f);
374     assert (out[3].second == Triple (-1.f, -0.2f, 0.f));
375     assert (out[4].first == -0.5f);
376     assert (out[4].second == Triple (-1.f, -1.f, -0.2f));
377   }
378
379   {
380     Triple tent (0.5f, 0.5f, 0.5f);
381     Triple axis_range (0.f, 0.5f, 1.f);
382     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
383     assert (out.length == 5);
384     assert (out[0].first == 1.f);
385     assert (out[0].second == Triple ());
386     assert (out[1].first == -1.f);
387     assert (out[1].second == Triple (0.f, 2/(float) (1 << 14), 1.f));
388     assert (out[2].first == -1.f);
389     assert (out[2].second == Triple (2/(float) (1 << 14), 1.f, 1.f));
390     assert (out[3].first == -1.f);
391     assert (out[3].second == Triple (-1.f, -2/(float) (1 << 14), 0.f));
392     assert (out[4].first == -1.f);
393     assert (out[4].second == Triple (-1.f, -1.f, -2/(float) (1 << 14)));
394   }
395
396   {
397     Triple tent (0.f, 1.f, 1.f);
398     Triple axis_range (-1.f, -0.5f, 1.f);
399     result_t out = rebase_tent (tent, axis_range, default_axis_distances);
400     assert (out.length == 1);
401     assert (out[0].first == 1.f);
402     assert (out[0].second == Triple (1.f/3, 1.f, 1.f));
403   }
404
405   {
406     Triple tent (0.f, 1.f, 1.f);
407     Triple axis_range (-1.f, -0.5f, 1.f);
408     TripleDistances axis_distances{2.f, 1.f};
409     result_t out = rebase_tent (tent, axis_range, axis_distances);
410     assert (out.length == 1);
411     assert (out[0].first == 1.f);
412     assert (out[0].second == Triple (0.5f, 1.f, 1.f));
413   }
414 }
415