Update HB to 7691a154e50f8c8c77bbd94787686262955bf5d4

Change-Id: I7dae9d74f338d3beeb1677a1676a07b66c05bb93
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Konstantin Ritt 2014-01-30 05:04:28 +02:00 committed by The Qt Project
parent a5614264d5
commit e707607ab0
32 changed files with 2312 additions and 1462 deletions

View File

@ -0,0 +1 @@
#include "../../src/hb-ot-shape.h"

View File

@ -14,6 +14,10 @@
# define HB_INTERNAL Q_DECL_HIDDEN
#endif
#if !defined(QT_NO_DEBUG)
# define NDEBUG
#endif
// because strdup() is not part of strict Posix, declare it here
extern "C" char *strdup(const char *src);

View File

@ -204,7 +204,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
*p++ = '+';
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
if (pos->y_advance)
if (pos[i].y_advance)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}

View File

@ -94,6 +94,7 @@ typedef uint32_t hb_tag_t;
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
#define HB_TAG_NONE HB_TAG(0,0,0,0)
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
/* len=-1 means str is NUL-terminated. */
hb_tag_t
@ -270,7 +271,12 @@ typedef enum
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
/* No script set. */
/*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE
/*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE,
/* Dummy value to ensure any hb_tag_t value can be passed/stored as hb_script_t
* without risking undefined behavior. */
/*---*/ _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX
} hb_script_t;
/* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */

View File

@ -1,138 +0,0 @@
/*
* Copyright © 2011 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#define HB_SHAPER fallback
#include "hb-shaper-impl-private.hh"
/*
* shaper face data
*/
struct hb_fallback_shaper_face_data_t {};
hb_fallback_shaper_face_data_t *
_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
{
return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
{
}
/*
* shaper font data
*/
struct hb_fallback_shaper_font_data_t {};
hb_fallback_shaper_font_data_t *
_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
{
return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
{
}
/*
* shaper shape_plan data
*/
struct hb_fallback_shaper_shape_plan_data_t {};
hb_fallback_shaper_shape_plan_data_t *
_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *user_features HB_UNUSED,
unsigned int num_user_features HB_UNUSED)
{
return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
{
}
/*
* shaper
*/
hb_bool_t
_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
/* TODO
*
* - Apply fallback kern.
* - Handle Variation Selectors?
* - Apply normalization?
*
* This will make the fallback shaper into a dumb "TrueType"
* shaper which many people unfortunately still request.
*/
hb_codepoint_t space;
font->get_glyph (' ', 0, &space);
buffer->clear_positions ();
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
{
if (buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
buffer->info[i].codepoint = space;
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
continue;
}
font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
buffer->props.direction,
&buffer->pos[i].x_advance,
&buffer->pos[i].y_advance);
font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
buffer->props.direction,
&buffer->pos[i].x_offset,
&buffer->pos[i].y_offset);
}
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
hb_buffer_reverse (buffer);
return true;
}

View File

@ -144,6 +144,12 @@ struct hb_font_t {
/* Public getters */
inline hb_bool_t has_glyph (hb_codepoint_t unicode)
{
hb_codepoint_t glyph;
return get_glyph (unicode, 0, &glyph);
}
inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{

View File

@ -592,7 +592,7 @@ struct LONGDATETIME
TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (this)));
}
private:
protected:
LONG major;
ULONG minor;
public:

View File

@ -109,11 +109,13 @@ struct ValueFormat : USHORT
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
if (format & xAdvance) {
if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++;
if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
values++;
}
/* y_advance values grow downward but font-space grows upward, hence negation */
if (format & yAdvance) {
if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++;
if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
values++;
}
if (!has_device ()) return;
@ -125,17 +127,21 @@ struct ValueFormat : USHORT
/* pixel -> fractional pixel */
if (format & xPlaDevice) {
if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_delta (font); else values++;
if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font);
values++;
}
if (format & yPlaDevice) {
if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_delta (font); else values++;
if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font);
values++;
}
if (format & xAdvDevice) {
if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font);
values++;
}
if (format & yAdvDevice) {
/* y_advance values grow downward but font-space grows upward, hence negation */
if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font);
values++;
}
}
@ -240,12 +246,12 @@ struct AnchorFormat2
unsigned int x_ppem = font->x_ppem;
unsigned int y_ppem = font->y_ppem;
hb_position_t cx, cy;
hb_bool_t ret = false;
hb_bool_t ret;
if (x_ppem || y_ppem)
ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
*x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
*y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
ret = (x_ppem || y_ppem) &&
font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
*x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
*y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
}
inline bool sanitize (hb_sanitize_context_t *c) {

View File

@ -193,11 +193,6 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
const hb_tag_t *features,
hb_set_t *lookup_indexes /* OUT */);
void
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
hb_tag_t table_tag,
hb_set_t *lookup_indexes /* OUT */);
void
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag,

View File

@ -199,7 +199,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (NULL);
map->add_global_bool_feature (HB_TAG('c','s','w','h'));
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
@ -366,7 +365,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
data_create_arabic,
data_destroy_arabic,
NULL, /* preprocess_text_arabic */
NULL, /* normalization_preference */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_arabic,

View File

