Handle shaping in non-native direction
This commit is contained in:
parent
b4b4272c8d
commit
ff44f88df2
|
@ -138,6 +138,7 @@ _hb_buffer_allocate_lig_id (hb_buffer_t *buffer);
|
||||||
#define IN_NEXTGLYPH() (buffer->in_string[buffer->in_pos + 1].codepoint)
|
#define IN_NEXTGLYPH() (buffer->in_string[buffer->in_pos + 1].codepoint)
|
||||||
#define IN_CURINFO() (&buffer->in_string[buffer->in_pos])
|
#define IN_CURINFO() (&buffer->in_string[buffer->in_pos])
|
||||||
#define IN_MASK(pos) (buffer->in_string[(pos)].mask)
|
#define IN_MASK(pos) (buffer->in_string[(pos)].mask)
|
||||||
|
#define IN_CLUSTER(pos) (buffer->in_string[(pos)].cluster)
|
||||||
#define IN_LIGID(pos) (buffer->in_string[(pos)].lig_id)
|
#define IN_LIGID(pos) (buffer->in_string[(pos)].lig_id)
|
||||||
#define IN_COMPONENT(pos) (buffer->in_string[(pos)].component)
|
#define IN_COMPONENT(pos) (buffer->in_string[(pos)].component)
|
||||||
#define POSITION(pos) (&buffer->positions[(pos)])
|
#define POSITION(pos) (&buffer->positions[(pos)])
|
||||||
|
|
|
@ -477,12 +477,14 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
hb_buffer_reverse (hb_buffer_t *buffer)
|
reverse_range (hb_buffer_t *buffer,
|
||||||
|
unsigned int start,
|
||||||
|
unsigned int end)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) {
|
for (i = start, j = end - 1; i < j; i++, j--) {
|
||||||
hb_internal_glyph_info_t t;
|
hb_internal_glyph_info_t t;
|
||||||
|
|
||||||
t = buffer->in_string[i];
|
t = buffer->in_string[i];
|
||||||
|
@ -491,7 +493,7 @@ hb_buffer_reverse (hb_buffer_t *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->positions) {
|
if (buffer->positions) {
|
||||||
for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) {
|
for (i = 0, j = end - 1; i < j; i++, j--) {
|
||||||
hb_internal_glyph_position_t t;
|
hb_internal_glyph_position_t t;
|
||||||
|
|
||||||
t = buffer->positions[i];
|
t = buffer->positions[i];
|
||||||
|
@ -501,6 +503,38 @@ hb_buffer_reverse (hb_buffer_t *buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_reverse (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
if (HB_UNLIKELY (!buffer->in_length))
|
||||||
|
return;
|
||||||
|
|
||||||
|
reverse_range (buffer, 0, buffer->in_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_reverse_clusters (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
unsigned int i, start, count, last_cluster;
|
||||||
|
|
||||||
|
if (HB_UNLIKELY (!buffer->in_length))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hb_buffer_reverse (buffer);
|
||||||
|
|
||||||
|
count = buffer->in_length;
|
||||||
|
start = 0;
|
||||||
|
last_cluster = buffer->in_string[0].cluster;
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
if (last_cluster != buffer->in_string[i].cluster) {
|
||||||
|
reverse_range (buffer, start, i);
|
||||||
|
start = i;
|
||||||
|
last_cluster = buffer->in_string[i].cluster;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reverse_range (buffer, start, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define ADD_UTF(T) \
|
#define ADD_UTF(T) \
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
|
|
|
@ -36,13 +36,6 @@ HB_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _hb_buffer_t hb_buffer_t;
|
typedef struct _hb_buffer_t hb_buffer_t;
|
||||||
|
|
||||||
typedef enum _hb_direction_t {
|
|
||||||
HB_DIRECTION_LTR,
|
|
||||||
HB_DIRECTION_RTL,
|
|
||||||
HB_DIRECTION_TTB,
|
|
||||||
HB_DIRECTION_BTT
|
|
||||||
} hb_direction_t;
|
|
||||||
|
|
||||||
typedef struct _hb_glyph_info_t {
|
typedef struct _hb_glyph_info_t {
|
||||||
hb_codepoint_t codepoint;
|
hb_codepoint_t codepoint;
|
||||||
hb_mask_t mask;
|
hb_mask_t mask;
|
||||||
|
@ -115,6 +108,9 @@ hb_buffer_ensure (hb_buffer_t *buffer,
|
||||||
void
|
void
|
||||||
hb_buffer_reverse (hb_buffer_t *buffer);
|
hb_buffer_reverse (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
/* Filling the buffer in */
|
/* Filling the buffer in */
|
||||||
|
|
||||||
|
|
|
@ -72,4 +72,15 @@ typedef uint32_t hb_mask_t;
|
||||||
|
|
||||||
typedef void (*hb_destroy_func_t) (void *user_data);
|
typedef void (*hb_destroy_func_t) (void *user_data);
|
||||||
|
|
||||||
|
typedef enum _hb_direction_t {
|
||||||
|
HB_DIRECTION_LTR,
|
||||||
|
HB_DIRECTION_RTL,
|
||||||
|
HB_DIRECTION_TTB,
|
||||||
|
HB_DIRECTION_BTT
|
||||||
|
} hb_direction_t;
|
||||||
|
|
||||||
|
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((dir) == HB_DIRECTION_LTR || (dir) == HB_DIRECTION_RTL)
|
||||||
|
#define HB_DIRECTION_IS_VERTICAL(dir) ((dir) == HB_DIRECTION_TTB || (dir) == HB_DIRECTION_BTT)
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_COMMON_H */
|
#endif /* HB_COMMON_H */
|
||||||
|
|
|
@ -37,6 +37,17 @@ is_variation_selector (hb_codepoint_t unicode)
|
||||||
(unicode >= 0xE0100 && unicode <= 0xE01EF);
|
(unicode >= 0xE0100 && unicode <= 0xE01EF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hb_form_clusters (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
count = buffer->in_length;
|
||||||
|
for (buffer->in_pos = 1; buffer->in_pos < count; buffer->in_pos++)
|
||||||
|
if (buffer->unicode->get_general_category (IN_CURGLYPH()) == HB_CATEGORY_NON_SPACING_MARK)
|
||||||
|
IN_CLUSTER (buffer->in_pos) = IN_CLUSTER (buffer->in_pos - 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hb_map_glyphs (hb_font_t *font,
|
hb_map_glyphs (hb_font_t *font,
|
||||||
hb_face_t *face,
|
hb_face_t *face,
|
||||||
|
@ -45,7 +56,6 @@ hb_map_glyphs (hb_font_t *font,
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
count = buffer->in_length - 1;
|
count = buffer->in_length - 1;
|
||||||
|
|
||||||
for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) {
|
for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) {
|
||||||
if (HB_UNLIKELY (is_variation_selector (IN_NEXTGLYPH()))) {
|
if (HB_UNLIKELY (is_variation_selector (IN_NEXTGLYPH()))) {
|
||||||
IN_CURGLYPH() = hb_font_get_glyph (font, face, IN_CURGLYPH(), IN_NEXTGLYPH());
|
IN_CURGLYPH() = hb_font_get_glyph (font, face, IN_CURGLYPH(), IN_NEXTGLYPH());
|
||||||
|
@ -67,7 +77,6 @@ hb_position_default (hb_font_t *font,
|
||||||
hb_buffer_clear_positions (buffer);
|
hb_buffer_clear_positions (buffer);
|
||||||
|
|
||||||
count = buffer->in_length;
|
count = buffer->in_length;
|
||||||
|
|
||||||
for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) {
|
for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) {
|
||||||
hb_glyph_metrics_t metrics;
|
hb_glyph_metrics_t metrics;
|
||||||
hb_font_get_glyph_metrics (font, face, IN_CURGLYPH(), &metrics);
|
hb_font_get_glyph_metrics (font, face, IN_CURGLYPH(), &metrics);
|
||||||
|
@ -77,6 +86,23 @@ hb_position_default (hb_font_t *font,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static hb_direction_t
|
||||||
|
hb_ensure_native_direction (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
hb_direction_t original_direction = hb_buffer_get_direction (buffer);
|
||||||
|
|
||||||
|
/* TODO vertical */
|
||||||
|
if (HB_DIRECTION_IS_HORIZONTAL (original_direction) &&
|
||||||
|
original_direction != _hb_script_get_horizontal_direction (hb_buffer_get_script (buffer)))
|
||||||
|
{
|
||||||
|
hb_buffer_reverse_clusters (buffer);
|
||||||
|
hb_buffer_set_direction (buffer, original_direction == HB_DIRECTION_LTR ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return original_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_shape (hb_font_t *font,
|
hb_shape (hb_font_t *font,
|
||||||
hb_face_t *face,
|
hb_face_t *face,
|
||||||
|
@ -84,7 +110,11 @@ hb_shape (hb_font_t *font,
|
||||||
hb_feature_t *features,
|
hb_feature_t *features,
|
||||||
unsigned int num_features)
|
unsigned int num_features)
|
||||||
{
|
{
|
||||||
/* form_clusters (buffer); */
|
hb_direction_t original_direction;
|
||||||
|
|
||||||
|
hb_form_clusters (buffer);
|
||||||
|
original_direction = hb_ensure_native_direction (buffer);
|
||||||
|
|
||||||
/* do_mirroring (buffer); */
|
/* do_mirroring (buffer); */
|
||||||
/* natural direction analysis */
|
/* natural direction analysis */
|
||||||
/* OT preprocess */
|
/* OT preprocess */
|
||||||
|
@ -99,4 +129,6 @@ hb_shape (hb_font_t *font,
|
||||||
hb_position_default (font, face, buffer);
|
hb_position_default (font, face, buffer);
|
||||||
|
|
||||||
/* GPOS / kern */
|
/* GPOS / kern */
|
||||||
|
|
||||||
|
hb_buffer_set_direction (buffer, original_direction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,11 @@ struct _hb_unicode_funcs_t {
|
||||||
HB_INTERNAL hb_unicode_funcs_t
|
HB_INTERNAL hb_unicode_funcs_t
|
||||||
_hb_unicode_funcs_nil;
|
_hb_unicode_funcs_nil;
|
||||||
|
|
||||||
|
|
||||||
|
HB_INTERNAL hb_direction_t
|
||||||
|
_hb_script_get_horizontal_direction (hb_script_t script);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
#endif /* HB_UNICODE_PRIVATE_H */
|
#endif /* HB_UNICODE_PRIVATE_H */
|
||||||
|
|
103
src/hb-unicode.c
103
src/hb-unicode.c
|
@ -159,3 +159,106 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
|
||||||
ufuncs->get_eastasian_width = eastasian_width_func ? eastasian_width_func : hb_unicode_get_eastasian_width_nil;
|
ufuncs->get_eastasian_width = eastasian_width_func ? eastasian_width_func : hb_unicode_get_eastasian_width_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define LTR HB_DIRECTION_LTR
|
||||||
|
#define RTL HB_DIRECTION_RTL
|
||||||
|
const hb_direction_t horiz_dir[] =
|
||||||
|
{
|
||||||
|
LTR, /* Zyyy */
|
||||||
|
LTR, /* Qaai */
|
||||||
|
RTL, /* Arab */
|
||||||
|
LTR, /* Armn */
|
||||||
|
LTR, /* Beng */
|
||||||
|
LTR, /* Bopo */
|
||||||
|
LTR, /* Cher */
|
||||||
|
LTR, /* Qaac */
|
||||||
|
LTR, /* Cyrl (Cyrs) */
|
||||||
|
LTR, /* Dsrt */
|
||||||
|
LTR, /* Deva */
|
||||||
|
LTR, /* Ethi */
|
||||||
|
LTR, /* Geor (Geon, Geoa) */
|
||||||
|
LTR, /* Goth */
|
||||||
|
LTR, /* Grek */
|
||||||
|
LTR, /* Gujr */
|
||||||
|
LTR, /* Guru */
|
||||||
|
LTR, /* Hani */
|
||||||
|
LTR, /* Hang */
|
||||||
|
RTL, /* Hebr */
|
||||||
|
LTR, /* Hira */
|
||||||
|
LTR, /* Knda */
|
||||||
|
LTR, /* Kana */
|
||||||
|
LTR, /* Khmr */
|
||||||
|
LTR, /* Laoo */
|
||||||
|
LTR, /* Latn (Latf, Latg) */
|
||||||
|
LTR, /* Mlym */
|
||||||
|
LTR, /* Mong */
|
||||||
|
LTR, /* Mymr */
|
||||||
|
LTR, /* Ogam */
|
||||||
|
LTR, /* Ital */
|
||||||
|
LTR, /* Orya */
|
||||||
|
LTR, /* Runr */
|
||||||
|
LTR, /* Sinh */
|
||||||
|
RTL, /* Syrc (Syrj, Syrn, Syre) */
|
||||||
|
LTR, /* Taml */
|
||||||
|
LTR, /* Telu */
|
||||||
|
RTL, /* Thaa */
|
||||||
|
LTR, /* Thai */
|
||||||
|
LTR, /* Tibt */
|
||||||
|
LTR, /* Cans */
|
||||||
|
LTR, /* Yiii */
|
||||||
|
LTR, /* Tglg */
|
||||||
|
LTR, /* Hano */
|
||||||
|
LTR, /* Buhd */
|
||||||
|
LTR, /* Tagb */
|
||||||
|
|
||||||
|
/* Unicode-4.0 additions */
|
||||||
|
LTR, /* Brai */
|
||||||
|
LTR, /* Cprt */
|
||||||
|
LTR, /* Limb */
|
||||||
|
LTR, /* Osma */
|
||||||
|
LTR, /* Shaw */
|
||||||
|
LTR, /* Linb */
|
||||||
|
LTR, /* Tale */
|
||||||
|
LTR, /* Ugar */
|
||||||
|
|
||||||
|
/* Unicode-4.1 additions */
|
||||||
|
LTR, /* Talu */
|
||||||
|
LTR, /* Bugi */
|
||||||
|
LTR, /* Glag */
|
||||||
|
LTR, /* Tfng */
|
||||||
|
LTR, /* Sylo */
|
||||||
|
LTR, /* Xpeo */
|
||||||
|
LTR, /* Khar */
|
||||||
|
|
||||||
|
/* Unicode-5.0 additions */
|
||||||
|
LTR, /* Zzzz */
|
||||||
|
LTR, /* Bali */
|
||||||
|
LTR, /* Xsux */
|
||||||
|
RTL, /* Phnx */
|
||||||
|
LTR, /* Phag */
|
||||||
|
RTL, /* Nkoo */
|
||||||
|
|
||||||
|
/* Unicode-5.1 additions */
|
||||||
|
LTR, /* Kali */
|
||||||
|
LTR, /* Lepc */
|
||||||
|
LTR, /* Rjng */
|
||||||
|
LTR, /* Sund */
|
||||||
|
LTR, /* Saur */
|
||||||
|
LTR, /* Cham */
|
||||||
|
LTR, /* Olck */
|
||||||
|
LTR, /* Vaii */
|
||||||
|
LTR, /* Cari */
|
||||||
|
LTR, /* Lyci */
|
||||||
|
LTR /* Lydi */
|
||||||
|
};
|
||||||
|
#undef LTR
|
||||||
|
#undef RTL
|
||||||
|
|
||||||
|
HB_INTERNAL hb_direction_t
|
||||||
|
_hb_script_get_horizontal_direction (hb_script_t script)
|
||||||
|
{
|
||||||
|
if (HB_UNLIKELY ((unsigned int) script >= ARRAY_LENGTH (horiz_dir)))
|
||||||
|
return HB_DIRECTION_LTR;
|
||||||
|
|
||||||
|
return horiz_dir[script];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue