[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
TODO |4 + src/hb-ot-shape-complex-arabic.cc | 110 + src/hb-ot-shape-complex-indic.cc |1 src/hb-ot-shape-complex-misc.cc| 12 ++-- src/hb-ot-shape-complex-private.hh | 15 - src/hb-ot-shape-fallback.cc| 22 ++- src/hb-ot-shape.cc |3 + 7 files changed, 123 insertions(+), 44 deletions(-) New commits: commit 9f9f04c2229227bb0712166e824157bbbf5cef80 Author: Behdad Esfahbod beh...@behdad.org Date: Sat Aug 11 18:34:13 2012 -0400 [OT] Unbreak Thai shaping and fallback Arabic shaping The merger of normalizer and glyph-mapping broke shapers that modified text stream. Unbreak them by adding a new preprocess_text shaping stage that happens before normalizing/cmap and disallow setup_mask modification of actual text. diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index e0db41c..e1a2791 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -274,12 +274,8 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer) } static void -setup_masks_arabic (const hb_ot_shape_plan_t *plan, - hb_buffer_t *buffer, - hb_font_t*font) +arabic_joining (hb_buffer_t *buffer) { - const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan-data; - unsigned int count = buffer-len; unsigned int prev = 0, state = 0; @@ -305,14 +301,37 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, state = entry-next_state; } - if (likely (!arabic_plan-do_fallback)) { -/* Has OpenType tables */ -for (unsigned int i = 0; i count; i++) - buffer-info[i].mask |= arabic_plan-mask_array[buffer-info[i].arabic_shaping_action()]; - } else + HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +} + +static void +preprocess_text_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t*font) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan-data; + + if (unlikely (arabic_plan-do_fallback)) + { +arabic_joining (buffer); arabic_fallback_shape (font, buffer); + } +} - HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +static void +setup_masks_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t*font) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan-data; + + if (likely (!arabic_plan-do_fallback)) + { +arabic_joining (buffer); +unsigned int count = buffer-len; +for (unsigned int i = 0; i count; i++) + buffer-info[i].mask |= arabic_plan-mask_array[buffer-info[i].arabic_shaping_action()]; + } } const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = @@ -322,6 +341,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = NULL, /* override_features */ data_create_arabic, data_destroy_arabic, + preprocess_text_arabic, NULL, /* normalization_preference */ setup_masks_arabic, true, /* zero_width_attached_marks */ diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 4f9a5af..6fbd5c8 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1134,6 +1134,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = override_features_indic, data_create_indic, data_destroy_indic, + NULL, /* preprocess_text */ NULL, /* normalization_preference */ setup_masks_indic, false, /* zero_width_attached_marks */ diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc index 4f1dd5b..13bc22b 100644 --- a/src/hb-ot-shape-complex-misc.cc +++ b/src/hb-ot-shape-complex-misc.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Google, Inc. + * Copyright © 2010,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -90,6 +90,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = NULL, /* override_features */ NULL, /* data_create */ NULL, /* data_destroy */ + NULL, /* preprocess_text */ normalization_preference_default, NULL, /* setup_masks */ true, /* zero_width_attached_marks */ @@ -99,9 +100,9 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = /* Thai / Lao shaper */ static void -setup_masks_thai (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_buffer_t *buffer, - hb_font_t*font HB_UNUSED) +preprocess_text_thai (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t*font HB_UNUSED) { /* The following is NOT specified in the MS OT Thai spec, however, it seems * to be what Uniscribe and
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/hb-ot-layout-gpos-table.hh |2 src/hb-ot-layout-gsub-table.hh |5 - src/hb-ot-layout-gsubgpos-private.hh | 10 +- src/hb-ot-layout-private.hh |3 src/hb-ot-layout.cc | 34 +++ src/hb-ot-map-private.hh | 85 +++-- src/hb-ot-map.cc | 18 +-- src/hb-ot-shape-complex-indic-private.hh | 16 --- src/hb-ot-shape-complex-indic.cc | 149 ++- 9 files changed, 184 insertions(+), 138 deletions(-) New commits: commit 610e5e8f713bb2a68939b72cb2b801a7aaede4f9 Author: Behdad Esfahbod beh...@behdad.org Date: Thu Aug 2 05:27:46 2012 -0400 [Indic] Streamline feature would_apply() Comes with some 10% speedup for Devanagari even! diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 2ba0f76..5e3c967 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -42,6 +42,38 @@ struct hb_ot_map_t public: + struct feature_map_t { +hb_tag_t tag; /* should be first for our bsearch to work */ +unsigned int index[2]; /* GSUB/GPOS */ +unsigned int stage[2]; /* GSUB/GPOS */ +unsigned int shift; +hb_mask_t mask; +hb_mask_t _1_mask; /* mask for value=1, for quick access */ + +static int cmp (const feature_map_t *a, const feature_map_t *b) +{ return a-tag b-tag ? -1 : a-tag b-tag ? 1 : 0; } + }; + + struct lookup_map_t { +unsigned int index; +hb_mask_t mask; + +static int cmp (const lookup_map_t *a, const lookup_map_t *b) +{ return a-index b-index ? -1 : a-index b-index ? 1 : 0; } + }; + + typedef void (*pause_func_t) (const hb_ot_map_t *map, void *face_or_font, hb_buffer_t *buffer, void *user_data); + typedef struct { +pause_func_t func; +void *user_data; + } pause_callback_t; + + struct pause_map_t { +unsigned int num_lookups; /* Cumulative */ +pause_callback_t callback; + }; + + hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); } typedef void (*gsub_pause_func_t) (const hb_ot_map_t *map, hb_face_t *face, hb_buffer_t *buffer, void *user_data); @@ -60,11 +92,30 @@ struct hb_ot_map_t return map ? map-_1_mask : 0; } - inline hb_mask_t get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const { + inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const { const feature_map_t *map = features.bsearch (feature_tag); return map ? map-index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX; } + inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const { +const feature_map_t *map = features.bsearch (feature_tag); +return map ? map-stage[table_index] : (unsigned int) -1; + } + + inline void get_stage_lookups (unsigned int table_index, unsigned int stage, +const struct lookup_map_t **plookups, unsigned int *lookup_count) const { +if (unlikely (stage == (unsigned int) -1)) { + *plookups = NULL; + *lookup_count = 0; + return; +} +assert (stage = pauses[table_index].len); +unsigned int start = stage ? pauses[table_index][stage - 1].num_lookups : 0; +unsigned int end = stage pauses[table_index].len ? pauses[table_index][stage].num_lookups : lookups[table_index].len; +*plookups = lookups[table_index][start]; +*lookup_count = end - start; + } + inline hb_tag_t get_chosen_script (unsigned int table_index) const { return chosen_script[table_index]; } @@ -80,38 +131,8 @@ struct hb_ot_map_t pauses[1].finish (); } - private: - - struct feature_map_t { -hb_tag_t tag; /* should be first for our bsearch to work */ -unsigned int index[2]; /* GSUB/GPOS */ -unsigned int stage[2]; /* GSUB/GPOS */ -unsigned int shift; -hb_mask_t mask; -hb_mask_t _1_mask; /* mask for value=1, for quick access */ - -static int cmp (const feature_map_t *a, const feature_map_t *b) -{ return a-tag b-tag ? -1 : a-tag b-tag ? 1 : 0; } - }; - - struct lookup_map_t { -unsigned int index; -hb_mask_t mask; - -static int cmp (const lookup_map_t *a, const lookup_map_t *b) -{ return a-index b-index ? -1 : a-index b-index ? 1 : 0; } - }; - typedef void (*pause_func_t) (const hb_ot_map_t *map, void *face_or_font, hb_buffer_t *buffer, void *user_data); - typedef struct { -pause_func_t func; -void *user_data; - } pause_callback_t; - - struct pause_map_t { -unsigned int num_lookups; /* Cumulative */ -pause_callback_t callback; - }; + private: HB_INTERNAL void add_lookups (hb_face_t*face, unsigned int table_index, diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 20e8e6f..ae0cb61 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -89,7 +89,8 @@ void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t *buffer) const
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/hb-old.cc | 12 +- src/hb-ot-layout-gsub-table.hh | 18 +++--- src/hb-shape-plan.cc |2 - src/test.cc |2 - test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/MANIFEST |1 test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/ligature-components.txt | 18 ++ 6 files changed, 38 insertions(+), 15 deletions(-) New commits: commit ef6e9cec3399e4f63f4b662abd77cf6d4683e8a3 Author: Behdad Esfahbod beh...@behdad.org Date: Sun Jul 29 21:35:22 2012 -0400 Fixup bb0e4ba3e9c5a407fc5d73c914e429d24d336380 diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index f9f9f3d..a478ba5 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -115,7 +115,7 @@ hb_shape_plan_get_empty (void) static const hb_shape_plan_t _hb_shape_plan_nil = { HB_OBJECT_HEADER_STATIC, -false, /* default_shaper_list */ +true, /* default_shaper_list */ NULL, /* face */ _HB_BUFFER_PROPS_DEFAULT, /* props */ commit cb3d34063154bf164c61eeba41c6166b0bd304fb Author: Behdad Esfahbod beh...@behdad.org Date: Sun Jul 29 20:37:38 2012 -0400 [GSUB] Don't set new lig_id on mark ligatures If two marks form a ligature, retain their previous lig_id, such that the mark ligature can attach to ligature components... Fixes https://bugzilla.gnome.org/show_bug.cgi?id=676343 In fact, I noticed that we should not let ligatures form between glyphs coming from different components of a previous ligature. For example, if the sequence is: LAM,SHADDA,LAM,FATHA,HEH, the LAM,LAM,HEH form a ligature, putting SHADDA and FATHA next to eachother. However, it would be wrong to ligate them. Uniscribe has this bug also. diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 03244b5..a74f707 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -499,11 +499,20 @@ struct Ligature if (likely (c-buffer-info[skippy_iter.idx].codepoint != component[i])) return TRACE_RETURN (false); } -unsigned int klass = first_was_mark found_non_mark ? HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE : 0; +bool is_a_mark_ligature = first_was_mark !found_non_mark; + +unsigned int klass = is_a_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE; + +/* If it's a mark ligature, we should leave the lig_id / lig_comp alone such that + * the resulting mark ligature has the opportunity to attach to ligature components + * of it's base later on. See for example: + * https://bugzilla.gnome.org/show_bug.cgi?id=676343 + */ /* Allocate new ligature id */ -unsigned int lig_id = allocate_lig_id (c-buffer); -set_lig_props (c-buffer-cur(), lig_id, 0); +unsigned int lig_id = is_a_mark_ligature ? 0 : allocate_lig_id (c-buffer); +if (!is_a_mark_ligature) + set_lig_props (c-buffer-cur(), lig_id, 0); if (skippy_iter.idx c-buffer-idx + count) /* No input glyphs skipped */ { @@ -526,7 +535,8 @@ struct Ligature { while (c-should_mark_skip_current_glyph ()) { - set_lig_props (c-buffer-cur(), lig_id, i); + if (!is_a_mark_ligature) + set_lig_props (c-buffer-cur(), lig_id, i); c-buffer-next_glyph (); } commit 97a201becf936f62046914b568e5763e27ee936e Author: Behdad Esfahbod beh...@behdad.org Date: Sun Jul 29 20:31:36 2012 -0400 Add Arabic tests for mark ligature component attachments diff --git a/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/MANIFEST b/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/MANIFEST index 242b2a1..c71d035 100644 --- a/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/MANIFEST +++ b/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/MANIFEST @@ -2,5 +2,6 @@ lam-alef.txt language-arabic.txt language-persian.txt language-urdu.txt +ligature-components.txt ligature-diacritics.txt mark-skipping.txt diff --git a/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/ligature-components.txt b/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/ligature-components.txt new file mode 100644 index 000..0d4d47f --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-arabic/script-arabic/misc/diacritics/ligature-components.txt @@ -0,0 +1,18 @@ +ÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙ +ÙÙÙÙÙÙ +ÙÙÙÙÙÙ +ÙÙÙÙÙÙ commit
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
test/shaping/Makefile.am |2 test/shaping/hb-diff-ngrams |5 + test/shaping/hb-diff-stat |5 + test/shaping/hb_test_tools.py | 174 +++--- 4 files changed, 177 insertions(+), 9 deletions(-) New commits: commit 2214a03900d32710573a1b05c7665195b3129761 Author: Behdad Esfahbod beh...@behdad.org Date: Wed May 9 09:54:54 2012 +0200 Add hb-diff-ngrams diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index 81c9991..4fb762c 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -13,6 +13,7 @@ EXTRA_DIST += \ hb-diff \ hb-diff-colorize \ hb-diff-filter-failures \ + hb-diff-ngrams \ hb-diff-stat \ hb-manifest-read \ hb-manifest-update \ diff --git a/test/shaping/hb-diff-ngrams b/test/shaping/hb-diff-ngrams new file mode 100755 index 000..a496447 --- /dev/null +++ b/test/shaping/hb-diff-ngrams @@ -0,0 +1,5 @@ +#!/usr/bin/python + +from hb_test_tools import * + +UtilMains.process_multiple_files (DiffSinks.print_ngrams) diff --git a/test/shaping/hb_test_tools.py b/test/shaping/hb_test_tools.py index a38f067..3ff75b8 100644 --- a/test/shaping/hb_test_tools.py +++ b/test/shaping/hb_test_tools.py @@ -155,12 +155,60 @@ class DiffFilters: if not DiffHelpers.test_passed (lines): for l in lines: yield l +class Stat: + + def __init__ (self): + self.count = 0 + self.freq = 0 + + def add (self, test): + self.count += 1 + self.freq += test.freq + +class Stats: + + def __init__ (self): + self.passed = Stat () + self.failed = Stat () + self.total = Stat () + + def add (self, test): + self.total.add (test) + if test.passed: + self.passed.add (test) + else: + self.failed.add (test) + + def mean (self): + return float (self.passed.count) / self.total.count + + def variance (self): + return (float (self.passed.count) / self.total.count) * \ + (float (self.failed.count) / self.total.count) + + def stddev (self): + return self.variance () ** .5 + + def zscore (self, population): + Calculate the standard score. + Population is the Stats for population. + Self is Stats for sample. + Returns larger absolute value if sample is highly unlikely to be random. + Anything outside of -3..+3 is very unlikely to be random. + See: http://en.wikipedia.org/wiki/Standard_score; + + return (self.mean () - population.mean ()) / population.stddev () + + + + class DiffSinks: @staticmethod def print_stat (f): passed = 0 failed = 0 + # XXX port to Stats, but that would really slow us down here for key, lines in DiffHelpers.separate_test_cases (f): if DiffHelpers.test_passed (lines): passed += 1 @@ -172,21 +220,34 @@ class DiffSinks: @staticmethod def print_ngrams (f, ns=(1,2,3)): gens = tuple (Ngram.generator (n) for n in ns) + allstats = Stats () + allgrams = {} for key, lines in DiffHelpers.separate_test_cases (f): test = Test (lines) - unicodes = test.unicodes - del test + allstats.add (test) for gen in gens: - print Printing %d-grams: % gen.n - for ngram in gen (unicodes): - print ngram + for ngram in gen (test.unicodes): + if ngram not in allgrams: + allgrams[ngram] = Stats () + allgrams[ngram].add (test) + + importantgrams = {} + for ngram, stats in allgrams.iteritems (): + if stats.failed.count = 30: # for statistical reasons + importantgrams[ngram] = stats + allgrams = importantgrams + del importantgrams + + for ngram, stats in allgrams.iteritems (): + print zscore: %9f failed: %6d passed: %6d ngram: %s % (stats.zscore (allstats), stats.failed.count, stats.passed.count, ','.join (U+%04X % u for u in ngram)) class Test: def __init__ (self, lines): + self.freq = 1 self.passed = True self.identifier = None self.text = None commit
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
configure.ac |6 ++-- src/Makefile.am| 11 +++- src/hb-blob.h |6 +++- src/hb-buffer.h|4 +++ src/hb-common.h| 10 +-- src/hb-fallback-shape-private.hh |9 +++ src/hb-fallback-shape.cc |9 +++ src/hb-font.h |4 +++ src/hb-ft.cc |2 + src/hb-ft.h|2 - src/hb-glib.h |1 src/hb-gobject.h |1 src/hb-graphite2-private.hh| 42 + src/hb-graphite2.cc|5 +-- src/hb-graphite2.h | 10 +-- src/hb-icu.h |1 src/hb-ot-layout-common-private.hh |2 - src/hb-ot-layout-gdef-table.hh |2 - src/hb-ot-layout-gpos-table.hh |5 +-- src/hb-ot-layout-gsub-table.hh |2 - src/hb-ot-layout-private.hh|2 - src/hb-ot-layout.h |8 +++--- src/hb-ot-shape-private.hh |8 -- src/hb-ot-shape.cc | 11 +++- src/hb-ot-shape.h | 47 - src/hb-ot-tag.h|6 +++- src/hb-ot.h|3 +- src/hb-private.hh |5 +++ src/hb-shape.cc| 24 +++--- src/hb-shape.h |5 +++ src/hb-unicode.h |4 +++ src/hb-uniscribe-private.hh| 42 + src/hb-uniscribe.cc|9 +++ src/hb-uniscribe.h | 10 --- src/hb-version.h.in|4 +++ src/hb.h |2 + util/helper-cairo.hh |5 ++- util/options.hh|9 ++- util/view-cairo.cc | 31 util/view-cairo.hh |1 40 files changed, 222 insertions(+), 148 deletions(-) New commits: commit 69b84a8f6c789726815261c2e86692de7a65d6e8 Author: Behdad Esfahbod beh...@behdad.org Date: Thu Apr 12 15:50:40 2012 -0400 Fix hb-view surface size calc for vertical text For some reason it doesn't quite work with IranianNastaliq, but that looks like a font issue. diff --git a/util/helper-cairo.hh b/util/helper-cairo.hh index 5edfc3a..bc3fe1d 100644 --- a/util/helper-cairo.hh +++ b/util/helper-cairo.hh @@ -64,8 +64,9 @@ struct helper_cairo_line_t { g_free (utf8); } - double get_width (void) { -return glyphs[num_glyphs].x; + void get_advance (double *x_advance, double *y_advance) { +*x_advance = glyphs[num_glyphs].x; +*y_advance = glyphs[num_glyphs].y; } }; diff --git a/util/options.hh b/util/options.hh index 165e7a1..da95017 100644 --- a/util/options.hh +++ b/util/options.hh @@ -48,6 +48,13 @@ #include glib.h #include glib/gprintf.h +#undef MIN +template typename Type static inline Type MIN (const Type a, const Type b) { return a b ? a : b; } + +#undef MAX +template typename Type static inline Type MAX (const Type a, const Type b) { return a b ? a : b; } + + void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN; diff --git a/util/view-cairo.cc b/util/view-cairo.cc index f766a4f..ce578ed 100644 --- a/util/view-cairo.cc +++ b/util/view-cairo.cc @@ -38,6 +38,7 @@ view_cairo_t::consume_line (hb_buffer_t *buffer, const char *text, unsigned int text_len) { + direction = hb_buffer_get_direction (buffer); helper_cairo_line_t l; helper_cairo_line_from_buffer (l, buffer, text, text_len, scale); g_array_append_val (lines, l); @@ -63,14 +64,17 @@ view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font, cairo_scaled_font_extents (scaled_font, font_extents); - *h = font_extents.ascent - + font_extents.descent - + ((int) lines-len - 1) * (font_extents.height + line_space); - *w = 0; + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + (vertical ? *w : *h) = (int) lines-len * (font_extents.height + line_space) - line_space; + (vertical ? *h : *w) = 0; for (unsigned int i = 0; i lines-len; i++) { helper_cairo_line_t line = g_array_index (lines, helper_cairo_line_t, i); -double line_width = line.get_width (); -*w = MAX (*w, line_width); +double x_advance, y_advance; +line.get_advance (x_advance, y_advance); +if (vertical) + *h = MAX (*h, y_advance); +else + *w = MAX (*w, x_advance); } *w += margin.l + margin.r; @@ -97,17 +101,26 @@ view_cairo_t::draw (cairo_t *cr) { cairo_save (cr); + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + int v = vertical ? 1 : 0; + int h = vertical ? 0 : 1; cairo_font_extents_t font_extents; cairo_font_extents (cr, font_extents); cairo_translate (cr, margin.l,
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/hb-common.cc |6 + src/hb-common.h| 203 +++-- src/hb-glib.cc | 11 +- src/hb-ot-shape-complex-private.hh |9 + 4 files changed, 129 insertions(+), 100 deletions(-) New commits: commit f91136cb528e298651c4a8a8a1d6dc54136e09ce Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:56:22 2012 -0500 Route three Unicode 6.1 scripts through Indic shaper diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 652d90a..52d0523 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -79,7 +79,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) /* Note: * * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according - * to Martin Hosken do not require complex shaping. + * to Martin Hosken and Jonathan Kew do not require complex shaping. + * + * TODO We should automate figuring out which scripts do not need complex shaping * * TODO We currently keep data for these scripts in our indic table. Need to fix the * generator to not do that. @@ -113,6 +115,7 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) case HB_SCRIPT_BALINESE: case HB_SCRIPT_BENGALI: case HB_SCRIPT_BUGINESE: +case HB_SCRIPT_CHAKMA: case HB_SCRIPT_CHAM: case HB_SCRIPT_DEVANAGARI: case HB_SCRIPT_GUJARATI: @@ -127,9 +130,11 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) case HB_SCRIPT_NEW_TAI_LUE: case HB_SCRIPT_ORIYA: case HB_SCRIPT_REJANG: +case HB_SCRIPT_SHARADA: case HB_SCRIPT_SINHALA: case HB_SCRIPT_SUNDANESE: case HB_SCRIPT_TAI_THAM: +case HB_SCRIPT_TAKRI: case HB_SCRIPT_TAMIL: case HB_SCRIPT_TELUGU: return hb_ot_complex_shaper_indic; commit f32c0012ad794cd2df669dfc7b0438fafbe38b2d Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:53:34 2012 -0500 Add Unicode 6.1.0 scripts diff --git a/src/hb-common.h b/src/hb-common.h index 75ae899..ca51c1f 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -285,6 +285,15 @@ typedef enum HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), HB_SCRIPT_MANDAIC= HB_TAG ('M','a','n','d'), + /* Unicode-6.1 additions */ + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), + HB_SCRIPT_SHARADA= HB_TAG ('S','h','r','d'), + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), + HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), + /* No script set */ HB_SCRIPT_INVALID= HB_TAG_NONE } hb_script_t; diff --git a/src/hb-glib.cc b/src/hb-glib.cc index f990988..26d40a3 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -144,7 +144,16 @@ glib_script_to_script[] = /* Unicode-6.0 additions */ HB_SCRIPT_BATAK, HB_SCRIPT_BRAHMI, - HB_SCRIPT_MANDAIC + HB_SCRIPT_MANDAIC, + + /* Unicode-6.1 additions */ + HB_SCRIPT_CHAKMA, + HB_SCRIPT_MEROITIC_CURSIVE, + HB_SCRIPT_MEROITIC_HIEROGLYPHS, + HB_SCRIPT_MIAO, + HB_SCRIPT_SHARADA, + HB_SCRIPT_SORA_SOMPENG, + HB_SCRIPT_TAKRI }; #endif commit 50e810cd0e55c25fddb0a2fd0861c51fbf65700e Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:49:08 2012 -0500 Lydian and Kharoshthi are right-to-left diff --git a/src/hb-common.cc b/src/hb-common.cc index 6093289..170b75f 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -274,10 +274,16 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-4.0 additions */ case HB_SCRIPT_CYPRIOT: +/* Unicode-4.1 additions */ +case HB_SCRIPT_KHAROSHTHI: + /* Unicode-5.0 additions */ case HB_SCRIPT_PHOENICIAN: case HB_SCRIPT_NKO: +/* Unicode-5.1 additions */ +case HB_SCRIPT_LYDIAN: + /* Unicode-5.2 additions */ case HB_SCRIPT_AVESTAN: case HB_SCRIPT_IMPERIAL_ARAMAIC: commit a52835635e4a2a12715aff2febb561515a10cd5a Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:38:39 2012 -0500 Whitespace diff --git a/src/hb-common.h b/src/hb-common.h index b7fef32..75ae899 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -176,117 +176,117 @@ typedef enum /* http://unicode.org/iso15924/ */ typedef enum { - HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), - HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), - HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), - HB_SCRIPT_ARMENIAN= HB_TAG ('A','r','m','n'), - HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), - HB_SCRIPT_BOPOMOFO= HB_TAG
Re: [HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
On 03/07/2012 12:56 PM, Behdad Esfahbod wrote: Route three Unicode 6.1 scripts through Indic shaper Martin, Jonathan, can you comment on these? Do they need any complex shaping at all? Thanks, behdad diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 652d90a..52d0523 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -79,7 +79,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) /* Note: * * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according - * to Martin Hosken do not require complex shaping. + * to Martin Hosken and Jonathan Kew do not require complex shaping. + * + * TODO We should automate figuring out which scripts do not need complex shaping * * TODO We currently keep data for these scripts in our indic table. Need to fix the * generator to not do that. @@ -113,6 +115,7 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) case HB_SCRIPT_BALINESE: case HB_SCRIPT_BENGALI: case HB_SCRIPT_BUGINESE: +case HB_SCRIPT_CHAKMA: case HB_SCRIPT_CHAM: case HB_SCRIPT_DEVANAGARI: case HB_SCRIPT_GUJARATI: @@ -127,9 +130,11 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) case HB_SCRIPT_NEW_TAI_LUE: case HB_SCRIPT_ORIYA: case HB_SCRIPT_REJANG: +case HB_SCRIPT_SHARADA: case HB_SCRIPT_SINHALA: case HB_SCRIPT_SUNDANESE: case HB_SCRIPT_TAI_THAM: +case HB_SCRIPT_TAKRI: case HB_SCRIPT_TAMIL: case HB_SCRIPT_TELUGU: return hb_ot_complex_shaper_indic; commit f32c0012ad794cd2df669dfc7b0438fafbe38b2d Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:53:34 2012 -0500 Add Unicode 6.1.0 scripts diff --git a/src/hb-common.h b/src/hb-common.h index 75ae899..ca51c1f 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -285,6 +285,15 @@ typedef enum HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), + /* Unicode-6.1 additions */ + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), + HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), + HB_SCRIPT_TAKRI= HB_TAG ('T','a','k','r'), + /* No script set */ HB_SCRIPT_INVALID = HB_TAG_NONE } hb_script_t; diff --git a/src/hb-glib.cc b/src/hb-glib.cc index f990988..26d40a3 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -144,7 +144,16 @@ glib_script_to_script[] = /* Unicode-6.0 additions */ HB_SCRIPT_BATAK, HB_SCRIPT_BRAHMI, - HB_SCRIPT_MANDAIC + HB_SCRIPT_MANDAIC, + + /* Unicode-6.1 additions */ + HB_SCRIPT_CHAKMA, + HB_SCRIPT_MEROITIC_CURSIVE, + HB_SCRIPT_MEROITIC_HIEROGLYPHS, + HB_SCRIPT_MIAO, + HB_SCRIPT_SHARADA, + HB_SCRIPT_SORA_SOMPENG, + HB_SCRIPT_TAKRI }; #endif commit 50e810cd0e55c25fddb0a2fd0861c51fbf65700e Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:49:08 2012 -0500 Lydian and Kharoshthi are right-to-left diff --git a/src/hb-common.cc b/src/hb-common.cc index 6093289..170b75f 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -274,10 +274,16 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-4.0 additions */ case HB_SCRIPT_CYPRIOT: +/* Unicode-4.1 additions */ +case HB_SCRIPT_KHAROSHTHI: + /* Unicode-5.0 additions */ case HB_SCRIPT_PHOENICIAN: case HB_SCRIPT_NKO: +/* Unicode-5.1 additions */ +case HB_SCRIPT_LYDIAN: + /* Unicode-5.2 additions */ case HB_SCRIPT_AVESTAN: case HB_SCRIPT_IMPERIAL_ARAMAIC: commit a52835635e4a2a12715aff2febb561515a10cd5a Author: Behdad Esfahbod beh...@behdad.org Date: Wed Mar 7 12:38:39 2012 -0500 Whitespace diff --git a/src/hb-common.h b/src/hb-common.h index b7fef32..75ae899 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -176,117 +176,117 @@ typedef enum /* http://unicode.org/iso15924/ */ typedef enum { - HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), - HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), - HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), - HB_SCRIPT_ARMENIAN= HB_TAG ('A','r','m','n'), - HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), - HB_SCRIPT_BOPOMOFO= HB_TAG ('B','o','p','o'), - HB_SCRIPT_CHEROKEE= HB_TAG ('C','h','e','r'), - HB_SCRIPT_COPTIC = HB_TAG
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
Makefile.am |3 configure.ac |1 src/Makefile.am | 13 - src/hb-uniscribe-shape.cc |7 src/hb-view.cc| 568 -- src/test.cc |3 test/hb-test.h|3 test/test-shape-complex.c | 20 + util/Makefile.am | 24 + util/hb-view.cc | 568 ++ 10 files changed, 618 insertions(+), 592 deletions(-) New commits: commit 511a136f0c092880b19250a5df53bcf9f4b043ca Author: Behdad Esfahbod beh...@behdad.org Date: Tue Aug 9 15:03:00 2011 +0200 Move hb-view into util/ diff --git a/Makefile.am b/Makefile.am index bb68ede..8b69c2d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ NULL = -SUBDIRS = src test +SUBDIRS = src util test pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = harfbuzz.pc @@ -76,5 +76,4 @@ $(gpg_file): $(sha256_file) release-files: $(tar_file) $(sha256_file) $(gpg_file) - -include $(top_srcdir)/git.mk diff --git a/configure.ac b/configure.ac index 3f13c43..d960856 100644 --- a/configure.ac +++ b/configure.ac @@ -161,6 +161,7 @@ Makefile harfbuzz.pc src/Makefile src/hb-version.h +util/Makefile test/Makefile ]) diff --git a/src/Makefile.am b/src/Makefile.am index 9b0307a..62a5b39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -149,19 +149,6 @@ hb-ot-shape-complex-indic-machine.hh: hb-ot-shape-complex-indic-machine.rl noinst_PROGRAMS = main test bin_PROGRAMS = -if HAVE_GLIB -if HAVE_FREETYPE -if HAVE_CAIRO_FT -if HAVE_CAIRO_PNG -hb_view_SOURCES = hb-view.cc -hb_view_CPPFLAGS = $(HBCFLAGS) $(CAIRO_FT_CFLAGS) $(CAIRO_PNG_CFLAGS) -hb_view_LDADD = libharfbuzz.la -lm $(HBLIBS) $(CAIRO_FT_LIBS) $(CAIRO_PNG_LIBS) -bin_PROGRAMS += hb-view -endif -endif -endif -endif - main_SOURCES = main.cc main_CPPFLAGS = $(HBCFLAGS) main_LDADD = libharfbuzz.la $(HBLIBS) diff --git a/src/hb-view.cc b/src/hb-view.cc deleted file mode 100644 index dc3fc47..000 --- a/src/hb-view.cc +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright © 2010 Behdad Esfahbod - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * 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. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifdef HAVE_CONFIG_H -#include config.h -#endif - -#include unistd.h -#include getopt.h -#include stdlib.h -#include stdio.h -#include string.h -#include math.h -#include locale.h - -#include glib.h - -#include cairo-ft.h -#include hb-ft.h - - - -/* Controlled by cmd-line options */ -static int margin_t = 10; -static int margin_b = 10; -static int margin_l = 10; -static int margin_r = 10; -static int line_space = 0; -static int face_index = 0; -static double font_size = 18; -static const char *fore = #00; -static const char *back = #ff; -static const char *text = NULL; -static const char *font_file = NULL; -static const char *out_file = /dev/stdout; -static const char *direction = NULL; -static const char *script = NULL; -static const char *language = NULL; -static hb_feature_t *features = NULL; -static unsigned int num_features; -static hb_bool_t annotate = FALSE; -static hb_bool_t debug = FALSE; - -/* Ugh, global vars. Ugly, but does the job */ -static int width = 0; -static int height = 0; -static cairo_surface_t *surface = NULL; -static cairo_pattern_t *fore_pattern = NULL; -static cairo_pattern_t *back_pattern = NULL; -static cairo_font_face_t *cairo_face; - - -G_GNUC_NORETURN static void -usage (FILE *f, int status) -{ - fprintf (f, usage: hb-view [OPTS...] font-file text\n); - exit (status); -} - -G_GNUC_NORETURN static void -version (void) -{ - printf (hb-view (harfbuzz) %s\n, HB_VERSION_STRING); - exit (0); -} - -static void parse_features (char *s); - -static void -parse_opts (int argc, char **argv) -{ - argv[0] = (char *) hb-view; - while (1) -{ - int option_index = 0, c; - static const struct option long_options[] = { - {annotate, 0, annotate, TRUE}, -
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/check-header-guards.sh |1 src/hb-common.cc|8 +++--- src/hb-open-type-private.hh | 10 +++ src/hb-shape.cc | 58 +--- src/hb-shape.h |3 ++ src/hb-view.cc |2 - test/Makefile.am|2 + test/test-c.c |8 ++ test/test-shape.c | 15 +++ 9 files changed, 83 insertions(+), 24 deletions(-) New commits: commit 9da554504e30a326fc57b28cdb0e57108bfa9555 Author: Behdad Esfahbod beh...@behdad.org Date: Fri Aug 5 19:48:49 2011 -0400 Add hb_shape_list_shapers() diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 9e4469d..78c39dd 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -66,8 +66,16 @@ static struct static_shaper_list_t { char *env = getenv (HB_SHAPER_LIST); shaper_list = NULL; -if (!env || !*env) +if (!env || !*env) { +fallback: + ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) = sizeof (static_buffer)); + shaper_list = (const char **) static_buffer; + unsigned int i; + for (i = 0; i ARRAY_LENGTH (shapers); i++) +shaper_list[i] = shapers[i].name; + shaper_list[i] = NULL; return; +} unsigned int count = 3; /* initial, fallback, null */ for (const char *p = env; (p == strchr (p, ',')) p++; ) @@ -76,7 +84,7 @@ static struct static_shaper_list_t unsigned int len = strlen (env); if (count 100 || len 1000) - return; + goto fallback; len += count * sizeof (*shaper_list) + 1; char *buffer = len sizeof (static_buffer) ? static_buffer : (char *) malloc (len); @@ -100,7 +108,13 @@ static struct static_shaper_list_t const char **shaper_list; char static_buffer[32]; -} env_shaper_list; +} static_shaper_list; + +const char ** +hb_shape_list_shapers (void) +{ + return static_shaper_list.shaper_list; +} hb_bool_t hb_shape_full (hb_font_t *font, @@ -111,7 +125,7 @@ hb_shape_full (hb_font_t *font, const char **shaper_list) { if (likely (!shaper_list)) -shaper_list = env_shaper_list.shaper_list; +shaper_list = static_shaper_list.shaper_list; if (likely (!shaper_list)) { for (unsigned int i = 0; i ARRAY_LENGTH (shapers); i++) diff --git a/src/hb-shape.h b/src/hb-shape.h index 75818dc..18b35ae 100644 --- a/src/hb-shape.h +++ b/src/hb-shape.h @@ -56,6 +56,9 @@ hb_shape_full (hb_font_t *font, const char *shaper_options, const char **shaper_list); +const char ** +hb_shape_list_shapers (void); + HB_END_DECLS diff --git a/test/Makefile.am b/test/Makefile.am index 0fbc689..18f36df 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -25,9 +25,11 @@ TEST_PROGS = \ test-version \ $(NULL) +if HAVE_OT TEST_PROGS += \ test-ot-tag \ $(NULL) +endif # Tests for header compilation TEST_PROGS += \ diff --git a/test/test-c.c b/test/test-c.c index 543fa7b..e72db27 100644 --- a/test/test-c.c +++ b/test/test-c.c @@ -43,6 +43,14 @@ #include hb-ft.h #endif +#if HAVE_OT +#include hb-ot.h +#endif + +#if HAVE_UNISCRIBE +#include hb-uniscribe.h +#endif + int main (int argc, char **argv) { diff --git a/test/test-shape.c b/test/test-shape.c index 5a41f0c..6d30824 100644 --- a/test/test-shape.c +++ b/test/test-shape.c @@ -138,6 +138,18 @@ test_shape (void) hb_font_destroy (font); } +static void +test_shape_list (void) +{ + const char **shapers = hb_shape_list_shapers (); + + unsigned int i; + for (i = 0; shapers[i]; i++) +; + + g_assert_cmpint (i, , 1); + g_assert (!strcmp (shapers[i - 1], fallback)); +} int main (int argc, char **argv) @@ -145,6 +157,9 @@ main (int argc, char **argv) hb_test_init (argc, argv); hb_test_add (test_shape); + /* TODO test fallback shaper */ + /* TODO test shaper_full */ + hb_test_add (test_shape_list); return hb_test_run(); } commit d7bf473ef222ab420456ff155ffaa09bacb3a394 Author: Behdad Esfahbod beh...@behdad.org Date: Fri Aug 5 18:18:21 2011 -0400 Minor diff --git a/src/check-header-guards.sh b/src/check-header-guards.sh index 212b803..dc1893c 100755 --- a/src/check-header-guards.sh +++ b/src/check-header-guards.sh @@ -10,7 +10,6 @@ test x$HBHEADERS = x HBHEADERS=`find . -maxdepth 1 -name 'hb*.h'` test x$HBSOURCES = x HBSOURCES=`find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'` -echo $srcdir for x in $HBHEADERS $HBSOURCES; do test -f $srcdir/$x x=$srcdir/$x echo $x | grep '[^h]$' -q continue; diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index a6f1389..ae44ed7 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -338,12 +338,12 @@ struct Sanitizer */ -template typename Type, int Bytes class BEInt; +template typename Type, int Bytes struct BEInt; /* LONGTERMTODO: On machines
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/hb-glib.cc | 149 +++- src/hb-icu.cc | 145 ++ src/hb-unicode.cc |6 +- test/test-unicode.c | 67 +++ 4 files changed, 317 insertions(+), 50 deletions(-) New commits: commit 498e1a9be673bb02c00aac3f12bb4c6993a85910 Author: Behdad Esfahbod beh...@behdad.org Date: Wed Jul 20 23:19:49 2011 -0400 [icu] Implement compose()/decompose() diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 4aa56f6..384b77d 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -35,6 +35,8 @@ #include unicode/uversion.h #include unicode/uchar.h +#include unicode/unorm.h +#include unicode/unistr.h HB_BEGIN_DECLS @@ -170,7 +172,34 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *ab, void *user_data HB_UNUSED) { - return FALSE; + if (!a || !b) +return FALSE; + + UChar utf16[4], normalized[5]; + gint len; + hb_bool_t ret, err; + UErrorCode icu_err; + + len = 0; + err = FALSE; + U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err); + if (err) return FALSE; + U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err); + if (err) return FALSE; + + icu_err = U_ZERO_ERROR; + len = unorm_normalize (utf16, len, UNORM_NFC, 0, normalized, ARRAY_LENGTH (normalized), icu_err); + if (icu_err) +return FALSE; + normalized[len] = 0; + if (u_strlen (normalized) == 1) { +U16_GET_UNSAFE (normalized, 0, *ab); +ret = TRUE; + } else { +ret = FALSE; + } + + return ret; } static hb_bool_t @@ -180,7 +209,61 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *b, void *user_data HB_UNUSED) { - return FALSE; + UChar utf16[2], normalized[20]; + gint len; + hb_bool_t ret, err; + UErrorCode icu_err; + + len = 0; + err = FALSE; + U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err); + if (err) return FALSE; + + icu_err = U_ZERO_ERROR; + len = unorm_normalize (utf16, len, UNORM_NFD, 0, normalized, ARRAY_LENGTH (normalized), icu_err); + if (icu_err) +return FALSE; + + normalized[len] = 0; + len = u_strlen (normalized); + + if (len == 1) { +U16_GET_UNSAFE (normalized, 0, *a); +*b = 0; +ret = *a != ab; + } else if (len == 2) { +/* Here's the ugly part: if ab decomposes to a single character and + * that character decomposes again, we have to detect that and undo + * the second part :-(. */ +UChar recomposed[20]; +icu_err = U_ZERO_ERROR; +len = unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), icu_err); +if (icu_err) + return FALSE; +U16_GET_UNSAFE (recomposed, 0, *a); +if (*a != ab) { + *b = 0; +} else { + len =0; + U16_NEXT_UNSAFE (normalized, len, *a); + U16_GET_UNSAFE (normalized, len, *b); +} +ret = TRUE; + } else { +/* If decomposed to more than two characters, take the last one, + * and recompose the rest to get the first component. */ +U16_PREV_UNSAFE (normalized, len, *b); +UChar recomposed[20]; +icu_err = U_ZERO_ERROR; +len = unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), icu_err); +if (icu_err) + return FALSE; +/* We expect that recomposed has exactly one character now. */ +U16_GET_UNSAFE (recomposed, 0, *a); +ret = TRUE; + } + + return ret; } extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_icu; diff --git a/test/test-unicode.c b/test/test-unicode.c index 09dde54..dd57984 100644 --- a/test/test-unicode.c +++ b/test/test-unicode.c @@ -864,6 +864,7 @@ main (int argc, char **argv) #endif #ifdef HAVE_ICU hb_test_add_data_flavor (hb_icu_get_unicode_funcs (), icu, test_unicode_properties); + hb_test_add_data_flavor (hb_icu_get_unicode_funcs (), icu, test_unicode_normalization); hb_test_add_data_flavor ((gconstpointer) script_roundtrip_icu, icu, test_unicode_script_roundtrip); #endif commit ffd4a436f7baccb68a0c3602f94ea0246e32844f Author: Behdad Esfahbod beh...@behdad.org Date: Wed Jul 20 22:30:29 2011 -0400 Add tests for compose()/decompose() Adjust glib fallback implementation. The tests are not hooked up for ICU yet. diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 6174498..fbf8cf5 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -244,6 +244,9 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, /* We don't ifdef-out the fallback code such that compiler always * sees it and makes sure it's compilable. */ + if (!a || !b) +return FALSE; + gchar utf8[12]; gchar *normalized; gint len; @@ -293,8 +296,18 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, *b = 0; ret = *a != ab; } else
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/hb-font.cc | 10 - src/hb-font.h|2 src/hb-ft.cc |2 test/test-font.c | 290 --- 4 files changed, 284 insertions(+), 20 deletions(-) New commits: commit 52df150efeff4cf003cee65f8c91618f1a980bc8 Author: Behdad Esfahbod beh...@behdad.org Date: Thu May 12 00:46:57 2011 -0400 Fix font subclass chainup Test passing now. diff --git a/src/hb-font.cc b/src/hb-font.cc index 7cdf5f6..10f686e 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -536,11 +536,7 @@ hb_font_create_sub_font (hb_font_t *parent) font-x_ppem = parent-x_ppem; font-y_ppem = parent-y_ppem; - /* We can safely copy user_data from parent since we hold a reference - * onto it and it's immutable. We should not copy the destroy notifiers - * though. */ - font-klass = hb_font_funcs_reference (parent-klass); - font-user_data = parent-user_data; + font-klass = _hb_font_funcs_nil; return font; } commit f2c1dd4f746c36a44cf33d0257a3cd800107c286 Author: Behdad Esfahbod beh...@behdad.org Date: Thu May 12 00:35:12 2011 -0400 [test/font] Test font_funcs subclassing diff --git a/test/test-font.c b/test/test-font.c index 01d20b4..aa78a20 100644 --- a/test/test-font.c +++ b/test/test-font.c @@ -183,7 +183,7 @@ test_fontfuncs_empty (void) } static void -test_fontfuncs_custom (void) +test_fontfuncs_nil (void) { hb_font_funcs_t *ffuncs; @@ -195,6 +195,158 @@ test_fontfuncs_custom (void) hb_font_funcs_destroy (ffuncs); } +static hb_bool_t +contour_point_func1 (hb_font_t *font, void *font_data, +hb_codepoint_t glyph, unsigned int point_index, +hb_position_t *x, hb_position_t *y, +void *user_data) +{ + if (glyph == 1) { +*x = 2; +*y = 3; +return TRUE; + } + if (glyph == 2) { +*x = 4; +*y = 5; +return TRUE; + } + + return FALSE; +} + +static hb_bool_t +contour_point_func2 (hb_font_t *font, void *font_data, +hb_codepoint_t glyph, unsigned int point_index, +hb_position_t *x, hb_position_t *y, +void *user_data) +{ + if (glyph == 1) { +*x = 6; +*y = 7; +return TRUE; + } + + return hb_font_get_contour_point (hb_font_get_parent (font), + glyph, point_index, x, y); +} + +static void +glyph_advance_func1 (hb_font_t *font, void *font_data, +hb_codepoint_t glyph, +hb_position_t *x_advance, hb_position_t *y_advance, +void *user_data) +{ + if (glyph == 1) { +*x_advance = 8; +*y_advance = 9; + } +} + +static void +test_fontfuncs_subclassing (void) +{ + hb_blob_t *blob; + hb_face_t *face; + + hb_font_funcs_t *ffuncs1; + hb_font_funcs_t *ffuncs2; + + hb_font_t *font1; + hb_font_t *font2; + hb_font_t *font3; + + hb_position_t x; + hb_position_t y; + + blob = hb_blob_create (test_data, sizeof (test_data), HB_MEMORY_MODE_READONLY, NULL, NULL); + face = hb_face_create (blob, 0); + hb_blob_destroy (blob); + font1 = hb_font_create (face); + hb_face_destroy (face); + hb_font_set_scale (font1, 10, 10); + + /* setup font1 */ + ffuncs1 = hb_font_funcs_create (); + hb_font_funcs_set_contour_point_func (ffuncs1, contour_point_func1, NULL, NULL); + hb_font_funcs_set_glyph_advance_func (ffuncs1, glyph_advance_func1, NULL, NULL); + hb_font_set_funcs (font1, ffuncs1, NULL, NULL); + hb_font_funcs_destroy (ffuncs1); + + x = y = 1; + g_assert (hb_font_get_contour_point (font1, 1, 2, x, y)); + g_assert_cmpint (x, ==, 2); + g_assert_cmpint (y, ==, 3); + g_assert (hb_font_get_contour_point (font1, 2, 5, x, y)); + g_assert_cmpint (x, ==, 4); + g_assert_cmpint (y, ==, 5); + g_assert (!hb_font_get_contour_point (font1, 3, 7, x, y)); + g_assert_cmpint (x, ==, 0); + g_assert_cmpint (y, ==, 0); + hb_font_get_glyph_advance (font1, 1, x, y); + g_assert_cmpint (x, ==, 8); + g_assert_cmpint (y, ==, 9); + hb_font_get_glyph_advance (font1, 2, x, y); + g_assert_cmpint (x, ==, 0); + g_assert_cmpint (y, ==, 0); + + + font2 = hb_font_create_sub_font (font1); + g_assert (hb_font_is_immutable (font1)); + hb_font_destroy (font1); + + /* setup font2 to override some funcs */ + ffuncs2 = hb_font_funcs_create (); + hb_font_funcs_set_contour_point_func (ffuncs2, contour_point_func2, NULL, NULL); + hb_font_set_funcs (font2, ffuncs2, NULL, NULL); + hb_font_funcs_destroy (ffuncs2); + + x = y = 1; + g_assert (hb_font_get_contour_point (font2, 1, 2, x, y)); + g_assert_cmpint (x, ==, 6); + g_assert_cmpint (y, ==, 7); + g_assert (hb_font_get_contour_point (font2, 2, 5, x, y)); + g_assert_cmpint (x, ==, 4); + g_assert_cmpint (y, ==, 5); + g_assert (!hb_font_get_contour_point (font2, 3, 7, x, y)); + g_assert_cmpint (x, ==, 0); + g_assert_cmpint (y, ==, 0); + hb_font_get_glyph_advance (font2, 1, x, y); + g_assert_cmpint (x, ==, 8); + g_assert_cmpint (y, ==, 9); +
[HarfBuzz] harfbuzz-ng: Branch 'master' - 5 commits
src/Makefile.am|4 - src/check-header-guards.sh | 20 + src/check-libstdc++.sh |1 src/hb-buffer-private.hh |6 - src/hb-font-private.hh |6 - src/hb-object-private.h|6 - src/hb-open-file-private.hh|1 src/hb-open-type-private.hh| 53 + src/hb-ot-layout-common-private.hh | 145 + src/hb-ot-layout-private.hh|6 - src/hb-ot-shape.h |2 11 files changed, 138 insertions(+), 112 deletions(-) New commits: commit cc8a4abea68f2dba26feb5785f9e518e6853c744 Author: Behdad Esfahbod beh...@behdad.org Date: Thu Jul 8 00:40:04 2010 -0400 Use bsearch where applicable diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 59c7866..9cc0518 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -394,6 +394,7 @@ struct IntType inline operator Type(void) const { return v; } inline bool operator == (const IntTypeType o) const { return v == o.v; } inline bool operator != (const IntTypeType o) const { return v != o.v; } + inline int cmp (Type b) const { Type a = v; return b a ? -1 : b == a ? 0 : +1; } inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); return likely (c-check_struct (this)); @@ -707,4 +708,52 @@ struct HeadlessArrayOf }; +/* An array with sorted elements. Supports binary searching. */ +template typename Type +struct SortedArrayOf : ArrayOfType { + + template typename SearchType + inline int search (const SearchType x) const { +class Cmp { + public: static int cmp (const void *p1, const void *p2) { + const SearchType *a = (const SearchType *) p1; + const Type *b = (const Type *) p2; + return b-cmp (*a); + } +}; +const Type *p = (const Type *) bsearch (x, this-array, this-len, sizeof (this-array[0]), Cmp::cmp); +return p ? p - this-array : -1; + } + + inline bool sanitize_order (hb_sanitize_context_t *c) { +/* Make sure the list is sorted, since we bsearch in it. */ +unsigned int count = this-len; +for (unsigned int i = 1; i count; i++) + if (unlikely (this-array[i].cmp (this-array[i-1]) 0)) { + /* We need to sort the entries. */ + if (!c-can_edit (this, this-get_size ())) return false; + class Cmp { + public: static int cmp (const void *p1, const void *p2) { + const Type *a = (const Type *) p1; + const Type *b = (const Type *) p2; + return b-cmp (*a); + } + }; + qsort (this-array, this-len, sizeof (this-array[0]), Cmp::cmp); + } +return true; + } + + inline bool sanitize (hb_sanitize_context_t *c) { +TRACE_SANITIZE (); +return ArrayOfType::sanitize (c) sanitize_order (c); + } + + inline bool sanitize (hb_sanitize_context_t *c, void *base) { +TRACE_SANITIZE (); +return ArrayOfType::sanitize (c, base) sanitize_order (c); + } +}; + + #endif /* HB_OPEN_TYPE_PRIVATE_HH */ diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index f965491..5954499 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -51,6 +51,14 @@ template typename Type struct Record { + inline int cmp (const Record other) const { +return cmp (other.tag); + } + inline int cmp (hb_tag_t b) const { +hb_tag_t a = tag; +return b a ? -1 : b == a ? 0 : -1; + } + inline bool sanitize (hb_sanitize_context_t *c, void *base) { TRACE_SANITIZE (); return c-check_struct (this) @@ -66,7 +74,7 @@ struct Record }; template typename Type -struct RecordArrayOf : ArrayOfRecordType { +struct RecordArrayOf : SortedArrayOfRecordType { inline const Tag get_tag (unsigned int i) const { if (unlikely (i = this-len)) return Null(Tag); @@ -86,21 +94,14 @@ struct RecordArrayOf : ArrayOfRecordType { } inline bool find_index (hb_tag_t tag, unsigned int *index) const { -Tag t; -t.set (tag); -/* TODO: bsearch (need to sort in sanitize) */ -const RecordType *a = this-array; -unsigned int count = this-len; -for (unsigned int i = 0; i count; i++) -{ - if (t == a[i].tag) - { +int i = this-search (tag); +if (i != -1) { if (index) *index = i; return true; - } +} else { + if (index) *index = Index::NOT_FOUND_INDEX; + return false; } -if (index) *index = Index::NOT_FOUND_INDEX; -return false; } }; @@ -117,6 +118,31 @@ struct RecordListOf : RecordArrayOfType }; +struct RangeRecord +{ + inline int cmp (const RangeRecord other) const { +hb_codepoint_t a = start, b = other.start; +return b a ? -1 : b == a ? 0 : +1; + } + inline int cmp (hb_codepoint_t g) const { +hb_codepoint_t a = start, b = end; +return g a ? -1 : g = b ? 0 : +1 ; + } + + inline bool