Home | History | Annotate | Download | only in src
      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-private.hh"
     28 
     29 #include "hb-ot-layout-private.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  * fvar/avar
     37  */
     38 
     39 static inline const OT::fvar&
     40 _get_fvar (hb_face_t *face)
     41 {
     42   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar);
     43   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
     44   return *(layout->fvar.get ());
     45 }
     46 static inline const OT::avar&
     47 _get_avar (hb_face_t *face)
     48 {
     49   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar);
     50   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
     51   return *(layout->avar.get ());
     52 }
     53 
     54 /**
     55  * hb_ot_var_has_data:
     56  * @face: #hb_face_t to test
     57  *
     58  * This function allows to verify the presence of OpenType variation data on the face.
     59  * Alternatively, use hb_ot_var_get_axis_count().
     60  *
     61  * Return value: true if face has a `fvar' table and false otherwise
     62  *
     63  * Since: 1.4.2
     64  **/
     65 hb_bool_t
     66 hb_ot_var_has_data (hb_face_t *face)
     67 {
     68   return &_get_fvar (face) != &OT::Null(OT::fvar);
     69 }
     70 
     71 /**
     72  * hb_ot_var_get_axis_count:
     73  *
     74  * Since: 1.4.2
     75  **/
     76 unsigned int
     77 hb_ot_var_get_axis_count (hb_face_t *face)
     78 {
     79   const OT::fvar &fvar = _get_fvar (face);
     80   return fvar.get_axis_count ();
     81 }
     82 
     83 /**
     84  * hb_ot_var_get_axes:
     85  *
     86  * Since: 1.4.2
     87  **/
     88 unsigned int
     89 hb_ot_var_get_axes (hb_face_t        *face,
     90 		    unsigned int      start_offset,
     91 		    unsigned int     *axes_count /* IN/OUT */,
     92 		    hb_ot_var_axis_t *axes_array /* OUT */)
     93 {
     94   const OT::fvar &fvar = _get_fvar (face);
     95   return fvar.get_axis_infos (start_offset, axes_count, axes_array);
     96 }
     97 
     98 /**
     99  * hb_ot_var_find_axis:
    100  *
    101  * Since: 1.4.2
    102  **/
    103 hb_bool_t
    104 hb_ot_var_find_axis (hb_face_t        *face,
    105 		     hb_tag_t          axis_tag,
    106 		     unsigned int     *axis_index,
    107 		     hb_ot_var_axis_t *axis_info)
    108 {
    109   const OT::fvar &fvar = _get_fvar (face);
    110   return fvar.find_axis (axis_tag, axis_index, axis_info);
    111 }
    112 
    113 
    114 /**
    115  * hb_ot_var_normalize_variations:
    116  *
    117  * Since: 1.4.2
    118  **/
    119 void
    120 hb_ot_var_normalize_variations (hb_face_t            *face,
    121 				const hb_variation_t *variations, /* IN */
    122 				unsigned int          variations_length,
    123 				int                  *coords, /* OUT */
    124 				unsigned int          coords_length)
    125 {
    126   for (unsigned int i = 0; i < coords_length; i++)
    127     coords[i] = 0;
    128 
    129   const OT::fvar &fvar = _get_fvar (face);
    130   for (unsigned int i = 0; i < variations_length; i++)
    131   {
    132     unsigned int axis_index;
    133     if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, nullptr) &&
    134 	axis_index < coords_length)
    135       coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value);
    136   }
    137 
    138   const OT::avar &avar = _get_avar (face);
    139   avar.map_coords (coords, coords_length);
    140 }
    141 
    142 /**
    143  * hb_ot_var_normalize_coords:
    144  *
    145  * Since: 1.4.2
    146  **/
    147 void
    148 hb_ot_var_normalize_coords (hb_face_t    *face,
    149 			    unsigned int coords_length,
    150 			    const float *design_coords, /* IN */
    151 			    int *normalized_coords /* OUT */)
    152 {
    153   const OT::fvar &fvar = _get_fvar (face);
    154   for (unsigned int i = 0; i < coords_length; i++)
    155     normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
    156 
    157   const OT::avar &avar = _get_avar (face);
    158   avar.map_coords (normalized_coords, coords_length);
    159 }
    160