@ -27,194 +27,18 @@
#include "hb-ot-shape-complex-private.hh"
/* TODO Add kana, and other small shapers here */
/* The default shaper *only* adds additional per-script features.*/
static const hb_tag_t hangul_features[] =
{
HB_TAG('l','j','m','o'),
HB_TAG('v','j','m','o'),
HB_TAG('t','j','m','o'),
HB_TAG_NONE
};
static const hb_tag_t tibetan_features[] =
{
HB_TAG('a','b','v','s'),
HB_TAG('b','l','w','s'),
HB_TAG('a','b','v','m'),
HB_TAG('b','l','w','m'),
HB_TAG_NONE
};
static void
collect_features_default (hb_ot_shape_planner_t *plan)
{
const hb_tag_t *script_features = NULL;
switch ((hb_tag_t) plan->props.script)
{
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
script_features = hangul_features;
break;
/* Unicode-2.0 additions */
case HB_SCRIPT_TIBETAN:
script_features = tibetan_features;
break;
}
for (; script_features && *script_features; script_features++)
plan->map.add_global_bool_feature (*script_features);
}
static hb_ot_shape_normalization_mode_t
normalization_preference_default (const hb_segment_properties_t *props)
{
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
}
static bool
compose_default (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab)
{
/* Hebrew presentation-form shaping.
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
* Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
* Note that some letters do not have a dagesh presForm encoded.
*/
static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
0xFB30, /* ALEF */
0xFB31, /* BET */
0xFB32, /* GIMEL */
0xFB33, /* DALET */
0xFB34, /* HE */
0xFB35, /* VAV */
0xFB36, /* ZAYIN */
0x0000, /* HET */
0xFB38, /* TET */
0xFB39, /* YOD */
0xFB3A, /* FINAL KAF */
0xFB3B, /* KAF */
0xFB3C, /* LAMED */
0x0000, /* FINAL MEM */
0xFB3E, /* MEM */
0x0000, /* FINAL NUN */
0xFB40, /* NUN */
0xFB41, /* SAMEKH */
0x0000, /* AYIN */
0xFB43, /* FINAL PE */
0xFB44, /* PE */
0x0000, /* FINAL TSADI */
0xFB46, /* TSADI */
0xFB47, /* QOF */
0xFB48, /* RESH */
0xFB49, /* SHIN */
0xFB4A /* TAV */
};
bool found = c->unicode->compose (a, b, ab);
if (!found && (b & ~0x7F) == 0x0580) {
/* Special-case Hebrew presentation forms that are excluded from
* standard normalization, but wanted for old fonts. */
switch (b) {
case 0x05B4: /* HIRIQ */
if (a == 0x05D9) { /* YOD */
*ab = 0xFB1D;
found = true;
}
break;
case 0x05B7: /* patah */
if (a == 0x05F2) { /* YIDDISH YOD YOD */
*ab = 0xFB1F;
found = true;
} else if (a == 0x05D0) { /* ALEF */
*ab = 0xFB2E;
found = true;
}
break;
case 0x05B8: /* QAMATS */
if (a == 0x05D0) { /* ALEF */
*ab = 0xFB2F;
found = true;
}
break;
case 0x05B9: /* HOLAM */
if (a == 0x05D5) { /* VAV */
*ab = 0xFB4B;
found = true;
}
break;
case 0x05BC: /* DAGESH */
if (a >= 0x05D0 && a <= 0x05EA) {
*ab = sDageshForms[a - 0x05D0];
found = (*ab != 0);
} else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
*ab = 0xFB2C;
found = true;
} else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
*ab = 0xFB2D;
found = true;
}
break;
case 0x05BF: /* RAFE */
switch (a) {
case 0x05D1: /* BET */
*ab = 0xFB4C;
found = true;
break;
case 0x05DB: /* KAF */
*ab = 0xFB4D;
found = true;
break;
case 0x05E4: /* PE */
*ab = 0xFB4E;
found = true;
break;
}
break;
case 0x05C1: /* SHIN DOT */
if (a == 0x05E9) { /* SHIN */
*ab = 0xFB2A;
found = true;
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
*ab = 0xFB2C;
found = true;
}
break;
case 0x05C2: /* SIN DOT */
if (a == 0x05E9) { /* SHIN */
*ab = 0xFB2B;
found = true;
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
*ab = 0xFB2D;
found = true;
}
break;
}
}
return found;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
{
"default",
collect_features_default,
NULL, /* collect_features */
NULL, /* override_features */
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
normalization_preference_default,
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
compose_default,
NULL, /* compose */
NULL, /* setup_masks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
true, /* fallback_position */
};

View File

