fontservices/textshaperplugin/source/cmaps.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /***************************************************************************
       
     2 *
       
     3 *   Copyright (C) 1998-2003, International Business Machines
       
     4 *   Corporation and others.  All Rights Reserved.
       
     5 *
       
     6 ************************************************************************/
       
     7 
       
     8 #include "LETypes.h"
       
     9 #include "LESwaps.h"
       
    10 
       
    11 #include "sfnt.h"
       
    12 #include "cmaps.h"
       
    13 
       
    14 #define SWAPU16(code) ((LEUnicode16) SWAPW(code))
       
    15 #define SWAPU32(code) ((LEUnicode32) SWAPL(code))
       
    16 
       
    17 //
       
    18 // Finds the high bit by binary searching
       
    19 // through the bits in value.
       
    20 //
       
    21 le_int8 highBit(le_uint32 value)
       
    22 {
       
    23     le_uint8 bit = 0;
       
    24 
       
    25     if (value >= 1 << 16) {
       
    26         value >>= 16;
       
    27         bit += 16;
       
    28     }
       
    29 
       
    30     if (value >= 1 << 8) {
       
    31         value >>= 8;
       
    32         bit += 8;
       
    33     }
       
    34 
       
    35     if (value >= 1 << 4) {
       
    36         value >>= 4;
       
    37         bit += 4;
       
    38     }
       
    39 
       
    40     if (value >= 1 << 2) {
       
    41         value >>= 2;
       
    42         bit += 2;
       
    43     }
       
    44 
       
    45     if (value >= 1 << 1) {
       
    46         value >>= 1;
       
    47         bit += 1;
       
    48     }
       
    49 
       
    50     return bit;
       
    51 }
       
    52 
       
    53 CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap)
       
    54 {
       
    55     le_uint16 i;
       
    56     le_uint16 nSubtables = SWAPW(cmap->numberSubtables);
       
    57     const CMAPEncodingSubtable *subtable = NULL;
       
    58     le_uint32 offset1 = 0, offset10 = 0;
       
    59 
       
    60     for (i = 0; i < nSubtables; i += 1) {
       
    61         const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
       
    62 
       
    63         if (SWAPW(esh->platformID) == 3) {
       
    64             switch (SWAPW(esh->platformSpecificID)) {
       
    65             case 1:
       
    66                 offset1 = SWAPL(esh->encodingOffset);
       
    67                 break;
       
    68 
       
    69             case 10:
       
    70                 offset10 = SWAPL(esh->encodingOffset);
       
    71                 break;
       
    72             }
       
    73         }
       
    74     }
       
    75 
       
    76 
       
    77     if (offset10 != 0)
       
    78     {
       
    79         subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset10);
       
    80     } else if (offset1 != 0) {
       
    81         subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset1);
       
    82     } else {
       
    83         return NULL;
       
    84     }
       
    85 
       
    86     switch (SWAPW(subtable->format)) {
       
    87     case 4:
       
    88         return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
       
    89 
       
    90     case 12:
       
    91     {
       
    92         const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable;
       
    93 
       
    94         return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
       
    95     }
       
    96 
       
    97     default:
       
    98         break;
       
    99     }
       
   100 
       
   101     return NULL;
       
   102 }
       
   103 
       
   104 CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header)
       
   105     : CMAPMapper(cmap)
       
   106 {
       
   107     le_uint16 segCount = SWAPW(header->segCountX2) / 2;
       
   108 
       
   109     fEntrySelector = SWAPW(header->entrySelector);
       
   110     fRangeShift = SWAPW(header->rangeShift) / 2;
       
   111     fEndCodes = &header->endCodes[0];
       
   112     fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad...
       
   113     fIdDelta = &fStartCodes[segCount];
       
   114     fIdRangeOffset = &fIdDelta[segCount];
       
   115 }
       
   116 
       
   117 LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const
       
   118 {
       
   119     if (unicode32 >= 0x10000) {
       
   120         return 0;
       
   121     }
       
   122 
       
   123     LEUnicode16 unicode = (LEUnicode16) unicode32;
       
   124     le_uint16 index = 0;
       
   125     le_uint16 probe = 1 << fEntrySelector;
       
   126     TTGlyphID result = 0;
       
   127 
       
   128     if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) {
       
   129         index = fRangeShift;
       
   130     }
       
   131 
       
   132     while (probe > (1 << 0)) {
       
   133         probe >>= 1;
       
   134 
       
   135         if (SWAPU16(fStartCodes[index + probe]) <= unicode) {
       
   136             index += probe;
       
   137         }
       
   138     }
       
   139 
       
   140     if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) {
       
   141         if (fIdRangeOffset[index] == 0) {
       
   142             result = (TTGlyphID) unicode;
       
   143         } else {
       
   144             le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
       
   145             le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
       
   146             le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset);
       
   147 
       
   148             result = SWAPW(glyphIndexTable[offset]);
       
   149         }
       
   150 
       
   151         result += SWAPW(fIdDelta[index]);
       
   152     } else {
       
   153         result = 0;
       
   154     }
       
   155 
       
   156     return LE_SET_GLYPH(0, result);
       
   157 }
       
   158 
       
   159 CMAPFormat4Mapper::~CMAPFormat4Mapper()
       
   160 {
       
   161     // parent destructor does it all
       
   162 }
       
   163 
       
   164 CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups)
       
   165     : CMAPMapper(cmap), fGroups(groups)
       
   166 {
       
   167     le_uint8 bit = highBit(nGroups);
       
   168     fPower = 1 << bit;
       
   169     fRangeOffset = nGroups - fPower;
       
   170 }
       
   171 
       
   172 LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const
       
   173 {
       
   174     le_int32 probe = fPower;
       
   175     le_int32 range = 0;
       
   176 
       
   177     if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) {
       
   178         range = fRangeOffset;
       
   179     }
       
   180 
       
   181     while (probe > (1 << 0)) {
       
   182         probe >>= 1;
       
   183 
       
   184         if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) {
       
   185             range += probe;
       
   186         }
       
   187     }
       
   188 
       
   189     if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) {
       
   190         return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
       
   191     }
       
   192 
       
   193     return 0;
       
   194 }
       
   195 
       
   196 CMAPGroupMapper::~CMAPGroupMapper()
       
   197 {
       
   198     // parent destructor does it all
       
   199 }
       
   200