mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-05 05:25:34 +00:00
ICU-22751 Delete icu4c/source/test/perf/leperf.
This commit is contained in:
parent
e59065cc74
commit
5314d9d737
18 changed files with 0 additions and 2870 deletions
|
@ -1304,7 +1304,6 @@ AC_CONFIG_FILES([icudefs.mk \
|
|||
test/perf/ustrperf/Makefile \
|
||||
test/perf/utfperf/Makefile \
|
||||
test/perf/utrie2perf/Makefile \
|
||||
test/perf/leperf/Makefile \
|
||||
test/fuzzer/Makefile \
|
||||
samples/Makefile])
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
****************************************************************************/
|
||||
/***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "FontObject.h"
|
||||
#include "layout/LESwaps.h"
|
||||
|
||||
using icu::LESwaps;
|
||||
|
||||
FontObject::FontObject(char *fileName)
|
||||
: directory(nullptr), numTables(0), searchRange(0),entrySelector(0),
|
||||
cmapTable(nullptr), cmSegCount(0), cmSearchRange(0), cmEntrySelector(0),
|
||||
cmEndCodes(nullptr), cmStartCodes(nullptr), cmIdDelta(nullptr), cmIdRangeOffset(nullptr),
|
||||
headTable(nullptr), hmtxTable(nullptr), numGlyphs(0), numOfLongHorMetrics(0), file(nullptr)
|
||||
{
|
||||
file = fopen(fileName, "rb");
|
||||
|
||||
if (file == nullptr) {
|
||||
printf("?? Couldn't open %s", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
SFNTDirectory tempDir;
|
||||
|
||||
fread(&tempDir, sizeof tempDir, 1, file);
|
||||
|
||||
numTables = SWAPW(tempDir.numTables);
|
||||
searchRange = SWAPW(tempDir.searchRange) >> 4;
|
||||
entrySelector = SWAPW(tempDir.entrySelector);
|
||||
rangeShift = SWAPW(tempDir.rangeShift) >> 4;
|
||||
|
||||
int dirSize = sizeof tempDir + ((numTables - ANY_NUMBER) * sizeof(DirectoryEntry));
|
||||
|
||||
directory = reinterpret_cast<SFNTDirectory*>(new char[dirSize]);
|
||||
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
fread(directory, sizeof(char), dirSize, file);
|
||||
|
||||
initUnicodeCMAP();
|
||||
}
|
||||
|
||||
FontObject::~FontObject()
|
||||
{
|
||||
fclose(file);
|
||||
delete[] directory;
|
||||
delete[] cmapTable;
|
||||
delete[] headTable;
|
||||
delete[] hmtxTable;
|
||||
}
|
||||
|
||||
void FontObject::deleteTable(void *table)
|
||||
{
|
||||
delete[] static_cast<char*>(table);
|
||||
}
|
||||
|
||||
DirectoryEntry *FontObject::findTable(LETag tag)
|
||||
{
|
||||
le_uint16 table = 0;
|
||||
le_uint16 probe = 1 << entrySelector;
|
||||
|
||||
if (SWAPL(directory->tableDirectory[rangeShift].tag) <= tag) {
|
||||
table = rangeShift;
|
||||
}
|
||||
|
||||
while (probe > (1 << 0)) {
|
||||
probe >>= 1;
|
||||
|
||||
if (SWAPL(directory->tableDirectory[table + probe].tag) <= tag) {
|
||||
table += probe;
|
||||
}
|
||||
}
|
||||
|
||||
if (SWAPL(directory->tableDirectory[table].tag) == tag) {
|
||||
return &directory->tableDirectory[table];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *FontObject::readTable(LETag tag, le_uint32 *length)
|
||||
{
|
||||
DirectoryEntry *entry = findTable(tag);
|
||||
|
||||
if (entry == nullptr) {
|
||||
*length = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*length = SWAPL(entry->length);
|
||||
|
||||
void *table = new char[*length];
|
||||
|
||||
fseek(file, SWAPL(entry->offset), SEEK_SET);
|
||||
fread(table, sizeof(char), *length, file);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
CMAPEncodingSubtable *FontObject::findCMAP(le_uint16 platformID, le_uint16 platformSpecificID)
|
||||
{
|
||||
LETag cmapTag = 0x636D6170; // 'cmap'
|
||||
|
||||
if (cmapTable == nullptr) {
|
||||
le_uint32 length;
|
||||
|
||||
cmapTable = static_cast<CMAPTable*>(readTable(cmapTag, &length));
|
||||
}
|
||||
|
||||
if (cmapTable != nullptr) {
|
||||
le_uint16 i;
|
||||
le_uint16 nSubtables = SWAPW(cmapTable->numberSubtables);
|
||||
|
||||
|
||||
for (i = 0; i < nSubtables; i += 1) {
|
||||
CMAPEncodingSubtableHeader *esh = &cmapTable->encodingSubtableHeaders[i];
|
||||
|
||||
if (SWAPW(esh->platformID) == platformID &&
|
||||
SWAPW(esh->platformSpecificID) == platformSpecificID) {
|
||||
return reinterpret_cast<CMAPEncodingSubtable*>(reinterpret_cast<char*>(cmapTable) + SWAPL(esh->encodingOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FontObject::initUnicodeCMAP()
|
||||
{
|
||||
CMAPEncodingSubtable *encodingSubtable = findCMAP(3, 1);
|
||||
|
||||
if (encodingSubtable == nullptr ||
|
||||
SWAPW(encodingSubtable->format) != 4) {
|
||||
printf("Can't find unicode 'cmap'");
|
||||
return;
|
||||
}
|
||||
|
||||
CMAPFormat4Encoding *header = (CMAPFormat4Encoding *) encodingSubtable;
|
||||
|
||||
cmSegCount = SWAPW(header->segCountX2) / 2;
|
||||
cmSearchRange = SWAPW(header->searchRange);
|
||||
cmEntrySelector = SWAPW(header->entrySelector);
|
||||
cmRangeShift = SWAPW(header->rangeShift) / 2;
|
||||
cmEndCodes = &header->endCodes[0];
|
||||
cmStartCodes = &header->endCodes[cmSegCount + 1]; // + 1 for reservedPad...
|
||||
cmIdDelta = &cmStartCodes[cmSegCount];
|
||||
cmIdRangeOffset = &cmIdDelta[cmSegCount];
|
||||
}
|
||||
|
||||
LEGlyphID FontObject::unicodeToGlyph(LEUnicode32 unicode32)
|
||||
{
|
||||
if (unicode32 >= 0x10000) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEUnicode16 unicode = static_cast<LEUnicode16>(unicode32);
|
||||
le_uint16 index = 0;
|
||||
le_uint16 probe = 1 << cmEntrySelector;
|
||||
LEGlyphID result = 0;
|
||||
|
||||
if (SWAPW(cmStartCodes[cmRangeShift]) <= unicode) {
|
||||
index = cmRangeShift;
|
||||
}
|
||||
|
||||
while (probe > (1 << 0)) {
|
||||
probe >>= 1;
|
||||
|
||||
if (SWAPW(cmStartCodes[index + probe]) <= unicode) {
|
||||
index += probe;
|
||||
}
|
||||
}
|
||||
|
||||
if (unicode >= SWAPW(cmStartCodes[index]) && unicode <= SWAPW(cmEndCodes[index])) {
|
||||
if (cmIdRangeOffset[index] == 0) {
|
||||
result = static_cast<LEGlyphID>(unicode);
|
||||
} else {
|
||||
le_uint16 offset = unicode - SWAPW(cmStartCodes[index]);
|
||||
le_uint16 rangeOffset = SWAPW(cmIdRangeOffset[index]);
|
||||
le_uint16* glyphIndexTable = reinterpret_cast<le_uint16*>(reinterpret_cast<char*>(&cmIdRangeOffset[index]) + rangeOffset);
|
||||
|
||||
result = SWAPW(glyphIndexTable[offset]);
|
||||
}
|
||||
|
||||
result += SWAPW(cmIdDelta[index]);
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
le_uint16 FontObject::getUnitsPerEM()
|
||||
{
|
||||
if (headTable == nullptr) {
|
||||
LETag headTag = 0x68656164; // 'head'
|
||||
le_uint32 length;
|
||||
|
||||
headTable = static_cast<HEADTable*>(readTable(headTag, &length));
|
||||
}
|
||||
|
||||
return SWAPW(headTable->unitsPerEm);
|
||||
}
|
||||
|
||||
le_uint16 FontObject::getGlyphAdvance(LEGlyphID glyph)
|
||||
{
|
||||
if (hmtxTable == nullptr) {
|
||||
LETag maxpTag = 0x6D617870; // 'maxp'
|
||||
LETag hheaTag = 0x68686561; // 'hhea'
|
||||
LETag hmtxTag = 0x686D7478; // 'hmtx'
|
||||
le_uint32 length;
|
||||
HHEATable *hheaTable;
|
||||
MAXPTable* maxpTable = static_cast<MAXPTable*>(readTable(maxpTag, &length));
|
||||
|
||||
numGlyphs = SWAPW(maxpTable->numGlyphs);
|
||||
deleteTable(maxpTable);
|
||||
|
||||
hheaTable = static_cast<HHEATable*>(readTable(hheaTag, &length));
|
||||
numOfLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
|
||||
deleteTable(hheaTable);
|
||||
|
||||
hmtxTable = static_cast<HMTXTable*>(readTable(hmtxTag, &length));
|
||||
}
|
||||
|
||||
le_uint16 index = glyph;
|
||||
|
||||
if (glyph >= numGlyphs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (glyph >= numOfLongHorMetrics) {
|
||||
index = numOfLongHorMetrics - 1;
|
||||
}
|
||||
|
||||
return SWAPW(hmtxTable->hMetrics[index].advanceWidth);
|
||||
}
|
||||
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
|
||||
#ifndef __FONTOBJECT_H
|
||||
#define __FONTOBJECT_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
|
||||
|
||||
#ifndef ANY_NUMBER
|
||||
#define ANY_NUMBER 1
|
||||
#endif
|
||||
|
||||
struct DirectoryEntry
|
||||
{
|
||||
le_uint32 tag;
|
||||
le_uint32 checksum;
|
||||
le_uint32 offset;
|
||||
le_uint32 length;
|
||||
};
|
||||
|
||||
struct SFNTDirectory
|
||||
{
|
||||
le_uint32 scalerType;
|
||||
le_uint16 numTables;
|
||||
le_uint16 searchRange;
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
DirectoryEntry tableDirectory[ANY_NUMBER];
|
||||
};
|
||||
|
||||
|
||||
struct CMAPEncodingSubtableHeader
|
||||
{
|
||||
le_uint16 platformID;
|
||||
le_uint16 platformSpecificID;
|
||||
le_uint32 encodingOffset;
|
||||
};
|
||||
|
||||
struct CMAPTable
|
||||
{
|
||||
le_uint16 version;
|
||||
le_uint16 numberSubtables;
|
||||
CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER];
|
||||
};
|
||||
|
||||
struct CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 format;
|
||||
le_uint16 length;
|
||||
le_uint16 language;
|
||||
};
|
||||
|
||||
struct CMAPFormat0Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint8 glyphIndexArray[256];
|
||||
};
|
||||
|
||||
struct CMAPFormat2Subheader
|
||||
{
|
||||
le_uint16 firstCode;
|
||||
le_uint16 entryCount;
|
||||
le_int16 idDelta;
|
||||
le_uint16 idRangeOffset;
|
||||
};
|
||||
|
||||
struct CMAPFormat2Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 subHeadKeys[256];
|
||||
CMAPFormat2Subheader subheaders[ANY_NUMBER];
|
||||
};
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
struct CMAPFormat6Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 firstCode;
|
||||
le_uint16 entryCount;
|
||||
le_uint16 glyphIndexArray[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef le_int32 fixed;
|
||||
|
||||
struct BigDate
|
||||
{
|
||||
le_uint32 bc;
|
||||
le_uint32 ad;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct LongHorMetric
|
||||
{
|
||||
le_uint16 advanceWidth;
|
||||
le_int16 leftSideBearing;
|
||||
};
|
||||
|
||||
struct HMTXTable
|
||||
{
|
||||
LongHorMetric hMetrics[ANY_NUMBER]; // ANY_NUMBER = numOfLongHorMetrics from hhea table
|
||||
// le_int16 leftSideBearing[ANY_NUMBER]; // ANY_NUMBER = numGlyphs - numOfLongHorMetrics
|
||||
};
|
||||
|
||||
class FontObject
|
||||
{
|
||||
public:
|
||||
FontObject(char *fontName);
|
||||
~FontObject();
|
||||
|
||||
void *readTable(LETag tag, le_uint32 *length);
|
||||
void deleteTable(void *table);
|
||||
|
||||
LEGlyphID unicodeToGlyph(LEUnicode32 unicode);
|
||||
|
||||
#if 0
|
||||
le_uint32 unicodesToGlyphs(LEUnicode *chars, le_uint32 nChars, LEGlyphID *glyphs,
|
||||
le_uint32 *charIndices, le_bool rightToLeft);
|
||||
#endif
|
||||
|
||||
le_uint16 getUnitsPerEM();
|
||||
|
||||
le_uint16 getGlyphAdvance(LEGlyphID glyph);
|
||||
|
||||
private:
|
||||
FontObject();
|
||||
|
||||
DirectoryEntry *findTable(LETag tag);
|
||||
CMAPEncodingSubtable *findCMAP(le_uint16 platformID, le_uint16 platformSpecificID);
|
||||
void initUnicodeCMAP();
|
||||
|
||||
SFNTDirectory *directory;
|
||||
le_uint16 numTables;
|
||||
le_uint16 searchRange;
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
|
||||
CMAPTable *cmapTable;
|
||||
le_uint16 cmSegCount;
|
||||
le_uint16 cmSearchRange;
|
||||
le_uint16 cmEntrySelector;
|
||||
le_uint16 cmRangeShift;
|
||||
le_uint16 *cmEndCodes;
|
||||
le_uint16 *cmStartCodes;
|
||||
le_uint16 *cmIdDelta;
|
||||
le_uint16 *cmIdRangeOffset;
|
||||
|
||||
HEADTable *headTable;
|
||||
|
||||
HMTXTable *hmtxTable;
|
||||
le_uint16 numGlyphs;
|
||||
le_uint16 numOfLongHorMetrics;
|
||||
|
||||
FILE *file;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
**************************************************************************
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*************************************************************************
|
||||
*************************************************************************
|
||||
* Copyright (C) 2003-2013, 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;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
FontTableCache::FontTableCache()
|
||||
: fTableCacheCurr(0), fTableCacheSize(TABLE_CACHE_INIT)
|
||||
{
|
||||
fTableCache = LE_NEW_ARRAY(FontTableCacheEntry, fTableCacheSize);
|
||||
|
||||
if (fTableCache == nullptr) {
|
||||
fTableCacheSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fTableCacheSize; i += 1) {
|
||||
fTableCache[i].tag = 0;
|
||||
fTableCache[i].table = nullptr;
|
||||
fTableCache[i].length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
FontTableCache::~FontTableCache()
|
||||
{
|
||||
for (int i = fTableCacheCurr - 1; i >= 0; i -= 1) {
|
||||
LE_DELETE_ARRAY(fTableCache[i].table);
|
||||
|
||||
fTableCache[i].tag = 0;
|
||||
fTableCache[i].table = nullptr;
|
||||
fTableCache[i].length = 0;
|
||||
}
|
||||
|
||||
fTableCacheCurr = 0;
|
||||
|
||||
LE_DELETE_ARRAY(fTableCache);
|
||||
}
|
||||
|
||||
void FontTableCache::freeFontTable(const void *table) const
|
||||
{
|
||||
LE_DELETE_ARRAY(table);
|
||||
}
|
||||
|
||||
const void *FontTableCache::find(LETag tableTag, size_t &length) const
|
||||
{
|
||||
for (int i = 0; i < fTableCacheCurr; i += 1) {
|
||||
if (fTableCache[i].tag == tableTag) {
|
||||
length = fTableCache[i].length;
|
||||
return fTableCache[i].table;
|
||||
}
|
||||
}
|
||||
|
||||
const void *table = readFontTable(tableTag, length);
|
||||
|
||||
const_cast<FontTableCache*>(this)->add(tableTag, table, length);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void FontTableCache::add(LETag tableTag, const void *table, size_t length)
|
||||
{
|
||||
if (fTableCacheCurr >= fTableCacheSize) {
|
||||
le_int32 newSize = fTableCacheSize + TABLE_CACHE_GROW;
|
||||
|
||||
fTableCache = static_cast<FontTableCacheEntry*>(LE_GROW_ARRAY(fTableCache, newSize));
|
||||
|
||||
for (le_int32 i = fTableCacheSize; i < newSize; i += 1) {
|
||||
fTableCache[i].tag = 0;
|
||||
fTableCache[i].table = nullptr;
|
||||
fTableCache[i].length = 0;
|
||||
}
|
||||
|
||||
fTableCacheSize = newSize;
|
||||
}
|
||||
|
||||
fTableCache[fTableCacheCurr].tag = tableTag;
|
||||
fTableCache[fTableCacheCurr].table = table;
|
||||
fTableCache[fTableCacheCurr].length = length;
|
||||
|
||||
fTableCacheCurr += 1;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
* Copyright (C) 2003-2013, 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, size_t &length) const;
|
||||
|
||||
protected:
|
||||
virtual const void *readFontTable(LETag tableTag, size_t &length) const = 0;
|
||||
virtual void freeFontTable(const void *table) const;
|
||||
|
||||
private:
|
||||
|
||||
void add(LETag tableTag, const void *table, size_t length);
|
||||
|
||||
FontTableCacheEntry *fTableCache;
|
||||
le_int32 fTableCacheCurr;
|
||||
le_int32 fTableCacheSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
## Makefile.in for ICU - test/perf/collperf
|
||||
## Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
## License & terms of use: http://www.unicode.org/copyright.html
|
||||
##
|
||||
## Copyright (c) 2001-2013, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
|
||||
## Source directory information
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
top_builddir = ../../..
|
||||
|
||||
include $(top_builddir)/icudefs.mk
|
||||
|
||||
-include Makefile.local
|
||||
|
||||
## Build directory information
|
||||
subdir = test/perf/leperf
|
||||
|
||||
## Extra files to remove for 'make clean'
|
||||
CLEANFILES = *~ $(DEPS)
|
||||
|
||||
## Target information
|
||||
TARGET = leperf
|
||||
|
||||
CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw -I$(top_srcdir)/io -I$(top_srcdir)/i18n
|
||||
LIBS = $(LIBCTESTFW) $(LIBICUIO) $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M)
|
||||
|
||||
OBJECTS = $(TARGET).o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
## List of phony targets
|
||||
.PHONY : all all-local install install-local clean clean-local \
|
||||
distclean distclean-local dist dist-local check check-local
|
||||
|
||||
## Clear suffix list
|
||||
.SUFFIXES :
|
||||
|
||||
## List of standard targets
|
||||
all: all-local
|
||||
install: install-local
|
||||
clean: clean-local
|
||||
distclean : distclean-local
|
||||
dist: dist-local
|
||||
check: all check-local
|
||||
|
||||
all-local: $(TARGET)
|
||||
|
||||
install-local:
|
||||
|
||||
dist-local:
|
||||
|
||||
clean-local:
|
||||
test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
|
||||
$(RMV) $(OBJECTS) $(TARGET)
|
||||
|
||||
distclean-local: clean-local
|
||||
$(RMV) Makefile
|
||||
|
||||
check-local: all-local
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(TARGET) : $(OBJECTS)
|
||||
$(LINK.cc) -o $@ $^ $(LIBS)
|
||||
$(POST_BUILD_STEP)
|
||||
|
||||
invoke:
|
||||
@$(RMV) current.out
|
||||
# following is bash specific
|
||||
set -o pipefail && ( ICU_DATA=$${ICU_DATA:-$(top_builddir)/data/} TZ=PST8PDT $(INVOKE) ./$(TARGET) $(INVOCATION) | tee current.out )
|
||||
|
||||
ifeq (,$(MAKECMDGOALS))
|
||||
-include $(DEPS)
|
||||
else
|
||||
ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
|
||||
ifneq ($(patsubst %install,,$(MAKECMDGOALS)),)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
|
@ -1,484 +0,0 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2013, 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>
|
||||
#include <stdio.h>
|
||||
|
||||
#if 0
|
||||
static const char *letagToStr(LETag tag, char *str) {
|
||||
str[0]= 0xFF & (tag>>24);
|
||||
str[1]= 0xFF & (tag>>16);
|
||||
str[2]= 0xFF & (tag>>8);
|
||||
str[3]= 0xFF & (tag>>0);
|
||||
str[4]= 0;
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// 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(nullptr), fPointSize(pointSize), fUnitsPerEM(0), fFontChecksum(0), fAscent(0), fDescent(0), fLeading(0),
|
||||
fDirectory(nullptr), fNAMETable(nullptr), fNameCount(0), fNameStringOffset(0), fCMAPMapper(nullptr), fHMTXTable(nullptr), fNumGlyphs(0), fNumLongHorMetrics(0)
|
||||
{
|
||||
if (LE_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// open the font file
|
||||
fFile = fopen(fileName, "rb");
|
||||
//printf("Open Font: %s\n", fileName);
|
||||
|
||||
if (fFile == nullptr) {
|
||||
printf("%s:%d: %s: FNF\n", __FILE__, __LINE__, fileName);
|
||||
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 = nullptr;
|
||||
const HHEATable *hheaTable = nullptr;
|
||||
// const NAMETable *nameTable = nullptr;
|
||||
le_uint16 numTables = 0;
|
||||
|
||||
fDirectory = reinterpret_cast<const SFNTDirectory*>(LE_NEW_ARRAY(char, dirSize));
|
||||
|
||||
if (fDirectory == nullptr) {
|
||||
printf("%s:%d: %s: malloc err\n", __FILE__, __LINE__, fileName);
|
||||
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 = static_cast<const HEADTable*>(readFontTable(headTag));
|
||||
|
||||
if (headTable == nullptr) {
|
||||
status = LE_MISSING_FONT_TABLE_ERROR;
|
||||
printf("%s:%d: %s: missing head table\n", __FILE__, __LINE__, fileName);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
fUnitsPerEM = SWAPW(headTable->unitsPerEm);
|
||||
fFontChecksum = SWAPL(headTable->checksumAdjustment);
|
||||
freeFontTable(headTable);
|
||||
|
||||
//nameTable = (NAMETable *) readFontTable(nameTag);
|
||||
|
||||
//if (nameTable == nullptr) {
|
||||
// status = LE_MISSING_FONT_TABLE_ERROR;
|
||||
// goto error_exit;
|
||||
//}
|
||||
|
||||
//fFontVersionString = findName(nameTable, NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
|
||||
|
||||
//if (fFontVersionString == nullptr) {
|
||||
// status = LE_MISSING_FONT_TABLE_ERROR;
|
||||
// goto error_exit;
|
||||
//}
|
||||
|
||||
//freeFontTable(nameTable);
|
||||
|
||||
hheaTable = (HHEATable *) readFontTable(hheaTag);
|
||||
|
||||
if (hheaTable == nullptr) {
|
||||
printf("%s:%d: %s: missing hhea table\n", __FILE__, __LINE__, fileName);
|
||||
status = LE_MISSING_FONT_TABLE_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
fAscent = static_cast<le_int32>(yUnitsToPoints(static_cast<float>(SWAPW(hheaTable->ascent))));
|
||||
fDescent = static_cast<le_int32>(yUnitsToPoints(static_cast<float>(SWAPW(hheaTable->descent))));
|
||||
fLeading = static_cast<le_int32>(yUnitsToPoints(static_cast<float>(SWAPW(hheaTable->lineGap))));
|
||||
|
||||
fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
|
||||
|
||||
freeFontTable((void *) hheaTable);
|
||||
|
||||
fCMAPMapper = findUnicodeMapper();
|
||||
|
||||
if (fCMAPMapper == nullptr) {
|
||||
printf("%s:%d: %s: can't load cmap\n", __FILE__, __LINE__, fileName);
|
||||
status = LE_MISSING_FONT_TABLE_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error_exit:
|
||||
fclose(fFile);
|
||||
fFile = nullptr;
|
||||
}
|
||||
|
||||
PortableFontInstance::~PortableFontInstance()
|
||||
{
|
||||
if (fFile != nullptr) {
|
||||
fclose(fFile);
|
||||
|
||||
freeFontTable(fHMTXTable);
|
||||
freeFontTable(fNAMETable);
|
||||
|
||||
delete fCMAPMapper;
|
||||
|
||||
LE_DELETE_ARRAY(fDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
|
||||
{
|
||||
if (fDirectory != nullptr) {
|
||||
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 nullptr;
|
||||
}
|
||||
|
||||
const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
|
||||
{
|
||||
const DirectoryEntry *entry = findTable(tag);
|
||||
|
||||
if (entry == nullptr) {
|
||||
*length = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*length = SWAPL(entry->length);
|
||||
|
||||
void *table = LE_NEW_ARRAY(char, *length);
|
||||
|
||||
if (table != nullptr) {
|
||||
fseek(fFile, SWAPL(entry->offset), SEEK_SET);
|
||||
fread(table, sizeof(char), *length, fFile);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
const void *PortableFontInstance::getFontTable(LETag tableTag) const
|
||||
{
|
||||
size_t ignored;
|
||||
return getFontTable(tableTag, ignored);
|
||||
}
|
||||
|
||||
const void *PortableFontInstance::getFontTable(LETag tableTag, size_t &length) const
|
||||
{
|
||||
return FontTableCache::find(tableTag, length);
|
||||
}
|
||||
|
||||
const void *PortableFontInstance::readFontTable(LETag tableTag, size_t &length) const
|
||||
{
|
||||
le_uint32 len;
|
||||
|
||||
const void *data= readTable(tableTag, &len);
|
||||
length = len;
|
||||
//char tag5[5];
|
||||
//printf("Read %s, result %p #%d\n", letagToStr(tableTag,tag5), data,len);
|
||||
return data;
|
||||
}
|
||||
|
||||
CMAPMapper *PortableFontInstance::findUnicodeMapper()
|
||||
{
|
||||
LETag cmapTag = LE_CMAP_TABLE_TAG;
|
||||
const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
|
||||
|
||||
if (cmap == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CMAPMapper::createUnicodeMapper(cmap);
|
||||
}
|
||||
|
||||
const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
|
||||
{
|
||||
if (fNAMETable == nullptr) {
|
||||
LETag nameTag = LE_NAME_TABLE_TAG;
|
||||
PortableFontInstance* realThis = const_cast<PortableFontInstance*>(this);
|
||||
|
||||
realThis->fNAMETable = static_cast<const NAMETable*>(readFontTable(nameTag));
|
||||
|
||||
if (realThis->fNAMETable != nullptr) {
|
||||
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 = LE_NEW_ARRAY(char, length + 2);
|
||||
|
||||
LE_ARRAY_COPY(result, name, length);
|
||||
result[length] = result[length + 1] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
|
||||
{
|
||||
if (fNAMETable == nullptr) {
|
||||
LETag nameTag = LE_NAME_TABLE_TAG;
|
||||
PortableFontInstance* realThis = const_cast<PortableFontInstance*>(this);
|
||||
|
||||
realThis->fNAMETable = static_cast<const NAMETable*>(readFontTable(nameTag));
|
||||
|
||||
if (realThis->fNAMETable != nullptr) {
|
||||
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) {
|
||||
const LEUnicode16* name = reinterpret_cast<const LEUnicode16*>(reinterpret_cast<const char*>(fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
|
||||
le_uint16 length = SWAPW(nameRecord->length) / 2;
|
||||
LEUnicode16 *result = LE_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 nullptr;
|
||||
}
|
||||
|
||||
void PortableFontInstance::deleteNameString(const char *name) const
|
||||
{
|
||||
LE_DELETE_ARRAY(name);
|
||||
}
|
||||
|
||||
void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
|
||||
{
|
||||
LE_DELETE_ARRAY(name);
|
||||
}
|
||||
|
||||
void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
|
||||
{
|
||||
TTGlyphID ttGlyph = static_cast<TTGlyphID>(LE_GET_GLYPH(glyph));
|
||||
|
||||
if (fHMTXTable == nullptr) {
|
||||
LETag maxpTag = LE_MAXP_TABLE_TAG;
|
||||
LETag hmtxTag = LE_HMTX_TABLE_TAG;
|
||||
const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
|
||||
PortableFontInstance* realThis = const_cast<PortableFontInstance*>(this);
|
||||
|
||||
if (maxpTable != nullptr) {
|
||||
realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
|
||||
freeFontTable(maxpTable);
|
||||
}
|
||||
|
||||
realThis->fHMTXTable = static_cast<const HMTXTable*>(readFontTable(hmtxTag));
|
||||
}
|
||||
|
||||
le_uint16 index = ttGlyph;
|
||||
|
||||
if (ttGlyph >= fNumGlyphs || fHMTXTable == nullptr) {
|
||||
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_uint32 PortableFontInstance::getRawChecksum() const
|
||||
{
|
||||
// how big is it?
|
||||
// fseek(fFile, 0L, SEEK_END);
|
||||
// long size = ftell(fFile);
|
||||
le_int32 chksum = 0;
|
||||
// now, calculate
|
||||
fseek(fFile, 0L, SEEK_SET);
|
||||
int r;
|
||||
while((r = fgetc(fFile)) != EOF) {
|
||||
chksum += r;
|
||||
}
|
||||
return static_cast<le_uint32>(chksum); // cast to signed
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2013, 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 { size_t ignored; return readFontTable(tableTag, ignored); }
|
||||
const void *readFontTable(LETag tableTag, size_t &length) const override;
|
||||
|
||||
public:
|
||||
PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status);
|
||||
|
||||
virtual ~PortableFontInstance();
|
||||
|
||||
virtual const void *getFontTable(LETag tableTag) const;
|
||||
const void *getFontTable(LETag tableTag, size_t &length) const override;
|
||||
|
||||
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;
|
||||
|
||||
le_int32 getUnitsPerEM() const override;
|
||||
|
||||
virtual le_uint32 getFontChecksum() const;
|
||||
|
||||
virtual le_uint32 getRawChecksum() const;
|
||||
|
||||
le_int32 getAscent() const override;
|
||||
|
||||
le_int32 getDescent() const override;
|
||||
|
||||
le_int32 getLeading() const override;
|
||||
|
||||
// We really want to inherit this method from the superclass, but some compilers
|
||||
// issue a warning if we don't implement it...
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const override;
|
||||
|
||||
// We really want to inherit this method from the superclass, but some compilers
|
||||
// issue a warning if we don't implement it...
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const override;
|
||||
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch) const override;
|
||||
|
||||
void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const override;
|
||||
|
||||
le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const override;
|
||||
|
||||
float getXPixelsPerEm() const override;
|
||||
|
||||
float getYPixelsPerEm() const override;
|
||||
|
||||
float getScaleFactorX() const override;
|
||||
|
||||
float getScaleFactorY() const override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: SimpleFontInstance.cpp
|
||||
*
|
||||
* created on: 03/30/2006
|
||||
* created by: Eric R. Mader
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uchar.h"
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LEFontInstance.h"
|
||||
|
||||
#include "layout/CanonShaping.h"
|
||||
#include "SimpleFontInstance.h"
|
||||
|
||||
SimpleFontInstance::SimpleFontInstance(float pointSize, LEErrorCode &status)
|
||||
: fPointSize(pointSize), fAscent(0), fDescent(0)
|
||||
{
|
||||
if (LE_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fAscent = static_cast<le_int32>(yUnitsToPoints(2000.0));
|
||||
fDescent = static_cast<le_int32>(yUnitsToPoints(600.0));
|
||||
}
|
||||
|
||||
SimpleFontInstance::~SimpleFontInstance()
|
||||
{
|
||||
// nothing to do...
|
||||
}
|
||||
|
||||
const void *SimpleFontInstance::getFontTable(LETag tableTag) const
|
||||
{
|
||||
if (tableTag == LE_GSUB_TABLE_TAG) {
|
||||
return CanonShaping::glyphSubstitutionTable;
|
||||
}
|
||||
|
||||
if (tableTag == LE_GDEF_TABLE_TAG) {
|
||||
return CanonShaping::glyphDefinitionTable;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SimpleFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
|
||||
{
|
||||
#if 0
|
||||
if (u_getCombiningClass((UChar32) glyph) == 0) {
|
||||
advance.fX = xUnitsToPoints(2048);
|
||||
} else {
|
||||
advance.fX = 0;
|
||||
}
|
||||
#else
|
||||
advance.fX = xUnitsToPoints(2048);
|
||||
#endif
|
||||
|
||||
advance.fY = 0;
|
||||
}
|
||||
|
||||
le_int32 SimpleFontInstance::getUnitsPerEM() const
|
||||
{
|
||||
return 2048;
|
||||
}
|
||||
|
||||
le_int32 SimpleFontInstance::getAscent() const
|
||||
{
|
||||
return fAscent;
|
||||
}
|
||||
|
||||
le_int32 SimpleFontInstance::getDescent() const
|
||||
{
|
||||
return fDescent;
|
||||
}
|
||||
|
||||
le_int32 SimpleFontInstance::getLeading() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We really want to inherit this method from the superclass, but some compilers
|
||||
// issue a warning if we don't implement it...
|
||||
LEGlyphID SimpleFontInstance::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 SimpleFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
|
||||
{
|
||||
return LEFontInstance::mapCharToGlyph(ch, mapper);
|
||||
}
|
||||
|
||||
LEGlyphID SimpleFontInstance::mapCharToGlyph(LEUnicode32 ch) const
|
||||
{
|
||||
return static_cast<LEGlyphID>(ch);
|
||||
}
|
||||
|
||||
float SimpleFontInstance::getXPixelsPerEm() const
|
||||
{
|
||||
return fPointSize;
|
||||
}
|
||||
|
||||
float SimpleFontInstance::getYPixelsPerEm() const
|
||||
{
|
||||
return fPointSize;
|
||||
}
|
||||
|
||||
float SimpleFontInstance::getScaleFactorX() const
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float SimpleFontInstance::getScaleFactorY() const
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
le_bool SimpleFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: SimpleFontInstance.h
|
||||
*
|
||||
* created on: 03/30/2006
|
||||
* created by: Eric R. Mader
|
||||
*/
|
||||
|
||||
#ifndef __SIMPLEFONTINSTANCE_H
|
||||
#define __SIMPLEFONTINSTANCE_H
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LEFontInstance.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
class SimpleFontInstance : public LEFontInstance
|
||||
{
|
||||
private:
|
||||
float fPointSize;
|
||||
le_int32 fAscent;
|
||||
le_int32 fDescent;
|
||||
|
||||
protected:
|
||||
const void *readFontTable(LETag tableTag) const;
|
||||
|
||||
public:
|
||||
SimpleFontInstance(float pointSize, LEErrorCode &status);
|
||||
|
||||
virtual ~SimpleFontInstance();
|
||||
|
||||
const void *getFontTable(LETag tableTag) const override;
|
||||
|
||||
le_int32 getUnitsPerEM() const override;
|
||||
|
||||
le_int32 getAscent() const override;
|
||||
|
||||
le_int32 getDescent() const override;
|
||||
|
||||
le_int32 getLeading() const override;
|
||||
|
||||
// We really want to inherit this method from the superclass, but some compilers
|
||||
// issue a warning if we don't implement it...
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const override;
|
||||
|
||||
// We really want to inherit this method from the superclass, but some compilers
|
||||
// issue a warning if we don't implement it...
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const override;
|
||||
|
||||
LEGlyphID mapCharToGlyph(LEUnicode32 ch) const override;
|
||||
|
||||
void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const override;
|
||||
|
||||
le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const override;
|
||||
|
||||
float getXPixelsPerEm() const override;
|
||||
|
||||
float getYPixelsPerEm() const override;
|
||||
|
||||
float getScaleFactorX() const override;
|
||||
|
||||
float getScaleFactorY() const override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/loengine.h"
|
||||
#include "PortableFontInstance.h"
|
||||
#include "SimpleFontInstance.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
le_font *le_portableFontOpen(const char *fileName,
|
||||
float pointSize,
|
||||
LEErrorCode *status)
|
||||
{
|
||||
return (le_font *) new PortableFontInstance(fileName, pointSize, *status);
|
||||
}
|
||||
|
||||
le_font *le_simpleFontOpen(float pointSize,
|
||||
LEErrorCode *status)
|
||||
{
|
||||
return (le_font *) new SimpleFontInstance(pointSize, *status);
|
||||
}
|
||||
|
||||
void le_fontClose(le_font *font)
|
||||
{
|
||||
LEFontInstance *fontInstance = (LEFontInstance *) font;
|
||||
|
||||
delete fontInstance;
|
||||
}
|
||||
|
||||
const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
return pfi->getNameString(nameID, platform, encoding, language);
|
||||
}
|
||||
|
||||
const LEUnicode16 *le_getUnicodeNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
return pfi->getUnicodeNameString(nameID, platform, encoding, language);
|
||||
}
|
||||
|
||||
void le_deleteNameString(le_font *font, const char *name)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
pfi->deleteNameString(name);
|
||||
}
|
||||
|
||||
void le_deleteUnicodeNameString(le_font *font, const LEUnicode16 *name)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
pfi->deleteNameString(name);
|
||||
}
|
||||
|
||||
le_uint32 le_getFontChecksum(le_font *font)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
return pfi->getFontChecksum();
|
||||
}
|
||||
|
||||
U_CDECL_END
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CFONTS_H
|
||||
#define __CFONTS_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
|
||||
le_font *le_portableFontOpen(const char *fileName,
|
||||
float pointSize,
|
||||
LEErrorCode *status);
|
||||
|
||||
le_font *le_simpleFontOpen(float pointSize,
|
||||
LEErrorCode *status);
|
||||
|
||||
void le_fontClose(le_font *font);
|
||||
|
||||
const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language);
|
||||
|
||||
const LEUnicode16 *le_getUnicodeNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language);
|
||||
|
||||
void le_deleteNameString(le_font *font, const char *name);
|
||||
|
||||
void le_deleteUnicodeNameString(le_font *font, const LEUnicode16 *name);
|
||||
|
||||
le_uint32 le_getFontChecksum(le_font *font);
|
||||
|
||||
#endif
|
|
@ -1,253 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LESwaps.h"
|
||||
|
||||
#include "sfnt.h"
|
||||
#include "cmaps.h"
|
||||
#include <stdio.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 = nullptr;
|
||||
le_bool found = false;
|
||||
//le_uint16 foundPlatformID = 0xFFFF;
|
||||
//le_uint16 foundPlatformSpecificID = 0xFFFF;
|
||||
le_uint32 foundOffset = 0;
|
||||
//le_uint16 foundTable = 0xFFFF;
|
||||
// first pass, look for MS table. (preferred?)
|
||||
for (i = 0; i < nSubtables && !found; i += 1) {
|
||||
const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
|
||||
|
||||
le_uint16 platformID = SWAPW(esh->platformID);
|
||||
le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID);
|
||||
if (platformID == 3) { // microsoft
|
||||
switch (platformSpecificID) {
|
||||
case 1: // Unicode BMP (UCS-2)
|
||||
case 10: // Unicode UCS-4
|
||||
foundOffset = SWAPL(esh->encodingOffset);
|
||||
//foundPlatformID = platformID;
|
||||
//foundPlatformSpecificID = platformSpecificID;
|
||||
found = true;
|
||||
//foundTable = i;
|
||||
break;
|
||||
|
||||
//default:
|
||||
// printf("%s:%d: microsoft (3) platform specific ID %d (wanted 1 or 10) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformSpecificID)), i, nSubtables);
|
||||
}
|
||||
} else {
|
||||
//printf("%s:%d: platform ID %d (wanted 3, microsoft) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformID)), i, nSubtables);
|
||||
}
|
||||
}
|
||||
|
||||
// second pass, allow non MS table
|
||||
// first pass, look for MS table. (preferred?)
|
||||
for (i = 0; i < nSubtables && !found; i += 1) {
|
||||
const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
|
||||
le_uint16 platformID = SWAPW(esh->platformID);
|
||||
le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID);
|
||||
//printf("%s:%d: table %d/%d has platform:specific %d:%d\n", __FILE__, __LINE__, i, nSubtables, platformID, platformSpecificID);
|
||||
switch(platformID) {
|
||||
case 0: // Unicode platform
|
||||
switch(platformSpecificID) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
foundOffset = SWAPL(esh->encodingOffset);
|
||||
//foundPlatformID = platformID;
|
||||
//foundPlatformSpecificID = platformSpecificID;
|
||||
//foundTable = i;
|
||||
found = true;
|
||||
break;
|
||||
|
||||
default: printf("Error: table %d (psid %d) is unknown. Skipping.\n", i, platformSpecificID); break;
|
||||
}
|
||||
break;
|
||||
|
||||
//default:
|
||||
//printf("Skipping platform id %d\n", platformID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (found)
|
||||
{
|
||||
subtable = reinterpret_cast<const CMAPEncodingSubtable*>(reinterpret_cast<const char*>(cmap) + foundOffset);
|
||||
//printf("%s:%d: using subtable #%d/%d type %d:%d\n", __FILE__, __LINE__, foundTable, nSubtables, foundPlatformID, foundPlatformSpecificID);
|
||||
} else {
|
||||
printf("%s:%d: could not find subtable.\n", __FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
le_uint16 tableFormat = SWAPW(subtable->format);
|
||||
//printf("%s:%d: table format %d\n", __FILE__, __LINE__, tableFormat);
|
||||
|
||||
switch (tableFormat) {
|
||||
case 4:
|
||||
return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
|
||||
|
||||
case 12:
|
||||
{
|
||||
const CMAPFormat12Encoding* encoding = reinterpret_cast<const CMAPFormat12Encoding*>(subtable);
|
||||
|
||||
return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s:%d: Unknown format %x.\n", __FILE__, __LINE__, (SWAPW(subtable->format)));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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 = static_cast<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 = static_cast<TTGlyphID>(unicode);
|
||||
} else {
|
||||
le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
|
||||
le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
|
||||
const le_uint16* glyphIndexTable = reinterpret_cast<const le_uint16*>(reinterpret_cast<const 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 static_cast<LEGlyphID>(SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMAPGroupMapper::~CMAPGroupMapper()
|
||||
{
|
||||
// parent destructor does it all
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2013, 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();
|
||||
|
||||
LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const override;
|
||||
|
||||
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();
|
||||
|
||||
LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const override;
|
||||
|
||||
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()
|
||||
{
|
||||
LE_DELETE_ARRAY(fcmap);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include "unicode/utimer.h"
|
||||
#include "unicode/ustdio.h"
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LayoutEngine.h"
|
||||
#include "layout/LEScripts.h"
|
||||
#include "SimpleFontInstance.h"
|
||||
#include "PortableFontInstance.h"
|
||||
|
||||
class Params {
|
||||
public:
|
||||
LEFontInstance *font;
|
||||
LEUnicode *chars;
|
||||
le_int32 charLen;
|
||||
ScriptCodes script;
|
||||
le_int32 glyphCount;
|
||||
};
|
||||
|
||||
LEUnicode ArabChars[] = {
|
||||
0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, // "English "
|
||||
0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, // MEM ALIF KAF NOON TEH WAW SHEEN
|
||||
0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E, 0 // " text."
|
||||
};
|
||||
|
||||
void iterate(void * p) {
|
||||
Params* params = static_cast<Params*>(p);
|
||||
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
LEFontInstance *font = params->font;
|
||||
LayoutEngine *engine = LayoutEngine::layoutEngineFactory(font, params->script, -1, status);
|
||||
LEGlyphID *glyphs = nullptr;
|
||||
le_int32 *indices = nullptr;
|
||||
float *positions = nullptr;
|
||||
le_int32 glyphCount = 0;
|
||||
LEUnicode *chars = params->chars;
|
||||
glyphCount = engine->layoutChars(chars, 0, params->charLen, params->charLen, true, 0.0, 0.0, status);
|
||||
glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount + 10);
|
||||
indices = LE_NEW_ARRAY(le_int32, glyphCount + 10);
|
||||
positions = LE_NEW_ARRAY(float, glyphCount + 10);
|
||||
engine->getGlyphs(glyphs, status);
|
||||
params->glyphCount = glyphCount;
|
||||
|
||||
|
||||
delete glyphs;
|
||||
delete indices;
|
||||
delete positions;
|
||||
delete engine;
|
||||
//delete font;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
double len=10.0;
|
||||
for(int i=1;i<argc;i++) {
|
||||
puts("arg:");
|
||||
puts(argv[i]);
|
||||
if(argv[i][0]=='p') {
|
||||
printf("hit enter-pid=%d", getpid());
|
||||
getchar();
|
||||
} else if(argv[i][0]>='0' && argv[i][0]<='9') {
|
||||
len = (1.0)*(argv[i][0]-'0');
|
||||
}
|
||||
}
|
||||
u_printf("leperf: Testing %s for %.fs...\n", U_ICU_VERSION, len);
|
||||
//LEErrorCode status = LE_NO_ERROR;
|
||||
//uloc_setDefault("en_US", &status);
|
||||
Params p;
|
||||
|
||||
#if 0
|
||||
p.script = arabScriptCode;
|
||||
p.chars = ArabChars;
|
||||
p.charLen = sizeof(ArabChars)/sizeof(ArabChars[0]);
|
||||
#else
|
||||
p.script = latnScriptCode;
|
||||
p.chars = new LEUnicode[257];
|
||||
for(int i=0;i<256;i++) {
|
||||
p.chars[i] = i+1;
|
||||
}
|
||||
p.chars[256] = 0;
|
||||
p.charLen = 256;
|
||||
#endif
|
||||
|
||||
int32_t loopCount;
|
||||
double timeTaken;
|
||||
double timeNs;
|
||||
#if 0
|
||||
p.font = new SimpleFontInstance(12, status);
|
||||
u_printf("leperf: Running SFI...\r");
|
||||
timeTaken = utimer_loopUntilDone(len, &loopCount, iterate, &p);
|
||||
u_printf("leperf: SFI .. took %.fs %.2fns/ea\nleperf: .. iter= %d\n", timeTaken, 1000000000.0*(timeTaken/(double)loopCount), (int32_t)loopCount);
|
||||
delete p.font;
|
||||
#endif
|
||||
PortableFontInstance *font;
|
||||
LEErrorCode fontStatus = LE_NO_ERROR;
|
||||
const char *fontPath = "myfont.ttf";
|
||||
|
||||
font = new PortableFontInstance(fontPath, 12, fontStatus);
|
||||
|
||||
p.font = font;
|
||||
loopCount=0;
|
||||
u_printf("leperf: testing %s\n", fontPath);
|
||||
u_printf("leperf: Running ...\r");
|
||||
timeTaken = utimer_loopUntilDone(len, &loopCount, iterate, &p);
|
||||
timeNs = 1000000000.0 * (timeTaken / static_cast<double>(loopCount));
|
||||
u_printf("leperf: PFI .. took %.fs %.2fns/ea\nleperf: .. iter= %d\n", timeTaken, timeNs, loopCount);
|
||||
u_printf("leperf: DATA|\"%s\"|%.2f|\n", U_ICU_VERSION, timeNs);
|
||||
u_printf("leperf: glyphs=%d\n", p.glyphCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// hack - #include these for easier build.
|
||||
#include "SimpleFontInstance.cpp"
|
||||
#include "PortableFontInstance.cpp"
|
||||
#include "cmaps.cpp"
|
||||
#include "FontTableCache.cpp"
|
|
@ -1,455 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
****************************************************************************/
|
||||
/***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2013, 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
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "unicode/uchar.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/uscript.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/ctest.h"
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LEScripts.h"
|
||||
|
||||
#include "letsutil.h"
|
||||
#include "letest.h"
|
||||
|
||||
#include "xmlreader.h"
|
||||
|
||||
#include "xmlparser.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//U_NAMESPACE_USE
|
||||
|
||||
#define CH_COMMA 0x002C
|
||||
|
||||
static le_uint32 *getHexArray(const UnicodeString &numbers, int32_t &arraySize)
|
||||
{
|
||||
int32_t offset = -1;
|
||||
|
||||
arraySize = 1;
|
||||
while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
|
||||
arraySize += 1;
|
||||
}
|
||||
|
||||
le_uint32 *array = NEW_ARRAY(le_uint32, arraySize);
|
||||
char number[16];
|
||||
le_int32 count = 0;
|
||||
le_int32 start = 0, end = 0;
|
||||
le_int32 len = 0;
|
||||
|
||||
// trim leading whitespace
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
start = end + 1;
|
||||
|
||||
sscanf(number, "%x", &array[count++]);
|
||||
|
||||
// trim whitespace following the comma
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// trim trailing whitespace
|
||||
end = numbers.length();
|
||||
while(u_isUWhiteSpace(numbers[end - 1])) {
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
sscanf(number, "%x", &array[count]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static float *getFloatArray(const UnicodeString &numbers, int32_t &arraySize)
|
||||
{
|
||||
int32_t offset = -1;
|
||||
|
||||
arraySize = 1;
|
||||
while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
|
||||
arraySize += 1;
|
||||
}
|
||||
|
||||
float *array = NEW_ARRAY(float, arraySize);
|
||||
char number[32];
|
||||
le_int32 count = 0;
|
||||
le_int32 start = 0, end = 0;
|
||||
le_int32 len = 0;
|
||||
|
||||
// trim leading whitespace
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
start = end + 1;
|
||||
|
||||
sscanf(number, "%f", &array[count++]);
|
||||
|
||||
// trim whiteapce following the comma
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
}
|
||||
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
// trim trailing whitespace
|
||||
end = numbers.length();
|
||||
while(u_isUWhiteSpace(numbers[end - 1])) {
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
sscanf(number, "%f", &array[count]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
U_CDECL_BEGIN
|
||||
void readTestFile(const char *testFilePath, TestCaseCallback callback)
|
||||
{
|
||||
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UXMLParser *parser = UXMLParser::createParser(status);
|
||||
UXMLElement *root = parser->parseFile(testFilePath, status);
|
||||
|
||||
if (root == nullptr) {
|
||||
log_err("Could not open the test data file: %s\n", testFilePath);
|
||||
delete parser;
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case");
|
||||
UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text");
|
||||
UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font");
|
||||
UnicodeString result_glyphs = UNICODE_STRING_SIMPLE("result-glyphs");
|
||||
UnicodeString result_indices = UNICODE_STRING_SIMPLE("result-indices");
|
||||
UnicodeString result_positions = UNICODE_STRING_SIMPLE("result-positions");
|
||||
|
||||
// test-case attributes
|
||||
UnicodeString id_attr = UNICODE_STRING_SIMPLE("id");
|
||||
UnicodeString script_attr = UNICODE_STRING_SIMPLE("script");
|
||||
UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang");
|
||||
|
||||
// test-font attributes
|
||||
UnicodeString name_attr = UNICODE_STRING_SIMPLE("name");
|
||||
UnicodeString ver_attr = UNICODE_STRING_SIMPLE("version");
|
||||
UnicodeString cksum_attr = UNICODE_STRING_SIMPLE("checksum");
|
||||
|
||||
const UXMLElement *testCase;
|
||||
int32_t tc = 0;
|
||||
|
||||
while((testCase = root->nextChildElement(tc)) != nullptr) {
|
||||
if (testCase->getTagName().compare(test_case) == 0) {
|
||||
char *id = getCString(testCase->getAttribute(id_attr));
|
||||
char *script = getCString(testCase->getAttribute(script_attr));
|
||||
char *lang = getCString(testCase->getAttribute(lang_attr));
|
||||
char *fontName = nullptr;
|
||||
char *fontVer = nullptr;
|
||||
char *fontCksum = nullptr;
|
||||
const UXMLElement *element;
|
||||
int32_t ec = 0;
|
||||
int32_t charCount = 0;
|
||||
UScriptCode scriptCode;
|
||||
le_int32 languageCode = -1;
|
||||
UnicodeString text, glyphs, indices, positions;
|
||||
int32_t glyphCount = 0, indexCount = 0, positionCount = 0;
|
||||
TestResult expected = {0, nullptr, nullptr, nullptr};
|
||||
|
||||
uscript_getCode(script, &scriptCode, 1, &status);
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("invalid script name: %s.\n", script);
|
||||
goto free_c_strings;
|
||||
}
|
||||
|
||||
if (lang != nullptr) {
|
||||
languageCode = getLanguageCode(lang);
|
||||
|
||||
if (languageCode < 0) {
|
||||
log_err("invalid language name: %s.\n", lang);
|
||||
goto free_c_strings;
|
||||
}
|
||||
}
|
||||
|
||||
while((element = testCase->nextChildElement(ec)) != nullptr) {
|
||||
UnicodeString tag = element->getTagName();
|
||||
|
||||
// TODO: make sure that each element is only used once.
|
||||
if (tag.compare(test_font) == 0) {
|
||||
fontName = getCString(element->getAttribute(name_attr));
|
||||
fontVer = getCString(element->getAttribute(ver_attr));
|
||||
fontCksum = getCString(element->getAttribute(cksum_attr));
|
||||
|
||||
} else if (tag.compare(test_text) == 0) {
|
||||
text = element->getText(true);
|
||||
charCount = text.length();
|
||||
} else if (tag.compare(result_glyphs) == 0) {
|
||||
glyphs = element->getText(true);
|
||||
} else if (tag.compare(result_indices) == 0) {
|
||||
indices = element->getText(true);
|
||||
} else if (tag.compare(result_positions) == 0) {
|
||||
positions = element->getText(true);
|
||||
} else {
|
||||
// an unknown tag...
|
||||
char *cTag = getCString(&tag);
|
||||
|
||||
log_info("Test %s: unknown element with tag \"%s\"\n", id, cTag);
|
||||
freeCString(cTag);
|
||||
}
|
||||
}
|
||||
|
||||
expected.glyphs = (LEGlyphID *) getHexArray(glyphs, glyphCount);
|
||||
expected.indices = (le_int32 *) getHexArray(indices, indexCount);
|
||||
expected.positions = getFloatArray(positions, positionCount);
|
||||
|
||||
expected.glyphCount = glyphCount;
|
||||
|
||||
if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) {
|
||||
log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n",
|
||||
id, charCount, glyphCount, indexCount, positionCount);
|
||||
goto free_expected;
|
||||
};
|
||||
|
||||
(*callback)(id, fontName, fontVer, fontCksum, scriptCode, languageCode, text.getBuffer(), charCount, &expected);
|
||||
|
||||
free_expected:
|
||||
DELETE_ARRAY(expected.positions);
|
||||
DELETE_ARRAY(expected.indices);
|
||||
DELETE_ARRAY(expected.glyphs);
|
||||
|
||||
free_c_strings:
|
||||
freeCString(fontCksum);
|
||||
freeCString(fontVer);
|
||||
freeCString(fontName);
|
||||
freeCString(lang);
|
||||
freeCString(script);
|
||||
freeCString(id);
|
||||
}
|
||||
}
|
||||
|
||||
delete root;
|
||||
delete parser;
|
||||
#endif
|
||||
}
|
||||
U_CDECL_END
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* © 2016 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XMLREADER_H
|
||||
#define __XMLREADER_H
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "letest.h"
|
||||
|
||||
typedef void (*TestCaseCallback) (const char *testID,
|
||||
const char *fontName,
|
||||
const char *fontVersion,
|
||||
const char *fontChecksum,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
const LEUnicode *text,
|
||||
le_int32 charCount,
|
||||
TestResult *expected);
|
||||
|
||||
U_CAPI void readTestFile(const char *testFilePath, TestCaseCallback callback);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue