[HarfBuzz] harfbuzz-ng: Branch 'master' - 12 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Jul 31 18:37:02 PDT 2012
src/hb-buffer-private.hh | 3
src/hb-buffer.cc | 24 ++--
src/hb-glib.cc | 30 +++++
src/hb-icu.cc | 36 ++++++-
src/hb-ot-layout-gpos-table.hh | 15 +-
src/hb-ot-layout-gsub-table.hh | 24 ++--
src/hb-ot-layout-gsubgpos-private.hh | 106 ++++++++++++++++++--
src/hb-ot-layout-private.hh | 16 ---
src/hb-ot-layout.cc | 144 +++-------------------------
src/hb-ot-layout.h | 12 +-
src/hb-ot-shape-complex-arabic.cc | 37 +++----
src/hb-ot-shape-complex-indic.cc | 54 ++++++----
src/hb-ot-shape-complex-misc.cc | 67 +++++--------
src/hb-ot-shape-complex-private.hh | 179 ++++++++++-------------------------
src/hb-ot-shape-normalize-private.hh | 4
src/hb-ot-shape-normalize.cc | 53 ++++++----
src/hb-ot-shape-private.hh | 2
src/hb-ot-shape.cc | 26 ++---
src/hb-unicode-private.hh | 1
src/hb-unicode.cc | 27 +++++
src/hb-unicode.h | 37 +++++++
test/api/hb-test.h | 1
test/api/test-unicode.c | 50 +++++++++
23 files changed, 519 insertions(+), 429 deletions(-)
New commits:
commit 378d279bbf692195c4654e312dae854ab3be04cf
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Jul 31 21:36:16 2012 -0400
Implement Unicode compatibility decompositions
Based on patch from Philip Withnall.
https://bugs.freedesktop.org/show_bug.cgi?id=41095
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 6b655dd..5246363 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -336,6 +336,36 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ret;
}
+static unsigned int
+hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed,
+ void *user_data HB_UNUSED)
+{
+#if GLIB_CHECK_VERSION(2,29,12)
+ return g_unichar_fully_decompose (u, TRUE, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
+#endif
+
+ /* If the user doesn't have GLib >= 2.29.12 we have to perform
+ * a round trip to UTF-8 and the associated memory management dance. */
+ gchar utf8[6];
+ gchar *utf8_decomposed, *c;
+ gsize utf8_len, utf8_decomposed_len, i;
+
+ /* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */
+ utf8_len = g_unichar_to_utf8 (u, utf8);
+ utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD);
+ utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1);
+
+ assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
+
+ for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c))
+ *decomposed++ = g_utf8_get_char (c);
+
+ g_free (utf8_decomposed);
+
+ return utf8_decomposed_len;
+}
extern HB_INTERNAL const hb_unicode_funcs_t _hb_glib_unicode_funcs;
const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 491c1c8..dce6103 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -207,7 +207,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t *b,
void *user_data HB_UNUSED)
{
- UChar utf16[2], normalized[20];
+ UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
int len;
hb_bool_t ret, err;
UErrorCode icu_err;
@@ -271,6 +271,40 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ret;
}
+static unsigned int
+hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed,
+ void *user_data HB_UNUSED)
+{
+ UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
+ gint len;
+ int32_t utf32_len;
+ hb_bool_t err;
+ UErrorCode icu_err;
+
+ /* Copy @u into a UTF-16 array to be passed to ICU. */
+ len = 0;
+ err = FALSE;
+ U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
+ if (err)
+ return 0;
+
+ /* Normalise the codepoint using NFKD mode. */
+ icu_err = U_ZERO_ERROR;
+ len = unorm_normalize (utf16, len, UNORM_NFKD, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
+ if (icu_err)
+ return 0;
+
+ /* Convert the decomposed form from UTF-16 to UTF-32. */
+ icu_err = U_ZERO_ERROR;
+ u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err);
+ if (icu_err)
+ return 0;
+
+ return utf32_len;
+}
+
extern HB_INTERNAL const hb_unicode_funcs_t _hb_icu_unicode_funcs;
const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index d4b0b27..46c89ec 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -62,7 +62,8 @@
* knowledge too. We need to provide assistance to the itemizer.
*
* - When a font does not support a character but supports its decomposition,
- * well, use the decomposition.
+ * well, use the decomposition (preferring the canonical decomposition, but
+ * falling back to the compatibility decomposition if necessary).
*
* - The Indic shaper requests decomposed output. This will handle splitting
* matra for the Indic shaper.
@@ -111,29 +112,45 @@ decompose (hb_font_t *font, hb_buffer_t *buffer,
return false;
}
-static void
-decompose_current_glyph (hb_font_t *font, hb_buffer_t *buffer,
- bool shortest)
+static bool
+decompose_compatibility (hb_font_t *font, hb_buffer_t *buffer,
+ hb_codepoint_t u)
{
- if (decompose (font, buffer, shortest, buffer->cur().codepoint))
- buffer->skip_glyph ();
- else
- buffer->next_glyph ();
+ unsigned int len, i;
+ hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+
+ len = hb_unicode_decompose_compatibility (buffer->unicode, u, decomposed);
+ if (!len)
+ return false;
+
+ hb_codepoint_t glyph;
+ for (i = 0; i < len; i++)
+ if (!hb_font_get_glyph (font, decomposed[i], 0, &glyph))
+ return false;
+
+ for (i = 0; i < len; i++)
+ output_glyph (buffer, decomposed[i]);
+
+ return true;
}
static void
-decompose_single_char_cluster (hb_font_t *font, hb_buffer_t *buffer,
- bool will_recompose)
+decompose_current_character (hb_font_t *font, hb_buffer_t *buffer,
+ bool shortest)
{
hb_codepoint_t glyph;
- /* If recomposing and font supports this, we're good to go */
- if (will_recompose && hb_font_get_glyph (font, buffer->cur().codepoint, 0, &glyph)) {
+ /* Kind of a cute waterfall here... */
+ if (shortest && hb_font_get_glyph (font, buffer->cur().codepoint, 0, &glyph))
+ buffer->next_glyph ();
+ else if (decompose (font, buffer, shortest, buffer->cur().codepoint))
+ buffer->skip_glyph ();
+ else if (!shortest && hb_font_get_glyph (font, buffer->cur().codepoint, 0, &glyph))
+ buffer->next_glyph ();
+ else if (decompose_compatibility (font, buffer, buffer->cur().codepoint))
+ buffer->skip_glyph ();
+ else
buffer->next_glyph ();
- return;
- }
-
- decompose_current_glyph (font, buffer, will_recompose);
}
static void
@@ -149,7 +166,7 @@ decompose_multi_char_cluster (hb_font_t *font, hb_buffer_t *buffer,
}
while (buffer->idx < end)
- decompose_current_glyph (font, buffer, false);
+ decompose_current_character (font, buffer, false);
}
static int
@@ -188,7 +205,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
break;
if (buffer->idx + 1 == end)
- decompose_single_char_cluster (font, buffer, recompose);
+ decompose_current_character (font, buffer, recompose);
else {
decompose_multi_char_cluster (font, buffer, end);
has_multichar_clusters = true;
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 1ce5adc..ba791eb 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -50,6 +50,7 @@
HB_UNICODE_FUNC_IMPLEMENT (script) \
HB_UNICODE_FUNC_IMPLEMENT (compose) \
HB_UNICODE_FUNC_IMPLEMENT (decompose) \
+ HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
/* ^--- Add new callbacks here */
/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index b05b290..f300fed 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -99,6 +99,15 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
}
+static unsigned int
+hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t u HB_UNUSED,
+ hb_codepoint_t *decomposed HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return 0;
+}
+
hb_unicode_funcs_t *
hb_unicode_funcs_get_default (void)
@@ -312,6 +321,23 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
}
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed)
+{
+ unsigned int ret = ufuncs->func.decompose_compatibility (ufuncs, u,
+ decomposed,
+ ufuncs->user_data.decompose_compatibility);
+ if (ret == 1 && u == decomposed[0]) {
+ decomposed[0] = 0;
+ return 0;
+ }
+
+ decomposed[ret] = 0;
+
+ return ret;
+}
unsigned int
@@ -380,4 +406,3 @@ _hb_unicode_modified_combining_class (hb_unicode_funcs_t *ufuncs,
return c;
}
-
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 808c6e1..2af2d67 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -1,7 +1,7 @@
/*
* Copyright © 2009 Red Hat, Inc.
* Copyright © 2011 Codethink Limited
- * Copyright © 2011 Google, Inc.
+ * Copyright © 2011,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -122,6 +122,32 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *b,
void *user_data);
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ */
+typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed,
+ void *user_data);
+
+/* See Unicode 6.1 for details on the maximum decomposition length. */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
/* setters */
void
@@ -159,6 +185,10 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_decompose_func_t decompose_func,
void *user_data, hb_destroy_func_t destroy);
+void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_decompose_compatibility_func_t decompose_compatibility_func,
+ void *user_data, hb_destroy_func_t destroy);
/* accessors */
@@ -193,6 +223,11 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *a,
hb_codepoint_t *b);
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed);
+
HB_END_DECLS
#endif /* HB_UNICODE_H */
diff --git a/test/api/hb-test.h b/test/api/hb-test.h
index d569757..8655f41 100644
--- a/test/api/hb-test.h
+++ b/test/api/hb-test.h
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
HB_BEGIN_DECLS
diff --git a/test/api/test-unicode.c b/test/api/test-unicode.c
index a420bf3..96c61dd 100644
--- a/test/api/test-unicode.c
+++ b/test/api/test-unicode.c
@@ -786,6 +786,7 @@ test_unicode_normalization (gconstpointer user_data)
{
hb_unicode_funcs_t *uf = (hb_unicode_funcs_t *) user_data;
gunichar a, b, ab;
+ hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
/* Test compose() */
@@ -849,6 +850,55 @@ test_unicode_normalization (gconstpointer user_data)
g_assert (hb_unicode_decompose (uf, 0xCE31, &a, &b) && a == 0xCE20 && b == 0x11B8);
g_assert (hb_unicode_decompose (uf, 0xCE20, &a, &b) && a == 0x110E && b == 0x1173);
+
+ /* Test decompose_compatibility() */
+
+ /* Not decomposable */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x0041, decomposed) == 0);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x1F632, decomposed) == 0);
+
+ /* Singletons */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x00B5, decomposed) == 1 && decomposed[0] == 0x03BC);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x03D6, decomposed) == 1 && decomposed[0] == 0x03C0);
+
+ /* Arabic compatibility */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0xFB54, decomposed) == 1 && decomposed[0] == 0x067B);
+
+ /* Longest decomposition ever */
+ g_assert (18 <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0xFDFA, decomposed) == 18 && decomposed[17] == 0x0645);
+
+ /* Note: we deliberately don't test characters that have canonical decompositions but no
+ * compatibility decomposition against the decompose_compatibility() function as that we
+ * leave up to implementations (for now). */
+
+ /* Spaces */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2002, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2003, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2004, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2005, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2006, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2008, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2009, decomposed) == 1 && decomposed[0] == 0x0020);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x200A, decomposed) == 1 && decomposed[0] == 0x0020);
+
+ /* Pairs */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x0587, decomposed) == 2 &&
+ decomposed[0] == 0x0565 && decomposed[1] == 0x0582);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2017, decomposed) == 2 &&
+ decomposed[0] == 0x0020 && decomposed[1] == 0x0333);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2025, decomposed) == 2 &&
+ decomposed[0] == 0x002E && decomposed[1] == 0x002E);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2033, decomposed) == 2 &&
+ decomposed[0] == 0x2032 && decomposed[1] == 0x2032);
+
+ /* Triples */
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2026, decomposed) == 3 &&
+ decomposed[0] == 0x002E && decomposed[1] == 0x002E && decomposed[2] == 0x002E);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x2034, decomposed) == 3 &&
+ decomposed[0] == 0x2032 && decomposed[1] == 0x2032 && decomposed[2] == 0x2032);
+ g_assert (hb_unicode_decompose_compatibility (uf, 0x213B, decomposed) == 3 &&
+ decomposed[0] == 0x0046 && decomposed[1] == 0x0041 && decomposed[2] == 0x0058);
}
commit 321ec29cc270e7e66a529696b70b2caac553c95f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Jul 31 21:10:16 2012 -0400
Remove unused function
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index b384e0e..55eedab 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -428,13 +428,6 @@ override_features_indic (const hb_ot_complex_shaper_t *shaper,
}
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_indic (const hb_segment_properties_t *props)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
-
static void
setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
const hb_ot_map_t *map,
commit 69cc492dc120847ed00cae65ec958593ebf550c5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Jul 31 14:51:36 2012 -0400
[buffer] Minor
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index d6189d2..c96723a 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -141,9 +141,11 @@ struct hb_buffer_t {
HB_INTERNAL void swap_buffers (void);
HB_INTERNAL void clear_output (void);
HB_INTERNAL void clear_positions (void);
+
HB_INTERNAL void replace_glyphs (unsigned int num_in,
unsigned int num_out,
const hb_codepoint_t *glyph_data);
+
HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
/* Makes a copy of the glyph at idx to output and replace glyph_index */
HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
@@ -196,5 +198,4 @@ struct hb_buffer_t {
HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var)
-
#endif /* HB_BUFFER_PRIVATE_HH */
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index f8c62ac..b9623e8 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -134,6 +134,7 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
}
+
/* HarfBuzz-Internal API */
void
@@ -234,12 +235,13 @@ hb_buffer_t::swap_buffers (void)
idx = 0;
}
+
void
hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
const uint32_t *glyph_data)
{
- if (!make_room_for (num_in, num_out)) return;
+ if (unlikely (!make_room_for (num_in, num_out))) return;
merge_clusters (idx, idx + num_in);
@@ -259,7 +261,7 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
void
hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
{
- if (!make_room_for (0, 1)) return;
+ if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
out_info[out_len].codepoint = glyph_index;
@@ -270,7 +272,7 @@ hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
void
hb_buffer_t::copy_glyph (void)
{
- if (!make_room_for (0, 1)) return;
+ if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
@@ -280,9 +282,10 @@ hb_buffer_t::copy_glyph (void)
void
hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
{
- if (!make_room_for (1, 1)) return;
-
- out_info[out_len] = info[idx];
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
+ }
out_info[out_len].codepoint = glyph_index;
idx++;
@@ -294,20 +297,17 @@ hb_buffer_t::next_glyph (void)
{
if (have_output)
{
- if (out_info != info)
- {
- if (unlikely (!ensure (out_len + 1))) return;
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
}
- else if (out_len != idx)
- out_info[out_len] = info[idx];
-
out_len++;
}
idx++;
}
+
void
hb_buffer_t::set_masks (hb_mask_t value,
hb_mask_t mask,
commit 693918ef8541014a5ef7dfb91c6ea0ae36d9c368
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 21:08:51 2012 -0400
[OT] Streamline complex shaper enumeration
Add a shaper class struct.
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 1f63c12..0f73d6d 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -164,9 +164,10 @@ static const struct arabic_state_table_entry {
-void
-_hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
+static void
+collect_features_arabic (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props)
{
/* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
* then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
@@ -199,18 +200,6 @@ _hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map,
map->add_bool_feature (HB_TAG('c','s','w','h'));
}
-void
-_hb_ot_shape_complex_override_features_arabic (hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_arabic (const hb_segment_properties_t *props)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
static void
arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
@@ -246,10 +235,11 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
buffer->swap_buffers ();
}
-void
-_hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font)
+static void
+setup_masks_arabic (const hb_ot_complex_shaper_t *shaper,
+ const hb_ot_map_t *map,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
{
unsigned int count = buffer->len;
unsigned int prev = 0, state = 0;
@@ -302,4 +292,11 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map,
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
-
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
+{
+ "arabic",
+ collect_features_arabic,
+ NULL, /* override_features */
+ NULL, /* normalization_preference */
+ setup_masks_arabic,
+};
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index c7025ff..b384e0e 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -89,8 +89,11 @@ compare_codepoint (const void *pa, const void *pb)
}
static bool
-would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count,
- hb_tag_t feature_tag, hb_ot_map_t *map, hb_face_t *face)
+would_substitute (hb_codepoint_t *glyphs,
+ unsigned int glyphs_count,
+ hb_tag_t feature_tag,
+ const hb_ot_map_t *map,
+ hb_face_t *face)
{
unsigned int lookup_indices[32];
unsigned int offset, len;
@@ -115,7 +118,9 @@ would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count,
}
static indic_position_t
-consonant_position (hb_codepoint_t u, hb_ot_map_t *map, hb_font_t *font)
+consonant_position (hb_codepoint_t u,
+ const hb_ot_map_t *map,
+ hb_font_t *font)
{
if ((u & ~0x007F) == 0x1780)
return POS_BELOW_C; /* In Khmer coeng model, all are subjoining. */
@@ -232,7 +237,9 @@ is_halant_or_coeng (const hb_glyph_info_t &info)
}
static inline void
-set_indic_properties (hb_glyph_info_t &info, hb_ot_map_t *map, hb_font_t *font)
+set_indic_properties (hb_glyph_info_t &info,
+ const hb_ot_map_t *map,
+ hb_font_t *font)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = get_indic_categories (u);
@@ -387,9 +394,10 @@ final_reordering (const hb_ot_map_t *map,
hb_buffer_t *buffer,
void *user_data HB_UNUSED);
-void
-_hb_ot_shape_complex_collect_features_indic (hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props HB_UNUSED)
+static void
+collect_features_indic (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props)
{
map->add_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
@@ -409,9 +417,10 @@ _hb_ot_shape_complex_collect_features_indic (hb_ot_map_builder_t *map,
map->add_bool_feature (indic_other_features[i].tag, indic_other_features[i].is_global);
}
-void
-_hb_ot_shape_complex_override_features_indic (hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props HB_UNUSED)
+static void
+override_features_indic (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props)
{
/* Uniscribe does not apply 'kern'. */
if (indic_options ().uniscribe_bug_compatible)
@@ -426,10 +435,11 @@ _hb_ot_shape_complex_normalization_preference_indic (const hb_segment_properties
}
-void
-_hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font)
+static void
+setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
+ const hb_ot_map_t *map,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
{
HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
@@ -1235,4 +1245,11 @@ final_reordering (const hb_ot_map_t *map,
}
-
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
+{
+ "indic",
+ collect_features_indic,
+ override_features_indic,
+ NULL, /* normalization_preference */
+ setup_masks_indic,
+};
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index 4b9e6a6..1815366 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -49,9 +49,10 @@ static const hb_tag_t tibetan_features[] =
HB_TAG_NONE
};
-void
-_hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map HB_UNUSED,
- const hb_segment_properties_t *props)
+static void
+collect_features_default (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props)
{
const hb_tag_t *script_features = NULL;
@@ -72,14 +73,9 @@ _hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map HB_UNUSE
map->add_bool_feature (*script_features);
}
-void
-_hb_ot_shape_complex_override_features_default (hb_ot_map_builder_t *map HB_UNUSED,
- const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_default (const hb_segment_properties_t *props)
+static hb_ot_shape_normalization_mode_t
+normalization_preference_default (const hb_ot_complex_shaper_t *shaper,
+ const hb_segment_properties_t *props)
{
switch ((hb_tag_t) props->script)
{
@@ -90,39 +86,23 @@ _hb_ot_shape_complex_normalization_preference_default (const hb_segment_properti
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
}
-void
-_hb_ot_shape_complex_setup_masks_default (hb_ot_map_t *map HB_UNUSED,
- hb_buffer_t *buffer HB_UNUSED,
- hb_font_t *font HB_UNUSED)
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
{
-}
-
+ "default",
+ collect_features_default,
+ NULL, /* override_features */
+ normalization_preference_default,
+ NULL, /* setup_masks */
+};
/* Thai / Lao shaper */
-void
-_hb_ot_shape_complex_collect_features_thai (hb_ot_map_builder_t *map HB_UNUSED,
- const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-void
-_hb_ot_shape_complex_override_features_thai (hb_ot_map_builder_t *map HB_UNUSED,
- const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_thai (const hb_segment_properties_t *props HB_UNUSED)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
-void
-_hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
+static void
+setup_masks_thai (const hb_ot_complex_shaper_t *shaper,
+ const hb_ot_map_t *map,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
{
/* The following is NOT specified in the MS OT Thai spec, however, it seems
* to be what Uniscribe and other engines implement. According to Eric Muller:
@@ -213,3 +193,12 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
}
buffer->swap_buffers ();
}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+{
+ "thai",
+ NULL, /* collect_features */
+ NULL, /* override_features */
+ NULL, /* normalization_preference */
+ setup_masks_thai,
+};
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 689ca61..c0864fe 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -44,6 +44,8 @@
#define complex_var_temporary_u8() var2.u8[0]
+
+/* Master OT shaper list */
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
@@ -51,21 +53,60 @@
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
/* ^--- Add new shapers here */
-enum hb_ot_complex_shaper_t {
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) hb_ot_complex_shaper_##name,
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
- /* Just here to avoid enum trailing comma: */
- hb_ot_complex_shaper_generic = hb_ot_complex_shaper_default
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+struct hb_ot_complex_shaper_t
+{
+ char name[8];
+
+ /* collect_features()
+ * Called during shape_plan().
+ * Shapers should use map to add their features and callbacks.
+ * May be NULL.
+ */
+ void (*collect_features) (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props);
+
+ /* override_features()
+ * Called during shape_plan().
+ * Shapers should use map to override features and add callbacks after
+ * common features are added.
+ * May be NULL.
+ */
+ void (*override_features) (const hb_ot_complex_shaper_t *shaper,
+ hb_ot_map_builder_t *map,
+ const hb_segment_properties_t *props);
+
+ /* normalization_preference()
+ * Called during shape_execute().
+ */
+ hb_ot_shape_normalization_mode_t
+ (*normalization_preference) (const hb_ot_complex_shaper_t *shaper,
+ const hb_segment_properties_t *props);
+
+
+ /* setup_masks()
+ * Called during shape_execute().
+ * Shapers should use map to get feature masks and set on buffer.
+ */
+ void (*setup_masks) (const hb_ot_complex_shaper_t *shaper,
+ const hb_ot_map_t *map,
+ hb_buffer_t *buffer,
+ hb_font_t *font);
};
-static inline hb_ot_complex_shaper_t
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
+HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+
+static inline const hb_ot_complex_shaper_t *
hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
{
switch ((hb_tag_t) props->script)
{
default:
- return hb_ot_complex_shaper_default;
+ return &_hb_ot_complex_shaper_default;
/* Unicode-1.1 additions */
@@ -79,14 +120,14 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
/* Unicode-6.0 additions */
case HB_SCRIPT_MANDAIC:
- return hb_ot_complex_shaper_arabic;
+ return &_hb_ot_complex_shaper_arabic;
/* Unicode-1.1 additions */
case HB_SCRIPT_THAI:
case HB_SCRIPT_LAO:
- return hb_ot_complex_shaper_thai;
+ return &_hb_ot_complex_shaper_thai;
@@ -201,125 +242,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
case HB_SCRIPT_SHARADA:
case HB_SCRIPT_TAKRI:
- return hb_ot_complex_shaper_indic;
- }
-}
-
-
-
-/*
- * collect_features()
- *
- * Called during shape_plan().
- *
- * Shapers should use map to add their features and callbacks.
- */
-
-typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t *props);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_##name;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
-{
- switch (shaper) {
- default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- case hb_ot_complex_shaper_##name: _hb_ot_shape_complex_collect_features_##name (map, props); return;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
+ return &_hb_ot_complex_shaper_indic;
}
}
-/*
- * override_features()
- *
- * Called during shape_plan().
- *
- * Shapers should use map to override features and add callbacks after
- * common features are added.
- */
-
-typedef void hb_ot_shape_complex_override_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t *props);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- HB_INTERNAL hb_ot_shape_complex_override_features_func_t _hb_ot_shape_complex_override_features_##name;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_override_features (hb_ot_complex_shaper_t shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
-{
- switch (shaper) {
- default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- case hb_ot_complex_shaper_##name: _hb_ot_shape_complex_override_features_##name (map, props); return;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
- }
-}
-
-
-/*
- * normalization_preference()
- *
- * Called during shape_execute().
- */
-
-typedef hb_ot_shape_normalization_mode_t hb_ot_shape_complex_normalization_preference_func_t (const hb_segment_properties_t *props HB_UNUSED);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- HB_INTERNAL hb_ot_shape_complex_normalization_preference_func_t _hb_ot_shape_complex_normalization_preference_##name;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline hb_ot_shape_normalization_mode_t
-hb_ot_shape_complex_normalization_preference (hb_ot_complex_shaper_t shaper,
- const hb_segment_properties_t *props)
-{
- switch (shaper) {
- default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- case hb_ot_complex_shaper_##name: return _hb_ot_shape_complex_normalization_preference_##name (props);
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
- }
-}
-
-
-/* setup_masks()
- *
- * Called during shape_execute().
- *
- * Shapers should use map to get feature masks and set on buffer.
- */
-
-typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer, hb_font_t *font);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_##name;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
- hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font)
-{
- switch (shaper) {
- default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
- case hb_ot_complex_shaper_##name: _hb_ot_shape_complex_setup_masks_##name (map, buffer, font); return;
- HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
- }
-}
-
-
-
#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
diff --git a/src/hb-ot-shape-normalize-private.hh b/src/hb-ot-shape-normalize-private.hh
index bb81f00..4c89a8f 100644
--- a/src/hb-ot-shape-normalize-private.hh
+++ b/src/hb-ot-shape-normalize-private.hh
@@ -36,7 +36,9 @@
enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL /* including base-to-base composition */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL, /* including base-to-base composition */
+
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS,
};
HB_INTERNAL void _hb_ot_shape_normalize (hb_font_t *font,
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index e1f6a69..30c7808 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -36,7 +36,7 @@
struct hb_ot_shape_plan_t
{
hb_ot_map_t map;
- hb_ot_complex_shaper_t shaper;
+ const hb_ot_complex_shaper_t *shaper;
};
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0cd548f..8df8251 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -73,7 +73,7 @@ hb_tag_t vertical_features[] = {
struct hb_ot_shape_planner_t
{
hb_ot_map_builder_t map;
- hb_ot_complex_shaper_t shaper;
+ const hb_ot_complex_shaper_t *shaper;
hb_ot_shape_planner_t (void) : map () {}
~hb_ot_shape_planner_t (void) { map.finish (); }
@@ -118,7 +118,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
planner->map.add_bool_feature (array[i]); \
} HB_STMT_END
- hb_ot_shape_complex_collect_features (planner->shaper, &planner->map, props);
+ if (planner->shaper->collect_features)
+ planner->shaper->collect_features (planner->shaper, &planner->map, props);
ADD_FEATURES (common_features);
@@ -127,7 +128,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
else
ADD_FEATURES (vertical_features);
- hb_ot_shape_complex_override_features (planner->shaper, &planner->map, props);
+ if (planner->shaper->override_features)
+ planner->shaper->override_features (planner->shaper, &planner->map, props);
#undef ADD_FEATURES
@@ -233,7 +235,8 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
hb_mask_t global_mask = c->plan->map.get_global_mask ();
c->buffer->reset_masks (global_mask);
- hb_ot_shape_complex_setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c->font);
+ if (c->plan->shaper->setup_masks)
+ c->plan->shaper->setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c->font);
for (unsigned int i = 0; i < c->num_user_features; i++)
{
@@ -493,8 +496,9 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ensure_native_direction (c->buffer);
_hb_ot_shape_normalize (c->font, c->buffer,
- hb_ot_shape_complex_normalization_preference (c->plan->shaper,
- &c->buffer->props));
+ c->plan->shaper->normalization_preference ?
+ c->plan->shaper->normalization_preference (c->plan->shaper, &c->buffer->props) :
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
hb_ot_shape_setup_masks (c);
commit c2e42c3db691515f3a458eb4c71fe1e6439d5620
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 19:54:50 2012 -0400
Minor
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 53f2354..339749e 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1671,7 +1671,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
}
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 328090a..05caee9 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1311,7 +1311,7 @@ struct GSUB : GSUBGPOS
void
GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer)
{
- HB_BUFFER_ALLOCATE_VAR (buffer, props_cache);
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
@@ -1319,7 +1319,7 @@ GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer)
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++) {
buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
- buffer->info[i].props_cache() = gdef.get_glyph_props (buffer->info[i].codepoint);
+ buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint);
}
}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index b49cb6c..1f20514 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -271,7 +271,7 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info->props_cache();
+ property = info->glyph_props();
*property_out = property;
return match_properties (info->codepoint, property, lookup_props);
@@ -284,7 +284,7 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info->props_cache();
+ property = info->glyph_props();
if (property_out)
*property_out = property;
@@ -305,9 +305,9 @@ struct hb_apply_context_t
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
{
if (likely (has_glyph_classes))
- buffer->cur().props_cache() = gdef.get_glyph_props (glyph_index);
+ buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
else if (class_guess)
- buffer->cur().props_cache() = class_guess;
+ buffer->cur().glyph_props() = class_guess;
}
inline void output_glyph (hb_codepoint_t glyph_index,
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 3da3dfe..fdbeb5b 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -38,7 +38,7 @@
/* buffer var allocations, used during the GSUB/GPOS processing */
-#define props_cache() var1.u16[1] /* GSUB/GPOS glyph_props cache */
+#define glyph_props() var1.u16[1] /* GDEF glyph properties */
#define syllable() var2.u8[0] /* GSUB/GPOS shaping boundaries */
#define lig_props() var2.u8[1] /* GSUB/GPOS ligature tracking */
@@ -122,7 +122,7 @@ get_lig_comp (const hb_glyph_info_t &info)
static inline unsigned int
get_lig_num_comps (const hb_glyph_info_t &info)
{
- if ((info.props_cache() & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE) && is_a_ligature (info))
+ if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE) && is_a_ligature (info))
return info.lig_props() & 0x0F;
else
return 1;
commit 03f67bc012f42131b36083a23efc78e1b04b828c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 19:47:53 2012 -0400
More refactoring glyph class access
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 61c5697..53f2354 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1515,7 +1515,7 @@ struct PosLookup : Lookup
{
unsigned int lookup_type = get_type ();
- if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->lookup_props, &c->property))
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
return false;
unsigned int count = get_subtable_count ();
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index d62d97a..328090a 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1179,7 +1179,7 @@ struct SubstLookup : Lookup
{
unsigned int lookup_type = get_type ();
- if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->lookup_props, &c->property))
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
return false;
unsigned int count = get_subtable_count ();
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 4324d6d..b49cb6c 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -96,82 +96,6 @@ struct hb_would_apply_context_t
hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
-
-static inline hb_bool_t
-_hb_ot_layout_match_properties_mark (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int glyph_props,
- unsigned int lookup_props)
-{
- /* If using mark filtering sets, the high short of
- * lookup_props has the set index.
- */
- if (lookup_props & LookupFlag::UseMarkFilteringSet)
- return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
-
- /* The second byte of lookup_props has the meaning
- * "ignore marks of attachment type different than
- * the attachment type specified."
- */
- if (lookup_props & LookupFlag::MarkAttachmentType)
- return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
-
- return true;
-}
-
-static inline hb_bool_t
-_hb_ot_layout_match_properties (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int glyph_props,
- unsigned int lookup_props)
-{
- /* Not covered, if, for example, glyph class is ligature and
- * lookup_props includes LookupFlags::IgnoreLigatures
- */
- if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
- return false;
-
- if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
- return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
-
- return true;
-}
-
-static inline hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = ginfo->props_cache();
- *property_out = property;
-
- return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-}
-
-static inline hb_bool_t
-_hb_ot_layout_skip_mark (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = ginfo->props_cache();
- if (property_out)
- *property_out = property;
-
- /* If it's a mark, skip it if we don't accept it. */
- if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
- return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-
- /* If not a mark, don't skip. */
- return false;
-}
-
-
struct hb_apply_context_t
{
hb_font_t *font;
@@ -236,7 +160,7 @@ struct hb_apply_context_t
if (has_no_chance ())
return false;
idx++;
- } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[idx], lookup_props, property_out));
+ } while (c->should_skip_mark (&c->buffer->info[idx], lookup_props, property_out));
num_items--;
return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ());
}
@@ -285,7 +209,7 @@ struct hb_apply_context_t
if (has_no_chance ())
return false;
idx--;
- } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[idx], lookup_props, property_out));
+ } while (c->should_skip_mark (&c->buffer->out_info[idx], lookup_props, property_out));
num_items--;
return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
}
@@ -302,10 +226,80 @@ struct hb_apply_context_t
uint8_t syllable;
};
- inline bool should_mark_skip_current_glyph (void) const
+ inline bool
+ match_properties_mark (hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props) const
+ {
+ /* If using mark filtering sets, the high short of
+ * lookup_props has the set index.
+ */
+ if (lookup_props & LookupFlag::UseMarkFilteringSet)
+ return gdef.mark_set_covers (lookup_props >> 16, glyph);
+
+ /* The second byte of lookup_props has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ if (lookup_props & LookupFlag::MarkAttachmentType)
+ return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+ return true;
+ }
+
+ inline bool
+ match_properties (hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props) const
+ {
+ /* Not covered, if, for example, glyph class is ligature and
+ * lookup_props includes LookupFlags::IgnoreLigatures
+ */
+ if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
+ return false;
+
+ if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ return match_properties_mark (glyph, glyph_props, lookup_props);
+
+ return true;
+ }
+
+ inline bool
+ check_glyph_property (hb_glyph_info_t *info,
+ unsigned int lookup_props,
+ unsigned int *property_out) const
{
unsigned int property;
- return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, &property);
+
+ property = info->props_cache();
+ *property_out = property;
+
+ return match_properties (info->codepoint, property, lookup_props);
+ }
+
+ inline bool
+ should_skip_mark (hb_glyph_info_t *info,
+ unsigned int lookup_props,
+ unsigned int *property_out) const
+ {
+ unsigned int property;
+
+ property = info->props_cache();
+ if (property_out)
+ *property_out = property;
+
+ /* If it's a mark, skip it if we don't accept it. */
+ if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ return !match_properties (info->codepoint, property, lookup_props);
+
+ /* If not a mark, don't skip. */
+ return false;
+ }
+
+
+ inline bool should_mark_skip_current_glyph (void) const
+ {
+ return should_skip_mark (&buffer->cur(), lookup_props, NULL);
}
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
commit 300c7307eb7943ba7416b672345506be1e27c6ba
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 19:37:44 2012 -0400
[OT] Don't crash if no GDEF available
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 00c64d5..4324d6d 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -183,8 +183,8 @@ struct hb_apply_context_t
unsigned int lookup_props;
unsigned int property; /* propety of first glyph */
unsigned int debug_depth;
- bool has_glyph_classes;
const GDEF &gdef;
+ bool has_glyph_classes;
hb_apply_context_t (hb_font_t *font_,
@@ -196,8 +196,10 @@ struct hb_apply_context_t
lookup_mask (lookup_mask_),
nesting_level_left (MAX_NESTING_LEVEL),
lookup_props (0), property (0), debug_depth (0),
- has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)),
- gdef (*hb_ot_layout_from_face (face_)->gdef /* XXX Unsafe dereference */) {}
+ gdef (hb_ot_layout_from_face (face_) &&
+ !HB_SHAPER_DATA_IS_INVALID (hb_ot_layout_from_face (face_)) ?
+ *hb_ot_layout_from_face (face_)->gdef : Null(GDEF)),
+ has_glyph_classes (gdef.has_glyph_classes ()) {}
void set_lookup (const Lookup &l) {
lookup_props = l.get_props ();
commit 3dcbdc2125c04c173f29f04922fc031929893f4e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 19:31:17 2012 -0400
Minor
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 1e57874..28c2f83 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -42,17 +42,12 @@
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
-static hb_bool_t
-hb_ot_layout_ensure (hb_face_t *face)
-{
- return hb_ot_shaper_face_data_ensure (face);
-}
-
-
hb_ot_layout_t *
_hb_ot_layout_create (hb_face_t *face)
{
hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+ if (unlikely (!layout))
+ return NULL;
layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GDEF));
layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
@@ -79,19 +74,19 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
static inline const GDEF&
_get_gdef (hb_face_t *face)
{
- if (unlikely (!hb_ot_layout_ensure (face))) return Null(GDEF);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(GDEF);
return *hb_ot_layout_from_face (face)->gdef;
}
static inline const GSUB&
_get_gsub (hb_face_t *face)
{
- if (unlikely (!hb_ot_layout_ensure (face))) return Null(GSUB);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(GSUB);
return *hb_ot_layout_from_face (face)->gsub;
}
static inline const GPOS&
_get_gpos (hb_face_t *face)
{
- if (unlikely (!hb_ot_layout_ensure (face))) return Null(GPOS);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(GPOS);
return *hb_ot_layout_from_face (face)->gpos;
}
commit 05bd1b63426e07d1df7a1b40bf845dc94ab995a8
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 19:30:01 2012 -0400
[GSUB/GPOS] Move glyph props matching around
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 5945b0f..61c5697 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1552,7 +1552,8 @@ struct PosLookup : Lookup
else
while (c->buffer->idx < c->buffer->len)
{
- if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c))
+ if ((c->buffer->cur().mask & c->lookup_mask) &&
+ apply_once (c))
ret = true;
else
c->buffer->idx++;
@@ -1585,8 +1586,8 @@ struct GPOS : GSUBGPOS
inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
{ return get_lookup (lookup_index).apply_string (c); }
- static inline void position_start (hb_buffer_t *buffer);
- static inline void position_finish (hb_buffer_t *buffer);
+ static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
@@ -1644,7 +1645,7 @@ fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di
}
void
-GPOS::position_start (hb_buffer_t *buffer)
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
{
buffer->clear_positions ();
@@ -1654,7 +1655,7 @@ GPOS::position_start (hb_buffer_t *buffer)
}
void
-GPOS::position_finish (hb_buffer_t *buffer)
+GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
{
unsigned int len;
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 6a292a1..d62d97a 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1220,7 +1220,8 @@ struct SubstLookup : Lookup
else
while (c->buffer->idx < c->buffer->len)
{
- if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c))
+ if ((c->buffer->cur().mask & c->lookup_mask) &&
+ apply_once (c))
ret = true;
else
c->buffer->next_glyph ();
@@ -1289,8 +1290,8 @@ struct GSUB : GSUBGPOS
inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
{ return get_lookup (lookup_index).apply_string (c); }
- static inline void substitute_start (hb_buffer_t *buffer);
- static inline void substitute_finish (hb_buffer_t *buffer);
+ static inline void substitute_start (hb_face_t *face, hb_buffer_t *buffer);
+ static inline void substitute_finish (hb_face_t *face, hb_buffer_t *buffer);
inline void closure_lookup (hb_closure_context_t *c,
unsigned int lookup_index) const
@@ -1308,19 +1309,22 @@ struct GSUB : GSUBGPOS
void
-GSUB::substitute_start (hb_buffer_t *buffer)
+GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer)
{
HB_BUFFER_ALLOCATE_VAR (buffer, props_cache);
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+ const GDEF &gdef = *hb_ot_layout_from_face (face)->gdef;
unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- buffer->info[i].props_cache() = buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
+ for (unsigned int i = 0; i < count; i++) {
+ buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
+ buffer->info[i].props_cache() = gdef.get_glyph_props (buffer->info[i].codepoint);
+ }
}
void
-GSUB::substitute_finish (hb_buffer_t *buffer HB_UNUSED)
+GSUB::substitute_finish (hb_face_t *face HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
{
}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 61dea3a..00c64d5 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -97,6 +97,81 @@ struct hb_would_apply_context_t
+static inline hb_bool_t
+_hb_ot_layout_match_properties_mark (hb_face_t *face,
+ hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props)
+{
+ /* If using mark filtering sets, the high short of
+ * lookup_props has the set index.
+ */
+ if (lookup_props & LookupFlag::UseMarkFilteringSet)
+ return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
+
+ /* The second byte of lookup_props has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ if (lookup_props & LookupFlag::MarkAttachmentType)
+ return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+ return true;
+}
+
+static inline hb_bool_t
+_hb_ot_layout_match_properties (hb_face_t *face,
+ hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props)
+{
+ /* Not covered, if, for example, glyph class is ligature and
+ * lookup_props includes LookupFlags::IgnoreLigatures
+ */
+ if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
+ return false;
+
+ if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
+
+ return true;
+}
+
+static inline hb_bool_t
+_hb_ot_layout_check_glyph_property (hb_face_t *face,
+ hb_glyph_info_t *ginfo,
+ unsigned int lookup_props,
+ unsigned int *property_out)
+{
+ unsigned int property;
+
+ property = ginfo->props_cache();
+ *property_out = property;
+
+ return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
+}
+
+static inline hb_bool_t
+_hb_ot_layout_skip_mark (hb_face_t *face,
+ hb_glyph_info_t *ginfo,
+ unsigned int lookup_props,
+ unsigned int *property_out)
+{
+ unsigned int property;
+
+ property = ginfo->props_cache();
+ if (property_out)
+ *property_out = property;
+
+ /* If it's a mark, skip it if we don't accept it. */
+ if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
+
+ /* If not a mark, don't skip. */
+ return false;
+}
+
+
struct hb_apply_context_t
{
hb_font_t *font;
@@ -109,6 +184,7 @@ struct hb_apply_context_t
unsigned int property; /* propety of first glyph */
unsigned int debug_depth;
bool has_glyph_classes;
+ const GDEF &gdef;
hb_apply_context_t (hb_font_t *font_,
@@ -120,7 +196,8 @@ struct hb_apply_context_t
lookup_mask (lookup_mask_),
nesting_level_left (MAX_NESTING_LEVEL),
lookup_props (0), property (0), debug_depth (0),
- has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)) {}
+ has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)),
+ gdef (*hb_ot_layout_from_face (face_)->gdef /* XXX Unsafe dereference */) {}
void set_lookup (const Lookup &l) {
lookup_props = l.get_props ();
@@ -229,30 +306,30 @@ struct hb_apply_context_t
return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, &property);
}
- inline void set_klass_guess (unsigned int klass_guess) const
+ inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
{
if (likely (has_glyph_classes))
- buffer->cur().props_cache() = 0;
- else if (klass_guess)
- buffer->cur().props_cache() = klass_guess;
+ buffer->cur().props_cache() = gdef.get_glyph_props (glyph_index);
+ else if (class_guess)
+ buffer->cur().props_cache() = class_guess;
}
inline void output_glyph (hb_codepoint_t glyph_index,
- unsigned int klass_guess = 0) const
+ unsigned int class_guess = 0) const
{
- set_klass_guess (klass_guess);
+ set_class (glyph_index, class_guess);
buffer->output_glyph (glyph_index);
}
inline void replace_glyph (hb_codepoint_t glyph_index,
- unsigned int klass_guess = 0) const
+ unsigned int class_guess = 0) const
{
- set_klass_guess (klass_guess);
+ set_class (glyph_index, class_guess);
buffer->replace_glyph (glyph_index);
}
inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
- unsigned int klass_guess = 0) const
+ unsigned int class_guess = 0) const
{
- set_klass_guess (klass_guess);
+ set_class (glyph_index, class_guess);
buffer->cur().codepoint = glyph_index;
}
};
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 78c9d64..3da3dfe 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -57,18 +57,6 @@ typedef enum {
} hb_ot_layout_glyph_class_t;
-HB_INTERNAL hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out);
-
-HB_INTERNAL hb_bool_t
-_hb_ot_layout_skip_mark (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out);
-
/*
* GSUB/GPOS
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 2530340..1e57874 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -106,93 +106,6 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
return _get_gdef (face).has_glyph_classes ();
}
-static inline unsigned int
-_hb_ot_layout_get_glyph_property (hb_face_t *face,
- hb_glyph_info_t *info)
-{
- if (!info->props_cache())
- {
- info->props_cache() = hb_ot_layout_from_face (face)->gdef->get_glyph_props (info->codepoint);
- }
-
- return info->props_cache();
-}
-
-static inline hb_bool_t
-_hb_ot_layout_match_properties_mark (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int glyph_props,
- unsigned int lookup_props)
-{
- /* If using mark filtering sets, the high short of
- * lookup_props has the set index.
- */
- if (lookup_props & LookupFlag::UseMarkFilteringSet)
- return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
-
- /* The second byte of lookup_props has the meaning
- * "ignore marks of attachment type different than
- * the attachment type specified."
- */
- if (lookup_props & LookupFlag::MarkAttachmentType)
- return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
-
- return true;
-}
-
-static inline hb_bool_t
-_hb_ot_layout_match_properties (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int glyph_props,
- unsigned int lookup_props)
-{
- /* Not covered, if, for example, glyph class is ligature and
- * lookup_props includes LookupFlags::IgnoreLigatures
- */
- if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
- return false;
-
- if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
- return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
-
- return true;
-}
-
-hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = _hb_ot_layout_get_glyph_property (face, ginfo);
- *property_out = property;
-
- return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-}
-
-hb_bool_t
-_hb_ot_layout_skip_mark (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = _hb_ot_layout_get_glyph_property (face, ginfo);
- if (property_out)
- *property_out = property;
-
- /* If it's a mark, skip it if we don't accept it. */
- if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
- return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-
- /* If not a mark, don't skip. */
- return false;
-}
-
-
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
@@ -215,6 +128,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
}
+
/*
* GSUB/GPOS
*/
@@ -492,9 +406,9 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
}
void
-hb_ot_layout_substitute_start (hb_buffer_t *buffer)
+hb_ot_layout_substitute_start (hb_face_t *face, hb_buffer_t *buffer)
{
- GSUB::substitute_start (buffer);
+ GSUB::substitute_start (face, buffer);
}
hb_bool_t
@@ -518,9 +432,9 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face,
}
void
-hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
+hb_ot_layout_substitute_finish (hb_face_t *face, hb_buffer_t *buffer)
{
- GSUB::substitute_finish (buffer);
+ GSUB::substitute_finish (face, buffer);
}
void
@@ -543,9 +457,9 @@ hb_ot_layout_has_positioning (hb_face_t *face)
}
void
-hb_ot_layout_position_start (hb_buffer_t *buffer)
+hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_start (buffer);
+ GPOS::position_start (font, buffer);
}
hb_bool_t
@@ -569,9 +483,9 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font,
}
void
-hb_ot_layout_position_finish (hb_buffer_t *buffer)
+hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_finish (buffer);
+ GPOS::position_finish (font, buffer);
}
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 07e062f..4e205d7 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -178,7 +178,8 @@ hb_ot_layout_would_substitute_lookup (hb_face_t *face,
/* Should be called before all the substitute_lookup's are done. */
void
-hb_ot_layout_substitute_start (hb_buffer_t *buffer);
+hb_ot_layout_substitute_start (hb_face_t *face,
+ hb_buffer_t *buffer);
hb_bool_t
hb_ot_layout_substitute_lookup (hb_face_t *face,
@@ -188,7 +189,8 @@ hb_ot_layout_substitute_lookup (hb_face_t *face,
/* Should be called after all the substitute_lookup's are done */
void
-hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
+hb_ot_layout_substitute_finish (hb_face_t *face,
+ hb_buffer_t *buffer);
void
@@ -205,7 +207,8 @@ hb_ot_layout_has_positioning (hb_face_t *face);
/* Should be called before all the position_lookup's are done. Resets positions to zero. */
void
-hb_ot_layout_position_start (hb_buffer_t *buffer);
+hb_ot_layout_position_start (hb_font_t *font,
+ hb_buffer_t *buffer);
hb_bool_t
hb_ot_layout_position_lookup (hb_font_t *font,
@@ -215,7 +218,8 @@ hb_ot_layout_position_lookup (hb_font_t *font,
/* Should be called after all the position_lookup's are done */
void
-hb_ot_layout_position_finish (hb_buffer_t *buffer);
+hb_ot_layout_position_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
HB_END_DECLS
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index c727fa6..0cd548f 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -342,8 +342,6 @@ hb_map_glyphs (hb_font_t *font,
static void
hb_substitute_default (hb_ot_shape_context_t *c)
{
- hb_ot_layout_substitute_start (c->buffer);
-
hb_mirror_chars (c);
hb_map_glyphs (c->font, c->buffer);
@@ -352,11 +350,13 @@ hb_substitute_default (hb_ot_shape_context_t *c)
static void
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
{
+ hb_ot_layout_substitute_start (c->face, c->buffer);
+
if (hb_ot_layout_has_substitution (c->face)) {
c->plan->map.substitute (c->face, c->buffer);
}
- hb_ot_layout_substitute_finish (c->buffer);
+ hb_ot_layout_substitute_finish (c->face, c->buffer);
return;
}
@@ -367,7 +367,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
static void
hb_position_default (hb_ot_shape_context_t *c)
{
- hb_ot_layout_position_start (c->buffer);
+ hb_ot_layout_position_start (c->font, c->buffer);
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) {
@@ -410,7 +410,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
c->applied_position_complex = true;
}
- hb_ot_layout_position_finish (c->buffer);
+ hb_ot_layout_position_finish (c->font, c->buffer);
return;
}
commit 2fca1426ca06cabbe8f027f2dc9dee9c27560c76
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 18:46:41 2012 -0400
[GSUB] Don't erase glyph classes if GDEF does not have glyph classes
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index e2423bc..61dea3a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -231,7 +231,10 @@ struct hb_apply_context_t
inline void set_klass_guess (unsigned int klass_guess) const
{
- buffer->cur().props_cache() = has_glyph_classes ? 0 : klass_guess;
+ if (likely (has_glyph_classes))
+ buffer->cur().props_cache() = 0;
+ else if (klass_guess)
+ buffer->cur().props_cache() = klass_guess;
}
inline void output_glyph (hb_codepoint_t glyph_index,
commit fd42257f8c45ff8e036e1c3eb1a788a101be7ead
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 18:40:27 2012 -0400
Minor
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 617034b..2530340 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -95,24 +95,6 @@ _get_gpos (hb_face_t *face)
return *hb_ot_layout_from_face (face)->gpos;
}
-static inline const GDEF&
-_get_gdef_fast (hb_face_t *face)
-{
- return *hb_ot_layout_from_face (face)->gdef;
-}
-static inline const GSUB&
-_get_gsub_fast (hb_face_t *face)
-{
- if (unlikely (!hb_ot_layout_ensure (face))) return Null(GSUB);
- return *hb_ot_layout_from_face (face)->gsub;
-}
-static inline const GPOS&
-_get_gpos_fast (hb_face_t *face)
-{
- if (unlikely (!hb_ot_layout_ensure (face))) return Null(GPOS);
- return *hb_ot_layout_from_face (face)->gpos;
-}
-
/*
* GDEF
@@ -130,8 +112,7 @@ _hb_ot_layout_get_glyph_property (hb_face_t *face,
{
if (!info->props_cache())
{
- const GDEF &gdef = _get_gdef_fast (face);
- info->props_cache() = gdef.get_glyph_props (info->codepoint);
+ info->props_cache() = hb_ot_layout_from_face (face)->gdef->get_glyph_props (info->codepoint);
}
return info->props_cache();
@@ -147,7 +128,7 @@ _hb_ot_layout_match_properties_mark (hb_face_t *face,
* lookup_props has the set index.
*/
if (lookup_props & LookupFlag::UseMarkFilteringSet)
- return _get_gdef_fast (face).mark_set_covers (lookup_props >> 16, glyph);
+ return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
/* The second byte of lookup_props has the meaning
* "ignore marks of attachment type different than
@@ -507,7 +488,7 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
{
if (unlikely (glyphs_length < 1 || glyphs_length > 2)) return false;
hb_would_apply_context_t c (face, glyphs[0], glyphs_length == 2 ? glyphs[1] : -1);
- return _get_gsub_fast (face).would_substitute_lookup (&c, lookup_index);
+ return hb_ot_layout_from_face (face)->gsub->would_substitute_lookup (&c, lookup_index);
}
void
@@ -533,7 +514,7 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face,
hb_mask_t mask)
{
hb_apply_context_t c (NULL, face, buffer, mask);
- return _get_gsub_fast (face).substitute_lookup (&c, lookup_index);
+ return hb_ot_layout_from_face (face)->gsub->substitute_lookup (&c, lookup_index);
}
void
@@ -584,7 +565,7 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font,
hb_mask_t mask)
{
hb_apply_context_t c (font, font->face, buffer, mask);
- return _get_gpos_fast (font->face).position_lookup (&c, lookup_index);
+ return hb_ot_layout_from_face (font->face)->gpos->position_lookup (&c, lookup_index);
}
void
commit 7fbbf86efe675e4c038dfc5985c24bbc544620cd
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jul 30 18:36:42 2012 -0400
[GSUB] Minor
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index bdc7b38..6a292a1 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -920,7 +920,7 @@ struct ReverseChainSingleSubstFormat1
match_coverage, this,
1))
{
- c->buffer->cur().codepoint = substitute[index];
+ c->replace_glyph_inplace (substitute[index]);
c->buffer->idx--; /* Reverse! */
return TRACE_RETURN (true);
}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 6dc2f16..e2423bc 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -246,6 +246,12 @@ struct hb_apply_context_t
set_klass_guess (klass_guess);
buffer->replace_glyph (glyph_index);
}
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
+ unsigned int klass_guess = 0) const
+ {
+ set_klass_guess (klass_guess);
+ buffer->cur().codepoint = glyph_index;
+ }
};
More information about the HarfBuzz
mailing list