Bug 1333656 - Update harfbuzz to version 1.4.2. r=jfkthame

--HG--
rename : gfx/harfbuzz/src/hb-ot-layout-math-table.hh => gfx/harfbuzz/src/hb-ot-math-table.hh
This commit is contained in:
Ryan VanderMeulen 2017-01-25 11:37:25 -05:00
parent e9ab36bd47
commit 895113f2db
41 changed files with 1584 additions and 463 deletions

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[1.4.1],
[1.4.2],
[https://github.com/behdad/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])

View File

@ -299,6 +299,8 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc
test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
check: harfbuzz.def # For check-defs.sh
dist_check_SCRIPTS = \
check-c-linkage-decls.sh \
check-defs.sh \

View File

@ -5,7 +5,7 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library ICU integration
Version: 1.4.1
Version: 1.4.2
Requires: harfbuzz
Requires.private: icu-uc

View File

@ -5,7 +5,7 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library
Version: 1.4.1
Version: 1.4.2
Libs: -L${libdir} -lharfbuzz
Libs.private:

View File

@ -605,3 +605,347 @@ hb_version_atleast (unsigned int major,
{
return HB_VERSION_ATLEAST (major, minor, micro);
}
/* hb_feature_t and hb_variation_t */
static bool
parse_space (const char **pp, const char *end)
{
while (*pp < end && ISSPACE (**pp))
(*pp)++;
return true;
}
static bool
parse_char (const char **pp, const char *end, char c)
{
parse_space (pp, end);
if (*pp == end || **pp != c)
return false;
(*pp)++;
return true;
}
static bool
parse_uint (const char **pp, const char *end, unsigned int *pv)
{
char buf[32];
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
strncpy (buf, *pp, len);
buf[len] = '\0';
char *p = buf;
char *pend = p;
unsigned int v;
/* Intentionally use strtol instead of strtoul, such that
* -1 turns into "big number"... */
errno = 0;
v = strtol (p, &pend, 0);
if (errno || p == pend)
return false;
*pv = v;
*pp += pend - p;
return true;
}
static bool
parse_float (const char **pp, const char *end, float *pv)
{
char buf[32];
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
strncpy (buf, *pp, len);
buf[len] = '\0';
char *p = buf;
char *pend = p;
float v;
errno = 0;
v = strtof (p, &pend);
if (errno || p == pend)
return false;
*pv = v;
*pp += pend - p;
return true;
}
static bool
parse_bool (const char **pp, const char *end, unsigned int *pv)
{
parse_space (pp, end);
const char *p = *pp;
while (*pp < end && ISALPHA(**pp))
(*pp)++;
/* CSS allows on/off as aliases 1/0. */
if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
*pv = 1;
else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
*pv = 0;
else
return false;
return true;
}
/* hb_feature_t */
static bool
parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
{
if (parse_char (pp, end, '-'))
feature->value = 0;
else {
parse_char (pp, end, '+');
feature->value = 1;
}
return true;
}
static bool
parse_tag (const char **pp, const char *end, hb_tag_t *tag)
{
parse_space (pp, end);
char quote = 0;
if (*pp < end && (**pp == '\'' || **pp == '"'))
{
quote = **pp;
(*pp)++;
}
const char *p = *pp;
while (*pp < end && ISALNUM(**pp))
(*pp)++;
if (p == *pp || *pp - p > 4)
return false;
*tag = hb_tag_from_string (p, *pp - p);
if (quote)
{
/* CSS expects exactly four bytes. And we only allow quotations for
* CSS compatibility. So, enforce the length. */
if (*pp - p != 4)
return false;
if (*pp == end || **pp != quote)
return false;
(*pp)++;
}
return true;
}
static bool
parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
{
parse_space (pp, end);
bool has_start;
feature->start = 0;
feature->end = (unsigned int) -1;
if (!parse_char (pp, end, '['))
return true;
has_start = parse_uint (pp, end, &feature->start);
if (parse_char (pp, end, ':')) {
parse_uint (pp, end, &feature->end);
} else {
if (has_start)
feature->end = feature->start + 1;
}
return parse_char (pp, end, ']');
}
static bool
parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
{
bool had_equal = parse_char (pp, end, '=');
bool had_value = parse_uint (pp, end, &feature->value) ||
parse_bool (pp, end, &feature->value);
/* CSS doesn't use equal-sign between tag and value.
* If there was an equal-sign, then there *must* be a value.
* A value without an eqaul-sign is ok, but not required. */
return !had_equal || had_value;
}
static bool
parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
{
return parse_feature_value_prefix (pp, end, feature) &&
parse_tag (pp, end, &feature->tag) &&
parse_feature_indices (pp, end, feature) &&
parse_feature_value_postfix (pp, end, feature) &&
parse_space (pp, end) &&
*pp == end;
}
/**
* hb_feature_from_string:
* @str: (array length=len) (element-type uint8_t): a string to parse
* @len: length of @str, or -1 if string is %NULL terminated
* @feature: (out): the #hb_feature_t to initialize with the parsed values
*
* Parses a string into a #hb_feature_t.
*
* TODO: document the syntax here.
*
* Return value:
* %true if @str is successfully parsed, %false otherwise.
*
* Since: 0.9.5
**/
hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature)
{
hb_feature_t feat;
if (len < 0)
len = strlen (str);
if (likely (parse_one_feature (&str, str + len, &feat)))
{
if (feature)
*feature = feat;
return true;
}
if (feature)
memset (feature, 0, sizeof (*feature));
return false;
}
/**
* hb_feature_to_string:
* @feature: an #hb_feature_t to convert
* @buf: (array length=size) (out): output string
* @size: the allocated size of @buf
*
* Converts a #hb_feature_t into a %NULL-terminated string in the format
* understood by hb_feature_from_string(). The client in responsible for
* allocating big enough size for @buf, 128 bytes is more than enough.
*
* Since: 0.9.5
**/
void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size)
{
if (unlikely (!size)) return;
char s[128];
unsigned int len = 0;
if (feature->value == 0)
s[len++] = '-';
hb_tag_to_string (feature->tag, s + len);
len += 4;
while (len && s[len - 1] == ' ')
len--;
if (feature->start != 0 || feature->end != (unsigned int) -1)
{
s[len++] = '[';
if (feature->start)
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
if (feature->end != feature->start + 1) {
s[len++] = ':';
if (feature->end != (unsigned int) -1)
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
}
s[len++] = ']';
}
if (feature->value > 1)
{
s[len++] = '=';
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
}
assert (len < ARRAY_LENGTH (s));
len = MIN (len, size - 1);
memcpy (buf, s, len);
buf[len] = '\0';
}
/* hb_variation_t */
static bool
parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
{
parse_char (pp, end, '='); /* Optional. */
return parse_float (pp, end, &variation->value);
}
static bool
parse_one_variation (const char **pp, const char *end, hb_variation_t *variation)
{
return parse_tag (pp, end, &variation->tag) &&
parse_variation_value (pp, end, variation) &&
parse_space (pp, end) &&
*pp == end;
}
/**
* hb_variation_from_string:
*
* Since: 1.4.2
*/
hb_bool_t
hb_variation_from_string (const char *str, int len,
hb_variation_t *variation)
{
hb_variation_t var;
if (len < 0)
len = strlen (str);
if (likely (parse_one_variation (&str, str + len, &var)))
{
if (variation)
*variation = var;
return true;
}
if (variation)
memset (variation, 0, sizeof (*variation));
return false;
}
/**
* hb_variation_to_string:
*
* Since: 1.4.2
*/
void
hb_variation_to_string (hb_variation_t *variation,
char *buf, unsigned int size)
{
if (unlikely (!size)) return;
char s[128];
unsigned int len = 0;
hb_tag_to_string (variation->tag, s + len);
len += 4;
while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value));
assert (len < ARRAY_LENGTH (s));
len = MIN (len, size - 1);
memcpy (buf, s, len);
buf[len] = '\0';
}