@ -0,0 +1,417 @@
/*
* Copyright © 2013 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#include "hb-ot-shape-complex-private.hh"
/* Hangul shaper */
/* Same order as the feature array below */
enum {
NONE,
LJMO,
VJMO,
TJMO,
FIRST_HANGUL_FEATURE = LJMO,
HANGUL_FEATURE_COUNT = TJMO + 1
};
static const hb_tag_t hangul_features[HANGUL_FEATURE_COUNT] =
{
HB_TAG_NONE,
HB_TAG('l','j','m','o'),
HB_TAG('v','j','m','o'),
HB_TAG('t','j','m','o')
};
static void
collect_features_hangul (hb_ot_shape_planner_t *plan)
{
hb_ot_map_builder_t *map = &plan->map;
for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
map->add_feature (hangul_features[i], 1, F_NONE);
}
struct hangul_shape_plan_t
{
ASSERT_POD ();
hb_mask_t mask_array[HANGUL_FEATURE_COUNT];
};
static void *
data_create_hangul (const hb_ot_shape_plan_t *plan)
{
hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
if (unlikely (!hangul_plan))
return NULL;
for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
return hangul_plan;
}
static void
data_destroy_hangul (void *data)
{
free (data);
}
/* Constants for algorithmic hangul syllable [de]composition. */
#define LBase 0x1100
#define VBase 0x1161
#define TBase 0x11A7
#define LCount 19
#define VCount 21
#define TCount 28
#define SBase 0xAC00
#define NCount (VCount * TCount)
#define SCount (LCount * NCount)
#define isCombiningL(u) (hb_in_range<hb_codepoint_t> ((u), LBase, LBase+LCount-1))
#define isCombiningV(u) (hb_in_range<hb_codepoint_t> ((u), VBase, VBase+VCount-1))
#define isCombiningT(u) (hb_in_range<hb_codepoint_t> ((u), TBase+1, TBase+TCount-1))
#define isCombinedS(u) (hb_in_range<hb_codepoint_t> ((u), SBase, SBase+SCount-1))
#define isL(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1100, 0x115F, 0xA960, 0xA97C))
#define isV(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1160, 0x11A7, 0xD7B0, 0xD7C6))
#define isT(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x11A8, 0x11FF, 0xD7CB, 0xD7FB))
#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302e, 0x302f))
/* buffer var allocations */
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
static bool
is_zero_width_char (hb_font_t *font,
hb_codepoint_t unicode)
{
hb_codepoint_t glyph;
return hb_font_get_glyph (font, unicode, 0, &glyph) && hb_font_get_glyph_h_advance (font, glyph) == 0;
}
static void
preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
HB_BUFFER_ALLOCATE_VAR (buffer, hangul_shaping_feature);
/* Hangul syllables come in two shapes: LV, and LVT. Of those:
*
* - LV can be precomposed, or decomposed. Lets call those
* <LV> and <L,V>,
* - LVT can be fully precomposed, partically precomposed, or
* fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
*
* The composition / decomposition is mechanical. However, not
* all <L,V> sequences compose, and not all <LV,T> sequences
* compose.
*
* Here are the specifics:
*
* - <L>: U+1100..115F, U+A960..A97F
* - <V>: U+1160..11A7, U+D7B0..D7C7
* - <T>: U+11A8..11FF, U+D7CB..D7FB
*
* - Only the <L,V> sequences for the 11xx ranges combine.
* - Only <LV,T> sequences for T in U+11A8..11C3 combine.
*
* Here is what we want to accomplish in this shaper:
*
* - If the whole syllable can be precomposed, do that,
* - Otherwise, fully decompose and apply ljmo/vjmo/tjmo features.
* - If a valid syllable is followed by a Hangul tone mark, reorder the tone
* mark to precede the whole syllable - unless it is a zero-width glyph, in
* which case we leave it untouched, assuming it's designed to overstrike.
*
* That is, of the different possible syllables:
*
* <L>
* <L,V>
* <L,V,T>
* <LV>
* <LVT>
* <LV, T>
*
* - <L> needs no work.
*
* - <LV> and <LVT> can stay the way they are if the font supports them, otherwise we
* should fully decompose them if font supports.
*
* - <L,V> and <L,V,T> we should compose if the whole thing can be composed.
*
* - <LV,T> we should compose if the whole thing can be composed, otherwise we should
* decompose.
*/
buffer->clear_output ();
unsigned int start = 0, end = 0; /* Extent of most recently seen syllable;
* valid only if start < end
*/
unsigned int count = buffer->len;
for (buffer->idx = 0; buffer->idx < count;)
{
hb_codepoint_t u = buffer->cur().codepoint;
if (isHangulTone (u))
{
/*
* We could cache the width of the tone marks and the existence of dotted-circle,
* but the use of the Hangul tone mark characters seems to be rare enough that
* I didn't bother for now.
*/
if (start < end && end == buffer->out_len)
{
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
buffer->next_glyph ();
if (!is_zero_width_char (font, u))
{
hb_glyph_info_t *info = buffer->out_info;
hb_glyph_info_t tone = info[end];
memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t));
info[start] = tone;
}
/* Merge clusters across the (possibly reordered) syllable+tone.
* We want to merge even in the zero-width tone mark case here,
* so that clustering behavior isn't dependent on how the tone mark
* is handled by the font.
*/
buffer->merge_out_clusters (start, end + 1);
}
else
{
/* No valid syllable as base for tone mark; try to insert dotted circle. */
if (font->has_glyph (0x25cc))
{
hb_codepoint_t chars[2];
if (!is_zero_width_char (font, u)) {
chars[0] = u;
chars[1] = 0x25cc;
} else {
chars[0] = 0x25cc;
chars[1] = u;
}
buffer->replace_glyphs (1, 2, chars);
}
else
{
/* No dotted circle available in the font; just leave tone mark untouched. */
buffer->next_glyph ();
}
}
start = end = buffer->out_len;
continue;
}
start = buffer->out_len; /* Remember current position as a potential syllable start;
* will only be used if we set end to a later position.
*/
if (isL (u) && buffer->idx + 1 < count)
{
hb_codepoint_t l = u;
hb_codepoint_t v = buffer->cur(+1).codepoint;
if (isV (v))
{
/* Have <L,V> or <L,V,T>. */
hb_codepoint_t t = 0;
unsigned int tindex = 0;
if (buffer->idx + 2 < count)
{
t = buffer->cur(+2).codepoint;
if (isT (t))
tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
else
t = 0; /* The next character was not a trailing jamo. */
}
/* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
{
/* Try to compose; if this succeeds, end is set to start+1. */
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);
if (unlikely (buffer->in_error))
return;
end = start + 1;
continue;
}
}
/* We didn't compose, either because it's an Old Hangul syllable without a
* precomposed character in Unicode, or because the font didn't support the
* necessary precomposed glyph.
* Set jamo features on the individual glyphs, and advance past them.
*/
buffer->cur().hangul_shaping_feature() = LJMO;
buffer->next_glyph ();
buffer->cur().hangul_shaping_feature() = VJMO;
buffer->next_glyph ();
if (t)
{
buffer->cur().hangul_shaping_feature() = TJMO;
buffer->next_glyph ();
end = start + 3;
}
else
end = start + 2;
buffer->merge_out_clusters (start, end);
continue;
}
}
else if (isCombinedS (u))
{
/* Have <LV>, <LVT>, or <LV,T> */
hb_codepoint_t s = u;
bool has_glyph = font->has_glyph (s);
unsigned int lindex = (s - SBase) / NCount;
unsigned int nindex = (s - SBase) % NCount;
unsigned int vindex = nindex / TCount;
unsigned int tindex = nindex % TCount;
if (!tindex &&
buffer->idx + 1 < count &&
isCombiningT (buffer->cur(+1).codepoint))
{
/* <LV,T>, try to combine. */
unsigned int new_tindex = buffer->cur(+1).codepoint - TBase;
hb_codepoint_t new_s = s + new_tindex;
if (font->has_glyph (new_s))
{
buffer->replace_glyphs (2, 1, &new_s);
if (unlikely (buffer->in_error))
return;
end = start + 1;
continue;
}
}
/* Otherwise, decompose if font doesn't support <LV> or <LVT>,
* or if having non-combining <LV,T>. Note that we already handled
* combining <LV,T> above. */
if (!has_glyph ||
(!tindex &&
buffer->idx + 1 < count &&
isT (buffer->cur(+1).codepoint)))
{
hb_codepoint_t decomposed[3] = {LBase + lindex,
VBase + vindex,
TBase + tindex};
if (font->has_glyph (decomposed[0]) &&
font->has_glyph (decomposed[1]) &&
(!tindex || font->has_glyph (decomposed[2])))
{
unsigned int s_len = tindex ? 3 : 2;
buffer->replace_glyphs (1, s_len, decomposed);
if (unlikely (buffer->in_error))
return;
/* We decomposed S: apply jamo features to the individual glyphs
* that are now in buffer->out_info.
*/
hb_glyph_info_t *info = buffer->out_info;
/* 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 ();
s_len++;
}
end = start + s_len;
unsigned int i = start;
info[i++].hangul_shaping_feature() = LJMO;
info[i++].hangul_shaping_feature() = VJMO;
if (i < end)
info[i++].hangul_shaping_feature() = TJMO;
buffer->merge_out_clusters (start, end);
continue;
}
}
if (has_glyph)
{
/* We didn't decompose the S, so just advance past it. */
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 ();
}
buffer->swap_buffers ();
}
static void
setup_masks_hangul (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED)
{
const hangul_shape_plan_t *hangul_plan = (const hangul_shape_plan_t *) plan->data;
if (likely (hangul_plan))
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++, info++)
info->mask |= hangul_plan->mask_array[info->hangul_shaping_feature()];
}
HB_BUFFER_DEALLOCATE_VAR (buffer, hangul_shaping_feature);
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
{
"hangul",
collect_features_hangul,
NULL, /* override_features */
data_create_hangul, /* data_create */
data_destroy_hangul, /* data_destroy */
preprocess_text_hangul,
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
NULL, /* decompose */
NULL, /* compose */
setup_masks_hangul, /* setup_masks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};

View File

@ -0,0 +1,172 @@
/*
* Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#include "hb-ot-shape-complex-private.hh"
static bool
compose_hebrew (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab)
{
/* Hebrew presentation-form shaping.
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
* Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
* Note that some letters do not have a dagesh presForm encoded.
*/
static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
0xFB30, /* ALEF */
0xFB31, /* BET */
0xFB32, /* GIMEL */
0xFB33, /* DALET */
0xFB34, /* HE */
0xFB35, /* VAV */
0xFB36, /* ZAYIN */
0x0000, /* HET */
0xFB38, /* TET */
0xFB39, /* YOD */
0xFB3A, /* FINAL KAF */
0xFB3B, /* KAF */
0xFB3C, /* LAMED */
0x0000, /* FINAL MEM */
0xFB3E, /* MEM */
0x0000, /* FINAL NUN */
0xFB40, /* NUN */
0xFB41, /* SAMEKH */
0x0000, /* AYIN */
0xFB43, /* FINAL PE */
0xFB44, /* PE */
0x0000, /* FINAL TSADI */
0xFB46, /* TSADI */
0xFB47, /* QOF */
0xFB48, /* RESH */
0xFB49, /* SHIN */
0xFB4A /* TAV */
};
bool found = c->unicode->compose (a, b, ab);
if (!found)
{
/* Special-case Hebrew presentation forms that are excluded from
* standard normalization, but wanted for old fonts. */
switch (b) {
case 0x05B4: /* HIRIQ */
if (a == 0x05D9) { /* YOD */
*ab = 0xFB1D;
found = true;
}
break;
case 0x05B7: /* patah */
if (a == 0x05F2) { /* YIDDISH YOD YOD */
*ab = 0xFB1F;
found = true;
} else if (a == 0x05D0) { /* ALEF */
*ab = 0xFB2E;
found = true;
}
break;
case 0x05B8: /* QAMATS */
if (a == 0x05D0) { /* ALEF */
*ab = 0xFB2F;
found = true;
}
break;
case 0x05B9: /* HOLAM */
if (a == 0x05D5) { /* VAV */
*ab = 0xFB4B;
found = true;
}
break;
case 0x05BC: /* DAGESH */
if (a >= 0x05D0 && a <= 0x05EA) {
*ab = sDageshForms[a - 0x05D0];
found = (*ab != 0);
} else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
*ab = 0xFB2C;
found = true;
} else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
*ab = 0xFB2D;
found = true;
}
break;
case 0x05BF: /* RAFE */
switch (a) {
case 0x05D1: /* BET */
*ab = 0xFB4C;
found = true;
break;
case 0x05DB: /* KAF */
*ab = 0xFB4D;
found = true;
break;
case 0x05E4: /* PE */
*ab = 0xFB4E;
found = true;
break;
}
break;
case 0x05C1: /* SHIN DOT */
if (a == 0x05E9) { /* SHIN */
*ab = 0xFB2A;
found = true;
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
*ab = 0xFB2C;
found = true;
}
break;
case 0x05C2: /* SIN DOT */
if (a == 0x05E9) { /* SHIN */
*ab = 0xFB2B;
found = true;
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
*ab = 0xFB2D;
found = true;
}
break;
}
}
return found;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
{
"hebrew",
NULL, /* collect_features */
NULL, /* override_features */
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
compose_hebrew,
NULL, /* setup_masks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
true, /* fallback_position */
};

