Home | History | Annotate | Download | only in fpdf_cmaps
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../../include/fpdfapi/fpdf_resource.h"
      8 #include "../../../include/fpdfapi/fpdf_module.h"
      9 #include "../fpdf_font/font_int.h"
     10 #include "cmap_int.h"
     11 void FPDFAPI_FindEmbeddedCMap(const char* name, int charset, int coding, const FXCMAP_CMap*& pMap)
     12 {
     13     pMap = NULL;
     14     CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
     15     const FXCMAP_CMap* pCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList;
     16     int nCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_Count;
     17     for (int i = 0; i < nCMaps; i ++) {
     18         if (FXSYS_strcmp(name, pCMaps[i].m_Name)) {
     19             continue;
     20         }
     21         pMap = &pCMaps[i];
     22         break;
     23     }
     24 }
     25 extern "C" {
     26     static int compareWord(const void* p1, const void* p2)
     27     {
     28         return (*(FX_WORD*)p1) - (*(FX_WORD*)p2);
     29     }
     30 };
     31 extern "C" {
     32     static int compareWordRange(const void* key, const void* element)
     33     {
     34         if (*(FX_WORD*)key < * (FX_WORD*)element) {
     35             return -1;
     36         }
     37         if (*(FX_WORD*)key > ((FX_WORD*)element)[1]) {
     38             return 1;
     39         }
     40         return 0;
     41     }
     42 };
     43 extern "C" {
     44     static int compareDWordRange(const void* p1, const void* p2)
     45     {
     46         FX_DWORD key = *(FX_DWORD*)p1;
     47         FX_WORD hiword = (FX_WORD)(key >> 16);
     48         FX_WORD* element = (FX_WORD*)p2;
     49         if (hiword < element[0]) {
     50             return -1;
     51         }
     52         if (hiword > element[0]) {
     53             return 1;
     54         }
     55         FX_WORD loword = (FX_WORD)key;
     56         if (loword < element[1]) {
     57             return -1;
     58         }
     59         if (loword > element[2]) {
     60             return 1;
     61         }
     62         return 0;
     63     }
     64 };
     65 extern "C" {
     66     static int compareDWordSingle(const void* p1, const void* p2)
     67     {
     68         FX_DWORD key = *(FX_DWORD*)p1;
     69         FX_DWORD value = ((*(FX_WORD*)p2) << 16) | ((FX_WORD*)p2)[1];
     70         if (key < value) {
     71             return -1;
     72         }
     73         if (key > value) {
     74             return 1;
     75         }
     76         return 0;
     77     }
     78 };
     79 FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode)
     80 {
     81     if (charcode >> 16) {
     82         while (1) {
     83             if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
     84                 FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 8, compareDWordRange);
     85                 if (found) {
     86                     return found[3] + (FX_WORD)charcode - found[1];
     87                 }
     88             } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
     89                 FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 6, compareDWordSingle);
     90                 if (found) {
     91                     return found[2];
     92                 }
     93             }
     94             if (pMap->m_UseOffset == 0) {
     95                 return 0;
     96             }
     97             pMap = pMap + pMap->m_UseOffset;
     98         }
     99         return 0;
    100     }
    101     FX_WORD code = (FX_WORD)charcode;
    102     while (1) {
    103         if (pMap->m_pWordMap == NULL) {
    104             return 0;
    105         }
    106         if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
    107             FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 4, compareWord);
    108             if (found) {
    109                 return found[1];
    110             }
    111         } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
    112             FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 6, compareWordRange);
    113             if (found) {
    114                 return found[2] + code - found[0];
    115             }
    116         }
    117         if (pMap->m_UseOffset == 0) {
    118             return 0;
    119         }
    120         pMap = pMap + pMap->m_UseOffset;
    121     }
    122     return 0;
    123 }
    124 FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid)
    125 {
    126     while (1) {
    127         if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
    128             const FX_WORD *pCur = pMap->m_pWordMap;
    129             const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2;
    130             while (pCur < pEnd) {
    131                 if (pCur[1] == cid) {
    132                     return pCur[0];
    133                 }
    134                 pCur += 2;
    135             }
    136         } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
    137             const FX_WORD *pCur = pMap->m_pWordMap;
    138             const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3;
    139             while (pCur < pEnd) {
    140                 if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) {
    141                     return pCur[0] + cid - pCur[2];
    142                 }
    143                 pCur += 3;
    144             }
    145         }
    146         if (pMap->m_UseOffset == 0) {
    147             return 0;
    148         }
    149         pMap = pMap + pMap->m_UseOffset;
    150     }
    151     while (1) {
    152         if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
    153             const FX_WORD *pCur = pMap->m_pDWordMap;
    154             const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 4;
    155             while (pCur < pEnd) {
    156                 if (cid >= pCur[3] && cid <= pCur[3] + pCur[2] - pCur[1]) {
    157                     return (((FX_DWORD)pCur[0] << 16) | pCur[1]) + cid - pCur[3];
    158                 }
    159                 pCur += 4;
    160             }
    161         } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
    162             const FX_WORD *pCur = pMap->m_pDWordMap;
    163             const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 3;
    164             while (pCur < pEnd) {
    165                 if (pCur[2] == cid) {
    166                     return ((FX_DWORD)pCur[0] << 16) | pCur[1];
    167                 }
    168                 pCur += 3;
    169             }
    170         }
    171         if (pMap->m_UseOffset == 0) {
    172             return 0;
    173         }
    174         pMap = pMap + pMap->m_UseOffset;
    175     }
    176     return 0;
    177 }
    178 void FPDFAPI_LoadCID2UnicodeMap(int charset, const FX_WORD*& pMap, FX_DWORD& count)
    179 {
    180     CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    181     pMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
    182     count = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
    183 }
    184