PortableFontInstance.cpp revision ac04d0bbe12b3ef54518635711412f178cb4d16
1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   Copyright (C) 1999-2007, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   file name:  PortableFontInstance.cpp
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   created on: 11/22/1999
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   created by: Eric R. Mader
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LETypes.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LEFontInstance.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LESwaps.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "PortableFontInstance.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "letest.h"
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "sfnt.h"
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Finds the high bit by binary searching
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// through the bits in n.
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int8 PortableFontInstance::highBit(le_int32 value)
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value <= 0) {
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -32;
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_uint8 bit = 0;
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value >= 1 << 16) {
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value >>= 16;
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bit += 16;
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value >= 1 << 8) {
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value >>= 8;
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bit += 8;
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value >= 1 << 4) {
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value >>= 4;
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bit += 4;
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value >= 1 << 2) {
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value >>= 2;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bit += 2;
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (value >= 1 << 1) {
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value >>= 1;
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bit += 1;
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return bit;
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruPortableFontInstance::PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status)
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    : fFile(NULL), fPointSize(pointSize), fUnitsPerEM(0), fFontChecksum(0), fAscent(0), fDescent(0), fLeading(0),
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDirectory(NULL), fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (LE_FAILURE(status)) {
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // open the font file
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fFile = fopen(fileName, "rb");
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fFile == NULL) {
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = LE_FONT_FILE_NOT_FOUND_ERROR;
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // read in the directory
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    SFNTDirectory tempDir;
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fread(&tempDir, sizeof tempDir, 1, fFile);
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const LETag headTag = LE_HEAD_TABLE_TAG;
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const LETag hheaTag = LE_HHEA_TABLE_TAG;
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const HEADTable *headTable = NULL;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const HHEATable *hheaTable = NULL;
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  const NAMETable *nameTable = NULL;
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_uint16 numTables = 0;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDirectory = (const SFNTDirectory *) NEW_ARRAY(char, dirSize);
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fDirectory == NULL) {
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = LE_MEMORY_ALLOCATION_ERROR;
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto error_exit;
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fseek(fFile, 0L, SEEK_SET);
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fread((void *) fDirectory, sizeof(char), dirSize, fFile);
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We calculate these numbers 'cause some fonts
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // have bogus values for them in the directory header.
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    numTables = SWAPW(fDirectory->numTables);
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDirPower = 1 << highBit(numTables);
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDirExtra = numTables - fDirPower;
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // read unitsPerEm from 'head' table
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    headTable = (const HEADTable *) readFontTable(headTag);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (headTable == NULL) {
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = LE_MISSING_FONT_TABLE_ERROR;
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto error_exit;
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fUnitsPerEM   = SWAPW(headTable->unitsPerEm);
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fFontChecksum = SWAPL(headTable->checksumAdjustment);
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    deleteTable(headTable);
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //nameTable = (NAMETable *) readFontTable(nameTag);
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //if (nameTable == NULL) {
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    status = LE_MISSING_FONT_TABLE_ERROR;
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    goto error_exit;
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //}
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //fFontVersionString = findName(nameTable, NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //if (fFontVersionString == NULL) {
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    status = LE_MISSING_FONT_TABLE_ERROR;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    goto error_exit;
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //}
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //deleteTable(nameTable);
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    hheaTable = (HHEATable *) readFontTable(hheaTag);
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (hheaTable == NULL) {
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = LE_MISSING_FONT_TABLE_ERROR;
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto error_exit;
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    deleteTable((void *) hheaTable);
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fCMAPMapper = findUnicodeMapper();
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fCMAPMapper == NULL) {
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = LE_MISSING_FONT_TABLE_ERROR;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto error_exit;
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruerror_exit:
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fclose(fFile);
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fFile = NULL;
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruPortableFontInstance::~PortableFontInstance()
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fFile != NULL) {
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fclose(fFile);
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        deleteTable(fHMTXTable);
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        deleteTable(fNAMETable);
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete fCMAPMapper;
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        DELETE_ARRAY(fDirectory);
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid PortableFontInstance::deleteTable(const void *table) const
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DELETE_ARRAY(table);
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fDirectory != NULL) {
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_uint16 table = 0;
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_uint16 probe = fDirPower;
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            table = fDirExtra;
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (probe > (1 << 0)) {
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            probe >>= 1;
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                table += probe;
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return &fDirectory->tableDirectory[table];
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const DirectoryEntry *entry = findTable(tag);
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (entry == NULL) {
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *length = 0;
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *length = SWAPL(entry->length);
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void *table = NEW_ARRAY(char, *length);
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (table != NULL) {
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fseek(fFile, SWAPL(entry->offset), SEEK_SET);
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fread(table, sizeof(char), *length, fFile);
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return table;
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *PortableFontInstance::getFontTable(LETag tableTag) const
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FontTableCache::find(tableTag);
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *PortableFontInstance::readFontTable(LETag tableTag) const
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_uint32 len;
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return readTable(tableTag, &len);
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPMapper *PortableFontInstance::findUnicodeMapper()
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LETag cmapTag = LE_CMAP_TABLE_TAG;
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (cmap == NULL) {
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return CMAPMapper::createUnicodeMapper(cmap);
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fNAMETable == NULL) {
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LETag nameTag = LE_NAME_TABLE_TAG;
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        PortableFontInstance *realThis = (PortableFontInstance *) this;
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (realThis->fNAMETable != NULL) {
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            realThis->fNameCount        = SWAPW(realThis->fNAMETable->count);
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(le_int32 i = 0; i < fNameCount; i += 1) {
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID == encodingID) &&
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            le_uint16 length = SWAPW(nameRecord->length);
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char *result = NEW_ARRAY(char, length + 2);
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ARRAY_COPY(result, name, length);
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            result[length] = result[length + 1] = 0;
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return result;
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid PortableFontInstance::deleteNameString(const char *name) const
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DELETE_ARRAY(name);
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fHMTXTable == NULL) {
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LETag maxpTag = LE_MAXP_TABLE_TAG;
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LETag hmtxTag = LE_HMTX_TABLE_TAG;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        PortableFontInstance *realThis = (PortableFontInstance *) this;
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (maxpTable != NULL) {
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            deleteTable(maxpTable);
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_uint16 index = ttGlyph;
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        advance.fX = advance.fY = 0;
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ttGlyph >= fNumLongHorMetrics) {
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        index = fNumLongHorMetrics - 1;
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    advance.fY = 0;
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 PortableFontInstance::getUnitsPerEM() const
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fUnitsPerEM;
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_uint32 PortableFontInstance::getFontChecksum() const
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fFontChecksum;
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 PortableFontInstance::getAscent() const
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fAscent;
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 PortableFontInstance::getDescent() const
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fDescent;
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 PortableFontInstance::getLeading() const
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fLeading;
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// We really want to inherit this method from the superclass, but some compilers
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// issue a warning if we don't implement it...
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// We really want to inherit this method from the superclass, but some compilers
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// issue a warning if we don't implement it...
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LEFontInstance::mapCharToGlyph(ch, mapper);
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fCMAPMapper->unicodeToGlyph(ch);
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufloat PortableFontInstance::getXPixelsPerEm() const
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fPointSize;
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufloat PortableFontInstance::getYPixelsPerEm() const
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fPointSize;
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufloat PortableFontInstance::getScaleFactorX() const
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 1.0;
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufloat PortableFontInstance::getScaleFactorY() const
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 1.0;
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
401