diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-11-16 12:13:51 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-11-16 12:25:52 +0000 |
commit | 0c3e1ee387c995f37aa53f358825f334c06324ec (patch) | |
tree | 6b42f4ea01f1376e24716da82f2d91f1d0ace89e /source | |
parent | 141870506d8809723e933963e9e001aca839cdfc (diff) | |
download | mupdf-0c3e1ee387c995f37aa53f358825f334c06324ec.tar.xz |
Bug 697301: Fix "crash" in epub.
Actually an assert. This is caused by a paragraph separator in the
text. The Unicode Bidirectional Algorithm says we should operate
paragraph by paragraph, and includes code to split paragraphs
at paragraph markers, changing their type to boundary neutrals
as it goes.
The use of this code was left "as an exercise for the reader" in
the example code, so we simply hook it up here.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/bidi-imp.h | 1 | ||||
-rw-r--r-- | source/fitz/bidi-std.c | 4 | ||||
-rw-r--r-- | source/fitz/bidi.c | 40 |
3 files changed, 32 insertions, 13 deletions
diff --git a/source/fitz/bidi-imp.h b/source/fitz/bidi-imp.h index cb0f8871..6c3aab77 100644 --- a/source/fitz/bidi-imp.h +++ b/source/fitz/bidi-imp.h @@ -75,3 +75,4 @@ void fz_bidi_resolve_implicit(const fz_bidi_chartype *pcls, fz_bidi_level *pleve void fz_bidi_resolve_weak(fz_context *ctx, fz_bidi_level baselevel, fz_bidi_chartype *pcls, fz_bidi_level *plevel, size_t cch); void fz_bidi_resolve_whitespace(fz_bidi_level baselevel, const fz_bidi_chartype *pcls, fz_bidi_level *plevel, size_t cch); size_t fz_bidi_resolve_explicit(fz_bidi_level level, fz_bidi_chartype dir, fz_bidi_chartype *pcls, fz_bidi_level *plevel, size_t cch, fz_bidi_level nNest); +int fz_bidi_resolve_paragraphs(fz_bidi_chartype *types, int cch); diff --git a/source/fitz/bidi-std.c b/source/fitz/bidi-std.c index 792db71b..f5ebcf56 100644 --- a/source/fitz/bidi-std.c +++ b/source/fitz/bidi-std.c @@ -367,8 +367,7 @@ void set_deferred_level_run(fz_bidi_level *pval, size_t cval, size_t iStart, fz_ or at the end of the input text. ------------------------------------------------------------------------*/ -#if 0 -static int resolve_paragraphs(fz_bidi_chartype *types, int cch) +int fz_bidi_resolve_paragraphs(fz_bidi_chartype *types, int cch) { int ich; @@ -381,6 +380,7 @@ static int resolve_paragraphs(fz_bidi_chartype *types, int cch) return ich; } +#if 0 /*------------------------------------------------------------------------ Function: base_level diff --git a/source/fitz/bidi.c b/source/fitz/bidi.c index 4436b615..b31ca749 100644 --- a/source/fitz/bidi.c +++ b/source/fitz/bidi.c @@ -414,9 +414,12 @@ create_levels(fz_context *ctx, int resolveWhiteSpace, int flags) { - fz_bidi_level *levels; + fz_bidi_level *levels , *plevels; fz_bidi_chartype *types = NULL; + fz_bidi_chartype *ptypes; fz_bidi_level baseLevel; + const uint32_t *ptext; + size_t plen, remaining; levels = fz_malloc(ctx, len * sizeof(*levels)); @@ -463,18 +466,33 @@ create_levels(fz_context *ctx, */ classify_quoted_blocks(text, types, len); - /* Work out the levels and character types... */ - (void)fz_bidi_resolve_explicit(baseLevel, BDI_N, types, levels, len, 0); - fz_bidi_resolve_weak(ctx, baseLevel, types, levels, len); - fz_bidi_resolve_neutrals(baseLevel,types, levels, len); - fz_bidi_resolve_implicit(types, levels, len); + /* Work one paragraph at a time. */ + plevels = levels; + ptypes = types; + ptext = text; + remaining = len; + while (remaining) + { + plen = fz_bidi_resolve_paragraphs(ptypes, remaining); + + /* Work out the levels and character types... */ + (void)fz_bidi_resolve_explicit(baseLevel, BDI_N, ptypes, plevels, plen, 0); + fz_bidi_resolve_weak(ctx, baseLevel, ptypes, plevels, plen); + fz_bidi_resolve_neutrals(baseLevel, ptypes, plevels, plen); + fz_bidi_resolve_implicit(ptypes, plevels, plen); - classify_characters(text, types, len, BIDI_CLASSIFY_WHITE_SPACE); + classify_characters(ptext, ptypes, plen, BIDI_CLASSIFY_WHITE_SPACE); - if (resolveWhiteSpace) - { - /* resolve whitespace */ - fz_bidi_resolve_whitespace(baseLevel, types, levels, len); + if (resolveWhiteSpace) + { + /* resolve whitespace */ + fz_bidi_resolve_whitespace(baseLevel, ptypes, plevels, plen); + } + + plevels += plen; + ptypes += plen; + ptext += plen; + remaining -= plen; } /* The levels buffer now has odd and even numbers indicating |