// 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

typedef void* FXFT_Library;
class CPDF_CMapManager : public CFX_Object
{
public:
    CPDF_CMapManager();
    ~CPDF_CMapManager();
    FX_LPVOID				GetPackage(FX_BOOL bPrompt);
    CPDF_CMap*				GetPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPrompt);
    CPDF_CID2UnicodeMap*	GetCID2UnicodeMap(int charset, FX_BOOL bPrompt);
    void					ReloadAll();
private:
    CPDF_CMap*				LoadPredefinedCMap(const CFX_ByteString& name,  FX_BOOL bPrompt);
    CPDF_CID2UnicodeMap*	LoadCID2UnicodeMap(int charset, FX_BOOL bPrompt);
    void					DropAll(FX_BOOL bReload);
#ifndef _FPDFAPI_MINI_
    FX_BOOL					m_bPrompted;
    FX_LPVOID				m_pPackage;
#endif
    CFX_MapByteStringToPtr	m_CMaps;
    CPDF_CID2UnicodeMap*	m_CID2UnicodeMaps[6];
};
class CPDF_FontGlobals : public CFX_Object
{
public:
    CPDF_FontGlobals();
    ~CPDF_FontGlobals();
    void				ClearAll();
    void				Clear(void* key);
    CPDF_Font*			Find(void* key, int index);
    void				Set(void* key, int index, CPDF_Font* pFont);
    CFX_MapPtrToPtr		m_pStockMap;
    CPDF_CMapManager	m_CMapManager;
    struct {
        const struct FXCMAP_CMap*	m_pMapList;
        int				m_Count;
    } m_EmbeddedCharsets[5];
    struct {
        const FX_WORD*	m_pMap;
        int				m_Count;
    } m_EmbeddedToUnicodes[5];
    FX_LPBYTE			m_pContrastRamps;
};
struct _CMap_CodeRange {
    int			m_CharSize;
    FX_BYTE		m_Lower[4];
    FX_BYTE		m_Upper[4];
};
class CPDF_CMapParser : public CFX_Object
{
public:
    CPDF_CMapParser();
    ~CPDF_CMapParser() {}
    FX_BOOL	Initialize(CPDF_CMap*);
    void	ParseWord(FX_BSTR str);
    CFX_BinaryBuf	m_AddMaps;
private:
    CPDF_CMap*	m_pCMap;
    int				m_Status;
    int				m_CodeSeq;
    FX_DWORD		m_CodePoints[4];
    CFX_ArrayTemplate<_CMap_CodeRange>	m_CodeRanges;
    CFX_ByteString	m_Registry, m_Ordering, m_Supplement;
    CFX_ByteString	m_LastWord;
};
#define CIDCODING_UNKNOWN	0
#define CIDCODING_GB		1
#define CIDCODING_BIG5		2
#define CIDCODING_JIS		3
#define CIDCODING_KOREA		4
#define CIDCODING_UCS2		5
#define CIDCODING_CID		6
#define CIDCODING_UTF16		7
class CPDF_CMap : public CFX_Object
{
public:
    CPDF_CMap();
    FX_BOOL					LoadPredefined(CPDF_CMapManager* pMgr, const FX_CHAR* name, FX_BOOL bPromptCJK);
    FX_BOOL					LoadEmbedded(FX_LPCBYTE pData, FX_DWORD dwSize);
    void					Release();
    FX_BOOL					IsLoaded() const
    {
        return m_bLoaded;
    }
    int						GetCharset()
    {
        return m_Charset;
    }
    FX_BOOL					IsVertWriting() const
    {
        return m_bVertical;
    }
    FX_WORD					CIDFromCharCode(FX_DWORD charcode) const;
    FX_DWORD				CharCodeFromCID(FX_WORD CID) const;
    int						GetCharSize(FX_DWORD charcode) const;
    FX_DWORD				GetNextChar(const FX_CHAR* pString, int& offset) const;
    int						CountChar(const FX_CHAR* pString, int size) const;
    int						AppendChar(FX_LPSTR str, FX_DWORD charcode) const;
    typedef enum {OneByte, TwoBytes, MixedTwoBytes, MixedFourBytes} CodingScheme;
protected:
    ~CPDF_CMap();
    friend class			CPDF_CMapParser;
    friend class			CPDF_CMapManager;
    friend class			CPDF_CIDFont;
protected:
    CFX_ByteString			m_PredefinedCMap;
    FX_BOOL					m_bVertical;
    int						m_Charset, m_Coding;
    CodingScheme			m_CodingScheme;
    int						m_nCodeRanges;
    FX_BYTE*				m_pLeadingBytes;
    FX_WORD*				m_pMapping;
    FX_LPBYTE				m_pAddMapping;
    FX_BOOL					m_bLoaded;
    const FXCMAP_CMap*		m_pEmbedMap;
    CPDF_CMap*				m_pUseMap;
};
class CPDF_PredefinedCMap
{
public:
    FX_LPCSTR	m_pName;
    int			m_Charset;
    int			m_Coding;
    CPDF_CMap::CodingScheme	m_CodingScheme;
    FX_DWORD	m_LeadingSegCount;
    FX_BYTE		m_LeadingSegs[4];
};
typedef struct _FileHeader {
    FX_BYTE		btTag[4];
    FX_BYTE		btVersion;
    FX_BYTE		btFormat;
    FX_BYTE		btReserved1[2];
    FX_DWORD	dwStartIndex;
    FX_DWORD	dwEndIndex;
    FX_DWORD	dwDataSize;
    FX_DWORD	dwDataOffset;
    FX_DWORD	dwRecordSize;
} FXMP_FILEHEADER;
class CPDF_FXMP : public CFX_Object
{
public:
    CPDF_FXMP()
    {
        m_pHeader = NULL;
        m_pTable = NULL;
    }
    ~CPDF_FXMP()
    {
        if (m_pHeader) {
            FX_Free(m_pHeader);
        }
    }
    FX_BOOL		IsLoaded()
    {
        return m_pTable != NULL;
    }
    FX_BOOL		LoadFile(FX_LPVOID pPackage, FX_LPCSTR fileid);
    FX_LPBYTE	GetRecord(FX_DWORD index);
private:
    FXMP_FILEHEADER*	m_pHeader;
    FX_LPBYTE	m_pTable;
};
class CPDF_CID2UnicodeMap : public CFX_Object
{
public:
    CPDF_CID2UnicodeMap();
    ~CPDF_CID2UnicodeMap();
    FX_BOOL		Initialize();
    FX_BOOL		IsLoaded();
    void		Load(CPDF_CMapManager* pMgr, int charset, FX_BOOL bPromptCJK);
    FX_WCHAR	UnicodeFromCID(FX_WORD CID);
protected:
    int			m_Charset;
    const FX_WORD*	m_pEmbeddedMap;
    FX_DWORD	m_EmbeddedCount;
#ifndef _FPDFAPI_MINI_
    CPDF_FXMP*	m_pExternalMap;
#endif
};
class CPDF_ToUnicodeMap : public CFX_Object
{
public:
    void					Load(CPDF_Stream* pStream);
    CFX_WideString			Lookup(FX_DWORD charcode);
    FX_DWORD				ReverseLookup(FX_WCHAR unicode);
protected:
    CFX_CMapDWordToDWord	m_Map;
    CPDF_CID2UnicodeMap*	m_pBaseMap;
    CFX_WideTextBuf			m_MultiCharBuf;
};
class CPDF_FontCharMap : public CFX_CharMap, public CFX_Object
{
public:
    CPDF_FontCharMap(CPDF_Font* pFont);
    CPDF_Font*		m_pFont;
};
