hb-ot-layout-private.hh 7.7 KB
Newer Older
B
Behdad Esfahbod 已提交
1
/*
B
Behdad Esfahbod 已提交
2
 * Copyright © 2007,2008,2009  Red Hat, Inc.
B
Behdad Esfahbod 已提交
3
 * Copyright © 2012  Google, Inc.
B
Behdad Esfahbod 已提交
4
 *
B
Behdad Esfahbod 已提交
5
 *  This is part of HarfBuzz, a text shaping library.
B
Behdad Esfahbod 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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.
 *
 * Red Hat Author(s): Behdad Esfahbod
B
Behdad Esfahbod 已提交
26
 * Google Author(s): Behdad Esfahbod
B
Behdad Esfahbod 已提交
27 28
 */

B
Behdad Esfahbod 已提交
29 30
#ifndef HB_OT_LAYOUT_PRIVATE_HH
#define HB_OT_LAYOUT_PRIVATE_HH
B
Behdad Esfahbod 已提交
31

32
#include "hb-private.hh"
B
Behdad Esfahbod 已提交
33

B
Behdad Esfahbod 已提交
34
#include "hb-ot-layout.h"
B
Behdad Esfahbod 已提交
35

36
#include "hb-font-private.hh"
37
#include "hb-buffer-private.hh"
38
#include "hb-set-private.hh"
B
Behdad Esfahbod 已提交
39

40

B
Behdad Esfahbod 已提交
41
/* buffer var allocations, used during the GSUB/GPOS processing */
42 43 44
#define glyph_props()		var1.u16[0] /* GDEF glyph properties */
#define syllable()		var1.u8[2] /* GSUB/GPOS shaping boundaries */
#define lig_props()		var1.u8[3] /* GSUB/GPOS ligature tracking */
B
Behdad Esfahbod 已提交
45

46 47 48 49 50 51 52 53 54 55
/* buffer var allocations, used during the entire shaping process */
#define unicode_props0()	var2.u8[0]
#define unicode_props1()	var2.u8[1]


inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
  info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
			   (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
56 57
			   (info->codepoint == 0x200C ? 0x40 : 0) |
			   (info->codepoint == 0x200D ? 0x20 : 0);
58 59 60 61 62 63
  info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
}

inline hb_unicode_general_category_t
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
{
64
  return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
}

inline void
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
{
  info->unicode_props1() = modified_class;
}

inline unsigned int
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
{
  return info->unicode_props1();
}

inline hb_bool_t
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
{
  return !!(info->unicode_props0() & 0x80);
}

inline hb_bool_t
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
{
  return !!(info->unicode_props0() & 0x40);
}

91 92 93 94 95 96
inline hb_bool_t
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
{
  return !!(info->unicode_props0() & 0x20);
}

97

98
#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
B
Behdad Esfahbod 已提交
99

100 101 102 103
/*
 * GDEF
 */

104
typedef enum {
B
Minor  
Behdad Esfahbod 已提交
105 106 107 108 109
  HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
  HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
110 111
} hb_ot_layout_glyph_class_mask_t;

B
Behdad Esfahbod 已提交
112

113

B
Behdad Esfahbod 已提交
114 115 116 117
/*
 * GSUB/GPOS
 */

118 119 120 121
/* lig_id / lig_comp
 *
 * When a ligature is formed:
 *
122 123
 *   - The ligature glyph and any marks in between all the same newly allocated
 *     lig_id,
B
Minor  
Behdad Esfahbod 已提交
124
 *   - The ligature glyph will get lig_num_comps set to the number of components
125 126 127 128 129 130 131 132 133
 *   - The marks get lig_comp > 0, reflecting which component of the ligature
 *     they were applied to.
 *   - This is used in GPOS to attach marks to the right component of a ligature
 *     in MarkLigPos.
 *
 * When a multiple-substitution is done:
 *
 *   - All resulting glyphs will have lig_id = 0,
 *   - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
134
 *   - This is used in GPOS to attach marks to the first component of a
135 136 137 138 139
 *     multiple substitution in MarkBasePos.
 *
 * The numbers are also used in GPOS to do mark-to-mark positioning only
 * to marks that belong to the same component of a ligature in MarkMarPos.
 */
B
Minor  
Behdad Esfahbod 已提交
140
#define IS_LIG_BASE 0x10
B
Behdad Esfahbod 已提交
141
static inline void
B
Behdad Esfahbod 已提交
142 143
set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps)
{
B
Minor  
Behdad Esfahbod 已提交
144
  info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
B
Behdad Esfahbod 已提交
145 146 147 148 149 150 151 152 153 154 155 156
}
static inline void
set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp)
{
  info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
}
static inline void
set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
{
  set_lig_props_for_mark (info, 0, comp);
}

B
Behdad Esfahbod 已提交
157 158 159
static inline unsigned int
get_lig_id (const hb_glyph_info_t &info)
{
B
Behdad Esfahbod 已提交
160
  return info.lig_props() >> 5;
B
Behdad Esfahbod 已提交
161
}
B
Minor  
Behdad Esfahbod 已提交
162 163 164 165 166
static inline bool
is_a_ligature (const hb_glyph_info_t &info)
{
  return !!(info.lig_props() & IS_LIG_BASE);
}
B
Behdad Esfahbod 已提交
167 168 169
static inline unsigned int
get_lig_comp (const hb_glyph_info_t &info)
{
B
Minor  
Behdad Esfahbod 已提交
170
  if (is_a_ligature (info))
B
Behdad Esfahbod 已提交
171 172 173 174 175 176 177
    return 0;
  else
    return info.lig_props() & 0x0F;
}
static inline unsigned int
get_lig_num_comps (const hb_glyph_info_t &info)
{
178
  if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
B
Behdad Esfahbod 已提交
179 180 181
    return info.lig_props() & 0x0F;
  else
    return 1;
B
Behdad Esfahbod 已提交
182 183 184
}

static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
B
Behdad Esfahbod 已提交
185
  uint8_t lig_id = buffer->next_serial () & 0x07;
B
Behdad Esfahbod 已提交
186 187 188 189 190 191
  if (unlikely (!lig_id))
    lig_id = allocate_lig_id (buffer); /* in case of overflow */
  return lig_id;
}


B
Behdad Esfahbod 已提交
192
HB_INTERNAL hb_bool_t
193
hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
194
					   unsigned int          lookup_index,
B
Behdad Esfahbod 已提交
195 196
					   const hb_codepoint_t *glyphs,
					   unsigned int          glyphs_length,
197
					   hb_bool_t             zero_context);
B
Behdad Esfahbod 已提交
198

B
Behdad Esfahbod 已提交
199 200 201

/* Should be called before all the substitute_lookup's are done. */
HB_INTERNAL void
202
hb_ot_layout_substitute_start (hb_font_t    *font,
B
Behdad Esfahbod 已提交
203 204
			       hb_buffer_t  *buffer);

B
Behdad Esfahbod 已提交
205
HB_INTERNAL hb_bool_t
206
hb_ot_layout_substitute_lookup (hb_font_t    *font,
B
Behdad Esfahbod 已提交
207 208
				hb_buffer_t  *buffer,
				unsigned int  lookup_index,
209
				hb_mask_t     mask,
210
				hb_bool_t     auto_zwj);
B
Behdad Esfahbod 已提交
211 212 213

/* Should be called after all the substitute_lookup's are done */
HB_INTERNAL void
214
hb_ot_layout_substitute_finish (hb_font_t    *font,
B
Behdad Esfahbod 已提交
215 216 217 218 219 220 221
				hb_buffer_t  *buffer);


/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
HB_INTERNAL void
hb_ot_layout_position_start (hb_font_t    *font,
			     hb_buffer_t  *buffer);
B
Behdad Esfahbod 已提交
222 223

HB_INTERNAL hb_bool_t
B
Behdad Esfahbod 已提交
224 225 226
hb_ot_layout_position_lookup (hb_font_t    *font,
			      hb_buffer_t  *buffer,
			      unsigned int  lookup_index,
227
			      hb_mask_t     mask,
228
			      hb_bool_t     auto_zwj);
B
Behdad Esfahbod 已提交
229 230 231 232

/* Should be called after all the position_lookup's are done */
HB_INTERNAL void
hb_ot_layout_position_finish (hb_font_t    *font,
233
			      hb_buffer_t  *buffer);
B
Behdad Esfahbod 已提交
234

B
Behdad Esfahbod 已提交
235 236


237 238 239 240
/*
 * hb_ot_layout_t
 */

241 242 243 244 245 246
namespace OT {
  struct GDEF;
  struct GSUB;
  struct GPOS;
}

B
Behdad Esfahbod 已提交
247
struct hb_ot_layout_t
B
Behdad Esfahbod 已提交
248
{
B
Behdad Esfahbod 已提交
249 250 251 252
  hb_blob_t *gdef_blob;
  hb_blob_t *gsub_blob;
  hb_blob_t *gpos_blob;

253 254 255
  const struct OT::GDEF *gdef;
  const struct OT::GSUB *gsub;
  const struct OT::GPOS *gpos;
256

257 258 259
  unsigned int gsub_lookup_count;
  unsigned int gpos_lookup_count;

260 261
  hb_set_digest_t *gsub_digests;
  hb_set_digest_t *gpos_digests;
262
};
B
Behdad Esfahbod 已提交
263

264

B
Behdad Esfahbod 已提交
265
HB_INTERNAL hb_ot_layout_t *
266
_hb_ot_layout_create (hb_face_t *face);
267

B
Behdad Esfahbod 已提交
268
HB_INTERNAL void
269
_hb_ot_layout_destroy (hb_ot_layout_t *layout);
270

B
Behdad Esfahbod 已提交
271

B
Behdad Esfahbod 已提交
272

B
Behdad Esfahbod 已提交
273
#endif /* HB_OT_LAYOUT_PRIVATE_HH */