From edee28801e4dbb5b734b4038d93fe1594e267ab1 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 21 Feb 2018 22:13:58 +0330 Subject: [PATCH 01/35] Add .editorconfig (#810) More information: http://editorconfig.org/ --- .editorconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..708188ad8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true + +[*.{c,cc,h,hh}] +indent_size = 2 +indent_style = space +tab_width = 8 + +[*.{py,sh}] +indent_style = tab + +[{CMakeLists.txt,*.cmake}] +indent_size = 2 From 4fb97be78d9287e489c9f67d1bfe7682235bdf38 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Feb 2018 14:38:02 -0800 Subject: [PATCH 02/35] Add two more ragel-generated headers Fixes https://github.com/harfbuzz/harfbuzz/issues/817 --- src/hb-buffer-deserialize-json.hh | 643 ++++++++++++++++++++++++++++++ src/hb-buffer-deserialize-text.hh | 571 ++++++++++++++++++++++++++ 2 files changed, 1214 insertions(+) create mode 100644 src/hb-buffer-deserialize-json.hh create mode 100644 src/hb-buffer-deserialize-text.hh diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh new file mode 100644 index 000000000..be374c77a --- /dev/null +++ b/src/hb-buffer-deserialize-json.hh @@ -0,0 +1,643 @@ + +#line 1 "hb-buffer-deserialize-json.rl" +/* + * Copyright © 2013 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_BUFFER_DESERIALIZE_JSON_HH +#define HB_BUFFER_DESERIALIZE_JSON_HH + +#include "hb-private.hh" + + +#line 36 "hb-buffer-deserialize-json.hh" +static const unsigned char _deserialize_json_trans_keys[] = { + 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, + 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 +}; + +static const char _deserialize_json_key_spans[] = { + 0, 115, 26, 7, 2, 1, 50, 49, + 10, 117, 117, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 50, 49, + 58, 89, 117, 117, 85, 115, 0 +}; + +static const short _deserialize_json_index_offsets[] = { + 0, 0, 116, 143, 151, 154, 156, 207, + 257, 268, 386, 504, 622, 624, 675, 725, + 736, 854, 972, 974, 976, 1027, 1077, 1195, + 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, + 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, + 2119, 2178, 2268, 2386, 2504, 2590, 2706 +}; + +static const char _deserialize_json_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 4, 1, + 5, 1, 6, 7, 1, 1, 8, 1, + 9, 10, 1, 11, 1, 11, 11, 11, + 11, 11, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 11, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 12, 1, + 12, 12, 12, 12, 12, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 12, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 13, 1, 1, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 1, 16, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 1, 18, 18, 18, + 18, 18, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 18, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 19, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 20, 1, 21, 21, 21, 21, 21, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 18, 18, 18, 18, 18, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 18, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 19, 1, 1, 1, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 20, 1, 23, + 1, 23, 23, 23, 23, 23, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 23, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 24, 1, 24, 24, 24, 24, + 24, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 24, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 25, 1, 1, 26, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 1, 28, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 1, 30, 30, 30, 30, 30, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 30, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 31, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 32, 1, 30, + 30, 30, 30, 30, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 30, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 31, 1, 1, 1, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 32, 1, 33, 1, 34, + 1, 34, 34, 34, 34, 34, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 35, 1, 35, 35, 35, 35, + 35, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 35, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 36, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 40, 1, 38, 38, 38, 38, + 38, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 38, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 39, + 1, 1, 1, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 40, 1, 42, 43, 1, 44, 1, 44, + 44, 44, 44, 44, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 44, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 45, 1, 45, 45, 45, 45, 45, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 46, 1, + 1, 47, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 1, 49, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 1, 51, + 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 51, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 52, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 53, 1, 51, 51, 51, + 51, 51, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 51, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 52, 1, 1, 1, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 53, 1, 54, 1, 54, 54, 54, + 54, 54, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 54, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 55, 1, + 55, 55, 55, 55, 55, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 55, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 56, 1, 1, 57, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 1, 59, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 1, 61, 61, 61, + 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 61, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 62, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 63, 1, 61, 61, 61, 61, 61, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 61, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 62, 1, + 1, 1, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 63, + 1, 64, 1, 64, 64, 64, 64, 64, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 64, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 65, 65, + 65, 65, 65, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 65, 1, 66, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 67, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 1, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 1, 1, 1, 1, 1, 1, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 1, 70, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 71, 71, + 1, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 1, 1, 1, 1, 1, + 1, 1, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 1, 1, 1, 1, + 71, 1, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 1, 72, 72, 72, + 72, 72, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 72, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 73, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 74, 1, 72, 72, 72, 72, 72, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 73, 1, + 1, 1, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, + 1, 76, 76, 76, 76, 76, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 76, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 78, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 0 +}; + +static const char _deserialize_json_trans_targs[] = { + 1, 0, 2, 2, 3, 4, 18, 24, + 37, 5, 12, 6, 7, 8, 9, 11, + 9, 11, 10, 2, 44, 10, 44, 13, + 14, 15, 16, 17, 16, 17, 10, 2, + 44, 19, 20, 21, 22, 23, 10, 2, + 44, 23, 25, 31, 26, 27, 28, 29, + 30, 29, 30, 10, 2, 44, 32, 33, + 34, 35, 36, 35, 36, 10, 2, 44, + 38, 39, 40, 42, 43, 41, 10, 41, + 10, 2, 44, 43, 44, 45, 46 +}; + +static const char _deserialize_json_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 2, + 0, 0, 3, 3, 4, 0, 5, 0, + 0, 2, 2, 2, 0, 0, 6, 6, + 7, 0, 0, 0, 2, 2, 8, 8, + 9, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 10, 10, 11, 0, 0, + 2, 2, 2, 0, 0, 12, 12, 13, + 0, 0, 0, 2, 2, 2, 14, 0, + 15, 15, 16, 0, 0, 0, 0 +}; + +static const int deserialize_json_start = 1; +static const int deserialize_json_first_final = 44; +static const int deserialize_json_error = 0; + +static const int deserialize_json_en_main = 1; + + +#line 97 "hb-buffer-deserialize-json.rl" + + +static hb_bool_t +_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) + { + *end_ptr = ++p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 466 "hb-buffer-deserialize-json.hh" + { + cs = deserialize_json_start; + } + +#line 471 "hb-buffer-deserialize-json.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_json_trans_keys + (cs<<1); + _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; + + _slen = _deserialize_json_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_json_trans_targs[_trans]; + + if ( _deserialize_json_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_json_trans_actions[_trans] ) { + case 1: +#line 38 "hb-buffer-deserialize-json.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + break; + case 5: +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 2: +#line 51 "hb-buffer-deserialize-json.rl" + { + tok = p; +} + break; + case 14: +#line 55 "hb-buffer-deserialize-json.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 15: +#line 62 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } + break; + case 8: +#line 63 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 10: +#line 64 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: +#line 65 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 3: +#line 66 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 6: +#line 67 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 16: +#line 62 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 63 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 64 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: +#line 65 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 4: +#line 66 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 7: +#line 67 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 624 "hb-buffer-deserialize-json.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +#line 125 "hb-buffer-deserialize-json.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh new file mode 100644 index 000000000..a6ab0bbde --- /dev/null +++ b/src/hb-buffer-deserialize-text.hh @@ -0,0 +1,571 @@ + +#line 1 "hb-buffer-deserialize-text.rl" +/* + * Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_HH +#define HB_BUFFER_DESERIALIZE_TEXT_HH + +#include "hb-private.hh" + + +#line 36 "hb-buffer-deserialize-text.hh" +static const unsigned char _deserialize_text_trans_keys[] = { + 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, + 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, + 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 0 +}; + +static const char _deserialize_text_key_spans[] = { + 0, 114, 13, 10, 13, 10, 10, 13, + 10, 1, 13, 10, 14, 116, 116, 0, + 114, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116 +}; + +static const short _deserialize_text_index_offsets[] = { + 0, 0, 115, 129, 140, 154, 165, 176, + 190, 201, 203, 217, 228, 243, 360, 477, + 478, 593, 710, 827, 944, 1061, 1178, 1295, + 1412, 1529, 1646 +}; + +static const char _deserialize_text_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, + 1, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 1, 1, 1, 1, 1, + 1, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 1, 5, 1, 1, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 1, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 1, 10, 1, 1, + 11, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 1, 13, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 1, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 1, 17, 1, 1, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 20, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 1, 22, 1, 23, 1, 1, 24, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 1, 26, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 1, 22, 1, 1, + 1, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 1, 28, 28, 28, 28, + 28, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 28, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 29, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 30, 1, 1, 31, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 32, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 33, + 1, 34, 34, 34, 34, 34, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 36, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 1, 1, 1, 1, 1, 1, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 1, 28, 28, 28, 28, 28, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 28, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 29, 1, 1, 1, + 1, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 1, 1, 1, 30, 1, + 1, 31, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 32, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 33, 1, 38, + 38, 38, 38, 38, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 38, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 39, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 40, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 41, 1, 42, 42, 42, 42, + 42, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 43, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 44, + 1, 42, 42, 42, 42, 42, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 42, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 43, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 44, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 40, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 41, 1, 45, 45, 45, 45, 45, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 45, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 46, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 48, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 49, 1, + 50, 50, 50, 50, 50, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 50, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 51, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 53, 1, 50, 50, 50, + 50, 50, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 50, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 51, + 1, 1, 1, 1, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 52, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 53, 1, 45, 45, 45, 45, 45, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 46, 1, 1, 1, + 1, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 1, 1, 1, 1, 1, + 1, 47, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 48, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 49, 1, 28, + 28, 28, 28, 28, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 28, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 29, 1, 55, 55, 1, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 1, 1, 1, 30, 1, 1, 31, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 1, 1, 32, 1, 55, 1, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 1, 33, 1, 0 +}; + +static const char _deserialize_text_trans_targs[] = { + 1, 0, 13, 17, 26, 3, 18, 21, + 18, 21, 5, 19, 20, 19, 20, 22, + 25, 8, 9, 12, 9, 12, 10, 11, + 23, 24, 23, 24, 14, 2, 6, 7, + 15, 16, 14, 15, 16, 17, 14, 4, + 15, 16, 14, 15, 16, 14, 2, 7, + 15, 16, 14, 2, 15, 16, 25, 26 +}; + +static const char _deserialize_text_trans_actions[] = { + 0, 0, 1, 1, 1, 2, 2, 2, + 0, 0, 2, 2, 2, 0, 0, 2, + 2, 2, 2, 2, 0, 0, 3, 2, + 2, 2, 0, 0, 4, 5, 5, 5, + 4, 4, 0, 0, 0, 0, 6, 7, + 6, 6, 8, 8, 8, 9, 10, 10, + 9, 9, 11, 12, 11, 11, 0, 0 +}; + +static const char _deserialize_text_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, + 0, 4, 6, 8, 8, 6, 9, 11, + 11, 9, 4 +}; + +static const int deserialize_text_start = 1; +static const int deserialize_text_first_final = 13; +static const int deserialize_text_error = 0; + +static const int deserialize_text_en_main = 1; + + +#line 91 "hb-buffer-deserialize-text.rl" + + +static hb_bool_t +_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? '|' : '[')) + { + *end_ptr = ++p; + } + + const char *eof = pe, *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 343 "hb-buffer-deserialize-text.hh" + { + cs = deserialize_text_start; + } + +#line 348 "hb-buffer-deserialize-text.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_text_trans_keys + (cs<<1); + _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs]; + + _slen = _deserialize_text_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_text_trans_targs[_trans]; + + if ( _deserialize_text_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_text_trans_actions[_trans] ) { + case 2: +#line 51 "hb-buffer-deserialize-text.rl" + { + tok = p; +} + break; + case 5: +#line 55 "hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 10: +#line 62 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 3: +#line 63 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: +#line 64 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 7: +#line 65 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 1: +#line 38 "hb-buffer-deserialize-text.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text.rl" + { + tok = p; +} + break; + case 4: +#line 55 "hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 62 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 64 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 6: +#line 65 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 8: +#line 66 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 480 "hb-buffer-deserialize-text.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + switch ( _deserialize_text_eof_actions[cs] ) { + case 4: +#line 55 "hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 62 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 64 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 6: +#line 65 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 8: +#line 66 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 557 "hb-buffer-deserialize-text.hh" + } + } + + _out: {} + } + +#line 119 "hb-buffer-deserialize-text.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ From 2d0265242bb9a080886d6e0aa653c62e5770a15a Mon Sep 17 00:00:00 2001 From: Rod Sheeter Date: Wed, 21 Feb 2018 09:42:46 -0800 Subject: [PATCH 03/35] [subset] keep the result of _subset --- src/hb-subset.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 418e481f8..a4794f18c 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -264,7 +264,7 @@ _subset_table (hb_subset_plan_t *plan, break; } DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED"); - return true; + return result; } static bool From fa13a04cf3345311a2434f0d7f6346f967491c45 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 22 Feb 2018 16:48:03 +0330 Subject: [PATCH 04/35] [dev-run] Add gdb/lldb shortcuts --- src/dev-run.sh | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/dev-run.sh b/src/dev-run.sh index 5a7ae1022..40f6463cb 100755 --- a/src/dev-run.sh +++ b/src/dev-run.sh @@ -13,26 +13,48 @@ [ $# = 0 ] && echo Usage: "src/dev-run.sh [FONT-FILE] [TEXT]" && exit command -v entr >/dev/null 2>&1 || { echo >&2 "This script needs `entr` be installed"; exit 1; } +GDB=gdb +# if gdb doesn't exist, hopefully lldb exist +command -v $GDB >/dev/null 2>&1 || export GDB="lldb" + [ -f 'build/build.ninja' ] && CMAKENINJA=TRUE # or "fswatch -0 . -e build/ -e .git" find src/ | entr printf '\0' | while read -d ""; do clear + echo '====================================================' if [[ $CMAKENINJA ]]; then - ninja -Cbuild hb-shape hb-view - build/hb-shape $@ - build/hb-view $@ + ninja -Cbuild hb-shape hb-view && { + build/hb-shape $@ + build/hb-view $@ + } else - make -Cbuild/src -j5 -s lib - build/util/hb-shape $@ - build/util/hb-view $@ + make -Cbuild/src -j5 -s lib && { + build/util/hb-shape $@ + build/util/hb-view $@ + } fi done -read -n 1 -p "Run the tests (y/n)? " answer -if [[ "$answer" = "y" ]]; then +read -n 1 -p "[T]est, [D]ebug, [R]estart, [Q]uit?" answer +case "$answer" in +t|T ) if [[ $CMAKENINJA ]]; then CTEST_OUTPUT_ON_FAILURE=1 CTEST_PARALLEL_LEVEL=5 ninja -Cbuild test else make -Cbuild -j5 check && .ci/fail.sh fi -fi +;; +d|D ) + if [[ $CMAKENINJA ]]; then + echo "Not supported on cmake builds yet" + else + build/libtool --mode=execute $GDB hb-shape $@ + fi +;; +r|R ) + src/dev-run.sh $@ +;; +* ) + exit +;; +esac From a6bd6bcee08c9522f9269b5c63f784688abddcff Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 22 Feb 2018 16:52:56 +0330 Subject: [PATCH 05/35] [dev-run] minor --- src/dev-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev-run.sh b/src/dev-run.sh index 40f6463cb..3b2257b1d 100755 --- a/src/dev-run.sh +++ b/src/dev-run.sh @@ -48,7 +48,7 @@ d|D ) if [[ $CMAKENINJA ]]; then echo "Not supported on cmake builds yet" else - build/libtool --mode=execute $GDB hb-shape $@ + build/libtool --mode=execute $GDB build/util/hb-shape $@ fi ;; r|R ) From 4f6f7c3b22ec788f609bdffc7e0893816657b3a0 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 23 Feb 2018 02:54:12 +0330 Subject: [PATCH 06/35] [util] Implement ppem/ptem on hb-{shape,view} (#811) --- util/options.cc | 33 ++++++++++++++++++++++++++++----- util/options.hh | 6 ++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/util/options.cc b/util/options.cc index 6d8064b90..d2444a499 100644 --- a/util/options.cc +++ b/util/options.cc @@ -481,6 +481,25 @@ parse_font_size (const char *name G_GNUC_UNUSED, return false; } } + +static gboolean +parse_font_ppem (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + font_options_t *font_opts = (font_options_t *) data; + switch (sscanf (arg, "%d%*[ ,]%d", &font_opts->x_ppem, &font_opts->y_ppem)) { + case 1: font_opts->y_ppem = font_opts->x_ppem; + case 2: return true; + default: + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "%s argument should be one or two space-separated numbers", + name); + return false; + } +} + void font_options_t::add_options (option_parser_t *parser) { @@ -513,12 +532,13 @@ font_options_t::add_options (option_parser_t *parser) GOptionEntry entries[] = { - {"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"}, - {"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"}, + {"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"}, + {"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"}, {"font-size", 0, default_font_size ? 0 : G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 numbers or 'upem'"}, - /* TODO Add font-ppem / font-ptem. */ - {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 integers or 'upem'"}, + {"font-ppem", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"}, + {"font-ptem", 0, 0, G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, + {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, {nullptr} }; parser->add_group (entries, @@ -691,6 +711,9 @@ font_options_t::get_font (void) const if (font_size_y == FONT_SIZE_UPEM) font_size_y = hb_face_get_upem (face); + hb_font_set_ppem (font, x_ppem, y_ppem); + hb_font_set_ptem (font, ptem); + int scale_x = (int) scalbnf (font_size_x, subpixel_bits); int scale_y = (int) scalbnf (font_size_y, subpixel_bits); hb_font_set_scale (font, scale_x, scale_y); diff --git a/util/options.hh b/util/options.hh index 411165bf2..cfbbade2f 100644 --- a/util/options.hh +++ b/util/options.hh @@ -452,6 +452,9 @@ struct font_options_t : option_group_t variations = nullptr; num_variations = 0; default_font_size = default_font_size_; + x_ppem = 0; + y_ppem = 0; + ptem = .0; subpixel_bits = subpixel_bits_; font_file = nullptr; face_index = 0; @@ -478,6 +481,9 @@ struct font_options_t : option_group_t hb_variation_t *variations; unsigned int num_variations; int default_font_size; + int x_ppem; + int y_ppem; + double ptem; unsigned int subpixel_bits; mutable double font_size_x; mutable double font_size_y; From fe42862ab30d17483a1d0c2e2b1d859d01bbaff1 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 14:18:49 -0800 Subject: [PATCH 07/35] [subset] Sketch out a basic hb-ot-hdmx.hh. --- src/Makefile.sources | 1 + src/hb-ot-hdmx-table.hh | 77 +++++++++++++++++++++++++++++++++++++++++ src/hb-subset.cc | 1 + 3 files changed, 79 insertions(+) create mode 100644 src/hb-ot-hdmx-table.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 9b96716d2..416ee44f7 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -20,6 +20,7 @@ HB_BASE_sources = \ hb-ot-cbdt-table.hh \ hb-ot-cmap-table.hh \ hb-ot-glyf-table.hh \ + hb-ot-hdmx-table.hh \ hb-ot-head-table.hh \ hb-ot-hhea-table.hh \ hb-ot-hmtx-table.hh \ diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh new file mode 100644 index 000000000..7117a9779 --- /dev/null +++ b/src/hb-ot-hdmx-table.hh @@ -0,0 +1,77 @@ +/* + * Copyright © 2018 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): Garret Rieger + */ + +#ifndef HB_OT_HDMX_TABLE_HH +#define HB_OT_HDMX_TABLE_HH + +#include "hb-open-type-private.hh" + +namespace OT { + +#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') + + +struct DeviceRecord +{ + HBUINT8 pixel_size; + HBUINT8 max_width; + HBUINT8 widths[VAR]; +}; + +struct hdmx +{ + inline unsigned int get_size (void) const + { + return min_size + num_records * size_device_record; + } + + inline const DeviceRecord& operator [] (unsigned int i) const + { + if (unlikely (i >= num_records)) return Null(DeviceRecord); + return StructAtOffset (this, min_size + i * size_device_record); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) + && version == 0)); + } + + HBUINT16 version; + HBINT16 num_records; + HBINT32 size_device_record; + + DeviceRecord records[VAR]; + + DEFINE_SIZE_MIN (8); + +}; + +} /* namespace OT */ + + +#endif /* HB_OT_HDMX_TABLE_HH */ diff --git a/src/hb-subset.cc b/src/hb-subset.cc index a4794f18c..1d6e636d4 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -35,6 +35,7 @@ #include "hb-open-file-private.hh" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-hdmx-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" From ab7a8f3b7419b604816e12cb93e77c0ba45a57af Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 15:15:22 -0800 Subject: [PATCH 08/35] [subset] Begin implementing serialize for hdmx. --- src/hb-ot-hdmx-table.hh | 79 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 7117a9779..a506c2940 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -36,13 +36,61 @@ namespace OT { struct DeviceRecord { + struct SubsetView + { + const DeviceRecord *source_device_record; + hb_subset_plan_t *subset_plan; + + inline void init(const DeviceRecord *source_device_record, + hb_subset_plan_t *subset_plan) + { + this->source_device_record = source_device_record; + this->subset_plan = subset_plan; + } + + inline unsigned int len () const + { + return this->subset_plan->gids_to_retain_sorted.len; + } + + inline const HBUINT8& operator [] (unsigned int i) const + { + if (unlikely (i >= len())) return Null(HBUINT8); + hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; + return this->source_device_record->widths[gid]; + } + }; + + inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + this->pixel_size.set (subset_view.source_device_record->pixel_size); + this->max_width.set (subset_view.source_device_record->max_width); + + for (unsigned int i = 0; i < subset_view.len(); i++) + { + HBUINT8 *width = c->extend (this->widths[i]); + if (unlikely (!width)) return_trace (false); + width->set (subset_view[i]); + } + + return_trace (true); + } + HBUINT8 pixel_size; HBUINT8 max_width; HBUINT8 widths[VAR]; + + DEFINE_SIZE_MIN (2); }; + + struct hdmx { + inline unsigned int get_size (void) const { return min_size + num_records * size_device_record; @@ -54,6 +102,33 @@ struct hdmx return StructAtOffset (this, min_size + i * size_device_record); } + inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->version.set (source_hdmx->version); + this->num_records.set (source_hdmx->num_records); + this->size_device_record.set (source_hdmx->size_device_record); + + for (unsigned int i = 0; i < source_hdmx->num_records; i++) + { + DeviceRecord::SubsetView subset_view; + subset_view.init (&(*source_hdmx)[i], plan); + + c->start_embed ()->serialize (c, subset_view); + } + + return_trace (true); + } + + inline bool subset (hb_subset_plan_t *plan) const + { + // TODO(grieger) + return false; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -65,10 +140,10 @@ struct hdmx HBINT16 num_records; HBINT32 size_device_record; - DeviceRecord records[VAR]; - DEFINE_SIZE_MIN (8); + private: + DeviceRecord records[VAR]; }; } /* namespace OT */ From dddf44279f610e77e8b9a0819fd91f48802158b6 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 15:36:09 -0800 Subject: [PATCH 09/35] [subset] When serializing a DeviceRecord in hdmx pad to make 32 bit aligned. --- src/hb-ot-hdmx-table.hh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index a506c2940..deedd3808 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -53,6 +53,15 @@ struct DeviceRecord return this->subset_plan->gids_to_retain_sorted.len; } + inline unsigned int get_size () const + { + unsigned int raw_size = min_size + len () * HBUINT8::static_size; + if (raw_size % 4) + /* Align to 32 bits */ + return raw_size + (4 - (raw_size % 4)); + return raw_size; + } + inline const HBUINT8& operator [] (unsigned int i) const { if (unlikely (i >= len())) return Null(HBUINT8); @@ -65,16 +74,14 @@ struct DeviceRecord { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min ((*this)))) return_trace (false); + if (unlikely (!c->allocate_size (subset_view.get_size()))) + return_trace (false); + this->pixel_size.set (subset_view.source_device_record->pixel_size); this->max_width.set (subset_view.source_device_record->max_width); for (unsigned int i = 0; i < subset_view.len(); i++) - { - HBUINT8 *width = c->extend (this->widths[i]); - if (unlikely (!width)) return_trace (false); - width->set (subset_view[i]); - } + widths[i].set (subset_view[i]); return_trace (true); } From 84b68e58862647b4ede414b2e608c47d390fd60a Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 15:43:47 -0800 Subject: [PATCH 10/35] [subset] In hdmx serialize set the correct value of sizeDeviceRecord. --- src/hb-ot-hdmx-table.hh | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index deedd3808..5f0d197ad 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -53,15 +53,6 @@ struct DeviceRecord return this->subset_plan->gids_to_retain_sorted.len; } - inline unsigned int get_size () const - { - unsigned int raw_size = min_size + len () * HBUINT8::static_size; - if (raw_size % 4) - /* Align to 32 bits */ - return raw_size + (4 - (raw_size % 4)); - return raw_size; - } - inline const HBUINT8& operator [] (unsigned int i) const { if (unlikely (i >= len())) return Null(HBUINT8); @@ -70,11 +61,20 @@ struct DeviceRecord } }; + static inline unsigned int get_size (unsigned int count) + { + unsigned int raw_size = min_size + count * HBUINT8::static_size; + if (raw_size % 4) + /* Align to 32 bits */ + return raw_size + (4 - (raw_size % 4)); + return raw_size; + } + inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) { TRACE_SERIALIZE (this); - if (unlikely (!c->allocate_size (subset_view.get_size()))) + if (unlikely (!c->allocate_size (get_size (subset_view.len())))) return_trace (false); this->pixel_size.set (subset_view.source_device_record->pixel_size); @@ -93,8 +93,6 @@ struct DeviceRecord DEFINE_SIZE_MIN (2); }; - - struct hdmx { @@ -117,7 +115,7 @@ struct hdmx this->version.set (source_hdmx->version); this->num_records.set (source_hdmx->num_records); - this->size_device_record.set (source_hdmx->size_device_record); + this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len)); for (unsigned int i = 0; i < source_hdmx->num_records; i++) { @@ -130,6 +128,11 @@ struct hdmx return_trace (true); } + static inline unsigned int get_subsetted_size (hb_subset_plan_t *plan) + { + return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len); + } + inline bool subset (hb_subset_plan_t *plan) const { // TODO(grieger) From 6704cded65985b2de262bdd3bb0887929e5a3b0b Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 16:00:10 -0800 Subject: [PATCH 11/35] [subset] Add hdmx subsetting implementation. --- src/hb-ot-hdmx-table.hh | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 5f0d197ad..d25570585 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -128,15 +128,38 @@ struct hdmx return_trace (true); } - static inline unsigned int get_subsetted_size (hb_subset_plan_t *plan) + static inline size_t get_subsetted_size (hb_subset_plan_t *plan) { return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len); } inline bool subset (hb_subset_plan_t *plan) const { - // TODO(grieger) - return false; + size_t dest_size = get_subsetted_size (plan); + hdmx *dest = (hdmx *) malloc (dest_size); + if (unlikely (!dest)) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for hdmx subset output.", (unsigned long) dest_size); + return false; + } + + hb_serialize_context_t c (dest, dest_size); + hdmx *hdmx_prime = c.start_serialize (); + if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan)) { + free (dest); + return false; + } + c.end_serialize (); + + hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest, + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob); + hb_blob_destroy (hdmx_prime_blob); + + return result; } inline bool sanitize (hb_sanitize_context_t *c) const From bd18b6adf8697c1ce3f4e3831b9f2a99d930e97d Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 17:42:58 -0800 Subject: [PATCH 12/35] [subset] Move DeviceRecord inside of hdmx. --- src/hb-ot-hdmx-table.hh | 118 ++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index d25570585..6bf492cbf 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -34,67 +34,69 @@ namespace OT { #define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') -struct DeviceRecord -{ - struct SubsetView - { - const DeviceRecord *source_device_record; - hb_subset_plan_t *subset_plan; - - inline void init(const DeviceRecord *source_device_record, - hb_subset_plan_t *subset_plan) - { - this->source_device_record = source_device_record; - this->subset_plan = subset_plan; - } - - inline unsigned int len () const - { - return this->subset_plan->gids_to_retain_sorted.len; - } - - inline const HBUINT8& operator [] (unsigned int i) const - { - if (unlikely (i >= len())) return Null(HBUINT8); - hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; - return this->source_device_record->widths[gid]; - } - }; - - static inline unsigned int get_size (unsigned int count) - { - unsigned int raw_size = min_size + count * HBUINT8::static_size; - if (raw_size % 4) - /* Align to 32 bits */ - return raw_size + (4 - (raw_size % 4)); - return raw_size; - } - - inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) - { - TRACE_SERIALIZE (this); - - if (unlikely (!c->allocate_size (get_size (subset_view.len())))) - return_trace (false); - - this->pixel_size.set (subset_view.source_device_record->pixel_size); - this->max_width.set (subset_view.source_device_record->max_width); - - for (unsigned int i = 0; i < subset_view.len(); i++) - widths[i].set (subset_view[i]); - - return_trace (true); - } - - HBUINT8 pixel_size; - HBUINT8 max_width; - HBUINT8 widths[VAR]; - - DEFINE_SIZE_MIN (2); -}; struct hdmx { + static const hb_tag_t tableTag = HB_OT_TAG_glyf; + + struct DeviceRecord + { + struct SubsetView + { + const DeviceRecord *source_device_record; + hb_subset_plan_t *subset_plan; + + inline void init(const DeviceRecord *source_device_record, + hb_subset_plan_t *subset_plan) + { + this->source_device_record = source_device_record; + this->subset_plan = subset_plan; + } + + inline unsigned int len () const + { + return this->subset_plan->gids_to_retain_sorted.len; + } + + inline const HBUINT8& operator [] (unsigned int i) const + { + if (unlikely (i >= len())) return Null(HBUINT8); + hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; + return this->source_device_record->widths[gid]; + } + }; + + static inline unsigned int get_size (unsigned int count) + { + unsigned int raw_size = min_size + count * HBUINT8::static_size; + if (raw_size % 4) + /* Align to 32 bits */ + return raw_size + (4 - (raw_size % 4)); + return raw_size; + } + + inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->allocate_size (get_size (subset_view.len())))) + return_trace (false); + + this->pixel_size.set (subset_view.source_device_record->pixel_size); + this->max_width.set (subset_view.source_device_record->max_width); + + for (unsigned int i = 0; i < subset_view.len(); i++) + widths[i].set (subset_view[i]); + + return_trace (true); + } + + HBUINT8 pixel_size; + HBUINT8 max_width; + HBUINT8 widths[VAR]; + + DEFINE_SIZE_MIN (2); + }; inline unsigned int get_size (void) const { From aa4aa2353c52f86fd56446de6b7ff86a9e990b9c Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 17:43:32 -0800 Subject: [PATCH 13/35] [subset] Enable hdmx subsetting. --- src/hb-subset.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 1d6e636d4..a9f599f93 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -230,6 +230,9 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_glyf: result = _subset (plan); break; + case HB_OT_TAG_hdmx: + result = _subset (plan); + break; case HB_OT_TAG_head: // SKIP head, it's handled by glyf result = true; From 15fc45bfedef433025145289fe916739907b573b Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 21 Feb 2018 17:59:57 -0800 Subject: [PATCH 14/35] [subset] Add a unit test for hdmx subsetting. --- test/api/Makefile.am | 2 + test/api/test-subset-hdmx.c | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/api/test-subset-hdmx.c diff --git a/test/api/Makefile.am b/test/api/Makefile.am index ecf447545..e2e6166c0 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -33,6 +33,7 @@ TEST_PROGS = \ test-shape \ test-subset-cmap \ test-subset-glyf \ + test-subset-hdmx \ test-subset-hmtx \ test-subset-os2 \ test-unicode \ @@ -42,6 +43,7 @@ TEST_PROGS = \ test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la +test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_hmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_os2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c new file mode 100644 index 000000000..291eb7937 --- /dev/null +++ b/test/api/test-subset-hdmx.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2018 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): Garret Rieger + */ + +#include + +#include "hb-test.h" +#include "hb-subset-test.h" + +/* Unit tests for hdmx subsetting */ + + +static void +test_subset_hdmx_simple_subset (void) +{ + hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'c'); + hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('h','d','m','x')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + +static void +test_subset_hdmx_noop (void) +{ + hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + + hb_set_t *codepoints = hb_set_create(); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('h','d','m','x')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_hdmx_simple_subset); + hb_test_add (test_subset_hdmx_noop); + + return hb_test_run(); +} From ec302ad5bda6bea870f6d33f9698a1782472a213 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 11:57:35 -0800 Subject: [PATCH 15/35] [subset] Fail subset if a table fails to sanitize. --- src/hb-subset.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index a9f599f93..b7d3e3710 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -83,16 +83,19 @@ template static bool _subset (hb_subset_plan_t *plan) { - OT::Sanitizer sanitizer; - hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag)); - const TableType *table = OT::Sanitizer::lock_instance (source_blob); - hb_bool_t result = table->subset(plan); + OT::Sanitizer sanitizer; - hb_blob_destroy (source_blob); + hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag)); + const TableType *table = OT::Sanitizer::lock_instance (source_blob); - hb_tag_t tag = TableType::tableTag; - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); - return result; + hb_bool_t result = false; + if (table != &OT::Null(TableType)) + result = table->subset(plan); + + hb_blob_destroy (source_blob); + hb_tag_t tag = TableType::tableTag; + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + return result; } From 6b372f439b257808b048d02ebf5a867dabcd1231 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 12:00:00 -0800 Subject: [PATCH 16/35] [subset] In hb-ot-hdmx-table, s/glyf/hdmx. --- src/hb-ot-hdmx-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 6bf492cbf..90d7448b0 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -37,7 +37,7 @@ namespace OT { struct hdmx { - static const hb_tag_t tableTag = HB_OT_TAG_glyf; + static const hb_tag_t tableTag = HB_OT_TAG_hdmx; struct DeviceRecord { From c02532a3d2325c8fb9332f63f687cbaec77b2239 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 16:40:50 -0800 Subject: [PATCH 17/35] [subset] Formatting and comments in hdmx. --- src/hb-ot-hdmx-table.hh | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 90d7448b0..1d9fe07b7 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -31,10 +31,12 @@ namespace OT { +/* + * hdmx - Horizontal Device Metric + */ + #define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') - - struct hdmx { static const hb_tag_t tableTag = HB_OT_TAG_hdmx; @@ -91,10 +93,15 @@ struct hdmx return_trace (true); } - HBUINT8 pixel_size; - HBUINT8 max_width; - HBUINT8 widths[VAR]; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ + HBUINT8 max_width; /* Maximum width. */ + HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ DEFINE_SIZE_MIN (2); }; @@ -171,14 +178,14 @@ struct hdmx && version == 0)); } - HBUINT16 version; - HBINT16 num_records; - HBINT32 size_device_record; - - DEFINE_SIZE_MIN (8); - + public: + HBUINT16 version; /* Table version number (0) */ + HBINT16 num_records; /* Number of device records. */ + HBINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ private: - DeviceRecord records[VAR]; + DeviceRecord records[VAR]; /* Array of device records. */ + public: + DEFINE_SIZE_MIN (8); }; } /* namespace OT */ From 96d7805a9235443972c6b6c5cd9502283c8836e9 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 16:48:28 -0800 Subject: [PATCH 18/35] [subset] More complete sanitization implementation for hdmx. --- src/hb-ot-hdmx-table.hh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 1d9fe07b7..0033e3ec2 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -93,10 +93,11 @@ struct hdmx return_trace (true); } - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this) + && c->check_range (this, size_device_record))); } HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ @@ -174,8 +175,17 @@ struct hdmx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) - && version == 0)); + if (unlikely (!c->check_struct (this) || version != 0)) + return_trace (false); + if (unlikely (!c->check_range (this, get_size()))) + return_trace (false); + + for (unsigned int i = 0; i < num_records; i++) + { + if (unlikely (!records[i].sanitize (c, size_device_record))) + return_trace (false); + } + return_trace (true); } public: From cf7a6e520e9601da9d27bc8f6bbe5d2eff23998d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 10:34:26 -0800 Subject: [PATCH 19/35] [hdmx] Move DeviceRecord to toplevel again More readable. --- src/hb-ot-hdmx-table.hh | 132 ++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 0033e3ec2..d13d7aac5 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -31,81 +31,83 @@ namespace OT { + /* * hdmx - Horizontal Device Metric */ #define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') +struct DeviceRecord +{ + struct SubsetView + { + const DeviceRecord *source_device_record; + hb_subset_plan_t *subset_plan; + + inline void init(const DeviceRecord *source_device_record, + hb_subset_plan_t *subset_plan) + { + this->source_device_record = source_device_record; + this->subset_plan = subset_plan; + } + + inline unsigned int len () const + { + return this->subset_plan->gids_to_retain_sorted.len; + } + + inline const HBUINT8& operator [] (unsigned int i) const + { + if (unlikely (i >= len())) return Null(HBUINT8); + hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; + return this->source_device_record->widths[gid]; + } + }; + + static inline unsigned int get_size (unsigned int count) + { + unsigned int raw_size = min_size + count * HBUINT8::static_size; + if (raw_size % 4) + /* Align to 32 bits */ + return raw_size + (4 - (raw_size % 4)); + return raw_size; + } + + inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->allocate_size (get_size (subset_view.len())))) + return_trace (false); + + this->pixel_size.set (subset_view.source_device_record->pixel_size); + this->max_width.set (subset_view.source_device_record->max_width); + + for (unsigned int i = 0; i < subset_view.len(); i++) + widths[i].set (subset_view[i]); + + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + c->check_range (this, size_device_record))); + } + + HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ + HBUINT8 max_width; /* Maximum width. */ + HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ + DEFINE_SIZE_MIN (2); +}; + + struct hdmx { static const hb_tag_t tableTag = HB_OT_TAG_hdmx; - struct DeviceRecord - { - struct SubsetView - { - const DeviceRecord *source_device_record; - hb_subset_plan_t *subset_plan; - - inline void init(const DeviceRecord *source_device_record, - hb_subset_plan_t *subset_plan) - { - this->source_device_record = source_device_record; - this->subset_plan = subset_plan; - } - - inline unsigned int len () const - { - return this->subset_plan->gids_to_retain_sorted.len; - } - - inline const HBUINT8& operator [] (unsigned int i) const - { - if (unlikely (i >= len())) return Null(HBUINT8); - hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; - return this->source_device_record->widths[gid]; - } - }; - - static inline unsigned int get_size (unsigned int count) - { - unsigned int raw_size = min_size + count * HBUINT8::static_size; - if (raw_size % 4) - /* Align to 32 bits */ - return raw_size + (4 - (raw_size % 4)); - return raw_size; - } - - inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) - { - TRACE_SERIALIZE (this); - - if (unlikely (!c->allocate_size (get_size (subset_view.len())))) - return_trace (false); - - this->pixel_size.set (subset_view.source_device_record->pixel_size); - this->max_width.set (subset_view.source_device_record->max_width); - - for (unsigned int i = 0; i < subset_view.len(); i++) - widths[i].set (subset_view[i]); - - return_trace (true); - } - - inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) - && c->check_range (this, size_device_record))); - } - - HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ - HBUINT8 max_width; /* Maximum width. */ - HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ - DEFINE_SIZE_MIN (2); - }; - inline unsigned int get_size (void) const { return min_size + num_records * size_device_record; From 84d4bb91ceca22484abb597c19eb18311e2514f1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 10:38:35 -0800 Subject: [PATCH 20/35] [hdmx] Minor --- src/hb-ot-hdmx-table.hh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index d13d7aac5..a4491518d 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -100,7 +100,8 @@ struct DeviceRecord HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ HBUINT8 max_width; /* Maximum width. */ HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ - DEFINE_SIZE_MIN (2); + public: + DEFINE_SIZE_ARRAY (2, widths); }; @@ -164,10 +165,10 @@ struct hdmx c.end_serialize (); hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob); hb_blob_destroy (hdmx_prime_blob); @@ -185,17 +186,17 @@ struct hdmx for (unsigned int i = 0; i < num_records; i++) { if (unlikely (!records[i].sanitize (c, size_device_record))) - return_trace (false); + return_trace (false); } return_trace (true); } public: - HBUINT16 version; /* Table version number (0) */ - HBINT16 num_records; /* Number of device records. */ - HBINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ + HBUINT16 version; /* Table version number (0) */ + HBUINT16 num_records; /* Number of device records. */ + HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ private: - DeviceRecord records[VAR]; /* Array of device records. */ + DeviceRecord records[VAR]; /* Array of device records. */ public: DEFINE_SIZE_MIN (8); }; From c2e4713b5b561675b0f7b358ccf83d64ef0b6c41 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 10:45:03 -0800 Subject: [PATCH 21/35] [hdmx] Fix sanitize() --- src/hb-ot-hdmx-table.hh | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index a4491518d..f08fe39d8 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -178,27 +178,18 @@ struct hdmx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || version != 0)) - return_trace (false); - if (unlikely (!c->check_range (this, get_size()))) - return_trace (false); - - for (unsigned int i = 0; i < num_records; i++) - { - if (unlikely (!records[i].sanitize (c, size_device_record))) - return_trace (false); - } - return_trace (true); + return_trace (c->check_struct (this) && version == 0 && + !_hb_unsigned_int_mul_overflows (num_records, size_device_record) && + c->check_range (this, get_size())); } - public: + protected: HBUINT16 version; /* Table version number (0) */ HBUINT16 num_records; /* Number of device records. */ HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ - private: - DeviceRecord records[VAR]; /* Array of device records. */ - public: - DEFINE_SIZE_MIN (8); + HBUINT8 data[VAR]; /* Array of device records. */ + public: + DEFINE_SIZE_ARRAY (8, data); }; } /* namespace OT */ From 537698b60131bd3d7999919a04596c41dda6b2e4 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 14:07:52 -0800 Subject: [PATCH 22/35] [subset] Don't compare actual to itself in Fix test/subset/run-tests. Print a diff on failure. --- test/subset/run-tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py index f648627ec..0dc14f382 100755 --- a/test/subset/run-tests.py +++ b/test/subset/run-tests.py @@ -6,6 +6,7 @@ from __future__ import print_function import io +from difflib import unified_diff import os import re import subprocess @@ -59,9 +60,12 @@ def run_test(test): return fail_test(test, cli_args, "ttx (actual) returned %d" % (return_code)) expected_ttx = strip_check_sum (expected_ttx) - actual_ttx = strip_check_sum (expected_ttx) + actual_ttx = strip_check_sum (actual_ttx) if not actual_ttx == expected_ttx: + for line in unified_diff(expected_ttx.splitlines(1), actual_ttx.splitlines(1)): + sys.stdout.write(line) + sys.stdout.flush() return fail_test(test, cli_args, 'ttx for expected and actual does not match.') return 0 From a88504c601ac95601730bd602861c13e5ac4fdd8 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 14:28:18 -0800 Subject: [PATCH 23/35] [subset] Fix checksum clearning in subset test diff. Add an updated expected file (has cmap4 restored). --- .../basics/Roboto-Regular.abc.default.62.ttf | Bin 1692 -> 1740 bytes test/subset/run-tests.py | 7 +++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf index 501d1d288c38e4ed350fe0fd177e11e8b6fb224c..52706dc90320133d24a0a6c3109b9d1ef1bf8ec7 100644 GIT binary patch delta 493 zcmX|-%_~Gv7{;Ib>E6jlGo%=4%IuV6A>t3fQWkdRny(vkxtWPUntx!5nk|vl$bwKx z(kv_}D>XYyOKA!`D(b?4+M0FkI;xd=+{fP6)skFIAz zgT5=|7&z&7}vZki`*smz! zcHD}6FFkLu_LV$pQ}Eqr$H+krQwZBmCTp0eu%M4@q*kLA7U)5G;iWrP)|E#TQ#?)% ztyoT6zV>}EWRu6-)pW*l5F;OnxVsj2j}tWxq&~1_8Zz?Un;O!AcJv@|5$Fy21LNm~ zJ?$hXu|mc!x-kb0fovz+0R<=r)&-z zX`;ynjiuxfQ+JRT^)0D7KhT`61?w~BaI-gs|0Nf)Qe=uK-ctF68m;no`sfK=Sbi-g bp&~@9atnRY^P0DJ*z9~+m9~|_gl_!;PVr#o delta 418 zcmXX?JxIeq7=5`UZBkOj9|~57fE@(ENu-0Ipo8uXF4D%NZG^@KTWmz6yL6~@)x}A4 zaBy%DQE(9)oW#*p=ui+rrC48D5AN=JKi|8br}%Nak*G-lfUNCVJ_hj(NG;+id$(dv zpG8jqb%J;;?-#u4SM~xBqx9Sqtg;UcBS54<-6$0I@^_cgBmH6Ct?PJ!t|~El-$LEZ zSx&dAFS71%&bcIvqs10xN1F|=#9FarTgb42>T`*BR^W>2d0LlUC*ig(~RA1|_q92are@}Q6Fu?O5Qea$jMPyC6 i4yPBsx9_qGJNz==f1fWvHt+9ZBOO^ diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py index 0dc14f382..b1dc7bef3 100755 --- a/test/subset/run-tests.py +++ b/test/subset/run-tests.py @@ -77,8 +77,11 @@ def run_ttx(file): return cmd(cli_args) def strip_check_sum (ttx_string): - return re.sub ('checksumAdjustment value=["]0x(\d+)["]', - 'checksumAdjustment value="0x00000000"', +# return re.sub ('checkSumAdjustment value=["]0x(\d+)["]', +# 'checkSumAdjustment value="0x00000000"', +# ttx_string, count=1) + return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]', + 'checkSumAdjustment value="0x00000000"', ttx_string, count=1) args = sys.argv[1:] From 2b844803433bd1557a7fd0c93a91c66ef5319b21 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 18:38:44 -0800 Subject: [PATCH 24/35] [subset] Update expected files for subsetting integration test to not include cmap 4. --- .../basics/Roboto-Regular.abc.default.62.ttf | Bin 1740 -> 1692 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf index 52706dc90320133d24a0a6c3109b9d1ef1bf8ec7..8d7e6b2279e0d37a78ad39cb522cc85c13269a24 100644 GIT binary patch delta 125 zcmX@ZJBN3IqB%dqPX-32Ees3{8p&lP3fe2!=Q1#`J^}JW(hAaZ%YP)S2Fl-IU|`&n zo>*MKz`-EQz`!Rje#^aof49pB%Km|OTKQP^41^};VBla72Ff3p7*Vg70aRpBkY8N#KbIi|D7XN~S12e-Em)NH>m&mM%ZZ6UzB0?L yNT2+H@wg>3P!fb?fFvW7<^s|-3@i)^K$-;zLE=gO|3k?C^TB+E%?Ft7FarP_87jd5 From e15e41ef12e146333e355defef8db210378b5be0 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 22 Feb 2018 18:41:50 -0800 Subject: [PATCH 25/35] [subset] Remove commented code from run-tests.py. --- test/subset/run-tests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py index b1dc7bef3..99f97826e 100755 --- a/test/subset/run-tests.py +++ b/test/subset/run-tests.py @@ -77,9 +77,6 @@ def run_ttx(file): return cmd(cli_args) def strip_check_sum (ttx_string): -# return re.sub ('checkSumAdjustment value=["]0x(\d+)["]', -# 'checkSumAdjustment value="0x00000000"', -# ttx_string, count=1) return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]', 'checkSumAdjustment value="0x00000000"', ttx_string, count=1) From e0939d811f1fdeda9c5763e7e53887b3d3cb21eb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 13:19:34 -0800 Subject: [PATCH 26/35] Clean up check-defs and check-symbols (#821) Also, call c++filt on their results. Also build and fix and check harfbuzz-gobject.def Also changes harfbuzz-gobject to distribute generated enum sources. --- CMakeLists.txt | 3 +-- src/Makefile.am | 33 +++++++++++++---------- src/Makefile.sources | 9 ++++--- src/check-defs.sh | 52 ------------------------------------- src/check-symbols.sh | 32 +++++++++++++++++------ src/hb-gobject-enums.h.tmpl | 3 ++- src/hb-gobject-structs.h | 45 +++++++++++++++++++++----------- 7 files changed, 82 insertions(+), 95 deletions(-) delete mode 100755 src/check-defs.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c19a4b98..6b4e10899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -836,10 +836,9 @@ if (UNIX OR MINGW) ) add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh) add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh) - add_test(NAME check-defs.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-defs.sh) set_tests_properties( - check-static-inits.sh check-libstdc++.sh check-symbols.sh check-defs.sh + check-static-inits.sh check-libstdc++.sh check-symbols.sh PROPERTIES ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src" SKIP_RETURN_CODE 77) diff --git a/src/Makefile.am b/src/Makefile.am index aba6803cd..769a8252b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -125,10 +125,12 @@ HBLIBS += $(HBNONPCLIBS) if OS_WIN32 export_symbols = -export-symbols harfbuzz.def harfbuzz_def_dependency = harfbuzz.def -export_symbols_icu = -export-symbols harfbuzz-icu.def -harfbuzz_icu_def_dependency = harfbuzz-icu.def export_symbols_subset = -export-symbols harfbuzz-subset.def harfbuzz_subset_def_dependency = harfbuzz-subset.def +export_symbols_icu = -export-symbols harfbuzz-icu.def +harfbuzz_icu_def_dependency = harfbuzz-icu.def +export_symbols_gobject = -export-symbols harfbuzz-gobject.def +harfbuzz_gobject_def_dependency = harfbuzz-gobject.def chosen_linker = $(CXXLINK) else if WITH_LIBSTDCXX @@ -210,13 +212,14 @@ EXTRA_DIST += harfbuzz-icu.pc.in if HAVE_GOBJECT lib_LTLIBRARIES += libharfbuzz-gobject.la libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS) -libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_sources) -nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources) +libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources) +nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources) libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS) libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la -pkginclude_HEADERS += $(HB_GOBJECT_headers) -nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers) +EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency) +pkginclude_HEADERS += $(HB_GOBJECT_DIST_headers) +nodist_pkginclude_HEADERS += $(HB_GOBJECT_NODIST_headers) pkgconfig_DATA += harfbuzz-gobject.pc BUILT_SOURCES += \ @@ -256,12 +259,19 @@ EXTRA_DIST += \ CLEANFILES += $(pkgconfig_DATA) -CLEANFILES += harfbuzz.def harfbuzz-icu.def harfbuzz-subset.def +DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def +if HAVE_GOBJECT +DEF_FILES += harfbuzz-gobject.def +endif +check: $(DEF_FILES) # For check-symbols.sh +CLEANFILES += $(DEF_FILES) harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ +harfbuzz-subset.def: $(HB_SUBSET_headers) + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ harfbuzz-icu.def: $(HB_ICU_headers) $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ -harfbuzz-subset.def: $(HB_SUBSET_headers) +harfbuzz-gobject.def: $(HB_GOBJECT_headers) $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ @@ -335,11 +345,8 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) -check: harfbuzz.def harfbuzz-icu.def harfbuzz-subset.def # For check-defs.sh - dist_check_SCRIPTS = \ check-c-linkage-decls.sh \ - check-defs.sh \ check-externs.sh \ check-header-guards.sh \ check-includes.sh \ @@ -415,10 +422,8 @@ HarfBuzz_0_0_gir_FILES = \ $(HBHEADERS) \ $(HBNODISTHEADERS) \ $(HBSOURCES) \ - $(HB_GOBJECT_ENUM_sources) \ - $(HB_GOBJECT_ENUM_headers) \ $(HB_GOBJECT_sources) \ - $(HB_GOBJECT_STRUCTS_headers) \ + $(HB_GOBJECT_headers) \ $(NULL) girdir = $(datadir)/gir-1.0 diff --git a/src/Makefile.sources b/src/Makefile.sources index 416ee44f7..2bb56b4f9 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -201,8 +201,11 @@ HB_SUBSET_headers = \ hb-subset-private.hh \ $(NULL) -HB_GOBJECT_sources = hb-gobject-structs.cc -HB_GOBJECT_STRUCTS_headers = hb-gobject-structs.h -HB_GOBJECT_headers = hb-gobject.h $(HB_GOBJECT_STRUCTS_headers) +HB_GOBJECT_DIST_sources = hb-gobject-structs.cc +HB_GOBJECT_DIST_headers = hb-gobject.h hb-gobject-structs.h HB_GOBJECT_ENUM_sources = hb-gobject-enums.cc HB_GOBJECT_ENUM_headers = hb-gobject-enums.h +HB_GOBJECT_NODIST_sources = $(HB_GOBJECT_ENUM_sources) +HB_GOBJECT_NODIST_headers = $(HB_GOBJECT_ENUM_headers) +HB_GOBJECT_sources = $(HB_GOBJECT_DIST_sources) $(HB_GOBJECT_NODIST_sources) +HB_GOBJECT_headers = $(HB_GOBJECT_DIST_headers) $(HB_GOBJECT_NODIST_headers) diff --git a/src/check-defs.sh b/src/check-defs.sh deleted file mode 100755 index ade593570..000000000 --- a/src/check-defs.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -test -z "$srcdir" && srcdir=. -test -z "$libs" && libs=.libs -stat=0 - -if which nm 2>/dev/null >/dev/null; then - : -else - echo "check-defs.sh: 'nm' not found; skipping test" - exit 77 -fi - -tested=false -for def in harfbuzz.def harfbuzz-icu.def harfbuzz-subset.def; do - if ! test -f "$def"; then - echo "check-defs.sh: '$def' not found; skipping test it" - continue - fi - lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'` - for suffix in so dylib; do - so=$libs/lib${lib}.$suffix - if ! test -f "$so"; then continue; fi - - # On macOS, C symbols are prefixed with _ - if test $suffix = dylib; then prefix="_"; fi - - EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $prefix"'\(_fini\>\|_init\>\|_fdata\>\|_ftext\>\|_fbss\>\|__bss_start\>\|__bss_start__\>\|__bss_end__\>\|_edata\>\|_end\>\|_bss_end__\>\|__end__\>\|__gcov_flush\>\|llvm_\)' | cut -d' ' -f3`" - - if test -f "$so"; then - - echo "Checking that $so has the same symbol list as $def" - { - echo EXPORTS - echo "$EXPORTED_SYMBOLS" | sed -e "s/^${prefix}hb/hb/g" - # cheat: copy the last line from the def file! - tail -n1 "$def" - } | diff "$def" - >&2 || stat=1 - - tested=true - fi - done -done -if ! $tested; then - echo "check-defs.sh: libharfbuzz shared library not found; skipping test" - exit 77 -fi - -exit $stat diff --git a/src/check-symbols.sh b/src/check-symbols.sh index af8af4416..bfc93b349 100755 --- a/src/check-symbols.sh +++ b/src/check-symbols.sh @@ -7,6 +7,7 @@ test -z "$srcdir" && srcdir=. test -z "$libs" && libs=.libs stat=0 +IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_flush\|llvm_.*' if which nm 2>/dev/null >/dev/null; then : @@ -15,31 +16,46 @@ else exit 77 fi -echo "Checking that we are not exposing internal symbols" tested=false for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do for suffix in so dylib; do so=$libs/lib$soname.$suffix if ! test -f "$so"; then continue; fi - EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| ___gcov_flush\>\| llvm_\| _llvm_' | cut -d' ' -f3`" - - prefix=`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` - # On macOS, C symbols are prefixed with _ - if test $suffix = dylib; then prefix="_$prefix"; fi + symprefix= + if test $suffix = dylib; then symprefix=_; fi - echo "Processing $so" + EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`" + + prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` + + echo + echo "Checking that $so does not expose internal symbols" if echo "$EXPORTED_SYMBOLS" | grep -v "^${prefix}\(_\|$\)"; then echo "Ouch, internal symbols exposed" stat=1 fi + def=$soname.def + if ! test -f "$def"; then + echo "'$def' not found; skipping" + else + echo + echo "Checking that $so has the same symbol list as $def" + { + echo EXPORTS + echo "$EXPORTED_SYMBOLS" | sed -e "s/^${symprefix}hb/hb/g" + # cheat: copy the last line from the def file! + tail -n1 "$def" + } | c++filt | diff "$def" - >&2 || stat=1 + fi + tested=true done done if ! $tested; then - echo "check-symbols.sh: no shared library found; skipping test" + echo "check-symbols.sh: no shared libraries found; skipping test" exit 77 fi diff --git a/src/hb-gobject-enums.h.tmpl b/src/hb-gobject-enums.h.tmpl index e28510c22..606727cd3 100644 --- a/src/hb-gobject-enums.h.tmpl +++ b/src/hb-gobject-enums.h.tmpl @@ -42,7 +42,8 @@ HB_BEGIN_DECLS /*** END file-header ***/ /*** BEGIN value-header ***/ -HB_EXTERN GType @enum_name@_get_type (void) G_GNUC_CONST; +HB_EXTERN GType +@enum_name@_get_type (void) G_GNUC_CONST; #define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) /*** END value-header ***/ diff --git a/src/hb-gobject-structs.h b/src/hb-gobject-structs.h index a34b06abb..302dc9584 100644 --- a/src/hb-gobject-structs.h +++ b/src/hb-gobject-structs.h @@ -45,7 +45,8 @@ HB_BEGIN_DECLS * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_blob_get_type (void); +HB_EXTERN GType +hb_gobject_blob_get_type (void); #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) /** @@ -53,7 +54,8 @@ HB_EXTERN GType hb_gobject_blob_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_buffer_get_type (void); +HB_EXTERN GType +hb_gobject_buffer_get_type (void); #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) /** @@ -61,7 +63,8 @@ HB_EXTERN GType hb_gobject_buffer_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_face_get_type (void); +HB_EXTERN GType +hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) /** @@ -69,7 +72,8 @@ HB_EXTERN GType hb_gobject_face_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_font_get_type (void); +HB_EXTERN GType +hb_gobject_font_get_type (void); #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) /** @@ -77,13 +81,16 @@ HB_EXTERN GType hb_gobject_font_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_font_funcs_get_type (void); +HB_EXTERN GType +hb_gobject_font_funcs_get_type (void); #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) -HB_EXTERN GType hb_gobject_set_get_type (void); +HB_EXTERN GType +hb_gobject_set_get_type (void); #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ()) -HB_EXTERN GType hb_gobject_shape_plan_get_type (void); +HB_EXTERN GType +hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) /** @@ -91,30 +98,38 @@ HB_EXTERN GType hb_gobject_shape_plan_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void); +HB_EXTERN GType +hb_gobject_unicode_funcs_get_type (void); #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) /* Value types */ -HB_EXTERN GType hb_gobject_feature_get_type (void); +HB_EXTERN GType +hb_gobject_feature_get_type (void); #define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ()) -HB_EXTERN GType hb_gobject_glyph_info_get_type (void); +HB_EXTERN GType +hb_gobject_glyph_info_get_type (void); #define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ()) -HB_EXTERN GType hb_gobject_glyph_position_get_type (void); +HB_EXTERN GType +hb_gobject_glyph_position_get_type (void); #define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ()) -HB_EXTERN GType hb_gobject_segment_properties_get_type (void); +HB_EXTERN GType +hb_gobject_segment_properties_get_type (void); #define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ()) -HB_EXTERN GType hb_gobject_user_data_key_get_type (void); +HB_EXTERN GType +hb_gobject_user_data_key_get_type (void); #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ()) -HB_EXTERN GType hb_gobject_ot_math_glyph_variant_get_type (void); +HB_EXTERN GType +hb_gobject_ot_math_glyph_variant_get_type (void); #define HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT (hb_gobject_ot_math_glyph_variant_get_type ()) -HB_EXTERN GType hb_gobject_ot_math_glyph_part_get_type (void); +HB_EXTERN GType +hb_gobject_ot_math_glyph_part_get_type (void); #define HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART (hb_gobject_ot_math_glyph_part_get_type ()) From d38f37b2e37942a3fd13cd753c8b8587a06c0f3a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 23 Feb 2018 16:55:53 -0500 Subject: [PATCH 27/35] autoconf: provide a harfbuzz-config for use from CMake (#822) --- configure.ac | 2 + src/Makefile.am | 4 +- src/harfbuzz-config.cmake.in | 82 ++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/harfbuzz-config.cmake.in diff --git a/configure.ac b/configure.ac index 8c3ab2029..eee2568dc 100644 --- a/configure.ac +++ b/configure.ac @@ -184,6 +184,7 @@ if $have_gobject; then AC_SUBST(GLIB_MKENUMS) fi AM_CONDITIONAL(HAVE_GOBJECT, $have_gobject) +AC_SUBST(have_gobject) dnl =========================================================================== @@ -491,6 +492,7 @@ AC_CONFIG_FILES([ Makefile src/Makefile src/hb-version.h +src/harfbuzz-config.cmake src/hb-ucdn/Makefile util/Makefile test/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 769a8252b..c4d5fb85b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -156,7 +156,9 @@ pkginclude_HEADERS = $(HBHEADERS) nodist_pkginclude_HEADERS = $(HBNODISTHEADERS) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = harfbuzz.pc -EXTRA_DIST += harfbuzz.pc.in +cmakedir = $(libdir)/cmake/harfbuzz +cmake_DATA = harfbuzz-config.cmake +EXTRA_DIST += harfbuzz.pc.in harfbuzz-config.cmake.in lib_LTLIBRARIES += libharfbuzz-subset.la libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) diff --git a/src/harfbuzz-config.cmake.in b/src/harfbuzz-config.cmake.in new file mode 100644 index 000000000..87b15721a --- /dev/null +++ b/src/harfbuzz-config.cmake.in @@ -0,0 +1,82 @@ +# Set these variables so that the `${prefix}/lib` expands to something we can +# remove. +set(_harfbuzz_remove_string "REMOVE_ME") +set(exec_prefix "${_harfbuzz_remove_string}") +set(prefix "${_harfbuzz_remove_string}") + +# Compute the installation prefix by stripping components from our current +# location. +get_filename_component(_harfbuzz_prefix "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) +get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) +set(_harfbuzz_libdir "@libdir@") +string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}") +set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}") +while (_harfbuzz_libdir_iter) + get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY) + get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) +endwhile () +unset(_harfbuzz_libdir_iter) + +# Get the include subdir. +set(_harfbuzz_includedir "@includedir@") +string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_includedir "${_harfbuzz_includedir}") + +# Extract version information from libtool. +set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@") +string(REPLACE ":" ";" _harfbuzz_version_info "${_harfbuzz_version_info}") +list(GET _harfbuzz_version_info 0 + _harfbuzz_current) +list(GET _harfbuzz_version_info 1 + _harfbuzz_revision) +list(GET _harfbuzz_version_info 2 + _harfbuzz_age) +unset(_harfbuzz_version_info) + +if (APPLE) + set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}") +elseif (UNIX) + set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}") +else () + # Unsupported. + set(harfbuzz_FOUND 0) +endif () + +# Add the libraries. +add_library(harfbuzz::harfbuzz SHARED IMPORTED) +set_target_properties(harfbuzz::harfbuzz PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}") + +add_library(harfbuzz::icu SHARED IMPORTED) +set_target_properties(harfbuzz::icu PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}") + +add_library(harfbuzz::subset SHARED IMPORTED) +set_target_properties(harfbuzz::subset PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}") + +# Only add the gobject library if it was built. +set(_harfbuzz_have_gobject "@have_gobject@") +if (_harfbuzz_have_gobject) + add_library(harfbuzz::gobject SHARED IMPORTED) + set_target_properties(harfbuzz::gobject PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}") +endif () + +# Clean out variables we used in our scope. +unset(_harfbuzz_lib_suffix) +unset(_harfbuzz_current) +unset(_harfbuzz_revision) +unset(_harfbuzz_age) +unset(_harfbuzz_includedir) +unset(_harfbuzz_libdir) +unset(_harfbuzz_prefix) +unset(exec_prefix) +unset(prefix) +unset(_harfbuzz_remove_string) From 5a36b55fba03cd07c9b101f0222b8d189bcd3bbf Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:30:14 -0800 Subject: [PATCH 28/35] [subset] Fix memory leak in subset face destroy. --- src/hb-subset.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index b7d3e3710..aff3aecc6 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -136,6 +136,9 @@ _hb_subset_face_data_destroy (void *user_data) { hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data; + for (int i = 0; i < data->tables.len; i++) + hb_blob_destroy (data->tables[i].blob); + data->tables.finish (); free (data); From 4665aaa19304bdf0362bdfcebcae65feb19a8964 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:36:14 -0800 Subject: [PATCH 29/35] [subset] Fix memory leak in hmtx subsetting. --- src/hb-ot-hmtx-table.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 11cc92794..3cd48a62e 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -105,7 +105,7 @@ struct hmtxvmtx /* alloc the new table */ size_t dest_sz = num_advances * 4 + (gids.len - num_advances) * 2; - void *dest = (void *) calloc (dest_sz, 1); + void *dest = (void *) malloc (dest_sz); if (unlikely (!dest)) { return false; @@ -166,9 +166,11 @@ struct hmtxvmtx hb_blob_t *result = hb_blob_create ((const char *)dest, dest_sz, HB_MEMORY_MODE_READONLY, - /* userdata */ nullptr, + dest, free); - return hb_subset_plan_add_table (plan, T::tableTag, result); + bool success = hb_subset_plan_add_table (plan, T::tableTag, result); + hb_blob_destroy (result); + return success; } struct accelerator_t From 0fb8a5ce192025ffd83ae714db932e4b86594ae1 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:37:43 -0800 Subject: [PATCH 30/35] [subset] Fix memory leak in cmap subsetting. --- src/hb-ot-cmap-table.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 4593152b5..020798986 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -602,7 +602,7 @@ struct cmap + 8 // 1 EncodingRecord + 16 // Format 12 header + 12 * groups.len; // SequentialMapGroup records - void *dest = calloc (dest_sz, 1); + void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; @@ -618,9 +618,11 @@ struct cmap hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, dest_sz, HB_MEMORY_MODE_READONLY, - /* userdata */ nullptr, + dest, free); - return hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + hb_blob_destroy (cmap_prime); + return result; } struct accelerator_t From 66b0a390793ab06692dd49e67baef52a6a7d82aa Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:41:52 -0800 Subject: [PATCH 31/35] [subset] Fix memory leak in hb-subset. --- src/hb-subset.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index aff3aecc6..3a0ddb036 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -263,14 +263,11 @@ _subset_table (hb_subset_plan_t *plan, break; default: hb_blob_t *source_table = hb_face_reference_table(plan->source, tag); - if (likely(source_table)) - { + if (likely (source_table)) result = hb_subset_plan_add_table(plan, tag, source_table); - } else - { result = false; - } + hb_blob_destroy (source_table); break; } DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED"); From e61f360dc828bfd46477b7ddff56874da9f03538 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:44:21 -0800 Subject: [PATCH 32/35] [subset] Fix memory leak in hb-subset-plan. --- src/hb-subset-plan.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index b9e299add..27c2c7f02 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -165,6 +165,7 @@ _populate_gids_to_retain (hb_face_t *face, while (hb_set_next (all_gids_to_retain, &gid)) *(old_gids_sorted.push ()) = gid; + hb_set_destroy (all_gids_to_retain); glyf.fini (); cmap.fini (); } From 99967e21c6e3f6882d6eadf5c22f4120684b1fc5 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 23 Feb 2018 15:45:45 -0800 Subject: [PATCH 33/35] [subset] Fix memory leak in hb-subset-glyf. --- src/hb-subset-glyf.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index d57b41159..d29efe9de 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -234,6 +234,8 @@ hb_subset_glyf_and_loca (hb_subset_plan_t *plan, use_short_loca, glyf_prime, loca_prime); + + hb_blob_destroy (glyf_blob); glyf.fini(); return result; From ec2538c8803be254b6e09ca0ea724b07c35126da Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 15:51:26 -0800 Subject: [PATCH 34/35] [subset] Fix checksum calc out-of-bounds access --- src/hb-open-file-private.hh | 18 ++++++++++-------- src/hb-open-type-private.hh | 3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index 88ce65a40..701935b7f 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -133,32 +133,34 @@ typedef struct OffsetTable unsigned int table_count) { TRACE_SERIALIZE (this); - /* alloc 12 for the OTHeader */ + /* Alloc 12 for the OTHeader. */ if (unlikely (!c->extend_min (*this))) return_trace (false); - /* write sfntVersion (bytes 0..3) */ + /* Write sfntVersion (bytes 0..3) */ sfnt_version.set (sfnt_tag); - /* take space for numTables, searchRange, entrySelector, RangeShift + /* Take space for numTables, searchRange, entrySelector, RangeShift * and the TableRecords themselves */ if (unlikely (!tables.serialize (c, table_count))) return_trace (false); - /* write OffsetTables, alloc for and write actual table blobs */ + /* Write OffsetTables, alloc for and write actual table blobs. */ for (unsigned int i = 0; i < table_count; i++) { TableRecord &rec = tables.array[i]; hb_blob_t *blob = blobs[i]; rec.tag.set (tags[i]); rec.length.set (hb_blob_get_length (blob)); - rec.checkSum.set_for_data (hb_blob_get_data (blob, nullptr), rec.length); rec.offset.serialize (c, this); - // take room for the table + /* Allocate room for the table. */ void *p = c->allocate_size (rec.length); + const char *start = (const char *) p; if (unlikely (!p)) {return false;} - /* copy the actual table */ + /* copy the actual table. */ memcpy (p, hb_blob_get_data (blob, nullptr), rec.length); - /* 4-byte allignment */ + /* 4-byte allignment. */ if (rec.length % 4) p = c->allocate_size (4 - rec.length % 4); + const char *end = (const char *) c->head; + rec.checkSum.set_for_data (start, end - start); } tags += table_count; blobs += table_count; diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 54eda4c52..f5c20bcb6 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -762,7 +762,8 @@ struct CheckSum : HBUINT32 static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length) { uint32_t Sum = 0L; - const HBUINT32 *EndPtr = Table+((Length+3) & ~3) / HBUINT32::static_size; + assert (0 == (Length & 3)); + const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size; while (Table < EndPtr) Sum += *Table++; From dc5c7927e75ea09461e46fe6e56897091b4b4f00 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Feb 2018 16:42:06 -0800 Subject: [PATCH 35/35] [subset] Caclculate head table checksum adjustment Test still fails, because we do not serialize tables in the same order that fonttools subsetter does. --- src/hb-open-file-private.hh | 51 ++++++++++++++++++++++++++++--------- src/hb-ot-head-table.hh | 2 ++ src/hb-subset.cc | 2 ++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index 701935b7f..e2644eaf9 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -30,6 +30,7 @@ #define HB_OPEN_FILE_PRIVATE_HH #include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" namespace OT { @@ -135,13 +136,15 @@ typedef struct OffsetTable TRACE_SERIALIZE (this); /* Alloc 12 for the OTHeader. */ if (unlikely (!c->extend_min (*this))) return_trace (false); - /* Write sfntVersion (bytes 0..3) */ + /* Write sfntVersion (bytes 0..3). */ sfnt_version.set (sfnt_tag); /* Take space for numTables, searchRange, entrySelector, RangeShift - * and the TableRecords themselves - */ + * and the TableRecords themselves. */ if (unlikely (!tables.serialize (c, table_count))) return_trace (false); + const char *dir_end = (const char *) c->head; + HBUINT32 *checksum_adjustment = nullptr; + /* Write OffsetTables, alloc for and write actual table blobs. */ for (unsigned int i = 0; i < table_count; i++) { @@ -150,24 +153,48 @@ typedef struct OffsetTable rec.tag.set (tags[i]); rec.length.set (hb_blob_get_length (blob)); rec.offset.serialize (c, this); - /* Allocate room for the table. */ - void *p = c->allocate_size (rec.length); - const char *start = (const char *) p; - if (unlikely (!p)) {return false;} - /* copy the actual table. */ - memcpy (p, hb_blob_get_data (blob, nullptr), rec.length); + + /* Allocate room for the table and copy it. */ + char *start = (char *) c->allocate_size (rec.length); + if (unlikely (!start)) {return false;} + + memcpy (start, hb_blob_get_data (blob, nullptr), rec.length); + /* 4-byte allignment. */ if (rec.length % 4) - p = c->allocate_size (4 - rec.length % 4); + c->allocate_size (4 - rec.length % 4); const char *end = (const char *) c->head; + + if (tags[i] == HB_OT_TAG_head && end - start >= head::static_size) + { + head *h = (head *) start; + checksum_adjustment = &h->checkSumAdjustment; + checksum_adjustment->set (0); + } + rec.checkSum.set_for_data (start, end - start); } tags += table_count; blobs += table_count; - /* TODO: update head table checkSumAdjustment. */ - tables.qsort (); + + if (checksum_adjustment) + { + CheckSum checksum; + + /* The following line is a slower version of the following block. */ + //checksum.set_for_data (this, (const char *) c->head - (const char *) this); + checksum.set_for_data (this, dir_end - (const char *) this); + for (unsigned int i = 0; i < table_count; i++) + { + TableRecord &rec = tables.array[i]; + checksum.set (checksum + rec.checkSum); + } + + checksum_adjustment->set (0xB1B0AFBAu - checksum); + } + return_trace (true); } diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index 2024cea7e..1d4584045 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -43,6 +43,8 @@ namespace OT { struct head { + friend struct OffsetTable; + static const hb_tag_t tableTag = HB_OT_TAG_head; inline unsigned int get_upem (void) const diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 3a0ddb036..12cdb1d21 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -198,6 +198,8 @@ _hb_subset_face_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data) return nullptr; } +/* TODO: Move this to hb-face.h and rename to hb_face_builder_create() + * with hb_face_builder_add_table(). */ hb_face_t * hb_subset_face_create (void) {