1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/test/letest/PortableFontInstance.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,281 @@
1.4 +/*
1.5 + *******************************************************************************
1.6 + *
1.7 + * Copyright (C) 1999-2003, International Business Machines
1.8 + * Corporation and others. All Rights Reserved.
1.9 + *
1.10 + *******************************************************************************
1.11 + * file name: PortableFontInstance.cpp
1.12 + *
1.13 + * created on: 11/22/1999
1.14 + * created by: Eric R. Mader
1.15 + */
1.16 +
1.17 +#include <stdio.h>
1.18 +
1.19 +#include "layout/LETypes.h"
1.20 +#include "layout/LEFontInstance.h"
1.21 +#include "layout/LESwaps.h"
1.22 +
1.23 +#include "PortableFontInstance.h"
1.24 +
1.25 +#include "sfnt.h"
1.26 +
1.27 +#include <string.h>
1.28 +
1.29 +//
1.30 +// Finds the high bit by binary searching
1.31 +// through the bits in n.
1.32 +//
1.33 +le_int8 PortableFontInstance::highBit(le_int32 value)
1.34 +{
1.35 + if (value <= 0) {
1.36 + return -32;
1.37 + }
1.38 +
1.39 + le_uint8 bit = 0;
1.40 +
1.41 + if (value >= 1 << 16) {
1.42 + value >>= 16;
1.43 + bit += 16;
1.44 + }
1.45 +
1.46 + if (value >= 1 << 8) {
1.47 + value >>= 8;
1.48 + bit += 8;
1.49 + }
1.50 +
1.51 + if (value >= 1 << 4) {
1.52 + value >>= 4;
1.53 + bit += 4;
1.54 + }
1.55 +
1.56 + if (value >= 1 << 2) {
1.57 + value >>= 2;
1.58 + bit += 2;
1.59 + }
1.60 +
1.61 + if (value >= 1 << 1) {
1.62 + value >>= 1;
1.63 + bit += 1;
1.64 + }
1.65 +
1.66 + return bit;
1.67 +}
1.68 +
1.69 +
1.70 +PortableFontInstance::PortableFontInstance(char *fileName, float pointSize, LEErrorCode &status)
1.71 + : fFile(NULL), fUnitsPerEM(0), fPointSize(pointSize), fAscent(0), fDescent(0), fLeading(0),
1.72 + fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
1.73 +{
1.74 + if (LE_FAILURE(status)) {
1.75 + return;
1.76 + }
1.77 +
1.78 + // open the font file
1.79 + fFile = fopen(fileName, "rb");
1.80 +
1.81 + if (fFile == NULL) {
1.82 + status = LE_FONT_FILE_NOT_FOUND_ERROR;
1.83 + return;
1.84 + }
1.85 +
1.86 + // read in the directory
1.87 + SFNTDirectory tempDir;
1.88 +
1.89 + fread(&tempDir, sizeof tempDir, 1, fFile);
1.90 +
1.91 + le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
1.92 + const LETag headTag = LE_HEAD_TABLE_TAG;
1.93 + const LETag hheaTag = LE_HHEA_TABLE_TAG;
1.94 + const HEADTable *headTable = NULL;
1.95 + const HHEATable *hheaTable = NULL;
1.96 + le_uint16 numTables = 0;
1.97 +
1.98 + fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
1.99 +
1.100 + if (fDirectory == NULL) {
1.101 + status = LE_MEMORY_ALLOCATION_ERROR;
1.102 + goto error_exit;
1.103 + }
1.104 +
1.105 + fseek(fFile, 0L, SEEK_SET);
1.106 + fread((void *) fDirectory, sizeof(char), dirSize, fFile);
1.107 +
1.108 + //
1.109 + // We calculate these numbers 'cause some fonts
1.110 + // have bogus values for them in the directory header.
1.111 + //
1.112 + numTables = SWAPW(fDirectory->numTables);
1.113 + fDirPower = 1 << highBit(numTables);
1.114 + fDirExtra = numTables - fDirPower;
1.115 +
1.116 + // read unitsPerEm from 'head' table
1.117 + headTable = (const HEADTable *) readFontTable(headTag);
1.118 +
1.119 + if (headTable == NULL) {
1.120 + status = LE_MISSING_FONT_TABLE_ERROR;
1.121 + goto error_exit;
1.122 + }
1.123 +
1.124 + fUnitsPerEM = SWAPW(headTable->unitsPerEm);
1.125 + deleteTable(headTable);
1.126 +
1.127 + hheaTable = (HHEATable *) readFontTable(hheaTag);
1.128 +
1.129 + if (hheaTable == NULL) {
1.130 + status = LE_MISSING_FONT_TABLE_ERROR;
1.131 + goto error_exit;
1.132 + }
1.133 +
1.134 + fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
1.135 + fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
1.136 + fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
1.137 +
1.138 + fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
1.139 +
1.140 + deleteTable((void *) hheaTable);
1.141 +
1.142 + fCMAPMapper = findUnicodeMapper();
1.143 +
1.144 + if (fCMAPMapper == NULL) {
1.145 + status = LE_MISSING_FONT_TABLE_ERROR;
1.146 + goto error_exit;
1.147 + }
1.148 +
1.149 + return;
1.150 +
1.151 +error_exit:
1.152 + fclose(fFile);
1.153 + fFile = NULL;
1.154 + return;
1.155 +}
1.156 +
1.157 +PortableFontInstance::~PortableFontInstance()
1.158 +{
1.159 + if (fFile != NULL) {
1.160 + fclose(fFile);
1.161 +
1.162 + deleteTable(fHMTXTable);
1.163 +
1.164 + delete fCMAPMapper;
1.165 +
1.166 + LE_DELETE_ARRAY(fDirectory);
1.167 + }
1.168 +};
1.169 +
1.170 +void PortableFontInstance::deleteTable(const void *table) const
1.171 +{
1.172 + LE_DELETE_ARRAY(table);
1.173 +}
1.174 +
1.175 +const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
1.176 +{
1.177 + if (fDirectory != NULL) {
1.178 + le_uint16 table = 0;
1.179 + le_uint16 probe = fDirPower;
1.180 +
1.181 + if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
1.182 + table = fDirExtra;
1.183 + }
1.184 +
1.185 + while (probe > (1 << 0)) {
1.186 + probe >>= 1;
1.187 +
1.188 + if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
1.189 + table += probe;
1.190 + }
1.191 + }
1.192 +
1.193 + if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
1.194 + return &fDirectory->tableDirectory[table];
1.195 + }
1.196 + }
1.197 +
1.198 + return NULL;
1.199 +}
1.200 +
1.201 +const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
1.202 +{
1.203 + const DirectoryEntry *entry = findTable(tag);
1.204 +
1.205 + if (entry == NULL) {
1.206 + *length = 0;
1.207 + return NULL;
1.208 + }
1.209 +
1.210 + *length = SWAPL(entry->length);
1.211 +
1.212 + void *table = LE_NEW_ARRAY(char, *length);
1.213 +
1.214 + if (table != NULL) {
1.215 + fseek(fFile, SWAPL(entry->offset), SEEK_SET);
1.216 + fread(table, sizeof(char), *length, fFile);
1.217 + }
1.218 +
1.219 + return table;
1.220 +}
1.221 +
1.222 +const void *PortableFontInstance::getFontTable(LETag tableTag) const
1.223 +{
1.224 + return FontTableCache::find(tableTag);
1.225 +}
1.226 +
1.227 +const void *PortableFontInstance::readFontTable(LETag tableTag) const
1.228 +{
1.229 + le_uint32 len;
1.230 +
1.231 + return readTable(tableTag, &len);
1.232 +}
1.233 +
1.234 +CMAPMapper *PortableFontInstance::findUnicodeMapper()
1.235 +{
1.236 + LETag cmapTag = LE_CMAP_TABLE_TAG;
1.237 + const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
1.238 +
1.239 + if (cmap == NULL) {
1.240 + return NULL;
1.241 + }
1.242 +
1.243 + return CMAPMapper::createUnicodeMapper(cmap);
1.244 +}
1.245 +
1.246 +
1.247 +void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
1.248 +{
1.249 + TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
1.250 +
1.251 + if (fHMTXTable == NULL) {
1.252 + LETag maxpTag = LE_MAXP_TABLE_TAG;
1.253 + LETag hmtxTag = LE_HMTX_TABLE_TAG;
1.254 + const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
1.255 + PortableFontInstance *realThis = (PortableFontInstance *) this;
1.256 +
1.257 + if (maxpTable != NULL) {
1.258 + realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
1.259 + deleteTable(maxpTable);
1.260 + }
1.261 +
1.262 + realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
1.263 + }
1.264 +
1.265 + le_uint16 index = ttGlyph;
1.266 +
1.267 + if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
1.268 + advance.fX = advance.fY = 0;
1.269 + return;
1.270 + }
1.271 +
1.272 + if (ttGlyph >= fNumLongHorMetrics) {
1.273 + index = fNumLongHorMetrics - 1;
1.274 + }
1.275 +
1.276 + advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
1.277 + advance.fY = 0;
1.278 +}
1.279 +
1.280 +le_bool PortableFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
1.281 +{
1.282 + return FALSE;
1.283 +}
1.284 +