tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-harfrust.cc (5656B)


      1 /*
      2 *  This is part of HarfBuzz, a text shaping library.
      3 *
      4 * Permission is hereby granted, without written agreement and without
      5 * license or royalty fees, to use, copy, modify, and distribute this
      6 * software and its documentation for any purpose, provided that the
      7 * above copyright notice and the following two paragraphs appear in
      8 * all copies of this software.
      9 *
     10 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     11 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     12 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     13 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     14 * DAMAGE.
     15 *
     16 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     17 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     18 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     19 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     20 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     21 *
     22 * Author(s): Behdad Esfahbod
     23 */
     24 
     25 #include "hb.hh"
     26 
     27 #ifdef HAVE_HARFRUST
     28 
     29 #include "hb-shaper-impl.hh"
     30 
     31 #include "hb-utf.hh"
     32 
     33 
     34 /*
     35 * buffer
     36 */
     37 extern "C" void *
     38 _hb_harfrust_buffer_create_rs (void);
     39 
     40 extern "C" void
     41 _hb_harfrust_buffer_destroy_rs (void *data);
     42 
     43 
     44 /*
     45 * shaper face data
     46 */
     47 
     48 extern "C" void *
     49 _hb_harfrust_shaper_face_data_create_rs (hb_face_t *face);
     50 
     51 hb_harfrust_face_data_t *
     52 _hb_harfrust_shaper_face_data_create (hb_face_t *face)
     53 {
     54  return (hb_harfrust_face_data_t *) _hb_harfrust_shaper_face_data_create_rs (face);
     55 }
     56 
     57 extern "C" void
     58 _hb_harfrust_shaper_face_data_destroy_rs (void *data);
     59 
     60 void
     61 _hb_harfrust_shaper_face_data_destroy (hb_harfrust_face_data_t *data)
     62 {
     63  _hb_harfrust_shaper_face_data_destroy_rs (data);
     64 }
     65 
     66 
     67 /*
     68 * shaper font data
     69 */
     70 
     71 extern "C" void *
     72 _hb_harfrust_shaper_font_data_create_rs (hb_font_t *font, const void *face_data);
     73 
     74 hb_harfrust_font_data_t *
     75 _hb_harfrust_shaper_font_data_create (hb_font_t *font)
     76 {
     77  const hb_harfrust_face_data_t *face_data = font->face->data.harfrust;
     78  return (hb_harfrust_font_data_t *) _hb_harfrust_shaper_font_data_create_rs (font, face_data);
     79 }
     80 
     81 extern "C" void
     82 _hb_harfrust_shaper_font_data_destroy_rs (void *data);
     83 
     84 void
     85 _hb_harfrust_shaper_font_data_destroy (hb_harfrust_font_data_t *data)
     86 {
     87  _hb_harfrust_shaper_font_data_destroy_rs (data);
     88 }
     89 
     90 
     91 /*
     92 * shape plan
     93 */
     94 
     95 extern "C" void *
     96 _hb_harfrust_shape_plan_create_rs (const void *font_data,
     97 			   hb_script_t script,
     98 			   hb_language_t language,
     99 			   hb_direction_t direction);
    100 
    101 extern "C" void
    102 _hb_harfrust_shape_plan_destroy_rs (void *data);
    103 
    104 
    105 /*
    106 * shaper
    107 */
    108 
    109 extern "C" hb_bool_t
    110 _hb_harfrust_shape_rs (const void         *font_data,
    111 	       const void         *face_data,
    112 	       const void         *rs_shape_plan,
    113 	       const void         *rs_buffer,
    114 	       hb_font_t          *font,
    115 	       hb_buffer_t        *buffer,
    116 	       const uint8_t      *pre_context,
    117 	       uint32_t            pre_context_len,
    118 	       const uint8_t      *post_context,
    119 	       uint32_t            post_context_len,
    120 	       const hb_feature_t *features,
    121 	       unsigned int        num_features);
    122 
    123 static hb_user_data_key_t hb_object_key = {0};
    124 
    125 hb_bool_t
    126 _hb_harfrust_shape (hb_shape_plan_t    *shape_plan,
    127 	    hb_font_t          *font,
    128 	    hb_buffer_t        *buffer,
    129 	    const hb_feature_t *features,
    130 	    unsigned int        num_features)
    131 {
    132  const hb_harfrust_font_data_t *font_data = font->data.harfrust;
    133  const hb_harfrust_face_data_t *face_data = font->face->data.harfrust;
    134 
    135 retry_buffer:
    136  void *hr_buffer = hb_buffer_get_user_data (buffer, &hb_object_key);
    137  if (unlikely (!hr_buffer))
    138  {
    139    hr_buffer = _hb_harfrust_buffer_create_rs ();
    140    if (unlikely (!hr_buffer))
    141      return false;
    142 
    143    if (!hb_buffer_set_user_data (buffer,
    144 			  &hb_object_key,
    145 			  hr_buffer,
    146 			  _hb_harfrust_buffer_destroy_rs,
    147 			  false))
    148    {
    149      _hb_harfrust_buffer_destroy_rs (hr_buffer);
    150      goto retry_buffer;
    151    }
    152  }
    153 
    154  void *hr_shape_plan = nullptr;
    155 
    156  if (!num_features)
    157  {
    158  retry_shape_plan:
    159    hr_shape_plan = hb_shape_plan_get_user_data (shape_plan, &hb_object_key);
    160    if (unlikely (!hr_shape_plan))
    161    {
    162      hr_shape_plan = _hb_harfrust_shape_plan_create_rs (font_data,
    163 						 shape_plan->key.props.script,
    164 						 shape_plan->key.props.language,
    165 						 shape_plan->key.props.direction);
    166      if (hr_shape_plan &&
    167   !hb_shape_plan_set_user_data (shape_plan,
    168 			       &hb_object_key,
    169 			       hr_shape_plan,
    170 			       _hb_harfrust_shape_plan_destroy_rs,
    171 			       false))
    172      {
    173        _hb_harfrust_shape_plan_destroy_rs (hr_shape_plan);
    174 goto retry_shape_plan;
    175      }
    176    }
    177  }
    178 
    179  // Encode buffer pre/post-context as UTF-8, so that HarfRust can use it.
    180  constexpr int CONTEXT_BYTE_SIZE = 4 * hb_buffer_t::CONTEXT_LENGTH;
    181  uint8_t pre_context[CONTEXT_BYTE_SIZE];
    182  unsigned pre_context_len = 0;
    183  for (unsigned i = buffer->context_len[0]; i; i--)
    184    pre_context_len = hb_utf8_t::encode (pre_context + pre_context_len,
    185 				 pre_context + CONTEXT_BYTE_SIZE,
    186 				 buffer->context[0][i - 1]) - pre_context;
    187  uint8_t post_context[CONTEXT_BYTE_SIZE];
    188  unsigned post_context_len = 0;
    189  for (unsigned i = 0; i < buffer->context_len[1]; i++)
    190    post_context_len = hb_utf8_t::encode (post_context + post_context_len,
    191 				  post_context + CONTEXT_BYTE_SIZE,
    192 				  buffer->context[1][i]) - post_context;
    193 
    194  return _hb_harfrust_shape_rs (font_data,
    195 			face_data,
    196 			hr_shape_plan,
    197 			hr_buffer,
    198 			font,
    199 			buffer,
    200 			pre_context,
    201 			pre_context_len,
    202 			post_context,
    203 			post_context_len,
    204 			features,
    205 			num_features);
    206 }
    207 
    208 
    209 #endif