File diff suppressed because it is too large Load Diff

View File

@ -1690,12 +1690,6 @@ clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static hb_ot_shape_normalization_mode_t
normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
{
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
}
static bool
decompose_indic (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
@ -1806,7 +1800,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
data_create_indic,
data_destroy_indic,
NULL, /* preprocess_text */
normalization_preference_indic,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_indic,
compose_indic,
setup_masks_indic,

View File

@ -34,196 +34,197 @@
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
30, 28, 25, 4, 25, 23, 21, 21,
31, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 27, 27, 27, 27, 25, 4,
25, 23, 21, 21, 27, 27, 27, 27,
28, 27, 30, 27, 27, 27, 27, 27,
27, 27, 27, 27
27, 27, 27, 27, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
0, 31, 60, 86, 91, 117, 141, 163,
185, 213, 241, 269, 297, 314, 342, 370,
398, 426, 454, 482, 510, 538, 566, 592,
597, 623, 647, 669, 691, 719, 747, 775,
803, 832, 860, 891, 919, 947, 975, 1003,
1031, 1059, 1087, 1115
0, 32, 61, 87, 92, 118, 142, 164,
186, 214, 242, 270, 298, 315, 343, 371,
399, 427, 455, 483, 511, 539, 567, 593,
598, 624, 648, 670, 692, 720, 748, 776,
804, 833, 861, 892, 920, 948, 976, 1004,
1032, 1060, 1088, 1116, 1144
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 0, 1, 0, 0, 0, 7,
0, 8, 1, 0, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 0, 20,
21, 22, 22, 19, 23, 19, 24, 19,
19, 19, 19, 19, 19, 19, 25, 19,
19, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 19, 22, 22, 19, 23,
19, 19, 19, 19, 19, 19, 19, 19,
19, 36, 19, 19, 19, 19, 19, 19,
30, 19, 19, 19, 34, 19, 22, 22,
19, 23, 19, 22, 22, 19, 23, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 30,
19, 19, 19, 34, 19, 37, 19, 22,
22, 19, 23, 19, 30, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 19, 22, 22, 19,
23, 19, 19, 19, 19, 19, 19, 19,
19, 19, 38, 19, 19, 19, 19, 19,
19, 30, 19, 22, 22, 19, 23, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 30,
19, 20, 19, 22, 22, 19, 23, 19,
24, 19, 19, 19, 19, 19, 19, 19,
39, 19, 19, 39, 19, 19, 19, 30,
40, 19, 19, 34, 19, 20, 19, 22,
22, 19, 23, 19, 24, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 19, 19, 19, 34,
19, 20, 19, 22, 22, 19, 23, 19,
24, 19, 19, 19, 19, 19, 19, 19,
39, 19, 19, 19, 19, 19, 19, 30,
40, 19, 19, 34, 19, 20, 19, 22,
22, 19, 23, 19, 24, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 40, 19, 19, 34,
19, 1, 1, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
1, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 25, 19, 19, 26, 27, 28, 29,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 33, 19, 19,
19, 19, 19, 19, 30, 31, 32, 33,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 30, 31, 32, 19,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
30, 19, 32, 19, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
26, 19, 28, 19, 30, 31, 32, 33,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 33, 19, 19, 26, 19, 19, 19,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
26, 27, 28, 19, 30, 31, 32, 33,
34, 19, 20, 21, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 25, 19, 19, 26, 27, 28, 29,
30, 31, 32, 33, 34, 19, 3, 3,
41, 5, 41, 41, 41, 41, 41, 41,
41, 41, 41, 42, 41, 41, 41, 41,
41, 41, 13, 41, 41, 41, 17, 41,
3, 3, 41, 5, 41, 3, 3, 41,
5, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 41, 41, 17, 41, 43,
41, 3, 3, 41, 5, 41, 13, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 41, 3,
3, 41, 5, 41, 41, 41, 41, 41,
41, 41, 41, 41, 44, 41, 41, 41,
41, 41, 41, 13, 41, 3, 3, 41,
5, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 45, 41, 41, 45, 41, 41,
41, 13, 46, 41, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 41, 41,
41, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 45, 41, 41, 41, 41, 41,
41, 13, 46, 41, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 46, 41,
41, 17, 41, 20, 21, 22, 22, 19,
23, 19, 24, 19, 19, 19, 19, 19,
19, 19, 47, 19, 19, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 19,
20, 48, 22, 22, 19, 23, 19, 24,
19, 19, 19, 19, 19, 19, 19, 25,
19, 19, 26, 27, 28, 29, 30, 31,
32, 33, 34, 19, 1, 1, 2, 3,
3, 3, 41, 5, 41, 6, 41, 1,
41, 41, 41, 1, 41, 8, 1, 41,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 8, 41, 41, 9, 10, 11,
12, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 16, 41,
41, 41, 41, 41, 41, 13, 14, 15,
16, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 14, 15,
41, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 15, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 9, 41, 11, 41, 13, 14, 15,
16, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 16, 41, 41, 9, 41, 41,
41, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 9, 10, 11, 41, 13, 14, 15,
16, 17, 41, 2, 3, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 8, 41, 41, 9, 10, 11,
12, 13, 14, 15, 16, 17, 41, 0
13, 14, 15, 16, 17, 18, 19, 0,
21, 22, 23, 23, 20, 24, 20, 25,
20, 20, 20, 20, 20, 20, 20, 26,
20, 20, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 20, 23, 23, 20,
24, 20, 20, 20, 20, 20, 20, 20,
20, 20, 37, 20, 20, 20, 20, 20,
20, 31, 20, 20, 20, 35, 20, 23,
23, 20, 24, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 20, 20, 35, 20, 38, 20,
23, 23, 20, 24, 20, 31, 20, 20,
20, 20, 20, 20, 20, 39, 20, 20,
20, 20, 20, 20, 31, 20, 23, 23,
20, 24, 20, 20, 20, 20, 20, 20,
20, 20, 20, 39, 20, 20, 20, 20,
20, 20, 31, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 40, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 20, 20, 20,
35, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 20, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 41, 20, 20,
35, 20, 1, 1, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 1, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 34, 20,
20, 20, 20, 20, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 31, 32, 33,
20, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 20, 33, 20, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 27, 20, 29, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 34, 20, 20, 27, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 27, 28, 29, 20, 31, 32, 33,
34, 35, 20, 21, 22, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 3,
3, 42, 5, 42, 42, 42, 42, 42,
42, 42, 42, 42, 43, 42, 42, 42,
42, 42, 42, 13, 42, 42, 42, 17,
42, 3, 3, 42, 5, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 42, 42, 17, 42,
44, 42, 3, 3, 42, 5, 42, 13,
42, 42, 42, 42, 42, 42, 42, 45,
42, 42, 42, 42, 42, 42, 13, 42,
3, 3, 42, 5, 42, 42, 42, 42,
42, 42, 42, 42, 42, 45, 42, 42,
42, 42, 42, 42, 13, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 46, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 42,
42, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 42, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 47,
42, 42, 17, 42, 21, 22, 23, 23,
20, 24, 20, 25, 20, 20, 20, 20,
20, 20, 20, 48, 20, 20, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36,
20, 21, 49, 23, 23, 20, 24, 20,
25, 20, 20, 20, 20, 20, 20, 20,
26, 20, 20, 27, 28, 29, 30, 31,
32, 33, 34, 35, 20, 1, 1, 2,
3, 3, 3, 42, 5, 42, 6, 42,
1, 42, 42, 42, 1, 42, 8, 1,
42, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 16,
42, 42, 42, 42, 42, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 14,
15, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 15, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 9, 42, 11, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 16, 42, 42, 9, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 9, 10, 11, 42, 13, 14,
15, 16, 17, 42, 2, 3, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
51, 50, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 22, 0, 0, 23, 29, 32,
35, 36, 40, 41, 42, 25, 38, 39,
37, 28, 43, 0, 2, 12, 0, 3,
9, 13, 14, 18, 19, 20, 5, 16,
17, 15, 8, 21, 4, 6, 7, 10,
11, 0, 24, 26, 27, 30, 31, 33,
34
37, 28, 43, 44, 0, 2, 12, 0,
3, 9, 13, 14, 18, 19, 20, 5,
16, 17, 15, 8, 21, 4, 6, 7,
10, 11, 0, 24, 26, 27, 30, 31,
33, 34, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 4, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 6, 0, 0, 7, 0,
0, 0, 0, 0, 6, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 8, 0, 0, 0, 0, 0, 0,
0
0, 0, 8, 0, 0, 0, 0, 0,
0, 0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@ -232,7 +233,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
0, 0, 0, 0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@ -241,16 +242,16 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
0, 0, 0, 0, 0
};
static const short _myanmar_syllable_machine_eof_trans[] = {
0, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
20, 20, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42
0, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
21, 21, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 51
};
static const int myanmar_syllable_machine_start = 0;
@ -264,7 +265,7 @@ static const int myanmar_syllable_machine_en_main = 0;
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
@ -284,7 +285,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 288 "hb-ot-shape-complex-myanmar-machine.hh"
#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@ -292,7 +293,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
#line 111 "hb-ot-shape-complex-myanmar-machine.rl"
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@ -301,7 +302,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 305 "hb-ot-shape-complex-myanmar-machine.hh"
#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@ -315,7 +316,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 319 "hb-ot-shape-complex-myanmar-machine.hh"
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -334,30 +335,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 7:
#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 5:
#line 84 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 4:
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 10:
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
break;
case 4:
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 6:
#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 8:
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
#line 361 "hb-ot-shape-complex-myanmar-machine.hh"
case 9:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@ -366,7 +375,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
@ -382,7 +391,7 @@ _again:
}
#line 120 "hb-ot-shape-complex-myanmar-machine.rl"
#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
}

