summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/bidi.c165
-rw-r--r--source/fitz/font.c4
2 files changed, 80 insertions, 89 deletions
diff --git a/source/fitz/bidi.c b/source/fitz/bidi.c
index e711e705..74548d4d 100644
--- a/source/fitz/bidi.c
+++ b/source/fitz/bidi.c
@@ -205,76 +205,83 @@ is_european_number(const uint32_t *str, unsigned int len)
return TRUE;
}
+/* Split fragments into single scripts (or punctation + single script) */
static void
-do_callback(const uint32_t *fragment,
+split_at_script(const uint32_t *fragment,
size_t fragment_len,
int block_r2l,
- uint32_t mirror,
+ int char_r2l,
void *arg,
fz_bidi_fragment_callback *callback)
{
- char char_r2l = block_r2l;
+ int script = UCDN_SCRIPT_COMMON;
+ size_t script_start, i;
- char_r2l = block_r2l && !is_european_number(fragment, fragment_len);
-
- (*callback)(fragment, fragment_len, block_r2l, char_r2l, mirror, arg);
-}
-
-/* Searches a RTL fragment for a mirror character
- * When it finds one it creates a separate fragment for the
- * character and the surrounding fragments. It passes the mirrored
- * character back through the callback.
- */
-static void
-create_fragment_mirrors(const uint32_t *text,
- int len,
- fz_bidi_fragment_callback *callback,
- void *arg)
-{
- int i;
- int lastPtr;
- uint32_t mirror;
-
- assert(text != NULL);
- assert(len > 0);
- lastPtr = 0;
- for (i = 0; i < len; i ++)
+ script_start = 0;
+ for (i = 0; i < fragment_len; i++)
{
- mirror = ucdn_mirror(text[i]);
- if (mirror != UNICODE_EOS)
+ int s = ucdn_get_script(fragment[i]);
+ if (s == UCDN_SCRIPT_COMMON || s == UCDN_SCRIPT_INHERITED)
{
- /* create preceding fragment */
- if (i > lastPtr)
- {
- do_callback(&text[lastPtr],
- i - lastPtr,
- TRUE,
- UNICODE_EOS,
- arg,
- callback);
- DBUGVF(("create mirror fragment for %x\n",(int)text[i]));
- }
- /* create mirror fragment */
- do_callback(&text[i],
- 1,
- TRUE,
- mirror,
- arg,
- callback);
- lastPtr = i + 1;
+ /* Punctuation etc. This is fine. */
+ }
+ else if (s == script)
+ {
+ /* Same script. Still fine. */
+ }
+ else if (script == UCDN_SCRIPT_COMMON || script == UCDN_SCRIPT_INHERITED)
+ {
+ /* First non punctuation thing. Set the script. */
+ script = s;
}
+ else
+ {
+ /* Change of script. Break the fragment. */
+ (*callback)(&fragment[script_start], i - script_start, block_r2l, char_r2l, script, arg);
+ script_start = i+1;
+ script = s;
+ }
+ }
+ if (script_start != fragment_len)
+ {
+ (*callback)(&fragment[script_start], fragment_len - script_start, block_r2l, char_r2l, script, arg);
}
+}
+
+static void
+detect_numbers(const uint32_t *fragment,
+ size_t fragment_len,
+ size_t start,
+ size_t end,
+ const fz_bidi_level *levels,
+ void *arg,
+ fz_bidi_fragment_callback *callback)
+{
+ int block_r2l = ODD(levels[start]);
+ int char_r2l = block_r2l;
- if (lastPtr < len)
+ /* Check to see if we've got a number. Numbers should
+ * never be block_r2l, so we can avoid the test. */
+ if (block_r2l || !is_european_number(&fragment[start], end-start))
{
- /* create end fragment */
- do_callback(&text[lastPtr],
- len - lastPtr,
- TRUE,
- UNICODE_EOS,
+ /* No number, just split as normal */
+ split_at_script(&fragment[start],
+ end-start,
+ block_r2l,
+ char_r2l,
arg,
callback);
+ return;
}
+
+ /* We have a number. We have to check to see whether this
+ * should be handled as a block_r2l thing. */
+ if (start != 0)
+ block_r2l = ODD(levels[start-1]);
+ if (block_r2l && end != fragment_len)
+ block_r2l = ODD(levels[end]);
+
+ split_at_script(&fragment[start], end-start, block_r2l, char_r2l, arg, callback);
}
/* Determines the character classes for all following
@@ -607,45 +614,25 @@ void fz_bidi_fragment_text(fz_context *ctx,
* Create a text object for it, then start
* a new fragment.
*/
- if (ODD(levels[startOfFragment]) != 0)
- {
- /* if RTL check for mirrors and create sub-frags */
- create_fragment_mirrors(&text[startOfFragment],
- i - startOfFragment,
- callback,
- arg);
- }
- else
- {
- do_callback(&text[startOfFragment],
- i - startOfFragment,
- ODD(levels[startOfFragment]),
- UNICODE_EOS,
- arg,
- callback);
- }
+ detect_numbers(text,
+ textlen,
+ startOfFragment,
+ i,
+ levels,
+ arg,
+ callback);
startOfFragment = i;
}
}
/* Now i == textlen. Deal with the final (or maybe only) fragment. */
- if (ODD(levels[startOfFragment]) != 0)
- {
- /* if RTL check for mirrors and create sub-frags */
- create_fragment_mirrors(&text[startOfFragment],
- i - startOfFragment,
- callback,
- arg);
- }
- else
- {
- /* otherwise create 1 fragment */
- do_callback(&text[startOfFragment],
- i - startOfFragment,
- ODD(levels[startOfFragment]),
- UNICODE_EOS,
- arg,
- callback);
- }
+ /* otherwise create 1 fragment */
+ detect_numbers(text,
+ textlen,
+ startOfFragment,
+ i,
+ levels,
+ arg,
+ callback);
}
fz_always(ctx)
{
diff --git a/source/fitz/font.c b/source/fitz/font.c
index a7db05d4..e7dbc827 100644
--- a/source/fitz/font.c
+++ b/source/fitz/font.c
@@ -1,6 +1,9 @@
#include "mupdf/fitz.h"
#include <ft2build.h>
+#include "hb.h"
+#include "hb-ft.h"
+
#include FT_FREETYPE_H
#include FT_ADVANCES_H
#include FT_STROKER_H
@@ -150,6 +153,7 @@ fz_drop_font(fz_context *ctx, fz_font *font)
fz_free(ctx, font->bbox_table);
fz_free(ctx, font->width_table);
fz_free(ctx, font->advance_cache);
+ hb_font_destroy(font->shaper);
fz_free(ctx, font);
}