// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../include/fpdfapi/fpdf_resource.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../fpdf_font/font_int.h"
#include "cmap_int.h"
void FPDFAPI_FindEmbeddedCMap(const char* name, int charset, int coding, const FXCMAP_CMap*& pMap)
{
    pMap = NULL;
    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    const FXCMAP_CMap* pCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList;
    int nCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_Count;
    for (int i = 0; i < nCMaps; i ++) {
        if (FXSYS_strcmp(name, pCMaps[i].m_Name)) {
            continue;
        }
        pMap = &pCMaps[i];
        break;
    }
}
extern "C" {
    static int compareWord(const void* p1, const void* p2)
    {
        return (*(FX_WORD*)p1) - (*(FX_WORD*)p2);
    }
};
extern "C" {
    static int compareWordRange(const void* key, const void* element)
    {
        if (*(FX_WORD*)key < * (FX_WORD*)element) {
            return -1;
        }
        if (*(FX_WORD*)key > ((FX_WORD*)element)[1]) {
            return 1;
        }
        return 0;
    }
};
extern "C" {
    static int compareDWordRange(const void* p1, const void* p2)
    {
        FX_DWORD key = *(FX_DWORD*)p1;
        FX_WORD hiword = (FX_WORD)(key >> 16);
        FX_WORD* element = (FX_WORD*)p2;
        if (hiword < element[0]) {
            return -1;
        }
        if (hiword > element[0]) {
            return 1;
        }
        FX_WORD loword = (FX_WORD)key;
        if (loword < element[1]) {
            return -1;
        }
        if (loword > element[2]) {
            return 1;
        }
        return 0;
    }
};
extern "C" {
    static int compareDWordSingle(const void* p1, const void* p2)
    {
        FX_DWORD key = *(FX_DWORD*)p1;
        FX_DWORD value = ((*(FX_WORD*)p2) << 16) | ((FX_WORD*)p2)[1];
        if (key < value) {
            return -1;
        }
        if (key > value) {
            return 1;
        }
        return 0;
    }
};
FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode)
{
    if (charcode >> 16) {
        while (1) {
            if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
                FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 8, compareDWordRange);
                if (found) {
                    return found[3] + (FX_WORD)charcode - found[1];
                }
            } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
                FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 6, compareDWordSingle);
                if (found) {
                    return found[2];
                }
            }
            if (pMap->m_UseOffset == 0) {
                return 0;
            }
            pMap = pMap + pMap->m_UseOffset;
        }
        return 0;
    }
    FX_WORD code = (FX_WORD)charcode;
    while (1) {
        if (pMap->m_pWordMap == NULL) {
            return 0;
        }
        if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
            FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 4, compareWord);
            if (found) {
                return found[1];
            }
        } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
            FX_WORD* found = (FX_WORD*)FXSYS_bsearch(&code, pMap->m_pWordMap, pMap->m_WordCount, 6, compareWordRange);
            if (found) {
                return found[2] + code - found[0];
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    return 0;
}
FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid)
{
    while (1) {
        if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
            const FX_WORD *pCur = pMap->m_pWordMap;
            const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2;
            while (pCur < pEnd) {
                if (pCur[1] == cid) {
                    return pCur[0];
                }
                pCur += 2;
            }
        } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
            const FX_WORD *pCur = pMap->m_pWordMap;
            const FX_WORD *pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3;
            while (pCur < pEnd) {
                if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) {
                    return pCur[0] + cid - pCur[2];
                }
                pCur += 3;
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    while (1) {
        if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
            const FX_WORD *pCur = pMap->m_pDWordMap;
            const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 4;
            while (pCur < pEnd) {
                if (cid >= pCur[3] && cid <= pCur[3] + pCur[2] - pCur[1]) {
                    return (((FX_DWORD)pCur[0] << 16) | pCur[1]) + cid - pCur[3];
                }
                pCur += 4;
            }
        } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
            const FX_WORD *pCur = pMap->m_pDWordMap;
            const FX_WORD *pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 3;
            while (pCur < pEnd) {
                if (pCur[2] == cid) {
                    return ((FX_DWORD)pCur[0] << 16) | pCur[1];
                }
                pCur += 3;
            }
        }
        if (pMap->m_UseOffset == 0) {
            return 0;
        }
        pMap = pMap + pMap->m_UseOffset;
    }
    return 0;
}
void FPDFAPI_LoadCID2UnicodeMap(int charset, const FX_WORD*& pMap, FX_DWORD& count)
{
    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    pMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
    count = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
}
