// 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;
};
