From a8a28e0702a1874d29d3c9f2b155bce1557eb4fd Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 23 Mar 2016 15:41:39 -0400 Subject: Move core/include/fxcrt to core/fxcrt/include. This CL moves the fxcrt code into the core/fxcrt directory. The only exception was fx_bidi.h which was moved into core/fxcrt as it is not used outside of core/. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1825953002 . --- core/fxcrt/include/fx_arb.h | 66 ++ core/fxcrt/include/fx_basic.h | 1153 +++++++++++++++++++++++++++++++++++ core/fxcrt/include/fx_coordinates.h | 672 ++++++++++++++++++++ core/fxcrt/include/fx_ext.h | 134 ++++ core/fxcrt/include/fx_memory.h | 84 +++ core/fxcrt/include/fx_safe_types.h | 20 + core/fxcrt/include/fx_stream.h | 162 +++++ core/fxcrt/include/fx_string.h | 819 +++++++++++++++++++++++++ core/fxcrt/include/fx_system.h | 320 ++++++++++ core/fxcrt/include/fx_ucd.h | 192 ++++++ core/fxcrt/include/fx_xml.h | 169 +++++ 11 files changed, 3791 insertions(+) create mode 100644 core/fxcrt/include/fx_arb.h create mode 100644 core/fxcrt/include/fx_basic.h create mode 100644 core/fxcrt/include/fx_coordinates.h create mode 100644 core/fxcrt/include/fx_ext.h create mode 100644 core/fxcrt/include/fx_memory.h create mode 100644 core/fxcrt/include/fx_safe_types.h create mode 100644 core/fxcrt/include/fx_stream.h create mode 100644 core/fxcrt/include/fx_string.h create mode 100644 core/fxcrt/include/fx_system.h create mode 100644 core/fxcrt/include/fx_ucd.h create mode 100644 core/fxcrt/include/fx_xml.h (limited to 'core/fxcrt/include') diff --git a/core/fxcrt/include/fx_arb.h b/core/fxcrt/include/fx_arb.h new file mode 100644 index 0000000000..6a0af83150 --- /dev/null +++ b/core/fxcrt/include/fx_arb.h @@ -0,0 +1,66 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_ARB_H_ +#define CORE_FXCRT_INCLUDE_FX_ARB_H_ + +#include "core/fxcrt/include/fx_system.h" +#include "core/fxcrt/include/fx_ucd.h" + +class IFX_ArabicChar; + +struct FX_ARBFORMTABLE { + uint16_t wIsolated; + uint16_t wFinal; + uint16_t wInitial; + uint16_t wMedial; +}; + +struct FX_ARAALEF { + uint16_t wAlef; + uint16_t wIsolated; +}; + +struct FX_ARASHADDA { + uint16_t wShadda; + uint16_t wIsolated; +}; + +const FX_ARBFORMTABLE* FX_GetArabicFormTable(FX_WCHAR unicode); +FX_WCHAR FX_GetArabicFromAlefTable(FX_WCHAR alef); +FX_WCHAR FX_GetArabicFromShaddaTable(FX_WCHAR shadda); + +enum FX_ARBPOSITION { + FX_ARBPOSITION_Isolated = 0, + FX_ARBPOSITION_Final, + FX_ARBPOSITION_Initial, + FX_ARBPOSITION_Medial, +}; + +class IFX_ArabicChar { + public: + static IFX_ArabicChar* Create(); + virtual ~IFX_ArabicChar() {} + virtual void Release() = 0; + virtual FX_BOOL IsArabicChar(FX_WCHAR wch) const = 0; + virtual FX_BOOL IsArabicFormChar(FX_WCHAR wch) const = 0; + virtual FX_WCHAR GetFormChar(FX_WCHAR wch, + FX_WCHAR prev = 0, + FX_WCHAR next = 0) const = 0; + virtual FX_WCHAR GetFormChar(const CFX_Char* cur, + const CFX_Char* prev, + const CFX_Char* next) const = 0; +}; + +void FX_BidiLine(CFX_WideString& wsText, int32_t iBaseLevel = 0); +void FX_BidiLine(CFX_TxtCharArray& chars, + int32_t iCount, + int32_t iBaseLevel = 0); +void FX_BidiLine(CFX_RTFCharArray& chars, + int32_t iCount, + int32_t iBaseLevel = 0); + +#endif // CORE_FXCRT_INCLUDE_FX_ARB_H_ diff --git a/core/fxcrt/include/fx_basic.h b/core/fxcrt/include/fx_basic.h new file mode 100644 index 0000000000..3da2e03e60 --- /dev/null +++ b/core/fxcrt/include/fx_basic.h @@ -0,0 +1,1153 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_BASIC_H_ +#define CORE_FXCRT_INCLUDE_FX_BASIC_H_ + +#include +#include + +#include "core/fxcrt/include/fx_memory.h" +#include "core/fxcrt/include/fx_stream.h" +#include "core/fxcrt/include/fx_string.h" +#include "core/fxcrt/include/fx_system.h" + +// The FX_ArraySize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use FX_ArraySize on +// a pointer by mistake, you will get a compile-time error. +// +// One caveat is that FX_ArraySize() doesn't accept any array of an +// anonymous type or a type defined inside a function. +#define FX_ArraySize(array) (sizeof(ArraySizeHelper(array))) + +// This template function declaration is used in defining FX_ArraySize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char(&ArraySizeHelper(T(&array)[N]))[N]; + +// Used with std::unique_ptr to FX_Free raw memory. +struct FxFreeDeleter { + inline void operator()(void* ptr) const { FX_Free(ptr); } +}; + +// Used with std::unique_ptr to Release() objects that can't be deleted. +template +struct ReleaseDeleter { + inline void operator()(T* ptr) const { ptr->Release(); } +}; + +class CFX_BinaryBuf { + public: + CFX_BinaryBuf(); + explicit CFX_BinaryBuf(FX_STRSIZE size); + ~CFX_BinaryBuf(); + + uint8_t* GetBuffer() const { return m_pBuffer.get(); } + FX_STRSIZE GetSize() const { return m_DataSize; } + + void Clear(); + void EstimateSize(FX_STRSIZE size, FX_STRSIZE alloc_step = 0); + void AppendBlock(const void* pBuf, FX_STRSIZE size); + void AppendString(const CFX_ByteStringC& str) { + AppendBlock(str.GetPtr(), str.GetLength()); + } + + void AppendByte(uint8_t byte) { + ExpandBuf(1); + m_pBuffer.get()[m_DataSize++] = byte; + } + + void InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size); + void Delete(int start_index, int count); + + // Takes ownership of |pBuf|. + void AttachData(uint8_t* pBuf, FX_STRSIZE size); + + // Releases ownership of |m_pBuffer| and returns it. + uint8_t* DetachBuffer(); + + protected: + void ExpandBuf(FX_STRSIZE size); + + FX_STRSIZE m_AllocStep; + FX_STRSIZE m_AllocSize; + FX_STRSIZE m_DataSize; + std::unique_ptr m_pBuffer; +}; + +class CFX_ByteTextBuf : public CFX_BinaryBuf { + public: + void AppendChar(int ch) { AppendByte((uint8_t)ch); } + FX_STRSIZE GetLength() const { return m_DataSize; } + CFX_ByteStringC GetByteString() const; + + CFX_ByteTextBuf& operator<<(int i); + CFX_ByteTextBuf& operator<<(FX_DWORD i); + CFX_ByteTextBuf& operator<<(double f); + CFX_ByteTextBuf& operator<<(const CFX_ByteStringC& lpsz); + CFX_ByteTextBuf& operator<<(const CFX_ByteTextBuf& buf); +}; + +class CFX_WideTextBuf : public CFX_BinaryBuf { + public: + void AppendChar(FX_WCHAR wch); + FX_STRSIZE GetLength() const { return m_DataSize / sizeof(FX_WCHAR); } + FX_WCHAR* GetBuffer() const { + return reinterpret_cast(m_pBuffer.get()); + } + CFX_WideStringC GetWideString() const; + + void Delete(int start_index, int count) { + CFX_BinaryBuf::Delete(start_index * sizeof(FX_WCHAR), + count * sizeof(FX_WCHAR)); + } + + CFX_WideTextBuf& operator<<(int i); + CFX_WideTextBuf& operator<<(double f); + CFX_WideTextBuf& operator<<(const FX_WCHAR* lpsz); + CFX_WideTextBuf& operator<<(const CFX_WideStringC& str); + CFX_WideTextBuf& operator<<(const CFX_WideString& str); + CFX_WideTextBuf& operator<<(const CFX_WideTextBuf& buf); +}; + +#ifdef PDF_ENABLE_XFA +class CFX_ArchiveSaver { + public: + CFX_ArchiveSaver() : m_pStream(NULL) {} + + CFX_ArchiveSaver& operator<<(uint8_t i); + + CFX_ArchiveSaver& operator<<(int i); + + CFX_ArchiveSaver& operator<<(FX_DWORD i); + + CFX_ArchiveSaver& operator<<(FX_FLOAT i); + + CFX_ArchiveSaver& operator<<(double i); + + CFX_ArchiveSaver& operator<<(const CFX_ByteStringC& bstr); + + CFX_ArchiveSaver& operator<<(const FX_WCHAR* bstr); + + CFX_ArchiveSaver& operator<<(const CFX_WideString& wstr); + + void Write(const void* pData, FX_STRSIZE dwSize); + + intptr_t GetLength() { return m_SavingBuf.GetSize(); } + + const uint8_t* GetBuffer() { return m_SavingBuf.GetBuffer(); } + + void SetStream(IFX_FileStream* pStream) { m_pStream = pStream; } + + protected: + CFX_BinaryBuf m_SavingBuf; + + IFX_FileStream* m_pStream; +}; +class CFX_ArchiveLoader { + public: + CFX_ArchiveLoader(const uint8_t* pData, FX_DWORD dwSize); + + CFX_ArchiveLoader& operator>>(uint8_t& i); + + CFX_ArchiveLoader& operator>>(int& i); + + CFX_ArchiveLoader& operator>>(FX_DWORD& i); + + CFX_ArchiveLoader& operator>>(FX_FLOAT& i); + + CFX_ArchiveLoader& operator>>(double& i); + + CFX_ArchiveLoader& operator>>(CFX_ByteString& bstr); + + CFX_ArchiveLoader& operator>>(CFX_WideString& wstr); + + FX_BOOL IsEOF(); + + FX_BOOL Read(void* pBuf, FX_DWORD dwSize); + + protected: + FX_DWORD m_LoadingPos; + + const uint8_t* m_pLoadingBuf; + + FX_DWORD m_LoadingSize; +}; +#endif // PDF_ENABLE_XFA + +class CFX_FileBufferArchive { + public: + CFX_FileBufferArchive(); + ~CFX_FileBufferArchive(); + + void Clear(); + bool Flush(); + int32_t AppendBlock(const void* pBuf, size_t size); + int32_t AppendByte(uint8_t byte); + int32_t AppendDWord(FX_DWORD i); + int32_t AppendString(const CFX_ByteStringC& lpsz); + + // |pFile| must outlive the CFX_FileBufferArchive. + void AttachFile(IFX_StreamWrite* pFile); + + private: + static const size_t kBufSize = 32768; + + size_t m_Length; + std::unique_ptr m_pBuffer; + IFX_StreamWrite* m_pFile; +}; + +class CFX_CharMap { + public: + static CFX_ByteString GetByteString(uint16_t codepage, + const CFX_WideString& wstr); + + static CFX_WideString GetWideString(uint16_t codepage, + const CFX_ByteString& bstr); + + CFX_CharMap() = delete; +}; + +class CFX_UTF8Decoder { + public: + CFX_UTF8Decoder() { m_PendingBytes = 0; } + + void Clear(); + + void Input(uint8_t byte); + + void AppendChar(FX_DWORD ch); + + void ClearStatus() { m_PendingBytes = 0; } + + CFX_WideStringC GetResult() const { return m_Buffer.GetWideString(); } + + protected: + int m_PendingBytes; + + FX_DWORD m_PendingChar; + + CFX_WideTextBuf m_Buffer; +}; + +class CFX_UTF8Encoder { + public: + CFX_UTF8Encoder() {} + + void Input(FX_WCHAR unicode); + void AppendStr(const CFX_ByteStringC& str) { m_Buffer << str; } + CFX_ByteStringC GetResult() const { return m_Buffer.GetByteString(); } + + protected: + CFX_ByteTextBuf m_Buffer; +}; + +class CFX_BasicArray { + protected: + CFX_BasicArray(int unit_size); + + ~CFX_BasicArray(); + + FX_BOOL SetSize(int nNewSize); + + FX_BOOL Append(const CFX_BasicArray& src); + + FX_BOOL Copy(const CFX_BasicArray& src); + + uint8_t* InsertSpaceAt(int nIndex, int nCount); + + FX_BOOL RemoveAt(int nIndex, int nCount); + + FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray); + + const void* GetDataPtr(int index) const; + + protected: + uint8_t* m_pData; + + int m_nSize; + + int m_nMaxSize; + + int m_nUnitSize; +}; +template +class CFX_ArrayTemplate : public CFX_BasicArray { + public: + CFX_ArrayTemplate() : CFX_BasicArray(sizeof(TYPE)) {} + + int GetSize() const { return m_nSize; } + + int GetUpperBound() const { return m_nSize - 1; } + + FX_BOOL SetSize(int nNewSize) { return CFX_BasicArray::SetSize(nNewSize); } + + void RemoveAll() { SetSize(0); } + + const TYPE GetAt(int nIndex) const { + if (nIndex < 0 || nIndex >= m_nSize) { + return (const TYPE&)(*(volatile const TYPE*)NULL); + } + return ((const TYPE*)m_pData)[nIndex]; + } + + FX_BOOL SetAt(int nIndex, TYPE newElement) { + if (nIndex < 0 || nIndex >= m_nSize) { + return FALSE; + } + ((TYPE*)m_pData)[nIndex] = newElement; + return TRUE; + } + + TYPE& ElementAt(int nIndex) { + if (nIndex < 0 || nIndex >= m_nSize) { + return *(TYPE*)NULL; + } + return ((TYPE*)m_pData)[nIndex]; + } + + const TYPE* GetData() const { return (const TYPE*)m_pData; } + + TYPE* GetData() { return (TYPE*)m_pData; } + + FX_BOOL SetAtGrow(int nIndex, TYPE newElement) { + if (nIndex < 0) + return FALSE; + + if (nIndex >= m_nSize && !SetSize(nIndex + 1)) + return FALSE; + + ((TYPE*)m_pData)[nIndex] = newElement; + return TRUE; + } + + FX_BOOL Add(TYPE newElement) { + if (m_nSize < m_nMaxSize) { + m_nSize++; + } else if (!SetSize(m_nSize + 1)) { + return FALSE; + } + ((TYPE*)m_pData)[m_nSize - 1] = newElement; + return TRUE; + } + + FX_BOOL Append(const CFX_ArrayTemplate& src) { + return CFX_BasicArray::Append(src); + } + + FX_BOOL Copy(const CFX_ArrayTemplate& src) { + return CFX_BasicArray::Copy(src); + } + + TYPE* GetDataPtr(int index) { + return (TYPE*)CFX_BasicArray::GetDataPtr(index); + } + + TYPE* AddSpace() { return (TYPE*)CFX_BasicArray::InsertSpaceAt(m_nSize, 1); } + + TYPE* InsertSpaceAt(int nIndex, int nCount) { + return (TYPE*)CFX_BasicArray::InsertSpaceAt(nIndex, nCount); + } + + const TYPE operator[](int nIndex) const { + if (nIndex < 0 || nIndex >= m_nSize) { + *(volatile char*)0 = '\0'; + } + return ((const TYPE*)m_pData)[nIndex]; + } + + TYPE& operator[](int nIndex) { + if (nIndex < 0 || nIndex >= m_nSize) { + *(volatile char*)0 = '\0'; + } + return ((TYPE*)m_pData)[nIndex]; + } + + FX_BOOL InsertAt(int nIndex, TYPE newElement, int nCount = 1) { + if (!InsertSpaceAt(nIndex, nCount)) { + return FALSE; + } + while (nCount--) { + ((TYPE*)m_pData)[nIndex++] = newElement; + } + return TRUE; + } + + FX_BOOL RemoveAt(int nIndex, int nCount = 1) { + return CFX_BasicArray::RemoveAt(nIndex, nCount); + } + + FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray) { + return CFX_BasicArray::InsertAt(nStartIndex, pNewArray); + } + + int Find(TYPE data, int iStart = 0) const { + if (iStart < 0) { + return -1; + } + for (; iStart < (int)m_nSize; iStart++) + if (((TYPE*)m_pData)[iStart] == data) { + return iStart; + } + return -1; + } +}; +typedef CFX_ArrayTemplate CFX_DWordArray; + +#ifdef PDF_ENABLE_XFA +typedef CFX_ArrayTemplate CFX_WideStringCArray; +typedef CFX_ArrayTemplate CFX_FloatArray; +typedef CFX_ArrayTemplate CFX_ByteArray; +typedef CFX_ArrayTemplate CFX_Int32Array; +typedef CFX_ArrayTemplate CFX_PtrArray; +#endif // PDF_ENABLE_XFA + +#ifdef PDF_ENABLE_XFA +template +class CFX_ObjectArray : public CFX_BasicArray { + public: + CFX_ObjectArray() : CFX_BasicArray(sizeof(ObjectClass)) {} + + ~CFX_ObjectArray() { RemoveAll(); } + + void Add(const ObjectClass& data) { + new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(data); + } + + ObjectClass& Add() { + return *(ObjectClass*)new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(); + } + + void* AddSpace() { return InsertSpaceAt(m_nSize, 1); } + + int32_t Append(const CFX_ObjectArray& src, + int32_t nStart = 0, + int32_t nCount = -1) { + if (nCount == 0) { + return 0; + } + int32_t nSize = src.GetSize(); + if (!nSize) { + return 0; + } + FXSYS_assert(nStart > -1 && nStart < nSize); + if (nCount < 0) { + nCount = nSize; + } + if (nStart + nCount > nSize) { + nCount = nSize - nStart; + } + if (nCount < 1) { + return 0; + } + nSize = m_nSize; + InsertSpaceAt(m_nSize, nCount); + ObjectClass* pStartObj = (ObjectClass*)GetDataPtr(nSize); + nSize = nStart + nCount; + for (int32_t i = nStart; i < nSize; i++, pStartObj++) { + new ((void*)pStartObj) ObjectClass(src[i]); + } + return nCount; + } + + int32_t Copy(const CFX_ObjectArray& src, + int32_t nStart = 0, + int32_t nCount = -1) { + if (nCount == 0) { + return 0; + } + int32_t nSize = src.GetSize(); + if (!nSize) { + return 0; + } + FXSYS_assert(nStart > -1 && nStart < nSize); + if (nCount < 0) { + nCount = nSize; + } + if (nStart + nCount > nSize) { + nCount = nSize - nStart; + } + if (nCount < 1) { + return 0; + } + RemoveAll(); + SetSize(nCount); + ObjectClass* pStartObj = (ObjectClass*)m_pData; + nSize = nStart + nCount; + for (int32_t i = nStart; i < nSize; i++, pStartObj++) { + new ((void*)pStartObj) ObjectClass(src[i]); + } + return nCount; + } + + int GetSize() const { return m_nSize; } + + ObjectClass& operator[](int index) const { + FXSYS_assert(index < m_nSize); + return *(ObjectClass*)CFX_BasicArray::GetDataPtr(index); + } + + ObjectClass* GetDataPtr(int index) { + return (ObjectClass*)CFX_BasicArray::GetDataPtr(index); + } + + void RemoveAt(int index) { + FXSYS_assert(index < m_nSize); + ((ObjectClass*)GetDataPtr(index))->~ObjectClass(); + CFX_BasicArray::RemoveAt(index, 1); + } + + void RemoveAll() { + for (int i = 0; i < m_nSize; i++) { + ((ObjectClass*)GetDataPtr(i))->~ObjectClass(); + } + CFX_BasicArray::SetSize(0); + } +}; +typedef CFX_ObjectArray CFX_ByteStringArray; +typedef CFX_ObjectArray CFX_WideStringArray; +class CFX_BaseSegmentedArray { + public: + CFX_BaseSegmentedArray(int unit_size = 1, + int segment_units = 512, + int index_size = 8); + + ~CFX_BaseSegmentedArray(); + + void SetUnitSize(int unit_size, int segment_units, int index_size = 8); + + void* Add(); + + void* GetAt(int index) const; + + void RemoveAll(); + + void Delete(int index, int count = 1); + + int GetSize() const { return m_DataSize; } + + int GetSegmentSize() const { return m_SegmentSize; } + + int GetUnitSize() const { return m_UnitSize; } + + void* Iterate(FX_BOOL (*callback)(void* param, void* pData), + void* param) const; + + private: + int m_UnitSize; + + short m_SegmentSize; + + uint8_t m_IndexSize; + + uint8_t m_IndexDepth; + + int m_DataSize; + + void* m_pIndex; + void** GetIndex(int seg_index) const; + void* IterateIndex(int level, + int& start, + void** pIndex, + FX_BOOL (*callback)(void* param, void* pData), + void* param) const; + void* IterateSegment(const uint8_t* pSegment, + int count, + FX_BOOL (*callback)(void* param, void* pData), + void* param) const; +}; +template +class CFX_SegmentedArray : public CFX_BaseSegmentedArray { + public: + CFX_SegmentedArray(int segment_units, int index_size = 8) + : CFX_BaseSegmentedArray(sizeof(ElementType), segment_units, index_size) { + } + + void Add(ElementType data) { + *(ElementType*)CFX_BaseSegmentedArray::Add() = data; + } + + ElementType& operator[](int index) { + return *(ElementType*)CFX_BaseSegmentedArray::GetAt(index); + } +}; +#endif // PDF_ENABLE_XFA + +template +class CFX_FixedBufGrow { + public: + explicit CFX_FixedBufGrow(int data_size) { + if (data_size > FixedSize) { + m_pGrowData.reset(FX_Alloc(DataType, data_size)); + return; + } + FXSYS_memset(m_FixedData, 0, sizeof(DataType) * FixedSize); + } + operator DataType*() { return m_pGrowData ? m_pGrowData.get() : m_FixedData; } + + private: + DataType m_FixedData[FixedSize]; + std::unique_ptr m_pGrowData; +}; + +#ifdef PDF_ENABLE_XFA +class CFX_MapPtrToPtr { + protected: + struct CAssoc { + CAssoc* pNext; + void* key; + void* value; + }; + + public: + CFX_MapPtrToPtr(int nBlockSize = 10); + ~CFX_MapPtrToPtr(); + + int GetCount() const { return m_nCount; } + bool IsEmpty() const { return m_nCount == 0; } + + FX_BOOL Lookup(void* key, void*& rValue) const; + + void* GetValueAt(void* key) const; + + void*& operator[](void* key); + + void SetAt(void* key, void* newValue) { (*this)[key] = newValue; } + + FX_BOOL RemoveKey(void* key); + + void RemoveAll(); + + FX_POSITION GetStartPosition() const { + return (m_nCount == 0) ? NULL : (FX_POSITION)-1; + } + + void GetNextAssoc(FX_POSITION& rNextPosition, + void*& rKey, + void*& rValue) const; + + FX_DWORD GetHashTableSize() const { return m_nHashTableSize; } + + void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE); + + protected: + CAssoc** m_pHashTable; + + FX_DWORD m_nHashTableSize; + + int m_nCount; + + CAssoc* m_pFreeList; + + struct CFX_Plex* m_pBlocks; + + int m_nBlockSize; + + FX_DWORD HashKey(void* key) const; + + CAssoc* NewAssoc(); + + void FreeAssoc(CAssoc* pAssoc); + + CAssoc* GetAssocAt(void* key, FX_DWORD& hash) const; +}; + +template +class CFX_MapPtrTemplate : public CFX_MapPtrToPtr { + public: + CFX_MapPtrTemplate() : CFX_MapPtrToPtr(10) {} + + FX_BOOL Lookup(KeyType key, ValueType& rValue) const { + void* pValue = NULL; + if (!CFX_MapPtrToPtr::Lookup((void*)(uintptr_t)key, pValue)) { + return FALSE; + } + rValue = (ValueType)(uintptr_t)pValue; + return TRUE; + } + + ValueType& operator[](KeyType key) { + return (ValueType&)CFX_MapPtrToPtr::operator[]((void*)(uintptr_t)key); + } + + void SetAt(KeyType key, ValueType newValue) { + CFX_MapPtrToPtr::SetAt((void*)(uintptr_t)key, (void*)(uintptr_t)newValue); + } + + FX_BOOL RemoveKey(KeyType key) { + return CFX_MapPtrToPtr::RemoveKey((void*)(uintptr_t)key); + } + + void GetNextAssoc(FX_POSITION& rNextPosition, + KeyType& rKey, + ValueType& rValue) const { + void* pKey = NULL; + void* pValue = NULL; + CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue); + rKey = (KeyType)(uintptr_t)pKey; + rValue = (ValueType)(uintptr_t)pValue; + } +}; +#endif // PDF_ENABLE_XFA + +class CFX_PtrList { + protected: + struct CNode { + CNode* pNext; + CNode* pPrev; + void* data; + }; + + public: + CFX_PtrList(int nBlockSize = 10); + + FX_POSITION GetHeadPosition() const { return (FX_POSITION)m_pNodeHead; } + FX_POSITION GetTailPosition() const { return (FX_POSITION)m_pNodeTail; } + + void* GetNext(FX_POSITION& rPosition) const { + CNode* pNode = (CNode*)rPosition; + rPosition = (FX_POSITION)pNode->pNext; + return pNode->data; + } + + void* GetPrev(FX_POSITION& rPosition) const { + CNode* pNode = (CNode*)rPosition; + rPosition = (FX_POSITION)pNode->pPrev; + return pNode->data; + } + + FX_POSITION GetNextPosition(FX_POSITION pos) const { + return ((CNode*)pos)->pNext; + } + + FX_POSITION GetPrevPosition(FX_POSITION pos) const { + return ((CNode*)pos)->pPrev; + } + + void* GetAt(FX_POSITION rPosition) const { + CNode* pNode = (CNode*)rPosition; + return pNode->data; + } + + int GetCount() const { return m_nCount; } + FX_POSITION AddTail(void* newElement); + FX_POSITION AddHead(void* newElement); + + void SetAt(FX_POSITION pos, void* newElement) { + CNode* pNode = (CNode*)pos; + pNode->data = newElement; + } + FX_POSITION InsertAfter(FX_POSITION pos, void* newElement); + + FX_POSITION Find(void* searchValue, FX_POSITION startAfter = NULL) const; + FX_POSITION FindIndex(int index) const; + + void RemoveAt(FX_POSITION pos); + void RemoveAll(); + + protected: + CNode* m_pNodeHead; + CNode* m_pNodeTail; + int m_nCount; + CNode* m_pNodeFree; + struct CFX_Plex* m_pBlocks; + int m_nBlockSize; + + CNode* NewNode(CNode* pPrev, CNode* pNext); + void FreeNode(CNode* pNode); + + public: + ~CFX_PtrList(); +}; +typedef void (*PD_CALLBACK_FREEDATA)(void* pData); + +struct FX_PRIVATEDATA { + void FreeData(); + + void* m_pModuleId; + void* m_pData; + PD_CALLBACK_FREEDATA m_pCallback; + FX_BOOL m_bSelfDestruct; +}; + +class CFX_PrivateData { + public: + CFX_PrivateData(); + ~CFX_PrivateData(); + + void ClearAll(); + + void SetPrivateData(void* module_id, + void* pData, + PD_CALLBACK_FREEDATA callback); + void SetPrivateObj(void* module_id, CFX_DestructObject* pObj); + + void* GetPrivateData(void* module_id); + FX_BOOL LookupPrivateData(void* module_id, void*& pData) const { + if (!module_id) { + return FALSE; + } + FX_DWORD nCount = m_DataList.GetSize(); + for (FX_DWORD n = 0; n < nCount; n++) { + if (m_DataList[n].m_pModuleId == module_id) { + pData = m_DataList[n].m_pData; + return TRUE; + } + } + return FALSE; + } + + FX_BOOL RemovePrivateData(void* module_id); + + protected: + CFX_ArrayTemplate m_DataList; + + void AddData(void* module_id, + void* pData, + PD_CALLBACK_FREEDATA callback, + FX_BOOL bSelfDestruct); +}; + +class CFX_BitStream { + public: + void Init(const uint8_t* pData, FX_DWORD dwSize); + + FX_DWORD GetBits(FX_DWORD nBits); + + void ByteAlign(); + + FX_BOOL IsEOF() { return m_BitPos >= m_BitSize; } + + void SkipBits(FX_DWORD nBits) { m_BitPos += nBits; } + + void Rewind() { m_BitPos = 0; } + + FX_DWORD GetPos() const { return m_BitPos; } + + FX_DWORD BitsRemaining() const { + return m_BitSize >= m_BitPos ? m_BitSize - m_BitPos : 0; + } + + protected: + FX_DWORD m_BitPos; + + FX_DWORD m_BitSize; + + const uint8_t* m_pData; +}; +template +class CFX_CountRef { + public: + typedef CFX_CountRef Ref; + + class CountedObj : public ObjClass { + public: + CountedObj() {} + + CountedObj(const CountedObj& src) : ObjClass(src) {} + + int m_RefCount; + }; + + CFX_CountRef() { m_pObject = NULL; } + + CFX_CountRef(const Ref& ref) { + m_pObject = ref.m_pObject; + if (m_pObject) { + m_pObject->m_RefCount++; + } + } + + ~CFX_CountRef() { + if (!m_pObject) { + return; + } + m_pObject->m_RefCount--; + if (m_pObject->m_RefCount <= 0) { + delete m_pObject; + } + } + + ObjClass* New() { + if (m_pObject) { + m_pObject->m_RefCount--; + if (m_pObject->m_RefCount <= 0) { + delete m_pObject; + } + } + m_pObject = new CountedObj; + m_pObject->m_RefCount = 1; + return m_pObject; + } + + void operator=(const Ref& ref) { + if (ref.m_pObject) { + ref.m_pObject->m_RefCount++; + } + if (m_pObject) { + m_pObject->m_RefCount--; + if (m_pObject->m_RefCount <= 0) { + delete m_pObject; + } + } + m_pObject = ref.m_pObject; + } + + void operator=(void* p) { + FXSYS_assert(p == 0); + if (!m_pObject) { + return; + } + m_pObject->m_RefCount--; + if (m_pObject->m_RefCount <= 0) { + delete m_pObject; + } + m_pObject = NULL; + } + + const ObjClass* GetObject() const { return m_pObject; } + + operator const ObjClass*() const { return m_pObject; } + + FX_BOOL IsNull() const { return !m_pObject; } + + FX_BOOL NotNull() const { return !IsNull(); } + + ObjClass* GetModify() { + if (!m_pObject) { + m_pObject = new CountedObj; + m_pObject->m_RefCount = 1; + } else if (m_pObject->m_RefCount > 1) { + m_pObject->m_RefCount--; + CountedObj* pOldObject = m_pObject; + m_pObject = new CountedObj(*pOldObject); + m_pObject->m_RefCount = 1; + } + return m_pObject; + } + + void SetNull() { + if (!m_pObject) { + return; + } + m_pObject->m_RefCount--; + if (m_pObject->m_RefCount <= 0) { + delete m_pObject; + } + m_pObject = NULL; + } + + bool operator==(const Ref& ref) const { return m_pObject == ref.m_pObject; } + + protected: + CountedObj* m_pObject; +}; +class IFX_Pause { + public: + virtual ~IFX_Pause() {} + virtual FX_BOOL NeedToPauseNow() = 0; +}; + +template +class CFX_AutoRestorer { + public: + explicit CFX_AutoRestorer(T* location) + : m_Location(location), m_OldValue(*location) {} + ~CFX_AutoRestorer() { *m_Location = m_OldValue; } + + private: + T* const m_Location; + const T m_OldValue; +}; + +#define FX_DATALIST_LENGTH 1024 +template +class CFX_SortListArray { + protected: + struct DataList { + int32_t start; + + int32_t count; + uint8_t* data; + }; + + public: + CFX_SortListArray() : m_CurList(0) {} + + ~CFX_SortListArray() { Clear(); } + + void Clear() { + for (int32_t i = m_DataLists.GetUpperBound(); i >= 0; i--) { + DataList list = m_DataLists.ElementAt(i); + FX_Free(list.data); + } + m_DataLists.RemoveAll(); + m_CurList = 0; + } + + void Append(int32_t nStart, int32_t nCount) { + if (nStart < 0) { + return; + } + while (nCount > 0) { + int32_t temp_count = std::min(nCount, FX_DATALIST_LENGTH); + DataList list; + list.data = FX_Alloc2D(uint8_t, temp_count, unit); + list.start = nStart; + list.count = temp_count; + Append(list); + nCount -= temp_count; + nStart += temp_count; + } + } + + uint8_t* GetAt(int32_t nIndex) { + if (nIndex < 0) { + return NULL; + } + if (m_CurList < 0 || m_CurList >= m_DataLists.GetSize()) { + return NULL; + } + DataList* pCurList = m_DataLists.GetDataPtr(m_CurList); + if (!pCurList || nIndex < pCurList->start || + nIndex >= pCurList->start + pCurList->count) { + pCurList = NULL; + int32_t iStart = 0; + int32_t iEnd = m_DataLists.GetUpperBound(); + int32_t iMid = 0; + while (iStart <= iEnd) { + iMid = (iStart + iEnd) / 2; + DataList* list = m_DataLists.GetDataPtr(iMid); + if (nIndex < list->start) { + iEnd = iMid - 1; + } else if (nIndex >= list->start + list->count) { + iStart = iMid + 1; + } else { + pCurList = list; + m_CurList = iMid; + break; + } + } + } + return pCurList ? pCurList->data + (nIndex - pCurList->start) * unit : NULL; + } + + protected: + void Append(const DataList& list) { + int32_t iStart = 0; + int32_t iEnd = m_DataLists.GetUpperBound(); + int32_t iFind = 0; + while (iStart <= iEnd) { + int32_t iMid = (iStart + iEnd) / 2; + DataList* cur_list = m_DataLists.GetDataPtr(iMid); + if (list.start < cur_list->start + cur_list->count) { + iEnd = iMid - 1; + } else { + if (iMid == iEnd) { + iFind = iMid + 1; + break; + } + DataList* next_list = m_DataLists.GetDataPtr(iMid + 1); + if (list.start < next_list->start) { + iFind = iMid + 1; + break; + } else { + iStart = iMid + 1; + } + } + } + m_DataLists.InsertAt(iFind, list); + } + int32_t m_CurList; + CFX_ArrayTemplate m_DataLists; +}; +template +class CFX_ListArrayTemplate { + public: + void Clear() { m_Data.Clear(); } + + void Add(int32_t nStart, int32_t nCount) { m_Data.Append(nStart, nCount); } + + T2& operator[](int32_t nIndex) { + uint8_t* data = m_Data.GetAt(nIndex); + FXSYS_assert(data); + return (T2&)(*(volatile T2*)data); + } + + T2* GetPtrAt(int32_t nIndex) { return (T2*)m_Data.GetAt(nIndex); } + + protected: + T1 m_Data; +}; +typedef CFX_ListArrayTemplate, + FX_FILESIZE> CFX_FileSizeListArray; + +#ifdef PDF_ENABLE_XFA +class IFX_Unknown { + public: + virtual ~IFX_Unknown() {} + virtual FX_DWORD Release() = 0; + virtual FX_DWORD AddRef() = 0; +}; +#define FX_IsOdd(a) ((a)&1) +#endif // PDF_ENABLE_XFA + +class CFX_Vector_3by1 { + public: + CFX_Vector_3by1() : a(0.0f), b(0.0f), c(0.0f) {} + + CFX_Vector_3by1(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1) + : a(a1), b(b1), c(c1) {} + + FX_FLOAT a; + FX_FLOAT b; + FX_FLOAT c; +}; +class CFX_Matrix_3by3 { + public: + CFX_Matrix_3by3() + : a(0.0f), + b(0.0f), + c(0.0f), + d(0.0f), + e(0.0f), + f(0.0f), + g(0.0f), + h(0.0f), + i(0.0f) {} + + CFX_Matrix_3by3(FX_FLOAT a1, + FX_FLOAT b1, + FX_FLOAT c1, + FX_FLOAT d1, + FX_FLOAT e1, + FX_FLOAT f1, + FX_FLOAT g1, + FX_FLOAT h1, + FX_FLOAT i1) + : a(a1), b(b1), c(c1), d(d1), e(e1), f(f1), g(g1), h(h1), i(i1) {} + + CFX_Matrix_3by3 Inverse(); + + CFX_Matrix_3by3 Multiply(const CFX_Matrix_3by3& m); + + CFX_Vector_3by1 TransformVector(const CFX_Vector_3by1& v); + + FX_FLOAT a; + FX_FLOAT b; + FX_FLOAT c; + FX_FLOAT d; + FX_FLOAT e; + FX_FLOAT f; + FX_FLOAT g; + FX_FLOAT h; + FX_FLOAT i; +}; + +#endif // CORE_FXCRT_INCLUDE_FX_BASIC_H_ diff --git a/core/fxcrt/include/fx_coordinates.h b/core/fxcrt/include/fx_coordinates.h new file mode 100644 index 0000000000..a7f0b8d5dc --- /dev/null +++ b/core/fxcrt/include/fx_coordinates.h @@ -0,0 +1,672 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ +#define CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ + +#include "core/fxcrt/include/fx_basic.h" + +class CFX_Matrix; + +template +class CFX_PSTemplate { + public: + CFX_PSTemplate() : x(0), y(0) {} + CFX_PSTemplate(BaseType new_x, BaseType new_y) : x(new_x), y(new_y) {} + CFX_PSTemplate(const CFX_PSTemplate& other) : x(other.x), y(other.y) {} + void clear() { + x = 0; + y = 0; + } + CFX_PSTemplate operator=(const CFX_PSTemplate& other) { + if (this != &other) { + x = other.x; + y = other.y; + } + return *this; + } + bool operator==(const CFX_PSTemplate& other) const { + return x == other.x && y == other.y; + } + bool operator!=(const CFX_PSTemplate& other) const { + return !(*this == other); + } + CFX_PSTemplate& operator+=(const CFX_PSTemplate& obj) { + x += obj.x; + y += obj.y; + return *this; + } + CFX_PSTemplate& operator-=(const CFX_PSTemplate& obj) { + x -= obj.x; + y -= obj.y; + return *this; + } + CFX_PSTemplate& operator*=(BaseType factor) { + x *= factor; + y *= factor; + return *this; + } + CFX_PSTemplate& operator/=(BaseType divisor) { + x /= divisor; + y /= divisor; + return *this; + } + CFX_PSTemplate operator+(const CFX_PSTemplate& other) { + return CFX_PSTemplate(x + other.x, y + other.y); + } + CFX_PSTemplate operator-(const CFX_PSTemplate& other) { + return CFX_PSTemplate(x - other.x, y - other.y); + } + CFX_PSTemplate operator*(BaseType factor) { + return CFX_PSTemplate(x * factor, y * factor); + } + CFX_PSTemplate operator/(BaseType divisor) { + return CFX_PSTemplate(x / divisor, y / divisor); + } + + BaseType x; + BaseType y; +}; +typedef CFX_PSTemplate CFX_Point; +typedef CFX_PSTemplate CFX_PointF; +typedef CFX_PSTemplate CFX_Size; +typedef CFX_PSTemplate CFX_SizeF; +typedef CFX_ArrayTemplate CFX_Points; +typedef CFX_ArrayTemplate CFX_PointsF; + +template +class CFX_VTemplate : public CFX_PSTemplate { + public: + using CFX_PSTemplate::x; + using CFX_PSTemplate::y; + + CFX_VTemplate() : CFX_PSTemplate() {} + CFX_VTemplate(BaseType new_x, BaseType new_y) + : CFX_PSTemplate(new_x, new_y) {} + + CFX_VTemplate(const CFX_VTemplate& other) : CFX_PSTemplate(other) {} + + CFX_VTemplate(const CFX_PSTemplate& point1, + const CFX_PSTemplate& point2) + : CFX_PSTemplate(point2.x - point1.x, point2.y - point1.y) {} + + FX_FLOAT Length() const { return FXSYS_sqrt(x * x + y * y); } + void Normalize() { + FX_FLOAT fLen = Length(); + if (fLen < 0.0001f) + return; + + x /= fLen; + y /= fLen; + } + void Translate(BaseType dx, BaseType dy) { + x += dx; + y += dy; + } + void Scale(BaseType sx, BaseType sy) { + x *= sx; + y *= sy; + } + void Rotate(FX_FLOAT fRadian) { + FX_FLOAT cosValue = FXSYS_cos(fRadian); + FX_FLOAT sinValue = FXSYS_sin(fRadian); + x = x * cosValue - y * sinValue; + y = x * sinValue + y * cosValue; + } +}; +typedef CFX_VTemplate CFX_Vector; +typedef CFX_VTemplate CFX_VectorF; + +// Rectangles. +// TODO(tsepez): Consolidate all these different rectangle classes. + +// LTRB rectangles (y-axis runs downwards). +struct FX_SMALL_RECT { + FX_SMALL_RECT() : FX_SMALL_RECT(kInvalid, kInvalid, kInvalid, kInvalid) {} + + FX_SMALL_RECT(int16_t l, int16_t t, int16_t r, int16_t b) + : left(l), top(t), right(r), bottom(b) {} + + static const int16_t kInvalid = -1; + + int16_t left; + int16_t top; + int16_t right; + int16_t bottom; +}; + +struct FX_RECT { + FX_RECT() : left(0), top(0), right(0), bottom(0) {} + + FX_RECT(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {} + + explicit FX_RECT(const FX_SMALL_RECT& other) + : FX_RECT(other.left, other.top, other.right, other.bottom) {} + + int Width() const { return right - left; } + int Height() const { return bottom - top; } + bool IsEmpty() const { return right <= left || bottom <= top; } + + void Normalize(); + + void Intersect(const FX_RECT& src); + void Intersect(int l, int t, int r, int b) { Intersect(FX_RECT(l, t, r, b)); } + + void Union(const FX_RECT& other_rect); + void Union(int l, int t, int r, int b) { Union(FX_RECT(l, t, r, b)); } + + void Offset(int dx, int dy) { + left += dx; + right += dx; + top += dy; + bottom += dy; + } + + bool operator==(const FX_RECT& src) const { + return left == src.left && right == src.right && top == src.top && + bottom == src.bottom; + } + + FX_BOOL Contains(const FX_RECT& other_rect) const { + return other_rect.left >= left && other_rect.right <= right && + other_rect.top >= top && other_rect.bottom <= bottom; + } + + FX_BOOL Contains(int x, int y) const { + return x >= left && x < right && y >= top && y < bottom; + } + + FX_SMALL_RECT ToSmallRect() const { + return FX_SMALL_RECT( + static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)); + } + + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +// LBRT rectangles (y-axis runs upwards). +class CFX_FloatPoint { + public: + CFX_FloatPoint(FX_FLOAT xx, FX_FLOAT yy) : x(xx), y(yy) {} + + FX_FLOAT x; + FX_FLOAT y; +}; + +class CFX_FloatRect { + public: + CFX_FloatRect() : CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f) {} + CFX_FloatRect(FX_FLOAT l, FX_FLOAT b, FX_FLOAT r, FX_FLOAT t) + : left(l), bottom(b), right(r), top(t) {} + + explicit CFX_FloatRect(const FX_FLOAT* pArray) + : CFX_FloatRect(pArray[0], pArray[1], pArray[2], pArray[3]) {} + + explicit CFX_FloatRect(const FX_RECT& rect); + + void Normalize(); + + void Reset() { + left = 0.0f; + right = 0.0f; + bottom = 0.0f; + top = 0.0f; + } + + bool IsEmpty() const { return left >= right || bottom >= top; } + bool Contains(const CFX_FloatRect& other_rect) const; + bool Contains(FX_FLOAT x, FX_FLOAT y) const; + + void Transform(const CFX_Matrix* pMatrix); + void Intersect(const CFX_FloatRect& other_rect); + void Union(const CFX_FloatRect& other_rect); + + FX_RECT GetInnerRect() const; + FX_RECT GetOutterRect() const; + FX_RECT GetClosestRect() const; + + int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects); + + void InitRect(FX_FLOAT x, FX_FLOAT y) { + left = x; + right = x; + bottom = y; + top = y; + } + void UpdateRect(FX_FLOAT x, FX_FLOAT y); + + FX_FLOAT Width() const { return right - left; } + FX_FLOAT Height() const { return top - bottom; } + + void Inflate(FX_FLOAT x, FX_FLOAT y) { + Normalize(); + left -= x; + right += x; + bottom -= y; + top += y; + } + + void Inflate(FX_FLOAT other_left, + FX_FLOAT other_bottom, + FX_FLOAT other_right, + FX_FLOAT other_top) { + Normalize(); + left -= other_left; + bottom -= other_bottom; + right += other_right; + top += other_top; + } + + void Inflate(const CFX_FloatRect& rt) { + Inflate(rt.left, rt.bottom, rt.right, rt.top); + } + + void Deflate(FX_FLOAT x, FX_FLOAT y) { + Normalize(); + left += x; + right -= x; + bottom += y; + top -= y; + } + + void Deflate(FX_FLOAT other_left, + FX_FLOAT other_bottom, + FX_FLOAT other_right, + FX_FLOAT other_top) { + Normalize(); + left += other_left; + bottom += other_bottom; + right -= other_right; + top -= other_top; + } + + void Deflate(const CFX_FloatRect& rt) { + Deflate(rt.left, rt.bottom, rt.right, rt.top); + } + + void Translate(FX_FLOAT e, FX_FLOAT f) { + left += e; + right += e; + top += f; + bottom += f; + } + + static CFX_FloatRect GetBBox(const CFX_PointF* pPoints, int nPoints); + + FX_RECT ToFxRect() const { + return FX_RECT(static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)); + } + + FX_FLOAT left; + FX_FLOAT bottom; + FX_FLOAT right; + FX_FLOAT top; +}; +using CFX_RectArray = CFX_ArrayTemplate; + +// LTWH rectangles (y-axis runs downwards). +template +class CFX_RTemplate { + public: + typedef CFX_PSTemplate FXT_POINT; + typedef CFX_PSTemplate FXT_SIZE; + typedef CFX_VTemplate FXT_VECTOR; + typedef CFX_RTemplate FXT_RECT; + void Set(baseType left, baseType top, baseType width, baseType height) { + FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width, + FXT_RECT::height = height; + } + void Set(baseType left, baseType top, const FXT_SIZE& size) { + FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size); + } + void Set(const FXT_POINT& p, baseType width, baseType height) { + TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height; + } + void Set(const FXT_POINT& p1, const FXT_POINT& p2) { + TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y, + FXT_RECT::Normalize(); + } + void Set(const FXT_POINT& p, const FXT_VECTOR& v) { + TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y, + FXT_RECT::Normalize(); + } + void Reset() { + FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0; + } + FXT_RECT& operator+=(const FXT_POINT& p) { + left += p.x, top += p.y; + return *this; + } + FXT_RECT& operator-=(const FXT_POINT& p) { + left -= p.x, top -= p.y; + return *this; + } + baseType right() const { return left + width; } + baseType bottom() const { return top + height; } + void Normalize() { + if (width < 0) { + left += width; + width = -width; + } + if (height < 0) { + top += height; + height = -height; + } + } + void Offset(baseType dx, baseType dy) { + left += dx; + top += dy; + } + void Inflate(baseType x, baseType y) { + left -= x; + width += x * 2; + top -= y; + height += y * 2; + } + void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); } + void Inflate(baseType left, baseType top, baseType right, baseType bottom) { + FXT_RECT::left -= left; + FXT_RECT::top -= top; + FXT_RECT::width += left + right; + FXT_RECT::height += top + bottom; + } + void Inflate(const FXT_RECT& rt) { + Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); + } + void Deflate(baseType x, baseType y) { + left += x; + width -= x * 2; + top += y; + height -= y * 2; + } + void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); } + void Deflate(baseType left, baseType top, baseType right, baseType bottom) { + FXT_RECT::left += left; + FXT_RECT::top += top; + FXT_RECT::width -= left + right; + FXT_RECT::height -= top + bottom; + } + void Deflate(const FXT_RECT& rt) { + Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); + } + FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; } + FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const { + return width <= fEpsilon || height <= fEpsilon; + } + void Empty() { width = height = 0; } + FX_BOOL Contains(baseType x, baseType y) const { + return x >= left && x < left + width && y >= top && y < top + height; + } + FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); } + FX_BOOL Contains(const FXT_RECT& rt) const { + return rt.left >= left && rt.right() <= right() && rt.top >= top && + rt.bottom() <= bottom(); + } + baseType Width() const { return width; } + baseType Height() const { return height; } + FXT_SIZE Size() const { + FXT_SIZE size; + size.Set(width, height); + return size; + } + void Size(FXT_SIZE s) { width = s.x, height = s.y; } + FXT_POINT TopLeft() const { + FXT_POINT p; + p.x = left; + p.y = top; + return p; + } + FXT_POINT TopRight() const { + FXT_POINT p; + p.x = left + width; + p.y = top; + return p; + } + FXT_POINT BottomLeft() const { + FXT_POINT p; + p.x = left; + p.y = top + height; + return p; + } + FXT_POINT BottomRight() const { + FXT_POINT p; + p.x = left + width; + p.y = top + height; + return p; + } + void TopLeft(FXT_POINT tl) { + left = tl.x; + top = tl.y; + } + void TopRight(FXT_POINT tr) { + width = tr.x - left; + top = tr.y; + } + void BottomLeft(FXT_POINT bl) { + left = bl.x; + height = bl.y - top; + } + void BottomRight(FXT_POINT br) { + width = br.x - left; + height = br.y - top; + } + FXT_POINT Center() const { + FXT_POINT p; + p.x = left + width / 2; + p.y = top + height / 2; + return p; + } + void Union(baseType x, baseType y) { + baseType r = right(), b = bottom(); + if (left > x) { + left = x; + } + if (r < x) { + r = x; + } + if (top > y) { + top = y; + } + if (b < y) { + b = y; + } + width = r - left; + height = b - top; + } + void Union(const FXT_POINT& p) { Union(p.x, p.y); } + void Union(const FXT_RECT& rt) { + baseType r = right(), b = bottom(); + if (left > rt.left) { + left = rt.left; + } + if (r < rt.right()) { + r = rt.right(); + } + if (top > rt.top) { + top = rt.top; + } + if (b < rt.bottom()) { + b = rt.bottom(); + } + width = r - left; + height = b - top; + } + void Intersect(const FXT_RECT& rt) { + baseType r = right(), b = bottom(); + if (left < rt.left) { + left = rt.left; + } + if (r > rt.right()) { + r = rt.right(); + } + if (top < rt.top) { + top = rt.top; + } + if (b > rt.bottom()) { + b = rt.bottom(); + } + width = r - left; + height = b - top; + } + FX_BOOL IntersectWith(const FXT_RECT& rt) const { + FXT_RECT rect = rt; + rect.Intersect(*this); + return !rect.IsEmpty(); + } + FX_BOOL IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const { + FXT_RECT rect = rt; + rect.Intersect(*this); + return !rect.IsEmpty(fEpsilon); + } + friend bool operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) { + return rc1.left == rc2.left && rc1.top == rc2.top && + rc1.width == rc2.width && rc1.height == rc2.height; + } + friend bool operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) { + return !(rc1 == rc2); + } + baseType left, top; + baseType width, height; +}; +typedef CFX_RTemplate CFX_Rect; +typedef CFX_RTemplate CFX_RectF; +typedef CFX_ArrayTemplate CFX_RectFArray; + +class CFX_Matrix { + public: + CFX_Matrix() { SetIdentity(); } + + CFX_Matrix(FX_FLOAT a1, + FX_FLOAT b1, + FX_FLOAT c1, + FX_FLOAT d1, + FX_FLOAT e1, + FX_FLOAT f1) { + a = a1; + b = b1; + c = c1; + d = d1; + e = e1; + f = f1; + } + + void Set(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f); + void Set(const FX_FLOAT n[6]); + + void SetIdentity() { + a = d = 1; + b = c = e = f = 0; + } + + void SetReverse(const CFX_Matrix& m); + + void Concat(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f, + FX_BOOL bPrepended = FALSE); + void Concat(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); + void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); + + void Copy(const CFX_Matrix& m) { *this = m; } + + FX_BOOL IsIdentity() const { + return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0; + } + FX_BOOL IsInvertible() const; + + FX_BOOL Is90Rotated() const; + + FX_BOOL IsScaled() const; + + void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE); + + void TranslateI(int32_t x, int32_t y, FX_BOOL bPrepended = FALSE) { + Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended); + } + + void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE); + + void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE); + + void RotateAt(FX_FLOAT fRadian, + FX_FLOAT x, + FX_FLOAT y, + FX_BOOL bPrepended = FALSE); + + void Shear(FX_FLOAT fAlphaRadian, + FX_FLOAT fBetaRadian, + FX_BOOL bPrepended = FALSE); + + void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src); + + FX_FLOAT GetXUnit() const; + + FX_FLOAT GetYUnit() const; + void GetUnitRect(CFX_RectF& rect) const; + + CFX_FloatRect GetUnitRect() const; + + FX_FLOAT GetUnitArea() const; + FX_FLOAT TransformXDistance(FX_FLOAT dx) const; + int32_t TransformXDistance(int32_t dx) const; + FX_FLOAT TransformYDistance(FX_FLOAT dy) const; + int32_t TransformYDistance(int32_t dy) const; + FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const; + int32_t TransformDistance(int32_t dx, int32_t dy) const; + FX_FLOAT TransformDistance(FX_FLOAT distance) const; + + void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const; + void TransformPoint(int32_t& x, int32_t& y) const; + + void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); } + void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const { + x1 = x, y1 = y; + TransformPoint(x1, y1); + } + + void TransformVector(CFX_VectorF& v) const; + void TransformVector(CFX_Vector& v) const; + void TransformRect(CFX_RectF& rect) const; + void TransformRect(CFX_Rect& rect) const; + + void TransformRect(FX_FLOAT& left, + FX_FLOAT& right, + FX_FLOAT& top, + FX_FLOAT& bottom) const; + void TransformRect(CFX_FloatRect& rect) const { + TransformRect(rect.left, rect.right, rect.top, rect.bottom); + } + + FX_FLOAT GetA() const { return a; } + FX_FLOAT GetB() const { return b; } + FX_FLOAT GetC() const { return c; } + FX_FLOAT GetD() const { return d; } + FX_FLOAT GetE() const { return e; } + FX_FLOAT GetF() const { return f; } + + public: + FX_FLOAT a; + FX_FLOAT b; + FX_FLOAT c; + FX_FLOAT d; + FX_FLOAT e; + FX_FLOAT f; +}; + +#endif // CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ diff --git a/core/fxcrt/include/fx_ext.h b/core/fxcrt/include/fx_ext.h new file mode 100644 index 0000000000..2a39530c07 --- /dev/null +++ b/core/fxcrt/include/fx_ext.h @@ -0,0 +1,134 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_EXT_H_ +#define CORE_FXCRT_INCLUDE_FX_EXT_H_ + +#include +#include + +#include "core/fxcrt/include/fx_basic.h" + +// TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal. +// Come up or wait for something better. This appears in this file rather +// than fx_stream.h due to include ordering restrictions. +using ScopedFileStream = + std::unique_ptr>; + +FX_FLOAT FXSYS_tan(FX_FLOAT a); +FX_FLOAT FXSYS_logb(FX_FLOAT b, FX_FLOAT x); +FX_FLOAT FXSYS_strtof(const FX_CHAR* pcsStr, + int32_t iLength = -1, + int32_t* pUsedLen = NULL); +FX_FLOAT FXSYS_wcstof(const FX_WCHAR* pwsStr, + int32_t iLength = -1, + int32_t* pUsedLen = NULL); +FX_WCHAR* FXSYS_wcsncpy(FX_WCHAR* dstStr, const FX_WCHAR* srcStr, size_t count); +int32_t FXSYS_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count); +int32_t FXSYS_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count); + +inline bool FXSYS_islower(int32_t ch) { + return ch >= 'a' && ch <= 'z'; +} +inline bool FXSYS_isupper(int32_t ch) { + return ch >= 'A' && ch <= 'Z'; +} +inline int32_t FXSYS_tolower(int32_t ch) { + return ch < 'A' || ch > 'Z' ? ch : (ch + 0x20); +} +inline int32_t FXSYS_toupper(int32_t ch) { + return ch < 'a' || ch > 'z' ? ch : (ch - 0x20); +} +inline bool FXSYS_iswalpha(wchar_t wch) { + return (wch >= L'A' && wch <= L'Z') || (wch >= L'a' && wch <= L'z'); +} +inline bool FXSYS_iswdigit(wchar_t wch) { + return wch >= L'0' && wch <= L'9'; +} +inline bool FXSYS_iswalnum(wchar_t wch) { + return FXSYS_iswalpha(wch) || FXSYS_iswdigit(wch); +} + +inline int FXSYS_toHexDigit(const FX_CHAR c) { + if (!std::isxdigit(c)) + return 0; + char upchar = std::toupper(c); + return upchar > '9' ? upchar - 'A' + 10 : upchar - '0'; +} + +inline bool FXSYS_isDecimalDigit(const FX_CHAR c) { + return !!std::isdigit(c); +} + +inline bool FXSYS_isDecimalDigit(const FX_WCHAR c) { + return !!std::iswdigit(c); +} + +inline int FXSYS_toDecimalDigit(const FX_CHAR c) { + return std::isdigit(c) ? c - '0' : 0; +} + +inline int FXSYS_toDecimalDigit(const FX_WCHAR c) { + return std::iswdigit(c) ? c - L'0' : 0; +} + +FX_DWORD FX_HashCode_String_GetA(const FX_CHAR* pStr, + int32_t iLength, + FX_BOOL bIgnoreCase = FALSE); +FX_DWORD FX_HashCode_String_GetW(const FX_WCHAR* pStr, + int32_t iLength, + FX_BOOL bIgnoreCase = FALSE); + +void* FX_Random_MT_Start(FX_DWORD dwSeed); + +FX_DWORD FX_Random_MT_Generate(void* pContext); + +void FX_Random_MT_Close(void* pContext); + +void FX_Random_GenerateBase(FX_DWORD* pBuffer, int32_t iCount); + +void FX_Random_GenerateMT(FX_DWORD* pBuffer, int32_t iCount); + +void FX_Random_GenerateCrypto(FX_DWORD* pBuffer, int32_t iCount); + +#ifdef PDF_ENABLE_XFA +typedef struct FX_GUID { + FX_DWORD data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +} FX_GUID, *FX_LPGUID; +typedef FX_GUID const* FX_LPCGUID; +void FX_GUID_CreateV4(FX_LPGUID pGUID); +void FX_GUID_ToString(FX_LPCGUID pGUID, + CFX_ByteString& bsStr, + FX_BOOL bSeparator = TRUE); +#endif // PDF_ENABLE_XFA + +template +class CFX_SSortTemplate { + public: + void ShellSort(baseType* pArray, int32_t iCount) { + FXSYS_assert(pArray && iCount > 0); + int32_t i, j, gap; + baseType v1, v2; + gap = iCount >> 1; + while (gap > 0) { + for (i = gap; i < iCount; i++) { + j = i - gap; + v1 = pArray[i]; + while (j > -1 && (v2 = pArray[j]) > v1) { + pArray[j + gap] = v2; + j -= gap; + } + pArray[j + gap] = v1; + } + gap >>= 1; + } + } +}; + +#endif // CORE_FXCRT_INCLUDE_FX_EXT_H_ diff --git a/core/fxcrt/include/fx_memory.h b/core/fxcrt/include/fx_memory.h new file mode 100644 index 0000000000..c3dafc8d5e --- /dev/null +++ b/core/fxcrt/include/fx_memory.h @@ -0,0 +1,84 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_MEMORY_H_ +#define CORE_FXCRT_INCLUDE_FX_MEMORY_H_ + +#include "core/fxcrt/include/fx_system.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// For external C libraries to malloc through PDFium. These may return NULL. +void* FXMEM_DefaultAlloc(size_t byte_size, int flags); +void* FXMEM_DefaultRealloc(void* pointer, size_t new_size, int flags); +void FXMEM_DefaultFree(void* pointer, int flags); + +#ifdef __cplusplus +} // extern "C" + +#include +#include +#include + +NEVER_INLINE void FX_OutOfMemoryTerminate(); + +inline void* FX_SafeRealloc(void* ptr, size_t num_members, size_t member_size) { + if (num_members < std::numeric_limits::max() / member_size) { + return realloc(ptr, num_members * member_size); + } + return nullptr; +} + +inline void* FX_AllocOrDie(size_t num_members, size_t member_size) { + // TODO(tsepez): See if we can avoid the implicit memset(0). + if (void* result = calloc(num_members, member_size)) { + return result; + } + FX_OutOfMemoryTerminate(); // Never returns. + return nullptr; // Suppress compiler warning. +} + +inline void* FX_AllocOrDie2D(size_t w, size_t h, size_t member_size) { + if (w < std::numeric_limits::max() / h) { + return FX_AllocOrDie(w * h, member_size); + } + FX_OutOfMemoryTerminate(); // Never returns. + return nullptr; // Suppress compiler warning. +} + +inline void* FX_ReallocOrDie(void* ptr, + size_t num_members, + size_t member_size) { + if (void* result = FX_SafeRealloc(ptr, num_members, member_size)) { + return result; + } + FX_OutOfMemoryTerminate(); // Never returns. + return nullptr; // Suppress compiler warning. +} + +// Never returns NULL. +#define FX_Alloc(type, size) (type*) FX_AllocOrDie(size, sizeof(type)) +#define FX_Alloc2D(type, w, h) (type*) FX_AllocOrDie2D(w, h, sizeof(type)) +#define FX_Realloc(type, ptr, size) \ + (type*) FX_ReallocOrDie(ptr, size, sizeof(type)) + +// May return NULL. +#define FX_TryAlloc(type, size) (type*) calloc(size, sizeof(type)) +#define FX_TryRealloc(type, ptr, size) \ + (type*) FX_SafeRealloc(ptr, size, sizeof(type)) + +#define FX_Free(ptr) free(ptr) + +class CFX_DestructObject { + public: + virtual ~CFX_DestructObject() {} +}; + +#endif // __cplusplus + +#endif // CORE_FXCRT_INCLUDE_FX_MEMORY_H_ diff --git a/core/fxcrt/include/fx_safe_types.h b/core/fxcrt/include/fx_safe_types.h new file mode 100644 index 0000000000..47eb55ddd5 --- /dev/null +++ b/core/fxcrt/include/fx_safe_types.h @@ -0,0 +1,20 @@ +// 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. + +#ifndef CORE_FXCRT_INCLUDE_FX_SAFE_TYPES_H_ +#define CORE_FXCRT_INCLUDE_FX_SAFE_TYPES_H_ + +#include // For size_t. + +#include "core/fxcrt/include/fx_stream.h" // for FX_FILESIZE. +#include "core/fxcrt/include/fx_system.h" +#include "third_party/base/numerics/safe_math.h" + +typedef pdfium::base::CheckedNumeric FX_SAFE_DWORD; +typedef pdfium::base::CheckedNumeric FX_SAFE_INT32; +typedef pdfium::base::CheckedNumeric FX_SAFE_SIZE_T; +typedef pdfium::base::CheckedNumeric FX_SAFE_FILESIZE; +typedef pdfium::base::CheckedNumeric FX_SAFE_STRSIZE; + +#endif // CORE_FXCRT_INCLUDE_FX_SAFE_TYPES_H_ diff --git a/core/fxcrt/include/fx_stream.h b/core/fxcrt/include/fx_stream.h new file mode 100644 index 0000000000..4b77796821 --- /dev/null +++ b/core/fxcrt/include/fx_stream.h @@ -0,0 +1,162 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_STREAM_H_ +#define CORE_FXCRT_INCLUDE_FX_STREAM_H_ + +#include "core/fxcrt/include/fx_string.h" +#include "core/fxcrt/include/fx_system.h" + +void* FX_OpenFolder(const FX_CHAR* path); +void* FX_OpenFolder(const FX_WCHAR* path); +FX_BOOL FX_GetNextFile(void* handle, + CFX_ByteString& filename, + FX_BOOL& bFolder); +FX_BOOL FX_GetNextFile(void* handle, + CFX_WideString& filename, + FX_BOOL& bFolder); +void FX_CloseFolder(void* handle); +FX_WCHAR FX_GetFolderSeparator(); + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define FX_FILESIZE int32_t +#else +#include +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif // O_BINARY + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif // O_LARGEFILE + +#define FX_FILESIZE off_t +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +#define FX_GETBYTEOFFSET32(a) 0 +#define FX_GETBYTEOFFSET40(a) 0 +#define FX_GETBYTEOFFSET48(a) 0 +#define FX_GETBYTEOFFSET56(a) 0 +#define FX_GETBYTEOFFSET24(a) ((uint8_t)(a >> 24)) +#define FX_GETBYTEOFFSET16(a) ((uint8_t)(a >> 16)) +#define FX_GETBYTEOFFSET8(a) ((uint8_t)(a >> 8)) +#define FX_GETBYTEOFFSET0(a) ((uint8_t)(a)) +#define FX_FILEMODE_Write 0 +#define FX_FILEMODE_ReadOnly 1 +#define FX_FILEMODE_Truncate 2 + +class IFX_StreamWrite { + public: + virtual ~IFX_StreamWrite() {} + virtual void Release() = 0; + virtual FX_BOOL WriteBlock(const void* pData, size_t size) = 0; +}; + +class IFX_FileWrite : public IFX_StreamWrite { + public: + // IFX_StreamWrite: + FX_BOOL WriteBlock(const void* pData, size_t size) override; + virtual FX_FILESIZE GetSize() = 0; + virtual FX_BOOL Flush() = 0; + virtual FX_BOOL WriteBlock(const void* pData, + FX_FILESIZE offset, + size_t size) = 0; +}; + +class IFX_StreamRead { + public: + virtual ~IFX_StreamRead() {} + + virtual void Release() = 0; + virtual FX_BOOL IsEOF() = 0; + virtual FX_FILESIZE GetPosition() = 0; + virtual size_t ReadBlock(void* buffer, size_t size) = 0; +}; + +class IFX_FileRead : IFX_StreamRead { + public: + // IFX_StreamRead: + void Release() override = 0; + FX_BOOL IsEOF() override; + FX_FILESIZE GetPosition() override; + size_t ReadBlock(void* buffer, size_t size) override; + + virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) = 0; + virtual FX_FILESIZE GetSize() = 0; +}; + +IFX_FileRead* FX_CreateFileRead(const FX_CHAR* filename); +IFX_FileRead* FX_CreateFileRead(const FX_WCHAR* filename); + +class IFX_FileStream : public IFX_FileRead, public IFX_FileWrite { + public: + virtual IFX_FileStream* Retain() = 0; + + // IFX_FileRead: + void Release() override = 0; + FX_BOOL IsEOF() override = 0; + FX_FILESIZE GetPosition() override = 0; + size_t ReadBlock(void* buffer, size_t size) override = 0; + FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override = 0; + FX_FILESIZE GetSize() override = 0; + + // IFX_FileWrite: + FX_BOOL WriteBlock(const void* buffer, + FX_FILESIZE offset, + size_t size) override = 0; + FX_BOOL WriteBlock(const void* buffer, size_t size) override; + FX_BOOL Flush() override = 0; +}; + +IFX_FileStream* FX_CreateFileStream(const FX_CHAR* filename, FX_DWORD dwModes); +IFX_FileStream* FX_CreateFileStream(const FX_WCHAR* filename, FX_DWORD dwModes); + +#ifdef PDF_ENABLE_XFA +class IFX_FileAccess { + public: + virtual ~IFX_FileAccess() {} + virtual void Release() = 0; + virtual IFX_FileAccess* Retain() = 0; + virtual void GetPath(CFX_WideString& wsPath) = 0; + virtual IFX_FileStream* CreateFileStream(FX_DWORD dwModes) = 0; +}; +IFX_FileAccess* FX_CreateDefaultFileAccess(const CFX_WideStringC& wsPath); +#endif // PDF_ENABLE_XFA + +class IFX_MemoryStream : public IFX_FileStream { + public: + virtual FX_BOOL IsConsecutive() const = 0; + virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) = 0; + virtual uint8_t* GetBuffer() const = 0; + virtual void AttachBuffer(uint8_t* pBuffer, + size_t nSize, + FX_BOOL bTakeOver = FALSE) = 0; + virtual void DetachBuffer() = 0; +}; + +IFX_MemoryStream* FX_CreateMemoryStream(uint8_t* pBuffer, + size_t nSize, + FX_BOOL bTakeOver = FALSE); +IFX_MemoryStream* FX_CreateMemoryStream(FX_BOOL bConsecutive = FALSE); + +class IFX_BufferRead : public IFX_StreamRead { + public: + // IFX_StreamRead: + void Release() override = 0; + FX_BOOL IsEOF() override = 0; + FX_FILESIZE GetPosition() override = 0; + size_t ReadBlock(void* buffer, size_t size) override = 0; + + virtual FX_BOOL ReadNextBlock(FX_BOOL bRestart = FALSE) = 0; + virtual const uint8_t* GetBlockBuffer() = 0; + virtual size_t GetBlockSize() = 0; + virtual FX_FILESIZE GetBlockOffset() = 0; +}; + +#endif // CORE_FXCRT_INCLUDE_FX_STREAM_H_ diff --git a/core/fxcrt/include/fx_string.h b/core/fxcrt/include/fx_string.h new file mode 100644 index 0000000000..4bca083dd0 --- /dev/null +++ b/core/fxcrt/include/fx_string.h @@ -0,0 +1,819 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_STRING_H_ +#define CORE_FXCRT_INCLUDE_FX_STRING_H_ + +#include // For intptr_t. +#include + +#include "core/fxcrt/include/fx_memory.h" +#include "core/fxcrt/include/fx_system.h" + +class CFX_BinaryBuf; +class CFX_ByteString; +class CFX_WideString; + +// An immutable string with caller-provided storage which must outlive the +// string itself. +class CFX_ByteStringC { + public: + typedef FX_CHAR value_type; + + CFX_ByteStringC() { + m_Ptr = NULL; + m_Length = 0; + } + + CFX_ByteStringC(const uint8_t* ptr, FX_STRSIZE size) { + m_Ptr = ptr; + m_Length = size; + } + + CFX_ByteStringC(const FX_CHAR* ptr) { + m_Ptr = (const uint8_t*)ptr; + m_Length = ptr ? FXSYS_strlen(ptr) : 0; + } + + // |ch| must be an lvalue that outlives the the CFX_ByteStringC. However, + // the use of char rvalues are not caught at compile time. They are + // implicitly promoted to CFX_ByteString (see below) and then the + // CFX_ByteStringC is constructed from the CFX_ByteString via the alternate + // constructor below. The CFX_ByteString then typically goes out of scope + // and |m_Ptr| may be left pointing to invalid memory. Beware. + // TODO(tsepez): Mark single-argument string constructors as explicit. + CFX_ByteStringC(FX_CHAR& ch) { + m_Ptr = (const uint8_t*)&ch; + m_Length = 1; + } + + CFX_ByteStringC(const FX_CHAR* ptr, FX_STRSIZE len) { + m_Ptr = (const uint8_t*)ptr; + m_Length = (len == -1) ? FXSYS_strlen(ptr) : len; + } + + CFX_ByteStringC(const CFX_ByteStringC& src) { + m_Ptr = src.m_Ptr; + m_Length = src.m_Length; + } + + CFX_ByteStringC(const CFX_ByteString& src); + + CFX_ByteStringC& operator=(const FX_CHAR* src) { + m_Ptr = (const uint8_t*)src; + m_Length = m_Ptr ? FXSYS_strlen(src) : 0; + return *this; + } + + CFX_ByteStringC& operator=(const CFX_ByteStringC& src) { + m_Ptr = src.m_Ptr; + m_Length = src.m_Length; + return *this; + } + + CFX_ByteStringC& operator=(const CFX_ByteString& src); + + bool operator==(const char* ptr) const { + return FXSYS_strlen(ptr) == m_Length && + FXSYS_memcmp(ptr, m_Ptr, m_Length) == 0; + } + bool operator==(const CFX_ByteStringC& other) const { + return other.m_Length == m_Length && + FXSYS_memcmp(other.m_Ptr, m_Ptr, m_Length) == 0; + } + bool operator!=(const char* ptr) const { return !(*this == ptr); } + bool operator!=(const CFX_ByteStringC& other) const { + return !(*this == other); + } + + FX_DWORD GetID(FX_STRSIZE start_pos = 0) const; + + const uint8_t* GetPtr() const { return m_Ptr; } + + const FX_CHAR* GetCStr() const { return (const FX_CHAR*)m_Ptr; } + + FX_STRSIZE GetLength() const { return m_Length; } + + bool IsEmpty() const { return m_Length == 0; } + + uint8_t GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } + + CFX_ByteStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { + if (index < 0) { + index = 0; + } + if (index > m_Length) { + return CFX_ByteStringC(); + } + if (count < 0 || count > m_Length - index) { + count = m_Length - index; + } + return CFX_ByteStringC(m_Ptr + index, count); + } + + const uint8_t& operator[](size_t index) const { return m_Ptr[index]; } + + bool operator<(const CFX_ByteStringC& that) const { + int result = memcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length)); + return result < 0 || (result == 0 && m_Length < that.m_Length); + } + + protected: + const uint8_t* m_Ptr; + FX_STRSIZE m_Length; + + private: + void* operator new(size_t) throw() { return NULL; } +}; +inline bool operator==(const char* lhs, const CFX_ByteStringC& rhs) { + return rhs == lhs; +} +inline bool operator!=(const char* lhs, const CFX_ByteStringC& rhs) { + return rhs != lhs; +} +#define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)) + +// A mutable string with shared buffers using copy-on-write semantics that +// avoids the cost of std::string's iterator stability guarantees. +class CFX_ByteString { + public: + typedef FX_CHAR value_type; + + CFX_ByteString() : m_pData(nullptr) {} + + // Copy constructor. + CFX_ByteString(const CFX_ByteString& str); + + // Move constructor. + inline CFX_ByteString(CFX_ByteString&& other) { + m_pData = other.m_pData; + other.m_pData = nullptr; + } + + CFX_ByteString(char ch); + CFX_ByteString(const FX_CHAR* ptr) + : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) {} + + CFX_ByteString(const FX_CHAR* ptr, FX_STRSIZE len); + CFX_ByteString(const uint8_t* ptr, FX_STRSIZE len); + + CFX_ByteString(const CFX_ByteStringC& bstrc); + CFX_ByteString(const CFX_ByteStringC& bstrc1, const CFX_ByteStringC& bstrc2); + + ~CFX_ByteString(); + + static CFX_ByteString FromUnicode(const FX_WCHAR* ptr, FX_STRSIZE len = -1); + + static CFX_ByteString FromUnicode(const CFX_WideString& str); + + // Explicit conversion to C-style string. + const FX_CHAR* c_str() const { return m_pData ? m_pData->m_String : ""; } + + // Implicit conversion to C-style string -- deprecated. + operator const FX_CHAR*() const { return m_pData ? m_pData->m_String : ""; } + + // Explicit conversion to uint8_t*. + const uint8_t* raw_str() const { + return m_pData ? reinterpret_cast(m_pData->m_String) + : nullptr; + } + + // Implicit conversiont to uint8_t* -- deprecated. + operator const uint8_t*() const { + return m_pData ? reinterpret_cast(m_pData->m_String) + : nullptr; + } + + FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; } + + bool IsEmpty() const { return !GetLength(); } + + int Compare(const CFX_ByteStringC& str) const; + + bool Equal(const char* ptr) const; + bool Equal(const CFX_ByteStringC& str) const; + bool Equal(const CFX_ByteString& other) const; + + bool EqualNoCase(const CFX_ByteStringC& str) const; + + bool operator==(const char* ptr) const { return Equal(ptr); } + bool operator==(const CFX_ByteStringC& str) const { return Equal(str); } + bool operator==(const CFX_ByteString& other) const { return Equal(other); } + + bool operator!=(const char* ptr) const { return !(*this == ptr); } + bool operator!=(const CFX_ByteStringC& str) const { return !(*this == str); } + bool operator!=(const CFX_ByteString& other) const { + return !(*this == other); + } + + bool operator<(const CFX_ByteString& str) const { + int result = FXSYS_memcmp(c_str(), str.c_str(), + std::min(GetLength(), str.GetLength())); + return result < 0 || (result == 0 && GetLength() < str.GetLength()); + } + + void Empty(); + + const CFX_ByteString& operator=(const FX_CHAR* str); + + const CFX_ByteString& operator=(const CFX_ByteStringC& bstrc); + + const CFX_ByteString& operator=(const CFX_ByteString& stringSrc); + + const CFX_ByteString& operator=(const CFX_BinaryBuf& buf); + + void Load(const uint8_t* str, FX_STRSIZE len); + + const CFX_ByteString& operator+=(FX_CHAR ch); + + const CFX_ByteString& operator+=(const FX_CHAR* str); + + const CFX_ByteString& operator+=(const CFX_ByteString& str); + + const CFX_ByteString& operator+=(const CFX_ByteStringC& bstrc); + + uint8_t GetAt(FX_STRSIZE nIndex) const { + return m_pData ? m_pData->m_String[nIndex] : 0; + } + + uint8_t operator[](FX_STRSIZE nIndex) const { + return m_pData ? m_pData->m_String[nIndex] : 0; + } + + void SetAt(FX_STRSIZE nIndex, FX_CHAR ch); + + FX_STRSIZE Insert(FX_STRSIZE index, FX_CHAR ch); + + FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1); + + void Format(const FX_CHAR* lpszFormat, ...); + + void FormatV(const FX_CHAR* lpszFormat, va_list argList); + + void Reserve(FX_STRSIZE len); + + FX_CHAR* GetBuffer(FX_STRSIZE len); + + void ReleaseBuffer(FX_STRSIZE len = -1); + + CFX_ByteString Mid(FX_STRSIZE first) const; + + CFX_ByteString Mid(FX_STRSIZE first, FX_STRSIZE count) const; + + CFX_ByteString Left(FX_STRSIZE count) const; + + CFX_ByteString Right(FX_STRSIZE count) const; + + FX_STRSIZE Find(const CFX_ByteStringC& lpszSub, FX_STRSIZE start = 0) const; + + FX_STRSIZE Find(FX_CHAR ch, FX_STRSIZE start = 0) const; + + FX_STRSIZE ReverseFind(FX_CHAR ch) const; + + void MakeLower(); + + void MakeUpper(); + + void TrimRight(); + + void TrimRight(FX_CHAR chTarget); + + void TrimRight(const CFX_ByteStringC& lpszTargets); + + void TrimLeft(); + + void TrimLeft(FX_CHAR chTarget); + + void TrimLeft(const CFX_ByteStringC& lpszTargets); + + FX_STRSIZE Replace(const CFX_ByteStringC& lpszOld, + const CFX_ByteStringC& lpszNew); + + FX_STRSIZE Remove(FX_CHAR ch); + + CFX_WideString UTF8Decode() const; + + FX_DWORD GetID(FX_STRSIZE start_pos = 0) const; + +#define FXFORMAT_SIGNED 1 +#define FXFORMAT_HEX 2 +#define FXFORMAT_CAPITAL 4 + + static CFX_ByteString FormatInteger(int i, FX_DWORD flags = 0); + static CFX_ByteString FormatFloat(FX_FLOAT f, int precision = 0); + + protected: + // To ensure ref counts do not overflow, consider the worst possible case: + // the entire address space contains nothing but pointers to this object. + // Since the count increments with each new pointer, the largest value is + // the number of pointers that can fit into the address space. The size of + // the address space itself is a good upper bound on it; we need not go + // larger. + class StringData { + public: + static StringData* Create(int nLen); + void Retain() { ++m_nRefs; } + void Release() { + if (--m_nRefs <= 0) + FX_Free(this); + } + + intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. + FX_STRSIZE m_nDataLength; + FX_STRSIZE m_nAllocLength; + FX_CHAR m_String[1]; + + private: + StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen) + : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) { + FXSYS_assert(dataLen >= 0); + FXSYS_assert(allocLen >= 0); + FXSYS_assert(dataLen <= allocLen); + m_String[dataLen] = 0; + } + ~StringData() = delete; + }; + + void AllocCopy(CFX_ByteString& dest, + FX_STRSIZE nCopyLen, + FX_STRSIZE nCopyIndex) const; + void AssignCopy(FX_STRSIZE nSrcLen, const FX_CHAR* lpszSrcData); + void ConcatCopy(FX_STRSIZE nSrc1Len, + const FX_CHAR* lpszSrc1Data, + FX_STRSIZE nSrc2Len, + const FX_CHAR* lpszSrc2Data); + void ConcatInPlace(FX_STRSIZE nSrcLen, const FX_CHAR* lpszSrcData); + void CopyBeforeWrite(); + void AllocBeforeWrite(FX_STRSIZE nLen); + + StringData* m_pData; + friend class fxcrt_ByteStringConcatInPlace_Test; +}; +inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src) { + m_Ptr = (const uint8_t*)src; + m_Length = src.GetLength(); +} +inline CFX_ByteStringC& CFX_ByteStringC::operator=(const CFX_ByteString& src) { + m_Ptr = (const uint8_t*)src; + m_Length = src.GetLength(); + return *this; +} + +inline bool operator==(const char* lhs, const CFX_ByteString& rhs) { + return rhs == lhs; +} +inline bool operator==(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) { + return rhs == lhs; +} +inline bool operator!=(const char* lhs, const CFX_ByteString& rhs) { + return rhs != lhs; +} +inline bool operator!=(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) { + return rhs != lhs; +} + +inline CFX_ByteString operator+(const CFX_ByteStringC& str1, + const CFX_ByteStringC& str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const CFX_ByteStringC& str1, + const FX_CHAR* str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const FX_CHAR* str1, + const CFX_ByteStringC& str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const CFX_ByteStringC& str1, FX_CHAR ch) { + return CFX_ByteString(str1, CFX_ByteStringC(ch)); +} +inline CFX_ByteString operator+(FX_CHAR ch, const CFX_ByteStringC& str2) { + return CFX_ByteString(ch, str2); +} +inline CFX_ByteString operator+(const CFX_ByteString& str1, + const CFX_ByteString& str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const CFX_ByteString& str1, FX_CHAR ch) { + return CFX_ByteString(str1, CFX_ByteStringC(ch)); +} +inline CFX_ByteString operator+(FX_CHAR ch, const CFX_ByteString& str2) { + return CFX_ByteString(ch, str2); +} +inline CFX_ByteString operator+(const CFX_ByteString& str1, + const FX_CHAR* str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const FX_CHAR* str1, + const CFX_ByteString& str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const CFX_ByteString& str1, + const CFX_ByteStringC& str2) { + return CFX_ByteString(str1, str2); +} +inline CFX_ByteString operator+(const CFX_ByteStringC& str1, + const CFX_ByteString& str2) { + return CFX_ByteString(str1, str2); +} +class CFX_WideStringC { + public: + typedef FX_WCHAR value_type; + + CFX_WideStringC() { + m_Ptr = NULL; + m_Length = 0; + } + + CFX_WideStringC(const FX_WCHAR* ptr) { + m_Ptr = ptr; + m_Length = ptr ? FXSYS_wcslen(ptr) : 0; + } + + CFX_WideStringC(FX_WCHAR& ch) { + m_Ptr = &ch; + m_Length = 1; + } + + CFX_WideStringC(const FX_WCHAR* ptr, FX_STRSIZE len) { + m_Ptr = ptr; + m_Length = (len == -1) ? FXSYS_wcslen(ptr) : len; + } + + CFX_WideStringC(const CFX_WideStringC& src) { + m_Ptr = src.m_Ptr; + m_Length = src.m_Length; + } + + CFX_WideStringC(const CFX_WideString& src); + + CFX_WideStringC& operator=(const FX_WCHAR* src) { + m_Ptr = src; + m_Length = FXSYS_wcslen(src); + return *this; + } + + CFX_WideStringC& operator=(const CFX_WideStringC& src) { + m_Ptr = src.m_Ptr; + m_Length = src.m_Length; + return *this; + } + + CFX_WideStringC& operator=(const CFX_WideString& src); + + bool operator==(const wchar_t* ptr) const { + return FXSYS_wcslen(ptr) == m_Length && wmemcmp(ptr, m_Ptr, m_Length) == 0; + } + bool operator==(const CFX_WideStringC& str) const { + return str.m_Length == m_Length && wmemcmp(str.m_Ptr, m_Ptr, m_Length) == 0; + } + bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); } + bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); } + + const FX_WCHAR* GetPtr() const { return m_Ptr; } + + FX_STRSIZE GetLength() const { return m_Length; } + + bool IsEmpty() const { return m_Length == 0; } + + FX_WCHAR GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } + + CFX_WideStringC Left(FX_STRSIZE count) const { + if (count < 1) { + return CFX_WideStringC(); + } + if (count > m_Length) { + count = m_Length; + } + return CFX_WideStringC(m_Ptr, count); + } + + CFX_WideStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { + if (index < 0) { + index = 0; + } + if (index > m_Length) { + return CFX_WideStringC(); + } + if (count < 0 || count > m_Length - index) { + count = m_Length - index; + } + return CFX_WideStringC(m_Ptr + index, count); + } + + CFX_WideStringC Right(FX_STRSIZE count) const { + if (count < 1) { + return CFX_WideStringC(); + } + if (count > m_Length) { + count = m_Length; + } + return CFX_WideStringC(m_Ptr + m_Length - count, count); + } + + const FX_WCHAR& operator[](size_t index) const { return m_Ptr[index]; } + + bool operator<(const CFX_WideStringC& that) const { + int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length)); + return result < 0 || (result == 0 && m_Length < that.m_Length); + } + + protected: + const FX_WCHAR* m_Ptr; + FX_STRSIZE m_Length; + + private: + void* operator new(size_t) throw() { return NULL; } +}; +inline bool operator==(const wchar_t* lhs, const CFX_WideStringC& rhs) { + return rhs == lhs; +} +inline bool operator!=(const wchar_t* lhs, const CFX_WideStringC& rhs) { + return rhs != lhs; +} +#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1) + +// A mutable string with shared buffers using copy-on-write semantics that +// avoids the cost of std::string's iterator stability guarantees. +class CFX_WideString { + public: + typedef FX_WCHAR value_type; + + CFX_WideString() : m_pData(nullptr) {} + + // Copy constructor. + CFX_WideString(const CFX_WideString& str); + + // Move constructor. + inline CFX_WideString(CFX_WideString&& other) { + m_pData = other.m_pData; + other.m_pData = nullptr; + } + + CFX_WideString(const FX_WCHAR* ptr) + : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) {} + + CFX_WideString(const FX_WCHAR* ptr, FX_STRSIZE len); + + CFX_WideString(FX_WCHAR ch); + + CFX_WideString(const CFX_WideStringC& str); + + CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2); + + ~CFX_WideString(); + + static CFX_WideString FromLocal(const CFX_ByteString& str); + + static CFX_WideString FromCodePage(const CFX_ByteString& str, + uint16_t codepage); + + static CFX_WideString FromUTF8(const char* str, FX_STRSIZE len); + + static CFX_WideString FromUTF16LE(const unsigned short* str, FX_STRSIZE len); + + static FX_STRSIZE WStringLength(const unsigned short* str); + + // Explicit conversion to C-style wide string. + const FX_WCHAR* c_str() const { return m_pData ? m_pData->m_String : L""; } + + // Implicit conversion to C-style wide string -- deprecated. + operator const FX_WCHAR*() const { return m_pData ? m_pData->m_String : L""; } + + void Empty(); + + bool IsEmpty() const { return !GetLength(); } + + FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; } + + const CFX_WideString& operator=(const FX_WCHAR* str); + + const CFX_WideString& operator=(const CFX_WideString& stringSrc); + + const CFX_WideString& operator=(const CFX_WideStringC& stringSrc); + + const CFX_WideString& operator+=(const FX_WCHAR* str); + + const CFX_WideString& operator+=(FX_WCHAR ch); + + const CFX_WideString& operator+=(const CFX_WideString& str); + + const CFX_WideString& operator+=(const CFX_WideStringC& str); + + bool operator==(const wchar_t* ptr) const { return Equal(ptr); } + bool operator==(const CFX_WideStringC& str) const { return Equal(str); } + bool operator==(const CFX_WideString& other) const { return Equal(other); } + + bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); } + bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); } + bool operator!=(const CFX_WideString& other) const { + return !(*this == other); + } + + bool operator<(const CFX_WideString& str) const { + int result = + wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength())); + return result < 0 || (result == 0 && GetLength() < str.GetLength()); + } + + FX_WCHAR GetAt(FX_STRSIZE nIndex) const { + return m_pData ? m_pData->m_String[nIndex] : 0; + } + + FX_WCHAR operator[](FX_STRSIZE nIndex) const { + return m_pData ? m_pData->m_String[nIndex] : 0; + } + + void SetAt(FX_STRSIZE nIndex, FX_WCHAR ch); + + int Compare(const FX_WCHAR* str) const; + + int Compare(const CFX_WideString& str) const; + + int CompareNoCase(const FX_WCHAR* str) const; + + bool Equal(const wchar_t* ptr) const; + bool Equal(const CFX_WideStringC& str) const; + bool Equal(const CFX_WideString& other) const; + + CFX_WideString Mid(FX_STRSIZE first) const; + + CFX_WideString Mid(FX_STRSIZE first, FX_STRSIZE count) const; + + CFX_WideString Left(FX_STRSIZE count) const; + + CFX_WideString Right(FX_STRSIZE count) const; + + FX_STRSIZE Insert(FX_STRSIZE index, FX_WCHAR ch); + + FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1); + + void Format(const FX_WCHAR* lpszFormat, ...); + + void FormatV(const FX_WCHAR* lpszFormat, va_list argList); + + void MakeLower(); + + void MakeUpper(); + + void TrimRight(); + + void TrimRight(FX_WCHAR chTarget); + + void TrimRight(const FX_WCHAR* lpszTargets); + + void TrimLeft(); + + void TrimLeft(FX_WCHAR chTarget); + + void TrimLeft(const FX_WCHAR* lpszTargets); + + void Reserve(FX_STRSIZE len); + + FX_WCHAR* GetBuffer(FX_STRSIZE len); + + void ReleaseBuffer(FX_STRSIZE len = -1); + + int GetInteger() const; + + FX_FLOAT GetFloat() const; + + FX_STRSIZE Find(const FX_WCHAR* lpszSub, FX_STRSIZE start = 0) const; + + FX_STRSIZE Find(FX_WCHAR ch, FX_STRSIZE start = 0) const; + + FX_STRSIZE Replace(const FX_WCHAR* lpszOld, const FX_WCHAR* lpszNew); + + FX_STRSIZE Remove(FX_WCHAR ch); + + CFX_ByteString UTF8Encode() const; + + CFX_ByteString UTF16LE_Encode() const; + + protected: + class StringData { + public: + static StringData* Create(int nLen); + void Retain() { ++m_nRefs; } + void Release() { + if (--m_nRefs <= 0) + FX_Free(this); + } + + intptr_t m_nRefs; // Would prefer ssize_t, but no windows support. + FX_STRSIZE m_nDataLength; + FX_STRSIZE m_nAllocLength; + FX_WCHAR m_String[1]; + + private: + StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen) + : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) { + FXSYS_assert(dataLen >= 0); + FXSYS_assert(allocLen >= 0); + FXSYS_assert(dataLen <= allocLen); + m_String[dataLen] = 0; + } + ~StringData() = delete; + }; + + void CopyBeforeWrite(); + void AllocBeforeWrite(FX_STRSIZE nLen); + void ConcatInPlace(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData); + void ConcatCopy(FX_STRSIZE nSrc1Len, + const FX_WCHAR* lpszSrc1Data, + FX_STRSIZE nSrc2Len, + const FX_WCHAR* lpszSrc2Data); + void AssignCopy(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData); + void AllocCopy(CFX_WideString& dest, + FX_STRSIZE nCopyLen, + FX_STRSIZE nCopyIndex) const; + + StringData* m_pData; + friend class fxcrt_WideStringConcatInPlace_Test; +}; +inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src) { + m_Ptr = src.c_str(); + m_Length = src.GetLength(); +} +inline CFX_WideStringC& CFX_WideStringC::operator=(const CFX_WideString& src) { + m_Ptr = src.c_str(); + m_Length = src.GetLength(); + return *this; +} + +inline CFX_WideString operator+(const CFX_WideStringC& str1, + const CFX_WideStringC& str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const CFX_WideStringC& str1, + const FX_WCHAR* str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const FX_WCHAR* str1, + const CFX_WideStringC& str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const CFX_WideStringC& str1, FX_WCHAR ch) { + return CFX_WideString(str1, CFX_WideStringC(ch)); +} +inline CFX_WideString operator+(FX_WCHAR ch, const CFX_WideStringC& str2) { + return CFX_WideString(ch, str2); +} +inline CFX_WideString operator+(const CFX_WideString& str1, + const CFX_WideString& str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const CFX_WideString& str1, FX_WCHAR ch) { + return CFX_WideString(str1, CFX_WideStringC(ch)); +} +inline CFX_WideString operator+(FX_WCHAR ch, const CFX_WideString& str2) { + return CFX_WideString(ch, str2); +} +inline CFX_WideString operator+(const CFX_WideString& str1, + const FX_WCHAR* str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const FX_WCHAR* str1, + const CFX_WideString& str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const CFX_WideString& str1, + const CFX_WideStringC& str2) { + return CFX_WideString(str1, str2); +} +inline CFX_WideString operator+(const CFX_WideStringC& str1, + const CFX_WideString& str2) { + return CFX_WideString(str1, str2); +} +inline bool operator==(const wchar_t* lhs, const CFX_WideString& rhs) { + return rhs == lhs; +} +inline bool operator==(const CFX_WideStringC& lhs, const CFX_WideString& rhs) { + return rhs == lhs; +} +inline bool operator!=(const wchar_t* lhs, const CFX_WideString& rhs) { + return rhs != lhs; +} +inline bool operator!=(const CFX_WideStringC& lhs, const CFX_WideString& rhs) { + return rhs != lhs; +} + +CFX_ByteString FX_UTF8Encode(const FX_WCHAR* pwsStr, FX_STRSIZE len); +inline CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr) { + return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength()); +} +inline CFX_ByteString FX_UTF8Encode(const CFX_WideString& wsStr) { + return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()); +} + +FX_FLOAT FX_atof(const CFX_ByteStringC& str); +inline FX_FLOAT FX_atof(const CFX_WideStringC& wsStr) { + return FX_atof(FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength())); +} +void FX_atonum(const CFX_ByteStringC& str, FX_BOOL& bInteger, void* pData); +FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf); + +#endif // CORE_FXCRT_INCLUDE_FX_STRING_H_ diff --git a/core/fxcrt/include/fx_system.h b/core/fxcrt/include/fx_system.h new file mode 100644 index 0000000000..eb863c6048 --- /dev/null +++ b/core/fxcrt/include/fx_system.h @@ -0,0 +1,320 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_SYSTEM_H_ +#define CORE_FXCRT_INCLUDE_FX_SYSTEM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// _FX_OS_ values: +#define _FX_WIN32_DESKTOP_ 1 +#define _FX_WIN64_DESKTOP_ 2 +#define _FX_LINUX_DESKTOP_ 4 +#define _FX_MACOSX_ 7 +#define _FX_ANDROID_ 12 + +// _FXM_PLATFORM_ values; +#define _FXM_PLATFORM_WINDOWS_ 1 // _FX_WIN32_DESKTOP_ or _FX_WIN64_DESKTOP_. +#define _FXM_PLATFORM_LINUX_ 2 // _FX_LINUX_DESKTOP_ always. +#define _FXM_PLATFORM_APPLE_ 3 // _FX_MACOSX_ always. +#define _FXM_PLATFORM_ANDROID_ 4 // _FX_ANDROID_ always. + +#ifndef _FX_OS_ +#if defined(__ANDROID__) +#define _FX_OS_ _FX_ANDROID_ +#define _FXM_PLATFORM_ _FXM_PLATFORM_ANDROID_ +#elif defined(_WIN32) +#define _FX_OS_ _FX_WIN32_DESKTOP_ +#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_ +#elif defined(_WIN64) +#define _FX_OS_ _FX_WIN64_DESKTOP_ +#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_ +#elif defined(__linux__) +#define _FX_OS_ _FX_LINUX_DESKTOP_ +#define _FXM_PLATFORM_ _FXM_PLATFORM_LINUX_ +#elif defined(__APPLE__) +#define _FX_OS_ _FX_MACOSX_ +#define _FXM_PLATFORM_ _FXM_PLATFORM_APPLE_ +#endif +#endif // _FX_OS_ + +#if !defined(_FX_OS_) || _FX_OS_ == 0 +#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro. +#endif + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#endif + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif +typedef void* FX_POSITION; // Keep until fxcrt containers gone +typedef uint32_t FX_DWORD; // Keep - "an efficient type" +typedef float FX_FLOAT; // Keep, allow upgrade to doubles. +typedef double FX_DOUBLE; // Keep, allow downgrade to floats. +typedef int FX_BOOL; // Keep, sadly not always 0 or 1. +typedef char FX_CHAR; // Keep, questionable signedness. +typedef wchar_t FX_WCHAR; // Keep, maybe bad platform wchars. + +// PDFium string sizes are limited to 2^31-1, and the value is signed to +// allow -1 as a placeholder for "unknown". +// TODO(palmer): it should be a |size_t|, or at least unsigned. +typedef int FX_STRSIZE; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef __cplusplus +static_assert(TRUE == true, "true_needs_to_be_true"); +static_assert(FALSE == false, "false_needs_to_be_false"); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define FXSYS_assert assert +#ifndef ASSERT +#ifndef NDEBUG +#define ASSERT FXSYS_assert +#else +#define ASSERT(a) +#endif +#endif + +// M_PI not universally present on all platforms. +#define FX_PI 3.1415926535897932384626433832795f +#define FX_BEZIER 0.5522847498308f + +// NOTE: prevent use of the return value from snprintf() since some platforms +// have different return values (e.g. windows _vsnprintf()), and provide +// versions that always NUL-terminate. +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 +void FXSYS_snprintf(char* str, + size_t size, + _Printf_format_string_ const char* fmt, + ...); +void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap); +#else +#define FXSYS_snprintf (void) snprintf +#define FXSYS_vsnprintf (void) vsnprintf +#endif + +#define FXSYS_sprintf DO_NOT_USE_SPRINTF_DIE_DIE_DIE +#define FXSYS_vsprintf DO_NOT_USE_VSPRINTF_DIE_DIE_DIE +#define FXSYS_strchr strchr +#define FXSYS_strncmp strncmp +#define FXSYS_strcmp strcmp +#define FXSYS_strcpy strcpy +#define FXSYS_strncpy strncpy +#define FXSYS_strstr strstr +#define FXSYS_FILE FILE +#define FXSYS_fopen fopen +#define FXSYS_fclose fclose +#define FXSYS_SEEK_END SEEK_END +#define FXSYS_SEEK_SET SEEK_SET +#define FXSYS_fseek fseek +#define FXSYS_ftell ftell +#define FXSYS_fread fread +#define FXSYS_fwrite fwrite +#define FXSYS_fprintf fprintf +#define FXSYS_fflush fflush + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#ifdef _NATIVE_WCHAR_T_DEFINED +#define FXSYS_wfopen(f, m) _wfopen((const wchar_t*)(f), (const wchar_t*)(m)) +#else +#define FXSYS_wfopen _wfopen +#endif +#else +FXSYS_FILE* FXSYS_wfopen(const FX_WCHAR* filename, const FX_WCHAR* mode); +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +#ifdef __cplusplus +} // extern "C" + +#include "third_party/base/numerics/safe_conversions.h" + +#define FXSYS_strlen(ptr) pdfium::base::checked_cast(strlen(ptr)) +#define FXSYS_wcslen(ptr) pdfium::base::checked_cast(wcslen(ptr)) + +extern "C" { +#else +#define FXSYS_strlen(ptr) ((FX_STRSIZE)strlen(ptr)) +#define FXSYS_wcslen(ptr) ((FX_STRSIZE)wcslen(ptr)) +#endif + +#define FXSYS_wcscmp wcscmp +#define FXSYS_wcschr wcschr +#define FXSYS_wcsstr wcsstr +#define FXSYS_wcsncmp wcsncmp +#define FXSYS_vswprintf vswprintf +#define FXSYS_mbstowcs mbstowcs +#define FXSYS_wcstombs wcstombs +#define FXSYS_memcmp memcmp +#define FXSYS_memcpy memcpy +#define FXSYS_memmove memmove +#define FXSYS_memset memset +#define FXSYS_memchr memchr +#define FXSYS_qsort qsort +#define FXSYS_bsearch bsearch + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define FXSYS_GetACP GetACP +#define FXSYS_itoa _itoa +#define FXSYS_strlwr _strlwr +#define FXSYS_strupr _strupr +#define FXSYS_stricmp _stricmp +#ifdef _NATIVE_WCHAR_T_DEFINED +#define FXSYS_wcsicmp(str1, str2) _wcsicmp((wchar_t*)(str1), (wchar_t*)(str2)) +#define FXSYS_WideCharToMultiByte(p1, p2, p3, p4, p5, p6, p7, p8) \ + WideCharToMultiByte(p1, p2, (const wchar_t*)(p3), p4, p5, p6, p7, p8) +#define FXSYS_MultiByteToWideChar(p1, p2, p3, p4, p5, p6) \ + MultiByteToWideChar(p1, p2, p3, p4, (wchar_t*)(p5), p6) +#define FXSYS_wcslwr(str) _wcslwr((wchar_t*)(str)) +#define FXSYS_wcsupr(str) _wcsupr((wchar_t*)(str)) +#else +#define FXSYS_wcsicmp _wcsicmp +#define FXSYS_WideCharToMultiByte WideCharToMultiByte +#define FXSYS_MultiByteToWideChar MultiByteToWideChar +#define FXSYS_wcslwr _wcslwr +#define FXSYS_wcsupr _wcsupr +#endif +#define FXSYS_GetFullPathName GetFullPathName +#define FXSYS_GetModuleFileName GetModuleFileName +#else +int FXSYS_GetACP(void); +char* FXSYS_itoa(int value, char* str, int radix); +int FXSYS_WideCharToMultiByte(FX_DWORD codepage, + FX_DWORD dwFlags, + const wchar_t* wstr, + int wlen, + char* buf, + int buflen, + const char* default_str, + int* pUseDefault); +int FXSYS_MultiByteToWideChar(FX_DWORD codepage, + FX_DWORD dwFlags, + const char* bstr, + int blen, + wchar_t* buf, + int buflen); +FX_DWORD FXSYS_GetFullPathName(const char* filename, + FX_DWORD buflen, + char* buf, + char** filepart); +FX_DWORD FXSYS_GetModuleFileName(void* hModule, char* buf, FX_DWORD bufsize); +char* FXSYS_strlwr(char* str); +char* FXSYS_strupr(char* str); +int FXSYS_stricmp(const char*, const char*); +int FXSYS_wcsicmp(const wchar_t* str1, const wchar_t* str2); +wchar_t* FXSYS_wcslwr(wchar_t* str); +wchar_t* FXSYS_wcsupr(wchar_t* str); +#endif // _FXM_PLATFORM == _FXM_PLATFORM_WINDOWS_ + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define FXSYS_pow(a, b) (FX_FLOAT) powf(a, b) +#else +#define FXSYS_pow(a, b) (FX_FLOAT) pow(a, b) +#endif +#define FXSYS_sqrt(a) (FX_FLOAT) sqrt(a) +#define FXSYS_fabs(a) (FX_FLOAT) fabs(a) +#define FXSYS_atan2(a, b) (FX_FLOAT) atan2(a, b) +#define FXSYS_ceil(a) (FX_FLOAT) ceil(a) +#define FXSYS_floor(a) (FX_FLOAT) floor(a) +#define FXSYS_cos(a) (FX_FLOAT) cos(a) +#define FXSYS_acos(a) (FX_FLOAT) acos(a) +#define FXSYS_sin(a) (FX_FLOAT) sin(a) +#define FXSYS_log(a) (FX_FLOAT) log(a) +#define FXSYS_log10(a) (FX_FLOAT) log10(a) +#define FXSYS_fmod(a, b) (FX_FLOAT) fmod(a, b) +#define FXSYS_abs abs +#define FXDWORD_FROM_LSBFIRST(i) (i) +#define FXDWORD_FROM_MSBFIRST(i) \ + (((uint8_t)(i) << 24) | ((uint8_t)((i) >> 8) << 16) | \ + ((uint8_t)((i) >> 16) << 8) | (uint8_t)((i) >> 24)) +#define FXDWORD_GET_LSBFIRST(p) \ + ((static_cast(p[3]) << 24) | (static_cast(p[2]) << 16) | \ + (static_cast(p[1]) << 8) | (static_cast(p[0]))) +#define FXDWORD_GET_MSBFIRST(p) \ + ((static_cast(p[0]) << 24) | (static_cast(p[1]) << 16) | \ + (static_cast(p[2]) << 8) | (static_cast(p[3]))) +#define FXSYS_HIBYTE(word) ((uint8_t)((word) >> 8)) +#define FXSYS_LOBYTE(word) ((uint8_t)(word)) +#define FXSYS_HIWORD(dword) ((uint16_t)((dword) >> 16)) +#define FXSYS_LOWORD(dword) ((uint16_t)(dword)) +int32_t FXSYS_atoi(const FX_CHAR* str); +uint32_t FXSYS_atoui(const FX_CHAR* str); +int32_t FXSYS_wtoi(const FX_WCHAR* str); +int64_t FXSYS_atoi64(const FX_CHAR* str); +int64_t FXSYS_wtoi64(const FX_WCHAR* str); +const FX_CHAR* FXSYS_i64toa(int64_t value, FX_CHAR* str, int radix); +int FXSYS_round(FX_FLOAT f); +#define FXSYS_sqrt2(a, b) (FX_FLOAT) FXSYS_sqrt((a) * (a) + (b) * (b)) +#ifdef __cplusplus +}; +#endif + +// To print a size_t value in a portable way: +// size_t size; +// printf("xyz: %" PRIuS, size); +// The "u" in the macro corresponds to %u, and S is for "size". + +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64) +#error "inttypes.h has already been included before this header file, but " +#error "without __STDC_FORMAT_MACROS defined." +#endif + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include + +#if !defined(PRIuS) +#define PRIuS "zu" +#endif + +#else // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +#if !defined(PRIuS) +#define PRIuS "Iu" +#endif + +#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +// Prevent a function from ever being inlined, typically because we'd +// like it to appear in stack traces. +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define NEVER_INLINE __declspec(noinline) +#else // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#define NEVER_INLINE __attribute__((__noinline__)) +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +#endif // CORE_FXCRT_INCLUDE_FX_SYSTEM_H_ diff --git a/core/fxcrt/include/fx_ucd.h b/core/fxcrt/include/fx_ucd.h new file mode 100644 index 0000000000..f2e4215aa8 --- /dev/null +++ b/core/fxcrt/include/fx_ucd.h @@ -0,0 +1,192 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_UCD_H_ +#define CORE_FXCRT_INCLUDE_FX_UCD_H_ + +#include "core/fxcrt/include/fx_basic.h" + +#define FX_BIDICLASSBITS 6 +#define FX_BIDICLASSBITSMASK (31 << FX_BIDICLASSBITS) + +enum FX_BIDICLASS { + FX_BIDICLASS_ON = 0, // Other Neutral + FX_BIDICLASS_L = 1, // Left Letter + FX_BIDICLASS_R = 2, // Right Letter + FX_BIDICLASS_AN = 3, // Arabic Number + FX_BIDICLASS_EN = 4, // European Number + FX_BIDICLASS_AL = 5, // Arabic Letter + FX_BIDICLASS_NSM = 6, // Non-spacing Mark + FX_BIDICLASS_CS = 7, // Common Number Separator + FX_BIDICLASS_ES = 8, // European Separator + FX_BIDICLASS_ET = 9, // European Number Terminator + FX_BIDICLASS_BN = 10, // Boundary Neutral + FX_BIDICLASS_S = 11, // Segment Separator + FX_BIDICLASS_WS = 12, // Whitespace + FX_BIDICLASS_B = 13, // Paragraph Separator + FX_BIDICLASS_RLO = 14, // Right-to-Left Override + FX_BIDICLASS_RLE = 15, // Right-to-Left Embedding + FX_BIDICLASS_LRO = 16, // Left-to-Right Override + FX_BIDICLASS_LRE = 17, // Left-to-Right Embedding + FX_BIDICLASS_PDF = 18, // Pop Directional Format + FX_BIDICLASS_N = FX_BIDICLASS_ON, +}; + +extern const FX_DWORD kTextLayoutCodeProperties[]; +extern const size_t kTextLayoutCodePropertiesSize; + +extern const uint16_t kFXTextLayoutVerticalMirror[]; +extern const size_t kFXTextLayoutVerticalMirrorSize; + +extern const uint16_t kFXTextLayoutBidiMirror[]; +extern const size_t kFXTextLayoutBidiMirrorSize; + +FX_DWORD FX_GetUnicodeProperties(FX_WCHAR wch); +FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch, FX_BOOL bRTL, FX_BOOL bVertical); + +#ifdef PDF_ENABLE_XFA +enum FX_CHARBREAKPROP { + FX_CBP_OP = 0, + FX_CBP_CL = 1, + FX_CBP_QU = 2, + FX_CBP_GL = 3, + FX_CBP_NS = 4, + FX_CBP_EX = 5, + FX_CBP_SY = 6, + FX_CBP_IS = 7, + FX_CBP_PR = 8, + FX_CBP_PO = 9, + FX_CBP_NU = 10, + FX_CBP_AL = 11, + FX_CBP_ID = 12, + FX_CBP_IN = 13, + FX_CBP_HY = 14, + FX_CBP_BA = 15, + FX_CBP_BB = 16, + FX_CBP_B2 = 17, + FX_CBP_ZW = 18, + FX_CBP_CM = 19, + FX_CBP_WJ = 20, + FX_CBP_H2 = 21, + FX_CBP_H3 = 22, + FX_CBP_JL = 23, + FX_CBP_JV = 24, + FX_CBP_JT = 25, + + FX_CBP_BK = 26, + FX_CBP_CR = 27, + FX_CBP_LF = 28, + FX_CBP_NL = 29, + FX_CBP_SA = 30, + FX_CBP_SG = 31, + FX_CBP_CB = 32, + FX_CBP_XX = 33, + FX_CBP_AI = 34, + FX_CBP_SP = 35, + FX_CBP_TB = 37, + FX_CBP_NONE = 36, +}; + +#define FX_CHARTYPEBITS 11 +#define FX_CHARTYPEBITSMASK (15 << FX_CHARTYPEBITS) +enum FX_CHARTYPE { + FX_CHARTYPE_Unknown = 0, + FX_CHARTYPE_Tab = (1 << FX_CHARTYPEBITS), + FX_CHARTYPE_Space = (2 << FX_CHARTYPEBITS), + FX_CHARTYPE_Control = (3 << FX_CHARTYPEBITS), + FX_CHARTYPE_Combination = (4 << FX_CHARTYPEBITS), + FX_CHARTYPE_Numeric = (5 << FX_CHARTYPEBITS), + FX_CHARTYPE_Normal = (6 << FX_CHARTYPEBITS), + FX_CHARTYPE_ArabicAlef = (7 << FX_CHARTYPEBITS), + FX_CHARTYPE_ArabicSpecial = (8 << FX_CHARTYPEBITS), + FX_CHARTYPE_ArabicDistortion = (9 << FX_CHARTYPEBITS), + FX_CHARTYPE_ArabicNormal = (10 << FX_CHARTYPEBITS), + FX_CHARTYPE_ArabicForm = (11 << FX_CHARTYPEBITS), + FX_CHARTYPE_Arabic = (12 << FX_CHARTYPEBITS), +}; + +FX_BOOL FX_IsCtrlCode(FX_WCHAR ch); +FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch, + FX_DWORD dwProps, + FX_BOOL bRTL, + FX_BOOL bVertical); +class CFX_Char { + public: + CFX_Char() + : m_wCharCode(0), + m_nBreakType(0), + m_nRotation(0), + m_dwCharProps(0), + m_dwCharStyles(0), + m_iCharWidth(0), + m_iHorizontalScale(100), + m_iVertialScale(100) {} + CFX_Char(uint16_t wCharCode, FX_DWORD dwCharProps) + : m_wCharCode(wCharCode), + m_nBreakType(0), + m_nRotation(0), + m_dwCharProps(dwCharProps), + m_dwCharStyles(0), + m_iCharWidth(0), + m_iHorizontalScale(100), + m_iVertialScale(100) {} + FX_DWORD GetCharType() const { return m_dwCharProps & FX_CHARTYPEBITSMASK; } + uint16_t m_wCharCode; + uint8_t m_nBreakType; + int8_t m_nRotation; + FX_DWORD m_dwCharProps; + FX_DWORD m_dwCharStyles; + int32_t m_iCharWidth; + int32_t m_iHorizontalScale; + int32_t m_iVertialScale; +}; +typedef CFX_ArrayTemplate CFX_CharArray; +class CFX_TxtChar : public CFX_Char { + public: + CFX_TxtChar() + : CFX_Char(), + m_dwStatus(0), + m_iBidiClass(0), + m_iBidiLevel(0), + m_iBidiPos(0), + m_iBidiOrder(0), + m_pUserData(NULL) {} + FX_DWORD m_dwStatus; + int16_t m_iBidiClass; + int16_t m_iBidiLevel; + int16_t m_iBidiPos; + int16_t m_iBidiOrder; + void* m_pUserData; +}; +typedef CFX_ArrayTemplate CFX_TxtCharArray; +class CFX_RTFChar : public CFX_Char { + public: + CFX_RTFChar() + : CFX_Char(), + m_dwStatus(0), + m_iFontSize(0), + m_iFontHeight(0), + m_iBidiClass(0), + m_iBidiLevel(0), + m_iBidiPos(0), + m_dwLayoutStyles(0), + m_dwIdentity(0), + m_pUserData(NULL) {} + FX_DWORD m_dwStatus; + int32_t m_iFontSize; + int32_t m_iFontHeight; + int16_t m_iBidiClass; + int16_t m_iBidiLevel; + int16_t m_iBidiPos; + int16_t m_iBidiOrder; + FX_DWORD m_dwLayoutStyles; + FX_DWORD m_dwIdentity; + IFX_Unknown* m_pUserData; +}; +typedef CFX_ArrayTemplate CFX_RTFCharArray; +#endif // PDF_ENABLE_XFA + +#endif // CORE_FXCRT_INCLUDE_FX_UCD_H_ diff --git a/core/fxcrt/include/fx_xml.h b/core/fxcrt/include/fx_xml.h new file mode 100644 index 0000000000..66add1befc --- /dev/null +++ b/core/fxcrt/include/fx_xml.h @@ -0,0 +1,169 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_XML_H_ +#define CORE_FXCRT_INCLUDE_FX_XML_H_ + +#include +#include + +#include "core/fxcrt/include/fx_basic.h" + +class CXML_AttrItem { + public: + bool Matches(const CFX_ByteStringC& space, const CFX_ByteStringC& name) const; + + CFX_ByteString m_QSpaceName; + CFX_ByteString m_AttrName; + CFX_WideString m_Value; +}; + +class CXML_AttrMap { + public: + const CFX_WideString* Lookup(const CFX_ByteStringC& space, + const CFX_ByteStringC& name) const; + void SetAt(const CFX_ByteStringC& space, + const CFX_ByteStringC& name, + const CFX_WideStringC& value); + int GetSize() const; + CXML_AttrItem& GetAt(int index) const; + + std::unique_ptr> m_pMap; +}; + +class CXML_Content { + public: + CXML_Content() : m_bCDATA(FALSE), m_Content() {} + void Set(FX_BOOL bCDATA, const CFX_WideStringC& content) { + m_bCDATA = bCDATA; + m_Content = content; + } + + FX_BOOL m_bCDATA; + CFX_WideString m_Content; +}; + +class CXML_Element { + public: + enum ChildType { Invalid, Element, Content }; + + static CXML_Element* Parse(const void* pBuffer, + size_t size, + FX_BOOL bSaveSpaceChars = FALSE, + FX_FILESIZE* pParsedSize = NULL); + static CXML_Element* Parse(IFX_FileRead* pFile, + FX_BOOL bSaveSpaceChars = FALSE, + FX_FILESIZE* pParsedSize = NULL); + static CXML_Element* Parse(IFX_BufferRead* pBuffer, + FX_BOOL bSaveSpaceChars = FALSE, + FX_FILESIZE* pParsedSize = NULL); + + CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagName); + CXML_Element(const CFX_ByteStringC& qTagName); + CXML_Element(); + ~CXML_Element(); + + void Empty(); + CFX_ByteString GetTagName(FX_BOOL bQualified = FALSE) const; + CFX_ByteString GetNamespace(FX_BOOL bQualified = FALSE) const; + CFX_ByteString GetNamespaceURI(const CFX_ByteStringC& qName) const; + CXML_Element* GetParent() const { return m_pParent; } + FX_DWORD CountAttrs() const { return m_AttrMap.GetSize(); } + void GetAttrByIndex(int index, + CFX_ByteString& space, + CFX_ByteString& name, + CFX_WideString& value) const; + FX_BOOL HasAttr(const CFX_ByteStringC& qName) const; + FX_BOOL GetAttrValue(const CFX_ByteStringC& name, + CFX_WideString& attribute) const; + CFX_WideString GetAttrValue(const CFX_ByteStringC& name) const { + CFX_WideString attr; + GetAttrValue(name, attr); + return attr; + } + + FX_BOOL GetAttrValue(const CFX_ByteStringC& space, + const CFX_ByteStringC& name, + CFX_WideString& attribute) const; + CFX_WideString GetAttrValue(const CFX_ByteStringC& space, + const CFX_ByteStringC& name) const { + CFX_WideString attr; + GetAttrValue(space, name, attr); + return attr; + } + + FX_BOOL GetAttrInteger(const CFX_ByteStringC& name, int& attribute) const; + int GetAttrInteger(const CFX_ByteStringC& name) const { + int attr = 0; + GetAttrInteger(name, attr); + return attr; + } + + FX_BOOL GetAttrInteger(const CFX_ByteStringC& space, + const CFX_ByteStringC& name, + int& attribute) const; + int GetAttrInteger(const CFX_ByteStringC& space, + const CFX_ByteStringC& name) const { + int attr = 0; + GetAttrInteger(space, name, attr); + return attr; + } + + FX_BOOL GetAttrFloat(const CFX_ByteStringC& name, FX_FLOAT& attribute) const; + FX_FLOAT GetAttrFloat(const CFX_ByteStringC& name) const { + FX_FLOAT attr = 0; + GetAttrFloat(name, attr); + return attr; + } + + FX_BOOL GetAttrFloat(const CFX_ByteStringC& space, + const CFX_ByteStringC& name, + FX_FLOAT& attribute) const; + FX_FLOAT GetAttrFloat(const CFX_ByteStringC& space, + const CFX_ByteStringC& name) const { + FX_FLOAT attr = 0; + GetAttrFloat(space, name, attr); + return attr; + } + + FX_DWORD CountChildren() const { return m_Children.size(); } + ChildType GetChildType(FX_DWORD index) const; + CFX_WideString GetContent(FX_DWORD index) const; + CXML_Element* GetElement(FX_DWORD index) const; + CXML_Element* GetElement(const CFX_ByteStringC& space, + const CFX_ByteStringC& tag) const { + return GetElement(space, tag, 0); + } + + FX_DWORD CountElements(const CFX_ByteStringC& space, + const CFX_ByteStringC& tag) const; + CXML_Element* GetElement(const CFX_ByteStringC& space, + const CFX_ByteStringC& tag, + int index) const; + + FX_DWORD FindElement(CXML_Element* pChild) const; + void SetTag(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname); + void SetTag(const CFX_ByteStringC& qTagName); + void RemoveChildren(); + void RemoveChild(FX_DWORD index); + + protected: + struct ChildRecord { + ChildType type; + void* child; // CXML_Element and CXML_Content lack a common ancestor. + }; + + CXML_Element* m_pParent; + CFX_ByteString m_QSpaceName; + CFX_ByteString m_TagName; + CXML_AttrMap m_AttrMap; + std::vector m_Children; + + friend class CXML_Parser; + friend class CXML_Composer; +}; + +#endif // CORE_FXCRT_INCLUDE_FX_XML_H_ -- cgit v1.2.3