Merge pull request #2900 from harfbuzz/nodiscard-buffer
Mark buffer modification methods that can fail with nodiscard
This commit is contained in:
commit
daeb277346
@ -117,11 +117,7 @@ jobs:
|
||||
- image: ubuntu:20.04
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; DEBIAN_FRONTEND=noninteractive apt install -y wget gnupg
|
||||
#- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
#- run: echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
#- run: echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
#- run: apt update || true
|
||||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y clang lld git binutils meson pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
# asan+ubsan
|
||||
- run: rm -rf build && meson build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
|
||||
@ -132,9 +128,7 @@ jobs:
|
||||
# msan, needs --force-fallback-for=glib,freetype2 also which doesn't work yet but runs fuzzer cases at least
|
||||
- run: rm -rf build && meson build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true
|
||||
- run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
# test -std=c++2a and -Weverything of nightly clang builds
|
||||
- run: clang -c src/harfbuzz.cc src/hb-subset*.cc -DHB_NO_MT -Werror -std=c++2a
|
||||
- run: clang -c src/hb-*.cc -DHB_NO_MT -Werror -Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code -Wno-unused-template -DHB_WITH_WIN1256
|
||||
|
||||
crossbuild-win32:
|
||||
executor: win32-executor
|
||||
|
@ -101,7 +101,7 @@ class ConstraintSet (object):
|
||||
self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&'))
|
||||
s.append ('{}{{\n'.format (indent))
|
||||
for i in range (index):
|
||||
s.append ('{}buffer->next_glyph ();\n'.format (self._indent (depth + 1)))
|
||||
s.append ('{}(void) buffer->next_glyph ();\n'.format (self._indent (depth + 1)))
|
||||
s.append ('{}matched = true;\n'.format (self._indent (depth + 1)))
|
||||
s.append ('{}}}\n'.format (indent))
|
||||
else:
|
||||
@ -171,15 +171,15 @@ print ()
|
||||
print ('static void')
|
||||
print ('_output_dotted_circle (hb_buffer_t *buffer)')
|
||||
print ('{')
|
||||
print (' hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);')
|
||||
print (' _hb_glyph_info_reset_continuation (&dottedcircle);')
|
||||
print (' (void) buffer->output_glyph (0x25CCu);')
|
||||
print (' _hb_glyph_info_reset_continuation (&buffer->prev());')
|
||||
print ('}')
|
||||
print ()
|
||||
print ('static void')
|
||||
print ('_output_with_dotted_circle (hb_buffer_t *buffer)')
|
||||
print ('{')
|
||||
print (' _output_dotted_circle (buffer);')
|
||||
print (' buffer->next_glyph ();')
|
||||
print (' (void) buffer->next_glyph ();')
|
||||
print ('}')
|
||||
print ()
|
||||
|
||||
@ -211,7 +211,7 @@ for script, constraints in sorted (constraints.items (), key=lambda s_c: script_
|
||||
print (' {')
|
||||
print ('\tbool matched = false;')
|
||||
write (str (constraints))
|
||||
print ('\tbuffer->next_glyph ();')
|
||||
print ('\t(void) buffer->next_glyph ();')
|
||||
print ('\tif (matched) _output_with_dotted_circle (buffer);')
|
||||
print (' }')
|
||||
print (' break;')
|
||||
|
@ -831,7 +831,7 @@ struct StateTableDriver
|
||||
break;
|
||||
|
||||
if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
|
||||
if (!c->in_place)
|
||||
|
@ -499,7 +499,7 @@ struct LigatureSubtable
|
||||
}
|
||||
|
||||
DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
|
||||
buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]);
|
||||
if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return;
|
||||
|
||||
if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
|
||||
action = *actionData;
|
||||
@ -525,25 +525,25 @@ struct LigatureSubtable
|
||||
hb_codepoint_t lig = ligatureData;
|
||||
|
||||
DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
|
||||
buffer->replace_glyph (lig);
|
||||
if (unlikely (!buffer->replace_glyph (lig))) return;
|
||||
|
||||
unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u;
|
||||
/* Now go and delete all subsequent components. */
|
||||
while (match_length - 1u > cursor)
|
||||
{
|
||||
DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
|
||||
buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]);
|
||||
buffer->replace_glyph (DELETED_GLYPH);
|
||||
if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return;
|
||||
if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return;
|
||||
}
|
||||
|
||||
buffer->move_to (lig_end);
|
||||
if (unlikely (!buffer->move_to (lig_end))) return;
|
||||
buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len);
|
||||
}
|
||||
|
||||
actionData++;
|
||||
}
|
||||
while (!(action & LigActionLast));
|
||||
buffer->move_to (end);
|
||||
if (unlikely (!buffer->move_to (end))) return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,17 +733,16 @@ struct InsertionSubtable
|
||||
bool before = flags & MarkedInsertBefore;
|
||||
|
||||
unsigned int end = buffer->out_len;
|
||||
buffer->move_to (mark);
|
||||
if (unlikely (!buffer->move_to (mark))) return;
|
||||
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->copy_glyph ();
|
||||
if (unlikely (!buffer->copy_glyph ())) return;
|
||||
/* TODO We ignore KashidaLike setting. */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->output_glyph (glyphs[i]);
|
||||
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->skip_glyph ();
|
||||
|
||||
buffer->move_to (end + count);
|
||||
if (unlikely (!buffer->move_to (end + count))) return;
|
||||
|
||||
buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
|
||||
}
|
||||
@ -764,10 +763,9 @@ struct InsertionSubtable
|
||||
unsigned int end = buffer->out_len;
|
||||
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->copy_glyph ();
|
||||
if (unlikely (!buffer->copy_glyph ())) return;
|
||||
/* TODO We ignore KashidaLike setting. */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->output_glyph (glyphs[i]);
|
||||
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->skip_glyph ();
|
||||
|
||||
@ -786,7 +784,7 @@ struct InsertionSubtable
|
||||
*
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
|
||||
*/
|
||||
buffer->move_to ((flags & DontAdvance) ? end : end + count);
|
||||
if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,7 @@ hb_buffer_t::swap_buffers ()
|
||||
if (unlikely (!successful)) return;
|
||||
|
||||
assert (idx <= len);
|
||||
next_glyphs (len - idx);
|
||||
if (unlikely (!next_glyphs (len - idx))) return;
|
||||
|
||||
assert (have_output);
|
||||
have_output = false;
|
||||
@ -342,31 +342,6 @@ hb_buffer_t::swap_buffers ()
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_buffer_t::replace_glyphs (unsigned int num_in,
|
||||
unsigned int num_out,
|
||||
const uint32_t *glyph_data)
|
||||
{
|
||||
if (unlikely (!make_room_for (num_in, num_out))) return;
|
||||
|
||||
assert (idx + num_in <= len);
|
||||
|
||||
merge_clusters (idx, idx + num_in);
|
||||
|
||||
hb_glyph_info_t orig_info = info[idx];
|
||||
hb_glyph_info_t *pinfo = &out_info[out_len];
|
||||
for (unsigned int i = 0; i < num_out; i++)
|
||||
{
|
||||
*pinfo = orig_info;
|
||||
pinfo->codepoint = glyph_data[i];
|
||||
pinfo++;
|
||||
}
|
||||
|
||||
idx += num_in;
|
||||
out_len += num_out;
|
||||
}
|
||||
|
||||
bool
|
||||
hb_buffer_t::move_to (unsigned int i)
|
||||
{
|
||||
@ -1316,7 +1291,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
|
||||
if (unlikely (hb_object_is_immutable (buffer)))
|
||||
return length == 0;
|
||||
|
||||
if (!buffer->ensure (length))
|
||||
if (unlikely (!buffer->ensure (length)))
|
||||
return false;
|
||||
|
||||
/* Wipe the new space */
|
||||
@ -1546,7 +1521,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
||||
if (item_length == -1)
|
||||
item_length = text_length - item_offset;
|
||||
|
||||
buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
|
||||
if (unlikely (item_length < 0 ||
|
||||
item_length > INT_MAX / 8 ||
|
||||
!buffer->ensure (buffer->len + item_length * sizeof (T) / 4)))
|
||||
return;
|
||||
|
||||
/* If buffer is empty and pre-context provided, install it.
|
||||
* This check is written this way, to make sure people can
|
||||
|
101
src/hb-buffer.hh
101
src/hb-buffer.hh
@ -139,7 +139,7 @@ struct hb_buffer_t
|
||||
|
||||
/* Methods */
|
||||
|
||||
bool in_error () const { return !successful; }
|
||||
HB_NODISCARD bool in_error () const { return !successful; }
|
||||
|
||||
void allocate_var (unsigned int start, unsigned int count)
|
||||
{
|
||||
@ -186,7 +186,7 @@ struct hb_buffer_t
|
||||
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
|
||||
bool has_separate_output () const { return info != out_info; }
|
||||
HB_NODISCARD bool has_separate_output () const { return info != out_info; }
|
||||
|
||||
|
||||
HB_INTERNAL void reset ();
|
||||
@ -210,86 +210,89 @@ struct hb_buffer_t
|
||||
HB_INTERNAL void clear_output ();
|
||||
HB_INTERNAL void clear_positions ();
|
||||
|
||||
HB_INTERNAL void replace_glyphs (unsigned int num_in,
|
||||
unsigned int num_out,
|
||||
const hb_codepoint_t *glyph_data);
|
||||
|
||||
void replace_glyph (hb_codepoint_t glyph_index)
|
||||
template <typename T>
|
||||
HB_NODISCARD bool replace_glyphs (unsigned int num_in,
|
||||
unsigned int num_out,
|
||||
const T *glyph_data)
|
||||
{
|
||||
if (unlikely (out_info != info || out_len != idx)) {
|
||||
if (unlikely (!make_room_for (1, 1))) return;
|
||||
out_info[out_len] = info[idx];
|
||||
if (unlikely (!make_room_for (num_in, num_out))) return false;
|
||||
|
||||
assert (idx + num_in <= len);
|
||||
|
||||
merge_clusters (idx, idx + num_in);
|
||||
|
||||
hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
|
||||
|
||||
hb_glyph_info_t *pinfo = &out_info[out_len];
|
||||
for (unsigned int i = 0; i < num_out; i++)
|
||||
{
|
||||
*pinfo = orig_info;
|
||||
pinfo->codepoint = glyph_data[i];
|
||||
pinfo++;
|
||||
}
|
||||
out_info[out_len].codepoint = glyph_index;
|
||||
|
||||
idx++;
|
||||
out_len++;
|
||||
idx += num_in;
|
||||
out_len += num_out;
|
||||
return true;
|
||||
}
|
||||
|
||||
HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index)
|
||||
{ return replace_glyphs (1, 1, &glyph_index); }
|
||||
|
||||
/* Makes a copy of the glyph at idx to output and replace glyph_index */
|
||||
hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
|
||||
HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index)
|
||||
{ return replace_glyphs (0, 1, &glyph_index); }
|
||||
|
||||
HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info)
|
||||
{
|
||||
if (unlikely (!make_room_for (0, 1))) return Crap (hb_glyph_info_t);
|
||||
|
||||
if (unlikely (idx == len && !out_len))
|
||||
return Crap (hb_glyph_info_t);
|
||||
|
||||
out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
|
||||
out_info[out_len].codepoint = glyph_index;
|
||||
|
||||
out_len++;
|
||||
|
||||
return out_info[out_len - 1];
|
||||
}
|
||||
void output_info (const hb_glyph_info_t &glyph_info)
|
||||
{
|
||||
if (unlikely (!make_room_for (0, 1))) return;
|
||||
if (unlikely (!make_room_for (0, 1))) return false;
|
||||
|
||||
out_info[out_len] = glyph_info;
|
||||
|
||||
out_len++;
|
||||
return true;
|
||||
}
|
||||
/* Copies glyph at idx to output but doesn't advance idx */
|
||||
void copy_glyph ()
|
||||
HB_NODISCARD bool copy_glyph ()
|
||||
{
|
||||
if (unlikely (!make_room_for (0, 1))) return;
|
||||
|
||||
out_info[out_len] = info[idx];
|
||||
|
||||
out_len++;
|
||||
/* Extra copy because cur()'s return can be freed within
|
||||
* output_info() call if buffer reallocates. */
|
||||
return output_info (hb_glyph_info_t (cur()));
|
||||
}
|
||||
|
||||
/* Copies glyph at idx to output and advance idx.
|
||||
* If there's no output, just advance idx. */
|
||||
void
|
||||
next_glyph ()
|
||||
HB_NODISCARD bool next_glyph ()
|
||||
{
|
||||
if (have_output)
|
||||
{
|
||||
if (out_info != info || out_len != idx)
|
||||
{
|
||||
if (unlikely (!make_room_for (1, 1))) return;
|
||||
if (unlikely (!make_room_for (1, 1))) return false;
|
||||
out_info[out_len] = info[idx];
|
||||
}
|
||||
out_len++;
|
||||
}
|
||||
|
||||
idx++;
|
||||
return true;
|
||||
}
|
||||
/* Copies n glyphs at idx to output and advance idx.
|
||||
* If there's no output, just advance idx. */
|
||||
void
|
||||
next_glyphs (unsigned int n)
|
||||
HB_NODISCARD bool next_glyphs (unsigned int n)
|
||||
{
|
||||
if (have_output)
|
||||
{
|
||||
if (out_info != info || out_len != idx)
|
||||
{
|
||||
if (unlikely (!make_room_for (n, n))) return;
|
||||
if (unlikely (!make_room_for (n, n))) return false;
|
||||
memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
|
||||
}
|
||||
out_len += n;
|
||||
}
|
||||
|
||||
idx += n;
|
||||
return true;
|
||||
}
|
||||
/* Advance idx without copying to output. */
|
||||
void skip_glyph () { idx++; }
|
||||
@ -329,14 +332,14 @@ struct hb_buffer_t
|
||||
|
||||
|
||||
/* Internal methods */
|
||||
HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
|
||||
HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
|
||||
|
||||
HB_INTERNAL bool enlarge (unsigned int size);
|
||||
HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
|
||||
|
||||
bool ensure (unsigned int size)
|
||||
HB_NODISCARD bool ensure (unsigned int size)
|
||||
{ return likely (!size || size < allocated) ? true : enlarge (size); }
|
||||
|
||||
bool ensure_inplace (unsigned int size)
|
||||
HB_NODISCARD bool ensure_inplace (unsigned int size)
|
||||
{ return likely (!size || size < allocated); }
|
||||
|
||||
void assert_glyphs ()
|
||||
@ -349,7 +352,7 @@ struct hb_buffer_t
|
||||
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
|
||||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
|
||||
}
|
||||
bool ensure_glyphs ()
|
||||
HB_NODISCARD bool ensure_glyphs ()
|
||||
{
|
||||
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
|
||||
{
|
||||
@ -360,7 +363,7 @@ struct hb_buffer_t
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool ensure_unicode ()
|
||||
HB_NODISCARD bool ensure_unicode ()
|
||||
{
|
||||
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
|
||||
{
|
||||
@ -372,8 +375,8 @@ struct hb_buffer_t
|
||||
return true;
|
||||
}
|
||||
|
||||
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
|
||||
HB_INTERNAL bool shift_forward (unsigned int count);
|
||||
HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
|
||||
HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count);
|
||||
|
||||
typedef long scratch_buffer_t;
|
||||
HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
|
||||
|
@ -289,7 +289,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
return true;
|
||||
}
|
||||
|
||||
buffer->ensure (glyph_count);
|
||||
(void) buffer->ensure (glyph_count);
|
||||
scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
|
||||
DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)
|
||||
|
@ -659,7 +659,7 @@ struct hb_ot_apply_context_t :
|
||||
void replace_glyph (hb_codepoint_t glyph_index) const
|
||||
{
|
||||
_set_glyph_props (glyph_index);
|
||||
buffer->replace_glyph (glyph_index);
|
||||
(void) buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
void replace_glyph_inplace (hb_codepoint_t glyph_index) const
|
||||
{
|
||||
@ -670,13 +670,13 @@ struct hb_ot_apply_context_t :
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_set_glyph_props (glyph_index, class_guess, true);
|
||||
buffer->replace_glyph (glyph_index);
|
||||
(void) buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
void output_glyph_for_component (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_set_glyph_props (glyph_index, class_guess, false, true);
|
||||
buffer->output_glyph (glyph_index);
|
||||
(void) buffer->output_glyph (glyph_index);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1043,7 +1043,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
|
||||
hb_min (this_comp, last_num_components);
|
||||
_hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
|
||||
last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
|
||||
@ -1272,7 +1272,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||
match_positions[next] += delta;
|
||||
}
|
||||
|
||||
buffer->move_to (end);
|
||||
(void) buffer->move_to (end);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
@ -1782,7 +1782,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
|
||||
if (applied)
|
||||
ret = true;
|
||||
else
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
{
|
||||
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
|
||||
buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
|
||||
buffer->next_glyph ();
|
||||
if (unlikely (!buffer->next_glyph ())) break;
|
||||
if (!is_zero_width_char (font, u))
|
||||
{
|
||||
buffer->merge_out_clusters (start, end + 1);
|
||||
@ -231,12 +231,12 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
chars[0] = 0x25CCu;
|
||||
chars[1] = u;
|
||||
}
|
||||
buffer->replace_glyphs (1, 2, chars);
|
||||
(void) buffer->replace_glyphs (1, 2, chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No dotted circle available in the font; just leave tone mark untouched. */
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
start = end = buffer->out_len;
|
||||
@ -273,7 +273,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
|
||||
if (font->has_glyph (s))
|
||||
{
|
||||
buffer->replace_glyphs (t ? 3 : 2, 1, &s);
|
||||
(void) buffer->replace_glyphs (t ? 3 : 2, 1, &s);
|
||||
end = start + 1;
|
||||
continue;
|
||||
}
|
||||
@ -285,13 +285,13 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
* Set jamo features on the individual glyphs, and advance past them.
|
||||
*/
|
||||
buffer->cur().hangul_shaping_feature() = LJMO;
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
buffer->cur().hangul_shaping_feature() = VJMO;
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (t)
|
||||
{
|
||||
buffer->cur().hangul_shaping_feature() = TJMO;
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
end = start + 3;
|
||||
}
|
||||
else
|
||||
@ -323,9 +323,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_codepoint_t new_s = s + new_tindex;
|
||||
if (font->has_glyph (new_s))
|
||||
{
|
||||
buffer->replace_glyphs (2, 1, &new_s);
|
||||
if (unlikely (!buffer->successful))
|
||||
break;
|
||||
(void) buffer->replace_glyphs (2, 1, &new_s);
|
||||
end = start + 1;
|
||||
continue;
|
||||
}
|
||||
@ -349,14 +347,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
(!tindex || font->has_glyph (decomposed[2])))
|
||||
{
|
||||
unsigned int s_len = tindex ? 3 : 2;
|
||||
buffer->replace_glyphs (1, s_len, decomposed);
|
||||
(void) buffer->replace_glyphs (1, s_len, decomposed);
|
||||
|
||||
/* If we decomposed an LV because of a non-combining T following,
|
||||
* we want to include this T in the syllable.
|
||||
*/
|
||||
if (has_glyph && !tindex)
|
||||
{
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
s_len++;
|
||||
}
|
||||
if (unlikely (!buffer->successful))
|
||||
@ -384,17 +382,15 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
|
||||
if (has_glyph)
|
||||
{
|
||||
/* We didn't decompose the S, so just advance past it. */
|
||||
/* We didn't decompose the S, so just advance past it and fall through. */
|
||||
end = start + 1;
|
||||
buffer->next_glyph ();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Didn't find a recognizable syllable, so we leave end <= start;
|
||||
* this will prevent tone-mark reordering happening.
|
||||
*/
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
@ -85,13 +85,13 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
|
||||
while (buffer->idx < buffer->len && buffer->successful &&
|
||||
last_syllable == buffer->cur().syllable() &&
|
||||
buffer->cur().complex_var_u8_category() == (unsigned) repha_category)
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
|
||||
buffer->output_info (ginfo);
|
||||
(void) buffer->output_info (ginfo);
|
||||
}
|
||||
else
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
@ -323,20 +323,19 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
|
||||
|
||||
buffer->clear_output ();
|
||||
unsigned int count = buffer->len;
|
||||
for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
|
||||
for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;)
|
||||
{
|
||||
hb_codepoint_t u = buffer->cur().codepoint;
|
||||
if (likely (!IS_SARA_AM (u))) {
|
||||
buffer->next_glyph ();
|
||||
if (likely (!IS_SARA_AM (u)))
|
||||
{
|
||||
if (unlikely (!buffer->next_glyph ())) break;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is SARA AM. Decompose and reorder. */
|
||||
hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
|
||||
_hb_glyph_info_set_continuation (&nikhahit);
|
||||
buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u));
|
||||
if (unlikely (!buffer->successful))
|
||||
return;
|
||||
(void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
|
||||
_hb_glyph_info_set_continuation (&buffer->prev());
|
||||
if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break;
|
||||
|
||||
/* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
|
||||
unsigned int end = buffer->out_len;
|
||||
|
@ -23,15 +23,15 @@
|
||||
static void
|
||||
_output_dotted_circle (hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
|
||||
_hb_glyph_info_reset_continuation (&dottedcircle);
|
||||
(void) buffer->output_glyph (0x25CCu);
|
||||
_hb_glyph_info_reset_continuation (&buffer->prev());
|
||||
}
|
||||
|
||||
static void
|
||||
_output_with_dotted_circle (hb_buffer_t *buffer)
|
||||
{
|
||||
_output_dotted_circle (buffer);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -96,12 +96,12 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
buffer->idx + 2 < count &&
|
||||
0x0907u == buffer->cur (2).codepoint)
|
||||
{
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -122,7 +122,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x09E2u == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -158,7 +158,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -182,7 +182,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x0ABEu == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -200,7 +200,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x0B57u == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -214,7 +214,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
{
|
||||
matched = true;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -237,7 +237,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x0C55u == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -255,7 +255,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x0CCCu == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -281,7 +281,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -316,7 +316,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -337,7 +337,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x11042u == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -358,7 +358,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -384,7 +384,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -404,7 +404,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
@ -427,7 +427,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
matched = 0x116B2u == buffer->cur (1).codepoint;
|
||||
break;
|
||||
}
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
if (matched) _output_with_dotted_circle (buffer);
|
||||
}
|
||||
break;
|
||||
|
@ -101,8 +101,9 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font)
|
||||
static inline void
|
||||
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
|
||||
{
|
||||
/* This is very confusing indeed. */
|
||||
buffer->cur().glyph_index() = glyph;
|
||||
buffer->output_glyph (unichar); /* This is very confusing indeed. */
|
||||
(void) buffer->output_glyph (unichar);
|
||||
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
|
||||
}
|
||||
|
||||
@ -110,7 +111,7 @@ static inline void
|
||||
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
|
||||
{
|
||||
buffer->cur().glyph_index() = glyph;
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -229,30 +230,35 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
|
||||
if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
|
||||
{
|
||||
hb_codepoint_t unicode = buffer->cur().codepoint;
|
||||
buffer->replace_glyphs (2, 1, &unicode);
|
||||
(void) buffer->replace_glyphs (2, 1, &unicode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just pass on the two characters separately, let GSUB do its magic. */
|
||||
set_glyph (buffer->cur(), font);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
set_glyph (buffer->cur(), font);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
/* Skip any further variation selectors. */
|
||||
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
|
||||
while (buffer->idx < end &&
|
||||
buffer->successful &&
|
||||
unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
|
||||
{
|
||||
set_glyph (buffer->cur(), font);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
set_glyph (buffer->cur(), font);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
if (likely (buffer->idx < end)) {
|
||||
if (likely (buffer->idx < end))
|
||||
{
|
||||
set_glyph (buffer->cur(), font);
|
||||
buffer->next_glyph ();
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +354,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
sizeof (buffer->info[0]),
|
||||
&buffer->cur().glyph_index(),
|
||||
sizeof (buffer->info[0]));
|
||||
buffer->next_glyphs (done);
|
||||
if (unlikely (!buffer->next_glyphs (done))) break;
|
||||
}
|
||||
while (buffer->idx < end && buffer->successful)
|
||||
decompose_current_character (&c, might_short_circuit);
|
||||
@ -429,8 +435,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
buffer->clear_output ();
|
||||
count = buffer->len;
|
||||
unsigned int starter = 0;
|
||||
buffer->next_glyph ();
|
||||
while (buffer->idx < count && buffer->successful)
|
||||
(void) buffer->next_glyph ();
|
||||
while (buffer->idx < count /* No need for: && buffer->successful */)
|
||||
{
|
||||
hb_codepoint_t composed, glyph;
|
||||
if (/* We don't try to compose a non-mark character with it's preceding starter.
|
||||
@ -452,9 +458,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
font->get_nominal_glyph (composed, &glyph))
|
||||
{
|
||||
/* Composes. */
|
||||
buffer->next_glyph (); /* Copy to out-buffer. */
|
||||
if (unlikely (!buffer->successful))
|
||||
return;
|
||||
if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */
|
||||
buffer->merge_out_clusters (starter, buffer->out_len);
|
||||
buffer->out_len--; /* Remove the second composable. */
|
||||
/* Modify starter and carry on. */
|
||||
@ -467,7 +471,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
}
|
||||
|
||||
/* Blocked, or doesn't compose. */
|
||||
buffer->next_glyph ();
|
||||
if (unlikely (!buffer->next_glyph ())) break;
|
||||
|
||||
if (info_cc (buffer->prev()) == 0)
|
||||
starter = buffer->out_len - 1;
|
||||
|
@ -534,7 +534,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
||||
hb_glyph_info_t info = dottedcircle;
|
||||
info.cluster = buffer->cur().cluster;
|
||||
info.mask = buffer->cur().mask;
|
||||
buffer->output_info (info);
|
||||
(void) buffer->output_info (info);
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ for filename in args:
|
||||
|
||||
if not reference:
|
||||
print ('%s "%s" %s %s --unicodes %s' %
|
||||
(hb_shape, fontfile, ' '.join(extra_options), options, unicodes))
|
||||
(hb_shape, fontfile, ' '.join(extra_options), ' '.join(options), unicodes))
|
||||
|
||||
if "--font-funcs=ft" in options and not have_freetype:
|
||||
skips += 1
|
||||
|
Loading…
Reference in New Issue
Block a user