gfx/harfbuzz/src/hb-icu-le.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/harfbuzz/src/hb-icu-le.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,215 @@
     1.4 +/*
     1.5 + * Copyright © 2012  Google, Inc.
     1.6 + *
     1.7 + *  This is part of HarfBuzz, a text shaping library.
     1.8 + *
     1.9 + * Permission is hereby granted, without written agreement and without
    1.10 + * license or royalty fees, to use, copy, modify, and distribute this
    1.11 + * software and its documentation for any purpose, provided that the
    1.12 + * above copyright notice and the following two paragraphs appear in
    1.13 + * all copies of this software.
    1.14 + *
    1.15 + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
    1.16 + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
    1.17 + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
    1.18 + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    1.19 + * DAMAGE.
    1.20 + *
    1.21 + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
    1.22 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    1.23 + * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
    1.24 + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
    1.25 + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
    1.26 + *
    1.27 + * Google Author(s): Behdad Esfahbod
    1.28 + */
    1.29 +
    1.30 +#define HB_SHAPER icu_le
    1.31 +#define hb_icu_le_shaper_font_data_t PortableFontInstance
    1.32 +#include "hb-shaper-impl-private.hh"
    1.33 +
    1.34 +#include "hb-icu-le/PortableFontInstance.h"
    1.35 +
    1.36 +#include "layout/loengine.h"
    1.37 +#include "unicode/unistr.h"
    1.38 +
    1.39 +#include "hb-icu.h"
    1.40 +
    1.41 +
    1.42 +/*
    1.43 + * shaper face data
    1.44 + */
    1.45 +
    1.46 +struct hb_icu_le_shaper_face_data_t {};
    1.47 +
    1.48 +hb_icu_le_shaper_face_data_t *
    1.49 +_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED)
    1.50 +{
    1.51 +  return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
    1.52 +}
    1.53 +
    1.54 +void
    1.55 +_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED)
    1.56 +{
    1.57 +}
    1.58 +
    1.59 +
    1.60 +/*
    1.61 + * shaper font data
    1.62 + */
    1.63 +
    1.64 +hb_icu_le_shaper_font_data_t *
    1.65 +_hb_icu_le_shaper_font_data_create (hb_font_t *font)
    1.66 +{
    1.67 +  LEErrorCode status = LE_NO_ERROR;
    1.68 +  hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face,
    1.69 +								 font->x_scale,
    1.70 +								 font->y_scale,
    1.71 +								 status);
    1.72 +  if (status != LE_NO_ERROR) {
    1.73 +    delete (data);
    1.74 +    return NULL;
    1.75 +  }
    1.76 +
    1.77 +  return data;
    1.78 +}
    1.79 +
    1.80 +void
    1.81 +_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
    1.82 +{
    1.83 +  delete (data);
    1.84 +}
    1.85 +
    1.86 +
    1.87 +/*
    1.88 + * shaper shape_plan data
    1.89 + */
    1.90 +
    1.91 +struct hb_icu_le_shaper_shape_plan_data_t {};
    1.92 +
    1.93 +hb_icu_le_shaper_shape_plan_data_t *
    1.94 +_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
    1.95 +					  const hb_feature_t *user_features,
    1.96 +					  unsigned int        num_user_features)
    1.97 +{
    1.98 +  return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
    1.99 +}
   1.100 +
   1.101 +void
   1.102 +_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data)
   1.103 +{
   1.104 +}
   1.105 +
   1.106 +
   1.107 +/*
   1.108 + * shaper
   1.109 + */
   1.110 +
   1.111 +hb_bool_t
   1.112 +_hb_icu_le_shape (hb_shape_plan_t    *shape_plan,
   1.113 +		  hb_font_t          *font,
   1.114 +		  hb_buffer_t        *buffer,
   1.115 +		  const hb_feature_t *features,
   1.116 +		  unsigned int        num_features)
   1.117 +{
   1.118 +  LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font);
   1.119 +  le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script);
   1.120 +  le_int32 language_code = -1 /* TODO */;
   1.121 +  le_int32 typography_flags = 3; /* Needed for ligatures and kerning */
   1.122 +  LEErrorCode status = LE_NO_ERROR;
   1.123 +  le_engine *le = le_create ((const le_font *) font_instance,
   1.124 +			     script_code,
   1.125 +			     language_code,
   1.126 +			     typography_flags,
   1.127 +			     &status);
   1.128 +  if (status != LE_NO_ERROR)
   1.129 +  { le_close (le); return false; }
   1.130 +
   1.131 +retry:
   1.132 +
   1.133 +  unsigned int scratch_size;
   1.134 +  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
   1.135 +
   1.136 +#define ALLOCATE_ARRAY(Type, name, len) \
   1.137 +  Type *name = (Type *) scratch; \
   1.138 +  scratch += (len) * sizeof ((name)[0]); \
   1.139 +  scratch_size -= (len) * sizeof ((name)[0]);
   1.140 +
   1.141 +  ALLOCATE_ARRAY (LEUnicode, chars, buffer->len);
   1.142 +  ALLOCATE_ARRAY (unsigned int, clusters, buffer->len);
   1.143 +
   1.144 +  /* XXX Use UTF-16 decoder! */
   1.145 +  for (unsigned int i = 0; i < buffer->len; i++) {
   1.146 +    chars[i] = buffer->info[i].codepoint;
   1.147 +    clusters[i] = buffer->info[i].cluster;
   1.148 +  }
   1.149 +
   1.150 +  unsigned int glyph_count = le_layoutChars (le,
   1.151 +					     chars,
   1.152 +					     0,
   1.153 +					     buffer->len,
   1.154 +					     buffer->len,
   1.155 +					     HB_DIRECTION_IS_BACKWARD (buffer->props.direction),
   1.156 +					     0., 0.,
   1.157 +					     &status);
   1.158 +  if (status != LE_NO_ERROR)
   1.159 +  { le_close (le); return false; }
   1.160 +
   1.161 +  unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) +
   1.162 +					    sizeof (le_int32) +
   1.163 +					    sizeof (float) * 2);
   1.164 +
   1.165 +  if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) {
   1.166 +    buffer->ensure (buffer->allocated * 2);
   1.167 +    if (buffer->in_error)
   1.168 +    { le_close (le); return false; }
   1.169 +    goto retry;
   1.170 +  }
   1.171 +
   1.172 +  ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count);
   1.173 +  ALLOCATE_ARRAY (le_int32, indices, glyph_count);
   1.174 +  ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2);
   1.175 +
   1.176 +  le_getGlyphs (le, glyphs, &status);
   1.177 +  le_getCharIndices (le, indices, &status);
   1.178 +  le_getGlyphPositions (le, positions, &status);
   1.179 +
   1.180 +#undef ALLOCATE_ARRAY
   1.181 +
   1.182 +  /* Ok, we've got everything we need, now compose output buffer,
   1.183 +   * very, *very*, carefully! */
   1.184 +
   1.185 +  unsigned int j = 0;
   1.186 +  hb_glyph_info_t *info = buffer->info;
   1.187 +  for (unsigned int i = 0; i < glyph_count; i++)
   1.188 +  {
   1.189 +    if (glyphs[i] >= 0xFFFE)
   1.190 +	continue;
   1.191 +
   1.192 +    info[j].codepoint = glyphs[i];
   1.193 +    info[j].cluster = clusters[indices[i]];
   1.194 +
   1.195 +    /* icu-le doesn't seem to have separate advance values. */
   1.196 +    info[j].mask = positions[2 * i + 2] - positions[2 * i];
   1.197 +    info[j].var1.u32 = 0;
   1.198 +    info[j].var2.u32 = -positions[2 * i + 1];
   1.199 +
   1.200 +    j++;
   1.201 +  }
   1.202 +  buffer->len = j;
   1.203 +
   1.204 +  buffer->clear_positions ();
   1.205 +
   1.206 +  for (unsigned int i = 0; i < buffer->len; i++) {
   1.207 +    hb_glyph_info_t *info = &buffer->info[i];
   1.208 +    hb_glyph_position_t *pos = &buffer->pos[i];
   1.209 +
   1.210 +    /* TODO vertical */
   1.211 +    pos->x_advance = info->mask;
   1.212 +    pos->x_offset = info->var1.u32;
   1.213 +    pos->y_offset = info->var2.u32;
   1.214 +  }
   1.215 +
   1.216 +  le_close (le);
   1.217 +  return true;
   1.218 +}

mercurial