[HarfBuzz] harfbuzz: Branch 'master' - 5 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Aug 23 21:42:43 PDT 2012
configure.ac | 9
src/Makefile.am | 8
src/hb-graphite2.cc | 77 +++--
src/hb-icu-le.cc | 213 +++++++++++++++
src/hb-icu-le/FontTableCache.cpp | 91 ++++++
src/hb-icu-le/FontTableCache.h | 44 +++
src/hb-icu-le/Makefile.am | 25 +
src/hb-icu-le/PortableFontInstance.cpp | 307 ++++++++++++++++++++++
src/hb-icu-le/PortableFontInstance.h | 112 ++++++++
src/hb-icu-le/README | 3
src/hb-icu-le/cmaps.cpp | 200 ++++++++++++++
src/hb-icu-le/cmaps.h | 84 ++++++
src/hb-icu-le/letest.h | 49 +++
src/hb-icu-le/license.html | 51 +++
src/hb-icu-le/sfnt.h | 449 +++++++++++++++++++++++++++++++++
src/hb-shaper-list.hh | 4
16 files changed, 1693 insertions(+), 33 deletions(-)
New commits:
commit 56e878ab875ff06d74702145e380e198be967bd6
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Aug 24 00:41:51 2012 -0400
[graphite2] Cleanup scratch buffer allocation
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index a30c42e..6c890d4 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -211,11 +211,6 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
gr_font *grfont = HB_SHAPER_DATA_GET (font);
- unsigned int charlen;
- hb_glyph_info_t *bufferi = hb_buffer_get_glyph_infos (buffer, &charlen);
-
- int success = 0;
-
const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
const char *lang_end = strchr (lang, '-');
int lang_len = lang_end ? lang_end - lang : -1;
@@ -229,24 +224,23 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
features++;
}
- /* TODO Use scratch buffer for these. */
- hb_codepoint_t *gids = NULL, *pg;
- hb_graphite2_cluster_t *clusters = NULL;
gr_segment *seg = NULL;
- uint32_t *text = NULL;
const gr_slot *is;
unsigned int ci = 0, ic = 0;
float curradvx = 0., curradvy = 0.;
- unsigned int glyphlen = 0;
- unsigned int *p;
- text = (uint32_t *) malloc ((charlen + 1) * sizeof (uint32_t));
- if (!text) goto dieout;
+ unsigned int scratch_size;
+ char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+ Type *name = (Type *) scratch; \
+ scratch += (len) * sizeof ((name)[0]); \
+ scratch_size -= (len) * sizeof ((name)[0]);
+
+ ALLOCATE_ARRAY (uint32_t, chars, buffer->len);
- p = text;
- for (unsigned int i = 0; i < charlen; ++i)
- *p++ = bufferi++->codepoint;
- *p = 0;
+ for (unsigned int i = 0; i < buffer->len; ++i)
+ chars[i] = buffer->info[i].codepoint;
hb_tag_t script_tag[2];
hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
@@ -254,18 +248,40 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
seg = gr_make_seg (grfont, grface,
script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
feats,
- gr_utf32, text, charlen,
+ gr_utf32, chars, buffer->len,
2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
- if (!seg) goto dieout;
- glyphlen = gr_seg_n_slots (seg);
- clusters = (hb_graphite2_cluster_t *) calloc (charlen, sizeof (hb_graphite2_cluster_t));
- if (!glyphlen || !clusters) goto dieout;
+ if (unlikely (!seg)) {
+ if (feats) gr_featureval_destroy (feats);
+ return false;
+ }
+
+ unsigned int glyph_count = gr_seg_n_slots (seg);
+ if (unlikely (!glyph_count)) {
+ if (feats) gr_featureval_destroy (feats);
+ gr_seg_destroy (seg);
+ return false;
+ }
+
+ scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+ while ((sizeof (hb_graphite2_cluster_t) * buffer->len +
+ sizeof (hb_codepoint_t) * glyph_count) > scratch_size)
+ {
+ buffer->ensure (buffer->allocated * 2);
+ if (unlikely (buffer->in_error)) {
+ if (feats) gr_featureval_destroy (feats);
+ gr_seg_destroy (seg);
+ return false;
+ }
+ scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+ }
- gids = (hb_codepoint_t *) malloc (glyphlen * sizeof (hb_codepoint_t));
- if (!gids) goto dieout;
+ ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
+ ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
- pg = gids;
+ memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
+
+ hb_codepoint_t *pg = gids;
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
{
unsigned int before = gr_slot_before (is);
@@ -325,13 +341,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
hb_buffer_reverse_clusters (buffer);
- success = 1;
-
-dieout:
if (feats) gr_featureval_destroy (feats);
- if (gids) free (gids);
- if (clusters) free (clusters);
- if (seg) gr_seg_destroy (seg);
- if (text) free (text);
- return success;
+ gr_seg_destroy (seg);
+
+ return true;
}
commit 2f7586c6229096143ca0a96712a27416ee0d3c85
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 23 23:59:55 2012 -0400
[icu-le] Implement icu layout engine shaper
diff --git a/configure.ac b/configure.ac
index de3c55c..47a7b2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,7 +160,7 @@ AM_CONDITIONAL(HAVE_ICU, $have_icu)
dnl ==========================================================================
-PKG_CHECK_MODULES(ICU_LE, icu-le, have_icu_le=true, have_icu_le=false)
+PKG_CHECK_MODULES(ICU_LE, icu-le icu-uc, have_icu_le=true, have_icu_le=false)
if $have_icu_le; then
AC_DEFINE(HAVE_ICU_LE, 1, [Have ICU Layout Engine library])
fi
diff --git a/src/hb-icu-le.cc b/src/hb-icu-le.cc
index 07f766d..68c9c42 100644
--- a/src/hb-icu-le.cc
+++ b/src/hb-icu-le.cc
@@ -30,14 +30,10 @@
#include "hb-icu-le/PortableFontInstance.h"
-#include "layout/loengine.h"
+#include "layout/LayoutEngine.h"
+#include "unicode/unistr.h"
-#include <harfbuzz.h>
-
-
-#ifndef HB_DEBUG_ICU_LE
-#define HB_DEBUG_ICU_LE (HB_DEBUG+0)
-#endif
+#include "hb-icu.h"
/*
@@ -93,8 +89,8 @@ struct hb_icu_le_shaper_shape_plan_data_t {};
hb_icu_le_shaper_shape_plan_data_t *
_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
{
return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
@@ -116,5 +112,102 @@ _hb_icu_le_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- return false;
+ LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font);
+ le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script);
+ le_int32 language_code = -1 /* TODO */;
+ le_int32 typography_flags = 3; // essential for ligatures and kerning
+ LEErrorCode status = LE_NO_ERROR;
+ LayoutEngine *le = LayoutEngine::layoutEngineFactory (font_instance,
+ script_code,
+ language_code,
+ typography_flags,
+ status);
+ if (status != LE_NO_ERROR)
+ { delete (le); return false; }
+
+retry:
+
+ unsigned int scratch_size;
+ char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+ Type *name = (Type *) scratch; \
+ scratch += (len) * sizeof ((name)[0]); \
+ scratch_size -= (len) * sizeof ((name)[0]);
+
+ ALLOCATE_ARRAY (LEUnicode, chars, buffer->len);
+ ALLOCATE_ARRAY (unsigned int, clusters, buffer->len);
+
+ for (unsigned int i = 0; i < buffer->len; i++) {
+ chars[i] = buffer->info[i].codepoint;
+ clusters[i] = buffer->info[i].cluster;
+ }
+
+ unsigned int glyph_count = le->layoutChars(chars,
+ 0,
+ buffer->len,
+ buffer->len,
+ HB_DIRECTION_IS_BACKWARD (buffer->props.direction),
+ 0., 0.,
+ status);
+ if (status != LE_NO_ERROR)
+ { delete (le); return false; }
+
+ unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) +
+ sizeof (le_int32) +
+ sizeof (float) * 2);
+
+ if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) {
+ buffer->ensure (buffer->allocated * 2);
+ if (buffer->in_error)
+ { delete (le); return false; }
+ goto retry;
+ }
+
+ ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count);
+ ALLOCATE_ARRAY (le_int32, indices, glyph_count);
+ ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2);
+
+ le->getGlyphs(glyphs, status);
+ le->getCharIndices(indices, status);
+ le->getGlyphPositions(positions, status);
+
+#undef ALLOCATE_ARRAY
+
+ /* Ok, we've got everything we need, now compose output buffer,
+ * very, *very*, carefully! */
+
+ unsigned int j = 0;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < glyph_count; i++)
+ {
+ if (glyphs[i] >= 0xFFFE)
+ continue;
+
+ info[j].codepoint = glyphs[i];
+ info[j].cluster = clusters[indices[i]];
+
+ /* icu-le doesn't seem to have separapte advance values. */
+ info[j].mask = positions[2 * i + 2] - positions[2 * i];
+ info[j].var1.u32 = 0;
+ info[j].var2.u32 = -positions[2 * i + 1];
+
+ j++;
+ }
+ buffer->len = j;
+
+ buffer->clear_positions ();
+
+ for (unsigned int i = 0; i < buffer->len; i++) {
+ hb_glyph_info_t *info = &buffer->info[i];
+ hb_glyph_position_t *pos = &buffer->pos[i];
+
+ /* TODO vertical */
+ pos->x_advance = info->mask;
+ pos->x_offset = info->var1.u32;
+ pos->y_offset = info->var2.u32;
+ }
+
+ delete (le);
+ return true;
}
diff --git a/src/hb-icu-le/cmaps.h b/src/hb-icu-le/cmaps.h
index df0bb11..fcad788 100644
--- a/src/hb-icu-le/cmaps.h
+++ b/src/hb-icu-le/cmaps.h
@@ -78,7 +78,6 @@ inline CMAPMapper::CMAPMapper(const CMAPTable *cmap)
inline CMAPMapper::~CMAPMapper()
{
- DELETE_ARRAY(fcmap);
}
#endif
diff --git a/src/hb-shaper-list.hh b/src/hb-shaper-list.hh
index 8e67dbd..6c02de4 100644
--- a/src/hb-shaper-list.hh
+++ b/src/hb-shaper-list.hh
@@ -47,4 +47,8 @@ HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
HB_SHAPER_IMPLEMENT (old)
#endif
+#ifdef HAVE_ICU_LE
+HB_SHAPER_IMPLEMENT (icu_le)
+#endif
+
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
commit ba7f6c3797e5b440557bacd9b666bf09713dca76
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 23 21:52:44 2012 -0400
[icu-le] Hook up to hb_face_t
diff --git a/src/hb-icu-le.cc b/src/hb-icu-le.cc
index 9629534..07f766d 100644
--- a/src/hb-icu-le.cc
+++ b/src/hb-icu-le.cc
@@ -25,6 +25,7 @@
*/
#define HB_SHAPER icu_le
+#define hb_icu_le_shaper_font_data_t PortableFontInstance
#include "hb-shaper-impl-private.hh"
#include "hb-icu-le/PortableFontInstance.h"
@@ -61,18 +62,26 @@ _hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data)
* shaper font data
*/
-struct hb_icu_le_shaper_font_data_t {};
-
hb_icu_le_shaper_font_data_t *
_hb_icu_le_shaper_font_data_create (hb_font_t *font)
{
- return (hb_icu_le_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ LEErrorCode status = LE_NO_ERROR;
+ hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face,
+ font->x_scale,
+ font->y_scale,
+ status);
+ if (status != LE_NO_ERROR) {
+ delete (data);
+ return NULL;
+ }
+
+ return data;
}
void
_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
{
- free (data);
+ delete (data);
}
diff --git a/src/hb-icu-le/FontTableCache.cpp b/src/hb-icu-le/FontTableCache.cpp
index 84d5507..93db6cc 100644
--- a/src/hb-icu-le/FontTableCache.cpp
+++ b/src/hb-icu-le/FontTableCache.cpp
@@ -16,7 +16,7 @@
struct FontTableCacheEntry
{
LETag tag;
- const void *table;
+ hb_blob_t *blob;
};
FontTableCache::FontTableCache()
@@ -30,18 +30,18 @@ FontTableCache::FontTableCache()
}
for (int i = 0; i < fTableCacheSize; i += 1) {
- fTableCache[i].tag = 0;
- fTableCache[i].table = NULL;
+ fTableCache[i].tag = 0;
+ fTableCache[i].blob = NULL;
}
}
FontTableCache::~FontTableCache()
{
for (int i = fTableCacheCurr - 1; i >= 0; i -= 1) {
- DELETE_ARRAY(fTableCache[i].table);
+ hb_blob_destroy(fTableCache[i].blob);
- fTableCache[i].tag = 0;
- fTableCache[i].table = NULL;
+ fTableCache[i].tag = 0;
+ fTableCache[i].blob = NULL;
}
fTableCacheCurr = 0;
@@ -49,27 +49,27 @@ FontTableCache::~FontTableCache()
DELETE_ARRAY(fTableCache);
}
-void FontTableCache::freeFontTable(const void *table) const
+void FontTableCache::freeFontTable(hb_blob_t *blob) const
{
- DELETE_ARRAY(table);
+ hb_blob_destroy(blob);
}
const void *FontTableCache::find(LETag tableTag) const
{
for (int i = 0; i < fTableCacheCurr; i += 1) {
if (fTableCache[i].tag == tableTag) {
- return fTableCache[i].table;
+ return hb_blob_get_data(fTableCache[i].blob, NULL);
}
}
- const void *table = readFontTable(tableTag);
+ hb_blob_t *blob = readFontTable(tableTag);
- ((FontTableCache *) this)->add(tableTag, table);
+ ((FontTableCache *) this)->add(tableTag, blob);
- return table;
+ return hb_blob_get_data (blob, NULL);
}
-void FontTableCache::add(LETag tableTag, const void *table)
+void FontTableCache::add(LETag tableTag, hb_blob_t *blob)
{
if (fTableCacheCurr >= fTableCacheSize) {
le_int32 newSize = fTableCacheSize + TABLE_CACHE_GROW;
@@ -77,15 +77,15 @@ void FontTableCache::add(LETag tableTag, const void *table)
fTableCache = (FontTableCacheEntry *) GROW_ARRAY(fTableCache, newSize);
for (le_int32 i = fTableCacheSize; i < newSize; i += 1) {
- fTableCache[i].tag = 0;
- fTableCache[i].table = NULL;
+ fTableCache[i].tag = 0;
+ fTableCache[i].blob = NULL;
}
fTableCacheSize = newSize;
}
- fTableCache[fTableCacheCurr].tag = tableTag;
- fTableCache[fTableCacheCurr].table = table;
+ fTableCache[fTableCacheCurr].tag = tableTag;
+ fTableCache[fTableCacheCurr].blob = blob;
fTableCacheCurr += 1;
}
diff --git a/src/hb-icu-le/FontTableCache.h b/src/hb-icu-le/FontTableCache.h
index 36971e4..d41d7c7 100644
--- a/src/hb-icu-le/FontTableCache.h
+++ b/src/hb-icu-le/FontTableCache.h
@@ -9,6 +9,9 @@
#define __FONTTABLECACHE_H
+#define HB_H_IN
+#include <hb-blob.h>
+
#include "layout/LETypes.h"
U_NAMESPACE_USE
@@ -25,12 +28,12 @@ public:
const void *find(LETag tableTag) const;
protected:
- virtual const void *readFontTable(LETag tableTag) const = 0;
- virtual void freeFontTable(const void *table) const;
+ virtual hb_blob_t *readFontTable(LETag tableTag) const = 0;
+ virtual void freeFontTable(hb_blob_t *blob) const;
private:
- void add(LETag tableTag, const void *table);
+ void add(LETag tableTag, hb_blob_t *blob);
FontTableCacheEntry *fTableCache;
le_int32 fTableCacheCurr;
diff --git a/src/hb-icu-le/PortableFontInstance.cpp b/src/hb-icu-le/PortableFontInstance.cpp
index 5394fb8..f4eb171 100644
--- a/src/hb-icu-le/PortableFontInstance.cpp
+++ b/src/hb-icu-le/PortableFontInstance.cpp
@@ -64,83 +64,24 @@ le_int8 PortableFontInstance::highBit(le_int32 value)
return bit;
}
-PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status)
- : fFile(NULL), fPointSize(pointSize), fUnitsPerEM(0), fFontChecksum(0), fAscent(0), fDescent(0), fLeading(0),
- fDirectory(NULL), fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
+PortableFontInstance::PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status)
+ : fFace(face), fXScale(xScale), fYScale(yScale), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
+ fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
{
if (LE_FAILURE(status)) {
return;
}
- // open the font file
- fFile = fopen(fileName, "rb");
-
- if (fFile == NULL) {
- status = LE_FONT_FILE_NOT_FOUND_ERROR;
- return;
- }
-
- // read in the directory
- SFNTDirectory tempDir;
-
- fread(&tempDir, sizeof tempDir, 1, fFile);
-
- le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
- const LETag headTag = LE_HEAD_TABLE_TAG;
const LETag hheaTag = LE_HHEA_TABLE_TAG;
- const HEADTable *headTable = NULL;
const HHEATable *hheaTable = NULL;
-// const NAMETable *nameTable = NULL;
- le_uint16 numTables = 0;
- fDirectory = (const SFNTDirectory *) NEW_ARRAY(char, dirSize);
-
- if (fDirectory == NULL) {
- status = LE_MEMORY_ALLOCATION_ERROR;
- goto error_exit;
- }
-
- fseek(fFile, 0L, SEEK_SET);
- fread((void *) fDirectory, sizeof(char), dirSize, fFile);
-
- //
- // We calculate these numbers 'cause some fonts
- // have bogus values for them in the directory header.
- //
- numTables = SWAPW(fDirectory->numTables);
- fDirPower = 1 << highBit(numTables);
- fDirExtra = numTables - fDirPower;
-
- // read unitsPerEm from 'head' table
- headTable = (const HEADTable *) getFontTable(headTag);
-
- if (headTable == NULL) {
- status = LE_MISSING_FONT_TABLE_ERROR;
- goto error_exit;
- }
-
- fUnitsPerEM = SWAPW(headTable->unitsPerEm);
- fFontChecksum = SWAPL(headTable->checksumAdjustment);
-
- //nameTable = (NAMETable *) getFontTable(nameTag);
-
- //if (nameTable == NULL) {
- // status = LE_MISSING_FONT_TABLE_ERROR;
- // goto error_exit;
- //}
-
- //fFontVersionString = findName(nameTable, NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
-
- //if (fFontVersionString == NULL) {
- // status = LE_MISSING_FONT_TABLE_ERROR;
- // goto error_exit;
- //}
+ fUnitsPerEM = hb_face_get_upem (face);
hheaTable = (HHEATable *) getFontTable(hheaTag);
if (hheaTable == NULL) {
status = LE_MISSING_FONT_TABLE_ERROR;
- goto error_exit;
+ return;
}
fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
@@ -153,73 +94,14 @@ PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize
if (fCMAPMapper == NULL) {
status = LE_MISSING_FONT_TABLE_ERROR;
- goto error_exit;
+ return;
}
-
- return;
-
-error_exit:
- fclose(fFile);
- fFile = NULL;
- return;
}
PortableFontInstance::~PortableFontInstance()
{
- if (fFile != NULL) {
- fclose(fFile);
-
+ if (fCMAPMapper)
delete fCMAPMapper;
-
- DELETE_ARRAY(fDirectory);
- }
-}
-
-const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
-{
- if (fDirectory != NULL) {
- le_uint16 table = 0;
- le_uint16 probe = fDirPower;
-
- if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
- table = fDirExtra;
- }
-
- while (probe > (1 << 0)) {
- probe >>= 1;
-
- if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
- table += probe;
- }
- }
-
- if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
- return &fDirectory->tableDirectory[table];
- }
- }
-
- return NULL;
-}
-
-const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
-{
- const DirectoryEntry *entry = findTable(tag);
-
- if (entry == NULL) {
- *length = 0;
- return NULL;
- }
-
- *length = SWAPL(entry->length);
-
- void *table = NEW_ARRAY(char, *length);
-
- if (table != NULL) {
- fseek(fFile, SWAPL(entry->offset), SEEK_SET);
- fread(table, sizeof(char), *length, fFile);
- }
-
- return table;
}
const void *PortableFontInstance::getFontTable(LETag tableTag) const
@@ -227,11 +109,9 @@ const void *PortableFontInstance::getFontTable(LETag tableTag) const
return FontTableCache::find(tableTag);
}
-const void *PortableFontInstance::readFontTable(LETag tableTag) const
+hb_blob_t *PortableFontInstance::readFontTable(LETag tableTag) const
{
- le_uint32 len;
-
- return readTable(tableTag, &len);
+ return hb_face_reference_table(fFace, tableTag);
}
CMAPMapper *PortableFontInstance::findUnicodeMapper()
@@ -369,7 +249,7 @@ le_int32 PortableFontInstance::getUnitsPerEM() const
le_uint32 PortableFontInstance::getFontChecksum() const
{
- return fFontChecksum;
+ return 0;
}
le_int32 PortableFontInstance::getAscent() const
@@ -408,12 +288,12 @@ LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
float PortableFontInstance::getXPixelsPerEm() const
{
- return fPointSize;
+ return fXScale;
}
float PortableFontInstance::getYPixelsPerEm() const
{
- return fPointSize;
+ return fYScale;
}
float PortableFontInstance::getScaleFactorX() const
diff --git a/src/hb-icu-le/PortableFontInstance.h b/src/hb-icu-le/PortableFontInstance.h
index 3e86112..a444772 100644
--- a/src/hb-icu-le/PortableFontInstance.h
+++ b/src/hb-icu-le/PortableFontInstance.h
@@ -15,32 +15,29 @@
#ifndef __PORTABLEFONTINSTANCE_H
#define __PORTABLEFONTINSTANCE_H
-#include <stdio.h>
+#define HB_H_IN
+#include <hb-font.h>
+#include <hb-blob.h>
#include "layout/LETypes.h"
#include "layout/LEFontInstance.h"
#include "FontTableCache.h"
-#include "sfnt.h"
#include "cmaps.h"
class PortableFontInstance : public LEFontInstance, protected FontTableCache
{
private:
- FILE *fFile;
+ hb_face_t *fFace;
- float fPointSize;
+ float fXScale;
+ float fYScale;
le_int32 fUnitsPerEM;
- le_uint32 fFontChecksum;
le_int32 fAscent;
le_int32 fDescent;
le_int32 fLeading;
- const SFNTDirectory *fDirectory;
- le_uint16 fDirPower;
- le_uint16 fDirExtra;
-
float fDeviceScaleX;
float fDeviceScaleY;
@@ -56,17 +53,15 @@ private:
static le_int8 highBit(le_int32 value);
- const DirectoryEntry *findTable(LETag tag) const;
- const void *readTable(LETag tag, le_uint32 *length) const;
void getMetrics();
CMAPMapper *findUnicodeMapper();
protected:
- const void *readFontTable(LETag tableTag) const;
+ hb_blob_t *readFontTable(LETag tableTag) const;
public:
- PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status);
+ PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status);
virtual ~PortableFontInstance();
diff --git a/src/hb-icu-le/README b/src/hb-icu-le/README
index cb4d2cf..329a218 100644
--- a/src/hb-icu-le/README
+++ b/src/hb-icu-le/README
@@ -1,2 +1,3 @@
This is PortableFontInstance from icu/test/testle of ICU50.
+Modified to use a hb_face_t.
For license information, see the file license.html.
commit e96bb36995b2a5321b4d32bb11906e1701aaf115
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 23 21:37:51 2012 -0400
[icu-le] Actually use the FontTableCache
diff --git a/src/hb-icu-le/PortableFontInstance.cpp b/src/hb-icu-le/PortableFontInstance.cpp
index 14e3f52..5394fb8 100644
--- a/src/hb-icu-le/PortableFontInstance.cpp
+++ b/src/hb-icu-le/PortableFontInstance.cpp
@@ -112,7 +112,7 @@ PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize
fDirExtra = numTables - fDirPower;
// read unitsPerEm from 'head' table
- headTable = (const HEADTable *) readFontTable(headTag);
+ headTable = (const HEADTable *) getFontTable(headTag);
if (headTable == NULL) {
status = LE_MISSING_FONT_TABLE_ERROR;
@@ -121,9 +121,8 @@ PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize
fUnitsPerEM = SWAPW(headTable->unitsPerEm);
fFontChecksum = SWAPL(headTable->checksumAdjustment);
- freeFontTable(headTable);
- //nameTable = (NAMETable *) readFontTable(nameTag);
+ //nameTable = (NAMETable *) getFontTable(nameTag);
//if (nameTable == NULL) {
// status = LE_MISSING_FONT_TABLE_ERROR;
@@ -137,9 +136,7 @@ PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize
// goto error_exit;
//}
- //freeFontTable(nameTable);
-
- hheaTable = (HHEATable *) readFontTable(hheaTag);
+ hheaTable = (HHEATable *) getFontTable(hheaTag);
if (hheaTable == NULL) {
status = LE_MISSING_FONT_TABLE_ERROR;
@@ -152,8 +149,6 @@ PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize
fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
- freeFontTable((void *) hheaTable);
-
fCMAPMapper = findUnicodeMapper();
if (fCMAPMapper == NULL) {
@@ -174,9 +169,6 @@ PortableFontInstance::~PortableFontInstance()
if (fFile != NULL) {
fclose(fFile);
- freeFontTable(fHMTXTable);
- freeFontTable(fNAMETable);
-
delete fCMAPMapper;
DELETE_ARRAY(fDirectory);
@@ -245,7 +237,7 @@ const void *PortableFontInstance::readFontTable(LETag tableTag) const
CMAPMapper *PortableFontInstance::findUnicodeMapper()
{
LETag cmapTag = LE_CMAP_TABLE_TAG;
- const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
+ const CMAPTable *cmap = (CMAPTable *) getFontTable(cmapTag);
if (cmap == NULL) {
return NULL;
@@ -260,7 +252,7 @@ const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 plat
LETag nameTag = LE_NAME_TABLE_TAG;
PortableFontInstance *realThis = (PortableFontInstance *) this;
- realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+ realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
if (realThis->fNAMETable != NULL) {
realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
@@ -293,7 +285,7 @@ const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID,
LETag nameTag = LE_NAME_TABLE_TAG;
PortableFontInstance *realThis = (PortableFontInstance *) this;
- realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+ realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
if (realThis->fNAMETable != NULL) {
realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
@@ -340,15 +332,14 @@ void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) co
if (fHMTXTable == NULL) {
LETag maxpTag = LE_MAXP_TABLE_TAG;
LETag hmtxTag = LE_HMTX_TABLE_TAG;
- const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
+ const MAXPTable *maxpTable = (MAXPTable *) getFontTable(maxpTag);
PortableFontInstance *realThis = (PortableFontInstance *) this;
if (maxpTable != NULL) {
realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
- freeFontTable(maxpTable);
}
- realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
+ realThis->fHMTXTable = (const HMTXTable *) getFontTable(hmtxTag);
}
le_uint16 index = ttGlyph;
commit 7d242364ea647f655a7092bda25f9a10774c57f5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 23 21:23:41 2012 -0400
[icu-le] Start adding a icu-layout-engine backend
Import PortableFontInstance and add shaper stub.
diff --git a/configure.ac b/configure.ac
index 916a5d4..de3c55c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,6 +160,14 @@ AM_CONDITIONAL(HAVE_ICU, $have_icu)
dnl ==========================================================================
+PKG_CHECK_MODULES(ICU_LE, icu-le, have_icu_le=true, have_icu_le=false)
+if $have_icu_le; then
+ AC_DEFINE(HAVE_ICU_LE, 1, [Have ICU Layout Engine library])
+fi
+AM_CONDITIONAL(HAVE_ICU_LE, $have_icu_le)
+
+dnl ==========================================================================
+
PKG_CHECK_MODULES(GRAPHITE2, graphite2, have_graphite=true, have_graphite=false)
if $have_graphite; then
AC_DEFINE(HAVE_GRAPHITE2, 1, [Have Graphite library])
@@ -229,6 +237,7 @@ harfbuzz.pc
src/Makefile
src/hb-version.h
src/hb-old/Makefile
+src/hb-icu-le/Makefile
util/Makefile
test/Makefile
test/api/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 5894b20..166ba79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -163,6 +163,14 @@ HBSOURCES += hb-old.cc
endif
DIST_SUBDIRS += hb-old
+if HAVE_ICU_LE
+SUBDIRS += hb-icu-le
+HBCFLAGS += -I$(srcdir)/hb-icu-le
+HBLIBS += hb-icu-le/libhb-icu-le.la
+HBSOURCES += hb-icu-le.cc
+endif
+DIST_SUBDIRS += hb-icu-le
+
# Put the library together
diff --git a/src/hb-icu-le.cc b/src/hb-icu-le.cc
new file mode 100644
index 0000000..9629534
--- /dev/null
+++ b/src/hb-icu-le.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 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
+ */
+
+#define HB_SHAPER icu_le
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-icu-le/PortableFontInstance.h"
+
+#include "layout/loengine.h"
+
+#include <harfbuzz.h>
+
+
+#ifndef HB_DEBUG_ICU_LE
+#define HB_DEBUG_ICU_LE (HB_DEBUG+0)
+#endif
+
+
+/*
+ * shaper face data
+ */
+
+struct hb_icu_le_shaper_face_data_t {};
+
+hb_icu_le_shaper_face_data_t *
+_hb_icu_le_shaper_face_data_create (hb_face_t *face)
+{
+ return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_icu_le_shaper_font_data_t {};
+
+hb_icu_le_shaper_font_data_t *
+_hb_icu_le_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_icu_le_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
+{
+ free (data);
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_icu_le_shaper_shape_plan_data_t {};
+
+hb_icu_le_shaper_shape_plan_data_t *
+_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+hb_bool_t
+_hb_icu_le_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ return false;
+}
diff --git a/src/hb-icu-le/FontTableCache.cpp b/src/hb-icu-le/FontTableCache.cpp
new file mode 100644
index 0000000..84d5507
--- /dev/null
+++ b/src/hb-icu-le/FontTableCache.cpp
@@ -0,0 +1,91 @@
+/*
+ **********************************************************************
+ * Copyright (C) 2003-2008, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ **********************************************************************
+ */
+
+#include "layout/LETypes.h"
+
+#include "letest.h"
+#include "FontTableCache.h"
+
+#define TABLE_CACHE_INIT 5
+#define TABLE_CACHE_GROW 5
+
+struct FontTableCacheEntry
+{
+ LETag tag;
+ const void *table;
+};
+
+FontTableCache::FontTableCache()
+ : fTableCacheCurr(0), fTableCacheSize(TABLE_CACHE_INIT)
+{
+ fTableCache = NEW_ARRAY(FontTableCacheEntry, fTableCacheSize);
+
+ if (fTableCache == NULL) {
+ fTableCacheSize = 0;
+ return;
+ }
+
+ for (int i = 0; i < fTableCacheSize; i += 1) {
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ }
+}
+
+FontTableCache::~FontTableCache()
+{
+ for (int i = fTableCacheCurr - 1; i >= 0; i -= 1) {
+ DELETE_ARRAY(fTableCache[i].table);
+
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ }
+
+ fTableCacheCurr = 0;
+
+ DELETE_ARRAY(fTableCache);
+}
+
+void FontTableCache::freeFontTable(const void *table) const
+{
+ DELETE_ARRAY(table);
+}
+
+const void *FontTableCache::find(LETag tableTag) const
+{
+ for (int i = 0; i < fTableCacheCurr; i += 1) {
+ if (fTableCache[i].tag == tableTag) {
+ return fTableCache[i].table;
+ }
+ }
+
+ const void *table = readFontTable(tableTag);
+
+ ((FontTableCache *) this)->add(tableTag, table);
+
+ return table;
+}
+
+void FontTableCache::add(LETag tableTag, const void *table)
+{
+ if (fTableCacheCurr >= fTableCacheSize) {
+ le_int32 newSize = fTableCacheSize + TABLE_CACHE_GROW;
+
+ fTableCache = (FontTableCacheEntry *) GROW_ARRAY(fTableCache, newSize);
+
+ for (le_int32 i = fTableCacheSize; i < newSize; i += 1) {
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ }
+
+ fTableCacheSize = newSize;
+ }
+
+ fTableCache[fTableCacheCurr].tag = tableTag;
+ fTableCache[fTableCacheCurr].table = table;
+
+ fTableCacheCurr += 1;
+}
diff --git a/src/hb-icu-le/FontTableCache.h b/src/hb-icu-le/FontTableCache.h
new file mode 100644
index 0000000..36971e4
--- /dev/null
+++ b/src/hb-icu-le/FontTableCache.h
@@ -0,0 +1,41 @@
+/*
+ **********************************************************************
+ * Copyright (C) 2003-2008, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ **********************************************************************
+ */
+
+#ifndef __FONTTABLECACHE_H
+
+#define __FONTTABLECACHE_H
+
+#include "layout/LETypes.h"
+
+U_NAMESPACE_USE
+
+struct FontTableCacheEntry;
+
+class FontTableCache
+{
+public:
+ FontTableCache();
+
+ virtual ~FontTableCache();
+
+ const void *find(LETag tableTag) const;
+
+protected:
+ virtual const void *readFontTable(LETag tableTag) const = 0;
+ virtual void freeFontTable(const void *table) const;
+
+private:
+
+ void add(LETag tableTag, const void *table);
+
+ FontTableCacheEntry *fTableCache;
+ le_int32 fTableCacheCurr;
+ le_int32 fTableCacheSize;
+};
+
+#endif
+
diff --git a/src/hb-icu-le/Makefile.am b/src/hb-icu-le/Makefile.am
new file mode 100644
index 0000000..dd99dc1
--- /dev/null
+++ b/src/hb-icu-le/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LTLIBRARIES = libhb-icu-le.la
+
+
+libhb_icu_le_la_SOURCES = \
+ FontTableCache.cpp \
+ FontTableCache.h \
+ PortableFontInstance.cpp \
+ PortableFontInstance.h \
+ cmaps.cpp \
+ cmaps.h \
+ letest.h \
+ sfnt.h
+libhb_icu_le_la_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(ICU_LE_CFLAGS)
+libhb_icu_le_la_LIBADD = \
+ $(ICU_LE_LIBS)
+
+EXTRA_DIST = README license.html
+
+-include $(top_srcdir)/git.mk
diff --git a/src/hb-icu-le/PortableFontInstance.cpp b/src/hb-icu-le/PortableFontInstance.cpp
new file mode 100644
index 0000000..14e3f52
--- /dev/null
+++ b/src/hb-icu-le/PortableFontInstance.cpp
@@ -0,0 +1,436 @@
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2008, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: PortableFontInstance.cpp
+ *
+ * created on: 11/22/1999
+ * created by: Eric R. Mader
+ */
+
+#include <stdio.h>
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+#include "layout/LESwaps.h"
+
+#include "PortableFontInstance.h"
+
+#include "letest.h"
+#include "sfnt.h"
+
+#include <string.h>
+
+//
+// Finds the high bit by binary searching
+// through the bits in n.
+//
+le_int8 PortableFontInstance::highBit(le_int32 value)
+{
+ if (value <= 0) {
+ return -32;
+ }
+
+ le_uint8 bit = 0;
+
+ if (value >= 1 << 16) {
+ value >>= 16;
+ bit += 16;
+ }
+
+ if (value >= 1 << 8) {
+ value >>= 8;
+ bit += 8;
+ }
+
+ if (value >= 1 << 4) {
+ value >>= 4;
+ bit += 4;
+ }
+
+ if (value >= 1 << 2) {
+ value >>= 2;
+ bit += 2;
+ }
+
+ if (value >= 1 << 1) {
+ value >>= 1;
+ bit += 1;
+ }
+
+ return bit;
+}
+
+PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status)
+ : fFile(NULL), fPointSize(pointSize), fUnitsPerEM(0), fFontChecksum(0), fAscent(0), fDescent(0), fLeading(0),
+ fDirectory(NULL), fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
+{
+ if (LE_FAILURE(status)) {
+ return;
+ }
+
+ // open the font file
+ fFile = fopen(fileName, "rb");
+
+ if (fFile == NULL) {
+ status = LE_FONT_FILE_NOT_FOUND_ERROR;
+ return;
+ }
+
+ // read in the directory
+ SFNTDirectory tempDir;
+
+ fread(&tempDir, sizeof tempDir, 1, fFile);
+
+ le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
+ const LETag headTag = LE_HEAD_TABLE_TAG;
+ const LETag hheaTag = LE_HHEA_TABLE_TAG;
+ const HEADTable *headTable = NULL;
+ const HHEATable *hheaTable = NULL;
+// const NAMETable *nameTable = NULL;
+ le_uint16 numTables = 0;
+
+ fDirectory = (const SFNTDirectory *) NEW_ARRAY(char, dirSize);
+
+ if (fDirectory == NULL) {
+ status = LE_MEMORY_ALLOCATION_ERROR;
+ goto error_exit;
+ }
+
+ fseek(fFile, 0L, SEEK_SET);
+ fread((void *) fDirectory, sizeof(char), dirSize, fFile);
+
+ //
+ // We calculate these numbers 'cause some fonts
+ // have bogus values for them in the directory header.
+ //
+ numTables = SWAPW(fDirectory->numTables);
+ fDirPower = 1 << highBit(numTables);
+ fDirExtra = numTables - fDirPower;
+
+ // read unitsPerEm from 'head' table
+ headTable = (const HEADTable *) readFontTable(headTag);
+
+ if (headTable == NULL) {
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ goto error_exit;
+ }
+
+ fUnitsPerEM = SWAPW(headTable->unitsPerEm);
+ fFontChecksum = SWAPL(headTable->checksumAdjustment);
+ freeFontTable(headTable);
+
+ //nameTable = (NAMETable *) readFontTable(nameTag);
+
+ //if (nameTable == NULL) {
+ // status = LE_MISSING_FONT_TABLE_ERROR;
+ // goto error_exit;
+ //}
+
+ //fFontVersionString = findName(nameTable, NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
+
+ //if (fFontVersionString == NULL) {
+ // status = LE_MISSING_FONT_TABLE_ERROR;
+ // goto error_exit;
+ //}
+
+ //freeFontTable(nameTable);
+
+ hheaTable = (HHEATable *) readFontTable(hheaTag);
+
+ if (hheaTable == NULL) {
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ goto error_exit;
+ }
+
+ fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
+ fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
+ fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
+
+ fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
+
+ freeFontTable((void *) hheaTable);
+
+ fCMAPMapper = findUnicodeMapper();
+
+ if (fCMAPMapper == NULL) {
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ goto error_exit;
+ }
+
+ return;
+
+error_exit:
+ fclose(fFile);
+ fFile = NULL;
+ return;
+}
+
+PortableFontInstance::~PortableFontInstance()
+{
+ if (fFile != NULL) {
+ fclose(fFile);
+
+ freeFontTable(fHMTXTable);
+ freeFontTable(fNAMETable);
+
+ delete fCMAPMapper;
+
+ DELETE_ARRAY(fDirectory);
+ }
+}
+
+const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
+{
+ if (fDirectory != NULL) {
+ le_uint16 table = 0;
+ le_uint16 probe = fDirPower;
+
+ if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
+ table = fDirExtra;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
+ table += probe;
+ }
+ }
+
+ if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
+ return &fDirectory->tableDirectory[table];
+ }
+ }
+
+ return NULL;
+}
+
+const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
+{
+ const DirectoryEntry *entry = findTable(tag);
+
+ if (entry == NULL) {
+ *length = 0;
+ return NULL;
+ }
+
+ *length = SWAPL(entry->length);
+
+ void *table = NEW_ARRAY(char, *length);
+
+ if (table != NULL) {
+ fseek(fFile, SWAPL(entry->offset), SEEK_SET);
+ fread(table, sizeof(char), *length, fFile);
+ }
+
+ return table;
+}
+
+const void *PortableFontInstance::getFontTable(LETag tableTag) const
+{
+ return FontTableCache::find(tableTag);
+}
+
+const void *PortableFontInstance::readFontTable(LETag tableTag) const
+{
+ le_uint32 len;
+
+ return readTable(tableTag, &len);
+}
+
+CMAPMapper *PortableFontInstance::findUnicodeMapper()
+{
+ LETag cmapTag = LE_CMAP_TABLE_TAG;
+ const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
+
+ if (cmap == NULL) {
+ return NULL;
+ }
+
+ return CMAPMapper::createUnicodeMapper(cmap);
+}
+
+const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
+{
+ if (fNAMETable == NULL) {
+ LETag nameTag = LE_NAME_TABLE_TAG;
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+
+ if (realThis->fNAMETable != NULL) {
+ realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
+ realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
+ }
+ }
+
+ for(le_int32 i = 0; i < fNameCount; i += 1) {
+ const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
+
+ if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
+ SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
+ char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
+ le_uint16 length = SWAPW(nameRecord->length);
+ char *result = NEW_ARRAY(char, length + 2);
+
+ ARRAY_COPY(result, name, length);
+ result[length] = result[length + 1] = 0;
+
+ return result;
+ }
+ }
+
+ return NULL;
+}
+
+const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
+{
+ if (fNAMETable == NULL) {
+ LETag nameTag = LE_NAME_TABLE_TAG;
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+
+ if (realThis->fNAMETable != NULL) {
+ realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
+ realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
+ }
+ }
+
+ for(le_int32 i = 0; i < fNameCount; i += 1) {
+ const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
+
+ if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
+ SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
+ LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
+ le_uint16 length = SWAPW(nameRecord->length) / 2;
+ LEUnicode16 *result = NEW_ARRAY(LEUnicode16, length + 2);
+
+ for (le_int32 c = 0; c < length; c += 1) {
+ result[c] = SWAPW(name[c]);
+ }
+
+ result[length] = 0;
+
+ return result;
+ }
+ }
+
+ return NULL;
+}
+
+void PortableFontInstance::deleteNameString(const char *name) const
+{
+ DELETE_ARRAY(name);
+}
+
+void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
+{
+ DELETE_ARRAY(name);
+}
+
+void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
+{
+ TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
+
+ if (fHMTXTable == NULL) {
+ LETag maxpTag = LE_MAXP_TABLE_TAG;
+ LETag hmtxTag = LE_HMTX_TABLE_TAG;
+ const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ if (maxpTable != NULL) {
+ realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
+ freeFontTable(maxpTable);
+ }
+
+ realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
+ }
+
+ le_uint16 index = ttGlyph;
+
+ if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
+ advance.fX = advance.fY = 0;
+ return;
+ }
+
+ if (ttGlyph >= fNumLongHorMetrics) {
+ index = fNumLongHorMetrics - 1;
+ }
+
+ advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
+ advance.fY = 0;
+}
+
+le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
+{
+ return FALSE;
+}
+
+le_int32 PortableFontInstance::getUnitsPerEM() const
+{
+ return fUnitsPerEM;
+}
+
+le_uint32 PortableFontInstance::getFontChecksum() const
+{
+ return fFontChecksum;
+}
+
+le_int32 PortableFontInstance::getAscent() const
+{
+ return fAscent;
+}
+
+le_int32 PortableFontInstance::getDescent() const
+{
+ return fDescent;
+}
+
+le_int32 PortableFontInstance::getLeading() const
+{
+ return fLeading;
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper);
+}
+
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
+{
+ return fCMAPMapper->unicodeToGlyph(ch);
+}
+
+float PortableFontInstance::getXPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float PortableFontInstance::getYPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float PortableFontInstance::getScaleFactorX() const
+{
+ return 1.0;
+}
+
+float PortableFontInstance::getScaleFactorY() const
+{
+ return 1.0;
+}
diff --git a/src/hb-icu-le/PortableFontInstance.h b/src/hb-icu-le/PortableFontInstance.h
new file mode 100644
index 0000000..3e86112
--- /dev/null
+++ b/src/hb-icu-le/PortableFontInstance.h
@@ -0,0 +1,117 @@
+
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2008, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: PortableFontInstance.h
+ *
+ * created on: 11/12/1999
+ * created by: Eric R. Mader
+ */
+
+#ifndef __PORTABLEFONTINSTANCE_H
+#define __PORTABLEFONTINSTANCE_H
+
+#include <stdio.h>
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+
+#include "FontTableCache.h"
+
+#include "sfnt.h"
+#include "cmaps.h"
+
+class PortableFontInstance : public LEFontInstance, protected FontTableCache
+{
+private:
+ FILE *fFile;
+
+ float fPointSize;
+ le_int32 fUnitsPerEM;
+ le_uint32 fFontChecksum;
+ le_int32 fAscent;
+ le_int32 fDescent;
+ le_int32 fLeading;
+
+ const SFNTDirectory *fDirectory;
+ le_uint16 fDirPower;
+ le_uint16 fDirExtra;
+
+ float fDeviceScaleX;
+ float fDeviceScaleY;
+
+ const NAMETable *fNAMETable;
+ le_uint16 fNameCount;
+ le_uint16 fNameStringOffset;
+
+ CMAPMapper *fCMAPMapper;
+
+ const HMTXTable *fHMTXTable;
+ le_uint16 fNumGlyphs;
+ le_uint16 fNumLongHorMetrics;
+
+ static le_int8 highBit(le_int32 value);
+
+ const DirectoryEntry *findTable(LETag tag) const;
+ const void *readTable(LETag tag, le_uint32 *length) const;
+ void getMetrics();
+
+ CMAPMapper *findUnicodeMapper();
+
+protected:
+ const void *readFontTable(LETag tableTag) const;
+
+public:
+ PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status);
+
+ virtual ~PortableFontInstance();
+
+ virtual const void *getFontTable(LETag tableTag) const;
+
+ virtual const char *getNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
+
+ virtual const LEUnicode16 *getUnicodeNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
+
+ virtual void deleteNameString(const char *name) const;
+
+ virtual void deleteNameString(const LEUnicode16 *name) const;
+
+ virtual le_int32 getUnitsPerEM() const;
+
+ virtual le_uint32 getFontChecksum() const;
+
+ virtual le_int32 getAscent() const;
+
+ virtual le_int32 getDescent() const;
+
+ virtual le_int32 getLeading() const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const;
+
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const;
+
+ virtual void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const;
+
+ virtual le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const;
+
+ float getXPixelsPerEm() const;
+
+ float getYPixelsPerEm() const;
+
+ float getScaleFactorX() const;
+
+ float getScaleFactorY() const;
+
+};
+
+#endif
diff --git a/src/hb-icu-le/README b/src/hb-icu-le/README
new file mode 100644
index 0000000..cb4d2cf
--- /dev/null
+++ b/src/hb-icu-le/README
@@ -0,0 +1,2 @@
+This is PortableFontInstance from icu/test/testle of ICU50.
+For license information, see the file license.html.
diff --git a/src/hb-icu-le/cmaps.cpp b/src/hb-icu-le/cmaps.cpp
new file mode 100644
index 0000000..87087aa
--- /dev/null
+++ b/src/hb-icu-le/cmaps.cpp
@@ -0,0 +1,200 @@
+/***************************************************************************
+*
+* Copyright (C) 1998-2003, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#include "layout/LETypes.h"
+#include "layout/LESwaps.h"
+
+#include "sfnt.h"
+#include "cmaps.h"
+
+#define SWAPU16(code) ((LEUnicode16) SWAPW(code))
+#define SWAPU32(code) ((LEUnicode32) SWAPL(code))
+
+//
+// Finds the high bit by binary searching
+// through the bits in value.
+//
+le_int8 highBit(le_uint32 value)
+{
+ le_uint8 bit = 0;
+
+ if (value >= 1 << 16) {
+ value >>= 16;
+ bit += 16;
+ }
+
+ if (value >= 1 << 8) {
+ value >>= 8;
+ bit += 8;
+ }
+
+ if (value >= 1 << 4) {
+ value >>= 4;
+ bit += 4;
+ }
+
+ if (value >= 1 << 2) {
+ value >>= 2;
+ bit += 2;
+ }
+
+ if (value >= 1 << 1) {
+ value >>= 1;
+ bit += 1;
+ }
+
+ return bit;
+}
+
+CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap)
+{
+ le_uint16 i;
+ le_uint16 nSubtables = SWAPW(cmap->numberSubtables);
+ const CMAPEncodingSubtable *subtable = NULL;
+ le_uint32 offset1 = 0, offset10 = 0;
+
+ for (i = 0; i < nSubtables; i += 1) {
+ const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
+
+ if (SWAPW(esh->platformID) == 3) {
+ switch (SWAPW(esh->platformSpecificID)) {
+ case 1:
+ offset1 = SWAPL(esh->encodingOffset);
+ break;
+
+ case 10:
+ offset10 = SWAPL(esh->encodingOffset);
+ break;
+ }
+ }
+ }
+
+
+ if (offset10 != 0)
+ {
+ subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset10);
+ } else if (offset1 != 0) {
+ subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset1);
+ } else {
+ return NULL;
+ }
+
+ switch (SWAPW(subtable->format)) {
+ case 4:
+ return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
+
+ case 12:
+ {
+ const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable;
+
+ return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
+ }
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header)
+ : CMAPMapper(cmap)
+{
+ le_uint16 segCount = SWAPW(header->segCountX2) / 2;
+
+ fEntrySelector = SWAPW(header->entrySelector);
+ fRangeShift = SWAPW(header->rangeShift) / 2;
+ fEndCodes = &header->endCodes[0];
+ fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad...
+ fIdDelta = &fStartCodes[segCount];
+ fIdRangeOffset = &fIdDelta[segCount];
+}
+
+LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const
+{
+ if (unicode32 >= 0x10000) {
+ return 0;
+ }
+
+ LEUnicode16 unicode = (LEUnicode16) unicode32;
+ le_uint16 index = 0;
+ le_uint16 probe = 1 << fEntrySelector;
+ TTGlyphID result = 0;
+
+ if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) {
+ index = fRangeShift;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPU16(fStartCodes[index + probe]) <= unicode) {
+ index += probe;
+ }
+ }
+
+ if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) {
+ if (fIdRangeOffset[index] == 0) {
+ result = (TTGlyphID) unicode;
+ } else {
+ le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
+ le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
+ le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset);
+
+ result = SWAPW(glyphIndexTable[offset]);
+ }
+
+ result += SWAPW(fIdDelta[index]);
+ } else {
+ result = 0;
+ }
+
+ return LE_SET_GLYPH(0, result);
+}
+
+CMAPFormat4Mapper::~CMAPFormat4Mapper()
+{
+ // parent destructor does it all
+}
+
+CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups)
+ : CMAPMapper(cmap), fGroups(groups)
+{
+ le_uint8 bit = highBit(nGroups);
+ fPower = 1 << bit;
+ fRangeOffset = nGroups - fPower;
+}
+
+LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const
+{
+ le_int32 probe = fPower;
+ le_int32 range = 0;
+
+ if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) {
+ range = fRangeOffset;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) {
+ range += probe;
+ }
+ }
+
+ if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) {
+ return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
+ }
+
+ return 0;
+}
+
+CMAPGroupMapper::~CMAPGroupMapper()
+{
+ // parent destructor does it all
+}
+
diff --git a/src/hb-icu-le/cmaps.h b/src/hb-icu-le/cmaps.h
new file mode 100644
index 0000000..df0bb11
--- /dev/null
+++ b/src/hb-icu-le/cmaps.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+*
+* Copyright (C) 1998-2006, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+
+#ifndef __CMAPS_H
+#define __CMAPS_H
+
+#include "layout/LETypes.h"
+#include "letest.h"
+#include "sfnt.h"
+
+class CMAPMapper
+{
+public:
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const = 0;
+
+ virtual ~CMAPMapper();
+
+ static CMAPMapper *createUnicodeMapper(const CMAPTable *cmap);
+
+protected:
+ CMAPMapper(const CMAPTable *cmap);
+
+ CMAPMapper() {};
+
+private:
+ const CMAPTable *fcmap;
+};
+
+class CMAPFormat4Mapper : public CMAPMapper
+{
+public:
+ CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header);
+
+ virtual ~CMAPFormat4Mapper();
+
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const;
+
+protected:
+ CMAPFormat4Mapper() {};
+
+private:
+ le_uint16 fEntrySelector;
+ le_uint16 fRangeShift;
+ const le_uint16 *fEndCodes;
+ const le_uint16 *fStartCodes;
+ const le_uint16 *fIdDelta;
+ const le_uint16 *fIdRangeOffset;
+};
+
+class CMAPGroupMapper : public CMAPMapper
+{
+public:
+ CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups);
+
+ virtual ~CMAPGroupMapper();
+
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const;
+
+protected:
+ CMAPGroupMapper() {};
+
+private:
+ le_int32 fPower;
+ le_int32 fRangeOffset;
+ const CMAPGroup *fGroups;
+};
+
+inline CMAPMapper::CMAPMapper(const CMAPTable *cmap)
+ : fcmap(cmap)
+{
+ // nothing else to do
+}
+
+inline CMAPMapper::~CMAPMapper()
+{
+ DELETE_ARRAY(fcmap);
+}
+
+#endif
+
diff --git a/src/hb-icu-le/letest.h b/src/hb-icu-le/letest.h
new file mode 100644
index 0000000..f924ca8
--- /dev/null
+++ b/src/hb-icu-le/letest.h
@@ -0,0 +1,49 @@
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2011, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: letest.h
+ *
+ * created on: 11/06/2000
+ * created by: Eric R. Mader
+ */
+
+#ifndef __LETEST_H
+#define __LETEST_H
+
+#include "layout/LETypes.h"
+/*#include "unicode/ctest.h"*/
+
+#include <stdlib.h>
+#include <string.h>
+
+U_NAMESPACE_USE
+
+#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
+
+#define ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
+
+#define NEW_ARRAY(type,count) (type *) malloc((count) * sizeof(type))
+
+#define DELETE_ARRAY(array) free((void *) (array))
+
+#define GROW_ARRAY(array,newSize) realloc((void *) (array), (newSize) * sizeof (array)[0])
+
+struct TestResult
+{
+ le_int32 glyphCount;
+ LEGlyphID *glyphs;
+ le_int32 *indices;
+ float *positions;
+};
+
+#ifndef __cplusplus
+typedef struct TestResult TestResult;
+#endif
+
+//U_CFUNC void addCTests(TestNode **root);
+
+#endif
diff --git a/src/hb-icu-le/license.html b/src/hb-icu-le/license.html
new file mode 100644
index 0000000..d078d05
--- /dev/null
+++ b/src/hb-icu-le/license.html
@@ -0,0 +1,51 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></meta>
+<title>ICU License - ICU 1.8.1 and later</title>
+</head>
+
+<body BGCOLOR="#ffffff">
+<h2>ICU License - ICU 1.8.1 and later</h2>
+
+<p>COPYRIGHT AND PERMISSION NOTICE</p>
+
+<p>
+Copyright (c) 1995-2012 International Business Machines Corporation and others
+</p>
+<p>
+All rights reserved.
+</p>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies
+of the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+</p>
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM,
+OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+USE OR PERFORMANCE OF THIS SOFTWARE.
+</p>
+<p>
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization of the copyright holder.
+</p>
+
+<hr>
+<p><small>
+All trademarks and registered trademarks mentioned herein are the property of their respective owners.
+</small></p>
+</body>
+</html>
diff --git a/src/hb-icu-le/sfnt.h b/src/hb-icu-le/sfnt.h
new file mode 100644
index 0000000..4a8f2f3
--- /dev/null
+++ b/src/hb-icu-le/sfnt.h
@@ -0,0 +1,449 @@
+/***************************************************************************
+*
+* Copyright (C) 1998-2011, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#ifndef __SFNT_H
+#define __SFNT_H
+
+#include "layout/LETypes.h"
+
+U_NAMESPACE_USE
+
+#ifndef ANY_NUMBER
+#define ANY_NUMBER 1
+#endif
+
+struct DirectoryEntry
+{
+ le_uint32 tag;
+ le_uint32 checksum;
+ le_uint32 offset;
+ le_uint32 length;
+};
+
+#ifndef __cplusplus
+typedef struct DirectoryEntry DirectoryEntry;
+#endif
+
+struct SFNTDirectory
+{
+ le_uint32 scalerType;
+ le_uint16 numTables;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ DirectoryEntry tableDirectory[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct SFNTDirectory SFNTDirectory;
+#endif
+
+
+struct CMAPEncodingSubtableHeader
+{
+ le_uint16 platformID;
+ le_uint16 platformSpecificID;
+ le_uint32 encodingOffset;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtableHeader CMAPEncodingSubtableHeader;
+#endif
+
+struct CMAPTable
+{
+ le_uint16 version;
+ le_uint16 numberSubtables;
+ CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct CMAPTable CMAPTable;
+#endif
+
+struct CMAPEncodingSubtable
+{
+ le_uint16 format;
+ le_uint16 length;
+ le_uint16 language;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtable CMAPEncodingSubtable;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat0Encoding : CMAPEncodingSubtable
+{
+ le_uint8 glyphIndexArray[256];
+};
+#else
+struct CMAPFormat0Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint8 glyphIndexArray[256];
+};
+
+typedef struct CMAPFormat0Encoding CMAPFormat0Encoding;
+#endif
+
+struct CMAPFormat2Subheader
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_int16 idDelta;
+ le_uint16 idRangeOffset;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPFormat2Subheader CMAPFormat2Subheader;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat2Encoding : CMAPEncodingSubtable
+{
+ le_uint16 subHeadKeys[256];
+ CMAPFormat2Subheader subheaders[ANY_NUMBER];
+};
+#else
+struct CMAPFormat2Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 subHeadKeys[256];
+ CMAPFormat2Subheader subheaders[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat2Encoding CMAPFormat2Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat4Encoding : CMAPEncodingSubtable
+{
+ le_uint16 segCountX2;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ le_uint16 endCodes[ANY_NUMBER];
+/*
+ le_uint16 reservedPad;
+ le_uint16 startCodes[ANY_NUMBER];
+ le_uint16 idDelta[ANY_NUMBER];
+ le_uint16 idRangeOffset[ANY_NUMBER];
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+*/
+};
+#else
+struct CMAPFormat4Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 segCountX2;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ le_uint16 endCodes[ANY_NUMBER];
+/*
+// le_uint16 reservedPad;
+// le_uint16 startCodes[ANY_NUMBER];
+// le_uint16 idDelta[ANY_NUMBER];
+// le_uint16 idRangeOffset[ANY_NUMBER];
+// le_uint16 glyphIndexArray[ANY_NUMBER];
+*/
+};
+
+typedef struct CMAPFormat4Encoding CMAPFormat4Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat6Encoding : CMAPEncodingSubtable
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+#else
+struct CMAPFormat6Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat6Encoding CMAPFormat6Encoding;
+#endif
+
+struct CMAPEncodingSubtable32
+{
+ le_uint32 format;
+ le_uint32 length;
+ le_uint32 language;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtable32 CMAPEncodingSubtable32;
+#endif
+
+struct CMAPGroup
+{
+ le_uint32 startCharCode;
+ le_uint32 endCharCode;
+ le_uint32 startGlyphCode;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPGroup CMAPGroup;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat8Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 is32[65536/32];
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+#else
+struct CMAPFormat8Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 is32[65536/32];
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat8Encoding CMAPFormat8Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat10Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 startCharCode;
+ le_uint32 numCharCodes;
+ le_uint16 glyphs[ANY_NUMBER];
+};
+#else
+struct CMAPFormat10Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 startCharCode;
+ le_uint32 numCharCodes;
+ le_uint16 glyphs[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat10Encoding CMAPFormat10Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat12Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+#else
+struct CMAPFormat12Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat12Encoding CMAPFormat12Encoding;
+#endif
+
+typedef le_int32 fixed;
+
+struct BigDate
+{
+ le_uint32 bc;
+ le_uint32 ad;
+};
+
+#ifndef __cplusplus
+typedef struct BigDate BigDate;
+#endif
+
+struct HEADTable
+{
+ fixed version;
+ fixed fontRevision;
+ le_uint32 checksumAdjustment;
+ le_uint32 magicNumber;
+ le_uint16 flags;
+ le_uint16 unitsPerEm;
+ BigDate created;
+ BigDate modified;
+ le_int16 xMin;
+ le_int16 yMin;
+ le_int16 xMax;
+ le_int16 yMax;
+ le_int16 lowestRecPPEM;
+ le_int16 fontDirectionHint;
+ le_int16 indexToLocFormat;
+ le_int16 glyphDataFormat;
+};
+
+#ifndef __cplusplus
+typedef struct HEADTable HEADTable;
+#endif
+
+struct MAXPTable
+{
+ fixed version;
+ le_uint16 numGlyphs;
+ le_uint16 maxPoints;
+ le_uint16 maxContours;
+ le_uint16 maxComponentPoints;
+ le_uint16 maxComponentContours;
+ le_uint16 maxZones;
+ le_uint16 maxTwilightPoints;
+ le_uint16 maxStorage;
+ le_uint16 maxFunctionDefs;
+ le_uint16 maxInstructionDefs;
+ le_uint16 maxStackElements;
+ le_uint16 maxSizeOfInstructions;
+ le_uint16 maxComponentElements;
+ le_uint16 maxComponentDepth;
+};
+
+#ifndef __cplusplus
+typedef struct MAXPTable MAXPTable;
+#endif
+
+struct HHEATable
+{
+ fixed version;
+ le_int16 ascent;
+ le_int16 descent;
+ le_int16 lineGap;
+ le_uint16 advanceWidthMax;
+ le_int16 minLeftSideBearing;
+ le_int16 minRightSideBearing;
+ le_int16 xMaxExtent;
+ le_int16 caretSlopeRise;
+ le_int16 caretSlopeRun;
+ le_int16 caretOffset;
+ le_int16 reserved1;
+ le_int16 reserved2;
+ le_int16 reserved3;
+ le_int16 reserved4;
+ le_int16 metricDataFormat;
+ le_uint16 numOfLongHorMetrics;
+};
+
+#ifndef __cplusplus
+typedef struct HHEATable HHEATable;
+#endif
+
+struct LongHorMetric
+{
+ le_uint16 advanceWidth;
+ le_int16 leftSideBearing;
+};
+
+#ifndef __cplusplus
+typedef struct LongHorMetric LongHorMetric;
+#endif
+
+struct HMTXTable
+{
+ LongHorMetric hMetrics[ANY_NUMBER]; /* ANY_NUMBER = numOfLongHorMetrics from hhea table */
+/* le_int16 leftSideBearing[ANY_NUMBER]; ANY_NUMBER = numGlyphs - numOfLongHorMetrics */
+};
+
+#ifndef __cplusplus
+typedef struct HMTXTable HMTXTable;
+#endif
+
+enum PlatformID
+{
+ PLATFORM_UNICODE = 0,
+ PLATFORM_MACINTOSH = 1,
+ PLATFORM_ISO = 2,
+ PLATFORM_MICROSOFT = 3,
+ PLATFORM_CUSTOM = 4
+};
+
+enum MacintoshEncodingID
+{
+ MACINTOSH_ROMAN = 0
+};
+
+enum MacintoshLanguageID
+{
+ MACINTOSH_ENGLISH = 0
+};
+
+enum MicrosoftEncodingID
+{
+ MICROSOFT_UNICODE_BMP = 1,
+ MICROSOFT_UNICODE_FULL = 10
+};
+
+enum MicrosoftLanguageID
+{
+ MICROSOFT_ENGLISH = 0x409
+};
+
+enum NameID
+{
+ NAME_COPYRIGHT_NOTICE = 0,
+ NAME_FONT_FAMILY = 1,
+ NAME_FONT_SUB_FAMILY = 2,
+ NAME_UNIQUE_FONT_ID = 3,
+ NAME_FULL_FONT_NAME = 4,
+ NAME_VERSION_STRING = 5,
+ NAME_POSTSCRIPT_NAME = 6,
+ NAME_TRADEMARK = 7,
+ NAME_MANUFACTURER = 8,
+ NAME_DESIGNER = 9,
+ NAME_DESCRIPTION = 10,
+ NAME_VENDOR_URL = 11,
+ NAME_DESIGNER_URL = 12,
+ NAME_LICENSE_DESCRIPTION = 13,
+ NAME_LICENSE_URL = 14,
+ NAME_RESERVED = 15,
+ NAME_PREFERRED_FAMILY = 16,
+ NAME_PREFERRED_SUB_FAMILY = 17,
+ NAME_COMPATIBLE_FULL = 18,
+ NAME_SAMPLE_TEXT = 19,
+ NAME_POSTSCRIPT_CID = 20
+};
+
+struct NameRecord
+{
+ le_uint16 platformID;
+ le_uint16 encodingID;
+ le_uint16 languageID;
+ le_uint16 nameID;
+ le_uint16 length;
+ le_uint16 offset;
+};
+
+#ifndef __cplusplus
+typedef struct NameRecord NameRecord;
+#endif
+
+struct NAMETable
+{
+ le_uint16 version;
+ le_uint16 count;
+ le_uint16 stringOffset;
+ NameRecord nameRecords[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct NAMETable NAMETable;
+#endif
+
+#endif
+
More information about the HarfBuzz
mailing list