Home | History | Annotate | Download | only in hb-icu-le
      1 /*
      2  *******************************************************************************
      3  *
      4  *   Copyright (C) 1999-2008, 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 "letest.h"
     23 #include "sfnt.h"
     24 
     25 #include <string.h>
     26 
     27 
     28 PortableFontInstance::PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status)
     29     : fFace(face), fXScale(xScale), fYScale(yScale), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
     30       fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
     31 {
     32     if (LE_FAILURE(status)) {
     33         return;
     34     }
     35 
     36     const LETag hheaTag = LE_HHEA_TABLE_TAG;
     37     const HHEATable *hheaTable = NULL;
     38 
     39     fUnitsPerEM = hb_face_get_upem (face);
     40 
     41     hheaTable = (HHEATable *) getFontTable(hheaTag);
     42 
     43     if (hheaTable == NULL) {
     44         status = LE_MISSING_FONT_TABLE_ERROR;
     45 	return;
     46     }
     47 
     48     fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
     49     fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
     50     fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
     51 
     52     fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
     53 
     54     fCMAPMapper = findUnicodeMapper();
     55 
     56     if (fCMAPMapper == NULL) {
     57         status = LE_MISSING_FONT_TABLE_ERROR;
     58 	return;
     59     }
     60 }
     61 
     62 PortableFontInstance::~PortableFontInstance()
     63 {
     64     if (fCMAPMapper)
     65         delete fCMAPMapper;
     66 }
     67 
     68 const void *PortableFontInstance::getFontTable(LETag tableTag) const
     69 {
     70     return FontTableCache::find(tableTag);
     71 }
     72 
     73 hb_blob_t *PortableFontInstance::readFontTable(LETag tableTag) const
     74 {
     75   return hb_face_reference_table(fFace, tableTag);
     76 }
     77 
     78 CMAPMapper *PortableFontInstance::findUnicodeMapper()
     79 {
     80     LETag cmapTag = LE_CMAP_TABLE_TAG;
     81     const CMAPTable *cmap = (CMAPTable *) getFontTable(cmapTag);
     82 
     83     if (cmap == NULL) {
     84         return NULL;
     85     }
     86 
     87     return CMAPMapper::createUnicodeMapper(cmap);
     88 }
     89 
     90 const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
     91 {
     92     if (fNAMETable == NULL) {
     93         LETag nameTag = LE_NAME_TABLE_TAG;
     94         PortableFontInstance *realThis = (PortableFontInstance *) this;
     95 
     96         realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
     97 
     98         if (realThis->fNAMETable != NULL) {
     99             realThis->fNameCount        = SWAPW(realThis->fNAMETable->count);
    100             realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
    101         }
    102     }
    103 
    104     for(le_int32 i = 0; i < fNameCount; i += 1) {
    105         const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
    106 
    107         if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
    108             SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
    109             char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
    110             le_uint16 length = SWAPW(nameRecord->length);
    111             char *result = NEW_ARRAY(char, length + 2);
    112 
    113             ARRAY_COPY(result, name, length);
    114             result[length] = result[length + 1] = 0;
    115 
    116             return result;
    117         }
    118     }
    119 
    120     return NULL;
    121 }
    122 
    123 const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
    124 {
    125     if (fNAMETable == NULL) {
    126         LETag nameTag = LE_NAME_TABLE_TAG;
    127         PortableFontInstance *realThis = (PortableFontInstance *) this;
    128 
    129         realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
    130 
    131         if (realThis->fNAMETable != NULL) {
    132             realThis->fNameCount        = SWAPW(realThis->fNAMETable->count);
    133             realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
    134         }
    135     }
    136 
    137     for(le_int32 i = 0; i < fNameCount; i += 1) {
    138         const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
    139 
    140         if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
    141             SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
    142             LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
    143             le_uint16 length = SWAPW(nameRecord->length) / 2;
    144             LEUnicode16 *result = NEW_ARRAY(LEUnicode16, length + 2);
    145 
    146             for (le_int32 c = 0; c < length; c += 1) {
    147                 result[c] = SWAPW(name[c]);
    148             }
    149 
    150             result[length] = 0;
    151 
    152             return result;
    153         }
    154     }
    155 
    156     return NULL;
    157 }
    158 
    159 void PortableFontInstance::deleteNameString(const char *name) const
    160 {
    161     DELETE_ARRAY(name);
    162 }
    163 
    164 void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
    165 {
    166     DELETE_ARRAY(name);
    167 }
    168 
    169 void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
    170 {
    171     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
    172 
    173     if (fHMTXTable == NULL) {
    174         LETag maxpTag = LE_MAXP_TABLE_TAG;
    175         LETag hmtxTag = LE_HMTX_TABLE_TAG;
    176         const MAXPTable *maxpTable = (MAXPTable *) getFontTable(maxpTag);
    177         PortableFontInstance *realThis = (PortableFontInstance *) this;
    178 
    179         if (maxpTable != NULL) {
    180             realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
    181         }
    182 
    183         realThis->fHMTXTable = (const HMTXTable *) getFontTable(hmtxTag);
    184     }
    185 
    186     le_uint16 index = ttGlyph;
    187 
    188     if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
    189         advance.fX = advance.fY = 0;
    190         return;
    191     }
    192 
    193     if (ttGlyph >= fNumLongHorMetrics) {
    194         index = fNumLongHorMetrics - 1;
    195     }
    196 
    197     advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
    198     advance.fY = 0;
    199 }
    200 
    201 le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
    202 {
    203     return FALSE;
    204 }
    205 
    206 le_int32 PortableFontInstance::getUnitsPerEM() const
    207 {
    208     return fUnitsPerEM;
    209 }
    210 
    211 le_uint32 PortableFontInstance::getFontChecksum() const
    212 {
    213     return 0;
    214 }
    215 
    216 le_int32 PortableFontInstance::getAscent() const
    217 {
    218     return fAscent;
    219 }
    220 
    221 le_int32 PortableFontInstance::getDescent() const
    222 {
    223     return fDescent;
    224 }
    225 
    226 le_int32 PortableFontInstance::getLeading() const
    227 {
    228     return fLeading;
    229 }
    230 
    231 // We really want to inherit this method from the superclass, but some compilers
    232 // issue a warning if we don't implement it...
    233 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
    234 {
    235     return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
    236 }
    237 
    238 // We really want to inherit this method from the superclass, but some compilers
    239 // issue a warning if we don't implement it...
    240 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
    241 {
    242     return LEFontInstance::mapCharToGlyph(ch, mapper);
    243 }
    244 
    245 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
    246 {
    247     return fCMAPMapper->unicodeToGlyph(ch);
    248 }
    249 
    250 float PortableFontInstance::getXPixelsPerEm() const
    251 {
    252     return fXScale;
    253 }
    254 
    255 float PortableFontInstance::getYPixelsPerEm() const
    256 {
    257     return fYScale;
    258 }
    259 
    260 float PortableFontInstance::getScaleFactorX() const
    261 {
    262     return 1.0;
    263 }
    264 
    265 float PortableFontInstance::getScaleFactorY() const
    266 {
    267     return 1.0;
    268 }
    269