diff options
author | Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org> | 2015-06-19 14:17:47 +0200 |
---|---|---|
committer | Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org> | 2015-06-19 14:17:47 +0200 |
commit | 31873b7a42c718cda5c7d07d7ca68bc317a17a59 (patch) | |
tree | fdc703c19520b49046d049ab62a34e8f13142656 | |
parent | 2111a9cce5b3c8f5d14111a185f99dff5735e1da (diff) | |
parent | a6446d44e6d04e1eeea994682e29f9cb6265f7f6 (diff) | |
download | harfbuzz_ng-linaro-upstream-0.9.41.tar.gz |
Merge update to 0.9.41linaro-upstream-0.9.41
60 files changed, 1062 insertions, 415 deletions
diff --git a/.travis.yml b/.travis.yml index 4b3e0f888..3f7378b2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ env: - CFLAGS="-Werror --coverage" - CXXFLAGS="-Werror --coverage" - LDFLAGS="--coverage" + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "RoR4NtzEDTR8QKmLVuy2wN+YGXuq8VcgVvDuFJDdOdIbtX+kQStesJXDcf1y0G1T8Ripjn9JGXBd9eoUwNc8sJpxNwKZBkIPi42FuK6e/cZZRYlgUyi5df0fQJ8VSCDU7OoZJq3pAtTe8mQPeeuk5G7cKRSsJVt8e03K7PQcU6Y=" install: - sudo apt-get install pkg-config ragel gtk-doc-tools # for autogen.sh - sudo apt-get install libfreetype6-dev # for font functions @@ -15,6 +18,7 @@ install: - sudo apt-get install libcairo2-dev # for utils - sudo apt-get install libicu-dev # for extra unicode functions - sudo apt-get install libgraphite2-dev # for extra shapers + - #sudo apt-get install libgirepository1.0-dev # for gobject-introspection - sudo pip install cpp-coveralls # for coveralls.io code coverage tracking script: - NOCONFIGURE=1 ./autogen.sh @@ -23,3 +27,13 @@ script: notifications: irc: "irc.freenode.org#harfbuzz" email: harfbuzz@lists.freedesktop.org + +addons: + coverity_scan: + project: + name: "behdad/harfbuzz" + description: "Build submitted via Travis CI" + notification_email: coverity@behdad.org + build_command_prepend: "./configure; make clean" + build_command: "make -j 4" + branch_pattern: master @@ -1,3 +1,13 @@ +Overview of changes leading to 0.9.41 +Thursday, June 18, 2015 +===================================== + +- Fix hb-coretext with trailing whitespace in right-to-left. +- New API: hb_buffer_reverse_range(). +- Allow implementing atomic ops in config.h. +- Fix hb_language_t in language bindings. +- Misc fixes. + Overview of changes leading to 0.9.40 Friday, March 20, 2015 ===================================== @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz) [![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz) +[![Coverity Scan](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/5450) This is HarfBuzz, a text shaping library. diff --git a/README.python b/README.python index eabdf5bbb..cd312649d 100644 --- a/README.python +++ b/README.python @@ -1,6 +1,10 @@ To enable HarfBuzz bindings for Python among other languages, make sure -you have latest version of gobject-introspection compiled, and then -run autogen.sh (if building from git), and then: +you have latest version of gobject-introspection available. On Ubuntu, +you can install that this way: + + sudo apt-get install libgirepository1.0-dev + +And then run autogen.sh (if building from git), and then: ./configure --with-gobject --enable-introspection diff --git a/configure.ac b/configure.ac index 5baad1fc7..4d2bbf81e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [0.9.40], + [0.9.41], [http://bugs.freedesktop.org/enter_bug.cgi?product=harfbuzz], [harfbuzz], [http://harfbuzz.org/]) @@ -235,6 +235,24 @@ AM_CONDITIONAL(HAVE_CAIRO_FT, $have_cairo_ft) dnl ========================================================================== +AC_ARG_WITH(fontconfig, + [AS_HELP_STRING([--with-fontconfig=@<:@yes/no/auto@:>@], + [Use fontconfig @<:@default=auto@:>@])],, + [with_fontconfig=auto]) +have_fontconfig=false +if test "x$with_fontconfig" = "xyes" -o "x$with_fontconfig" = "xauto"; then + PKG_CHECK_MODULES(FONTCONFIG, fontconfig, have_fontconfig=true, :) +fi +if test "x$with_fontconfig" = "xyes" -a "x$have_fontconfig" != "xtrue"; then + AC_MSG_ERROR([fontconfig support requested but not found]) +fi +if $have_fontconfig; then + AC_DEFINE(HAVE_FONTCONFIG, 1, [Have fontconfig library]) +fi +AM_CONDITIONAL(HAVE_FONTCONFIG, $have_fontconfig) + +dnl ========================================================================== + AC_ARG_WITH(icu, [AS_HELP_STRING([--with-icu=@<:@yes/no/auto@:>@], [Use ICU @<:@default=auto@:>@])],, @@ -438,6 +456,7 @@ Font callbacks (the more the better): Tools used for command-line utilities: Cairo: ${have_cairo} + Fontconfig: ${have_fontconfig} Additional shapers (the more the better): Graphite2: ${have_graphite2} diff --git a/src/check-libstdc++.sh b/src/check-libstdc++.sh index 27deb42dc..b541828bc 100755 --- a/src/check-libstdc++.sh +++ b/src/check-libstdc++.sh @@ -19,9 +19,9 @@ for suffix in so dylib; do so=.libs/libharfbuzz.$suffix if ! test -f "$so"; then continue; fi - echo "Checking that we are not linking to libstdc++" - if ldd $so | grep 'libstdc[+][+]'; then - echo "Ouch, linked to libstdc++" + echo "Checking that we are not linking to libstdc++ or libc++" + if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then + echo "Ouch, linked to libstdc++ or libc++" stat=1 fi tested=true diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh index e6738b7d9..8179571ad 100644 --- a/src/hb-atomic-private.hh +++ b/src/hb-atomic-private.hh @@ -39,7 +39,11 @@ /* We need external help for these */ -#if 0 +#if defined(hb_atomic_int_impl_add) \ + && defined(hb_atomic_ptr_impl_get) \ + && defined(hb_atomic_ptr_impl_cmpexch) + +/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */ #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -58,11 +62,12 @@ static inline void _HBMemoryBarrier (void) { #endif } -typedef LONG hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) +typedef LONG hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) +#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -74,28 +79,31 @@ typedef LONG hb_atomic_int_t; #include <Availability.h> #endif -typedef int32_t hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) -#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P)) +typedef int32_t hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) + +#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) #else #if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) #else -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) #endif #endif #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) -#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) +#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) #elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) @@ -103,33 +111,54 @@ typedef int hb_atomic_int_t; #include <atomic.h> #include <mbarrier.h> -typedef unsigned int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) +typedef unsigned int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) +#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) #elif !defined(HB_NO_MT) #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ -typedef volatile int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) +typedef volatile int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) #else /* HB_NO_MT */ -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) #endif -/* TODO Add tracing. */ + +#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)} + +struct hb_atomic_int_t +{ + hb_atomic_int_impl_t v; + + inline void set_unsafe (int v_) { v = v_; } + inline int get_unsafe (void) const { return v; } + inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); } + inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); } +}; + + +#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P) +#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N)) + #endif /* HB_ATOMIC_PRIVATE_HH */ diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl index 8856580fb..8a682f737 100644 --- a/src/hb-buffer-deserialize-text.rl +++ b/src/hb-buffer-deserialize-text.rl @@ -111,8 +111,8 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, const char *eof = pe, *tok = NULL; int cs; - hb_glyph_info_t info; - hb_glyph_position_t pos; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; %%{ write init; write exec; diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index b9fe263ce..e13ee4a45 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -36,6 +36,9 @@ #endif +/** + * Since: 0.9.7 + **/ hb_bool_t hb_segment_properties_equal (const hb_segment_properties_t *a, const hb_segment_properties_t *b) @@ -48,6 +51,9 @@ hb_segment_properties_equal (const hb_segment_properties_t *a, } +/** + * Since: 0.9.7 + **/ unsigned int hb_segment_properties_hash (const hb_segment_properties_t *p) { @@ -804,7 +810,7 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_buffer_set_content_type (hb_buffer_t *buffer, @@ -821,7 +827,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.5 **/ hb_buffer_content_type_t hb_buffer_get_content_type (hb_buffer_t *buffer) @@ -967,7 +973,7 @@ hb_buffer_set_language (hb_buffer_t *buffer, * * * - * Return value: + * Return value: (transfer none): * * Since: 1.0 **/ @@ -984,7 +990,7 @@ hb_buffer_get_language (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_segment_properties (hb_buffer_t *buffer, @@ -999,11 +1005,11 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_get_segment_properties: * @buffer: a buffer. - * @props: + * @props: (out): * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_get_segment_properties (hb_buffer_t *buffer, @@ -1020,7 +1026,7 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_flags (hb_buffer_t *buffer, @@ -1040,7 +1046,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer) @@ -1056,7 +1062,7 @@ hb_buffer_get_flags (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, @@ -1076,7 +1082,7 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.31 **/ hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) @@ -1105,7 +1111,7 @@ hb_buffer_reset (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.11 **/ void hb_buffer_clear_contents (hb_buffer_t *buffer) @@ -1283,6 +1289,23 @@ hb_buffer_reverse (hb_buffer_t *buffer) } /** + * hb_buffer_reverse_range: + * @buffer: a buffer. + * @start: start index. + * @end: end index. + * + * Reverses buffer contents between start to end. + * + * Since: 1.0 + **/ +void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + buffer->reverse_range (start, end); +} + +/** * hb_buffer_reverse_clusters: * @buffer: a buffer. * @@ -1320,7 +1343,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer) @@ -1473,7 +1496,7 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.39 **/ void hb_buffer_add_latin1 (hb_buffer_t *buffer, @@ -1495,7 +1518,7 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_add_codepoints (hb_buffer_t *buffer, @@ -1569,7 +1592,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) diff --git a/src/hb-buffer.h b/src/hb-buffer.h index e5b46d867..520141b8a 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -222,6 +222,10 @@ void hb_buffer_reverse (hb_buffer_t *buffer); void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end); + +void hb_buffer_reverse_clusters (hb_buffer_t *buffer); diff --git a/src/hb-common.cc b/src/hb-common.cc index 05a1f9ce1..21d3b4117 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -57,7 +57,7 @@ _hb_options_init (void) /** * hb_tag_from_string: - * @str: (array length=len): + * @str: (array length=len) (element-type uint8_t): * @len: * * @@ -92,7 +92,7 @@ hb_tag_from_string (const char *str, int len) * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_tag_to_string (hb_tag_t tag, char *buf) @@ -115,7 +115,7 @@ const char direction_strings[][4] = { /** * hb_direction_from_string: - * @str: (array length=len): + * @str: (array length=len) (element-type uint8_t): * @len: * * @@ -179,7 +179,7 @@ static const char canon_map[256] = { 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 }; -static hb_bool_t +static bool lang_equal (hb_language_t v1, const void *v2) { @@ -281,12 +281,12 @@ retry: /** * hb_language_from_string: - * @str: (array length=len): + * @str: (array length=len) (element-type uint8_t): * @len: * * * - * Return value: + * Return value: (transfer none): * * Since: 1.0 **/ @@ -334,7 +334,7 @@ hb_language_to_string (hb_language_t language) * * * - * Return value: + * Return value: (transfer none): * * Since: 1.0 **/ @@ -401,7 +401,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) /** * hb_script_from_string: - * @s: (array length=len): + * @s: (array length=len) (element-type uint8_t): * @len: * * @@ -579,7 +579,7 @@ hb_version_string (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.30 **/ hb_bool_t hb_version_atleast (unsigned int major, diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 4a4517528..0b710c2b7 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -788,6 +788,17 @@ retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; double advances_so_far = 0; + /* For right-to-left runs, CoreText returns the glyphs positioned such that + * any trailing whitespace is to the left of (0,0). Adjust coordinate system + * to fix for that. Test with any RTL string with trailing spaces. + * https://code.google.com/p/chromium/issues/detail?id=469028 + */ + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + { + advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); + if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) + advances_so_far = -advances_so_far; + } const CFRange range_all = CFRangeMake (0, 0); diff --git a/src/hb-face.cc b/src/hb-face.cc index 9348af7bf..96ea1da46 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -165,8 +165,8 @@ hb_face_create (hb_blob_t *blob, { hb_face_t *face; - if (unlikely (!blob || !hb_blob_get_length (blob))) - return hb_face_get_empty (); + if (unlikely (!blob)) + blob = hb_blob_get_empty (); hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); @@ -347,7 +347,7 @@ hb_face_reference_table (hb_face_t *face, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_face_reference_blob (hb_face_t *face) @@ -362,7 +362,7 @@ hb_face_reference_blob (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_index (hb_face_t *face, @@ -382,7 +382,7 @@ hb_face_set_index (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_face_get_index (hb_face_t *face) @@ -397,7 +397,7 @@ hb_face_get_index (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_upem (hb_face_t *face, @@ -441,7 +441,7 @@ hb_face_t::load_upem (void) const * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_face_set_glyph_count (hb_face_t *face, @@ -461,7 +461,7 @@ hb_face_set_glyph_count (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ unsigned int hb_face_get_glyph_count (hb_face_t *face) diff --git a/src/hb-font.cc b/src/hb-font.cc index 4364ca72f..0cfba837a 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -604,7 +604,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_name (hb_font_t *font, @@ -625,7 +625,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_from_name (hb_font_t *font, @@ -800,7 +800,7 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_glyph_to_string (hb_font_t *font, @@ -814,7 +814,7 @@ hb_font_glyph_to_string (hb_font_t *font, /** * hb_font_glyph_from_string: * @font: a font. - * @s: (array length=len): + * @s: (array length=len) (element-type uint8_t): * @len: * @glyph: (out): * @@ -822,7 +822,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_glyph_from_string (hb_font_t *font, @@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face) if (unlikely (!face)) face = hb_face_get_empty (); - if (unlikely (hb_object_is_inert (face))) - return hb_font_get_empty (); if (!(font = hb_object_create<hb_font_t> ())) return hb_font_get_empty (); @@ -880,7 +878,7 @@ hb_font_t * hb_font_create_sub_font (hb_font_t *parent) { if (unlikely (!parent)) - return hb_font_get_empty (); + parent = hb_font_get_empty (); hb_font_t *font = hb_font_create (parent->face); @@ -1080,7 +1078,7 @@ hb_font_get_parent (hb_font_t *font) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_font_get_face (hb_font_t *font) @@ -1098,7 +1096,7 @@ hb_font_get_face (hb_font_t *font) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs (hb_font_t *font, @@ -1133,7 +1131,7 @@ hb_font_set_funcs (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs_data (hb_font_t *font, diff --git a/src/hb-font.h b/src/hb-font.h index 7273db43e..cf22589ec 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -292,7 +292,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, @@ -308,7 +308,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 322f93a8e..468742cfd 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -75,15 +75,19 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { + unsigned int g; FT_Face ft_face = (FT_Face) font_data; - if (unlikely (variation_selector)) { - *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); - return *glyph != 0; - } + if (likely (!variation_selector)) + g = FT_Get_Char_Index (ft_face, unicode); + else + g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); - *glyph = FT_Get_Char_Index (ft_face, unicode); - return *glyph != 0; + if (unlikely (!g)) + return false; + + *glyph = g; + return true; } static hb_position_t @@ -377,7 +381,7 @@ hb_ft_face_create (FT_Face ft_face, * * * Return value: (transfer full): - * Since: 1.0 + * Since: 0.9.38 **/ hb_face_t * hb_ft_face_create_referenced (FT_Face ft_face) @@ -464,7 +468,7 @@ hb_ft_font_create (FT_Face ft_face, * * * Return value: (transfer full): - * Since: 1.0 + * Since: 0.9.38 **/ hb_font_t * hb_ft_font_create_referenced (FT_Face ft_face) diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 61dff5e3d..7dbd83d29 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -382,6 +382,9 @@ hb_glib_get_unicode_funcs (void) return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs); } +/** + * Since: 0.9.38 + **/ hb_blob_t * hb_glib_blob_create (GBytes *gbytes) { diff --git a/src/hb-gobject-structs.cc b/src/hb-gobject-structs.cc index 2451b6629..6bd63368b 100644 --- a/src/hb-gobject-structs.cc +++ b/src/hb-gobject-structs.cc @@ -54,6 +54,17 @@ hb_gobject_##name##_get_type (void) \ #define HB_DEFINE_OBJECT_TYPE(name) \ HB_DEFINE_BOXED_TYPE (name, hb_##name##_reference, hb_##name##_destroy); +#define HB_DEFINE_VALUE_TYPE(name) \ + static hb_##name##_t *_hb_##name##_reference (const hb_##name##_t *l) \ + { \ + hb_##name##_t *c = (hb_##name##_t *) calloc (1, sizeof (hb_##name##_t)); \ + if (unlikely (!c)) return NULL; \ + *c = *l; \ + return c; \ + } \ + static void _hb_##name##_destroy (hb_##name##_t *l) { free (l); } \ + HB_DEFINE_BOXED_TYPE (name, _hb_##name##_reference, _hb_##name##_destroy); + HB_DEFINE_OBJECT_TYPE (buffer) HB_DEFINE_OBJECT_TYPE (blob) HB_DEFINE_OBJECT_TYPE (face) @@ -62,59 +73,8 @@ HB_DEFINE_OBJECT_TYPE (font_funcs) HB_DEFINE_OBJECT_TYPE (set) HB_DEFINE_OBJECT_TYPE (shape_plan) HB_DEFINE_OBJECT_TYPE (unicode_funcs) - - -static hb_feature_t *feature_reference (hb_feature_t *g) -{ - hb_feature_t *c = (hb_feature_t *) calloc (1, sizeof (hb_feature_t)); - if (unlikely (!c)) return NULL; - *c = *g; - return c; -} -static void feature_destroy (hb_feature_t *g) { free (g); } -HB_DEFINE_BOXED_TYPE (feature, feature_reference, feature_destroy) - -static hb_glyph_info_t *glyph_info_reference (hb_glyph_info_t *g) -{ - hb_glyph_info_t *c = (hb_glyph_info_t *) calloc (1, sizeof (hb_glyph_info_t)); - if (unlikely (!c)) return NULL; - *c = *g; - return c; -} -static void glyph_info_destroy (hb_glyph_info_t *g) { free (g); } -HB_DEFINE_BOXED_TYPE (glyph_info, glyph_info_reference, glyph_info_destroy) - -static hb_glyph_position_t *glyph_position_reference (hb_glyph_position_t *g) -{ - hb_glyph_position_t *c = (hb_glyph_position_t *) calloc (1, sizeof (hb_glyph_position_t)); - if (unlikely (!c)) return NULL; - *c = *g; - return c; -} -static void glyph_position_destroy (hb_glyph_position_t *g) { free (g); } -HB_DEFINE_BOXED_TYPE (glyph_position, glyph_position_reference, glyph_position_destroy) - -static hb_segment_properties_t *segment_properties_reference (hb_segment_properties_t *g) -{ - hb_segment_properties_t *c = (hb_segment_properties_t *) calloc (1, sizeof (hb_segment_properties_t)); - if (unlikely (!c)) return NULL; - *c = *g; - return c; -} -static void segment_properties_destroy (hb_segment_properties_t *g) { free (g); } -HB_DEFINE_BOXED_TYPE (segment_properties, segment_properties_reference, segment_properties_destroy) - -static hb_user_data_key_t user_data_key_reference (hb_user_data_key_t l) { return l; } -static void user_data_key_destroy (hb_user_data_key_t l) { } -HB_DEFINE_BOXED_TYPE (user_data_key, user_data_key_reference, user_data_key_destroy) - - -static hb_language_t *language_reference (hb_language_t *l) -{ - hb_language_t *c = (hb_language_t *) calloc (1, sizeof (hb_language_t)); - if (unlikely (!c)) return NULL; - *c = *l; - return c; -} -static void language_destroy (hb_language_t *l) { free (l); } -HB_DEFINE_BOXED_TYPE (language, language_reference, language_destroy) +HB_DEFINE_VALUE_TYPE (feature) +HB_DEFINE_VALUE_TYPE (glyph_info) +HB_DEFINE_VALUE_TYPE (glyph_position) +HB_DEFINE_VALUE_TYPE (segment_properties) +HB_DEFINE_VALUE_TYPE (user_data_key) diff --git a/src/hb-gobject-structs.h b/src/hb-gobject-structs.h index 4a88d569e..0a0387dce 100644 --- a/src/hb-gobject-structs.h +++ b/src/hb-gobject-structs.h @@ -40,18 +40,33 @@ HB_BEGIN_DECLS /* Object types */ +/** + * Since: 0.9.2 + **/ GType hb_gobject_blob_get_type (void); #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) +/** + * Since: 0.9.2 + **/ GType hb_gobject_buffer_get_type (void); #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) +/** + * Since: 0.9.2 + **/ GType hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) +/** + * Since: 0.9.2 + **/ GType hb_gobject_font_get_type (void); #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) +/** + * Since: 0.9.2 + **/ GType hb_gobject_font_funcs_get_type (void); #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) @@ -61,6 +76,9 @@ GType hb_gobject_set_get_type (void); GType hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) +/** + * Since: 0.9.2 + **/ GType hb_gobject_unicode_funcs_get_type (void); #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) @@ -81,14 +99,6 @@ GType hb_gobject_segment_properties_get_type (void); GType hb_gobject_user_data_key_get_type (void); #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ()) -/* Currently gobject-introspection doesn't understand that hb_language_t - * can be passed by-value. As such we box it up. May remove in the - * future. - * - * https://bugzilla.gnome.org/show_bug.cgi?id=707656 - */ -GType hb_gobject_language_get_type (void); -#define HB_GOBJECT_TYPE_LANGUAGE (hb_gobject_language_get_type ()) HB_END_DECLS diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index a8ea39ccf..ed2703571 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -39,7 +39,13 @@ /* We need external help for these */ -#if 0 +#if defined(HB_MUTEX_IMPL_INIT) \ + && defined(hb_mutex_impl_init) \ + && defined(hb_mutex_impl_lock) \ + && defined(hb_mutex_impl_unlock) \ + && defined(hb_mutex_impl_finish) + +/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -113,10 +119,12 @@ typedef int hb_mutex_impl_t; #define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END + #endif #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} + struct hb_mutex_t { /* TODO Add tracing. */ diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 7bd0f1624..635d62dc1 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -47,19 +47,20 @@ /* reference_count */ -#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) -#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} +#define HB_REFERENCE_COUNT_INVALID_VALUE -1 +#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INVALID_VALUE)} + struct hb_reference_count_t { hb_atomic_int_t ref_count; - inline void init (int v) { ref_count = v; } - inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); } - inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); } - inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; } - - inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; } + inline void init (int v) { ref_count.set_unsafe (v); } + inline int get_unsafe (void) const { return ref_count.get_unsafe (); } + inline int inc (void) { return ref_count.inc (); } + inline int dec (void) { return ref_count.dec (); } + inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_INVALID_VALUE); } + inline bool is_invalid (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INVALID_VALUE; } }; @@ -102,7 +103,7 @@ struct hb_object_header_t hb_reference_count_t ref_count; hb_user_data_array_t user_data; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT} private: ASSERT_POD (); @@ -117,7 +118,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) DEBUG_MSG (OBJECT, (void *) obj, "%s refcount=%d", function, - obj ? obj->header.ref_count.ref_count : 0); + obj ? obj->header.ref_count.get_unsafe () : 0); } template <typename Type> diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 2af2f54a7..df6514dd3 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -45,9 +45,9 @@ struct hb_ot_face_metrics_accelerator_t inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, - unsigned int default_advance) + unsigned int default_advance_) { - this->default_advance = default_advance; + this->default_advance = default_advance_; this->num_metrics = face->get_num_glyphs (); hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag)); @@ -114,6 +114,7 @@ struct hb_ot_face_cmap_accelerator_t if (!subtable) subtable = cmap->find_subtable (0, 2); if (!subtable) subtable = cmap->find_subtable (0, 1); if (!subtable) subtable = cmap->find_subtable (0, 0); + if (!subtable) subtable = cmap->find_subtable (3, 0); /* Meh. */ if (!subtable) subtable = &OT::Null(OT::CmapSubtable); @@ -219,7 +220,7 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph)); + return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t @@ -334,6 +335,9 @@ _hb_ot_get_font_funcs (void) } +/** + * Since: 0.9.28 + **/ void hb_ot_font_set_funcs (hb_font_t *font) { diff --git a/src/hb-ot-font.h b/src/hb-ot-font.h index 7a8c04ac3..b9947a16b 100644 --- a/src/hb-ot-font.h +++ b/src/hb-ot-font.h @@ -24,6 +24,10 @@ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader */ +#ifndef HB_OT_H_IN +#error "Include <hb-ot.h> instead." +#endif + #ifndef HB_OT_FONT_H #define HB_OT_FONT_H diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index d88f7876e..69609d06c 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1450,7 +1450,6 @@ struct PosLookup : Lookup { TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTable> (); return TRACE_RETURN (dispatch (c)); } }; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index ebe4c9ec4..ad1339dc6 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1222,7 +1222,6 @@ struct SubstLookup : Lookup { TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - const OffsetArrayOf<SubstLookupSubTable> &list = get_subtables<SubstLookupSubTable> (); if (unlikely (!dispatch (c))) return TRACE_RETURN (false); if (unlikely (get_type () == SubstLookupSubTable::Extension)) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index cbc6840bc..842be880d 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -516,39 +516,39 @@ struct hb_apply_context_t inline bool match_properties_mark (hb_codepoint_t glyph, unsigned int glyph_props, - unsigned int lookup_props) const + unsigned int match_props) const { /* If using mark filtering sets, the high short of - * lookup_props has the set index. + * match_props has the set index. */ - if (lookup_props & LookupFlag::UseMarkFilteringSet) - return gdef.mark_set_covers (lookup_props >> 16, glyph); + if (match_props & LookupFlag::UseMarkFilteringSet) + return gdef.mark_set_covers (match_props >> 16, glyph); - /* The second byte of lookup_props has the meaning + /* The second byte of match_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); + if (match_props & LookupFlag::MarkAttachmentType) + return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); return true; } inline bool check_glyph_property (const hb_glyph_info_t *info, - unsigned int lookup_props) const + unsigned int match_props) const { hb_codepoint_t glyph = info->codepoint; unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); /* Not covered, if, for example, glyph class is ligature and - * lookup_props includes LookupFlags::IgnoreLigatures + * match_props includes LookupFlags::IgnoreLigatures */ - if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) + if (glyph_props & match_props & LookupFlag::IgnoreFlags) return false; if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return match_properties_mark (glyph, glyph_props, lookup_props); + return match_properties_mark (glyph, glyph_props, match_props); return true; } diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index b1e69e89f..05ea0603c 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -128,6 +128,9 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face) return _get_gdef (face).has_glyph_classes (); } +/** + * Since: 0.9.7 + **/ hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, hb_codepoint_t glyph) @@ -135,6 +138,9 @@ hb_ot_layout_get_glyph_class (hb_face_t *face, return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, @@ -335,6 +341,9 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, NULL); } +/** + * Since: 0.9.30 + **/ hb_bool_t hb_ot_layout_language_get_required_feature (hb_face_t *face, hb_tag_t table_tag, @@ -419,6 +428,9 @@ hb_ot_layout_language_find_feature (hb_face_t *face, return false; } +/** + * Since: 0.9.7 + **/ unsigned int hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -433,6 +445,9 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); } +/** + * Since: 0.9.22 + **/ unsigned int hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag) @@ -590,6 +605,9 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face, } } +/** + * Since: 0.9.8 + **/ void hb_ot_layout_collect_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -631,6 +649,9 @@ hb_ot_layout_collect_lookups (hb_face_t *face, } } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, @@ -676,6 +697,9 @@ hb_ot_layout_has_substitution (hb_face_t *face) return &_get_gsub (face) != &OT::Null(OT::GSUB); } +/** + * Since: 0.9.7 + **/ hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, @@ -714,6 +738,9 @@ hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_finish (font, buffer); } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, @@ -748,6 +775,9 @@ hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) OT::GPOS::position_finish (font, buffer); } +/** + * Since: 0.9.8 + **/ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index e268933ce..4dc4f58d7 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -179,9 +179,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_PSALTER_PAHLAVI: /* For Arabic script, use the Arabic shaper even if no OT script tag was found. - * This is because we do fallback shaping for Arabic script (and not others). */ - if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || - planner->props.script == HB_SCRIPT_ARABIC) + * This is because we do fallback shaping for Arabic script (and not others). + * But note that Arabic shaping is applicable only to horizontal layout; for + * vertical text, just use the generic shaper instead. */ + if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || + planner->props.script == HB_SCRIPT_ARABIC) && + HB_DIRECTION_IS_HORIZONTAL(planner->props.direction)) return &_hb_ot_complex_shaper_arabic; else return &_hb_ot_complex_shaper_default; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 07adb04f6..5fb0e0537 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -736,6 +736,9 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, } +/** + * Since: 0.9.7 + **/ void hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, @@ -766,6 +769,9 @@ add_char (hb_font_t *font, } +/** + * Since: 0.9.2 + **/ void hb_ot_shape_glyphs_closure (hb_font_t *font, hb_buffer_t *buffer, diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 878dd79b6..61c38b196 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -175,6 +175,11 @@ typedef struct { * * Some items still missing. Those are commented out at the end. * Keep sorted for bsearch. + * + * Updated as of 2015-05-06: OT1.7 on MS website has some newer + * items that we don't have here, eg. Zazaki. This is the new + * items in OpenType 1.7 (red items), most of which we have: + * http://www.microsoft.com/typography/otspec170/languagetags.htm */ static const LangTag ot_languages[] = { @@ -217,9 +222,9 @@ static const LangTag ot_languages[] = { {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ - {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ + {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ - {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ + {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */ @@ -346,9 +351,9 @@ static const LangTag ot_languages[] = { {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ {"har", HB_TAG('H','R','I',' ')}, /* Harari */ - {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ - {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ - {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ + {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ + {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ + {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ @@ -542,6 +547,7 @@ static const LangTag ot_languages[] = { {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */ + {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */ {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ @@ -864,6 +870,15 @@ hb_ot_tag_from_language (hb_language_t language) return HB_OT_TAG_DEFAULT_LANGUAGE; } +/** + * hb_ot_tag_to_language: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ hb_language_t hb_ot_tag_to_language (hb_tag_t tag) { diff --git a/src/hb-private.hh b/src/hb-private.hh index 06b24a80f..45afc20b1 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -121,16 +121,17 @@ # if defined(_WIN32_WCE) /* Some things not defined on Windows CE. */ +# define strdup _strdup # define getenv(Name) NULL -# define setlocale(Category, Locale) "C" +# if _WIN32_WCE < 0x800 +# define setlocale(Category, Locale) "C" static int errno = 0; /* Use something better? */ +# endif # elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) # define getenv(Name) NULL # endif -# if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) +# if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf - /* Windows CE only has _strdup, while rest of Windows has both. */ -# define strdup _strdup # endif #endif @@ -246,8 +247,8 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4); /* Void! */ struct _hb_void_t {}; -typedef const _hb_void_t &hb_void_t; -#define HB_VOID (* (const _hb_void_t *) NULL) +typedef const _hb_void_t *hb_void_t; +#define HB_VOID ((const _hb_void_t *) NULL) /* Return the number of 1 bits in mask. */ static inline HB_CONST_FUNC unsigned int diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index acba4e946..bba401517 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -354,7 +354,6 @@ struct hb_frozen_set_t return; unsigned int min = set.get_min (); const elt_t &min_elt = set.elt (min); - const elt_t &max_elt = set.elt (max); start = min & ~MASK; count = max - start + 1; diff --git a/src/hb-set.cc b/src/hb-set.cc index 59a0af46e..cb7fcdbf6 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -35,7 +35,7 @@ * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_create (void) @@ -55,7 +55,7 @@ hb_set_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_get_empty (void) @@ -76,7 +76,7 @@ hb_set_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_reference (hb_set_t *set) @@ -88,7 +88,7 @@ hb_set_reference (hb_set_t *set) * hb_set_destroy: (skip) * @set: a set. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_destroy (hb_set_t *set) @@ -110,7 +110,7 @@ hb_set_destroy (hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_set_user_data (hb_set_t *set, @@ -129,7 +129,7 @@ hb_set_set_user_data (hb_set_t *set, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_set_get_user_data (hb_set_t *set, @@ -147,7 +147,7 @@ hb_set_get_user_data (hb_set_t *set, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) @@ -161,7 +161,7 @@ hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_clear (hb_set_t *set) @@ -177,7 +177,7 @@ hb_set_clear (hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_is_empty (const hb_set_t *set) @@ -194,7 +194,7 @@ hb_set_is_empty (const hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_has (const hb_set_t *set, @@ -210,7 +210,7 @@ hb_set_has (const hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_add (hb_set_t *set, @@ -227,7 +227,7 @@ hb_set_add (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_set_add_range (hb_set_t *set, @@ -244,7 +244,7 @@ hb_set_add_range (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_del (hb_set_t *set, @@ -261,7 +261,7 @@ hb_set_del (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_set_del_range (hb_set_t *set, @@ -280,7 +280,7 @@ hb_set_del_range (hb_set_t *set, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_is_equal (const hb_set_t *set, @@ -296,7 +296,7 @@ hb_set_is_equal (const hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_set (hb_set_t *set, @@ -312,7 +312,7 @@ hb_set_set (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_union (hb_set_t *set, @@ -328,7 +328,7 @@ hb_set_union (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_intersect (hb_set_t *set, @@ -344,7 +344,7 @@ hb_set_intersect (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_subtract (hb_set_t *set, @@ -360,7 +360,7 @@ hb_set_subtract (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_symmetric_difference (hb_set_t *set, @@ -375,7 +375,7 @@ hb_set_symmetric_difference (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.10 **/ void hb_set_invert (hb_set_t *set) @@ -391,7 +391,7 @@ hb_set_invert (hb_set_t *set) * * Return value: set population. * - * Since: 1.0 + * Since: 0.9.7 **/ unsigned int hb_set_get_population (const hb_set_t *set) @@ -407,7 +407,7 @@ hb_set_get_population (const hb_set_t *set) * * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_codepoint_t hb_set_get_min (const hb_set_t *set) @@ -423,7 +423,7 @@ hb_set_get_min (const hb_set_t *set) * * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_codepoint_t hb_set_get_max (const hb_set_t *set) @@ -440,7 +440,7 @@ hb_set_get_max (const hb_set_t *set) * * Return value: whether there was a next value. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_next (const hb_set_t *set, @@ -460,7 +460,7 @@ hb_set_next (const hb_set_t *set, * * Return value: whether there was a next range. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_next_range (const hb_set_t *set, diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 2166173f9..d2f293d69 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -106,7 +106,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_create (hb_face_t *face, @@ -126,7 +126,7 @@ hb_shape_plan_create (hb_face_t *face, if (unlikely (!face)) face = hb_face_get_empty (); - if (unlikely (!props || hb_object_is_inert (face))) + if (unlikely (!props)) return hb_shape_plan_get_empty (); if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t)))) return hb_shape_plan_get_empty (); @@ -158,7 +158,7 @@ hb_shape_plan_create (hb_face_t *face, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_get_empty (void) @@ -194,7 +194,7 @@ hb_shape_plan_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_reference (hb_shape_plan_t *shape_plan) @@ -208,7 +208,7 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) @@ -236,7 +236,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, @@ -257,7 +257,7 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.7 **/ void * hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, @@ -279,7 +279,7 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_shape_plan_execute (hb_shape_plan_t *shape_plan, @@ -294,7 +294,6 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, shape_plan->shaper_func); if (unlikely (hb_object_is_inert (shape_plan) || - hb_object_is_inert (font) || hb_object_is_inert (buffer))) return false; @@ -396,7 +395,7 @@ hb_non_global_user_features_present (const hb_feature_t *user_features, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_create_cached (hb_face_t *face, @@ -453,6 +452,10 @@ retry: hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + /* Don't add to the cache if face is inert. */ + if (unlikely (hb_object_is_inert (face))) + return shape_plan; + /* Don't add the plan to the cache if there were user features with non-global ranges */ if (hb_non_global_user_features_present (user_features, num_user_features)) @@ -483,7 +486,7 @@ retry: * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.7 **/ const char * hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 9a59c0855..5ddde5ad5 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -33,6 +33,17 @@ #include "hb-buffer-private.hh" #include "hb-font-private.hh" +/** + * SECTION:hb-shape + * @title: Shaping + * @short_description: Conversion of text strings into positioned glyphs + * @include: hb.h + * + * Shaping is the central operation of HarfBuzz. Shaping operates on buffers, + * which are sequences of Unicode characters that use the same font and have + * the same text direction, script and language. After shaping the buffer + * contains the output glyphs and their positions. + **/ static bool parse_space (const char **pp, const char *end) @@ -198,15 +209,16 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) /** * hb_feature_from_string: - * @str: (array length=len): - * @len: - * @feature: (out) (optional): + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is nul-terminated + * @feature: (out): the #hb_feature_t to initialize with the parsed values * - * + * Parses a string into a #hb_feature_t. If @len is -1 then @str is + * %NULL-terminated. * - * Return value: + * Return value: %TRUE if @str is successfully parsed, %FALSE otherwise * - * Since: 1.0 + * Since: 0.9.5 **/ hb_bool_t hb_feature_from_string (const char *str, int len, @@ -231,13 +243,15 @@ hb_feature_from_string (const char *str, int len, /** * hb_feature_to_string: - * @feature: - * @buf: (array length=size): - * @size: + * @feature: an #hb_feature_t to convert + * @buf: (array length=size) (out): output string + * @size: the allocated size of @buf * - * + * Converts a #hb_feature_t into a %NULL-terminated string in the format + * understood by hb_feature_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_feature_to_string (hb_feature_t *feature, @@ -290,11 +304,12 @@ void free_static_shaper_list (void) /** * hb_shape_list_shapers: * - * + * Retrieves the list of shapers supported by HarfBuzz. * - * Return value: (transfer none): + * Return value: (transfer none) (array zero-terminated=1): an array of + * constant strings * - * Since: 1.0 + * Since: 0.9.2 **/ const char ** hb_shape_list_shapers (void) @@ -333,17 +348,21 @@ retry: /** * hb_shape_full: - * @font: a font. - * @buffer: a buffer. - * @features: (array length=num_features): - * @num_features: - * @shaper_list: (array zero-terminated=1): + * @font: an #hb_font_t to use for shaping + * @buffer: an #hb_buffer_t to shape + * @features: (array length=num_features) (allow-none): an array of user + * specified #hb_feature_t or %NULL + * @num_features: the length of @features array + * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated + * array of shapers to use or %NULL * - * + * See hb_shape() for details. If @shaper_list is not %NULL, the specified + * shapers will be used in the given order, otherwise the default shapers list + * will be used. * - * Return value: + * Return value: %FALSE if all shapers failed, %TRUE otherwise * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_shape_full (hb_font_t *font, @@ -368,12 +387,17 @@ hb_shape_full (hb_font_t *font, /** * hb_shape: - * @font: a font. - * @buffer: a buffer. - * @features: (array length=num_features): - * @num_features: + * @font: an #hb_font_t to use for shaping + * @buffer: an #hb_buffer_t to shape + * @features: (array length=num_features) (allow-none): an array of user + * specified #hb_feature_t or %NULL + * @num_features: the length of @features array + * + * Shapes @buffer using @font turning its Unicode characters content to + * positioned glyphs. If @features is not %NULL, it will be used to control the + * features applied during shaping. * - * + * Return value: %FALSE if all shapers failed, %TRUE otherwise * * Since: 1.0 **/ diff --git a/src/hb-shape.h b/src/hb-shape.h index 10a35cb51..b665509a0 100644 --- a/src/hb-shape.h +++ b/src/hb-shape.h @@ -47,13 +47,10 @@ typedef struct hb_feature_t { unsigned int end; } hb_feature_t; -/* len=-1 means str is NUL-terminated */ hb_bool_t hb_feature_from_string (const char *str, int len, hb_feature_t *feature); -/* Something like 128 bytes is more than enough. - * nul-terminates. */ void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size); diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index fc19006d3..cf2032fd6 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -147,11 +147,11 @@ hb_unicode_funcs_get_default (void) #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) #ifdef _MSC_VER -#pragma message("Could not find any Unicode functions implementation, you have to provide your own") -#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS") +#pragma error("Could not find any Unicode functions implementation, you have to provide your own.") +#pragma error("Consider building hb-ucdn.c. If you absolutely want to build without any, check the code.") #else -#warning "Could not find any Unicode functions implementation, you have to provide your own" -#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS" +#error "Could not find any Unicode functions implementation, you have to provide your own" +#error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code." #endif #endif @@ -400,7 +400,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, @@ -422,7 +422,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, @@ -443,7 +443,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, diff --git a/src/hb-unicode.h b/src/hb-unicode.h index 1c4e097b9..bf1796dca 100644 --- a/src/hb-unicode.h +++ b/src/hb-unicode.h @@ -363,7 +363,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, @@ -379,7 +379,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, @@ -395,7 +395,7 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, @@ -404,37 +404,62 @@ hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, /* accessors */ +/** + * Since: 0.9.2 + **/ hb_unicode_combining_class_t hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ unsigned int hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_unicode_general_category_t hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_codepoint_t hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_script_t hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab); + +/** + * Since: 0.9.2 + **/ hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b); +/** + * Since: 0.9.2 + **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t u, diff --git a/src/hb-warning.cc b/src/hb-warning.cc index e0f88e2d4..e69fff234 100644 --- a/src/hb-warning.cc +++ b/src/hb-warning.cc @@ -30,26 +30,20 @@ #if defined(HB_ATOMIC_INT_NIL) #ifdef _MSC_VER -#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe") +#pragma error("Could not find any system to define atomic_int macros, library WILL NOT be thread-safe") +#pragma error("Check hb-atomic-private.hh for possible resolutions.") #else -#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe" +#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe" +#error "Check hb-atomic-private.hh for possible resolutions." #endif #endif #if defined(HB_MUTEX_IMPL_NIL) #ifdef _MSC_VER -#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe") +#pragma error("Could not find any system to define mutex macros, library WILL NOT be thread-safe") +#pragma error("Check hb-mutex-private.hh for possible resolutions.") #else -#warning "Could not find any system to define mutex macros, library may NOT be thread-safe" +#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe" +#error "Check hb-mutex-private.hh for possible resolutions." #endif #endif - -#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL) -#ifdef _MSC_VER -#pragma message("To suppress these warnings, define HB_NO_MT") -#else -#warning "To suppress these warnings, define HB_NO_MT" -#endif -#endif - - diff --git a/test/api/test-font.c b/test/api/test-font.c index 6b6a5039f..2fc06313b 100644 --- a/test/api/test-font.c +++ b/test/api/test-font.c @@ -36,8 +36,8 @@ static void test_face_empty (void) { g_assert (hb_face_get_empty ()); - g_assert (hb_face_get_empty () == hb_face_create (hb_blob_get_empty (), 0)); - g_assert (hb_face_get_empty () == hb_face_create (NULL, 0)); + g_assert (hb_face_get_empty () != hb_face_create (hb_blob_get_empty (), 0)); + g_assert (hb_face_get_empty () != hb_face_create (NULL, 0)); g_assert (hb_face_reference_table (hb_face_get_empty (), HB_TAG ('h','e','a','d')) == hb_blob_get_empty ()); @@ -348,9 +348,9 @@ static void test_font_empty (void) { g_assert (hb_font_get_empty ()); - g_assert (hb_font_get_empty () == hb_font_create (hb_face_get_empty ())); - g_assert (hb_font_get_empty () == hb_font_create (NULL)); - g_assert (hb_font_get_empty () == hb_font_create_sub_font (NULL)); + g_assert (hb_font_get_empty () != hb_font_create (hb_face_get_empty ())); + g_assert (hb_font_get_empty () != hb_font_create (NULL)); + g_assert (hb_font_get_empty () != hb_font_create_sub_font (NULL)); g_assert (hb_font_is_immutable (hb_font_get_empty ())); g_assert (hb_font_get_face (hb_font_get_empty ()) == hb_face_get_empty ()); diff --git a/test/api/test-object.c b/test/api/test-object.c index 3afe6ae87..4ea6f7cbf 100644 --- a/test/api/test-object.c +++ b/test/api/test-object.c @@ -36,7 +36,7 @@ create_blob (void) return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL); } static void * -create_blob_inert (void) +create_blob_from_inert (void) { return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL); } @@ -47,7 +47,7 @@ create_buffer (void) return hb_buffer_create (); } static void * -create_buffer_inert (void) +create_buffer_from_inert (void) { return NULL; } @@ -58,7 +58,7 @@ create_set (void) return hb_set_create (); } static void * -create_set_inert (void) +create_set_from_inert (void) { return NULL; } @@ -72,7 +72,7 @@ create_face (void) return face; } static void * -create_face_inert (void) +create_face_from_inert (void) { return hb_face_create (hb_blob_get_empty (), 0); } @@ -86,7 +86,7 @@ create_font (void) return font; } static void * -create_font_inert (void) +create_font_from_inert (void) { return hb_font_create (hb_face_get_empty ()); } @@ -97,7 +97,7 @@ create_font_funcs (void) return hb_font_funcs_create (); } static void * -create_font_funcs_inert (void) +create_font_funcs_from_inert (void) { return NULL; } @@ -108,9 +108,9 @@ create_unicode_funcs (void) return hb_unicode_funcs_create (NULL); } static void * -create_unicode_funcs_inert (void) +create_unicode_funcs_from_inert (void) { - return hb_unicode_funcs_get_default (); + return hb_unicode_funcs_create (hb_unicode_funcs_get_empty ()); } @@ -125,7 +125,7 @@ typedef hb_bool_t (*is_immutable_func_t) (void *obj); typedef struct { create_func_t create; - create_func_t create_inert; + create_func_t create_from_inert; create_func_t get_empty; reference_func_t reference; destroy_func_t destroy; @@ -139,7 +139,7 @@ typedef struct { #define OBJECT_WITHOUT_IMMUTABILITY(name) \ { \ (create_func_t) create_##name, \ - (create_func_t) create_##name##_inert, \ + (create_func_t) create_##name##_from_inert, \ (create_func_t) hb_##name##_get_empty, \ (reference_func_t) hb_##name##_reference, \ (destroy_func_t) hb_##name##_destroy, \ @@ -152,7 +152,7 @@ typedef struct { #define OBJECT_WITH_IMMUTABILITY(name) \ { \ (create_func_t) create_##name, \ - (create_func_t) create_##name##_inert, \ + (create_func_t) create_##name##_from_inert, \ (create_func_t) hb_##name##_get_empty, \ (reference_func_t) hb_##name##_reference, \ (destroy_func_t) hb_##name##_destroy, \ @@ -340,8 +340,8 @@ test_object (void) { data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}}; - g_test_message ("->create_inert()"); - obj = o->create_inert (); + g_test_message ("->create_from_inert()"); + obj = o->create_from_inert (); if (!obj) continue; if (obj == o->get_empty ()) @@ -351,10 +351,10 @@ test_object (void) o->destroy (obj); if (o->is_immutable) - g_assert (o->is_immutable (obj)); + g_assert (!o->is_immutable (obj)); - g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); - g_assert (!o->get_user_data (obj, &key[0])); + g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); + g_assert (o->get_user_data (obj, &key[0])); o->destroy (obj); o->destroy (obj); @@ -362,7 +362,7 @@ test_object (void) o->destroy (obj); o->destroy (obj); - g_assert (!data[0].freed); + g_assert (data[0].freed); } } } diff --git a/test/shaping/hb-diff b/test/shaping/hb-diff index 6a13fa2eb..3705de7d0 100755 --- a/test/shaping/hb-diff +++ b/test/shaping/hb-diff @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * import sys, os diff --git a/test/shaping/hb-diff-colorize b/test/shaping/hb-diff-colorize index 4e045d2d9..1fdae8a43 100755 --- a/test/shaping/hb-diff-colorize +++ b/test/shaping/hb-diff-colorize @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-diff-filter-failures b/test/shaping/hb-diff-filter-failures index 4fe218adb..34b76de9a 100755 --- a/test/shaping/hb-diff-filter-failures +++ b/test/shaping/hb-diff-filter-failures @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-diff-ngrams b/test/shaping/hb-diff-ngrams index a496447c8..c02f5415f 100755 --- a/test/shaping/hb-diff-ngrams +++ b/test/shaping/hb-diff-ngrams @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-diff-stat b/test/shaping/hb-diff-stat index 81626e1e8..12ee8f098 100755 --- a/test/shaping/hb-diff-stat +++ b/test/shaping/hb-diff-stat @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-manifest-read b/test/shaping/hb-manifest-read index f486bcce2..b1b36ba8a 100755 --- a/test/shaping/hb-manifest-read +++ b/test/shaping/hb-manifest-read @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-manifest-update b/test/shaping/hb-manifest-update index b963f22fc..eeb84b86b 100755 --- a/test/shaping/hb-manifest-update +++ b/test/shaping/hb-manifest-update @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-unicode-decode b/test/shaping/hb-unicode-decode index 5b00eae03..9ac5ed6e6 100755 --- a/test/shaping/hb-unicode-decode +++ b/test/shaping/hb-unicode-decode @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-unicode-encode b/test/shaping/hb-unicode-encode index 11bf365fd..588980714 100755 --- a/test/shaping/hb-unicode-encode +++ b/test/shaping/hb-unicode-encode @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb-unicode-prettyname b/test/shaping/hb-unicode-prettyname index ecc26cca2..1d004c0e1 100755 --- a/test/shaping/hb-unicode-prettyname +++ b/test/shaping/hb-unicode-prettyname @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from hb_test_tools import * diff --git a/test/shaping/hb_test_tools.py b/test/shaping/hb_test_tools.py index a370e5e76..ba4a8bb7b 100644 --- a/test/shaping/hb_test_tools.py +++ b/test/shaping/hb_test_tools.py @@ -1,11 +1,15 @@ -#!/usr/bin/python +#!/usr/bin/env python +from __future__ import print_function import sys, os, re, difflib, unicodedata, errno, cgi from itertools import * diff_symbols = "-+=*&^%$#@!~/" diff_colors = ['red', 'green', 'blue'] +if sys.version_info[0] >= 3: + unichr = chr + class ColorFormatter: class Null: @@ -142,7 +146,7 @@ class ZipDiffer: sys.stdout.writelines ([symbols[i], l]) except IOError as e: if e.errno != errno.EPIPE: - print >> sys.stderr, "%s: %s: %s" % (sys.argv[0], e.filename, e.strerror) + print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr) sys.exit (1) @@ -215,7 +219,7 @@ class DiffSinks: else: failed += 1 total = passed + failed - print "%d out of %d tests passed. %d failed (%g%%)" % (passed, total, failed, 100. * failed / total) + print ("%d out of %d tests passed. %d failed (%g%%)" % (passed, total, failed, 100. * failed / total)) @staticmethod def print_ngrams (f, ns=(1,2,3)): @@ -240,7 +244,7 @@ class DiffSinks: 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)) + 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))) @@ -310,7 +314,7 @@ class FilterHelpers: def filter_printer_function (filter_callback): def printer (f): for line in filter_callback (f): - print line + print (line) return printer @staticmethod @@ -344,7 +348,7 @@ class UtilMains: def process_multiple_files (callback, mnemonic = "FILE"): if "--help" in sys.argv: - print "Usage: %s %s..." % (sys.argv[0], mnemonic) + print ("Usage: %s %s..." % (sys.argv[0], mnemonic)) sys.exit (1) try: @@ -353,14 +357,14 @@ class UtilMains: callback (FileHelpers.open_file_or_stdin (s)) except IOError as e: if e.errno != errno.EPIPE: - print >> sys.stderr, "%s: %s: %s" % (sys.argv[0], e.filename, e.strerror) + print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr) sys.exit (1) @staticmethod def process_multiple_args (callback, mnemonic): if len (sys.argv) == 1 or "--help" in sys.argv: - print "Usage: %s %s..." % (sys.argv[0], mnemonic) + print ("Usage: %s %s..." % (sys.argv[0], mnemonic)) sys.exit (1) try: @@ -368,7 +372,7 @@ class UtilMains: callback (s) except IOError as e: if e.errno != errno.EPIPE: - print >> sys.stderr, "%s: %s: %s" % (sys.argv[0], e.filename, e.strerror) + print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr) sys.exit (1) @staticmethod @@ -377,8 +381,8 @@ class UtilMains: concat_separator = False): if "--help" in sys.argv: - print "Usage:\n %s %s...\nor:\n %s\n\nWhen called with no arguments, input is read from standard input." \ - % (sys.argv[0], mnemonic, sys.argv[0]) + print ("Usage:\n %s %s...\nor:\n %s\n\nWhen called with no arguments, input is read from standard input." \ + % (sys.argv[0], mnemonic, sys.argv[0])) sys.exit (1) try: @@ -389,15 +393,15 @@ class UtilMains: break if line[-1] == '\n': line = line[:-1] - print callback (line) + print (callback (line)) else: args = sys.argv[1:] if concat_separator != False: args = [concat_separator.join (args)] - print separator.join (callback (x) for x in (args)) + print (separator.join (callback (x) for x in (args))) except IOError as e: if e.errno != errno.EPIPE: - print >> sys.stderr, "%s: %s: %s" % (sys.argv[0], e.filename, e.strerror) + print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr) sys.exit (1) @@ -410,12 +414,14 @@ class Unicode: @staticmethod def parse (s): s = re.sub (r"0[xX]", " ", s) - s = re.sub (r"[<+>,;&#\\xXuU\n ]", " ", s) + s = re.sub (r"[<+>,;&#\\xXuUnNiI\n ]", " ", s) return [int (x, 16) for x in s.split ()] @staticmethod def encode (s): - return u''.join (unichr (x) for x in Unicode.parse (s)).encode ('utf-8') + s = u''.join (unichr (x) for x in Unicode.parse (s)) + if sys.version_info[0] == 2: s = s.encode ('utf-8') + return s shorthands = { "ZERO WIDTH NON-JOINER": "ZWNJ", @@ -471,7 +477,7 @@ class Manifest: if not os.path.exists (s): if strict: - print >> sys.stderr, "%s: %s does not exist" % (sys.argv[0], s) + print ("%s: %s does not exist" % (sys.argv[0], s), file=sys.stderr) sys.exit (1) return @@ -487,7 +493,7 @@ class Manifest: yield p except IOError: if strict: - print >> sys.stderr, "%s: %s does not exist" % (sys.argv[0], os.path.join (s, "MANIFEST")) + print ("%s: %s does not exist" % (sys.argv[0], os.path.join (s, "MANIFEST")), file=sys.stderr) sys.exit (1) return else: @@ -506,12 +512,12 @@ class Manifest: dirnames.sort () filenames.sort () ms = os.path.join (dirpath, "MANIFEST") - print " GEN %s" % ms + print (" GEN %s" % ms) m = open (ms, "w") for f in filenames: - print >> m, f + print (f, file=m) for f in dirnames: - print >> m, f + print (f, file=m) for f in dirnames: Manifest.update_recursive (os.path.join (dirpath, f)) diff --git a/util/Makefile.am b/util/Makefile.am index 3f23babf3..a676e0456 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -76,4 +76,19 @@ endif # HAVE_OT endif # HAVE_GLIB +#if HAVE_OT +#if HAVE_FONTCONFIG +#hb_fc_list_SOURCES = \ +# hb-fc.cc \ +# hb-fc.h \ +# hb-fc-list.c \ +# $(NULL) +#hb_fc_list_LDADD = \ +# $(LDADD) \ +# $(FONTCONFIG_LIBS) \ +# $(NULL) +#bin_PROGRAMS += hb-fc-list +#endif # HAVE_FONTCONFIG +#endif # HAVE_OT + -include $(top_srcdir)/git.mk diff --git a/util/ansi-print.cc b/util/ansi-print.cc index 0fc37194b..e9060af56 100644 --- a/util/ansi-print.cc +++ b/util/ansi-print.cc @@ -222,11 +222,12 @@ struct biimage_t }; const char * -block_best (const biimage_t &bi, unsigned int *score, bool *inverse) +block_best (const biimage_t &bi, bool *inverse) { assert (bi.width <= CELL_W); assert (bi.height <= CELL_H); + unsigned int score = (unsigned int) -1; unsigned int row_sum[CELL_H] = {0}; unsigned int col_sum[CELL_W] = {0}; unsigned int row_sum_i[CELL_H] = {0}; @@ -262,14 +263,14 @@ block_best (const biimage_t &bi, unsigned int *score, bool *inverse) const char *best_c = " "; /* Maybe empty is better! */ - if (total < *score) { - *score = total; + if (total < score) { + score = total; *inverse = false; best_c = " "; } /* Maybe full is better! */ - if (total_i < *score) { - *score = total_i; + if (total_i < score) { + score = total_i; *inverse = true; best_c = " "; } @@ -295,11 +296,11 @@ block_best (const biimage_t &bi, unsigned int *score, bool *inverse) best_inv = true; } } - if (best_s < *score) { + if (best_s < score) { static const char *lower[7] = {"▁", "▂", "▃", "▄", "▅", "▆", "▇"}; unsigned int which = lround (((best_i + 1) * 8) / bi.height); if (1 <= which && which <= 7) { - *score = best_s; + score = best_s; *inverse = best_inv; best_c = lower[7 - which]; } @@ -327,11 +328,11 @@ block_best (const biimage_t &bi, unsigned int *score, bool *inverse) best_inv = false; } } - if (best_s < *score) { + if (best_s < score) { static const char *left [7] = {"▏", "▎", "▍", "▌", "▋", "▊", "▉"}; unsigned int which = lround (((best_i + 1) * 8) / bi.width); if (1 <= which && which <= 7) { - *score = best_s; + score = best_s; *inverse = best_inv; best_c = left[which - 1]; } @@ -349,7 +350,7 @@ block_best (const biimage_t &bi, unsigned int *score, bool *inverse) qs += quad_i[i][j]; } else qs += quad[i][j]; - if (qs < *score) { + if (qs < score) { const char *c = NULL; bool inv = false; switch (q) { @@ -365,7 +366,7 @@ block_best (const biimage_t &bi, unsigned int *score, bool *inverse) case 14: c = "▟"; inv = true; break; } if (c) { - *score = qs; + score = qs; *inverse = inv; best_c = c; } @@ -400,9 +401,8 @@ ansi_print_image_rgb24 (const uint32_t *data, printf (" "); } else { /* Figure out the closest character to the biimage */ - unsigned int score = (unsigned int) -1; bool inverse = false; - const char *c = block_best (bi, &score, &inverse); + const char *c = block_best (bi, &inverse); if (inverse) { if (last_bg != bi.fg || last_fg != bi.bg) { printf ("\e[%d;%dm", 30 + bi.bg, 40 + bi.fg); diff --git a/util/hb-fc-list.c b/util/hb-fc-list.c new file mode 100644 index 000000000..573d11e7c --- /dev/null +++ b/util/hb-fc-list.c @@ -0,0 +1,222 @@ +/* + * Copyright © 2002 Keith Packard + * Copyright © 2014 Google, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Google Author(s): Behdad Esfahbod + */ + +#define HAVE_GETOPT_LONG 1 /* XXX */ + +#include "hb-fc.h" + +#include <fontconfig/fontconfig.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_CONFIG_H +#include <config.h> +#else +#ifdef linux +#define HAVE_GETOPT_LONG 1 +#endif +#define HAVE_GETOPT 1 +#endif + +#ifndef HAVE_GETOPT +#define HAVE_GETOPT 0 +#endif +#ifndef HAVE_GETOPT_LONG +#define HAVE_GETOPT_LONG 0 +#endif + +#if HAVE_GETOPT_LONG +#undef _GNU_SOURCE +#define _GNU_SOURCE +#include <getopt.h> +const struct option longopts[] = { + {"verbose", 0, 0, 'v'}, + {"format", 1, 0, 'f'}, + {"quiet", 0, 0, 'q'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {NULL,0,0,0}, +}; +#else +#if HAVE_GETOPT +extern char *optarg; +extern int optind, opterr, optopt; +#endif +#endif + +static void +usage (char *program, int error) +{ + FILE *file = error ? stderr : stdout; +#if HAVE_GETOPT_LONG + fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] text [pattern] {element ...} \n", + program); +#else + fprintf (file, "usage: %s [-vqVh] [-f FORMAT] text [pattern] {element ...} \n", + program); +#endif + fprintf (file, "List fonts matching [pattern] that can render [text]\n"); + fprintf (file, "\n"); +#if HAVE_GETOPT_LONG + fprintf (file, " -v, --verbose display entire font pattern verbosely\n"); + fprintf (file, " -f, --format=FORMAT use the given output format\n"); + fprintf (file, " -q, --quiet suppress all normal output, exit 1 if no fonts matched\n"); + fprintf (file, " -V, --version display font config version and exit\n"); + fprintf (file, " -h, --help display this help and exit\n"); +#else + fprintf (file, " -v (verbose) display entire font pattern verbosely\n"); + fprintf (file, " -f FORMAT (format) use the given output format\n"); + fprintf (file, " -q, (quiet) suppress all normal output, exit 1 if no fonts matched\n"); + fprintf (file, " -V (version) display HarfBuzz version and exit\n"); + fprintf (file, " -h (help) display this help and exit\n"); +#endif + exit (error); +} + +int +main (int argc, char **argv) +{ + int verbose = 0; + int quiet = 0; + const FcChar8 *format = NULL; + int nfont = 0; + int i; + FcObjectSet *os = 0; + FcFontSet *fs; + FcPattern *pat; + const char *text; +#if HAVE_GETOPT_LONG || HAVE_GETOPT + int c; + +#if HAVE_GETOPT_LONG + while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1) +#else + while ((c = getopt (argc, argv, "vf:qVh")) != -1) +#endif + { + switch (c) { + case 'v': + verbose = 1; + break; + case 'f': + format = (FcChar8 *) strdup (optarg); + break; + case 'q': + quiet = 1; + break; + case 'V': + fprintf (stderr, "fontconfig version %d.%d.%d\n", + FC_MAJOR, FC_MINOR, FC_REVISION); + exit (0); + case 'h': + usage (argv[0], 0); + default: + usage (argv[0], 1); + } + } + i = optind; +#else + i = 1; +#endif + + if (!argv[i]) + usage (argv[0], 1); + + text = argv[i]; + i++; + + if (argv[i]) + { + pat = FcNameParse ((FcChar8 *) argv[i]); + if (!pat) + { + fputs ("Unable to parse the pattern\n", stderr); + return 1; + } + while (argv[++i]) + { + if (!os) + os = FcObjectSetCreate (); + FcObjectSetAdd (os, argv[i]); + } + } + else + pat = FcPatternCreate (); + if (quiet && !os) + os = FcObjectSetCreate (); + if (!verbose && !format && !os) + os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0); + FcObjectSetAdd (os, FC_CHARSET); + if (!format) + format = (const FcChar8 *) "%{=fclist}\n"; + fs = FcFontList (0, pat, os); + if (os) + FcObjectSetDestroy (os); + if (pat) + FcPatternDestroy (pat); + + if (!quiet && fs) + { + int j; + + for (j = 0; j < fs->nfont; j++) + { + hb_font_t *font = hb_fc_font_create (fs->fonts[j]); + hb_bool_t can_render = hb_fc_can_render (font, text); + hb_font_destroy (font); + + if (!can_render) + continue; + + FcPatternDel (fs->fonts[j], FC_CHARSET); + + if (verbose) + { + FcPatternPrint (fs->fonts[j]); + } + else + { + FcChar8 *s; + + s = FcPatternFormat (fs->fonts[j], format); + if (s) + { + printf ("%s", s); + FcStrFree (s); + } + } + } + } + + if (fs) { + nfont = fs->nfont; + FcFontSetDestroy (fs); + } + + FcFini (); + + return quiet ? (nfont == 0 ? 1 : 0) : 0; +} diff --git a/util/hb-fc.cc b/util/hb-fc.cc new file mode 100644 index 000000000..e99b1aefc --- /dev/null +++ b/util/hb-fc.cc @@ -0,0 +1,149 @@ +/* + * Copyright © 2014 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 + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "hb-fc.h" + +static hb_bool_t +hb_fc_get_glyph (hb_font_t *font /*HB_UNUSED*/, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data /*HB_UNUSED*/) + +{ + FcCharSet *cs = (FcCharSet *) font_data; + + if (variation_selector) + { + /* Fontconfig doesn't cache cmap-14 info. However: + * 1. If the font maps the variation_selector, assume it's + * supported, + * 2. If the font doesn't map it, still say it's supported, + * but return 0. This way, the caller will see the zero + * and reject. If we return unsupported here, then the + * variation selector will be hidden and ignored. + */ + if (FcCharSetHasChar (cs, unicode) && + FcCharSetHasChar (cs, variation_selector)) + { + unsigned int var_num = 0; + if (variation_selector - 0xFE00u < 16) + var_num = variation_selector - 0xFE00 + 1; + else if (variation_selector - 0xE0100u < (256 - 16)) + var_num = variation_selector - 0xE0100 + 17; + *glyph = (var_num << 21) | unicode; + } + else + { + *glyph = 0; + } + return true; + } + + *glyph = FcCharSetHasChar (cs, unicode) ? unicode : 0; + return *glyph != 0; +} + +static hb_font_funcs_t * +_hb_fc_get_font_funcs (void) +{ + static const hb_font_funcs_t *fc_ffuncs; + + const hb_font_funcs_t *ffuncs; + + if (!(ffuncs = fc_ffuncs)) + { + hb_font_funcs_t *newfuncs = hb_font_funcs_create (); + + hb_font_funcs_set_glyph_func (newfuncs, hb_fc_get_glyph, NULL, NULL); + + /* XXX MT-unsafe */ + if (fc_ffuncs) + hb_font_funcs_destroy (newfuncs); + else + fc_ffuncs = ffuncs = newfuncs; + } + + return const_cast<hb_font_funcs_t *> (fc_ffuncs); +} + + +hb_font_t * +hb_fc_font_create (FcPattern *fcfont) +{ + static hb_face_t *face; + hb_font_t *font; + + FcCharSet *cs; + if (FcResultMatch != FcPatternGetCharSet (fcfont, FC_CHARSET, 0, &cs)) + return hb_font_get_empty (); + + if (!face) /* XXX MT-unsafe */ + face = hb_face_create (hb_blob_get_empty (), 0); + + font = hb_font_create (face); + + hb_font_set_funcs (font, + _hb_fc_get_font_funcs (), + FcCharSetCopy (cs), + (hb_destroy_func_t) FcCharSetDestroy); + + return font; +} + +hb_bool_t +hb_fc_can_render (hb_font_t *font, const char *text) +{ + static const char *ot[] = {"ot", NULL}; + + hb_buffer_t *buffer = hb_buffer_create (); + hb_buffer_add_utf8 (buffer, text, -1, 0, -1); + + /* XXX Do we need this? I think Arabic and Hangul shapers are the + * only one that make any use of this. The Hangul case is not really + * needed, and for Arabic we'll miss a very narrow set of fonts. + * Might be better to force generic shaper perhaps. */ + hb_buffer_guess_segment_properties (buffer); + + if (!hb_shape_full (font, buffer, NULL, 0, ot)) + abort (); /* hb-ot shaper not enabled? */ + + unsigned int len; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &len); + for (unsigned int i = 0; i < len; i++) + { + if (!info[i].codepoint) + { + return false; + } + } + + return true; +} diff --git a/util/hb-fc.h b/util/hb-fc.h new file mode 100644 index 000000000..bb2f78a82 --- /dev/null +++ b/util/hb-fc.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2014 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 + */ + +#ifndef HB_FC_H +#define HB_FC_H + +#include "hb.h" + +#include <fontconfig/fontconfig.h> + +HB_BEGIN_DECLS + + +hb_font_t * +hb_fc_font_create (FcPattern *font); + +hb_bool_t +hb_fc_can_render (hb_font_t *font, const char *text); + + +HB_END_DECLS + +#endif /* HB_FC_H */ diff --git a/util/options.cc b/util/options.cc index 7387a5616..0f92aec0e 100644 --- a/util/options.cc +++ b/util/options.cc @@ -30,7 +30,7 @@ #include <hb-ft.h> #endif #ifdef HAVE_OT -#include <hb-ot-font.h> +#include <hb-ot.h> #endif struct supported_font_funcs_t { @@ -174,7 +174,7 @@ parse_margin (const char *name G_GNUC_UNUSED, { view_options_t *view_opts = (view_options_t *) data; view_options_t::margin_t &m = view_opts->margin; - switch (sscanf (arg, "%lf %lf %lf %lf", &m.t, &m.r, &m.b, &m.l)) { + switch (sscanf (arg, "%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf", &m.t, &m.r, &m.b, &m.l)) { case 1: m.r = m.t; case 2: m.b = m.t; case 3: m.l = m.r; @@ -361,7 +361,7 @@ parse_font_size (const char *name G_GNUC_UNUSED, font_opts->font_size_y = font_opts->font_size_x = FONT_SIZE_UPEM; return true; } - switch (sscanf (arg, "%lf %lf", &font_opts->font_size_x, &font_opts->font_size_y)) { + switch (sscanf (arg, "%lf%*[ ,]%lf", &font_opts->font_size_x, &font_opts->font_size_y)) { case 1: font_opts->font_size_y = font_opts->font_size_x; case 2: return true; default: @@ -440,7 +440,7 @@ output_options_t::add_options (option_parser_t *parser) const char *text; if (NULL == supported_formats) - text = "Set output format"; + text = "Set output serialization format"; else { char *items = g_strjoinv ("/", const_cast<char **> (supported_formats)); @@ -457,8 +457,8 @@ output_options_t::add_options (option_parser_t *parser) }; parser->add_group (entries, "output", - "Output options:", - "Options controlling the output", + "Output destination & format options:", + "Options controlling the destination and form of the output", this); } @@ -694,19 +694,26 @@ format_options_t::add_options (option_parser_t *parser) { GOptionEntry entries[] = { - {"no-glyph-names", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &this->show_glyph_names, "Use glyph indices instead of names", NULL}, - {"no-positions", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &this->show_positions, "Do not show glyph positions", NULL}, - {"no-clusters", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &this->show_clusters, "Do not show cluster mapping", NULL}, - {"show-text", 0, 0, G_OPTION_ARG_NONE, &this->show_text, "Show input text", NULL}, - {"show-unicode", 0, 0, G_OPTION_ARG_NONE, &this->show_unicode, "Show input Unicode codepoints", NULL}, - {"show-line-num", 0, 0, G_OPTION_ARG_NONE, &this->show_line_num, "Show line numbers", NULL}, - {"verbose", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,(gpointer) &parse_verbose, "Show everything", NULL}, + {"show-text", 0, 0, G_OPTION_ARG_NONE, &this->show_text, "Prefix each line of output with its corresponding input text", NULL}, + {"show-unicode", 0, 0, G_OPTION_ARG_NONE, &this->show_unicode, "Prefix each line of output with its corresponding input codepoint(s)", NULL}, + {"show-line-num", 0, 0, G_OPTION_ARG_NONE, &this->show_line_num, "Prefix each line of output with its corresponding input line number", NULL}, + {"verbose", 0, G_OPTION_FLAG_NO_ARG, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_verbose, "Prefix each line of output with all of the above", NULL}, + {"no-glyph-names", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_glyph_names, "Output glyph indices instead of names", NULL}, + {"no-positions", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_positions, "Do not output glyph positions", NULL}, + {"no-clusters", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_clusters, "Do not output cluster indices", NULL}, {NULL} }; parser->add_group (entries, - "format", - "Format options:", - "Options controlling the formatting of buffer contents", + "output-syntax", + "Output syntax:\n" + " text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n" + " json: [{\"g\": <glyph name or index>, \"ax\": <horizontal advance>, \"ay\": <vertical advance>, \"dx\": <horizontal displacement>, \"dy\": <vertical displacement>, \"cl\": <glyph cluster index within input>}, ...]\n" + "\nOutput syntax options:", + "Options controlling the syntax of the output", this); } diff --git a/util/view-cairo.cc b/util/view-cairo.cc index 160250e2d..41b8d6e94 100644 --- a/util/view-cairo.cc +++ b/util/view-cairo.cc @@ -26,71 +26,71 @@ #include "view-cairo.hh" +#include <assert.h> + + void -view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font, - double *w, double *h) +view_cairo_t::render (const font_options_t *font_opts) { - cairo_font_extents_t font_extents; + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + int vert = vertical ? 1 : 0; + int horiz = vertical ? 0 : 1; - cairo_scaled_font_extents (scaled_font, &font_extents); + int x_sign = font_opts->font_size_x < 0 ? -1 : +1; + int y_sign = font_opts->font_size_y < 0 ? -1 : +1; - bool vertical = HB_DIRECTION_IS_VERTICAL (direction); - (vertical ? *w : *h) = (int) lines->len * (font_extents.height + view_options.line_space) - view_options.line_space; - (vertical ? *h : *w) = 0; + cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts); + cairo_font_extents_t font_extents; + cairo_scaled_font_extents (scaled_font, &font_extents); + /* Looks like cairo doesn't negate the sign of font extents even if + * y_scale is negative. This is probably a bug, but that's the way + * it is, and we code for it. Assert, just in case this accidentally + * changes in the future (or is different on non-FreeType cairo font + * backends. */ + assert (font_extents.height >= 0); + double leading = font_extents.height + view_options.line_space; + + /* Calculate surface size. */ + double w, h; + (vertical ? w : h) = (int) lines->len * leading - view_options.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 x_advance, y_advance; line.get_advance (&x_advance, &y_advance); if (vertical) - *h = MAX (*h, y_advance); + h = MAX (h, y_sign * y_advance); else - *w = MAX (*w, x_advance); + w = MAX (w, x_sign * x_advance); } - *w += view_options.margin.l + view_options.margin.r; - *h += view_options.margin.t + view_options.margin.b; -} - -void -view_cairo_t::render (const font_options_t *font_opts) -{ - cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts); - double w, h; - get_surface_size (scaled_font, &w, &h); - cairo_t *cr = helper_cairo_create_context (w, h, &view_options, &output_options); + /* Create surface. */ + cairo_t *cr = helper_cairo_create_context (w + view_options.margin.l + view_options.margin.r, + h + view_options.margin.t + view_options.margin.b, + &view_options, &output_options); cairo_set_scaled_font (cr, scaled_font); - cairo_scaled_font_destroy (scaled_font); - - draw (cr); - helper_cairo_destroy_context (cr); -} - -void -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); + /* Setup coordinate system. */ cairo_translate (cr, view_options.margin.l, view_options.margin.t); - double descent; if (vertical) - descent = font_extents.height * (lines->len + .5); + cairo_translate (cr, + w /* We stack lines right to left */ + -font_extents.height * .5 /* "ascent" for vertical */, + y_sign < 0 ? h : 0); else - descent = font_extents.height - font_extents.ascent; - cairo_translate (cr, v * descent, h * -descent); + { + cairo_translate (cr, + x_sign < 0 ? w : 0, + y_sign < 0 ? font_extents.descent : font_extents.ascent); + } + + /* Draw. */ + cairo_translate (cr, +vert * leading, -horiz * leading); for (unsigned int i = 0; i < lines->len; i++) { helper_cairo_line_t &l = g_array_index (lines, helper_cairo_line_t, i); - if (i) - cairo_translate (cr, v * -view_options.line_space, h * view_options.line_space); - - cairo_translate (cr, v * -font_extents.height, h * font_extents.height); + cairo_translate (cr, -vert * leading, +horiz * leading); if (view_options.annotate) { cairo_save (cr); @@ -122,5 +122,7 @@ view_cairo_t::draw (cairo_t *cr) cairo_show_glyphs (cr, l.glyphs, l.num_glyphs); } - cairo_restore (cr); + /* Clean up. */ + helper_cairo_destroy_context (cr); + cairo_scaled_font_destroy (scaled_font); } diff --git a/util/view-cairo.hh b/util/view-cairo.hh index cb523737a..f55d4bb4d 100644 --- a/util/view-cairo.hh +++ b/util/view-cairo.hh @@ -95,8 +95,6 @@ struct view_cairo_t view_options_t view_options; void render (const font_options_t *font_opts); - void get_surface_size (cairo_scaled_font_t *scaled_font, double *w, double *h); - void draw (cairo_t *cr); hb_direction_t direction; // Remove this, make segment_properties accessible GArray *lines; |