--- old/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-cff-common.cc 2020-07-21 14:26:17.050861073 -0700 +++ /dev/null 2020-01-23 11:31:37.155195123 -0800 @@ -1,226 +0,0 @@ -/* - * Copyright © 2018 Adobe 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. - * - * Adobe Author(s): Michiharu Ariza - */ - -#include "hb-ot-cff-common.hh" -#include "hb-ot-cff2-table.hh" -#include "hb-subset-cff-common.hh" - -/* Disable FDSelect format 0 for compatibility with fonttools which doesn't seem choose it. - * Rarely any/much smaller than format 3 anyway. */ -#define CFF_SERIALIZE_FDSELECT_0 0 - -using namespace CFF; - -/** - * hb_plan_subset_cff_fdselect - * Determine an optimal FDSelect format according to a provided plan. - * - * Return value: FDSelect format, size, and ranges for the most compact subset FDSelect - * along with a font index remapping table - **/ - -bool -hb_plan_subset_cff_fdselect (const hb_vector_t &glyphs, - unsigned int fdCount, - const FDSelect &src, /* IN */ - unsigned int &subset_fd_count /* OUT */, - unsigned int &subset_fdselect_size /* OUT */, - unsigned int &subset_fdselect_format /* OUT */, - hb_vector_t &fdselect_ranges /* OUT */, - remap_t &fdmap /* OUT */) -{ - subset_fd_count = 0; - subset_fdselect_size = 0; - subset_fdselect_format = 0; - unsigned int num_ranges = 0; - - unsigned int subset_num_glyphs = glyphs.length; - if (subset_num_glyphs == 0) - return true; - - { - /* use hb_set to determine the subset of font dicts */ - hb_set_t *set = hb_set_create (); - if (set == &Null (hb_set_t)) - return false; - hb_codepoint_t prev_fd = CFF_UNDEF_CODE; - for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++) - { - hb_codepoint_t fd = src.get_fd (glyphs[i]); - set->add (fd); - - if (fd != prev_fd) - { - num_ranges++; - prev_fd = fd; - code_pair_t pair = { fd, i }; - fdselect_ranges.push (pair); - } - } - - subset_fd_count = set->get_population (); - if (subset_fd_count == fdCount) - { - /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */ - fdmap.identity (fdCount); - hb_set_destroy (set); - } - else - { - /* create a fdmap */ - if (!fdmap.reset (fdCount)) - { - hb_set_destroy (set); - return false; - } - - hb_codepoint_t fd = CFF_UNDEF_CODE; - while (set->next (&fd)) - fdmap.add (fd); - hb_set_destroy (set); - if (unlikely (fdmap.get_count () != subset_fd_count)) - return false; - } - - /* update each font dict index stored as "code" in fdselect_ranges */ - for (unsigned int i = 0; i < fdselect_ranges.length; i++) - fdselect_ranges[i].code = fdmap[fdselect_ranges[i].code]; - } - - /* determine which FDSelect format is most compact */ - if (subset_fd_count > 0xFF) - { - if (unlikely (src.format != 4)) - return false; - subset_fdselect_format = 4; - subset_fdselect_size = FDSelect::min_size + FDSelect4::min_size + FDSelect4_Range::static_size * num_ranges + HBUINT32::static_size; - } - else - { -#if CFF_SERIALIZE_FDSELECT_0 - unsigned int format0_size = FDSelect::min_size + FDSelect0::min_size + HBUINT8::static_size * subset_num_glyphs; -#endif - unsigned int format3_size = FDSelect::min_size + FDSelect3::min_size + FDSelect3_Range::static_size * num_ranges + HBUINT16::static_size; - -#if CFF_SERIALIZE_FDSELECT_0 - if (format0_size <= format3_size) - { - // subset_fdselect_format = 0; - subset_fdselect_size = format0_size; - } - else -#endif - { - subset_fdselect_format = 3; - subset_fdselect_size = format3_size; - } - } - - return true; -} - -template -static inline bool -serialize_fdselect_3_4 (hb_serialize_context_t *c, - const unsigned int num_glyphs, - const FDSelect &src, - unsigned int size, - const hb_vector_t &fdselect_ranges) -{ - TRACE_SERIALIZE (this); - FDSELECT3_4 *p = c->allocate_size (size); - if (unlikely (p == nullptr)) return_trace (false); - p->nRanges ().set (fdselect_ranges.length); - for (unsigned int i = 0; i < fdselect_ranges.length; i++) - { - p->ranges[i].first.set (fdselect_ranges[i].glyph); - p->ranges[i].fd.set (fdselect_ranges[i].code); - } - p->sentinel().set (num_glyphs); - return_trace (true); -} - -/** - * hb_serialize_cff_fdselect - * Serialize a subset FDSelect format planned above. - **/ -bool -hb_serialize_cff_fdselect (hb_serialize_context_t *c, - const unsigned int num_glyphs, - const FDSelect &src, - unsigned int fd_count, - unsigned int fdselect_format, - unsigned int size, - const hb_vector_t &fdselect_ranges) -{ - TRACE_SERIALIZE (this); - FDSelect *p = c->allocate_min (); - if (unlikely (p == nullptr)) return_trace (false); - p->format.set (fdselect_format); - size -= FDSelect::min_size; - - switch (fdselect_format) - { -#if CFF_SERIALIZE_FDSELECT_0 - case 0: - { - FDSelect0 *p = c->allocate_size (size); - if (unlikely (p == nullptr)) return_trace (false); - unsigned int range_index = 0; - unsigned int fd = fdselect_ranges[range_index++].code; - for (unsigned int i = 0; i < num_glyphs; i++) - { - if ((range_index < fdselect_ranges.len) && - (i >= fdselect_ranges[range_index].glyph)) - { - fd = fdselect_ranges[range_index++].code; - } - p->fds[i].set (fd); - } - break; - } -#endif /* CFF_SERIALIZE_FDSELECT_0 */ - - case 3: - return serialize_fdselect_3_4 (c, - num_glyphs, - src, - size, - fdselect_ranges); - - case 4: - return serialize_fdselect_3_4 (c, - num_glyphs, - src, - size, - fdselect_ranges); - - default: - assert(false); - } - - return_trace (true); -} --- /dev/null 2020-01-23 11:31:37.155195123 -0800 +++ new/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc 2020-07-21 14:26:16.790861078 -0700 @@ -0,0 +1,226 @@ +/* + * Copyright © 2018 Adobe 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. + * + * Adobe Author(s): Michiharu Ariza + */ + +#include "hb-ot-cff-common.hh" +#include "hb-ot-cff2-table.hh" +#include "hb-subset-cff-common.hh" + +/* Disable FDSelect format 0 for compatibility with fonttools which doesn't seem choose it. + * Rarely any/much smaller than format 3 anyway. */ +#define CFF_SERIALIZE_FDSELECT_0 0 + +using namespace CFF; + +/** + * hb_plan_subset_cff_fdselect + * Determine an optimal FDSelect format according to a provided plan. + * + * Return value: FDSelect format, size, and ranges for the most compact subset FDSelect + * along with a font index remapping table + **/ + +bool +hb_plan_subset_cff_fdselect (const hb_vector_t &glyphs, + unsigned int fdCount, + const FDSelect &src, /* IN */ + unsigned int &subset_fd_count /* OUT */, + unsigned int &subset_fdselect_size /* OUT */, + unsigned int &subset_fdselect_format /* OUT */, + hb_vector_t &fdselect_ranges /* OUT */, + remap_t &fdmap /* OUT */) +{ + subset_fd_count = 0; + subset_fdselect_size = 0; + subset_fdselect_format = 0; + unsigned int num_ranges = 0; + + unsigned int subset_num_glyphs = glyphs.length; + if (subset_num_glyphs == 0) + return true; + + { + /* use hb_set to determine the subset of font dicts */ + hb_set_t *set = hb_set_create (); + if (set == &Null (hb_set_t)) + return false; + hb_codepoint_t prev_fd = CFF_UNDEF_CODE; + for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++) + { + hb_codepoint_t fd = src.get_fd (glyphs[i]); + set->add (fd); + + if (fd != prev_fd) + { + num_ranges++; + prev_fd = fd; + code_pair_t pair = { fd, i }; + fdselect_ranges.push (pair); + } + } + + subset_fd_count = set->get_population (); + if (subset_fd_count == fdCount) + { + /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */ + fdmap.identity (fdCount); + hb_set_destroy (set); + } + else + { + /* create a fdmap */ + if (!fdmap.reset (fdCount)) + { + hb_set_destroy (set); + return false; + } + + hb_codepoint_t fd = CFF_UNDEF_CODE; + while (set->next (&fd)) + fdmap.add (fd); + hb_set_destroy (set); + if (unlikely (fdmap.get_count () != subset_fd_count)) + return false; + } + + /* update each font dict index stored as "code" in fdselect_ranges */ + for (unsigned int i = 0; i < fdselect_ranges.length; i++) + fdselect_ranges[i].code = fdmap[fdselect_ranges[i].code]; + } + + /* determine which FDSelect format is most compact */ + if (subset_fd_count > 0xFF) + { + if (unlikely (src.format != 4)) + return false; + subset_fdselect_format = 4; + subset_fdselect_size = FDSelect::min_size + FDSelect4::min_size + FDSelect4_Range::static_size * num_ranges + HBUINT32::static_size; + } + else + { +#if CFF_SERIALIZE_FDSELECT_0 + unsigned int format0_size = FDSelect::min_size + FDSelect0::min_size + HBUINT8::static_size * subset_num_glyphs; +#endif + unsigned int format3_size = FDSelect::min_size + FDSelect3::min_size + FDSelect3_Range::static_size * num_ranges + HBUINT16::static_size; + +#if CFF_SERIALIZE_FDSELECT_0 + if (format0_size <= format3_size) + { + // subset_fdselect_format = 0; + subset_fdselect_size = format0_size; + } + else +#endif + { + subset_fdselect_format = 3; + subset_fdselect_size = format3_size; + } + } + + return true; +} + +template +static inline bool +serialize_fdselect_3_4 (hb_serialize_context_t *c, + const unsigned int num_glyphs, + const FDSelect &src, + unsigned int size, + const hb_vector_t &fdselect_ranges) +{ + TRACE_SERIALIZE (this); + FDSELECT3_4 *p = c->allocate_size (size); + if (unlikely (p == nullptr)) return_trace (false); + p->nRanges ().set (fdselect_ranges.length); + for (unsigned int i = 0; i < fdselect_ranges.length; i++) + { + p->ranges[i].first.set (fdselect_ranges[i].glyph); + p->ranges[i].fd.set (fdselect_ranges[i].code); + } + p->sentinel().set (num_glyphs); + return_trace (true); +} + +/** + * hb_serialize_cff_fdselect + * Serialize a subset FDSelect format planned above. + **/ +bool +hb_serialize_cff_fdselect (hb_serialize_context_t *c, + const unsigned int num_glyphs, + const FDSelect &src, + unsigned int fd_count, + unsigned int fdselect_format, + unsigned int size, + const hb_vector_t &fdselect_ranges) +{ + TRACE_SERIALIZE (this); + FDSelect *p = c->allocate_min (); + if (unlikely (p == nullptr)) return_trace (false); + p->format.set (fdselect_format); + size -= FDSelect::min_size; + + switch (fdselect_format) + { +#if CFF_SERIALIZE_FDSELECT_0 + case 0: + { + FDSelect0 *p = c->allocate_size (size); + if (unlikely (p == nullptr)) return_trace (false); + unsigned int range_index = 0; + unsigned int fd = fdselect_ranges[range_index++].code; + for (unsigned int i = 0; i < num_glyphs; i++) + { + if ((range_index < fdselect_ranges.len) && + (i >= fdselect_ranges[range_index].glyph)) + { + fd = fdselect_ranges[range_index++].code; + } + p->fds[i].set (fd); + } + break; + } +#endif /* CFF_SERIALIZE_FDSELECT_0 */ + + case 3: + return serialize_fdselect_3_4 (c, + num_glyphs, + src, + size, + fdselect_ranges); + + case 4: + return serialize_fdselect_3_4 (c, + num_glyphs, + src, + size, + fdselect_ranges); + + default: + assert(false); + } + + return_trace (true); +}