1 /*
   2  * Copyright © 2017  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): Behdad Esfahbod
  25  */
  26 
  27 #include "hb-open-type.hh"
  28 
  29 #include "hb-ot-face.hh"
  30 #include "hb-ot-var-avar-table.hh"
  31 #include "hb-ot-var-fvar-table.hh"
  32 #include "hb-ot-var-mvar-table.hh"
  33 #include "hb-ot-var.h"
  34 
  35 
  36 /**
  37  * SECTION:hb-ot-var
  38  * @title: hb-ot-var
  39  * @short_description: OpenType Font Variations
  40  * @include: hb-ot.h
  41  *
  42  * Functions for fetching information about OpenType Variable Fonts.
  43  **/
  44 
  45 
  46 /*
  47  * fvar/avar
  48  */
  49 
  50 
  51 /**
  52  * hb_ot_var_has_data:
  53  * @face: #hb_face_t to test
  54  *
  55  * This function allows to verify the presence of OpenType variation data on the face.
  56  *
  57  * Return value: true if face has a `fvar' table and false otherwise
  58  *
  59  * Since: 1.4.2
  60  **/
  61 hb_bool_t
  62 hb_ot_var_has_data (hb_face_t *face)
  63 {
  64   return face->table.fvar->has_data ();
  65 }
  66 
  67 /**
  68  * hb_ot_var_get_axis_count:
  69  *
  70  * Since: 1.4.2
  71  **/
  72 unsigned int
  73 hb_ot_var_get_axis_count (hb_face_t *face)
  74 {
  75   return face->table.fvar->get_axis_count ();
  76 }
  77 
  78 /**
  79  * hb_ot_var_get_axes:
  80  *
  81  * Since: 1.4.2
  82  * Deprecated: 2.2.0
  83  **/
  84 unsigned int
  85 hb_ot_var_get_axes (hb_face_t        *face,
  86                     unsigned int      start_offset,
  87                     unsigned int     *axes_count /* IN/OUT */,
  88                     hb_ot_var_axis_t *axes_array /* OUT */)
  89 {
  90   return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array);
  91 }
  92 
  93 /**
  94  * hb_ot_var_find_axis:
  95  *
  96  * Since: 1.4.2
  97  * Deprecated: 2.2.0
  98  **/
  99 hb_bool_t
 100 hb_ot_var_find_axis (hb_face_t        *face,
 101                      hb_tag_t          axis_tag,
 102                      unsigned int     *axis_index,
 103                      hb_ot_var_axis_t *axis_info)
 104 {
 105   return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
 106 }
 107 
 108 /**
 109  * hb_ot_var_get_axis_infos:
 110  *
 111  * Since: 2.2.0
 112  **/
 113 HB_EXTERN unsigned int
 114 hb_ot_var_get_axis_infos (hb_face_t             *face,
 115                           unsigned int           start_offset,
 116                           unsigned int          *axes_count /* IN/OUT */,
 117                           hb_ot_var_axis_info_t *axes_array /* OUT */)
 118 {
 119   return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array);
 120 }
 121 
 122 /**
 123  * hb_ot_var_find_axis_info:
 124  *
 125  * Since: 2.2.0
 126  **/
 127 HB_EXTERN hb_bool_t
 128 hb_ot_var_find_axis_info (hb_face_t             *face,
 129                           hb_tag_t               axis_tag,
 130                           hb_ot_var_axis_info_t *axis_info)
 131 {
 132   return face->table.fvar->find_axis_info (axis_tag, axis_info);
 133 }
 134 
 135 
 136 /*
 137  * Named instances.
 138  */
 139 
 140 unsigned int
 141 hb_ot_var_get_named_instance_count (hb_face_t *face)
 142 {
 143   return face->table.fvar->get_instance_count ();
 144 }
 145 
 146 hb_ot_name_id_t
 147 hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t   *face,
 148                                                 unsigned int instance_index)
 149 {
 150   return face->table.fvar->get_instance_subfamily_name_id (instance_index);
 151 }
 152 
 153 hb_ot_name_id_t
 154 hb_ot_var_named_instance_get_postscript_name_id (hb_face_t  *face,
 155                                                 unsigned int instance_index)
 156 {
 157   return face->table.fvar->get_instance_postscript_name_id (instance_index);
 158 }
 159 
 160 unsigned int
 161 hb_ot_var_named_instance_get_design_coords (hb_face_t    *face,
 162                                             unsigned int  instance_index,
 163                                             unsigned int *coords_length, /* IN/OUT */
 164                                             float        *coords         /* OUT */)
 165 {
 166   return face->table.fvar->get_instance_coords (instance_index, coords_length, coords);
 167 }
 168 
 169 
 170 /**
 171  * hb_ot_var_normalize_variations:
 172  *
 173  * Since: 1.4.2
 174  **/
 175 void
 176 hb_ot_var_normalize_variations (hb_face_t            *face,
 177                                 const hb_variation_t *variations, /* IN */
 178                                 unsigned int          variations_length,
 179                                 int                  *coords, /* OUT */
 180                                 unsigned int          coords_length)
 181 {
 182   for (unsigned int i = 0; i < coords_length; i++)
 183     coords[i] = 0;
 184 
 185   const OT::fvar &fvar = *face->table.fvar;
 186   for (unsigned int i = 0; i < variations_length; i++)
 187   {
 188     hb_ot_var_axis_info_t info;
 189     if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) &&
 190         info.axis_index < coords_length)
 191       coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value);
 192   }
 193 
 194   face->table.avar->map_coords (coords, coords_length);
 195 }
 196 
 197 /**
 198  * hb_ot_var_normalize_coords:
 199  *
 200  * Since: 1.4.2
 201  **/
 202 void
 203 hb_ot_var_normalize_coords (hb_face_t    *face,
 204                             unsigned int coords_length,
 205                             const float *design_coords, /* IN */
 206                             int *normalized_coords /* OUT */)
 207 {
 208   const OT::fvar &fvar = *face->table.fvar;
 209   for (unsigned int i = 0; i < coords_length; i++)
 210     normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
 211 
 212   face->table.avar->map_coords (normalized_coords, coords_length);
 213 }