diff --git a/src/Makefile.sources b/src/Makefile.sources index 36a115286..f83d6dcc4 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -102,6 +102,7 @@ HB_OT_sources = \ hb-aat-layout-feat-table.hh \ hb-aat-layout-just-table.hh \ hb-aat-layout-kerx-table.hh \ + hb-aat-layout-lcar-table.hh \ hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh \ hb-aat-layout.hh \ diff --git a/src/hb-aat-layout-lcar-table.hh b/src/hb-aat-layout-lcar-table.hh new file mode 100644 index 000000000..e57836a08 --- /dev/null +++ b/src/hb-aat-layout-lcar-table.hh @@ -0,0 +1,92 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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. + */ +#ifndef HB_AAT_LAYOUT_LCAR_TABLE_HH +#define HB_AAT_LAYOUT_LCAR_TABLE_HH + +#include "hb-open-type.hh" +#include "hb-aat-layout-common.hh" + +/* + * lcar -- Ligature caret + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html + */ +#define HB_AAT_TAG_lcar HB_TAG('l','c','a','r') + + +namespace AAT { + +typedef ArrayOf LigCaretClassEntry; + +struct lcar +{ + static const hb_tag_t tableTag = HB_AAT_TAG_lcar; + + inline unsigned int get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph, + unsigned int start_offset, + unsigned int *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const + { + const OffsetTo* entry_offset = lookup.get_value (glyph, font->face->num_glyphs); + const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry); + if (caret_count && *caret_count) + { + const HBINT16 *arr = array.sub_array (start_offset, caret_count); + unsigned int count = *caret_count; + for (unsigned int i = 0; i < count; ++i) + switch (format) + { + case 0: caret_array[i] = font->em_scale_dir (arr[i], direction); break; + case 1: + hb_position_t x, y; + font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y); + caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; + break; + } + } + return array.len; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + version.major == 1 && + lookup.sanitize (c, this))); + } + + protected: + FixedVersion<>version; /* Version number of the ligature caret table */ + HBUINT16 format; /* Format of the ligature caret table. */ + Lookup > + lookup; /* data Lookup table associating glyphs */ + + public: + DEFINE_SIZE_MIN (8); +}; + +} /* namespace AAT */ + +#endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */ diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index f393d4b1b..4a36a4dcb 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -60,6 +60,7 @@ HB_OT_TABLE(AAT, kerx) \ HB_OT_TABLE(AAT, ankr) \ HB_OT_TABLE(AAT, trak) \ + HB_OT_TABLE(AAT, lcar) \ HB_OT_TABLE(AAT, ltag) \ /* OpenType variations. */ \ HB_OT_TABLE(OT, fvar) \ diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index ea5f1c07d..af7e5a833 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -123,10 +123,8 @@ struct CaretValueFormat2 inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const { hb_position_t x, y; - if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y)) - return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; - else - return 0; + font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y); + return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index eb5140fc2..33bf03c13 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -42,6 +42,8 @@ #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" +#include "hb-aat-layout-lcar-table.hh" + /** * SECTION:hb-ot-layout @@ -275,12 +277,15 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { - return font->face->table.GDEF->table->get_lig_carets (font, - direction, - glyph, - start_offset, - caret_count, - caret_array); + unsigned int result_caret_count = 0; + unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array); + if (result) + { + if (caret_count) *caret_count = result_caret_count; + } + else + result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); + return result; } diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 947832b81..4c329408f 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -74,6 +74,7 @@ endif TEST_PROGS += \ test-ot-color \ + test-ot-ligature-carets \ test-ot-name \ test-ot-tag \ $(NULL) diff --git a/test/api/fonts/lcar.ttf b/test/api/fonts/lcar.ttf new file mode 100644 index 000000000..4d176636e Binary files /dev/null and b/test/api/fonts/lcar.ttf differ diff --git a/test/api/test-ot-ligature-carets.c b/test/api/test-ot-ligature-carets.c new file mode 100644 index 000000000..d84278513 --- /dev/null +++ b/test/api/test-ot-ligature-carets.c @@ -0,0 +1,67 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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. + * + */ + +#include "hb-test.h" + +#include + +static void +test_ot_layout_feature_get_name_ids_and_characters (void) +{ + hb_face_t *face = hb_test_open_font_file ("fonts/lcar.ttf"); + hb_font_t *font = hb_font_create (face); + hb_font_set_scale (font, hb_face_get_upem (face) * 2, hb_face_get_upem (face) * 4); + + hb_position_t caret_array[2]; + unsigned int caret_count = 2; + g_assert_cmpuint (2, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_RTL, + 98, 0, &caret_count, + caret_array)); + + g_assert_cmpuint (2, ==, caret_count); + g_assert_cmpuint (1130, ==, caret_array[0]); + g_assert_cmpuint (2344, ==, caret_array[1]); + + g_assert_cmpuint (2, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_BTT, + 98, 0, &caret_count, + caret_array)); + + g_assert_cmpuint (2, ==, caret_count); + g_assert_cmpuint (2260, ==, caret_array[0]); + g_assert_cmpuint (4688, ==, caret_array[1]); + + hb_font_destroy (font); + hb_face_destroy (face); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + hb_test_add (test_ot_layout_feature_get_name_ids_and_characters); + + return hb_test_run (); +}