View File

@ -362,6 +362,42 @@ typedef struct hb_user_data_key_t {
typedef void (*hb_destroy_func_t) (void *user_data);
/* Font features and variations. */
typedef struct hb_feature_t {
hb_tag_t tag;
uint32_t value;
unsigned int start;
unsigned int end;
} hb_feature_t;
HB_EXTERN hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature);
HB_EXTERN void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size);
/**
* hb_variation_t:
*
* Since: 1.4.2
*/
typedef struct hb_variation_t {
hb_tag_t tag;
float value;
} hb_variation_t;
HB_EXTERN hb_bool_t
hb_variation_from_string (const char *str, int len,
hb_variation_t *variation);
HB_EXTERN void
hb_variation_to_string (hb_variation_t *variation,
char *buf, unsigned int size);
HB_END_DECLS
#endif /* HB_COMMON_H */

View File

@ -671,7 +671,7 @@ retry_getglyphs:
DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
malloc (maxGlyphCount * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES));
hr = analyzer->GetGlyphs (textString, textLength, fontFace, FALSE,
hr = analyzer->GetGlyphs (textString, textLength, fontFace, false,
isRightToLeft, &runHead->mScript, localeName, NULL, &dwFeatures,
featureRangeLengths, 1, maxGlyphCount, clusterMap, textProperties, glyphIndices,
glyphProperties, &glyphCount);
@ -719,7 +719,7 @@ retry_getglyphs:
hr = analyzer->GetGlyphPlacements (textString,
clusterMap, textProperties, textLength, glyphIndices,
glyphProperties, glyphCount, fontFace, fontEmSize,
FALSE, isRightToLeft, &runHead->mScript, localeName,
false, isRightToLeft, &runHead->mScript, localeName,
&dwFeatures, featureRangeLengths, 1,
glyphAdvances, glyphOffsets);
@ -915,7 +915,7 @@ _hb_directwrite_shape(hb_shape_plan_t *shape_plan,
*/
hb_bool_t
hb_shape_dwrite_experimental_width(hb_font_t *font,
hb_directwrite_shape_experimental_width(hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features,

View File

@ -30,7 +30,7 @@
HB_BEGIN_DECLS
HB_EXTERN hb_bool_t
hb_shape_dwrite_experimental_width(hb_font_t *font, hb_buffer_t *buffer,
hb_directwrite_shape_experimental_width(hb_font_t *font, hb_buffer_t *buffer,
const hb_feature_t *features, unsigned int num_features, float width);
HB_END_DECLS

View File

@ -50,12 +50,16 @@ struct hb_face_t {
void *user_data;
hb_destroy_func_t destroy;
unsigned int index;
mutable unsigned int upem;
mutable unsigned int num_glyphs;
unsigned int index; /* Face index in a collection, zero-based. */
mutable unsigned int upem; /* Units-per-EM. */
mutable unsigned int num_glyphs; /* Number of glyphs. */
struct hb_shaper_data_t shaper_data;
struct hb_shaper_data_t shaper_data; /* Various shaper data. */
/* Various non-shaping data. */
/* ... */
/* Cache */
struct plan_node_t {
hb_shape_plan_t *shape_plan;
plan_node_t *next;

View File

@ -28,15 +28,11 @@
#include "hb-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
#include "hb-face-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
#include <string.h>
/*
* hb_face_t

View File

@ -28,14 +28,7 @@
#include "hb-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
#include <string.h>
/*
@ -1543,30 +1536,112 @@ hb_font_get_ppem (hb_font_t *font,
if (y_ppem) *y_ppem = font->y_ppem;
}
/*
* Variations
*/
static void
_hb_font_adopt_var_coords_normalized (hb_font_t *font,
int *coords, /* 2.14 normalized */
unsigned int coords_length)
{
free (font->coords);
font->coords = coords;
font->num_coords = coords_length;
}
/**
* hb_font_set_variations:
*
* Since: 1.4.2
*/
void
hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,
unsigned int variations_length)
{
if (font->immutable)
return;
if (!variations_length)
{
hb_font_set_var_coords_normalized (font, NULL, 0);
return;
}
unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL;
if (unlikely (coords_length && !normalized))
return;
hb_ot_var_normalize_variations (font->face,
variations, variations_length,
normalized, coords_length);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
/**
* hb_font_set_var_coords_design:
*
* Since: 1.4.2
*/
void
hb_font_set_var_coords_design (hb_font_t *font,
const float *coords,
unsigned int coords_length)
{
if (font->immutable)
return;
int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL;
if (unlikely (coords_length && !normalized))
return;
hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
/**
* hb_font_set_var_coords_normalized:
*
* Since: 1.4.2
*/
void
hb_font_set_var_coords_normalized (hb_font_t *font,
int *coords, /* XXX 2.14 normalized */
const int *coords, /* 2.14 normalized */
unsigned int coords_length)
{
if (font->immutable)
return;
/* Skip tail zero entries. */
while (coords_length && !coords[coords_length - 1])
coords_length--;
int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL;
if (unlikely (coords_length && !copy))
return;
free (font->coords);
if (coords_length)
memcpy (copy, coords, coords_length * sizeof (coords[0]));
font->coords = copy;
font->num_coords = coords_length;
_hb_font_adopt_var_coords_normalized (font, copy, coords_length);
}
/**
* hb_font_set_var_coords_normalized:
*
* Return value is valid as long as variation coordinates of the font
* are not modified.
*
* Since: 1.4.2
*/
const int *
hb_font_get_var_coords_normalized (hb_font_t *font,
unsigned int *length)
{
if (length)
*length = font->num_coords;
return font->coords;
}

View File

@ -603,12 +603,25 @@ hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem);
HB_EXTERN void
hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,
unsigned int variations_length);
HB_EXTERN void
hb_font_set_var_coords_design (hb_font_t *font,
const float *coords,
unsigned int coords_length);
HB_EXTERN void
hb_font_set_var_coords_normalized (hb_font_t *font,
int *coords, /* XXX 2.14 normalized */
const int *coords, /* 2.14 normalized */
unsigned int coords_length);
HB_EXTERN const int *
hb_font_get_var_coords_normalized (hb_font_t *font,
unsigned int *length);
HB_END_DECLS
#endif /* HB_FONT_H */

View File

@ -621,17 +621,22 @@ hb_ft_font_create (FT_Face ft_face,
FT_MM_Var *mm_var = NULL;
if (!FT_Get_MM_Var (ft_face, &mm_var))
{
FT_Fixed coords[mm_var->num_axis];
int hbCoords[mm_var->num_axis];
if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, coords))
FT_Fixed *ft_coords = (FT_Fixed *) calloc (mm_var->num_axis, sizeof (FT_Fixed));
int *coords = (int *) calloc (mm_var->num_axis, sizeof (int));
if (coords && ft_coords)
{
for (int i = 0; i < mm_var->num_axis; ++i)
hbCoords[i] = coords[i] >> 2;
if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords))
{
for (unsigned int i = 0; i < mm_var->num_axis; ++i)
coords[i] = ft_coords[i] >>= 2;
hb_font_set_var_coords_normalized (font, hbCoords, mm_var->num_axis);
hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
}
free (coords);
free (ft_coords);
}
free (mm_var);
}
free (mm_var);
#endif
return font;
@ -736,6 +741,20 @@ hb_ft_font_set_funcs (hb_font_t *font)
FT_Set_Transform (ft_face, &matrix, NULL);
}
unsigned int num_coords;
const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
if (num_coords)
{
FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed));
if (ft_coords)
{
for (unsigned int i = 0; i < num_coords; i++)
ft_coords[i] = coords[i] << 2;
FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
free (ft_coords);
}
}
ft_face->generic.data = blob;
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;

View File

@ -142,7 +142,7 @@ struct TTCHeaderVersion1
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
FixedVersion<>version; /* Version of the TTC Header (1.0),
* 0x00010000u */
ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG>
ArrayOf<LOffsetTo<OffsetTable>, ULONG>
table; /* Array of offsets to the OffsetTable for each font
* from the beginning of the file */
public:

View File

@ -30,6 +30,7 @@
#define HB_OPEN_TYPE_PRIVATE_HH
#include "hb-private.hh"
#include "hb-face-private.hh"
namespace OT {
@ -829,6 +830,7 @@ struct OffsetTo : Offset<OffsetType>
}
DEFINE_SIZE_STATIC (sizeof(OffsetType));
};
template <typename Type> struct LOffsetTo : OffsetTo<Type, ULONG> {};
template <typename Base, typename OffsetType, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
template <typename Base, typename OffsetType, typename Type>
@ -950,6 +952,7 @@ struct ArrayOf
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
};
template <typename Type> struct LArrayOf : ArrayOf<Type, ULONG> {};
/* Array of Offset's */
template <typename Type, typename OffsetType=USHORT>
@ -1061,6 +1064,104 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
};
/* Lazy struct and blob loaders. */
/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
template <typename T>
struct hb_lazy_loader_t
{
inline void init (hb_face_t *face_)
{
face = face_;
instance = NULL;
}
inline void fini (void)
{
if (instance && instance != &OT::Null(T))
{
instance->fini();
free (instance);
}
}
inline const T* get (void) const
{
retry:
T *p = (T *) hb_atomic_ptr_get (&instance);
if (unlikely (!p))
{
p = (T *) calloc (1, sizeof (T));
if (unlikely (!p))
p = const_cast<T *> (&OT::Null(T));
else
p->init (face);
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p)))
{
if (p != &OT::Null(T))
p->fini ();
goto retry;
}
}
return p;
}
inline const T* operator-> (void) const
{
return get ();
}
private:
hb_face_t *face;
T *instance;
};
/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
template <typename T>
struct hb_lazy_table_loader_t
{
inline void init (hb_face_t *face_)
{
face = face_;
instance = NULL;
blob = NULL;
}
inline void fini (void)
{
hb_blob_destroy (blob);
}
inline const T* get (void) const
{
retry:
T *p = (T *) hb_atomic_ptr_get (&instance);
if (unlikely (!p))
{
hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag));
p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p))
{
hb_blob_destroy (blob_);
goto retry;
}
blob = blob_;
}
return p;
}
inline const T* operator-> (void) const
{
return get();
}
private:
hb_face_t *face;
T *instance;
mutable hb_blob_t *blob;
};
} /* namespace OT */

View File

@ -216,7 +216,7 @@ struct IndexSubtableRecord
USHORT firstGlyphIndex;
USHORT lastGlyphIndex;
OffsetTo<IndexSubtable, ULONG> offsetToSubtable;
LOffsetTo<IndexSubtable> offsetToSubtable;
DEFINE_SIZE_STATIC(8);
};
@ -275,7 +275,7 @@ struct BitmapSizeTable
}
protected:
OffsetTo<IndexSubtableArray, ULONG> indexSubtableArrayOffset;
LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
ULONG indexTablesSize;
ULONG numberOfIndexSubtables;
ULONG colorRef;
@ -348,8 +348,8 @@ struct CBLC
}
protected:
FixedVersion<>version;
ArrayOf<BitmapSizeTable, ULONG> sizeTables;
FixedVersion<> version;
LArrayOf<BitmapSizeTable> sizeTables;
public:
DEFINE_SIZE_ARRAY(8, sizeTables);

View File

@ -380,9 +380,9 @@ struct VariationSelectorRecord
}
UINT24 varSelector; /* Variation selector. */
OffsetTo<DefaultUVS, ULONG>
LOffsetTo<DefaultUVS>
defaultUVS; /* Offset to Default UVS Table. May be 0. */
OffsetTo<NonDefaultUVS, ULONG>
LOffsetTo<NonDefaultUVS>
nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
public:
DEFINE_SIZE_STATIC (11);
@ -486,7 +486,7 @@ struct EncodingRecord
USHORT platformID; /* Platform ID. */
USHORT encodingID; /* Platform-specific encoding ID. */
OffsetTo<CmapSubtable, ULONG>
LOffsetTo<CmapSubtable>
subtable; /* Byte offset from beginning of table to the subtable for this encoding. */
public:
DEFINE_SIZE_STATIC (8);

View File

@ -37,6 +37,7 @@
#include "hb-ot-hhea-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-var-hvar-table.hh"
//#include "hb-ot-post-table.hh"
@ -50,12 +51,16 @@ struct hb_ot_face_metrics_accelerator_t
unsigned short line_gap;
bool has_font_extents;
const OT::_mtx *table;
const OT::hmtxvmtx *table;
hb_blob_t *blob;
const OT::HVARVVAR *var;
hb_blob_t *var_blob;
inline void init (hb_face_t *face,
hb_tag_t _hea_tag,
hb_tag_t _mtx_tag,
hb_tag_t _var_tag,
hb_tag_t os2_tag,
unsigned int default_advance = 0)
{
@ -91,7 +96,7 @@ struct hb_ot_face_metrics_accelerator_t
this->has_font_extents = got_font_extents;
this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
this->blob = OT::Sanitizer<OT::hmtxvmtx>::sanitize (face->reference_table (_mtx_tag));
/* Cap num_metrics() and num_advances() based on table length. */
unsigned int len = hb_blob_get_length (this->blob);
@ -107,15 +112,20 @@ struct hb_ot_face_metrics_accelerator_t
hb_blob_destroy (this->blob);
this->blob = hb_blob_get_empty ();
}
this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob);
this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob);
this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag));
this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob);
}
inline void fini (void)
{
hb_blob_destroy (this->blob);
hb_blob_destroy (this->var_blob);
}
inline unsigned int get_advance (hb_codepoint_t glyph) const
inline unsigned int get_advance (hb_codepoint_t glyph,
hb_font_t *font) const
{
if (unlikely (glyph >= this->num_metrics))
{
@ -128,10 +138,8 @@ struct hb_ot_face_metrics_accelerator_t
return this->default_advance;
}
if (glyph >= this->num_advances)
glyph = this->num_advances - 1;
return this->table->longMetric[glyph].advance;
return this->table->longMetric[MIN (glyph, this->num_advances - 1)].advance
+ this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
}
};
@ -421,55 +429,13 @@ struct hb_ot_face_cmap_accelerator_t
}
};
template <typename T>
struct hb_lazy_loader_t
{
inline void init (hb_face_t *face_)
{
face = face_;
instance = NULL;
}
inline void fini (void)
{
if (instance && instance != &OT::Null(T))
{
instance->fini();
free (instance);
}
}
inline const T* operator-> (void) const
{
retry:
T *p = (T *) hb_atomic_ptr_get (&instance);
if (unlikely (!p))
{
p = (T *) calloc (1, sizeof (T));
if (unlikely (!p))
return &OT::Null(T);
p->init (face);
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p)))
{
p->fini ();
goto retry;
}
}
return p;
}
private:
hb_face_t *face;
T *instance;
};
struct hb_ot_font_t
{
hb_ot_face_cmap_accelerator_t cmap;
hb_ot_face_metrics_accelerator_t h_metrics;
hb_ot_face_metrics_accelerator_t v_metrics;
hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
};
@ -482,8 +448,8 @@ _hb_ot_font_create (hb_face_t *face)
return NULL;
ot_font->cmap.init (face);
ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2);
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE,
ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2);
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE,
ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
ot_font->glyf.init (face);
ot_font->cbdt.init (face);
@ -529,23 +495,23 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
}
static hb_position_t
hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
hb_ot_get_glyph_h_advance (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
return font->em_scale_x (ot_font->h_metrics.get_advance (glyph));
return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font));
}
static hb_position_t
hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
hb_ot_get_glyph_v_advance (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph));
return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font));
}
static hb_bool_t
@ -559,6 +525,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
bool ret = ot_font->glyf->get_extents (glyph, extents);
if (!ret)
ret = ot_font->cbdt->get_extents (glyph, extents);
// TODO Hook up side-bearings variations.
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);
extents->width = font->em_scale_x (extents->width);
@ -576,6 +543,7 @@ hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
// TODO Hook up variations.
return ot_font->h_metrics.has_font_extents;
}
@ -589,6 +557,7 @@ hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
// TODO Hook up variations.
return ot_font->v_metrics.has_font_extents;
}

View File

@ -50,10 +50,8 @@ struct LongMetric
DEFINE_SIZE_STATIC (4);
};
struct _mtx
struct hmtxvmtx
{
static const hb_tag_t tableTag = HB_TAG('_','m','t','x');
static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
@ -91,10 +89,10 @@ struct _mtx
DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
};
struct hmtx : _mtx {
struct hmtx : hmtxvmtx {
static const hb_tag_t tableTag = HB_OT_TAG_hmtx;
};
struct vmtx : _mtx {
struct vmtx : hmtxvmtx {
static const hb_tag_t tableTag = HB_OT_TAG_vmtx;
};

View File

@ -1323,6 +1323,14 @@ struct VariationStore
this+regions);
}
inline float get_delta (unsigned int index,
int *coords, unsigned int coord_count) const
{
unsigned int outer = index >> 16;
unsigned int inner = index & 0xFFFF;
return get_delta (outer, inner, coords, coord_count);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -1334,7 +1342,7 @@ struct VariationStore
protected:
USHORT format;
OffsetTo<VarRegionList, ULONG> regions;
LOffsetTo<VarRegionList> regions;
OffsetArrayOf<VarData, ULONG> dataSets;
public:
DEFINE_SIZE_ARRAY (8, dataSets);
@ -1433,8 +1441,8 @@ struct FeatureTableSubstitutionRecord
}
protected:
USHORT featureIndex;
OffsetTo<Feature, ULONG> feature;
USHORT featureIndex;
LOffsetTo<Feature> feature;
public:
DEFINE_SIZE_STATIC (6);
};
@ -1481,9 +1489,9 @@ struct FeatureVariationRecord
}
protected:
OffsetTo<ConditionSet, ULONG>
LOffsetTo<ConditionSet>
conditions;
OffsetTo<FeatureTableSubstitution, ULONG>
LOffsetTo<FeatureTableSubstitution>
substitutions;
public:
DEFINE_SIZE_STATIC (8);
@ -1527,7 +1535,7 @@ struct FeatureVariations
protected:
FixedVersion<> version; /* Version--0x00010000u */
ArrayOf<FeatureVariationRecord, ULONG>
LArrayOf<FeatureVariationRecord>
varRecords;
public:
DEFINE_SIZE_ARRAY (8, varRecords);

View File

@ -295,7 +295,7 @@ struct MarkGlyphSetsFormat1
protected:
USHORT format; /* Format identifier--format = 1 */
ArrayOf<OffsetTo<Coverage, ULONG> >
ArrayOf<LOffsetTo<Coverage> >
coverage; /* Array of long offsets to mark set
* coverage tables */
public:
@ -443,7 +443,7 @@ struct GDEF
* definitions--from beginning of GDEF
* header (may be NULL). Introduced
* in version 0x00010002. */
OffsetTo<VariationStore, ULONG>
LOffsetTo<VariationStore>
varStore; /* Offset to the table of Item Variation
* Store--from beginning of GDEF
* header (may be NULL). Introduced

View File

@ -2313,7 +2313,7 @@ struct GSUBGPOS
featureList; /* FeatureList table */
OffsetTo<LookupList>
lookupList; /* LookupList table */
OffsetTo<FeatureVariations, ULONG>
LOffsetTo<FeatureVariations>
featureVars; /* Offset to Feature Variations
table--from beginning of table
* (may be NULL). Introduced

View File

@ -34,6 +34,7 @@
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
#include "hb-set-private.hh"
#include "hb-open-type-private.hh"
/* Private API corresponding to hb-ot-layout.h: */
@ -125,6 +126,8 @@ namespace OT {
struct GSUB;
struct GPOS;
struct MATH;
struct fvar;
struct avar;
}
struct hb_ot_layout_lookup_accelerator_t
@ -153,12 +156,15 @@ struct hb_ot_layout_t
hb_blob_t *gdef_blob;
hb_blob_t *gsub_blob;
hb_blob_t *gpos_blob;
hb_blob_t *math_blob;
const struct OT::GDEF *gdef;
const struct OT::GSUB *gsub;
const struct OT::GPOS *gpos;
const struct OT::MATH *math;
/* TODO Move the following out of this struct. */
OT::hb_lazy_table_loader_t<struct OT::MATH> math;
OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
OT::hb_lazy_table_loader_t<struct OT::avar> avar;
unsigned int gsub_lookup_count;
unsigned int gpos_lookup_count;

View File

@ -34,13 +34,10 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-layout-jstf-table.hh"
#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-map-private.hh"
#include <stdlib.h>
#include <string.h>
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
@ -60,9 +57,9 @@ _hb_ot_layout_create (hb_face_t *face)
layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
/* The MATH table is rarely used, so only try and load it in _get_math. */
layout->math_blob = NULL;
layout->math = NULL;
layout->math.init (face);
layout->fvar.init (face);
layout->avar.init (face);
{
/*
@ -181,7 +178,10 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
hb_blob_destroy (layout->gdef_blob);
hb_blob_destroy (layout->gsub_blob);
hb_blob_destroy (layout->gpos_blob);
hb_blob_destroy (layout->math_blob);
layout->math.fini ();
layout->fvar.fini ();
layout->avar.fini ();
free (layout);
}

View File

@ -24,8 +24,8 @@
* Igalia Author(s): Frédéric Wang
*/
#ifndef HB_OT_LAYOUT_MATH_TABLE_HH
#define HB_OT_LAYOUT_MATH_TABLE_HH
#ifndef HB_OT_MATH_TABLE_HH
#define HB_OT_MATH_TABLE_HH
#include "hb-open-type-private.hh"
#include "hb-ot-layout-common-private.hh"
@ -716,7 +716,7 @@ struct MATH
DEFINE_SIZE_STATIC (10);
};
} /* mathspace OT */
} /* namespace OT */
#endif /* HB_OT_LAYOUT_MATH_TABLE_HH */
#endif /* HB_OT_MATH_TABLE_HH */

View File

@ -26,7 +26,7 @@
#include "hb-open-type-private.hh"
#include "hb-ot-layout-math-table.hh"
#include "hb-ot-math-table.hh"
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
@ -34,25 +34,8 @@ static inline const OT::MATH&
_get_math (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH);
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
retry:
const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math);
if (unlikely (!math))
{
hb_blob_t *blob = OT::Sanitizer<OT::MATH>::sanitize (face->reference_table (HB_OT_TAG_MATH));
math = OT::Sanitizer<OT::MATH>::lock_instance (blob);
if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math))
{
hb_blob_destroy (blob);
goto retry;
}
layout->math_blob = blob;
}
return *math;
return *(layout->math.get ());
}
/*
@ -64,10 +47,9 @@ retry:
* @face: #hb_face_t to test
*
* This function allows to verify the presence of an OpenType MATH table on the
* face. If so, such a table will be loaded into memory and sanitized. You can
* then safely call other functions for math layout and shaping.
* face.
*
* Return value: #TRUE if face has a MATH table and #FALSE otherwise
* Return value: true if face has a MATH table, false otherwise
*
* Since: 1.3.3
**/
@ -136,10 +118,10 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
/**
* hb_ot_math_is_glyph_extended_shape:
* @font: a #hb_font_t to test
* @face: a #hb_face_t to test
* @glyph: a glyph index to test
*
* Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise
* Return value: true if the glyph is an extended shape, false otherwise
*
* Since: 1.3.3
**/

View File

@ -32,7 +32,7 @@
/* Same order as the feature array below */
enum {
NONE,
_JMO,
LJMO,
VJMO,

View File

@ -572,28 +572,6 @@ decompose_use (const hb_ot_shape_normalize_context_t *c,
*/
case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true;
case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true;
/*
* Decompose split matras that don't have Unicode decompositions.
*/
/* Limbu */
case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true;
case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true;
/* Balinese */
case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true;
#if 0
/* Lepcha */
case 0x1C29u : *a = no decomp, -> LEFT; return true;
/* Javanese */
case 0xA9C0u : *a = no decomp, -> RIGHT; return true;
/* Sharada */
case 0x111BFu : *a = no decomp, -> ABOVE; return true;
#endif
}
return (bool) c->unicode->decompose (ab, a, b);

View File

@ -362,6 +362,18 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
hb_buffer_t *buffer = c->buffer;
hb_mask_t pre_mask, post_mask;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
{
pre_mask = c->plan->numr_mask | c->plan->frac_mask;
post_mask = c->plan->frac_mask | c->plan->dnom_mask;
}
else
{
pre_mask = c->plan->frac_mask | c->plan->dnom_mask;
post_mask = c->plan->numr_mask | c->plan->frac_mask;
}
/* TODO look in pre/post context text also. */
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
@ -380,10 +392,10 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
end++;
for (unsigned int j = start; j < i; j++)
info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
info[j].mask |= pre_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;
info[j].mask |= post_mask;
i = end - 1;
}

View File

@ -28,9 +28,6 @@
#include "hb-private.hh"
#include <string.h>
/* hb_script_t */
@ -201,6 +198,7 @@ static const LangTag ot_languages[] = {
{"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
{"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
{"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic */
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
{"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
@ -239,6 +237,7 @@ static const LangTag ot_languages[] = {
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
{"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */
{"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
{"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
{"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
@ -270,8 +269,10 @@ static const LangTag ot_languages[] = {
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
{"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */
{"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
{"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
{"cfm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin */
{"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
{"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
@ -279,8 +280,17 @@ static const LangTag ot_languages[] = {
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
{"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
{"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */
{"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */
{"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin */
{"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic */
{"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin */
{"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin */
{"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin */
{"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin */
{"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cpp", HB_TAG('C','P','P',' ')}, /* Creoles */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
@ -293,6 +303,9 @@ static const LangTag ot_languages[] = {
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
{"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
{"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin */
{"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin */
{"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin */
{"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
{"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
@ -300,7 +313,9 @@ static const LangTag ot_languages[] = {
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
{"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
{"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin */
{"da", HB_TAG('D','A','N',' ')}, /* Danish */
{"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin */
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
{"dax", HB_TAG('D','A','X',' ')}, /* Dayi */
@ -343,7 +358,7 @@ static const LangTag ot_languages[] = {
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
{"flm", HB_TAG('H','A','L',' ')}, /* Halam */
{"flm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin [retired ISO639 code] */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
@ -390,6 +405,7 @@ static const LangTag ot_languages[] = {
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
{"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin */
{"hmn", HB_TAG('H','M','N',' ')}, /* Hmong */
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
@ -553,6 +569,7 @@ static const LangTag ot_languages[] = {
{"mos", HB_TAG('M','O','S',' ')}, /* Mossi */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
{"mrh", HB_TAG('Q','I','N',' ')}, /* Mara Chin */
{"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
{"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */
@ -617,6 +634,7 @@ static const LangTag ot_languages[] = {
{"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */
{"pcd", HB_TAG('P','C','D',' ')}, /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
{"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin */
{"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */
{"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */
{"phk", HB_TAG('P','H','K',' ')}, /* Phake */
@ -674,6 +692,7 @@ static const LangTag ot_languages[] = {
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
{"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin */
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
{"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */
{"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */
@ -713,12 +732,15 @@ static const LangTag ot_languages[] = {
{"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */
{"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */
{"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */
{"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac */
{"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */
{"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
{"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
{"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin */
{"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
@ -786,11 +808,13 @@ static const LangTag ot_languages[] = {
{"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
{"yos", HB_TAG('Q','I','N',' ')}, /* Yos, deprecated by IANA in favor of Zou [zom] */
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
{"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */
{"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */
{"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Morrocan Tamazigh */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
{"zom", HB_TAG('Q','I','N',' ')}, /* Zou */
{"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */
{"zum", HB_TAG('L','R','C',' ')}, /* Kumzari */
{"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki */
@ -907,6 +931,30 @@ hb_ot_tag_from_language (hb_language_t language)
return HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */
}
/*
* "Syre" is a BCP-47 script tag, meaning the Estrangela variant of the Syriac script.
* It can be applied to any language.
*/
if (strstr (lang_str, "-syre")) {
return HB_TAG('S','Y','R','E'); /* Estrangela Syriac */
}
/*
* "Syrj" is a BCP-47 script tag, meaning the Western variant of the Syriac script.
* It can be applied to any language.
*/
if (strstr (lang_str, "-syrj")) {
return HB_TAG('S','Y','R','J'); /* Western Syriac */
}
/*
* "Syrn" is a BCP-47 script tag, meaning the Eastern variant of the Syriac script.
* It can be applied to any language.
*/
if (strstr (lang_str, "-syrn")) {
return HB_TAG('S','Y','R','N'); /* Eastern Syriac */
}
/* Find a language matching in the first component */
{
const LangTag *lang_tag;
@ -962,6 +1010,22 @@ hb_ot_tag_to_language (hb_tag_t tag)
if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
return NULL;
/* struct LangTag has only room for 3-letter language tags. */
switch (tag) {
case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
return hb_language_from_string ("und-fonnapa", -1);
case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
return hb_language_from_string ("und-fonipa", -1);
case HB_TAG('S','Y','R',' '): /* Syriac [macrolanguage] */
return hb_language_from_string ("syr", -1);
case HB_TAG('S','Y','R','E'): /* Estrangela Syriac */
return hb_language_from_string ("und-Syre", -1);
case HB_TAG('S','Y','R','J'): /* Western Syriac */
return hb_language_from_string ("und-Syrj", -1);
case HB_TAG('S','Y','R','N'): /* Eastern Syriac */
return hb_language_from_string ("und-Syrn", -1);
}
for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
if (ot_languages[i].tag == tag)
return hb_language_from_string (ot_languages[i].language, -1);
@ -976,14 +1040,6 @@ hb_ot_tag_to_language (hb_tag_t tag)
}
}
/* struct LangTag has only room for 3-letter language tags. */
switch (tag) {
case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
return hb_language_from_string ("und-fonnapa", -1);
case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
return hb_language_from_string ("und-fonipa", -1);
}
/* Else return a custom language in the form of "x-hbotABCD" */
{
unsigned char buf[11] = "x-hbot";

View File

@ -0,0 +1,144 @@
/*
* Copyright © 2017 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
*/
#ifndef HB_OT_VAR_AVAR_TABLE_HH
#define HB_OT_VAR_AVAR_TABLE_HH
#include "hb-open-type-private.hh"
namespace OT {
struct AxisValueMap
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
F2DOT14 fromCoord; /* A normalized coordinate value obtained using
* default normalization. */
F2DOT14 toCoord; /* The modified, normalized coordinate value. */
public:
DEFINE_SIZE_STATIC (4);
};
struct SegmentMaps : ArrayOf<AxisValueMap>
{
inline int map (int value) const
{
/* The following special-cases are not part of OpenType, which requires
* that at least -1, 0, and +1 must be mapped. But we include these as
* part of a better error recovery scheme. */
if (!len)
return value;
if (value <= array[0].fromCoord)
return value - array[0].fromCoord + array[0].toCoord;
unsigned int i;
unsigned int count = len;
for (i = 1; i < count && value > array[i].fromCoord; i++)
;
if (value >= array[i].fromCoord)
return value - array[i].fromCoord + array[i].toCoord;
if (unlikely (array[i-1].fromCoord == array[i].fromCoord))
return array[i-1].toCoord;
int denom = array[i].fromCoord - array[i-1].fromCoord;
return array[i-1].toCoord +
(array[i].toCoord - array[i-1].toCoord) *
(value - array[i-1].fromCoord + denom/2) / denom;
}
DEFINE_SIZE_ARRAY (2, array);
};
/*
* avar Axis Variations Table
*/
#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
struct avar
{
static const hb_tag_t tableTag = HB_OT_TAG_avar;
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!(version.sanitize (c) &&
version.major == 1 &&
c->check_struct (this))))
return_trace (false);
const SegmentMaps *map = &axisSegmentMapsZ;
unsigned int count = axisCount;
for (unsigned int i = 0; i < count; i++)
{
if (unlikely (!map->sanitize (c)))
return_trace (false);
map = &StructAfter<SegmentMaps> (*map);
}
return_trace (true);
}
inline void map_coords (int *coords, unsigned int coords_length) const
{
unsigned int count = MIN<unsigned int> (coords_length, axisCount);
const SegmentMaps *map = &axisSegmentMapsZ;
for (unsigned int i = 0; i < count; i++)
{
coords[i] = map->map (coords[i]);
map = &StructAfter<SegmentMaps> (*map);
}
}
protected:
FixedVersion<>version; /* Version of the avar table
* initially set to 0x00010000u */
USHORT reserved; /* This field is permanently reserved. Set to 0. */
USHORT axisCount; /* The number of variation axes in the font. This
* must be the same number as axisCount in the
* 'fvar' table. */
SegmentMaps axisSegmentMapsZ;
public:
DEFINE_SIZE_MIN (8);
};
} /* namespace OT */
#endif /* HB_OT_VAR_AVAR_TABLE_HH */

View File

@ -0,0 +1,209 @@
/*
* Copyright © 2017 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
*/
#ifndef HB_OT_VAR_FVAR_TABLE_HH
#define HB_OT_VAR_FVAR_TABLE_HH
#include "hb-open-type-private.hh"
namespace OT {
struct InstanceRecord
{
inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_array (coordinates, coordinates[0].static_size, axis_count));
}
protected:
USHORT subfamilyNameID;/* The name ID for entries in the 'name' table
* that provide subfamily names for this instance. */
USHORT reserved; /* Reserved for future use — set to 0. */
Fixed coordinates[VAR];/* The coordinates array for this instance. */
//USHORT postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
// * table that provide PostScript names for this
// * instance. */
public:
DEFINE_SIZE_ARRAY (4, coordinates);
};
struct AxisRecord
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
Tag axisTag; /* Tag identifying the design variation for the axis. */
Fixed minValue; /* The minimum coordinate value for the axis. */
Fixed defaultValue; /* The default coordinate value for the axis. */
Fixed maxValue; /* The maximum coordinate value for the axis. */
USHORT reserved; /* Reserved for future use — set to 0. */
USHORT axisNameID; /* The name ID for entries in the 'name' table that
* provide a display name for this axis. */
public:
DEFINE_SIZE_STATIC (20);
};
/*
* fvar Font Variations Table
*/
#define HB_OT_TAG_fvar HB_TAG('f','v','a','r')
struct fvar
{
static const hb_tag_t tableTag = HB_OT_TAG_fvar;
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
likely (version.major == 1) &&
c->check_struct (this) &&
instanceSize >= axisCount * 4 + 4 &&
axisSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */
instanceSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */
c->check_range (this, things) &&
c->check_range (&StructAtOffset<char> (this, things),
axisCount * axisSize + instanceCount * instanceSize));
}
inline unsigned int get_axis_count (void) const
{ return axisCount; }
inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const
{
if (unlikely (index >= axisCount))
return false;
if (info)
{
const AxisRecord &axis = get_axes ()[index];
info->tag = axis.axisTag;
info->name_id = axis.axisNameID;
info->default_value = axis.defaultValue / 65536.;
/* Ensure order, to simplify client math. */
info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
}
return true;
}
inline unsigned int get_axis_infos (unsigned int start_offset,
unsigned int *axes_count /* IN/OUT */,
hb_ot_var_axis_t *axes_array /* OUT */) const
{
if (axes_count)
{
unsigned int count = axisCount;
start_offset = MIN (start_offset, count);
count -= start_offset;
axes_array += start_offset;
count = MIN (count, *axes_count);
*axes_count = count;
for (unsigned int i = 0; i < count; i++)
get_axis (start_offset + i, axes_array + i);
}
return axisCount;
}
inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const
{
const AxisRecord *axes = get_axes ();
unsigned int count = get_axis_count ();
for (unsigned int i = 0; i < count; i++)
if (axes[i].axisTag == tag)
{
if (index)
*index = i;
return get_axis (i, info);
}
if (index)
*index = HB_OT_VAR_NO_AXIS_INDEX;
return false;
}
inline int normalize_axis_value (unsigned int axis_index, float v) const
{
hb_ot_var_axis_t axis;
if (!get_axis (axis_index, &axis))
return 0;
v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
if (v == axis.default_value)
return 0;
else if (v < axis.default_value)
v = (v - axis.default_value) / (axis.default_value - axis.min_value);
else
v = (v - axis.default_value) / (axis.max_value - axis.default_value);
return (int) (v * 16384. + (v >= 0. ? .5 : -.5));
}
protected:
inline const AxisRecord * get_axes (void) const
{ return &StructAtOffset<AxisRecord> (this, things); }
inline const InstanceRecord * get_instances (void) const
{ return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); }
protected:
FixedVersion<>version; /* Version of the fvar table
* initially set to 0x00010000u */
Offset<> things; /* Offset in bytes from the beginning of the table
* to the start of the AxisRecord array. */
USHORT reserved; /* This field is permanently reserved. Set to 2. */
USHORT axisCount; /* The number of variation axes in the font (the
* number of records in the axes array). */
USHORT axisSize; /* The size in bytes of each VariationAxisRecord —
* set to 20 (0x0014) for this version. */
USHORT instanceCount; /* The number of named instances defined in the font
* (the number of records in the instances array). */
USHORT instanceSize; /* The size in bytes of each InstanceRecord — set
* to either axisCount * sizeof(Fixed) + 4, or to
* axisCount * sizeof(Fixed) + 6. */
public:
DEFINE_SIZE_STATIC (16);
};
} /* namespace OT */
#endif /* HB_OT_VAR_FVAR_TABLE_HH */

View File

@ -0,0 +1,165 @@
/*
* Copyright © 2017 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
*/
#ifndef HB_OT_VAR_HVAR_TABLE_HH
#define HB_OT_VAR_HVAR_TABLE_HH
#include "hb-ot-layout-common-private.hh"
namespace OT {
struct DeltaSetIndexMap
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_array (mapData, get_width (), mapCount));
}
unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
{
/* If count is zero, pass value unchanged. This takes
* care of direct mapping for advance map. */
if (!mapCount)
return v;
if (v >= mapCount)
v = mapCount - 1;
unsigned int u = 0;
{ /* Fetch it. */
unsigned int w = get_width ();
const BYTE *p = mapData + w * v;
for (; w; w--)
u = (u << 8) + *p++;
}
{ /* Repack it. */
unsigned int n = get_inner_bitcount ();
unsigned int outer = u >> n;
unsigned int inner = u & ((1 << n) - 1);
u = (outer<<16) | inner;
}
return u;
}
protected:
inline unsigned int get_width (void) const
{ return ((format >> 4) & 3) + 1; }
inline unsigned int get_inner_bitcount (void) const
{ return (format & 0xF) + 1; }
protected:
USHORT format; /* A packed field that describes the compressed
* representation of delta-set indices. */
USHORT mapCount; /* The number of mapping entries. */
BYTE mapData[VAR]; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_ARRAY (4, mapData);
};
/*
* HVAR -- The Horizontal Metrics Variations Table
* VVAR -- The Vertical Metrics Variations Table
*/
#define HB_OT_TAG_HVAR HB_TAG('H','V','A','R')
#define HB_OT_TAG_VVAR HB_TAG('V','V','A','R')
struct HVARVVAR
{
static const hb_tag_t HVARTag = HB_OT_TAG_HVAR;
static const hb_tag_t VVARTag = HB_OT_TAG_VVAR;
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
likely (version.major == 1) &&
varStore.sanitize (c, this) &&
advMap.sanitize (c, this) &&
lsbMap.sanitize (c, this) &&
rsbMap.sanitize (c, this));
}
inline float get_advance_var (hb_codepoint_t glyph,
int *coords, unsigned int coord_count) const
{
unsigned int varidx = (this+advMap).map (glyph);
return (this+varStore).get_delta (varidx, coords, coord_count);
}
inline bool has_sidebearing_deltas (void) const
{ return lsbMap && rsbMap; }
protected:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */
LOffsetTo<VariationStore>
varStore; /* Offset to item variation store table. */
LOffsetTo<DeltaSetIndexMap>
advMap; /* Offset to advance var-idx mapping. */
LOffsetTo<DeltaSetIndexMap>
lsbMap; /* Offset to lsb/tsb var-idx mapping. */
LOffsetTo<DeltaSetIndexMap>
rsbMap; /* Offset to rsb/bsb var-idx mapping. */
public:
DEFINE_SIZE_STATIC (20);
};
struct HVAR : HVARVVAR {
static const hb_tag_t tableTag = HB_OT_TAG_HVAR;
};
struct VVAR : HVARVVAR {
static const hb_tag_t tableTag = HB_OT_TAG_VVAR;
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (static_cast<const HVARVVAR *> (this)->sanitize (c) &&
vorgMap.sanitize (c, this));
}
protected:
LOffsetTo<DeltaSetIndexMap>
vorgMap; /* Offset to vertical-origin var-idx mapping. */
public:
DEFINE_SIZE_STATIC (24);
};
} /* namespace OT */
#endif /* HB_OT_VAR_HVAR_TABLE_HH */

View File

@ -0,0 +1,160 @@
/*
* Copyright © 2017 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-open-type-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-ot-var-avar-table.hh"
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-var.h"
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
/*
* fvar/avar
*/
static inline const OT::fvar&
_get_fvar (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar);
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
return *(layout->fvar.get ());
}
static inline const OT::avar&
_get_avar (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar);
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
return *(layout->avar.get ());
}
/**
* hb_ot_var_has_data:
* @face: #hb_face_t to test
*
* This function allows to verify the presence of OpenType variation data on the face.
* Alternatively, use hb_ot_var_get_axis_count().
*
* Return value: true if face has a `fvar' table and false otherwise
*
* Since: 1.4.2
**/
hb_bool_t
hb_ot_var_has_data (hb_face_t *face)
{
return &_get_fvar (face) != &OT::Null(OT::fvar);
}
/**
* hb_ot_var_get_axis_count:
*
* Since: 1.4.2
**/
unsigned int
hb_ot_var_get_axis_count (hb_face_t *face)
{
const OT::fvar &fvar = _get_fvar (face);
return fvar.get_axis_count ();
}
/**
* hb_ot_var_get_axes:
*
* Since: 1.4.2
**/
unsigned int
hb_ot_var_get_axes (hb_face_t *face,
unsigned int start_offset,
unsigned int *axes_count /* IN/OUT */,
hb_ot_var_axis_t *axes_array /* OUT */)
{
const OT::fvar &fvar = _get_fvar (face);
return fvar.get_axis_infos (start_offset, axes_count, axes_array);
}
/**
* hb_ot_var_find_axis:
*
* Since: 1.4.2
**/
hb_bool_t
hb_ot_var_find_axis (hb_face_t *face,
hb_tag_t axis_tag,
unsigned int *axis_index,
hb_ot_var_axis_t *axis_info)
{
const OT::fvar &fvar = _get_fvar (face);
return fvar.find_axis (axis_tag, axis_index, axis_info);
}
/**
* hb_ot_var_normalize_variations:
*
* Since: 1.4.2
**/
void
hb_ot_var_normalize_variations (hb_face_t *face,
const hb_variation_t *variations, /* IN */
unsigned int variations_length,
int *coords, /* OUT */
unsigned int coords_length)
{
for (unsigned int i = 0; i < coords_length; i++)
coords[i] = 0;
const OT::fvar &fvar = _get_fvar (face);
for (unsigned int i = 0; i < variations_length; i++)
{
unsigned int axis_index;
if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, NULL) &&
axis_index < coords_length)
coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value);
}
const OT::avar &avar = _get_avar (face);
avar.map_coords (coords, coords_length);
}
/**
* hb_ot_var_normalize_coords:
*
* Since: 1.4.2
**/
void
hb_ot_var_normalize_coords (hb_face_t *face,
unsigned int coords_length,
const float *design_coords, /* IN */
int *normalized_coords /* OUT */)
{
const OT::fvar &fvar = _get_fvar (face);
for (unsigned int i = 0; i < coords_length; i++)
normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
const OT::avar &avar = _get_avar (face);
avar.map_coords (normalized_coords, coords_length);
}

View File

@ -0,0 +1,105 @@
/*
* Copyright © 2017 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.
*
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
#ifndef HB_OT_VAR_H
#define HB_OT_VAR_H
#include "hb.h"
HB_BEGIN_DECLS
#define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l')
#define HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_TAG('o','p','s','z')
#define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t')
#define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h')
#define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t')
/*
* fvar / avar
*/
/**
* hb_ot_var_axis_t:
*
* Since: 1.4.2
*/
typedef struct hb_ot_var_axis_t {
hb_tag_t tag;
unsigned int name_id;
float min_value;
float default_value;
float max_value;
} hb_ot_var_axis_t;
HB_EXTERN hb_bool_t
hb_ot_var_has_data (hb_face_t *face);
/**
* HB_OT_VAR_NO_AXIS_INDEX:
*
* Since: 1.4.2
*/
#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu
HB_EXTERN unsigned int
hb_ot_var_get_axis_count (hb_face_t *face);
HB_EXTERN unsigned int
hb_ot_var_get_axes (hb_face_t *face,
unsigned int start_offset,
unsigned int *axes_count /* IN/OUT */,
hb_ot_var_axis_t *axes_array /* OUT */);
HB_EXTERN hb_bool_t
hb_ot_var_find_axis (hb_face_t *face,
hb_tag_t axis_tag,
unsigned int *axis_index,
hb_ot_var_axis_t *axis_info);
HB_EXTERN void
hb_ot_var_normalize_variations (hb_face_t *face,
const hb_variation_t *variations, /* IN */
unsigned int variations_length,
int *coords, /* OUT */
unsigned int coords_length);
HB_EXTERN void
hb_ot_var_normalize_coords (hb_face_t *face,
unsigned int coords_length,
const float *design_coords, /* IN */
int *normalized_coords /* OUT */);
HB_END_DECLS
#endif /* HB_OT_VAR_H */

View File

@ -35,6 +35,7 @@
#include "hb-ot-math.h"
#include "hb-ot-tag.h"
#include "hb-ot-shape.h"
#include "hb-ot-var.h"
HB_BEGIN_DECLS

View File

@ -105,7 +105,7 @@ hb_set_destroy (hb_set_t *set)
* @set: a set.
* @key:
* @data:
* @destroy (closure data):
* @destroy:
* @replace:
*
* Return value:

View File

@ -45,254 +45,6 @@
* contains the output glyphs and their positions.
**/
static bool
parse_space (const char **pp, const char *end)
{
while (*pp < end && ISSPACE (**pp))
(*pp)++;
return true;
}
static bool
parse_char (const char **pp, const char *end, char c)
{
parse_space (pp, end);
if (*pp == end || **pp != c)
return false;
(*pp)++;
return true;
}
static bool
parse_uint (const char **pp, const char *end, unsigned int *pv)
{
char buf[32];
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
strncpy (buf, *pp, len);
buf[len] = '\0';
char *p = buf;
char *pend = p;
unsigned int v;
/* Intentionally use strtol instead of strtoul, such that
* -1 turns into "big number"... */
errno = 0;
v = strtol (p, &pend, 0);
if (errno || p == pend)
return false;
*pv = v;
*pp += pend - p;
return true;
}
static bool
parse_bool (const char **pp, const char *end, unsigned int *pv)
{
parse_space (pp, end);
const char *p = *pp;
while (*pp < end && ISALPHA(**pp))
(*pp)++;
/* CSS allows on/off as aliases 1/0. */
if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
*pv = 1;
else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
*pv = 0;
else
return false;
return true;
}
static bool
parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
{
if (parse_char (pp, end, '-'))
feature->value = 0;
else {
parse_char (pp, end, '+');
feature->value = 1;
}
return true;
}
static bool
parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
{
parse_space (pp, end);
char quote = 0;
if (*pp < end && (**pp == '\'' || **pp == '"'))
{
quote = **pp;
(*pp)++;
}
const char *p = *pp;
while (*pp < end && ISALNUM(**pp))
(*pp)++;
if (p == *pp || *pp - p > 4)
return false;
feature->tag = hb_tag_from_string (p, *pp - p);
if (quote)
{
/* CSS expects exactly four bytes. And we only allow quotations for
* CSS compatibility. So, enforce the length. */
if (*pp - p != 4)
return false;
if (*pp == end || **pp != quote)
return false;
(*pp)++;
}
return true;
}
static bool
parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
{
parse_space (pp, end);
bool has_start;
feature->start = 0;
feature->end = (unsigned int) -1;
if (!parse_char (pp, end, '['))
return true;
has_start = parse_uint (pp, end, &feature->start);
if (parse_char (pp, end, ':')) {
parse_uint (pp, end, &feature->end);
} else {
if (has_start)
feature->end = feature->start + 1;
}
return parse_char (pp, end, ']');
}
static bool
parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
{
bool had_equal = parse_char (pp, end, '=');
bool had_value = parse_uint (pp, end, &feature->value) ||
parse_bool (pp, end, &feature->value);
/* CSS doesn't use equal-sign between tag and value.
* If there was an equal-sign, then there *must* be a value.
* A value without an eqaul-sign is ok, but not required. */
return !had_equal || had_value;
}
static bool
parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
{
return parse_feature_value_prefix (pp, end, feature) &&
parse_feature_tag (pp, end, feature) &&
parse_feature_indices (pp, end, feature) &&
parse_feature_value_postfix (pp, end, feature) &&
parse_space (pp, end) &&
*pp == end;
}
/**
* hb_feature_from_string:
* @str: (array length=len) (element-type uint8_t): a string to parse
* @len: length of @str, or -1 if string is %NULL terminated
* @feature: (out): the #hb_feature_t to initialize with the parsed values
*
* Parses a string into a #hb_feature_t.
*
* TODO: document the syntax here.
*
* Return value:
* %true if @str is successfully parsed, %false otherwise.
*
* Since: 0.9.5
**/
hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature)
{
hb_feature_t feat;
if (len < 0)
len = strlen (str);
if (likely (parse_one_feature (&str, str + len, &feat)))
{
if (feature)
*feature = feat;
return true;
}
if (feature)
memset (feature, 0, sizeof (*feature));
return false;
}
/**
* hb_feature_to_string:
* @feature: an #hb_feature_t to convert
* @buf: (array length=size) (out): output string
* @size: the allocated size of @buf
*
* Converts a #hb_feature_t into a %NULL-terminated string in the format
* understood by hb_feature_from_string(). The client in responsible for
* allocating big enough size for @buf, 128 bytes is more than enough.
*
* Since: 0.9.5
**/
void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size)
{
if (unlikely (!size)) return;
char s[128];
unsigned int len = 0;
if (feature->value == 0)
s[len++] = '-';
hb_tag_to_string (feature->tag, s + len);
len += 4;
while (len && s[len - 1] == ' ')
len--;
if (feature->start != 0 || feature->end != (unsigned int) -1)
{
s[len++] = '[';
if (feature->start)
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
if (feature->end != feature->start + 1) {
s[len++] = ':';
if (feature->end != (unsigned int) -1)
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
}
s[len++] = ']';
}
if (feature->value > 1)
{
s[len++] = '=';
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
}
assert (len < ARRAY_LENGTH (s));
len = MIN (len, size - 1);
memcpy (buf, s, len);
buf[len] = '\0';
}
static const char **static_shaper_list;
#ifdef HB_USE_ATEXIT
@ -362,7 +114,7 @@ retry:
* shapers will be used in the given order, otherwise the default shapers list
* will be used.
*
* Return value: %FALSE if all shapers failed, %TRUE otherwise
* Return value: false if all shapers failed, true otherwise
*
* Since: 0.9.2
**/

View File

@ -40,22 +40,6 @@
HB_BEGIN_DECLS
typedef struct hb_feature_t {
hb_tag_t tag;
uint32_t value;
unsigned int start;
unsigned int end;
} hb_feature_t;
HB_EXTERN hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature);
HB_EXTERN void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size);
HB_EXTERN void
hb_shape (hb_font_t *font,
hb_buffer_t *buffer,

View File

@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 1
#define HB_VERSION_MINOR 4
#define HB_VERSION_MICRO 1
#define HB_VERSION_MICRO 2
#define HB_VERSION_STRING "1.4.1"
#define HB_VERSION_STRING "1.4.2"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \

View File

@ -16,6 +16,7 @@ EXPORTS.harfbuzz += [
'hb-ot-math.h',
'hb-ot-shape.h',
'hb-ot-tag.h',
'hb-ot-var.h',
'hb-ot.h',
'hb-set.h',
'hb-shape-plan.h',
@ -54,6 +55,7 @@ UNIFIED_SOURCES += [
'hb-ot-shape-fallback.cc',
'hb-ot-shape-normalize.cc',
'hb-ot-tag.cc',
'hb-ot-var.cc',
'hb-set.cc',
'hb-shape.cc',
'hb-shaper.cc',