提交 85646fda 编写于 作者: G Garret Rieger

[subset] Limit the iterations of the closure algorithm.

Prevents O(n^2) run times.
上级 94759d4c
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
#ifndef HB_MAX_CONTEXT_LENGTH #ifndef HB_MAX_CONTEXT_LENGTH
#define HB_MAX_CONTEXT_LENGTH 64 #define HB_MAX_CONTEXT_LENGTH 64
#endif #endif
#ifndef HB_CLOSURE_MAX_STAGES
/*
* The maximum number of times a lookup can be applied during shaping.
* Used to limit the number of iterations of the closure algorithm.
*/
#define HB_CLOSURE_MAX_STAGES 8
#endif
namespace OT { namespace OT {
......
...@@ -971,6 +971,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, ...@@ -971,6 +971,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
OT::hb_closure_context_t c (face, glyphs, &done_lookups); OT::hb_closure_context_t c (face, glyphs, &done_lookups);
const OT::GSUB& gsub = _get_gsub (face); const OT::GSUB& gsub = _get_gsub (face);
unsigned int iteration_count = 0;
unsigned int glyphs_length; unsigned int glyphs_length;
do do
{ {
...@@ -985,7 +986,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, ...@@ -985,7 +986,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
gsub.get_lookup (i).closure (&c, i); gsub.get_lookup (i).closure (&c, i);
} }
} while (glyphs_length != glyphs->get_population ()); iteration_count++;
} while (iteration_count <= HB_CLOSURE_MAX_STAGES
&& glyphs_length != glyphs->get_population ());
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册