diff options
Diffstat (limited to 'core/fxcrt/fx_basic_util.cpp')
-rw-r--r-- | core/fxcrt/fx_basic_util.cpp | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/core/fxcrt/fx_basic_util.cpp b/core/fxcrt/fx_basic_util.cpp new file mode 100644 index 0000000000..2422212d59 --- /dev/null +++ b/core/fxcrt/fx_basic_util.cpp @@ -0,0 +1,367 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/include/fxcrt/fx_basic.h" +#include "core/include/fxcrt/fx_ext.h" + +#include <cctype> + +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ +#include <dirent.h> +#include <sys/types.h> +#else +#include <direct.h> +#endif + +CFX_PrivateData::CFX_PrivateData() {} + +CFX_PrivateData::~CFX_PrivateData() { + ClearAll(); +} +void FX_PRIVATEDATA::FreeData() { + if (!m_pData) { + return; + } + if (m_bSelfDestruct) { + delete (CFX_DestructObject*)m_pData; + } else if (m_pCallback) { + m_pCallback(m_pData); + } +} +void CFX_PrivateData::AddData(void* pModuleId, + void* pData, + PD_CALLBACK_FREEDATA callback, + FX_BOOL bSelfDestruct) { + if (!pModuleId) { + return; + } + FX_PRIVATEDATA* pList = m_DataList.GetData(); + int count = m_DataList.GetSize(); + for (int i = 0; i < count; i++) { + if (pList[i].m_pModuleId == pModuleId) { + pList[i].FreeData(); + pList[i].m_pData = pData; + pList[i].m_pCallback = callback; + return; + } + } + FX_PRIVATEDATA data = {pModuleId, pData, callback, bSelfDestruct}; + m_DataList.Add(data); +} +void CFX_PrivateData::SetPrivateData(void* pModuleId, + void* pData, + PD_CALLBACK_FREEDATA callback) { + AddData(pModuleId, pData, callback, FALSE); +} +void CFX_PrivateData::SetPrivateObj(void* pModuleId, CFX_DestructObject* pObj) { + AddData(pModuleId, pObj, NULL, TRUE); +} +FX_BOOL CFX_PrivateData::RemovePrivateData(void* pModuleId) { + if (!pModuleId) { + return FALSE; + } + FX_PRIVATEDATA* pList = m_DataList.GetData(); + int count = m_DataList.GetSize(); + for (int i = 0; i < count; i++) { + if (pList[i].m_pModuleId == pModuleId) { + m_DataList.RemoveAt(i); + return TRUE; + } + } + return FALSE; +} +void* CFX_PrivateData::GetPrivateData(void* pModuleId) { + if (!pModuleId) { + return NULL; + } + FX_PRIVATEDATA* pList = m_DataList.GetData(); + int count = m_DataList.GetSize(); + for (int i = 0; i < count; i++) { + if (pList[i].m_pModuleId == pModuleId) { + return pList[i].m_pData; + } + } + return NULL; +} +void CFX_PrivateData::ClearAll() { + FX_PRIVATEDATA* pList = m_DataList.GetData(); + int count = m_DataList.GetSize(); + for (int i = 0; i < count; i++) { + pList[i].FreeData(); + } + m_DataList.RemoveAll(); +} +void FX_atonum(const CFX_ByteStringC& strc, FX_BOOL& bInteger, void* pData) { + if (!FXSYS_memchr(strc.GetPtr(), '.', strc.GetLength())) { + bInteger = TRUE; + int cc = 0, integer = 0; + const FX_CHAR* str = strc.GetCStr(); + int len = strc.GetLength(); + FX_BOOL bNegative = FALSE; + if (str[0] == '+') { + cc++; + } else if (str[0] == '-') { + bNegative = TRUE; + cc++; + } + while (cc < len && std::isdigit(str[cc])) { + // TODO(dsinclair): This is not the right way to handle overflow. + integer = integer * 10 + FXSYS_toDecimalDigit(str[cc]); + if (integer < 0) + break; + cc++; + } + if (bNegative) { + integer = -integer; + } + *(int*)pData = integer; + } else { + bInteger = FALSE; + *(FX_FLOAT*)pData = FX_atof(strc); + } +} +FX_FLOAT FX_atof(const CFX_ByteStringC& strc) { + if (strc.GetLength() == 0) { + return 0.0; + } + int cc = 0; + FX_BOOL bNegative = FALSE; + const FX_CHAR* str = strc.GetCStr(); + int len = strc.GetLength(); + if (str[0] == '+') { + cc++; + } else if (str[0] == '-') { + bNegative = TRUE; + cc++; + } + while (cc < len) { + if (str[cc] != '+' && str[cc] != '-') { + break; + } + cc++; + } + FX_FLOAT value = 0; + while (cc < len) { + if (str[cc] == '.') { + break; + } + value = value * 10 + FXSYS_toDecimalDigit(str[cc]); + cc++; + } + static const FX_FLOAT fraction_scales[] = { + 0.1f, 0.01f, 0.001f, 0.0001f, + 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, + 0.000000001f, 0.0000000001f, 0.00000000001f}; + int scale = 0; + if (cc < len && str[cc] == '.') { + cc++; + while (cc < len) { + value += fraction_scales[scale] * FXSYS_toDecimalDigit(str[cc]); + scale++; + if (scale == sizeof fraction_scales / sizeof(FX_FLOAT)) { + break; + } + cc++; + } + } + return bNegative ? -value : value; +} + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 +void FXSYS_snprintf(char* str, + size_t size, + _Printf_format_string_ const char* fmt, + ...) { + va_list ap; + va_start(ap, fmt); + FXSYS_vsnprintf(str, size, fmt, ap); + va_end(ap); +} +void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap) { + (void)_vsnprintf(str, size, fmt, ap); + if (size) { + str[size - 1] = 0; + } +} +#endif // _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +class CFindFileData { + public: + virtual ~CFindFileData() {} + HANDLE m_Handle; + FX_BOOL m_bEnd; +}; +class CFindFileDataA : public CFindFileData { + public: + virtual ~CFindFileDataA() {} + WIN32_FIND_DATAA m_FindData; +}; +class CFindFileDataW : public CFindFileData { + public: + virtual ~CFindFileDataW() {} + WIN32_FIND_DATAW m_FindData; +}; +#endif +void* FX_OpenFolder(const FX_CHAR* path) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#ifndef _WIN32_WCE + CFindFileDataA* pData = new CFindFileDataA; + pData->m_Handle = + FindFirstFileExA(CFX_ByteString(path) + "/*.*", FindExInfoStandard, + &pData->m_FindData, FindExSearchNameMatch, NULL, 0); +#else + CFindFileDataW* pData = new CFindFileDataW; + pData->m_Handle = FindFirstFileW(CFX_WideString::FromLocal(path) + L"/*.*", + &pData->m_FindData); +#endif + if (pData->m_Handle == INVALID_HANDLE_VALUE) { + delete pData; + return NULL; + } + pData->m_bEnd = FALSE; + return pData; +#else + DIR* dir = opendir(path); + return dir; +#endif +} +void* FX_OpenFolder(const FX_WCHAR* path) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + CFindFileDataW* pData = new CFindFileDataW; + pData->m_Handle = FindFirstFileExW((CFX_WideString(path) + L"/*.*").c_str(), + FindExInfoStandard, &pData->m_FindData, + FindExSearchNameMatch, NULL, 0); + if (pData->m_Handle == INVALID_HANDLE_VALUE) { + delete pData; + return NULL; + } + pData->m_bEnd = FALSE; + return pData; +#else + DIR* dir = opendir(CFX_ByteString::FromUnicode(path)); + return dir; +#endif +} +FX_BOOL FX_GetNextFile(void* handle, + CFX_ByteString& filename, + FX_BOOL& bFolder) { + if (!handle) { + return FALSE; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#ifndef _WIN32_WCE + CFindFileDataA* pData = (CFindFileDataA*)handle; + if (pData->m_bEnd) { + return FALSE; + } + filename = pData->m_FindData.cFileName; + bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + if (!FindNextFileA(pData->m_Handle, &pData->m_FindData)) { + pData->m_bEnd = TRUE; + } + return TRUE; +#else + CFindFileDataW* pData = (CFindFileDataW*)handle; + if (pData->m_bEnd) { + return FALSE; + } + filename = CFX_ByteString::FromUnicode(pData->m_FindData.cFileName); + bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) { + pData->m_bEnd = TRUE; + } + return TRUE; +#endif +#elif defined(__native_client__) + abort(); + return FALSE; +#else + struct dirent* de = readdir((DIR*)handle); + if (!de) { + return FALSE; + } + filename = de->d_name; + bFolder = de->d_type == DT_DIR; + return TRUE; +#endif +} +FX_BOOL FX_GetNextFile(void* handle, + CFX_WideString& filename, + FX_BOOL& bFolder) { + if (!handle) { + return FALSE; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + CFindFileDataW* pData = (CFindFileDataW*)handle; + if (pData->m_bEnd) { + return FALSE; + } + filename = pData->m_FindData.cFileName; + bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) { + pData->m_bEnd = TRUE; + } + return TRUE; +#elif defined(__native_client__) + abort(); + return FALSE; +#else + struct dirent* de = readdir((DIR*)handle); + if (!de) { + return FALSE; + } + filename = CFX_WideString::FromLocal(de->d_name); + bFolder = de->d_type == DT_DIR; + return TRUE; +#endif +} +void FX_CloseFolder(void* handle) { + if (!handle) { + return; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + CFindFileData* pData = (CFindFileData*)handle; + FindClose(pData->m_Handle); + delete pData; +#else + closedir((DIR*)handle); +#endif +} +FX_WCHAR FX_GetFolderSeparator() { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + return '\\'; +#else + return '/'; +#endif +} + +CFX_Matrix_3by3 CFX_Matrix_3by3::Inverse() { + FX_FLOAT det = + a * (e * i - f * h) - b * (i * d - f * g) + c * (d * h - e * g); + if (FXSYS_fabs(det) < 0.0000001) + return CFX_Matrix_3by3(); + + return CFX_Matrix_3by3( + (e * i - f * h) / det, -(b * i - c * h) / det, (b * f - c * e) / det, + -(d * i - f * g) / det, (a * i - c * g) / det, -(a * f - c * d) / det, + (d * h - e * g) / det, -(a * h - b * g) / det, (a * e - b * d) / det); +} + +CFX_Matrix_3by3 CFX_Matrix_3by3::Multiply(const CFX_Matrix_3by3& m) { + return CFX_Matrix_3by3( + a * m.a + b * m.d + c * m.g, a * m.b + b * m.e + c * m.h, + a * m.c + b * m.f + c * m.i, d * m.a + e * m.d + f * m.g, + d * m.b + e * m.e + f * m.h, d * m.c + e * m.f + f * m.i, + g * m.a + h * m.d + i * m.g, g * m.b + h * m.e + i * m.h, + g * m.c + h * m.f + i * m.i); +} + +CFX_Vector_3by1 CFX_Matrix_3by3::TransformVector(const CFX_Vector_3by1& v) { + return CFX_Vector_3by1(a * v.a + b * v.b + c * v.c, + d * v.a + e * v.b + f * v.c, + g * v.a + h * v.b + i * v.c); +} |