View File

@ -541,13 +541,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
static hb_ot_shape_normalization_mode_t
normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
{
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
"myanmar",
@ -556,7 +549,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
normalization_preference_myanmar,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_myanmar,

View File

@ -44,7 +44,9 @@ enum hb_ot_shape_zero_width_marks_type_t {
// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE
};
@ -52,10 +54,13 @@ enum hb_ot_shape_zero_width_marks_type_t {
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
/* ^--- Add new shapers here */
@ -105,12 +110,7 @@ struct hb_ot_complex_shaper_t
hb_font_t *font);
/* normalization_preference()
* Called during shape().
* May be NULL.
*/
hb_ot_shape_normalization_mode_t
(*normalization_preference) (const hb_segment_properties_t *props);
hb_ot_shape_normalization_mode_t normalization_preference;
/* decompose()
* Called during shape()'s normalization.
@ -189,19 +189,22 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_thai;
#if 0
/* Note:
* Currently we don't have a separate Hangul shaper. The default shaper handles
* Hangul by enabling jamo features. We may want to implement a separate shaper
* in the future. See this thread for details of what such a shaper would do:
*
* http://lists.freedesktop.org/archives/harfbuzz/2013-April/003070.html
*/
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
return &_hb_ot_complex_shaper_hangul;
#endif
/* Unicode-2.0 additions */
case HB_SCRIPT_TIBETAN:
return &_hb_ot_complex_shaper_tibetan;
/* Unicode-1.1 additions */
case HB_SCRIPT_HEBREW:
return &_hb_ot_complex_shaper_hebrew;
/* ^--- Add new shapers here */
@ -241,9 +244,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_LAO:
case HB_SCRIPT_THAI:
/* Unicode-2.0 additions */
case HB_SCRIPT_TIBETAN:
/* Unicode-3.2 additions */
case HB_SCRIPT_TAGALOG:
case HB_SCRIPT_TAGBANWA:

View File

@ -360,13 +360,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
static hb_ot_shape_normalization_mode_t
normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
{
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
{
"sea",
@ -375,7 +368,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
normalization_preference_sea,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_sea,

View File

@ -369,10 +369,10 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
NULL, /* data_create */
NULL, /* data_destroy */
preprocess_text_thai,
NULL, /* normalization_preference */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
NULL, /* compose */
NULL, /* setup_masks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
false,/* fallback_position */
};

View File

@ -0,0 +1,61 @@
/*
* Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#include "hb-ot-shape-complex-private.hh"
static const hb_tag_t tibetan_features[] =
{
HB_TAG('a','b','v','s'),
HB_TAG('b','l','w','s'),
HB_TAG('a','b','v','m'),
HB_TAG('b','l','w','m'),
HB_TAG_NONE
};
static void
collect_features_tibetan (hb_ot_shape_planner_t *plan)
{
for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
plan->map.add_global_bool_feature (*script_features);
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
{
"default",
collect_features_tibetan,
NULL, /* override_features */
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
NULL, /* compose */
NULL, /* setup_masks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
true, /* fallback_position */
};

View File

@ -430,14 +430,12 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
if (!kern_mask) return;
if (!plan->has_kern) return;
unsigned int count = buffer->len;
OT::hb_apply_context_t c (1, font, buffer);
c.set_lookup_mask (kern_mask);
c.set_lookup_mask (plan->kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
hb_glyph_info_t *info = buffer->info;

View File

@ -36,6 +36,7 @@
struct hb_ot_shape_plan_t;
enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */

View File

@ -213,8 +213,9 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
}
static inline void
handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
/* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
hb_buffer_t * const buffer = c->buffer;
hb_font_t * const font = c->font;
for (; buffer->idx < end - 1;) {
@ -250,27 +251,26 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns
}
static inline void
decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
hb_buffer_t * const buffer = c->buffer;
/* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
for (unsigned int i = buffer->idx; i < end; i++)
if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
handle_variation_selector_cluster (c, end);
handle_variation_selector_cluster (c, end, short_circuit);
return;
}
while (buffer->idx < end)
decompose_current_character (c, false);
decompose_current_character (c, short_circuit);
}
static inline void
decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end)
decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
{
if (likely (c->buffer->idx + 1 == end))
decompose_current_character (c, short_circuit);
decompose_current_character (c, might_short_circuit);
else
decompose_multi_char_cluster (c, end);
decompose_multi_char_cluster (c, end, always_short_circuit);
}
@ -289,9 +289,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ?
plan->shaper->normalization_preference (&buffer->props) :
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT;
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
const hb_ot_shape_normalize_context_t c = {
plan,
buffer,
@ -301,8 +299,10 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
plan->shaper->compose ? plan->shaper->compose : compose_unicode
};
bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE;
bool might_short_circuit = always_short_circuit ||
(mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT);
unsigned int count;
/* We do a fairly straightforward yet custom normalization process in three
@ -323,7 +323,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (buffer->cur().cluster != buffer->info[end].cluster)
break;
decompose_cluster (&c, short_circuit, end);
decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
}
buffer->swap_buffers ();
@ -355,7 +355,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
}
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
return;
/* Third round, recompose */
@ -393,8 +394,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
return;
buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */
buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
set_glyph (buffer->out_info[starter], font);
/* Modify starter and carry on. */
buffer->out_info[starter].codepoint = composed;
buffer->out_info[starter].glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
continue;

View File

@ -40,6 +40,10 @@ struct hb_ot_shape_plan_t
const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
const void *data;
hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
hb_mask_t kern_mask;
unsigned int has_frac : 1;
unsigned int has_kern : 1;
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
{
@ -77,6 +81,17 @@ struct hb_ot_shape_planner_t
plan.props = props;
plan.shaper = shaper;
map.compile (plan.map);
plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
plan.has_kern = !!plan.kern_mask;
}
private:

View File

@ -88,6 +88,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
}
map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
if (planner->shaper->collect_features)
planner->shaper->collect_features (planner);
@ -234,8 +238,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
if (!font->has_glyph (0x25CC))
return;
hb_glyph_info_t dottedcircle;
@ -292,7 +295,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
hb_buffer_t *buffer = c->buffer;
hb_unicode_funcs_t *unicode = buffer->unicode;
hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
hb_mask_t rtlm_mask = c->plan->rtlm_mask;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
@ -306,13 +309,58 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
{
if (!c->plan->has_frac)
return;
hb_buffer_t *buffer = c->buffer;
/* TODO look in pre/post context text also. */
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
{
if (info[i].codepoint == 0x2044) /* FRACTION SLASH */
{
unsigned int start = i, end = i + 1;
while (start &&
_hb_glyph_info_get_general_category (&info[start - 1]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
start--;
while (end < count &&
_hb_glyph_info_get_general_category (&info[end]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
end++;
for (unsigned int j = start; j < i; j++)
info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
info[i].mask |= c->plan->frac_mask;
for (unsigned int j = i + 1; j < end; j++)
info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask;
i = end - 1;
}
}
}
static inline void
hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
hb_mask_t global_mask = map->get_global_mask ();
buffer->reset_masks (global_mask);
}
static inline void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
hb_ot_shape_setup_masks_fraction (c);
if (c->plan->shaper->setup_masks)
c->plan->shaper->setup_masks (c->plan, buffer, c->font);
@ -358,6 +406,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
if (c->plan->shaper->preprocess_text)
c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
hb_ot_shape_initialize_masks (c);
hb_ot_mirror_chars (c);
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);

View File

@ -0,0 +1,54 @@
/*
* Copyright © 2013 Red Hat, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_SHAPE_H
#define HB_OT_SHAPE_H
#define HB_OT_SHAPE_H_IN
#include "hb.h"
#include "hb-ot-layout.h"
#include "hb-ot-tag.h"
HB_BEGIN_DECLS
/* TODO port to shape-plan / set. */
void
hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features,
hb_set_t *glyphs);
void
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
hb_tag_t table_tag,
hb_set_t *lookup_indexes /* OUT */);
HB_END_DECLS
#undef HB_OT_SHAPE_H_IN
#endif /* HB_OT_SHAPE_H */

