Edit

kc3-lang/harfbuzz/src/test-subset-instancer-solver.cc

Branch :

  • Show log

    Commit

  • Author : Qunxin Liu
    Date : 2023-06-22 09:37:48
    Hash : 7232c01d
    Message : [instancer-solver] add tests for instancer-solver crossing calculation fix

  • src/test-subset-instancer-solver.cc
  • /*
     * Copyright © 2023  Google, Inc.
     *
     *  This is part of HarfBuzz, a text shaping library.
     *
     * Permission is hereby granted, without written agreement and without
     * license or royalty fees, to use, copy, modify, and distribute this
     * software and its documentation for any purpose, provided that the
     * above copyright notice and the following two paragraphs appear in
     * all copies of this software.
     *
     * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     * DAMAGE.
     *
     * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     *
     * Google Author(s): Qunxin Liu
     */
    
    #include "hb-subset-instancer-solver.hh"
    
    static inline bool approx (Triple a, Triple b)
    {
      return fabsf (a.minimum - b.minimum) < 0.000001f &&
             fabsf (a.middle - b.middle) < 0.000001f &&
             fabsf (a.maximum - b.maximum) < 0.000001f;
    }
    
    static inline bool approx (float a, float b)
    { return fabsf (a - b) < 0.000001f; }
    
    /* tests ported from
     * https://github.com/fonttools/fonttools/blob/main/Tests/varLib/instancer/solver_test.py */
    int
    main (int argc, char **argv)
    {
      /* Case 1 */
      {
        /* pin axis*/
        Triple tent (0.f, 1.f, 1.f);
        Triple axis_range (0.f, 0.f, 0.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 0);
      }
    
      {
        /* pin axis*/
        Triple tent (0.f, 1.f, 1.f);
        Triple axis_range (0.5f, 0.5f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple ());
      }
    
      {
        /* tent falls outside the new axis range */
        Triple tent (0.3f, 0.5f, 0.8f);
        Triple axis_range (0.1f, 0.2f, 0.3f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 0);
      }
    
      /* Case 2 */
      {
        Triple tent (0.f, 1.f, 1.f);
        Triple axis_range (-1.f, 0.f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple (0.f, 1.f, 1.f));
      }
    
      /* Case 2 */
      {
        Triple tent (0.f, 1.f, 1.f);
        Triple axis_range (-1.f, 0.f, 0.75f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 0.75f);
        assert (out[0].second == Triple (0.f, 1.f, 1.f));
      }
    
      /* Without gain: */
      /* Case 3 */
      {
        Triple tent (0.f, 0.2f, 1.f);
        Triple axis_range (-1.f, 0.f, 0.8f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (0.f, 0.25f, 1.25f));
      }
    
      /* Case 3 boundary */
      {
        Triple tent (0.f, 0.4f, 1.f);
        Triple axis_range (-1.f, 0.f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (0.f, 0.8f, 32767/(float) (1 << 14)));
      }
    
      /* Case 4 */
      {
        Triple tent (0.f, 0.25f, 1.f);
        Triple axis_range (-1.f, 0.f, 0.4f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 2);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (0.f, 0.625f, 1.f));
        assert (approx (out[1].first, 0.8f));
        assert (out[1].second == Triple (0.625f, 1.f, 1.f));
      }
    
      /* Case 4 */
      {
        Triple tent (0.25f, 0.3f, 1.05f);
        Triple axis_range (0.f, 0.2f, 0.4f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 2);
        assert (out[0].first == 1.f);
        assert (approx (out[0].second, Triple (0.25f, 0.5f, 1.f)));
        assert (approx (out[1].first, 2.6f/3));
        assert (approx (out[1].second, Triple (0.5f, 1.f, 1.f)));
      }
    
      /* Case 4 boundary */
      {
        Triple tent (0.25f, 0.5f, 1.f);
        Triple axis_range (0.f, 0.25f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (0.f, 1.f, 1.f));
      }
    
      /* With gain */
      /* Case 3a/1neg */
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (0.f, 0.5f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 3);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -1.f);
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (out[2].first == -1.f);
        assert (out[2].second == Triple (-1.f, -1.f, 0.f));
      }
    
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (0.f, 0.5f, 0.75f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 3);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -0.5f);
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (out[2].first == -1.f);
        assert (out[2].second == Triple (-1.f, -1.f, 0.f));
      }
    
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (0.f, 0.25f, 0.8f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 4);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple ());
        assert (out[1].first == 0.5f);
        assert (approx (out[1].second, Triple (0.f, 0.454545f, 0.909091f)));
        assert (approx (out[2].first, -0.1f));
        assert (approx (out[2].second, Triple (0.909091f, 1.f, 1.f)));
        assert (out[3].first == -0.5f);
        assert (out[3].second == Triple (-1.f, -1.f, 0.f));
      }
    
      /* Case 3a/1neg */
      {
        Triple tent (0.f, 0.5f, 2.f);
        Triple axis_range (0.2f, 0.5f, 0.8f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 3);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (approx (out[1].first, -0.2f));
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (approx (out[2].first, -0.6f));
        assert (out[2].second == Triple (-1.f, -1.f, 0.f));
      }
    
      /* Case 3a/1neg */
      {
        Triple tent (0.f, 0.5f, 2.f);
        Triple axis_range (0.2f, 0.5f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 3);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (approx (out[1].first, -1.f/3));
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (approx (out[2].first, -0.6f));
        assert (out[2].second == Triple (-1.f, -1.f, 0.f));
      }
    
      /* Case 3 */
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (0.25f, 0.25f, 0.75f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 2);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple ());
        assert (out[1].first == 0.5f);
        assert (out[1].second == Triple (0.f, 0.5f, 1.0f));
      }
    
      /* Case 1neg */
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (0.f, 0.25f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 3);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple ());
        assert (out[1].first == 0.5f);
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (out[2].first == -0.5f);
        assert (out[2].second == Triple (-1.f, -1.f, 0.f));
      }
    
      /* Case 2neg */
      {
        Triple tent (0.05f, 0.55f, 1.f);
        Triple axis_range (0.f, 0.25f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 4);
        assert (approx (out[0].first, 0.4f));
        assert (out[0].second == Triple ());
        assert (approx (out[1].first, 0.5f));
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
        assert (approx (out[2].first, -0.4f));
        assert (out[2].second == Triple (-1.f, -0.8f, 0.f));
        assert (approx (out[3].first, -0.4f));
        assert (out[3].second == Triple (-1.f, -1.f, -0.8f));
      }
    
      /* Case 2neg, other side */
      {
        Triple tent (-1.f, -0.55f, -0.05f);
        Triple axis_range (-0.5f, -0.25f, 0.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 4);
        assert (approx (out[0].first, 0.4f));
        assert (out[0].second == Triple ());
        assert (approx (out[1].first, 0.5f));
        assert (out[1].second == Triple (-1.f, -1.f, 0.f));
        assert (approx (out[2].first, -0.4f));
        assert (out[2].second == Triple (0.f, 0.8f, 1.f));
        assert (approx (out[3].first, -0.4f));
        assert (out[3].second == Triple (0.8f, 1.f, 1.f));
      }
    
      /* Misc corner cases */
      {
        Triple tent (0.5f, 0.5f, 0.5f);
        Triple axis_range (0.5f, 0.5f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
      }
    
      {
        Triple tent (0.3f, 0.5f, 0.7f);
        Triple axis_range (0.1f, 0.5f, 0.9f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 5);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -1.f);
        assert (out[1].second == Triple (0.f, 0.5f, 1.f));
        assert (out[2].first == -1.f);
        assert (out[2].second == Triple (0.5f, 1.f, 1.f));
        assert (out[3].first == -1.f);
        assert (approx (out[3].second, Triple (-1.f, -0.5f, 0.f)));
        assert (out[4].first == -1.f);
        assert (approx (out[4].second, Triple (-1.f, -1.f, -0.5f)));
      }
    
      {
        Triple tent (0.5f, 0.5f, 0.5f);
        Triple axis_range (0.25f, 0.25f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (1.f, 1.f, 1.f));
      }
    
      {
        Triple tent (0.5f, 0.5f, 0.5f);
        Triple axis_range (0.25f, 0.35f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (1.f, 1.f, 1.f));
      }
    
      {
        Triple tent (0.5f, 0.5f, 0.55f);
        Triple axis_range (0.25f, 0.35f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (1.f, 1.f, 1.f));
      }
    
      {
        Triple tent (0.5f, 0.5f, 1.f);
        Triple axis_range (0.5f, 0.5f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 2);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -1.f);
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
      }
    
      {
        Triple tent (0.25f, 0.5f, 1.f);
        Triple axis_range (0.5f, 0.5f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 2);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -1.f);
        assert (out[1].second == Triple (0.f, 1.f, 1.f));
      }
    
      {
        Triple tent (0.f, 0.2f, 1.f);
        Triple axis_range (0.f, 0.f, 0.5f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 1);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple (0.f, 0.4f, 32767/(float) (1 << 14)));
      }
    
    
      {
        Triple tent (0.f, 0.5f, 1.f);
        Triple axis_range (-1.f, 0.25f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 5);
        assert (out[0].first == 0.5f);
        assert (out[0].second == Triple ());
        assert (out[1].first == 0.5f);
        assert (out[1].second == Triple (0.f, 1.f/3, 2.f/3));
        assert (out[2].first == -0.5f);
        assert (out[2].second == Triple (2.f/3, 1.f, 1.f));
        assert (out[3].first == -0.5f);
        assert (out[3].second == Triple (-1.f, -0.2f, 0.f));
        assert (out[4].first == -0.5f);
        assert (out[4].second == Triple (-1.f, -1.f, -0.2f));
      }
    
      {
        Triple tent (0.5f, 0.5f, 0.5f);
        Triple axis_range (0.f, 0.5f, 1.f);
        result_t out = rebase_tent (tent, axis_range);
        assert (out.length == 5);
        assert (out[0].first == 1.f);
        assert (out[0].second == Triple ());
        assert (out[1].first == -1.f);
        assert (out[1].second == Triple (0.f, 2/(float) (1 << 14), 1.f));
        assert (out[2].first == -1.f);
        assert (out[2].second == Triple (2/(float) (1 << 14), 1.f, 1.f));
        assert (out[3].first == -1.f);
        assert (out[3].second == Triple (-1.f, -2/(float) (1 << 14), 0.f));
        assert (out[4].first == -1.f);
        assert (out[4].second == Triple (-1.f, -1.f, -2/(float) (1 << 14)));
      }
    }