fontservices/textshaperplugin/test/letest/PortableFontInstance.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2  *******************************************************************************
       
     3  *
       
     4  *   Copyright (C) 1999-2003, International Business Machines
       
     5  *   Corporation and others.  All Rights Reserved.
       
     6  *
       
     7  *******************************************************************************
       
     8  *   file name:  PortableFontInstance.cpp
       
     9  *
       
    10  *   created on: 11/22/1999
       
    11  *   created by: Eric R. Mader
       
    12  */
       
    13 
       
    14 #include <stdio.h>
       
    15 
       
    16 #include "layout/LETypes.h"
       
    17 #include "layout/LEFontInstance.h"
       
    18 #include "layout/LESwaps.h"
       
    19 
       
    20 #include "PortableFontInstance.h"
       
    21 
       
    22 #include "sfnt.h"
       
    23 
       
    24 #include <string.h>
       
    25 
       
    26 //
       
    27 // Finds the high bit by binary searching
       
    28 // through the bits in n.
       
    29 //
       
    30 le_int8 PortableFontInstance::highBit(le_int32 value)
       
    31 {
       
    32     if (value <= 0) {
       
    33         return -32;
       
    34     }
       
    35 
       
    36     le_uint8 bit = 0;
       
    37 
       
    38     if (value >= 1 << 16) {
       
    39         value >>= 16;
       
    40         bit += 16;
       
    41     }
       
    42 
       
    43     if (value >= 1 << 8) {
       
    44         value >>= 8;
       
    45         bit += 8;
       
    46     }
       
    47 
       
    48     if (value >= 1 << 4) {
       
    49         value >>= 4;
       
    50         bit += 4;
       
    51     }
       
    52 
       
    53     if (value >= 1 << 2) {
       
    54         value >>= 2;
       
    55         bit += 2;
       
    56     }
       
    57 
       
    58     if (value >= 1 << 1) {
       
    59         value >>= 1;
       
    60         bit += 1;
       
    61     }
       
    62 
       
    63     return bit;
       
    64 }
       
    65 
       
    66 
       
    67 PortableFontInstance::PortableFontInstance(char *fileName, float pointSize, LEErrorCode &status)
       
    68     : fFile(NULL), fUnitsPerEM(0), fPointSize(pointSize), fAscent(0), fDescent(0), fLeading(0),
       
    69       fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
       
    70 {
       
    71     if (LE_FAILURE(status)) {
       
    72         return;
       
    73     }
       
    74 
       
    75     // open the font file
       
    76     fFile = fopen(fileName, "rb");
       
    77 
       
    78     if (fFile == NULL) {
       
    79         status = LE_FONT_FILE_NOT_FOUND_ERROR;
       
    80         return;
       
    81     }
       
    82 
       
    83     // read in the directory
       
    84     SFNTDirectory tempDir;
       
    85 
       
    86     fread(&tempDir, sizeof tempDir, 1, fFile);
       
    87 
       
    88     le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
       
    89     const LETag headTag = LE_HEAD_TABLE_TAG;
       
    90     const LETag hheaTag = LE_HHEA_TABLE_TAG;
       
    91     const HEADTable *headTable = NULL;
       
    92     const HHEATable *hheaTable = NULL;
       
    93     le_uint16 numTables = 0;
       
    94 
       
    95     fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
       
    96 
       
    97     if (fDirectory == NULL) {
       
    98         status = LE_MEMORY_ALLOCATION_ERROR;
       
    99         goto error_exit;
       
   100     }
       
   101 
       
   102     fseek(fFile, 0L, SEEK_SET);
       
   103     fread((void *) fDirectory, sizeof(char), dirSize, fFile);
       
   104 
       
   105     //
       
   106     // We calculate these numbers 'cause some fonts
       
   107     // have bogus values for them in the directory header.
       
   108     //
       
   109     numTables = SWAPW(fDirectory->numTables);
       
   110     fDirPower = 1 << highBit(numTables);
       
   111     fDirExtra = numTables - fDirPower;
       
   112 
       
   113     // read unitsPerEm from 'head' table
       
   114     headTable = (const HEADTable *) readFontTable(headTag);
       
   115 
       
   116     if (headTable == NULL) {
       
   117         status = LE_MISSING_FONT_TABLE_ERROR;
       
   118         goto error_exit;
       
   119     }
       
   120 
       
   121     fUnitsPerEM = SWAPW(headTable->unitsPerEm);
       
   122     deleteTable(headTable);
       
   123 
       
   124     hheaTable = (HHEATable *) readFontTable(hheaTag);
       
   125 
       
   126     if (hheaTable == NULL) {
       
   127         status = LE_MISSING_FONT_TABLE_ERROR;
       
   128         goto error_exit;
       
   129     }
       
   130 
       
   131     fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
       
   132     fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
       
   133     fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
       
   134 
       
   135     fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
       
   136 
       
   137     deleteTable((void *) hheaTable);
       
   138 
       
   139     fCMAPMapper = findUnicodeMapper();
       
   140 
       
   141     if (fCMAPMapper == NULL) {
       
   142         status = LE_MISSING_FONT_TABLE_ERROR;
       
   143         goto error_exit;
       
   144     }
       
   145 
       
   146     return;
       
   147 
       
   148 error_exit:
       
   149     fclose(fFile);
       
   150     fFile = NULL;
       
   151     return;
       
   152 }
       
   153 
       
   154 PortableFontInstance::~PortableFontInstance()
       
   155 {
       
   156     if (fFile != NULL) {
       
   157         fclose(fFile);
       
   158 
       
   159         deleteTable(fHMTXTable);
       
   160 
       
   161         delete fCMAPMapper;
       
   162 
       
   163         LE_DELETE_ARRAY(fDirectory);
       
   164     }
       
   165 };
       
   166 
       
   167 void PortableFontInstance::deleteTable(const void *table) const
       
   168 {
       
   169     LE_DELETE_ARRAY(table);
       
   170 }
       
   171 
       
   172 const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
       
   173 {
       
   174     if (fDirectory != NULL) {
       
   175         le_uint16 table = 0;
       
   176         le_uint16 probe = fDirPower;
       
   177 
       
   178         if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
       
   179             table = fDirExtra;
       
   180         }
       
   181 
       
   182         while (probe > (1 << 0)) {
       
   183             probe >>= 1;
       
   184 
       
   185             if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
       
   186                 table += probe;
       
   187             }
       
   188         }
       
   189 
       
   190         if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
       
   191             return &fDirectory->tableDirectory[table];
       
   192         }
       
   193     }
       
   194 
       
   195     return NULL;
       
   196 }
       
   197 
       
   198 const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
       
   199 {
       
   200     const DirectoryEntry *entry = findTable(tag);
       
   201 
       
   202     if (entry == NULL) {
       
   203         *length = 0;
       
   204         return NULL;
       
   205     }
       
   206 
       
   207     *length = SWAPL(entry->length);
       
   208 
       
   209     void *table = LE_NEW_ARRAY(char, *length);
       
   210 
       
   211     if (table != NULL) {
       
   212         fseek(fFile, SWAPL(entry->offset), SEEK_SET);
       
   213         fread(table, sizeof(char), *length, fFile);
       
   214     }
       
   215 
       
   216     return table;
       
   217 }
       
   218 
       
   219 const void *PortableFontInstance::getFontTable(LETag tableTag) const
       
   220 {
       
   221     return FontTableCache::find(tableTag);
       
   222 }
       
   223 
       
   224 const void *PortableFontInstance::readFontTable(LETag tableTag) const
       
   225 {
       
   226     le_uint32 len;
       
   227 
       
   228     return readTable(tableTag, &len);
       
   229 }
       
   230 
       
   231 CMAPMapper *PortableFontInstance::findUnicodeMapper()
       
   232 {
       
   233     LETag cmapTag = LE_CMAP_TABLE_TAG;
       
   234     const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
       
   235 
       
   236     if (cmap == NULL) {
       
   237         return NULL;
       
   238     }
       
   239 
       
   240     return CMAPMapper::createUnicodeMapper(cmap);
       
   241 }
       
   242 
       
   243 
       
   244 void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
       
   245 {
       
   246     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
       
   247 
       
   248     if (fHMTXTable == NULL) {
       
   249         LETag maxpTag = LE_MAXP_TABLE_TAG;
       
   250         LETag hmtxTag = LE_HMTX_TABLE_TAG;
       
   251         const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
       
   252         PortableFontInstance *realThis = (PortableFontInstance *) this;
       
   253 
       
   254         if (maxpTable != NULL) {
       
   255             realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
       
   256             deleteTable(maxpTable);
       
   257         }
       
   258 
       
   259         realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
       
   260     }
       
   261 
       
   262     le_uint16 index = ttGlyph;
       
   263 
       
   264     if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
       
   265         advance.fX = advance.fY = 0;
       
   266         return;
       
   267     }
       
   268 
       
   269     if (ttGlyph >= fNumLongHorMetrics) {
       
   270         index = fNumLongHorMetrics - 1;
       
   271     }
       
   272 
       
   273     advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
       
   274     advance.fY = 0;
       
   275 }
       
   276 
       
   277 le_bool PortableFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
       
   278 {
       
   279     return FALSE;
       
   280 }
       
   281