Import PortableFontInstance and add shaper stub.
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])
src/Makefile
src/hb-version.h
src/hb-old/Makefile
+src/hb-icu-le/Makefile
util/Makefile
test/Makefile
test/api/Makefile
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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ **********************************************************************
+ * 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;
+}
--- /dev/null
+/*
+ **********************************************************************
+ * 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
+
--- /dev/null
+## 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
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * 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;
+}
--- /dev/null
+
+/*
+ *******************************************************************************
+ *
+ * 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
--- /dev/null
+This is PortableFontInstance from icu/test/testle of ICU50.
+For license information, see the file license.html.
--- /dev/null
+/***************************************************************************
+*
+* 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
+}
+
--- /dev/null
+/***************************************************************************
+*
+* 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
+
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * 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
--- /dev/null
+<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>
--- /dev/null
+/***************************************************************************
+*
+* 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
+