View File

@ -32,17 +32,10 @@
#include "hb-ot-layout.h"
#include "hb-ot-tag.h"
#include "hb-ot-shape.h"
HB_BEGIN_DECLS
/* TODO remove */
void
hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features,
hb_set_t *glyphs);
HB_END_DECLS
#undef HB_OT_H_IN

View File

@ -807,6 +807,12 @@ hb_in_range (T u, T lo, T hi)
return lo <= u && u <= hi;
}
template <typename T> static inline bool
hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
{
return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
}
template <typename T> static inline bool
hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
{

View File

@ -52,4 +52,6 @@ HB_SHAPER_IMPLEMENT (uniscribe)
HB_SHAPER_IMPLEMENT (coretext)
#endif
#ifdef HAVE_FALLBACK
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
#endif

View File

@ -106,7 +106,11 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
modified_combining_class (hb_codepoint_t unicode)
{
/* XXX This hack belongs to the Myanmar shaper. */
if (unicode == 0x1037) unicode = 0x103A;
if (unlikely (unicode == 0x1037)) unicode = 0x103A;
/* XXX This hack belongs to the SEA shaper (for Tai Tham):
* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (unicode == 0x1A60)) return 254;
return _hb_modified_combining_class[combining_class (unicode)];
}
@ -130,10 +134,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 6.3 is also added manually. The new Unicode 6.3 bidi formatting
* characters are encoded in a block that was Default_Ignorable already.
*
* Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
* hide them, as the way Uniscribe has implemented them is with regular
* spacing glyphs, and that's the way fonts are made to work. As such,
* we make exceptions for those two.
* Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
* we do NOT want to hide them, as the way Uniscribe has implemented them
* is with regular spacing glyphs, and that's the way fonts are made to work.
* As such, we make exceptions for those four.
*
* Gathered from:
* http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
@ -155,10 +159,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 200B..200F ;RIGHT-TO-LEFT MARK
* 202A..202E ;RIGHT-TO-LEFT OVERRIDE
* 2060..206F ;NOMINAL DIGIT SHAPES
* 3164 ;HANGUL FILLER
* #3164 ;HANGUL FILLER
* FE00..FE0F ;VARIATION SELECTOR-16
* FEFF ;ZERO WIDTH NO-BREAK SPACE
* FFA0 ;HALFWIDTH HANGUL FILLER
* #FFA0 ;HALFWIDTH HANGUL FILLER
* FFF0..FFF8 ;<unassigned-FFF8>
* 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
* E0000..E0FFF ;<unassigned-E0FFF>
@ -180,9 +184,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F,
0x202A, 0x202E,
0x2060, 0x206F);
case 0x31: return unlikely (ch == 0x3164);
case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0;
case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8);
default: return false;
}
}

View File

@ -9,7 +9,6 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-buffer-serialize.cc \
$$QT_HARFBUZZ_DIR/src/hb-common.cc \
$$QT_HARFBUZZ_DIR/src/hb-face.cc \
$$QT_HARFBUZZ_DIR/src/hb-fallback-shape.cc \
$$QT_HARFBUZZ_DIR/src/hb-font.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-tag.cc \
$$QT_HARFBUZZ_DIR/src/hb-set.cc \
@ -65,11 +64,14 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-ot-shape.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-default.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hangul.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hebrew.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-table.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-thai.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-tibetan.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize.cc
@ -96,6 +98,7 @@ contains(QT_CONFIG, harfbuzz) {
HEADERS += \
$$QT_HARFBUZZ_DIR/src/hb-ot.h \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout.h \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape.h \
$$QT_HARFBUZZ_DIR/src/hb-ot-tag.h
DEFINES += HAVE_CONFIG_H