Commit fa9c096f authored by Oleg Korshul's avatar Oleg Korshul

font names project (full work)

parent e1ec9d94
......@@ -709,6 +709,44 @@ void CFontInfo::ToBuffer(BYTE*& pBuffer, std::wstring strDirectory, bool bIsOnly
pBuffer += sizeof(SHORT);
}
#ifdef BUILD_FONT_NAMES_DICTIONARY
#include "ftsnames.h"
#include "tttables.h"
#include "ftxf86.h"
#include "internal/internal.h"
#include "internal/tttypes.h"
void CFontInfo::ReadNames(FT_Face pFace)
{
TT_Face pTT_Face = (TT_Face)(pFace);
names.clear();
if (NULL != pTT_Face)
{
for (int i = 0; i < pTT_Face->utf16_len; ++i)
{
std::wstring s(pTT_Face->utf16_names[i]);
if (s == m_wsFontName)
continue;
bool bIsPresent = false;
for (std::vector<std::wstring>::iterator i = names.begin(); i != names.end(); i++)
{
if (*i == s)
{
bIsPresent = true;
break;
}
}
if (!bIsPresent)
names.push_back(s);
}
}
}
#endif
///////////////////////////////////////////////////////////////////////////////////
namespace NSCharsets
{
......@@ -1583,6 +1621,10 @@ void CFontList::LoadFromArrayFiles(std::vector<std::wstring>& oArray, int nFlag)
shXHeight,
shCapHeight );
#ifdef BUILD_FONT_NAMES_DICTIONARY
pFontInfo->ReadNames(pFace);
#endif
Add(pFontInfo);
FT_Done_Face( pFace );
......@@ -1642,6 +1684,7 @@ void CFontList::Add(CFontInfo* pInfo)
return;
}
}
m_pList.Add(pInfo);
}
......
......@@ -159,6 +159,12 @@ public:
SHORT m_shLineGap; // Межсимвольный интервал
SHORT m_shXHeight; // Высота буквы 'x' (в нижнем регистре)
SHORT m_shCapHeight; // Высота буквы 'H' (в верхнем регистре)
#ifdef BUILD_FONT_NAMES_DICTIONARY
std::vector<std::wstring> names;
void ReadNames(FT_Face pFace);
#endif
};
namespace NSCharsets
......
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include "windows.h"
class CFile
{
public:
CFile()
{
m_hFileHandle = NULL;
m_lFileSize = 0;
m_lFilePosition = 0;
}
virtual ~CFile()
{
CloseFile();
}
virtual HRESULT OpenFile(CString FileName)
{
CloseFile();
HRESULT hRes = S_OK;
DWORD AccessMode = GENERIC_READ;
DWORD ShareMode = FILE_SHARE_READ;
DWORD Disposition = OPEN_EXISTING;
m_hFileHandle = ::CreateFile(FileName, AccessMode, ShareMode, NULL, Disposition, FILE_ATTRIBUTE_NORMAL, NULL);
if (NULL == m_hFileHandle || INVALID_HANDLE_VALUE == m_hFileHandle)
hRes = S_FALSE;
else
{
ULARGE_INTEGER nTempSize;
nTempSize.LowPart = ::GetFileSize(m_hFileHandle, &nTempSize.HighPart);
m_lFileSize = nTempSize.QuadPart;
SetPosition(0);
}
return hRes;
}
virtual HRESULT OpenFileRW(CString FileName)
{
CloseFile();
HRESULT hRes = S_OK;
DWORD AccessMode = GENERIC_READ | GENERIC_WRITE;
DWORD ShareMode = FILE_SHARE_READ;
DWORD Disposition = OPEN_EXISTING;
m_hFileHandle = ::CreateFile(FileName, AccessMode, ShareMode, NULL, Disposition, 0, 0);
if (NULL == m_hFileHandle || INVALID_HANDLE_VALUE == m_hFileHandle)
{
hRes = S_FALSE;
}
else
{
ULARGE_INTEGER nTempSize;
nTempSize.LowPart = ::GetFileSize(m_hFileHandle, &nTempSize.HighPart);
m_lFileSize = nTempSize.QuadPart;
SetPosition(0);
}
return hRes;
}
HRESULT ReadFile(BYTE* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
}
return S_OK;
}
HRESULT ReadFile2(BYTE* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
for (size_t index = 0; index < nBytesToRead / 2; ++index)
{
BYTE temp = pData[index];
pData[index] = pData[nBytesToRead - index - 1];
pData[nBytesToRead - index - 1] = temp;
}
}
return S_OK;
}
HRESULT ReadFile3(void* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
}
return S_OK;
}
HRESULT WriteFile(void* pData, DWORD nBytesToWrite)
{
if(m_hFileHandle)
{
DWORD dwWritten = 0;
::WriteFile(m_hFileHandle, pData, nBytesToWrite, &dwWritten, NULL);
m_lFilePosition += nBytesToWrite;
}
return S_OK;
}
HRESULT WriteFile2(void* pData, DWORD nBytesToWrite)
{
if(m_hFileHandle)
{
BYTE* mem = new BYTE[nBytesToWrite];
memcpy(mem, pData, nBytesToWrite);
for (size_t index = 0; index < nBytesToWrite / 2; ++index)
{
BYTE temp = mem[index];
mem[index] = mem[nBytesToWrite - index - 1];
mem[nBytesToWrite - index - 1] = temp;
}
DWORD dwWritten = 0;
::WriteFile(m_hFileHandle, (void*)mem, nBytesToWrite, &dwWritten, NULL);
m_lFilePosition += nBytesToWrite;
delete[] mem;
}
return S_OK;
}
HRESULT CreateFile(CString strFileName)
{
CloseFile();
DWORD AccessMode = GENERIC_WRITE;
DWORD ShareMode = FILE_SHARE_WRITE;
DWORD Disposition = CREATE_ALWAYS;
m_hFileHandle = ::CreateFile(strFileName, AccessMode, ShareMode, NULL, Disposition, FILE_ATTRIBUTE_NORMAL, NULL);
return SetPosition(0);
}
HRESULT SetPosition( ULONG64 nPos )
{
if (m_hFileHandle && nPos < (ULONG)m_lFileSize)
{
LARGE_INTEGER nTempPos;
nTempPos.QuadPart = nPos;
::SetFilePointer(m_hFileHandle, nTempPos.LowPart, &nTempPos.HighPart, FILE_BEGIN);
m_lFilePosition = nPos;
return S_OK;
}
else
{
return (INVALID_HANDLE_VALUE == m_hFileHandle) ? S_FALSE : S_OK;
}
}
LONG64 GetPosition()
{
return m_lFilePosition;
}
HRESULT SkipBytes(ULONG64 nCount)
{
return SetPosition(m_lFilePosition + nCount);
}
HRESULT CloseFile()
{
m_lFileSize = 0;
m_lFilePosition = 0;
CloseHandle(m_hFileHandle);
m_hFileHandle = NULL;
return S_OK;
}
ULONG64 GetFileSize()
{
return m_lFileSize;
}
void WriteStringUTF8(CString& strXml)
{
int nLength = strXml.GetLength();
CStringA saStr;
#ifdef UNICODE
// Encoding Unicode to UTF-8
WideCharToMultiByte(CP_UTF8, 0, strXml.GetBuffer(), nLength + 1, saStr.GetBuffer(nLength*3 + 1), nLength*3, NULL, NULL);
saStr.ReleaseBuffer();
#else
wchar_t* pWStr = new wchar_t[nLength + 1];
if (!pWStr)
return;
// set end string
pWStr[nLength] = 0;
// Encoding ASCII to Unicode
MultiByteToWideChar(CP_ACP, 0, strXml, nLength, pWStr, nLength);
int nLengthW = (int)wcslen(pWStr);
// Encoding Unicode to UTF-8
WideCharToMultiByte(CP_UTF8, 0, pWStr, nLengthW + 1, saStr.GetBuffer(nLengthW*3 + 1), nLengthW*3, NULL, NULL);
saStr.ReleaseBuffer();
delete[] pWStr;
#endif
WriteFile((void*)saStr.GetBuffer(), saStr.GetLength());
}
LONG GetProgress()
{
if (0 >= m_lFileSize)
return -1;
double dVal = (double)(100 * m_lFilePosition);
LONG lProgress = (LONG)(dVal / m_lFileSize);
return lProgress;
}
protected:
HANDLE m_hFileHandle;
LONG64 m_lFileSize;
LONG64 m_lFilePosition;
};
\ No newline at end of file
......@@ -32,34 +32,35 @@
// FontMaps.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "WinFont.h"
#include "File.h"
#include "../../common/File.h"
#include <algorithm>
#include "../../fontengine/ApplicationFonts.h"
#include "../../common/StringBuilder.h"
class CFontInfoJS
{
public:
CString m_sName;
std::wstring m_sName;
LONG m_lIndexR;
LONG m_lFaceIndexR;
CAtlArray<CString> namesR;
std::vector<std::wstring> namesR;
LONG m_lIndexI;
LONG m_lFaceIndexI;
CAtlArray<CString> namesI;
std::vector<std::wstring> namesI;
LONG m_lIndexB;
LONG m_lFaceIndexB;
CAtlArray<CString> namesB;
std::vector<std::wstring> namesB;
LONG m_lIndexBI;
LONG m_lFaceIndexBI;
CAtlArray<CString> namesBI;
std::vector<std::wstring> namesBI;
CFontInfoJS()
{
m_sName = _T("");
m_sName = L"";
m_lIndexR = -1;
m_lFaceIndexR = -1;
......@@ -90,119 +91,105 @@ public:
m_lFaceIndexB = oSrc.m_lFaceIndexB;
m_lFaceIndexBI = oSrc.m_lFaceIndexBI;
namesR.RemoveAll();
namesR.Copy(oSrc.namesR);
namesR.clear();
namesR = oSrc.namesR;
namesI.RemoveAll();
namesI.Copy(oSrc.namesI);
namesI.clear();
namesI = oSrc.namesI;
namesB.RemoveAll();
namesB.Copy(oSrc.namesB);
namesB.clear();
namesB = oSrc.namesB;
namesBI.RemoveAll();
namesBI.Copy(oSrc.namesBI);
namesBI.clear();
namesBI = oSrc.namesBI;
return *this;
}
};
int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char* argv[])
{
FT_Library pLibrary = NULL;
//CString strFolder = _T("\\\\mediaserver\\Exchange\\Korshul\\Fonts");
CString strFolder = _T("X:\\AVS\\Sources\\TeamlabOffice\\trunk\\ServerComponents\\DesktopEditor\\freetype_names\\FontsDictionaryFiles");
CWinFontList* m_pList = NULL;
CApplicationFonts oFonts;
oFonts.InitializeFromFolder(L"D:\\onlyoffice_trunk\\fonts\\all");
//oFonts.Initialize();
if (!FT_Init_FreeType( &pLibrary ))
{
if (_T("") == strFolder)
m_pList = new CWinFontList(pLibrary);
else
m_pList = new CWinFontList(pLibrary, strFolder);
FT_Done_FreeType( pLibrary );
}
std::wstring strFontDictionaryPath = L"D:\\GIT\\core\\DesktopEditor\\freetype_names\\FontMaps\\FontDictionary.h";
CString strFontDictionaryPath = _T("X:\\AVS\\Sources\\TeamlabOffice\\trunk\\ServerComponents\\DesktopEditor\\freetype_names\\FontMaps\\FontDictionary.h");
int nCount = m_pList->GetFonts()->GetLength();
int nCount = oFonts.GetList()->GetFonts()->GetCount();
// теперь строим массив всех шрифтов по имени
CAtlMap<CString, CFontInfoJS> mapFonts;
CAtlMap<CString, CFontInfoJS> mapFontsUnicodes;
CAtlArray<CString> arrFonts;
CAtlArray<CString> arrFontsUnicodes;
std::map<std::wstring, CFontInfoJS> mapFonts;
std::map<std::wstring, CFontInfoJS> mapFontsUnicodes;
std::vector<std::wstring> arrFonts;
std::vector<std::wstring> arrFontsUnicodes;
int nError = 0;
CAtlMap<CString, BOOL> mapMainAscii;
std::map<std::wstring, bool> mapMainAscii;
for (int i = 0; i < nCount; ++i)
{
CWinFontInfo* pInfo = (CWinFontInfo*)m_pList->GetByIndex(i);
CString strPath = (CString)pInfo->m_wsFontPath;
CString strName = (CString)pInfo->m_wsFontName;
CFontInfo* pInfo = oFonts.GetList()->GetFonts()->operator [](i);
std::wstring strPath = pInfo->m_wsFontPath;
std::wstring strName = pInfo->m_wsFontName;
LONG lFontIndex = 0;
LONG lFaceIndex = 0;
//CAtlMap<CString, LONG>::CPair* pPairFontFiles = mapFontFiles.Lookup(strPath);
//lFontIndex = pPairFontFiles->m_value;
lFontIndex = (LONG)i;
if (pInfo->m_lIndex >= 0)
lFaceIndex = pInfo->m_lIndex;
mapMainAscii.SetAt(pInfo->m_wsFontName, TRUE);
mapMainAscii.insert(std::pair<std::wstring, bool>(pInfo->m_wsFontName, true));
CAtlMap<CString, CFontInfoJS>::CPair* pPair = mapFonts.Lookup(pInfo->m_wsFontName);
if (NULL != pPair)
std::map<std::wstring, CFontInfoJS>::iterator pPair = mapFonts.find(pInfo->m_wsFontName);
if (mapFonts.end() != pPair)
{
pPair->m_value.m_sName = pInfo->m_wsFontName;
pPair->second.m_sName = pInfo->m_wsFontName;
if (pInfo->m_bBold && pInfo->m_bItalic)
{
if (-1 != pPair->m_value.m_lIndexBI)
if (-1 != pPair->second.m_lIndexBI)
nError++;
pPair->m_value.m_lIndexBI = lFontIndex;
pPair->m_value.m_lFaceIndexBI = lFaceIndex;
pPair->second.m_lIndexBI = lFontIndex;
pPair->second.m_lFaceIndexBI = lFaceIndex;
pPair->m_value.namesBI.RemoveAll();
pPair->m_value.namesBI.Copy(pInfo->names);
pPair->second.namesBI.clear();
pPair->second.namesBI = pInfo->names;
}
else if (pInfo->m_bBold)
{
if (-1 != pPair->m_value.m_lIndexB)
if (-1 != pPair->second.m_lIndexB)
nError++;
pPair->m_value.m_lIndexB = lFontIndex;
pPair->m_value.m_lFaceIndexB = lFaceIndex;
pPair->second.m_lIndexB = lFontIndex;
pPair->second.m_lFaceIndexB = lFaceIndex;
pPair->m_value.namesB.RemoveAll();
pPair->m_value.namesB.Copy(pInfo->names);
pPair->second.namesB.clear();
pPair->second.namesB = pInfo->names;
}
else if (pInfo->m_bItalic)
{
if (-1 != pPair->m_value.m_lIndexI)
if (-1 != pPair->second.m_lIndexI)
nError++;
pPair->m_value.m_lIndexI = lFontIndex;
pPair->m_value.m_lFaceIndexI = lFaceIndex;
pPair->second.m_lIndexI = lFontIndex;
pPair->second.m_lFaceIndexI = lFaceIndex;
pPair->m_value.namesI.RemoveAll();
pPair->m_value.namesI.Copy(pInfo->names);
pPair->second.namesI.clear();
pPair->second.namesI = pInfo->names;
}
else
{
if (-1 != pPair->m_value.m_lIndexR)
if (-1 != pPair->second.m_lIndexR)
nError++;
pPair->m_value.m_lIndexR = lFontIndex;
pPair->m_value.m_lFaceIndexR = lFaceIndex;
pPair->second.m_lIndexR = lFontIndex;
pPair->second.m_lFaceIndexR = lFaceIndex;
pPair->m_value.namesR.RemoveAll();
pPair->m_value.namesR.Copy(pInfo->names);
pPair->second.namesR.clear();
pPair->second.namesR = pInfo->names;
}
}
else
......@@ -216,70 +203,68 @@ int _tmain(int argc, _TCHAR* argv[])
fontInfo.m_lIndexBI = lFontIndex;
fontInfo.m_lFaceIndexBI = lFaceIndex;
fontInfo.namesBI.RemoveAll();
fontInfo.namesBI.Copy(pInfo->names);
fontInfo.namesBI.clear();
fontInfo.namesBI = pInfo->names;
}
else if (pInfo->m_bBold)
{
fontInfo.m_lIndexB = lFontIndex;
fontInfo.m_lFaceIndexB = lFaceIndex;
fontInfo.namesB.RemoveAll();
fontInfo.namesB.Copy(pInfo->names);
fontInfo.namesB.clear();
fontInfo.namesB = pInfo->names;
}
else if (pInfo->m_bItalic)
{
fontInfo.m_lIndexI = lFontIndex;
fontInfo.m_lFaceIndexI = lFaceIndex;
fontInfo.namesI.RemoveAll();
fontInfo.namesI.Copy(pInfo->names);
fontInfo.namesI.clear();
fontInfo.namesI = pInfo->names;
}
else
{
fontInfo.m_lIndexR = lFontIndex;
fontInfo.m_lFaceIndexR = lFaceIndex;
fontInfo.namesR.RemoveAll();
fontInfo.namesR.Copy(pInfo->names);
fontInfo.namesR.clear();
fontInfo.namesR = pInfo->names;
}
mapFonts.SetAt(fontInfo.m_sName, fontInfo);
arrFonts.Add(fontInfo.m_sName);
mapFonts.insert(std::pair<std::wstring, CFontInfoJS>(fontInfo.m_sName, fontInfo));
arrFonts.push_back(fontInfo.m_sName);
}
}
// additional names
for (int i = 0; i < nCount; ++i)
{
CWinFontInfo* pInfo = (CWinFontInfo*)m_pList->GetByIndex(i);
CString strPath = (CString)pInfo->m_wsFontPath;
CString strName = (CString)pInfo->m_wsFontName;
CFontInfo* pInfo = oFonts.GetList()->GetFonts()->operator [](i);
std::wstring strPath = pInfo->m_wsFontPath;
std::wstring strName = pInfo->m_wsFontName;
LONG lFontIndex = 0;
LONG lFaceIndex = 0;
//CAtlMap<CString, LONG>::CPair* pPairFontFiles = mapFontFiles.Lookup(strPath);
//lFontIndex = pPairFontFiles->m_value;
lFontIndex = (LONG)i;
if (pInfo->m_lIndex >= 0)
lFaceIndex = pInfo->m_lIndex;
int nNamesAdditional = pInfo->names.GetCount();
int nNamesAdditional = pInfo->names.size();
for (int j = 0; j < nNamesAdditional; ++j)
{
CString strNameA = pInfo->names[j];
std::wstring strNameA = pInfo->names[j];
CAtlMap<CString, BOOL>::CPair* pPairMain = mapMainAscii.Lookup(strNameA);
if (NULL != pPairMain)
std::map<std::wstring, bool>::iterator pPairMain = mapMainAscii.find(strNameA);
if (mapMainAscii.end() != pPairMain)
continue;
WCHAR* pBufferA = strNameA.GetBuffer();
int len = strNameA.GetLength();
const wchar_t* pBufferA = strNameA.c_str();
int len = strNameA.length();
CAtlMap<CString, CFontInfoJS>* pMap = &mapFonts;
CAtlArray<CString>* pArrFonts = &arrFonts;
std::map<std::wstring, CFontInfoJS>* pMap = &mapFonts;
std::vector<std::wstring>* pArrFonts = &arrFonts;
for (int k = 0; k < len; ++k)
{
......@@ -291,54 +276,54 @@ int _tmain(int argc, _TCHAR* argv[])
}
}
CAtlMap<CString, CFontInfoJS>::CPair* pPair = pMap->Lookup(strNameA);
if (NULL != pPair)
std::map<std::wstring, CFontInfoJS>::iterator pPair = pMap->find(strNameA);
if (pMap->end() != pPair)
{
pPair->m_value.m_sName = strNameA;
pPair->second.m_sName = strNameA;
if (pInfo->m_bBold && pInfo->m_bItalic)
{
if (-1 != pPair->m_value.m_lIndexBI)
if (-1 != pPair->second.m_lIndexBI)
nError++;
pPair->m_value.m_lIndexBI = lFontIndex;
pPair->m_value.m_lFaceIndexBI = lFaceIndex;
pPair->second.m_lIndexBI = lFontIndex;
pPair->second.m_lFaceIndexBI = lFaceIndex;
pPair->m_value.namesBI.RemoveAll();
pPair->m_value.namesBI.Copy(pInfo->names);
pPair->second.namesBI.clear();
pPair->second.namesBI = pInfo->names;
}
else if (pInfo->m_bBold)
{
if (-1 != pPair->m_value.m_lIndexB)
if (-1 != pPair->second.m_lIndexB)
nError++;
pPair->m_value.m_lIndexB = lFontIndex;
pPair->m_value.m_lFaceIndexB = lFaceIndex;
pPair->second.m_lIndexB = lFontIndex;
pPair->second.m_lFaceIndexB = lFaceIndex;
pPair->m_value.namesB.RemoveAll();
pPair->m_value.namesB.Copy(pInfo->names);
pPair->second.namesB.clear();
pPair->second.namesB = pInfo->names;
}
else if (pInfo->m_bItalic)
{
if (-1 != pPair->m_value.m_lIndexI)
if (-1 != pPair->second.m_lIndexI)
nError++;
pPair->m_value.m_lIndexI = lFontIndex;
pPair->m_value.m_lFaceIndexI = lFaceIndex;
pPair->second.m_lIndexI = lFontIndex;
pPair->second.m_lFaceIndexI = lFaceIndex;
pPair->m_value.namesI.RemoveAll();
pPair->m_value.namesI.Copy(pInfo->names);
pPair->second.namesI.clear();
pPair->second.namesI = pInfo->names;
}
else
{
if (-1 != pPair->m_value.m_lIndexR)
if (-1 != pPair->second.m_lIndexR)
nError++;
pPair->m_value.m_lIndexR = lFontIndex;
pPair->m_value.m_lFaceIndexR = lFaceIndex;
pPair->second.m_lIndexR = lFontIndex;
pPair->second.m_lFaceIndexR = lFaceIndex;
pPair->m_value.namesR.RemoveAll();
pPair->m_value.namesR.Copy(pInfo->names);
pPair->second.namesR.clear();
pPair->second.namesR = pInfo->names;
}
}
else
......@@ -352,137 +337,93 @@ int _tmain(int argc, _TCHAR* argv[])
fontInfo.m_lIndexBI = lFontIndex;
fontInfo.m_lFaceIndexBI = lFaceIndex;
fontInfo.namesBI.RemoveAll();
fontInfo.namesBI.Copy(pInfo->names);
fontInfo.namesBI.clear();
fontInfo.namesBI = pInfo->names;
}
else if (pInfo->m_bBold)
{
fontInfo.m_lIndexB = lFontIndex;
fontInfo.m_lFaceIndexB = lFaceIndex;
fontInfo.namesB.RemoveAll();
fontInfo.namesB.Copy(pInfo->names);
fontInfo.namesB.clear();
fontInfo.namesB = pInfo->names;
}
else if (pInfo->m_bItalic)
{
fontInfo.m_lIndexI = lFontIndex;
fontInfo.m_lFaceIndexI = lFaceIndex;
fontInfo.namesI.RemoveAll();
fontInfo.namesI.Copy(pInfo->names);
fontInfo.namesI.clear();
fontInfo.namesI = pInfo->names;
}
else
{
fontInfo.m_lIndexR = lFontIndex;
fontInfo.m_lFaceIndexR = lFaceIndex;
fontInfo.namesR.RemoveAll();
fontInfo.namesR.Copy(pInfo->names);
fontInfo.namesR.clear();
fontInfo.namesR = pInfo->names;
}
pMap->SetAt(fontInfo.m_sName, fontInfo);
pArrFonts->Add(fontInfo.m_sName);
pMap->insert(std::pair<std::wstring, CFontInfoJS>(fontInfo.m_sName, fontInfo));
pArrFonts->push_back(fontInfo.m_sName);
}
}
}
// -------------------------------------------
// теперь сортируем шрифты по имени ----------
size_t nCountFonts = arrFonts.GetCount();
for (size_t i = 0; i < nCountFonts; ++i)
{
for (size_t j = i + 1; j < nCountFonts; ++j)
{
if (arrFonts[i] > arrFonts[j])
{
CString temp = arrFonts[i];
arrFonts[i] = arrFonts[j];
arrFonts[j] = temp;
}
}
}
size_t nCountFonts = arrFonts.size();
std::sort(arrFonts.begin(), arrFonts.end());
size_t nCountFontsU = arrFontsUnicodes.GetCount();
for (size_t i = 0; i < nCountFontsU; ++i)
{
for (size_t j = i + 1; j < nCountFontsU; ++j)
{
if (arrFontsUnicodes[i] > arrFontsUnicodes[j])
{
CString temp = arrFontsUnicodes[i];
arrFontsUnicodes[i] = arrFontsUnicodes[j];
arrFontsUnicodes[j] = temp;
}
}
}
#if 0
CFile oFile;
oFile.CreateFile(_T("c:\\fonts.txt"));
BYTE bom[3];
bom[0] = 0xEF;
bom[1] = 0xBB;
bom[2] = 0xBF;
oFile.WriteFile((void*)&bom, 3);
size_t nCountFontsU = arrFontsUnicodes.size();
std::sort(arrFontsUnicodes.begin(), arrFontsUnicodes.end());
CString strInfos = _T("");
for (int index = 0; index < nCountFonts; ++index)
{
const CAtlMap<CString, CFontInfoJS>::CPair* pPair = mapFonts.Lookup(arrFonts[index]);
CString strFontInfo = pPair->m_value.m_sName + _T(": [");
for (size_t i = 0; i < pPair->m_value.namesR.GetCount(); ++i)
{
strFontInfo += pPair->m_value.namesR[i];
strFontInfo += _T(",");
}
strFontInfo += _T(";");
for (size_t i = 0; i < pPair->m_value.namesI.GetCount(); ++i)
{
strFontInfo += pPair->m_value.namesI[i];
strFontInfo += _T(",");
}
strFontInfo += _T(";");
for (size_t i = 0; i < pPair->m_value.namesB.GetCount(); ++i)
{
strFontInfo += pPair->m_value.namesB[i];
strFontInfo += _T(",");
}
strFontInfo += _T(";");
for (size_t i = 0; i < pPair->m_value.namesBI.GetCount(); ++i)
{
strFontInfo += pPair->m_value.namesBI[i];
strFontInfo += _T(",");
}
strFontInfo += _T("]\n");
strInfos += strFontInfo;
}
oFile.WriteStringUTF8(strInfos);
oFile.CloseFile();
#endif
CFile oFileW;
NSFile::CFileBinary oFileW;
oFileW.CreateFile(strFontDictionaryPath);
BYTE bom[3];
bom[0] = 0xEF;
bom[1] = 0xBB;
bom[2] = 0xBF;
oFileW.WriteFile((void*)&bom, 3);
CString strAll = _T("");
CString strConstant1 = _T("#ifndef _FONT_DICTIONARY_H\n\n\
oFileW.WriteFile(bom, 3);
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L"\
/*\n\
* (c) Copyright Ascensio System SIA 2010-2017\n\
*\n\
* This program is a free software product. You can redistribute it and/or\n\
* modify it under the terms of the GNU Affero General Public License (AGPL)\n\
* version 3 as published by the Free Software Foundation. In accordance with\n\
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect\n\
* that Ascensio System SIA expressly excludes the warranty of non-infringement\n\
* of any third-party rights.\n\
*\n\
* This program is distributed WITHOUT ANY WARRANTY; without even the implied\n\
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For\n\
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html\n\
*\n\
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,\n\
* EU, LV-1021.\n\
*\n\
* The interactive user interfaces in modified source and object code versions\n\
* of the Program must display Appropriate Legal Notices, as required under\n\
* Section 5 of the GNU AGPL version 3.\n\
*\n\
* Pursuant to Section 7(b) of the License you must retain the original Product\n\
* logo when distributing the program. Pursuant to Section 7(e) we decline to\n\
* grant you any rights under trademark law for use of our trademarks.\n\
*\n\
* All the Product's GUI elements, including illustrations and icon sets, as\n\
* well as technical writing content are licensed under the terms of the\n\
* Creative Commons Attribution-ShareAlike 4.0 International. See the License\n\
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode\n\
*\n\
*/\n");
oBuilder.WriteString(L"#ifndef _FONT_DICTIONARY_H\n\n\
typedef struct FD_FontMapRec_\n\
{\n\
const char* m_name;\n\
......@@ -502,40 +443,45 @@ typedef struct FD_FontMapRecW_\n\
int m_index_bi;\n\
} FD_FontMapRecW;\n\n");
strAll += strConstant1;
int nAsciiNamesCount = (int)arrFonts.GetCount();
CString sAsciiNames = _T("");
sAsciiNames.Format(_T("#define FONTS_DICT_ASCII_NAMES_COUNT %d\n"), nAsciiNamesCount);
sAsciiNames += _T("static const FD_FontMapRec FD_Ascii_Names[FONTS_DICT_ASCII_NAMES_COUNT] = \n{\n");
int nAsciiNamesCount = (int)arrFonts.size();
oBuilder.WriteString(L"#define FONTS_DICT_ASCII_NAMES_COUNT ");
oBuilder.AddInt(nAsciiNamesCount);
oBuilder.WriteString(L"\n");
oBuilder.WriteString(L"static const FD_FontMapRec FD_Ascii_Names[FONTS_DICT_ASCII_NAMES_COUNT] = \n{\n");
for (int k = 0; k < nAsciiNamesCount; ++k)
{
CAtlMap<CString, CFontInfoJS>::CPair* pPair = mapFonts.Lookup(arrFonts[k]);
sAsciiNames += _T("\t{ \"");
sAsciiNames += pPair->m_value.m_sName;
sAsciiNames += _T("\", ");
std::map<std::wstring, CFontInfoJS>::iterator pPair = mapFonts.find(arrFonts[k]);
CString strP = _T("");
oBuilder.WriteString(L"\t{ \"");
oBuilder.WriteString(pPair->second.m_sName);
oBuilder.WriteString(L"\", ");
if (k != (nAsciiNamesCount - 1))
{
strP.Format(_T("%d, %d, %d, %d },\n"), pPair->m_value.m_lIndexR,
pPair->m_value.m_lIndexI, pPair->m_value.m_lIndexB, pPair->m_value.m_lIndexBI);
oBuilder.AddInt(pPair->second.m_lIndexR);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexI);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexB);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexBI);
oBuilder.WriteString(L" },\n");
}
else
{
strP.Format(_T("%d, %d, %d, %d }\n"), pPair->m_value.m_lIndexR,
pPair->m_value.m_lIndexI, pPair->m_value.m_lIndexB, pPair->m_value.m_lIndexBI);
oBuilder.AddInt(pPair->second.m_lIndexR);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexI);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexB);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexBI);
oBuilder.WriteString(L" }\n");
}
sAsciiNames += strP;
}
sAsciiNames += _T("};\n\n");
strAll += sAsciiNames;
oBuilder.WriteString(L"};\n\n");
int _offsets[256];
for (int t = 0; t < 256; ++t)
......@@ -544,7 +490,7 @@ typedef struct FD_FontMapRecW_\n\
int nCurChar = -1;
for (int k = 0; k < nAsciiNamesCount; ++k)
{
int nChar = (int)arrFonts[k].GetAt(0);
int nChar = (int)arrFonts[k].c_str()[0];
nChar = max(0, min(nChar, 255));
if (nChar != nCurChar)
......@@ -554,66 +500,70 @@ typedef struct FD_FontMapRecW_\n\
nCurChar = nChar;
}
CString strAsciiOffsets = _T("static const int FD_Ascii_Names_Offsets[256] =\n{\n");
oBuilder.WriteString(L"static const int FD_Ascii_Names_Offsets[256] =\n{\n");
for (int k = 0; k < 256; ++k)
{
CString sMem = _T("");
sMem.Format(_T("%d"), _offsets[k]);
std::wstring sMem = std::to_wstring(_offsets[k]);
while (sMem.GetLength() < 4)
sMem = (_T(" ") + sMem);
while (sMem.length() < 4)
sMem = (L" " + sMem);
if (0 == k % 32)
sMem = _T("\t") + sMem;
sMem = L"\t" + sMem;
if (k != 255)
sMem += _T(",");
sMem += L",";
if (0 == (k + 1) % 32)
sMem += _T("\n");
sMem += L"\n";
strAsciiOffsets += sMem;
oBuilder.WriteString(sMem);
}
strAsciiOffsets += _T("};\n\n");
oBuilder.WriteString(L"};\n\n");
strAll += strAsciiOffsets;
int nUnicodeNamesCount = (int)arrFontsUnicodes.GetCount();
CString sUnicodeNames = _T("");
sUnicodeNames.Format(_T("#define FONTS_DICT_UNICODE_NAMES_COUNT %d\n"), nUnicodeNamesCount);
sUnicodeNames += _T("static const FD_FontMapRecW FD_Unicode_Names[FONTS_DICT_UNICODE_NAMES_COUNT] = \n{\n");
int nUnicodeNamesCount = (int)arrFontsUnicodes.size();
oBuilder.WriteString(L"#define FONTS_DICT_UNICODE_NAMES_COUNT ");
oBuilder.AddInt(nUnicodeNamesCount);
oBuilder.WriteString(L"\n");
oBuilder.WriteString(L"static const FD_FontMapRecW FD_Unicode_Names[FONTS_DICT_UNICODE_NAMES_COUNT] = \n{\n");
for (int k = 0; k < nUnicodeNamesCount; ++k)
{
CAtlMap<CString, CFontInfoJS>::CPair* pPair = mapFontsUnicodes.Lookup(arrFontsUnicodes[k]);
sUnicodeNames += _T("\t{ L\"");
sUnicodeNames += pPair->m_value.m_sName;
sUnicodeNames += _T("\", ");
std::map<std::wstring, CFontInfoJS>::iterator pPair = mapFontsUnicodes.find(arrFontsUnicodes[k]);
CString strP = _T("");
oBuilder.WriteString(L"\t{ L\"");
oBuilder.WriteString(pPair->second.m_sName);
oBuilder.WriteString(L"\", ");
if (k != (nAsciiNamesCount - 1))
{
strP.Format(_T("%d, %d, %d, %d },\n"), pPair->m_value.m_lIndexR,
pPair->m_value.m_lIndexI, pPair->m_value.m_lIndexB, pPair->m_value.m_lIndexBI);
oBuilder.AddInt(pPair->second.m_lIndexR);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexI);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexB);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexBI);
oBuilder.WriteString(L" },\n");
}
else
{
strP.Format(_T("%d, %d, %d, %d }\n"), pPair->m_value.m_lIndexR,
pPair->m_value.m_lIndexI, pPair->m_value.m_lIndexB, pPair->m_value.m_lIndexBI);
oBuilder.AddInt(pPair->second.m_lIndexR);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexI);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexB);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pPair->second.m_lIndexBI);
oBuilder.WriteString(L" }\n");
}
sUnicodeNames += strP;
}
sUnicodeNames += _T("};\n\n");
strAll += sUnicodeNames;
oBuilder.WriteString(L"};\n\n");
CString strConstant2 = _T("typedef struct FD_Font_Rec\n\
oBuilder.WriteString(L"typedef struct FD_Font_Rec\n\
{\n\
const char* m_name;\n\
\n\
......@@ -646,81 +596,107 @@ typedef struct FD_FontMapRecW_\n\
short m_shCapHeight;\n\
} FD_Font;\n\n");
strAll += strConstant2;
int nAllFontsCount = (int)nCount;
CString sAllFontsNames = _T("");
sAllFontsNames.Format(_T("#define FONTS_DICT_ASCII_FONTS_COUNT %d\n"), nCount);
sAllFontsNames += _T("static const FD_Font FD_Ascii_Files[FONTS_DICT_ASCII_FONTS_COUNT] = \n{\n");
oBuilder.WriteString(L"#define FONTS_DICT_ASCII_FONTS_COUNT ");
oBuilder.AddInt(nCount);
oBuilder.WriteString(L"\n");
oBuilder.WriteString(L"static const FD_Font FD_Ascii_Files[FONTS_DICT_ASCII_FONTS_COUNT] = \n{\n");
for (int k = 0; k < nCount; ++k)
{
CWinFontInfo* pInfo = (CWinFontInfo*)m_pList->GetByIndex(k);
CFontInfo* pInfo = oFonts.GetList()->GetFonts()->operator [](k);
#if 1
// CORRECT!!!
if (pInfo->m_wsFontName == _T("Monotype Sorts"))
if (pInfo->m_wsFontName == L"Monotype Sorts")
pInfo->m_aPanose[0] = 5;
#endif
oBuilder.WriteString(L"\t{\"");
oBuilder.WriteString(pInfo->m_wsFontName);
CString sMem = _T("");
sMem.Format(_T("\", %d, %d, %d, %d, { %d, %d, %d, %d, %d, %d, %d, %d, %d, %d }, %u, %u, %u, %u, %u, %u, %u, %u, %d, %d, %d, %d, %d, %d, %d, %d }"),
pInfo->m_lIndex,
pInfo->m_bBold,
pInfo->m_bItalic,
pInfo->m_bIsFixed,
pInfo->m_aPanose[0],
pInfo->m_aPanose[1],
pInfo->m_aPanose[2],
pInfo->m_aPanose[3],
pInfo->m_aPanose[4],
pInfo->m_aPanose[5],
pInfo->m_aPanose[6],
pInfo->m_aPanose[7],
pInfo->m_aPanose[8],
pInfo->m_aPanose[9],
pInfo->m_ulUnicodeRange1,
pInfo->m_ulUnicodeRange2,
pInfo->m_ulUnicodeRange3,
pInfo->m_ulUnicodeRange4,
pInfo->m_ulCodePageRange1,
pInfo->m_ulCodePageRange2,
pInfo->m_usWeigth,
pInfo->m_usWidth,
pInfo->m_sFamilyClass,
pInfo->m_eFontFormat,
pInfo->m_shAvgCharWidth,
pInfo->m_shAscent,
pInfo->m_shDescent,
pInfo->m_shLineGap,
pInfo->m_shXHeight,
pInfo->m_shCapHeight);
sAllFontsNames += _T("\t{\"");
sAllFontsNames += pInfo->m_wsFontName;
sAllFontsNames += sMem;
oBuilder.WriteString(L"\", ");
oBuilder.AddInt(pInfo->m_lIndex);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_bBold);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_bItalic);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_bIsFixed);
oBuilder.WriteString(L", { ");
oBuilder.AddInt(pInfo->m_aPanose[0]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[1]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[2]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[3]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[4]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[5]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[6]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[7]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[8]);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_aPanose[9]);
oBuilder.WriteString(L" }, ");
oBuilder.AddInt64((__int64)pInfo->m_ulUnicodeRange1);
oBuilder.WriteString(L", ");
oBuilder.AddInt64((__int64)pInfo->m_ulUnicodeRange2);
oBuilder.WriteString(L", ");
oBuilder.AddInt64((__int64)pInfo->m_ulUnicodeRange3);
oBuilder.WriteString(L", ");
oBuilder.AddInt64((__int64)pInfo->m_ulUnicodeRange4);
oBuilder.WriteString(L", ");
oBuilder.AddInt64((__int64)pInfo->m_ulCodePageRange1);
oBuilder.WriteString(L", ");
oBuilder.AddInt64((__int64)pInfo->m_ulCodePageRange2);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_usWeigth);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_usWidth);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_sFamilyClass);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_eFontFormat);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shAvgCharWidth);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shAscent);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shDescent);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shLineGap);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shXHeight);
oBuilder.WriteString(L", ");
oBuilder.AddInt(pInfo->m_shCapHeight);
oBuilder.WriteString(L" }");
if (k != (nCount - 1))
sAllFontsNames += _T(",\n");
oBuilder.WriteString(L",\n");
else
sAllFontsNames += _T("\n");
oBuilder.WriteString(L"\n");
}
sAllFontsNames += _T("};\n\n");
oBuilder.WriteString(L"};\n\n");
strAll += sAllFontsNames;
oBuilder.WriteString(L"// error : ");
oBuilder.AddInt(nError);
oBuilder.WriteString(L"\n\n");
oBuilder.WriteString(L"#endif /* _FONT_DICTIONARY_H */");
CString strError = _T("");
strError.Format(_T("// error : %d\n\n"), nError);
strAll += strError;
strAll += _T("#endif /* _FONT_DICTIONARY_H */");
oFileW.WriteStringUTF8(strAll);
oFileW.WriteStringUTF8(oBuilder.GetData());
oFileW.CloseFile();
if (NULL != m_pList)
delete m_pList;
return 0;
return 0;
}

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FontMaps", "FontMaps.vcproj", "{841E1A33-234B-4C2B-97EB-1D6785A26DA9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{841E1A33-234B-4C2B-97EB-1D6785A26DA9}.Debug|Win32.ActiveCfg = Debug|Win32
{841E1A33-234B-4C2B-97EB-1D6785A26DA9}.Debug|Win32.Build.0 = Debug|Win32
{841E1A33-234B-4C2B-97EB-1D6785A26DA9}.Release|Win32.ActiveCfg = Release|Win32
{841E1A33-234B-4C2B-97EB-1D6785A26DA9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="FontMaps"
ProjectGUID="{841E1A33-234B-4C2B-97EB-1D6785A26DA9}"
RootNamespace="FontMaps"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfATL="1"
ATLMinimizesCRunTimeLibraryUsage="true"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../freetype-2.5.3/include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib $(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib $(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\FontMaps.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\File.h"
>
</File>
<File
RelativePath=".\FontDictionary.h"
>
</File>
<File
RelativePath=".\FontDictionaryWorker.h"
>
</File>
<File
RelativePath=".\FontUtils.h"
>
</File>
<File
RelativePath=".\List.h"
>
</File>
<File
RelativePath=".\ShareMemArray.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\WinFont.h"
>
</File>
<File
RelativePath=".\WinFontStorage.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _FONT_UTILS_H
#define _FONT_UTILS_H
#include FT_SFNT_NAMES_H
#define fabs(X) ( X >= 0 ? X : -X )
namespace FontConstants
{
enum FontStyle
{
FontStyleRegular = 0,
FontStyleBold = 1,
FontStyleItalic = 2,
FontStyleBoldItalic = 3,
FontStyleUnderline = 4,
FontStyleStrikeout = 8
};
}
#define UNKNOWN_CHARSET 3 // для случаев, когда задано значение DEFAULT_CHARSET, но
// на самом деле charset не учитывается
//---------------------------------------------------------------------------------------------------
#define MAX_FONT_CACHE_SIZE 16
#define MAX_FONT_NAME_LEN 50
#define MAX_FONT_STYLE_LEN 40
static long GetNextNameValue(HKEY key, LPCTSTR pszSubkey, LPTSTR pszName, LPTSTR pszData)
{
static HKEY hkey = NULL; // registry handle, kept open between calls
static DWORD dwIndex = 0; // count of values returned
LONG retval;
// if all parameters are NULL then close key
if (pszSubkey == NULL && pszName == NULL && pszData == NULL)
{
if (hkey)
RegCloseKey(hkey);
hkey = NULL;
return ERROR_SUCCESS;
}
// if subkey is specified then open key (first time)
if (pszSubkey && pszSubkey[0] != 0)
{
retval = RegOpenKeyEx(key, pszSubkey, 0, KEY_READ, &hkey);
if (retval != ERROR_SUCCESS)
{
return retval;
}
dwIndex = 0;
}
else
{
dwIndex++;
}
_ASSERTE(pszName != NULL && pszData != NULL);
*pszName = 0;
*pszData = 0;
TCHAR szValueName[MAX_PATH];
DWORD dwValueNameSize = sizeof(szValueName)-1;
BYTE szValueData[MAX_PATH];
DWORD dwValueDataSize = sizeof(szValueData)-1;
DWORD dwType = 0;
retval = RegEnumValue(hkey, dwIndex, szValueName, &dwValueNameSize, NULL,
&dwType, szValueData, &dwValueDataSize);
if (retval == ERROR_SUCCESS)
{
lstrcpy(pszName, (LPTSTR)szValueName);
lstrcpy(pszData, (LPTSTR)szValueData);
}
return retval;
}
static FT_Error FT_New_FaceW(FT_Library pLibrary, wchar_t *wsFilePath, FT_Long lIndex, FT_Face *pFace)
{
USES_CONVERSION;
FT_Open_Args oOpenArgs;
oOpenArgs.flags = FT_OPEN_PATHNAME;
oOpenArgs.pathname = W2A( wsFilePath );
FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 );
pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' );
pParams[0].data = NULL;
pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' );
pParams[1].data = NULL;
pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY;
pParams[2].data = NULL;
pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY;
pParams[3].data = NULL;
oOpenArgs.num_params = 4;
oOpenArgs.params = pParams;
int nError = FT_Open_Face( pLibrary, &oOpenArgs, lIndex, pFace );
::free( pParams );
return nError;
}
static int GetDefaultCharset(BOOL bUseDefCharset = TRUE)
{
if ( !bUseDefCharset )
return UNKNOWN_CHARSET;
LOCALESIGNATURE LocSig;
GetLocaleInfo( GetSystemDefaultLCID(), LOCALE_FONTSIGNATURE, (LPWSTR)&LocSig, sizeof(LocSig) / sizeof(TCHAR) );
if ( LocSig.lsCsbDefault[0] & 1 )
return 0;
else if ( LocSig.lsCsbDefault[0] & 2 )
return 238;
else if ( LocSig.lsCsbDefault[0] & 4 )
return 204;
else if ( LocSig.lsCsbDefault[0] & 8 )
return 161;
else if ( LocSig.lsCsbDefault[0] & 16 )
return 162;
else if ( LocSig.lsCsbDefault[0] & 32 )
return 177;
else if ( LocSig.lsCsbDefault[0] & 64 )
return 178;
else if ( LocSig.lsCsbDefault[0] & 128 )
return 186;
else if ( LocSig.lsCsbDefault[0] & 256 )
return 163;
else if ( LocSig.lsCsbDefault[0] & 0x10000 )
return 222;
else if ( LocSig.lsCsbDefault[0] & 0x20000 )
return 128;
else if ( LocSig.lsCsbDefault[0] & 0x40000 )
return 134;
else if ( LocSig.lsCsbDefault[0] & 0x80000 )
return 129;
else if ( LocSig.lsCsbDefault[0] & 0x100000 )
return 136;
else if ( LocSig.lsCsbDefault[0] & 0x200000 )
return 130;
else if ( LocSig.lsCsbDefault[0] & 0x20000000 )
return 77;
else if ( LocSig.lsCsbDefault[0] & 0x40000000 )
return 255;
else if ( LocSig.lsCsbDefault[0] & 0x80000000 )
return 2;
return 0;
}
static void GetCodePageByCharset(unsigned char unCharset, unsigned long *pulBit, unsigned int *punLongIndex)
{
// Данная функция возвращает параметры, которые нужно посылать на вход
// функции AVSFontManager::IsUnicodeRangeAvailable
// Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478
// http://msdn.microsoft.com/en-us/library/cc194829.aspx
// Charset Name Charset Value(hex) Codepage number
// ------------------------------------------------------
//
// DEFAULT_CHARSET 1 (x01)
// SYMBOL_CHARSET 2 (x02)
// OEM_CHARSET 255 (xFF)
// ANSI_CHARSET 0 (x00) 1252
// RUSSIAN_CHARSET 204 (xCC) 1251
// EASTEUROPE_CHARSET 238 (xEE) 1250
// GREEK_CHARSET 161 (xA1) 1253
// TURKISH_CHARSET 162 (xA2) 1254
// BALTIC_CHARSET 186 (xBA) 1257
// HEBREW_CHARSET 177 (xB1) 1255
// ARABIC _CHARSET 178 (xB2) 1256
// SHIFTJIS_CHARSET 128 (x80) 932
// HANGEUL_CHARSET 129 (x81) 949
// GB2313_CHARSET 134 (x86) 936
// CHINESEBIG5_CHARSET 136 (x88) 950
// THAI_CHARSET 222 (xDE) 874
// JOHAB_CHARSET 130 (x82) 1361
// VIETNAMESE_CHARSET 163 (xA3) 1258
// MAC_CHARSET 77 (x4D)
// Соответсвие CodePage -> ulCodePageRange1 : http://www.microsoft.com/Typography/otspec/os2.htm#cpr
if ( punLongIndex )
*punLongIndex = 4;
if ( unCharset == DEFAULT_CHARSET )
unCharset = GetDefaultCharset();
if ( pulBit )
{
switch( unCharset )
{
case 0x00: *pulBit = 0; break;
case 0xEE: *pulBit = 1; break;
case 0xCC: *pulBit = 2; break;
case 0xA1: *pulBit = 3; break;
case 0xA2: *pulBit = 4; break;
case 0xB1: *pulBit = 5; break;
case 0xB2: *pulBit = 6; break;
case 0xBA: *pulBit = 7; break;
case 0xA3: *pulBit = 8; break;
case 0xDE: *pulBit = 16; break;
case 0x80: *pulBit = 17; break;
case 0x86: *pulBit = 18; break;
case 0x81: *pulBit = 19; break;
case 0x88: *pulBit = 20; break;
case 0x82: *pulBit = 21; break;
case 0x4D: *pulBit = 29; break;
case 0x02: *pulBit = 31; break;
case 0xFF: *pulBit = 30; break;
default: *pulBit = 0; break;
}
}
}
#endif /* _FONT_UTILS_H */
\ No newline at end of file
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _LIST_H
#define _LIST_H
//------------------------------------------------------------------------
// CList
//------------------------------------------------------------------------
class CList
{
public:
// Создаем пустой список.
CList()
{
m_nItemSize = 8;
m_ppData = (void **)::malloc( m_nItemSize * sizeof(void*) );
m_nCount = 0;
m_nIncreament = 0;
}
// Создаем пустой список с с выделенной памятью под <nSize> элементов.
CList(int nSize)
{
m_nItemSize = nSize;
m_ppData = (void **)::malloc( m_nItemSize * sizeof(void*) );
m_nCount = 0;
m_nIncreament = 0;
}
// Деструктор.
~CList()
{
if ( m_ppData )
::free( m_ppData );
}
int GetLength()
{
return m_nCount;
}
// Возвращает <nIndex>Ый элемент.
// Если 0 <= nIndex < m_nCount, возвращает NULL.
void *GetByIndex(int nIndex)
{
if ( nIndex < 0 || nIndex >= m_nCount )
return NULL;
return m_ppData[ nIndex ];
}
// Добавляем элемент в окнец списка.
void Append(void *pItem)
{
if ( m_nCount >= m_nItemSize )
Expand();
m_ppData[m_nCount++] = pItem;
}
// Добавляем другой список в конец данного.
void Append(CList *pList)
{
while ( m_nCount + pList->m_nCount > m_nItemSize )
Expand();
for (int nIndex = 0; nIndex < pList->m_nCount; ++nIndex )
m_ppData[m_nCount++] = pList->m_ppData[ nIndex ];
}
// Вставляем элемент на место <nIndex>.
// Если !(0 <= nIndex <= m_nCount), ничего не делаем.
void Insert(int nIndex, void *pItem)
{
if ( 0 > nIndex || nIndex > m_nCount )
return;
if ( m_nCount >= m_nItemSize )
Expand();
if ( nIndex < m_nCount )
memmove( m_ppData + nIndex + 1, m_ppData + nIndex, ( m_nCount - nIndex ) * sizeof(void *));
m_ppData[ nIndex ] = pItem;
++m_nCount;
}
// Удаляем из списка и возвращаем ссылку на элемент.
// Если !(0 <= nIndex <= m_nCount), ничего не делаем.
void *Delete(int nIndex)
{
void *pItem = m_ppData[ nIndex ];
if ( nIndex < m_nCount - 1 )
memmove( m_ppData + nIndex, m_ppData + nIndex + 1, (m_nCount - nIndex - 1) * sizeof(void *));
--m_nCount;
if ( m_nItemSize - m_nCount >= ((m_nIncreament > 0) ? m_nIncreament : m_nItemSize / 2 ) )
Shrink();
return pItem;
}
// Сортируем список, в соответствии с данной функцией
// сранвения.
void Sort(int (*CompareFunc)(const void *pItem1, const void *pItem2 ) )
{
qsort( m_ppData, m_nCount, sizeof(void *), CompareFunc);
}
// Если m_nIncreament > 0, тогда при расширении списка ровно
// m_nIncreament элементов будет добавляться. Если m_nIncreament <= 0,
// тогда список будем удваивать при расширении.
void SetAllocationIncreament(int nIncreament)
{
m_nIncreament = nIncreament;
}
private:
void Expand()
{
m_nItemSize += ( m_nIncreament > 0 ) ? m_nIncreament : m_nItemSize;
m_ppData = (void **)::realloc( m_ppData, m_nItemSize * sizeof(void*) );
}
void Shrink()
{
m_nItemSize -= ( m_nIncreament > 0 ) ? m_nIncreament : m_nItemSize / 2;
m_ppData = (void **)::realloc( m_ppData, m_nItemSize * sizeof(void*) );
}
private:
void **m_ppData; // список элементов
int m_nItemSize; // размер данных в массиве
int m_nCount; // количестов элементов в списке
int m_nIncreament; // на сколько будем увеличивать список
};
#define DeleteCList(list, T) \
do { \
CList *_list = (list); \
{ \
int _i; \
for (_i = 0; _i < _list->GetLength(); ++_i) { \
delete (T*)_list->GetByIndex(_i); \
} \
delete _list; \
} \
} while (0)
#endif /* _LIST_H */
\ No newline at end of file
========================================================================
CONSOLE APPLICATION : FontMaps Project Overview
========================================================================
AppWizard has created this FontMaps application for you.
This file contains a summary of what you will find in each of the files that
make up your FontMaps application.
FontMaps.vcproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
FontMaps.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named FontMaps.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/***************************************************************
CShareMemArray
шаблон класса для работы с именованной
Shared-памятью. Реализаваны загрузка массива
из памяти и сохранение в память.
***************************************************************/
#pragma once
#pragma warning( disable : 4996 4244) // No CRT-secure warning
#include <atlcoll.h>
#include "../../../Common/ASCUtils.h" // CSyncAccess class definition
#define AVS_USER_NAME_LEN 1024
// Статус хранилища (ошибка, уже создано, новое)
enum TSMAStatus {SMAS_ERROR, SMAS_ALREADYEXISTS, SMAS_NEW};
// Хранилище
template <typename STOR_TYPE>
class CShareMemArray
{
protected:
HANDLE m_hAccessMutex; // Мьютекс для безопасного доступа к Shared-Memory
HANDLE m_hMapFile; // Хендл на map таблицы
STOR_TYPE *m_pArray; // Указатель на массив
LONG64 m_nSize; // Размер таблицы
CString m_sMutexName; // Имя мьютекса
CString m_sMapName; // Имя маппа
TSMAStatus m_sStatus;
protected:
// Читаем из памяти
bool ReadFromSharedMem(LONG64 nIndex, STOR_TYPE &nValue)
{
if (NULL == m_pArray)
{
m_sStatus = SMAS_ERROR;
return false;
}
__try
{
STOR_TYPE *pTable = (STOR_TYPE *) (((BYTE *) m_pArray) + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы
nValue = pTable[nIndex];
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
ATLTRACE2("CIndexerStorage::ReadFromSharedMem()\n");
return false;
}
return true;
}
// Пишем в память
bool WriteToSharedMem(LONG64 nIndex, STOR_TYPE aValue)
{
if (NULL == m_pArray)
{
m_sStatus = SMAS_ERROR;
return false;
}
__try
{
STOR_TYPE *pTable = (STOR_TYPE *) (((BYTE *) m_pArray) + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы
pTable[nIndex] = aValue;
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
ATLTRACE2("Error CIndexerStorage::WriteToSharedMem(#i)\n", nIndex);
return false;
}
return true;
}
// Загрузка таблицы индексов из SharedMemory
bool SaveTable_unsync(CAtlArray<STOR_TYPE> &aTable)
{
if ((NULL == m_pArray) || (NULL == m_hMapFile))
{
m_sStatus = SMAS_ERROR;
return false; // Защита от дурака
}
bool bRes = true;
// Защита от дурака
LONG64 nCopyCount = (m_nSize <= (LONG64) aTable.GetCount()) ? m_nSize : aTable.GetCount();
// Сохраняем размер таблицы
Size_unsync(m_nSize);
// копируем из памяти в массив (safe)
for (LONG64 nIndex = 0; nIndex < nCopyCount; nIndex++)
{
bRes &= WriteToSharedMem (nIndex, aTable[nIndex]);
}
return bRes;
}
// Сохранение таблицы индексов из SharedMemory
bool LoadTable_unsync(CAtlArray<STOR_TYPE> &aTable)
{
if ((NULL == m_pArray) || (NULL == m_hMapFile))
{
m_sStatus = SMAS_ERROR;
return false; // Защита от дурака
}
aTable.RemoveAll();
// Определяем размер
m_nSize = Size_unsync();
STOR_TYPE nValue;
// копируем из памяти в массив
for (DWORD nIndex = 0; nIndex < m_nSize; nIndex++)
{
if (ReadFromSharedMem(nIndex, nValue))
{
// Добавляем в таблицу
aTable.Add(nValue);
}
}
return true;
}
// Размер
LONG64 Size_unsync()
{
LONG64 nValue = -1;
if (NULL == m_pArray)
{
m_sStatus = SMAS_ERROR;
return nValue;
}
__try
{
LONG64 *pSize = (LONG64 *) m_pArray;
nValue = *pSize;
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
ATLTRACE2("CIndexerStorage::Size_unsync()\n");
return -1;
}
return nValue;
}
void Size_unsync(LONG64 aSize)
{
if (NULL == m_pArray)
{
m_sStatus = SMAS_ERROR;
return;
}
__try
{
LONG64 *pSize = (LONG64*) m_pArray; // sizeof(LONG64) - размер таблицы
*pSize = aSize;
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
ATLTRACE2("Error CIndexerStorage::Size_unsync(LONG64 aSize)\n");
}
}
public:
// aSize - размер таблицы индексации (кол-во полусекунд),
// Id - дополнительный идектификатор, чтоб можно было создавать много сторейджей для одного файла
CShareMemArray(CString &aFileName, LONG64 aSize, DWORD aId = ISID_DEFAULT):
m_hMapFile(NULL), m_nSize(aSize), m_pArray(NULL), m_sStatus(SMAS_ERROR)
{
// "Вытаскиваем" имя файла
TCHAR aDrive[_MAX_DRIVE];
TCHAR aDir[_MAX_DIR];
TCHAR aFName[_MAX_FNAME];
TCHAR aExt[_MAX_EXT];
_tsplitpath (aFileName.GetBuffer(), aDrive, aDir, aFName, aExt);
//_wsplitpath_s (aFileName.GetBuffer(), aDrive, _MAX_DRIVE, aDir, _MAX_DIR, aFName, _MAX_FNAME, aExt, _MAX_EXT);
// Дополнительно формируем уникальные символы для этого пути, чтобы включить в имя файла
DWORD dwPathID = 0;
TCHAR tcPathIDItem = 0;
// Подсчитываем контрольную сумму для пути
for (int i = 0; i < (int) _tcslen(aDir); i++)
{
tcPathIDItem ^= aDir[i];
dwPathID ^= dwPathID << 1;
dwPathID += (DWORD) tcPathIDItem;
}
// Подсчитываем контрольную сумму для расширения
DWORD dwExtID = 0;
TCHAR tcExtIDItem = 0;
for (int i = 0; i < (int) _tcslen(aExt); i++)
{
tcExtIDItem ^= aExt[i];
dwExtID ^= dwExtID << 1;
dwExtID += (DWORD) tcExtIDItem;
}
// Формируем имя мутекса и мапа
// Этот код не работает если зашло два пользователя и каждый запускает свою копию приложения.
// Фича в именовании мьютекса.
// В начале имени мьютекса должно стоять "Global\"
// ШульгаИван: "Global\" не проходит на Win7, если прога запущена не под админом
m_sMutexName.Format(_T("Local\\avs_mutex%u_%s_%06x_%06I64x_%06x"), aId, aFName, dwPathID, aSize, dwExtID);
m_sMapName.Format(_T("Local\\avs_storage%u_%s_%06x_%06I64x_%06x"), aId, aFName, dwPathID, aSize, dwExtID);
// добавляем имя юзера
TCHAR pBufferUserName[AVS_USER_NAME_LEN];
DWORD dwBufferUserNameLen = AVS_USER_NAME_LEN;
GetUserName(pBufferUserName, &dwBufferUserNameLen);
CString strUserName(pBufferUserName, dwBufferUserNameLen);
m_sMutexName += strUserName;
m_sMapName += strUserName;
// Создаем мьютекс
m_hAccessMutex = CreateMutex(NULL, FALSE, m_sMutexName.GetBuffer());
// Далее все делаем "под мутексом" :)
CSynchAccess oAccess = m_hAccessMutex;
// Создаем мап
ATLTRACE2("CShareMemArray()::CShareMemArray(): m_nSize = %d\n", m_nSize);
ULARGE_INTEGER nMappingSize;
nMappingSize.QuadPart = m_nSize * sizeof(STOR_TYPE) + sizeof(LONG64);
m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, nMappingSize.HighPart, nMappingSize.LowPart, m_sMapName.GetBuffer());
if (NULL == m_hMapFile)
{
// Ошибка
ATLTRACE2("CShareMemArray::CShareMemArray():CreateFileMapping() FAILS (0x%x)!\n", GetLastError());
m_sStatus = SMAS_ERROR;
}
else
{
// Все ок!
m_sStatus = (GetLastError() == ERROR_ALREADY_EXISTS) ? SMAS_ALREADYEXISTS : SMAS_NEW;
ATLTRACE2 (SMAS_ALREADYEXISTS == m_sStatus ? "CShareMemArray: open existing!\n" : "CShareMemArray: create new!\n");
// создаем View of file
m_pArray = (STOR_TYPE *) MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, (SIZE_T) nMappingSize.QuadPart);
if (NULL == m_pArray)
{
// Ошибка
ATLTRACE2("CShareMemArray::CShareMemArray():MapViewOfFile() FAILS (0x%x)!\n", GetLastError());
m_sStatus = SMAS_ERROR;
}
}
}
virtual ~CShareMemArray()
{
if (m_pArray) UnmapViewOfFile(m_pArray); // удаляем view
if (NULL != m_hMapFile) CloseHandle(m_hMapFile); // удаляем мап
if (NULL != m_hAccessMutex) CloseHandle(m_hAccessMutex); // Удаляем мьютекс
}
public:
// Сохранить таблицу в шаред-мемори
bool Save(CAtlArray<STOR_TYPE> &aTable)
{
CSynchAccess oAccess = m_hAccessMutex;
return SaveTable_unsync(aTable);
}
// Загрузить таблицу
bool Load(CAtlArray<STOR_TYPE> &aTable)
{
CSynchAccess oAccess = m_hAccessMutex;
return LoadTable_unsync(aTable);
}
// Размер получение
LONG64 Size()
{
CSynchAccess oAccess = m_hAccessMutex;
return Size_unsync();
}
/*void Size(LONG64 aSize)
{
CSynchAccess oAccess = m_hAccessMutex;
Size_unsync(aSize);
}*/
// Получение статуса
TSMAStatus Status(void) const
{
CSynchAccess oAccess = m_hAccessMutex;
return m_sStatus;
}
};
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _WIN_FONT_H
#define _WIN_FONT_H
#include <shlobj.h>
// FreeType
#include "../freetype-2.5.3/include/ft2build.h"
#include FT_FREETYPE_H
#pragma comment (lib, "../freetype-2.5.3/objs/win32/vc2005/freetype253ST_D.lib")
#include "../freetype-2.5.3/include/ftsnames.h"
#include "../freetype-2.5.3/include/tttables.h"
#include "../freetype-2.5.3/include/ftxf86.h"
#include "../freetype-2.5.3/include/internal/internal.h"
#include "../freetype-2.5.3/include/internal/tttypes.h"
#include "List.h"
#include "FontUtils.h"
#include "../../../Common/XmlUtils.h"
#include "FontDictionaryWorker.h"
static _bstr_t g_cpszXML_Font_Name = L"name";
static _bstr_t g_cpszXML_Font_Bold = L"bold";
static _bstr_t g_cpszXML_Font_Italic = L"italic";
static _bstr_t g_cpszXML_Font_Path = L"path";
static _bstr_t g_cpszXML_Font_Index = L"index";
static LONG g_lSizeofLONG = sizeof(LONG);
static LONG g_lSizeofBOOL = sizeof(BOOL);
static LONG g_lSizeofWCHAR = sizeof(WCHAR);
static LONG g_lSizeofULONG = sizeof(ULONG);
static LONG g_lSizeofUSHORT = sizeof(USHORT);
static LONG g_lSizeofSHORT = sizeof(SHORT);
//-------------------------------------------------------------------------------------------------------------------------------
// CWinFontInfo
//-------------------------------------------------------------------------------------------------------------------------------
enum EFontFormat
{
fontWindowsFNT = 0, // *.fon
fontTrueType = 1, // *.ttf
fontOpenType = 2, // *.ttf, *.otf (CFF формат)
fontUnknown = 3
};
class CWinFontInfo
{
public:
CWinFontInfo(const CStringW &wsFontName, const CStringW &wsStyle, const CString &wsFontPath, long lIndex, BOOL bBold, BOOL bItalic, BOOL bFixedWidth, BYTE *pPanose, ULONG ulRange1, ULONG ulRange2, ULONG ulRange3, ULONG ulRange4, ULONG ulCodeRange1, ULONG ulCodeRange2, USHORT usWeigth, USHORT usWidth, SHORT sFamilyClass, EFontFormat eFormat, SHORT shAvgCharWidth, SHORT shAscent, SHORT shDescent, SHORT shLineGap, SHORT shXHeight, SHORT shCapHeight)
{
m_wsFontName = wsFontName;
m_wsFontPath = wsFontPath;
m_wsStyle = wsStyle;
m_lIndex = lIndex;
m_bBold = bBold;
m_bItalic = bItalic;
m_bIsFixed = bFixedWidth;
if ( pPanose )
memcpy( (void*)m_aPanose, (const void *)pPanose, 10 );
else
memset( (void*)m_aPanose, 0x00, 10 );
m_ulUnicodeRange1 = ulRange1;
m_ulUnicodeRange2 = ulRange2;
m_ulUnicodeRange3 = ulRange3;
m_ulUnicodeRange4 = ulRange4;
m_ulCodePageRange1 = ulCodeRange1;
m_ulCodePageRange2 = ulCodeRange2;
m_usWeigth = usWeigth;
m_usWidth = usWidth;
m_sFamilyClass = sFamilyClass;
m_eFontFormat = eFormat;
m_shAvgCharWidth = shAvgCharWidth;
m_shAscent = shAscent;
m_shDescent = shDescent;
m_shLineGap = shLineGap;
m_shXHeight = shXHeight;
m_shCapHeight = shCapHeight;
}
CWinFontInfo(BSTR wsFontName, BSTR wsFontPath, const long& lIndex, const BOOL& bBold, const BOOL& bItalic, const BOOL& bFixedWidth, BYTE *pPanose, const ULONG& ulRange1, const ULONG& ulRange2, const ULONG& ulRange3, const ULONG& ulRange4, const ULONG& ulCodeRange1, const ULONG& ulCodeRange2, const USHORT& usWeigth, const USHORT& usWidth, const SHORT& sFamilyClass, EFontFormat eFormat, const SHORT& shAvgCharWidth, const SHORT& shAscent, const SHORT& shDescent, const SHORT& shLineGap, const SHORT& shXHeight, const SHORT& shCapHeight)
{
m_wsFontName = wsFontName;
m_wsFontPath = wsFontPath;
m_wsStyle = L"";
m_lIndex = lIndex;
m_bBold = bBold;
m_bItalic = bItalic;
m_bIsFixed = bFixedWidth;
if ( pPanose )
memcpy( (void*)m_aPanose, (const void *)pPanose, 10 );
else
memset( (void*)m_aPanose, 0x00, 10 );
m_ulUnicodeRange1 = ulRange1;
m_ulUnicodeRange2 = ulRange2;
m_ulUnicodeRange3 = ulRange3;
m_ulUnicodeRange4 = ulRange4;
m_ulCodePageRange1 = ulCodeRange1;
m_ulCodePageRange2 = ulCodeRange2;
m_usWeigth = usWeigth;
m_usWidth = usWidth;
m_sFamilyClass = sFamilyClass;
m_eFontFormat = eFormat;
m_shAvgCharWidth = shAvgCharWidth;
m_shAscent = shAscent;
m_shDescent = shDescent;
m_shLineGap = shLineGap;
m_shXHeight = shXHeight;
m_shCapHeight = shCapHeight;
}
virtual ~CWinFontInfo()
{
}
BOOL Equals(CWinFontInfo *pFontInfo)
{
return ( m_wsFontName == pFontInfo->m_wsFontName && m_wsStyle == pFontInfo->m_wsStyle && m_wsFontPath == pFontInfo->m_wsFontPath && m_bItalic == pFontInfo->m_bItalic && m_bBold == pFontInfo->m_bBold );
}
void WriteToXml(XmlUtils::CXmlWriter *pWriter)
{
FromXmlString( m_wsFontName );
FromXmlString( m_wsFontPath );
pWriter->WriteNodeBegin( _T("WinFontEntry"), TRUE );
pWriter->WriteAttribute( _T("name"), m_wsFontName );
pWriter->WriteAttribute( _T("bold"), (int)m_bBold );
pWriter->WriteAttribute( _T("italic"), (int)m_bItalic );
pWriter->WriteAttribute( _T("path"), m_wsFontPath );
pWriter->WriteAttribute( _T("index"), (int)m_lIndex );
pWriter->WriteNodeEnd( _T("WinFontEntry"), TRUE );
}
inline static BSTR GetAttribute(XML::IXMLDOMNamedNodeMapPtr pAttributes, _bstr_t& bsName)
{
IXMLDOMNodePtr tempNode = pAttributes->getNamedItem(bsName);
if (NULL == tempNode)
return NULL;
BSTR bsValue;
tempNode->get_text(&bsValue);
return bsValue;
}
static CWinFontInfo *FromXml(XmlUtils::CXmlNode oNode)
{
if ( _T("WinFontEntry") == oNode.GetName() )
{
XML::IXMLDOMNamedNodeMapPtr pAttributes = oNode.GetAttributes();
BSTR bsBold = GetAttribute(pAttributes, g_cpszXML_Font_Bold);
BSTR bsItalic = GetAttribute(pAttributes, g_cpszXML_Font_Italic);
BSTR bsIndex = GetAttribute(pAttributes, g_cpszXML_Font_Index);
BOOL bBold = (BOOL)XmlUtils::GetInteger(bsBold);
BOOL bItalic = (BOOL)XmlUtils::GetInteger(bsItalic);
BSTR sName = GetAttribute(pAttributes, g_cpszXML_Font_Name);
BSTR sPath = GetAttribute(pAttributes, g_cpszXML_Font_Path);
long lIndex = (long)XmlUtils::GetInteger(bsIndex);
CWinFontInfo* pInfo = new CWinFontInfo( sName, sPath, lIndex, bBold, bItalic, FALSE, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, (EFontFormat)0, 0, 0, 0, 0, 0, 0 );
SysFreeString(bsBold);
SysFreeString(bsItalic);
SysFreeString(bsIndex);
SysFreeString(sName);
SysFreeString(sPath);
return pInfo;
}
return NULL;
}
static CWinFontInfo* FromBuffer(BYTE*& pBuffer, CString strFontDir)
{
// name
LONG lLen = *((LONG*)pBuffer);
pBuffer += g_lSizeofLONG;
BSTR bsName = (BSTR)pBuffer;
pBuffer += lLen;
// path
lLen = *((LONG*)pBuffer);
pBuffer += g_lSizeofLONG;
BSTR bsPath = (BSTR)pBuffer;
pBuffer += lLen;
// index
LONG lIndex = *((LONG*)pBuffer);
pBuffer += g_lSizeofLONG;
// italic
BOOL bItalic = *((BOOL*)pBuffer);
pBuffer += g_lSizeofBOOL;
// bold
BOOL bBold = *((BOOL*)pBuffer);
pBuffer += g_lSizeofBOOL;
// FixedWidth
BOOL bFixedWidth = *((BOOL*)pBuffer);
pBuffer += g_lSizeofBOOL;
// Panose
lLen = *((LONG*)pBuffer); // должно быть равно 10
pBuffer += g_lSizeofLONG;
BYTE pPanose[10];
memcpy( (void *)pPanose, (const void *)pBuffer, 10 );
pBuffer += lLen;
// ulUnicodeRange1
ULONG ulRange1 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// ulUnicodeRange2
ULONG ulRange2 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// ulUnicodeRange3
ULONG ulRange3 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// ulUnicodeRange4
ULONG ulRange4 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// ulCodePageRange1
ULONG ulCodeRange1 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// ulCodePageRange2
ULONG ulCodeRange2 = *((ULONG*)pBuffer);
pBuffer += g_lSizeofULONG;
// usWeightClass
USHORT usWeight = *((USHORT*)pBuffer);
pBuffer += g_lSizeofUSHORT;
// usWidthClass
USHORT usWidth = *((USHORT*)pBuffer);
pBuffer += g_lSizeofUSHORT;
// sFamilyClass
SHORT sFamilyClass = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// FontFormat
SHORT sFormat = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// AvgCharWidth
SHORT shAvgCharWidth = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// Ascent
SHORT shAscent = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// Descent
SHORT shDescent = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// LineGap
SHORT shLineGap = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// XHeight
SHORT shXHeight = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
// CapHeight
SHORT shCapHeight = *((SHORT*)pBuffer);
pBuffer += g_lSizeofSHORT;
CStringW strPath = (CStringW)bsPath;
strPath = strFontDir + strPath;
bsPath = strPath.AllocSysString();
CWinFontInfo* pInfo = new CWinFontInfo( bsName, bsPath, lIndex, bBold, bItalic, bFixedWidth, (BYTE*)pPanose, ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2, usWeight, usWidth, sFamilyClass, (EFontFormat)sFormat, shAvgCharWidth, shAscent, shDescent, shLineGap, shXHeight, shCapHeight );
SysFreeString(bsPath);
return pInfo;
}
LONG GetBufferLen(CString strDirectory = _T(""))
{
CStringW sPath = m_wsFontPath;
if (0 != strDirectory.GetLength())
{
if (0 == sPath.Find(strDirectory))
{
sPath = sPath.Mid(strDirectory.GetLength());
}
}
return 4 * g_lSizeofLONG + 3 * g_lSizeofBOOL + (m_wsFontName.GetLength() + sPath.GetLength() + 2) * g_lSizeofWCHAR + 2 * g_lSizeofUSHORT + 6 * g_lSizeofULONG + 10 + 8 * g_lSizeofSHORT;
}
void ToBuffer(BYTE*& pBuffer, CString strDirectory = _T(""))
{
// name
LONG lLen = (m_wsFontName.GetLength() + 1) * g_lSizeofWCHAR;
*((LONG*)(pBuffer)) = lLen;
pBuffer += g_lSizeofLONG;
memcpy(pBuffer, m_wsFontName.GetBuffer(), lLen);
pBuffer += lLen;
// path
CStringW sPath = m_wsFontPath;
if (0 != strDirectory.GetLength())
{
if (0 == sPath.Find(strDirectory))
{
sPath = sPath.Mid(strDirectory.GetLength());
}
}
lLen = (sPath.GetLength() + 1) * g_lSizeofWCHAR;
*((LONG*)(pBuffer)) = lLen;
pBuffer += g_lSizeofLONG;
memcpy(pBuffer, sPath.GetBuffer(), lLen);
pBuffer += lLen;
// index
*((LONG*)(pBuffer)) = m_lIndex;
pBuffer += g_lSizeofLONG;
// italic
*((BOOL*)(pBuffer)) = m_bItalic;
pBuffer += g_lSizeofBOOL;
// bold
*((BOOL*)(pBuffer)) = m_bBold;
pBuffer += g_lSizeofBOOL;
// FixedWidth
*((BOOL*)pBuffer) = m_bIsFixed;
pBuffer += g_lSizeofBOOL;
// Panose
lLen = 10;
*((LONG*)(pBuffer)) = lLen;
pBuffer += g_lSizeofLONG;
memcpy( (void *)pBuffer, (const void *)m_aPanose, lLen );
pBuffer += lLen;
// ulUnicodeRange1
*((ULONG*)pBuffer) = m_ulUnicodeRange1;
pBuffer += g_lSizeofULONG;
// ulUnicodeRange2
*((ULONG*)pBuffer) = m_ulUnicodeRange2;
pBuffer += g_lSizeofULONG;
// ulUnicodeRange3
*((ULONG*)pBuffer) = m_ulUnicodeRange3;
pBuffer += g_lSizeofULONG;
// ulUnicodeRange4
*((ULONG*)pBuffer) = m_ulUnicodeRange4;
pBuffer += g_lSizeofULONG;
// ulCodePageRange1
*((ULONG*)pBuffer) = m_ulCodePageRange1;
pBuffer += g_lSizeofULONG;
// ulCodePageRange2
*((ULONG*)pBuffer) = m_ulCodePageRange2;
pBuffer += g_lSizeofULONG;
// usWeightClass
*((USHORT*)pBuffer) = m_usWeigth;
pBuffer += g_lSizeofUSHORT;
// usWidthClass
*((USHORT*)pBuffer) = m_usWidth;
pBuffer += g_lSizeofUSHORT;
// sFamilyClass
*((SHORT*)pBuffer) = m_sFamilyClass;
pBuffer += g_lSizeofSHORT;
// FontFormat
*((SHORT*)pBuffer) = (SHORT)m_eFontFormat;
pBuffer += g_lSizeofSHORT;
// AvgCharWidth
*((SHORT*)pBuffer) = (SHORT)m_shAvgCharWidth;
pBuffer += g_lSizeofSHORT;
// Ascent
*((SHORT*)pBuffer) = (SHORT)m_shAscent;
pBuffer += g_lSizeofSHORT;
// Descent
*((SHORT*)pBuffer) = (SHORT)m_shDescent;
pBuffer += g_lSizeofSHORT;
// LineGap
*((SHORT*)pBuffer) = (SHORT)m_shLineGap;
pBuffer += g_lSizeofSHORT;
// XHeight
*((SHORT*)pBuffer) = (SHORT)m_shXHeight;
pBuffer += g_lSizeofSHORT;
// CapHeight
*((SHORT*)pBuffer) = (SHORT)m_shCapHeight;
pBuffer += g_lSizeofSHORT;
}
static void FromXmlString(CString& strText)
{
strText.Replace(_T("&apos;"), _T("'"));
strText.Replace(_T("&lt;"), _T("<"));
strText.Replace(_T("&gt;"), _T(">"));
strText.Replace(_T("&quot;"), _T("\""));
strText.Replace(_T("&amp;"), _T("&"));
}
public:
CStringW m_wsFontName; // Имя шрифта
CStringW m_wsFontPath; // Путь к файлу с шрифтом
long m_lIndex; // Номер шрифта в файле(если в файле больше 1 шрифта)
CStringW m_wsStyle;
BOOL m_bBold; // Bold text
BOOL m_bItalic; // Italic text
BOOL m_bIsFixed; // Моноширинный шрифт?
BYTE m_aPanose[10];
ULONG m_ulUnicodeRange1; // Bits 0-31
ULONG m_ulUnicodeRange2; // Bits 32-63
ULONG m_ulUnicodeRange3; // Bits 64-95
ULONG m_ulUnicodeRange4; // Bits 96-127
ULONG m_ulCodePageRange1; // Bits 0-31
ULONG m_ulCodePageRange2; // Bits 32-63
USHORT m_usWeigth;
USHORT m_usWidth;
SHORT m_sFamilyClass;
EFontFormat m_eFontFormat;
SHORT m_shAvgCharWidth; // Средняя ширина символов
SHORT m_shAscent; // Ascent
SHORT m_shDescent; // Descent
SHORT m_shLineGap; // Межсимвольный интервал
SHORT m_shXHeight; // Высота буквы 'x' (в нижнем регистре)
SHORT m_shCapHeight; // Высота буквы 'H' (в верхнем регистре)
CAtlArray<CString> names;
public:
void ReadNames(FT_Face pFace)
{
TT_Face pTT_Face = (TT_Face)(pFace);
names.RemoveAll();
if (NULL != pTT_Face)
{
for (int i = 0; i < pTT_Face->utf16_len; ++i)
{
CString s(pTT_Face->utf16_names[i]);
names.Add(s);
}
}
for (int i = 0; i < (int)names.GetCount(); ++i)
{
bool bIsRemove = false;
if (names[i] == m_wsFontName)
bIsRemove = true;
if (!bIsRemove)
{
for (int j = i + 1; j < (int)names.GetCount(); ++j)
{
if (names[i] == names[j])
{
bIsRemove = true;
break;
}
}
}
if (bIsRemove)
{
names.RemoveAt(i);
--i;
}
}
}
};
//-------------------------------------------------------------------------------------------------------------------------------
// CWinFontList
//-------------------------------------------------------------------------------------------------------------------------------
class CWinFontList
{
public:
CWinFontList(FT_Library pLibrary)
{
m_lDefIndex = -1;
m_pFonts = new CList();
// Ищем директорию с фонтами (обычно это C:\Windows\Fonts)
m_wsWinFontDir[0] = '\0';
if ( !SHGetSpecialFolderPathW( NULL, m_wsWinFontDir, CSIDL_FONTS, FALSE ) )
m_wsWinFontDir[0] = '\0';
OSVERSIONINFO oVersion;
oVersion.dwOSVersionInfoSize = sizeof(oVersion);
GetVersionEx( &oVersion );
wchar_t wsPath[1000];
if ( oVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\") );
else
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\") );
TCHAR szName[2 * MAX_PATH];
TCHAR szData[2 * MAX_PATH];
while ( GetNextNameValue( HKEY_LOCAL_MACHINE, wsPath, szName, szData ) == ERROR_SUCCESS)
{
int nError = 0;
FT_Face pFace = NULL;
CStringW wsFilePath( szData );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsFilePath = CStringW( m_wsWinFontDir ) + CStringW( _T("\\") ) + CStringW( szData );
wsFilePath.Replace( _T("\0"), _T("") );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
}
// TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер
// произвольно) мы не грузим. Возможно в будущем надо будет
// сделать, чтобы работал и такой вариант. (в Word такие шрифты
// не используются)
if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) )
{
FT_Done_Face( pFace );
wsPath[0] = _T('\0');
continue;
}
int nFacesCount = pFace->num_faces;
if ( nError = FT_Done_Face( pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
for ( int nIndex = 0; nIndex < nFacesCount; nIndex++ )
{
if ( FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), nIndex, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
BOOL bBold = ( pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0 );
BOOL bItalic = pFace->style_flags & FT_STYLE_FLAG_ITALIC;
CStringW wsPostscriptName = CStringW( FT_Get_Postscript_Name( pFace ) );
//if ( wsPostscriptName.GetLength() <= 0 )
// CStringW wsPostscriptName = CStringW( (char*)pFace->family_name );
int nNamesCount = FT_Get_Sfnt_Name_Count( pFace );
for ( int nNameIndex = 0; nNameIndex < nNamesCount; nNameIndex++ )
{
FT_SfntName_ oSfntName;
FT_Get_Sfnt_Name( pFace, nNameIndex, &oSfntName );
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 1 && oSfntName.platform_id == 3 )
{
// Family
int k= 10;
}
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 16 && oSfntName.platform_id == 3 )
{
// Preffered family
int k= 10;
}
}
BOOL bFixedWidth = FT_IS_FIXED_WIDTH( pFace );
TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 );
BYTE *pPanose = NULL;
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
USHORT usWidth = 0, usWeight = 0;
SHORT sFamilyClass = 0;
SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0;
if ( NULL != pOs2 )
{
pPanose = (BYTE *)pOs2->panose;
ulRange1 = pOs2->ulUnicodeRange1;
ulRange2 = pOs2->ulUnicodeRange2;
ulRange3 = pOs2->ulUnicodeRange3;
ulRange4 = pOs2->ulUnicodeRange4;
ulCodeRange1 = pOs2->ulCodePageRange1;
ulCodeRange2 = pOs2->ulCodePageRange2;
usWeight = pOs2->usWeightClass;
usWidth = pOs2->usWidthClass;
sFamilyClass = pOs2->sFamilyClass;
if ( 0 != pFace->units_per_EM )
{
double dKoef = ( 1000 / (double)pFace->units_per_EM );
shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef);
shAscent = (SHORT)(pOs2->sTypoAscender * dKoef);
shDescent = (SHORT)(pOs2->sTypoDescender * dKoef);
shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef);
shXHeight = (SHORT)(pOs2->sxHeight * dKoef);
shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef);
}
else
{
shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth;
shAscent = (SHORT)pOs2->sTypoAscender;
shDescent = (SHORT)pOs2->sTypoDescender;
shLineGap = (SHORT)pOs2->sTypoLineGap;
shXHeight = (SHORT)pOs2->sxHeight;
shCapHeight = (SHORT)pOs2->sCapHeight;
}
}
if ( true )
{
// Специальная ветка для случаев, когда charset может быть задан не через значения
// ulCodePageRange, а непосредственно через тип Cmap.
// Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description
// -------------------------------------------------------------------------------------------------
//
// SYMBOL_CHARSET 2 (x02) 3 0 Symbol
// SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS
// GB2313_CHARSET 134 (x86) 936 3 3 PRC
// CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5
// HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung
// JOHAB_CHARSET 130 (x82) 1361 3 6 Johab
for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ )
{
// Symbol
if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x80000000;
// ShiftJIS
if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00020000;
// PRC
if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00040000;
// Big5
if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00100000;
// Wansung
if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00080000;
// Johab
if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00200000;
}
}
EFontFormat eFormat = GetFontFormat( pFace );
CWinFontInfo *pWinFontInfo = new CWinFontInfo( CStringW( (char*)pFace->family_name ), CStringW( (char*)pFace->style_name ), wsFilePath.GetBuffer(), nIndex, bBold, bItalic, bFixedWidth, pPanose, ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2, usWeight, usWidth, sFamilyClass, eFormat, shAvgCharWidth, shAscent, shDescent, shLineGap, shXHeight, shCapHeight );
pWinFontInfo->ReadNames(pFace);
Add( pWinFontInfo );
FT_Done_Face( pFace );
}
wsPath[0] = _T('\0');
}
}
CWinFontList(FT_Library pLibrary, CString sDir)
{
m_lDefIndex = -1;
m_pFonts = new CList();
m_wsWinFontDir[0] = '\0';
WIN32_FIND_DATA oFD;
CString sSpec = sDir + _T("\\*.*");
HANDLE hRes = FindFirstFile( sSpec, &oFD );
if( INVALID_HANDLE_VALUE == hRes )
return;
do
{
sSpec = oFD.cFileName;
if( sSpec != _T(".") && sSpec != _T("..") )
{
sSpec = sDir + _T("\\") + sSpec;
if( !( oFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
{
int nError = 0;
FT_Face pFace = NULL;
CStringW wsFilePath = sSpec;
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
continue;
// TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер
// произвольно) мы не грузим. Возможно в будущем надо будет
// сделать, чтобы работал и такой вариант. (в Word такие шрифты
// не используются)
if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) )
{
FT_Done_Face( pFace );
continue;
}
int nFacesCount = pFace->num_faces;
if ( nError = FT_Done_Face( pFace ) )
{
continue;
}
for ( int nIndex = 0; nIndex < nFacesCount; nIndex++ )
{
if (_T("\\\\mediaserver\\Exchange\\Korshul\\Fonts\\kaiu.ttf") == wsFilePath)
{
int y = 0;
y++;
}
if (_T("\\\\mediaserver\\Exchange\\Korshul\\Fonts\\DejaVuSans-BoldOblique.ttf") == wsFilePath)
{
int y = 0;
y++;
}
if ( FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), nIndex, &pFace ) )
{
continue;
}
BOOL bBold = ( pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0 );
BOOL bItalic = pFace->style_flags & FT_STYLE_FLAG_ITALIC;
CStringW wsPostscriptName = CStringW( FT_Get_Postscript_Name( pFace ) );
//if ( wsPostscriptName.GetLength() <= 0 )
// CStringW wsPostscriptName = CStringW( (char*)pFace->family_name );
int nNamesCount = FT_Get_Sfnt_Name_Count( pFace );
for ( int nNameIndex = 0; nNameIndex < nNamesCount; nNameIndex++ )
{
FT_SfntName_ oSfntName;
FT_Get_Sfnt_Name( pFace, nNameIndex, &oSfntName );
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 1 && oSfntName.platform_id == 3 )
{
// Family
int k= 10;
}
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 16 && oSfntName.platform_id == 3 )
{
// Preffered family
int k= 10;
}
}
BOOL bFixedWidth = FT_IS_FIXED_WIDTH( pFace );
TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 );
BYTE *pPanose = NULL;
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
USHORT usWidth = 0, usWeight = 0;
SHORT sFamilyClass = 0;
SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0;
if ( NULL != pOs2 )
{
pPanose = (BYTE *)pOs2->panose;
ulRange1 = pOs2->ulUnicodeRange1;
ulRange2 = pOs2->ulUnicodeRange2;
ulRange3 = pOs2->ulUnicodeRange3;
ulRange4 = pOs2->ulUnicodeRange4;
ulCodeRange1 = pOs2->ulCodePageRange1;
ulCodeRange2 = pOs2->ulCodePageRange2;
usWeight = pOs2->usWeightClass;
usWidth = pOs2->usWidthClass;
sFamilyClass = pOs2->sFamilyClass;
if ( 0 != pFace->units_per_EM )
{
double dKoef = ( 1000 / (double)pFace->units_per_EM );
shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef);
shAscent = (SHORT)(pOs2->sTypoAscender * dKoef);
shDescent = (SHORT)(pOs2->sTypoDescender * dKoef);
shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef);
shXHeight = (SHORT)(pOs2->sxHeight * dKoef);
shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef);
}
else
{
shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth;
shAscent = (SHORT)pOs2->sTypoAscender;
shDescent = (SHORT)pOs2->sTypoDescender;
shLineGap = (SHORT)pOs2->sTypoLineGap;
shXHeight = (SHORT)pOs2->sxHeight;
shCapHeight = (SHORT)pOs2->sCapHeight;
}
}
if ( true )
{
// Специальная ветка для случаев, когда charset может быть задан не через значения
// ulCodePageRange, а непосредственно через тип Cmap.
// Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description
// -------------------------------------------------------------------------------------------------
//
// SYMBOL_CHARSET 2 (x02) 3 0 Symbol
// SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS
// GB2313_CHARSET 134 (x86) 936 3 3 PRC
// CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5
// HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung
// JOHAB_CHARSET 130 (x82) 1361 3 6 Johab
for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ )
{
// Symbol
if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x80000000;
// ShiftJIS
if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00020000;
// PRC
if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00040000;
// Big5
if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00100000;
// Wansung
if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00080000;
// Johab
if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id )
ulCodeRange1 |= 0x00200000;
}
}
EFontFormat eFormat = GetFontFormat( pFace );
CWinFontInfo *pWinFontInfo = new CWinFontInfo( CStringW( (char*)pFace->family_name ), CStringW( (char*)pFace->style_name ), wsFilePath.GetBuffer(), nIndex, bBold, bItalic, bFixedWidth, pPanose, ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2, usWeight, usWidth, sFamilyClass, eFormat, shAvgCharWidth, shAscent, shDescent, shLineGap, shXHeight, shCapHeight );
pWinFontInfo->ReadNames(pFace);
Add( pWinFontInfo );
FT_Done_Face( pFace );
}
}
}
} while( FindNextFile( hRes, &oFD ) );
FindClose( hRes );
}
CWinFontList(CString sWinFontsXml)
{
m_lDefIndex = -1;
m_pFonts = new CList();
m_wsWinFontDir[0] = '\0';
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlString( sWinFontsXml );
if ( _T("WinFontList") == oMainNode.GetName() )
{
XmlUtils::CXmlNodes oFonts;
oMainNode.GetNodes( _T("WinFontEntry"), oFonts );
for ( int nIndex = 0; nIndex < oFonts.GetCount(); nIndex++ )
{
XmlUtils::CXmlNode oFontNode;
if ( oFonts.GetAt( nIndex, oFontNode ) )
{
CWinFontInfo *pWinFontInfo = CWinFontInfo::FromXml( oFontNode );
if ( NULL != pWinFontInfo )
Add( pWinFontInfo );
}
}
}
}
CWinFontList(BYTE* pBuffer, CString sFontDir)
{
m_lDefIndex = -1;
m_pFonts = new CList();
m_wsWinFontDir[0] = '\0';
LONG lCount = *((LONG*)pBuffer);
pBuffer += g_lSizeofLONG;
for (LONG nIndex = 0; nIndex < lCount; ++nIndex)
{
CWinFontInfo *pWinFontInfo = CWinFontInfo::FromBuffer( pBuffer, sFontDir );
Add(pWinFontInfo);
}
}
~CWinFontList()
{
DeleteCList( m_pFonts, CWinFontInfo );
}
CList *GetFonts()
{
return m_pFonts;
}
CWinFontInfo *GetByIndex(int nIndex)
{
return (CWinFontInfo *)m_pFonts->GetByIndex( nIndex );
}
CWinFontInfo *GetByParams(const CString& sParamsXml)
{
if ( m_pFonts->GetLength() <= 0 )
return NULL;
//********************************************
/*
CString sXml = _T("<FontProperties>\
<Name value='Tahoma'/>\
<AltName value='Helvetica'/>\
<Charset value='EE'/>\
<FamilyClass name='swiss'/>\
<Style bold='1' italic='0'/>\
<FixedWidth value='0'/>\
<Panose value='001F2A3B4C5D6F738491'/>\
<UnicodeRange range1='F7FFAFFF' range2='E9DFFFFF' range3='0000003F' range4='00000000' coderange1='003F01FF' coderange2='00000000'/>\
<Weight value='550'/>\
<Width value='1000'/>\
<FontFormat value='1'/>\
<AvgCharWidth value='267'/>\
<Ascent value='850'/>\
<Descent value='-109'/>\
<LineGap value='217'/>\
<xHeight value='745'/>\
<CapHeight value='848'/>\
</FontProperties>");
*/
//********************************************
CString wsFamilyName, wsFamilyClass, wsAltName;
unsigned char unCharset = 0;
BOOL bBold = FALSE, bItalic = FALSE, bFixedWidth = FALSE;
BYTE pPanose[10];
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
USHORT usWeight = 0, usWidth = 0;
SHORT sFamilyClass = 0;
EFontFormat eFontFormat = fontTrueType;
SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0;
BOOL bIsName = FALSE, bIsAltName = FALSE, bIsStyle = FALSE, bIsFixed = FALSE, bIsPanose = FALSE, bIsRanges = FALSE, bIsWeight = FALSE, bIsWidth = FALSE, bIsFamilyClass = FALSE;
BOOL bIsAvgWidth = FALSE, bIsAscent = FALSE, bIsDescent = FALSE, bIsLineGap = FALSE, bIsXHeight = FALSE, bIsCapHeight = FALSE;
// Считываем настройки шрифта
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlString( sParamsXml );
if ( _T("FontProperties") == oMainNode.GetName() )
{
XmlUtils::CXmlNode oNode;
if ( oMainNode.GetNode( _T("Name"), oNode ) )
{
bIsName = TRUE;
wsFamilyName = oNode.GetAttribute( _T("value") );
}
if ( oMainNode.GetNode( _T("AltName"), oNode ) )
{
bIsAltName = TRUE;
wsAltName = oNode.GetAttribute( _T("value") );
if ( wsAltName.GetLength() <= 0 )
bIsAltName = FALSE;
}
if ( oMainNode.GetNode( _T("Style"), oNode ) )
{
bIsStyle = TRUE;
bBold = (BOOL)XmlUtils::GetInteger( oNode.GetAttribute( _T("bold") ) );
bItalic = (BOOL)XmlUtils::GetInteger( oNode.GetAttribute( _T("italic") ) );
}
if ( oMainNode.GetNode( _T("FixedWidth"), oNode ) )
{
bIsFixed = TRUE;
bFixedWidth = (BOOL)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("Panose"), oNode ) )
{
CString sValue = oNode.GetAttribute( _T("value") );
if ( 20 == sValue.GetLength() )
{
for ( int nIndex = 0; nIndex < 10; nIndex++ )
{
int nChar1 = sValue.GetAt( nIndex * 2 );
int nChar2 = sValue.GetAt( nIndex * 2 + 1 );
unsigned char unValue = ((unsigned char)( HexToInt( nChar1 ) << 4 )) | HexToInt( nChar2 );
pPanose[nIndex] = unValue;
// Если хоть одно значение не 0, то используем Panose
if ( 0 != unValue )
bIsPanose = TRUE;
}
}
}
if ( oMainNode.GetNode( _T("UnicodeRange"), oNode ) )
{
ulRange1 = (ULONG)HexToInt( oNode.GetAttribute( _T("range1") ) );
ulRange2 = (ULONG)HexToInt( oNode.GetAttribute( _T("range2") ) );
ulRange3 = (ULONG)HexToInt( oNode.GetAttribute( _T("range3") ) );
ulRange4 = (ULONG)HexToInt( oNode.GetAttribute( _T("range4") ) );
ulCodeRange1 = (ULONG)HexToInt( oNode.GetAttribute( _T("coderange1") ) );
ulCodeRange2 = (ULONG)HexToInt( oNode.GetAttribute( _T("coderange2") ) );
if ( !( 0 == ulRange1 && 0 == ulRange2 && 0 == ulRange3 && 0 == ulRange4 && 0 == ulCodeRange1 && 0 == ulCodeRange2 ) )
bIsRanges = TRUE;
}
if ( oMainNode.GetNode( _T("Weight"), oNode ) )
{
usWeight = (USHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
if ( 0 != usWeight )
bIsWeight = TRUE;
}
if ( oMainNode.GetNode( _T("Width"), oNode ) )
{
bIsWidth = TRUE;
usWidth = (USHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("FamilyClass"), oNode ) )
{
bIsFamilyClass = TRUE;
wsFamilyClass = oNode.GetAttribute( _T("type"), _T("") );
sFamilyClass = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("FontFormat"), oNode ) )
{
// Формат мы всегда сравниваем
eFontFormat = (EFontFormat)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("Charset"), oNode ) )
{
// Если charset не задан, то считаем его нулевым (Cp-1252)
unCharset = (unsigned char)HexToInt( oNode.GetAttribute( _T("value") ) );
}
else
unCharset = UNKNOWN_CHARSET;
if ( oMainNode.GetNode( _T("AvgCharWidth"), oNode ) )
{
bIsAvgWidth = TRUE;
shAvgCharWidth = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("Ascent"), oNode ) )
{
bIsAscent = TRUE;
shAscent = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("Descent"), oNode ) )
{
bIsDescent = TRUE;
shDescent = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("LineGap"), oNode ) )
{
bIsLineGap = TRUE;
shLineGap = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("xHeight"), oNode ) )
{
bIsXHeight = TRUE;
shXHeight = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
if ( oMainNode.GetNode( _T("CapHeight"), oNode ) )
{
bIsCapHeight = TRUE;
shCapHeight = (SHORT)XmlUtils::GetInteger( oNode.GetAttribute( _T("value") ) );
}
}
int nMinIndex = 0; // Номер шрифта в списке с минимальным весом
int nMinPenalty = 0; // Минимальный вес
int nDefPenalty = INT_MAX;
for ( int nIndex = 0; nIndex < m_pFonts->GetLength(); nIndex++ )
{
int nCurPenalty = 0;
CWinFontInfo *pInfo = (CWinFontInfo *)m_pFonts->GetByIndex( nIndex );
if ( bIsPanose )
{
nCurPenalty += GetPanosePenalty( pInfo->m_aPanose, pPanose );
}
ULONG arrCandRanges[6] = { pInfo->m_ulUnicodeRange1, pInfo->m_ulUnicodeRange2, pInfo->m_ulUnicodeRange3, pInfo->m_ulUnicodeRange4, pInfo->m_ulCodePageRange1, pInfo->m_ulCodePageRange2 };
//if ( bIsRanges )
//{
// ULONG arrReqRanges[6] = { ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2 };
// nCurPenalty += GetSigPenalty( arrCandRanges, arrReqRanges );
//}
if ( bIsFixed )
nCurPenalty += GetFixedPitchPenalty( pInfo->m_bIsFixed, bFixedWidth );
if ( bIsAltName && bIsName )
{
nCurPenalty += min( GetFaceNamePenalty( pInfo->m_wsFontName, wsFamilyName ), GetFaceNamePenalty( pInfo->m_wsFontName, wsAltName ) );
}
else if ( bIsName )
nCurPenalty += GetFaceNamePenalty( pInfo->m_wsFontName, wsFamilyName );
else if ( bIsAltName )
nCurPenalty += GetFaceNamePenalty( pInfo->m_wsFontName, wsAltName );
if ( bIsWidth )
nCurPenalty += GetWidthPenalty( pInfo->m_usWidth, usWidth );
if ( bIsWeight )
nCurPenalty += GetWeightPenalty( pInfo->m_usWeigth, usWeight );
if ( bIsStyle )
{
nCurPenalty += GetItalicPenalty( pInfo->m_bItalic, bItalic );
nCurPenalty += GetBoldPenalty( pInfo->m_bBold, bBold );
}
if ( bIsFamilyClass )
{
if ( _T("") != wsFamilyClass )
nCurPenalty += GetFamilyUnlikelyPenalty( pInfo->m_sFamilyClass, wsFamilyClass );
else
nCurPenalty += GetFamilyUnlikelyPenalty( pInfo->m_sFamilyClass, sFamilyClass );
}
nCurPenalty += GetFontFormatPenalty( pInfo->m_eFontFormat, eFontFormat );
nCurPenalty += GetCharsetPenalty( arrCandRanges, unCharset );
if ( bIsAvgWidth )
nCurPenalty += GetAvgWidthPenalty( pInfo->m_shAvgCharWidth, shAvgCharWidth );
if ( bIsAscent )
nCurPenalty += GetAscentPenalty( pInfo->m_shAscent, shAscent );
if ( bIsDescent )
nCurPenalty += GetDescentPenalty( pInfo->m_shDescent, shDescent );
if ( bIsLineGap )
nCurPenalty += GetLineGapPenalty( pInfo->m_shLineGap, shLineGap );
if ( bIsXHeight )
nCurPenalty += GetXHeightPenalty( pInfo->m_shXHeight, shXHeight );
if ( bIsCapHeight )
nCurPenalty += GetCapHeightPenalty( pInfo->m_shCapHeight, shCapHeight );
if ( 0 == nIndex )
{
nMinIndex = 0;
nMinPenalty = nCurPenalty;
}
else if ( nCurPenalty < nMinPenalty )
{
nMinIndex = nIndex;
nMinPenalty = nCurPenalty;
}
if ( -1 != m_lDefIndex && nIndex == m_lDefIndex )
{
nDefPenalty = nCurPenalty;
}
// Нашелся шрифт, удовлетворяющий всем параметрам, дальше искать нет смысла
if ( 0 == nCurPenalty )
break;
}
if ( -1 != m_lDefIndex && nDefPenalty == nMinPenalty )
nMinIndex = m_lDefIndex;
return (CWinFontInfo *)m_pFonts->GetByIndex( nMinIndex );
}
CWinFontInfo *GetByParams(wchar_t* wsAltFontName, long lCharset, wchar_t* wsFamily, long lStyle, long lFixed, wchar_t *wsPanose, long lUnicodeRange1, long lUnicodeRange2, long lUnicodeRange3, long lUnicodeRange4, long lCodePageRange1, long lCodePageRange2, long lAvgWidth)
{
if ( m_pFonts->GetLength() <= 0 )
return NULL;
CString wsFamilyName, wsFamilyClass;
unsigned char unCharset = 0;
BOOL bBold = FALSE, bItalic = FALSE, bFixedWidth = FALSE;
BYTE pPanose[10];
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
SHORT shAvgCharWidth = 0;
BOOL bIsName = FALSE, bIsStyle = FALSE, bIsFixed = FALSE, bIsPanose = FALSE, bIsRanges = FALSE, bIsFamilyClass = FALSE, bIsAvgWidth = FALSE;
if ( NULL != wsAltFontName )
{
bIsName = TRUE;
wsFamilyName = CString( wsAltFontName );
}
if ( lStyle >= 0 )
{
bIsStyle = TRUE;
bBold = (lStyle & FontConstants::FontStyleBold ? TRUE : FALSE);
bItalic = (lStyle & FontConstants::FontStyleItalic ? TRUE : FALSE);
}
if ( lFixed >= 0 )
{
bIsFixed = TRUE;
bFixedWidth = ( lFixed > 0 ? TRUE : FALSE );
}
if ( NULL != wsPanose )
{
if ( 20 == wcslen( wsPanose ) )
{
for ( int nIndex = 0; nIndex < 10; nIndex++ )
{
int nChar1 = wsPanose[nIndex * 2 ];
int nChar2 = wsPanose[nIndex * 2 + 1 ];
unsigned char unValue = ((unsigned char)( HexToInt( nChar1 ) << 4 )) | HexToInt( nChar2 );
pPanose[nIndex] = unValue;
// Если хоть одно значение не 0, то используем Panose
if ( 0 != unValue )
bIsPanose = TRUE;
}
}
}
ulRange1 = (ULONG)lUnicodeRange1;
ulRange2 = (ULONG)lUnicodeRange2;
ulRange3 = (ULONG)lUnicodeRange3;
ulRange4 = (ULONG)lUnicodeRange4;
ulCodeRange1 = (ULONG)lCodePageRange1;
ulCodeRange2 = (ULONG)lCodePageRange2;
if ( !( 0 == ulRange1 && 0 == ulRange2 && 0 == ulRange3 && 0 == ulRange4 && 0 == ulCodeRange1 && 0 == ulCodeRange2 ) )
bIsRanges = TRUE;
if ( NULL != wsFamily )
{
bIsFamilyClass = TRUE;
wsFamilyClass = CString(wsFamily);
}
if ( lCharset >= 0 )
unCharset = (unsigned char)lCharset;
else
unCharset = UNKNOWN_CHARSET;
if ( lAvgWidth >= 0 )
{
bIsAvgWidth = TRUE;
shAvgCharWidth = (SHORT)lAvgWidth;
}
int nMinIndex = 0; // Номер шрифта в списке с минимальным весом
int nMinPenalty = 0; // Минимальный вес
int nDefPenalty = 0;
for ( int nIndex = 0; nIndex < m_pFonts->GetLength(); nIndex++ )
{
int nCurPenalty = 0;
CWinFontInfo *pInfo = (CWinFontInfo *)m_pFonts->GetByIndex( nIndex );
if ( bIsPanose )
{
nCurPenalty += GetPanosePenalty( pInfo->m_aPanose, pPanose );
}
ULONG arrCandRanges[6] = { pInfo->m_ulUnicodeRange1, pInfo->m_ulUnicodeRange2, pInfo->m_ulUnicodeRange3, pInfo->m_ulUnicodeRange4, pInfo->m_ulCodePageRange1, pInfo->m_ulCodePageRange2 };
if ( bIsRanges )
{
ULONG arrReqRanges[6] = { ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2 };
nCurPenalty += GetSigPenalty( arrCandRanges, arrReqRanges, 10000 );
}
if ( bIsFixed )
nCurPenalty += GetFixedPitchPenalty( pInfo->m_bIsFixed, bFixedWidth );
if ( bIsName )
nCurPenalty += GetFaceNamePenalty( pInfo->m_wsFontName, wsFamilyName );
if ( bIsStyle )
{
nCurPenalty += GetItalicPenalty( pInfo->m_bItalic, bItalic );
nCurPenalty += GetBoldPenalty( pInfo->m_bBold, bBold );
}
if ( bIsFamilyClass )
nCurPenalty += GetFamilyUnlikelyPenalty( pInfo->m_sFamilyClass, wsFamilyClass );
nCurPenalty += GetCharsetPenalty( arrCandRanges, unCharset );
if ( bIsAvgWidth )
nCurPenalty += GetAvgWidthPenalty( pInfo->m_shAvgCharWidth, shAvgCharWidth );
if ( 0 == nIndex )
{
nMinIndex = 0;
nMinPenalty = nCurPenalty;
}
else if ( nCurPenalty < nMinPenalty )
{
nMinIndex = nIndex;
nMinPenalty = nCurPenalty;
}
if ( -1 != m_lDefIndex && nIndex == m_lDefIndex )
{
nDefPenalty = nCurPenalty;
}
// Нашелся шрифт, удовлетворяющий всем параметрам, дальше искать нет смысла
if ( 0 == nCurPenalty )
break;
}
if ( -1 != m_lDefIndex && nDefPenalty == nMinPenalty )
nMinIndex = m_lDefIndex;
return (CWinFontInfo *)m_pFonts->GetByIndex( nMinIndex );
}
void SetDefaultFont(long lIndex)
{
if ( lIndex >= 0 && lIndex < m_pFonts->GetLength() )
m_lDefIndex = lIndex;
}
static CString GetWinFontsXml(FT_Library pLibrary)
{
XmlUtils::CXmlWriter oWriter;
oWriter.WriteNodeBegin( _T("WinFontList") );
// Ищем директорию с фонтами (обычно это C:\Windows\Fonts)
wchar_t wsWinFontDir[MAX_PATH];
wsWinFontDir[0] = '\0';
if ( !SHGetSpecialFolderPathW( NULL, wsWinFontDir, CSIDL_FONTS, FALSE ) )
wsWinFontDir[0] = '\0';
OSVERSIONINFO oVersion;
oVersion.dwOSVersionInfoSize = sizeof(oVersion);
GetVersionEx( &oVersion );
wchar_t wsPath[1000];
if ( oVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\") );
else
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\") );
TCHAR szName[2 * MAX_PATH];
TCHAR szData[2 * MAX_PATH];
while ( GetNextNameValue( HKEY_LOCAL_MACHINE, wsPath, szName, szData ) == ERROR_SUCCESS)
{
int nError = 0;
FT_Face pFace = NULL;
CStringW wsFilePath( szData );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsFilePath = CStringW( wsWinFontDir ) + CStringW( _T("\\") ) + CStringW( szData );
wsFilePath.Replace( _T("\0"), _T("") );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
}
// TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер
// произвольно) мы не грузим. Возможно в будущем надо будет
// сделать, чтобы работал и такой вариант. (в Word такие шрифты
// не используются)
if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) )
{
FT_Done_Face( pFace );
wsPath[0] = _T('\0');
continue;
}
int nFacesCount = pFace->num_faces;
if ( nError = FT_Done_Face( pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
for ( int nIndex = 0; nIndex < nFacesCount; nIndex++ )
{
if ( FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), nIndex, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
BOOL bBold = ( pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0 );
BOOL bItalic = pFace->style_flags & FT_STYLE_FLAG_ITALIC;
CStringW wsPostscriptName = CStringW( FT_Get_Postscript_Name( pFace ) );
//if ( wsPostscriptName.GetLength() <= 0 )
// CStringW wsPostscriptName = CStringW( (char*)pFace->family_name );
int nNamesCount = FT_Get_Sfnt_Name_Count( pFace );
for ( int nNameIndex = 0; nNameIndex < nNamesCount; nNameIndex++ )
{
FT_SfntName_ oSfntName;
FT_Get_Sfnt_Name( pFace, nNameIndex, &oSfntName );
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 1 && oSfntName.platform_id == 3 )
{
// Family
int k= 10;
}
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 16 && oSfntName.platform_id == 3 )
{
// Preffered family
int k= 10;
}
}
BOOL bFixedWidth = FT_IS_FIXED_WIDTH( pFace );
TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 );
BYTE *pPanose = NULL;
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
USHORT usWidth = 0, usWeight = 0;
SHORT sFamilyClass = 0;
SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0;
if ( NULL != pOs2 )
{
pPanose = (BYTE *)pOs2->panose;
ulRange1 = pOs2->ulUnicodeRange1;
ulRange2 = pOs2->ulUnicodeRange2;
ulRange3 = pOs2->ulUnicodeRange3;
ulRange4 = pOs2->ulUnicodeRange4;
ulCodeRange1 = pOs2->ulCodePageRange1;
ulCodeRange2 = pOs2->ulCodePageRange2;
usWeight = pOs2->usWeightClass;
usWidth = pOs2->usWidthClass;
sFamilyClass = pOs2->sFamilyClass;
if ( 0 != pFace->units_per_EM )
{
double dKoef = ( 1000 / (double)pFace->units_per_EM );
shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef);
shAscent = (SHORT)(pOs2->sTypoAscender * dKoef);
shDescent = (SHORT)(pOs2->sTypoDescender * dKoef);
shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef);
shXHeight = (SHORT)(pOs2->sxHeight * dKoef);
shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef);
}
else
{
shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth;
shAscent = (SHORT)pOs2->sTypoAscender;
shDescent = (SHORT)pOs2->sTypoDescender;
shLineGap = (SHORT)pOs2->sTypoLineGap;
shXHeight = (SHORT)pOs2->sxHeight;
shCapHeight = (SHORT)pOs2->sCapHeight;
}
}
EFontFormat eFormat = GetFontFormat( pFace );
CWinFontInfo oWinFontInfo( CStringW( (char*)pFace->family_name ), CStringW( (char*)pFace->style_name ), wsFilePath.GetBuffer(), nIndex, bBold, bItalic, bFixedWidth, pPanose, ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2, usWeight, usWidth, sFamilyClass, eFormat, shAvgCharWidth, shAscent, shDescent, shLineGap, shXHeight, shCapHeight );
oWinFontInfo.WriteToXml( &oWriter );
FT_Done_Face( pFace );
}
wsPath[0] = _T('\0');
}
oWriter.WriteNodeEnd( _T("WinFontList") );
return oWriter.GetXmlString();
}
static BYTE* GetWinFontsData(FT_Library pLibrary, LONG& lDataSize)
{
// Ищем директорию с фонтами (обычно это C:\Windows\Fonts)
wchar_t wsWinFontDir[MAX_PATH];
CAtlArray<CWinFontInfo*> arrInfos;
wsWinFontDir[0] = '\0';
if ( !SHGetSpecialFolderPathW( NULL, wsWinFontDir, CSIDL_FONTS, FALSE ) )
wsWinFontDir[0] = '\0';
OSVERSIONINFO oVersion;
oVersion.dwOSVersionInfoSize = sizeof(oVersion);
GetVersionEx( &oVersion );
wchar_t wsPath[1000];
if ( oVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\") );
else
_tcscpy_s( wsPath, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\") );
TCHAR szName[2 * MAX_PATH];
TCHAR szData[2 * MAX_PATH];
while ( GetNextNameValue( HKEY_LOCAL_MACHINE, wsPath, szName, szData ) == ERROR_SUCCESS)
{
int nError = 0;
FT_Face pFace = NULL;
CStringW wsFilePath( szData );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsFilePath = CStringW( wsWinFontDir ) + CStringW( _T("\\") ) + CStringW( szData );
wsFilePath.Replace( _T("\0"), _T("") );
if ( nError = FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), 0, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
}
// TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер
// произвольно) мы не грузим. Возможно в будущем надо будет
// сделать, чтобы работал и такой вариант. (в Word такие шрифты
// не используются)
if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) )
{
FT_Done_Face( pFace );
wsPath[0] = _T('\0');
continue;
}
int nFacesCount = pFace->num_faces;
if ( nError = FT_Done_Face( pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
for ( int nIndex = 0; nIndex < nFacesCount; nIndex++ )
{
if ( FT_New_FaceW( pLibrary, wsFilePath.GetBuffer(), nIndex, &pFace ) )
{
wsPath[0] = _T('\0');
continue;
}
BOOL bBold = ( pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0 );
BOOL bItalic = pFace->style_flags & FT_STYLE_FLAG_ITALIC;
CStringW wsPostscriptName = CStringW( FT_Get_Postscript_Name( pFace ) );
//if ( wsPostscriptName.GetLength() <= 0 )
// CStringW wsPostscriptName = CStringW( (char*)pFace->family_name );
int nNamesCount = FT_Get_Sfnt_Name_Count( pFace );
for ( int nNameIndex = 0; nNameIndex < nNamesCount; nNameIndex++ )
{
FT_SfntName_ oSfntName;
FT_Get_Sfnt_Name( pFace, nNameIndex, &oSfntName );
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 1 && oSfntName.platform_id == 3 )
{
// Family
int k= 10;
}
if ( oSfntName.language_id == 0x0409 && oSfntName.name_id == 16 && oSfntName.platform_id == 3 )
{
// Preffered family
int k= 10;
}
}
BOOL bFixedWidth = FT_IS_FIXED_WIDTH( pFace );
TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 );
BYTE *pPanose = NULL;
ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0;
USHORT usWidth = 0, usWeight = 0;
SHORT sFamilyClass = 0;
SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0;
if ( NULL != pOs2 )
{
pPanose = (BYTE *)pOs2->panose;
ulRange1 = pOs2->ulUnicodeRange1;
ulRange2 = pOs2->ulUnicodeRange2;
ulRange3 = pOs2->ulUnicodeRange3;
ulRange4 = pOs2->ulUnicodeRange4;
ulCodeRange1 = pOs2->ulCodePageRange1;
ulCodeRange2 = pOs2->ulCodePageRange2;
usWeight = pOs2->usWeightClass;
usWidth = pOs2->usWidthClass;
sFamilyClass = pOs2->sFamilyClass;
if ( 0 != pFace->units_per_EM )
{
double dKoef = ( 1000 / (double)pFace->units_per_EM );
shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef);
shAscent = (SHORT)(pOs2->sTypoAscender * dKoef);
shDescent = (SHORT)(pOs2->sTypoDescender * dKoef);
shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef);
shXHeight = (SHORT)(pOs2->sxHeight * dKoef);
shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef);
}
else
{
shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth;
shAscent = (SHORT)pOs2->sTypoAscender;
shDescent = (SHORT)pOs2->sTypoDescender;
shLineGap = (SHORT)pOs2->sTypoLineGap;
shXHeight = (SHORT)pOs2->sxHeight;
shCapHeight = (SHORT)pOs2->sCapHeight;
}
}
EFontFormat eFormat = GetFontFormat( pFace );
CWinFontInfo* __pInfo = new CWinFontInfo( CStringW( (char*)pFace->family_name ), CStringW( (char*)pFace->style_name ), wsFilePath.GetBuffer(), nIndex, bBold, bItalic, bFixedWidth, pPanose, ulRange1, ulRange2, ulRange3, ulRange4, ulCodeRange1, ulCodeRange2, usWeight, usWidth, sFamilyClass, eFormat, shAvgCharWidth, shAscent, shDescent, shLineGap, shXHeight, shCapHeight );
arrInfos.Add(__pInfo);
FT_Done_Face( pFace );
}
wsPath[0] = _T('\0');
}
lDataSize = g_lSizeofLONG;
for (size_t i = 0; i < arrInfos.GetCount(); ++i)
{
lDataSize += arrInfos[i]->GetBufferLen();
}
BYTE* pData = new BYTE[lDataSize];
BYTE* pDataMem = pData;
*(LONG*)pDataMem = (LONG)arrInfos.GetCount();
pDataMem += g_lSizeofLONG;
for (size_t i = 0; i < arrInfos.GetCount(); ++i)
{
CWinFontInfo* pInfo = arrInfos[i];
pInfo->ToBuffer(pDataMem);
delete pInfo;
}
arrInfos.RemoveAll();
return pData;
}
void ToBuffer(BYTE** pDstData, LONG* pLen, CString strDirectory = _T(""))
{
LONG lDataSize = g_lSizeofLONG;
size_t nFontsCount = (size_t)m_pFonts->GetLength();
for (size_t i = 0; i < nFontsCount; ++i)
{
lDataSize += ((CWinFontInfo*)(m_pFonts->GetByIndex((int)i)))->GetBufferLen(strDirectory);
}
BYTE* pData = new BYTE[lDataSize];
BYTE* pDataMem = pData;
*(LONG*)pDataMem = (LONG)m_pFonts->GetLength();
pDataMem += g_lSizeofLONG;
for (size_t i = 0; i < nFontsCount; ++i)
{
CWinFontInfo* pInfo = ((CWinFontInfo*)(m_pFonts->GetByIndex((int)i)));
pInfo->ToBuffer(pDataMem, strDirectory);
}
*pDstData = pData;
*pLen = lDataSize;
}
static EFontFormat GetFontFormat(FT_Face pFace)
{
CString wsFormat( FT_Get_X11_Font_Format( pFace ) );
if ( _T("Windows FNT") == wsFormat )
return fontWindowsFNT;
else if ( _T("TrueType") == wsFormat )
return fontTrueType;
else if ( _T("CFF") == wsFormat )
return fontOpenType;
return fontUnknown;
}
private:
void Add(CWinFontInfo *pFontInfo)
{
for ( int nIndex = 0; nIndex < m_pFonts->GetLength(); ++nIndex )
{
if ( ((CWinFontInfo *)m_pFonts->GetByIndex(nIndex))->Equals( pFontInfo ) )
{
if ( pFontInfo )
delete pFontInfo;
return;
}
}
m_pFonts->Append( pFontInfo );
}
unsigned char HexToInt(int nHex)
{
if ( nHex >= '0' && nHex <= '9' ) return (unsigned char)(nHex - '0');
if ( nHex >= 'a' && nHex <= 'f' ) return (unsigned char)(nHex - 'a' + 10);
if ( nHex >= 'A' && nHex <= 'F' ) return (unsigned char)(nHex - 'A' + 10);
return 0;
}
__int64 HexToInt(CString sHex)
{
__int64 nResult = 0;
__int64 nMult = 1;
for ( int nIndex = sHex.GetLength() - 1; nIndex >= 0; nIndex-- )
{
nResult += HexToInt( sHex.GetAt( nIndex ) ) * nMult;
nMult <<= 4;
}
return nResult;
}
int GetCharsetPenalty(ULONG ulCandRanges[6], unsigned char unReqCharset)
{
// Penalty = 65000 (это самый весомый параметр)
if ( UNKNOWN_CHARSET == unReqCharset )
return 0;
unsigned long ulBit = 0;
unsigned int unLongIndex = 0;
GetCodePageByCharset( unReqCharset, &ulBit, &unLongIndex );
int nMult = 1;
for ( int nIndex = 0; nIndex < (int)ulBit; nIndex++ )
nMult <<= 1;
if ( !(ulCandRanges[unLongIndex] & nMult) )
return 65000;
return 0;
}
int GetSigPenalty(ULONG ulCandRanges[6], ULONG ulReqRanges[6], double dRangeWeight = 1, bool bPenaltyForSuperflouous = false)
{
double dPenalty = 0;
// Для начала просматриваем сколько вообще различных пространств надо.
// Исходя из их общего количества, находим вес 1 пропущеного пространства.
unsigned char arrCandidate[192], arrRequest[192];
memset( arrCandidate, 0x00, 192 );
memset( arrRequest, 0x00, 192 );
int nRangesCount = 0; // Количество необходимых пространств
int nAddCount = 0; // количество дополнительных(ненужных) пространств у кандидата
for ( int nIndex = 0; nIndex < 6; nIndex++ )
{
for ( unsigned long nBitCount = 0, nBit = 1; nBitCount < 32; nBitCount++, nBit *= 2 )
{
BOOL bReqAdd = FALSE;
if ( ulReqRanges[nIndex] & nBit )
{
arrRequest[ nIndex * 32 + nBitCount ] = 1;
nRangesCount++;
bReqAdd = TRUE;
}
if ( ulCandRanges[nIndex] & nBit )
{
arrCandidate[ nIndex * 32 + nBitCount ] = 1;
if ( !bReqAdd )
nAddCount++;
}
}
}
if ( 0 == nRangesCount )
return 0;
//double dRangeWeight = 1;//1000.0 / nRangesCount;
for ( int nIndex = 0; nIndex < 192; nIndex++ )
{
if ( 1 == arrRequest[nIndex] && 0 == arrCandidate[nIndex] )
dPenalty += dRangeWeight;
else if ( bPenaltyForSuperflouous && 0 == arrRequest[nIndex] && 1 == arrCandidate[nIndex] )
dPenalty += dRangeWeight;
}
return (int)dPenalty;
}
int GetFixedPitchPenalty(BOOL bCandFixed, BOOL bReqFixed)
{
int nPenalty = 0;
// Если запрашивается моноширинный, а кандидат не моноширинный, то вес 15000
// Если запрашивается не моноширинный, а кандидат моноширинный, то вес 350
if ( bReqFixed && !bCandFixed )
nPenalty = 15000;
if ( !bReqFixed && bCandFixed )
nPenalty = 350;
return nPenalty;
}
int GetFaceNamePenalty(CString sCandName, CString sReqName)
{
// На MSDN написано, что если имена не совпадают, то вес 10000.
// Мы будем сравнивать сколько совпало символов у запрашиваемого
// имени и с именем кандидата, без учета решистра, пробелов, запятых
// и тире.
sCandName.Remove(' '); sReqName.Remove(' ');
sCandName.Remove(','); sReqName.Remove(',');
sCandName.Remove('-'); sReqName.Remove('-');
sCandName.MakeLower(); sReqName.MakeLower();
if ( 0 == sReqName.GetLength() )
return 0;
if ( 0 == sCandName.GetLength() )
return 10000;
if ( sReqName == sCandName )
return 0;
else if ( -1 != sReqName.Find( sCandName ) || -1 != sCandName.Find( sReqName ) )
return 1000;
return 10000;
}
int GetFamilyUnlikelyPenalty(SHORT nCandFamilyClass, SHORT nReqFamilyClass)
{
// Requested a roman/modern/swiss family, but the candidate is
// decorative/script. Or requested decorative/script, and the
// candidate is roman/modern/swiss. Penalty = 50.
int nReqClassID = nReqFamilyClass >> 8;
int nCandClassID = nCandFamilyClass >> 8;
if ( 0 == nReqClassID ) // Unknown
return 0;
if ( 0 == nCandClassID ) // Unknown
return 50;
if ( ( nReqClassID <= 8 && nCandClassID > 8 ) || ( nReqClassID > 8 && nCandClassID <= 8 ) )
return 50;
return 0;
}
int GetFamilyUnlikelyPenalty(int nCandFamilyClass, CString sReqFamilyClass)
{
// Requested a roman/modern/swiss family, but the candidate is
// decorative/script. Or requested decorative/script, and the
// candidate is roman/modern/swiss. Penalty = 50.
int nCandClassID = nCandFamilyClass >> 8;
sReqFamilyClass.MakeLower();
if ( _T("any") == sReqFamilyClass || _T("unknown") == sReqFamilyClass )
return 0;
else if ( 0 == nCandClassID )
return 50;
else if ( ( ( _T("swiss") == sReqFamilyClass || _T("roman") == sReqFamilyClass || _T("modern") == sReqFamilyClass ) && nCandClassID > 8 ) || ( ( _T("decorative") == sReqFamilyClass || _T("script") == sReqFamilyClass ) && nCandClassID <= 8 ) )
return 50;
return 0;
}
int GetWidthPenalty(USHORT usCandWidth, USHORT usReqWidth)
{
// Penalty * width difference (Penalty = 50)
return abs( (int)usCandWidth - (int)usReqWidth ) * 50;
}
int GetWeightPenalty(USHORT usCandWeight, USHORT usReqWeight)
{
// Penalty * ( weight difference / 10 ) (Penalty = 3)
return (3 * ( abs( (int)usCandWeight - (int)usReqWeight ) / 10 ));
}
int GetItalicPenalty(BOOL bCandItalic, BOOL bReqItalic)
{
// Penalty = 4
if ( bCandItalic != bReqItalic )
return 4;
return 0;
}
int GetBoldPenalty(BOOL bCandBold, BOOL bReqBold)
{
// SmallPenalty
// Penalty = 1
if ( bCandBold != bReqBold )
return 1;
return 0;
}
int GetFontFormatPenalty(EFontFormat eCandFormat, EFontFormat eReqFormat)
{
// Вообще, на МSDN написано только про TrueType. Но мы будем сравнивать
// все типы форматов и при несовпадении даем вес = 4. Если формат не задан
// то по умолчанию считаем его TrueType.
if ( eReqFormat == fontUnknown )
{
// Считаем, что когда формат не известен, значит это 100% не TrueType.
if ( eCandFormat == fontTrueType )
return 4;
else
return 0;
}
if ( eCandFormat != eReqFormat )
return 4;
return 0;
}
int GetPanosePenalty(BYTE *pCandPanose, BYTE *pReqPanose)
{
int nPenalty = 0;
for ( int nIndex = 0; nIndex < 10; nIndex++ )
{
if ( pCandPanose[nIndex] != pReqPanose[nIndex] && 0 != pReqPanose[nIndex] )
{
int nKoef = abs(pCandPanose[nIndex] - pReqPanose[nIndex]);
switch(nIndex)
{
case 0: nPenalty += 1000 * nKoef; break;
case 1: nPenalty += 100 * nKoef; break;
case 2: nPenalty += 100 * nKoef; break;
case 3: nPenalty += 100 * nKoef; break;
case 4: nPenalty += 100 * nKoef; break;
case 5: nPenalty += 100 * nKoef; break;
case 6: nPenalty += 100 * nKoef; break;
case 7: nPenalty += 100 * nKoef; break;
case 8: nPenalty += 100 * nKoef; break;
case 9: nPenalty += 100 * nKoef; break;
}
}
}
return nPenalty;
}
int GetAvgWidthPenalty(SHORT shCandWidth, SHORT shReqWidth)
{
if ( 0 == shCandWidth && 0 != shReqWidth )
return 4000;
return abs( shCandWidth - shReqWidth ) * 4;
}
int GetAscentPenalty(SHORT shCandAscent, SHORT shReqAscent)
{
if ( 0 == shCandAscent && 0 != shReqAscent )
return 100;
return abs( shCandAscent - shReqAscent ) / 10;
}
int GetDescentPenalty(SHORT shCandDescent, SHORT shReqDescent)
{
if ( 0 == shCandDescent && 0 != shReqDescent )
return 100;
return abs( shCandDescent - shReqDescent ) / 10;
}
int GetLineGapPenalty(SHORT shCandLineGap, SHORT shReqLineGap)
{
if ( 0 == shCandLineGap && 0 != shReqLineGap )
return 100;
return abs( shCandLineGap - shReqLineGap ) / 10;
}
int GetXHeightPenalty(SHORT shCandXHeight, SHORT shReqXHeight)
{
if ( 0 == shCandXHeight && 0 != shReqXHeight )
return 50;
return abs( shCandXHeight - shReqXHeight ) / 20;
}
int GetCapHeightPenalty(SHORT shCandCapHeight, SHORT shReqCapHeight)
{
if ( 0 == shCandCapHeight && 0 != shReqCapHeight )
return 50;
return abs( shCandCapHeight - shReqCapHeight ) / 20;
}
public:
CString GetAllStylesByFontName(const CString& strName)
{
CString strAllStyles = _T("<styles>");
int nCount = m_pFonts->GetLength();
for (int i = 0; i < nCount; ++i)
{
CWinFontInfo* pInfo = GetByIndex(i);
if (pInfo->m_wsFontName == strName)
{
LONG lStyle = 0;
if (pInfo->m_bBold)
lStyle |= 1;
if (pInfo->m_bItalic)
lStyle |= 2;
CString strPath = pInfo->m_wsFontPath;
strPath.Replace(_T("'"), _T("&apos;"));
strPath.Replace(_T("<"), _T("&lt;"));
strPath.Replace(_T(">"), _T("&gt;"));
strPath.Replace(_T("\""), _T("&quot;"));
strPath.Replace(_T("&"), _T("&amp;"));
CString s = _T("");
s.Format(_T("<font style=\"%d\" path=\"%s\" faceindex=\"%d\"/>"), lStyle, strPath, pInfo->m_lIndex);
strAllStyles += s;
}
}
strAllStyles += _T("</styles>");
return strAllStyles;
}
private:
CList *m_pFonts; // [CWinFontInfo]
wchar_t m_wsWinFontDir[MAX_PATH]; //
long m_lDefIndex; // Номер стандартного шрифта (-1, если не задан)
};
#endif /* _WIN_FONT */
\ No newline at end of file
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include "../../../Common/ShareMemArray.h"
// Идентификаторы хранилищ
#define ISID_DEFAULT 0x0000 // По умолчанию
#define ISID_WIN_FONT_STATUS_STORAGE 0x0001 // Таблица для статуса
#define ISID_WIN_FONT_INFO_STORAGE 0x0002 // Таблица для Информации
// Макс. длина имени таблицы
#define STORAGE_TABLE_NAME_LEN 1024
#define STATUS_STORAGE_NAME CString( _T("AVS_LOADED_WIN_FONTS") )
namespace NSStrings
{
static CString ConvertCStringWToCString(CStringW& strW)
{
BSTR bstr = strW.AllocSysString();
CString str(bstr);
SysFreeString(bstr);
return str;
}
static CStringW GetCStringWFromUTF8( BYTE* pBuffer, LONG64 lCount )
{
LONG64 lLenght = 0;
CStringW strRes = L"";
for (LONG lIndex = 0; lIndex < lCount; ++lIndex)
{
if (0x00 == (0x80 & pBuffer[lIndex]))
{
strRes += (WCHAR)pBuffer[lIndex];
continue;
}
else if (0x00 == (0x20 & pBuffer[lIndex]))
{
WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x1F) << 6) + (pBuffer[lIndex + 1] & 0x3F));
strRes += mem;
lIndex += 1;
}
else if (0x00 == (0x10 & pBuffer[lIndex]))
{
WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x0F) << 12) + ((pBuffer[lIndex + 1] & 0x3F) << 6) + (pBuffer[lIndex + 2] & 0x3F));
strRes += mem;
lIndex += 2;
}
}
return strRes;
}
static CString GetCStringFromUTF8( BYTE* pBuffer, LONG64 lCount )
{
CStringW strRes = GetCStringWFromUTF8(pBuffer, lCount);
return ConvertCStringWToCString(strRes);
}
};
// статус таблицы установленных шрифтов
enum WinFontsTableStatus {STIF_ERROR, STIF_AVAILABLE, STIF_CREATING, STIF_BROKEN};
enum StringCoding
{
scASCII = 0,
scUNICODE = 1,
scUTF8 = 2
};
// Структура для определения статуса таблицы хранилища
struct WinFontsStatusStorage
{
// Общие данные
WinFontsTableStatus m_sStatus; // Статус
LONG64 m_lLength; // Размер таблицы
WinFontsStatusStorage()
{
Reset();
}
void Reset()
{
// Общие данные
m_sStatus = STIF_ERROR; // Статус
m_lLength = 0;
}
};
// Структура для определения информации
struct WinFontsInfoStorage
{
LONG m_lCount;
CStringA m_strXml;
BYTE* m_pBuffer;
LONG m_lCountData;
WinFontsInfoStorage()
{
Reset();
}
~WinFontsInfoStorage()
{
}
void Reset()
{
m_lCount = 0;
m_strXml = "";
m_pBuffer = NULL;
}
void GenerateInfo(BSTR bstrXML)
{
m_strXml = CStringA(bstrXML);
m_pBuffer = NULL;
m_lCountData = 0;
}
void GenerateInfo(BYTE* pBuffer, LONG lCountData)
{
m_pBuffer = pBuffer;
m_lCountData = lCountData;
}
void Save(BYTE* pBuffer)
{
if (NULL == pBuffer)
return;
if (0 == m_lCountData)
{
memcpy(pBuffer, (BYTE*)m_strXml.GetBuffer(), m_strXml.GetLength());
}
else
{
memcpy(pBuffer, m_pBuffer, m_lCountData);
}
}
LONG64 GetLength()
{
if (0 == m_lCountData)
{
return m_strXml.GetLength();
}
return m_lCountData;
}
void Load(BYTE* pBuffer, LONG64 lLength)
{
//m_pBuffer = pBuffer;
m_lCountData = (LONG)lLength;
m_pBuffer = new BYTE[m_lCountData];
memcpy(m_pBuffer, pBuffer, m_lCountData);
}
};
// Класс хранилища таблицы статуса
class CWinFontsStatusStorage: public CShareMemArray<BYTE>
{
protected:
bool ReadStruct_unsync(WinFontsStatusStorage *aData) // Прочитать структуру unsync
{
__try
{
WinFontsStatusStorage *pTable = (WinFontsStatusStorage *) ( (BYTE *)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы
memcpy(aData, pTable, sizeof(WinFontsStatusStorage));
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
//ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n");
return false;
}
return true;
}
bool WriteStruct_unsync(WinFontsStatusStorage *aData) // Записать структуру unsync
{
__try
{
WinFontsStatusStorage *pTable = (WinFontsStatusStorage *) ( (BYTE *)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы
memcpy(pTable, aData, sizeof(WinFontsStatusStorage));
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
//ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n");
return false;
}
return true;
}
public:
bool ReadStruct(WinFontsStatusStorage *aData)
{
CSynchAccess oAccess = m_hAccessMutex;
return ReadStruct_unsync(aData);
}
bool WriteStruct(WinFontsStatusStorage *aData)
{
CSynchAccess oAccess = m_hAccessMutex;
return WriteStruct_unsync(aData);
}
public:
// Получить статус индексатора (bForceControl - Попытаться стать мастером, если получится)
// возвращаем *bForceControl == true - вызывающий объект стал мастером
bool GetStatus(bool *bForceControl, WinFontsStatusStorage* aIS)
{
bool bTryToForceControl = bForceControl && (*bForceControl);
if (NULL == aIS) return false;
if (bForceControl) *bForceControl = false; // Пока мы не можем стать мастером
// Делаем все под мутексом :)
CSynchAccess oAccess = m_hAccessMutex;
if (!ReadStruct_unsync(aIS)) return false; // Не получилось прочитать статус
if ((STIF_BROKEN == aIS->m_sStatus) || (STIF_ERROR == aIS->m_sStatus))
{
// Таблица нарушена - говорим, что можно стать мастером (если нужно было)
if (bTryToForceControl)
{
// Сбрасываем таблицу
aIS->Reset();
aIS->m_sStatus = STIF_CREATING;
*bForceControl = WriteStruct_unsync(aIS); // пишем в память и говорим, что стали мастером
}
}
return true;
}
// Установить статус, как нарушенное хранилище. Мастерство может перехватываться другими объектами
bool SetBroken()
{
CSynchAccess oAccess = m_hAccessMutex;
WinFontsStatusStorage sStor;
sStor.m_sStatus = STIF_BROKEN;
// Пишем в ш-память
return WriteStruct_unsync(&sStor);
}
private:
// Скрываем методы работы с массивами
bool Save(CAtlArray<BYTE> &aTable)
{
return false;
}
bool Load(CAtlArray<BYTE> &aTable)
{
return false;
}
public:
CWinFontsStatusStorage(CString &aName): CShareMemArray(aName, sizeof(WinFontsStatusStorage), ISID_WIN_FONT_STATUS_STORAGE)
{
// Параметр aName должен быть AVS_LOAD_WIN_FONTS
//ATLTRACE2("CStatusStorage created;\n");
};
~CWinFontsStatusStorage()
{
//ATLTRACE2("CStatusStorage destroyed;\n");
};
};
// Класс хранилища таблицы информации
class CWinFontsInfoStorage: public CShareMemArray<BYTE>
{
protected:
bool ReadStruct_unsync(WinFontsInfoStorage *aData) // Прочитать структуру unsync
{
__try
{
LONG64 lLength = Size();
aData->Load((BYTE*)m_pArray + sizeof(LONG64), lLength); // sizeof(LONG64) - размер таблицы
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
//ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n");
return false;
}
return true;
}
bool WriteStruct_unsync(WinFontsInfoStorage *aData) // Записать структуру unsync
{
__try
{
LONG64 *pSize = (LONG64*)m_pArray;
*pSize = m_nSize;
aData->Save((BYTE*)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
//ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n");
return false;
}
return true;
}
public:
bool ReadStruct(WinFontsInfoStorage *aData)
{
//CSynchAccess oAccess = m_hAccessMutex;
return ReadStruct_unsync(aData);
}
bool WriteStruct(WinFontsInfoStorage *aData)
{
CSynchAccess oAccess = m_hAccessMutex;
return WriteStruct_unsync(aData);
}
bool WriteCount(WinFontsInfoStorage *aData)
{
__try
{
BYTE* pData = (BYTE*)m_pArray + sizeof(LONG64);
*((LONG*)pData) = aData->m_lCount;
}
__except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Failed to read from the view.
//ATLTRACE2("CWinFontsInfoStorage::ReadStruct_unsync() fails!\n");
return false;
}
return true;
}
private:
// Скрываем методы работы с массивами
bool Save(CAtlArray<BYTE> &aTable)
{
return false;
}
bool Load(CAtlArray<BYTE> &aTable)
{
return false;
}
public:
CWinFontsInfoStorage(CString &aFileName, LONG64 lSize): CShareMemArray(aFileName, lSize, ISID_WIN_FONT_INFO_STORAGE)
{
//ATLTRACE2("CWinFontsInfoStorage created;\n");
};
~CWinFontsInfoStorage()
{
//ATLTRACE2("CWinFontsInfoStorage destroyed;\n");
};
};
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _FONT_DICTIONARY_WORKER_H
#include "FontDictionary.h"
namespace NSFontDictionary
{
static bool CorrectParamsFromDictionary(CString& wsFamily, BOOL& bBold, BOOL& bItalic, BOOL& bFixedWidth, BYTE* pPanose,
ULONG& ulRange1, ULONG& ulRange2, ULONG& ulRange3, ULONG& ulRange4, ULONG& ulCodeRange1, ULONG& ulCodeRange2,
USHORT& usWeight, USHORT& usWidth, SHORT& sFamilyClass,
SHORT& shAvgCharWidth, SHORT& shAscent, SHORT& shDescent, SHORT& shLineGap, SHORT& shXHeight, SHORT& shCapHeight,
BOOL& bIsStyle, BOOL& bIsFixed, BOOL& bIsPanose, BOOL& bIsRanges,
BOOL& bIsWeight, BOOL& bIsWidth, BOOL& bIsFamilyClass,
BOOL& bIsAvgWidth, BOOL& bIsAscent, BOOL& bIsDescent, BOOL& bIsLineGap, BOOL& bIsXHeight, BOOL& bIsCapHeight)
{
int nNameLen = wsFamily.GetLength();
if (nNameLen == 0)
return false;
bool bIsAscii = true;
wchar_t* pName = wsFamily.GetBuffer();
for (int i = 0; i < nNameLen; ++i)
{
if (pName[i] > 255 || pName[i] < 0)
{
bIsAscii = false;
break;
}
}
const FD_Font* pFont = NULL;
if (bIsAscii)
{
int nStartIndex = FD_Ascii_Names_Offsets[pName[0]];
if (-1 != nStartIndex)
{
int nIndex = -1;
for (int i = nStartIndex; i < FONTS_DICT_ASCII_NAMES_COUNT; ++i)
{
const char* _name = FD_Ascii_Names[i].m_name;
if (pName[0] != (wchar_t)_name[0])
break;
bool bIsEqual = true;
for (int j = 1; j < nNameLen; ++j)
{
if ('\0' == _name[j] && j != (nNameLen - 1))
{
bIsEqual = false;
break;
}
if (pName[j] != (wchar_t)_name[j])
{
bIsEqual = false;
break;
}
}
if (bIsEqual)
{
nIndex = i;
break;
}
}
if (nIndex != -1)
{
const FD_FontMapRec* pRec = &FD_Ascii_Names[nIndex];
int nFontIndex = -1;
int nStyle = 0;
if (bIsStyle && bItalic)
nStyle |= 1;
if (bIsStyle && bBold)
nStyle |= 2;
switch (nStyle)
{
case 1:
{
if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else
nFontIndex = pRec->m_index_b;
break;
}
case 2:
{
if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else
nFontIndex = pRec->m_index_i;
break;
}
case 3:
{
if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else
nFontIndex = pRec->m_index_r;
break;
}
case 0:
default:
{
if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else
nFontIndex = pRec->m_index_bi;
break;
}
}
if (nFontIndex != -1)
pFont = &FD_Ascii_Files[nFontIndex];
}
}
}
else
{
int nIndex = -1;
for (int i = 0; i < FONTS_DICT_UNICODE_NAMES_COUNT; ++i)
{
const wchar_t* _name = FD_Unicode_Names[i].m_name;
if (pName[0] != _name[0])
continue;
bool bIsEqual = true;
for (int j = 1; j < nNameLen; ++j)
{
if (((wchar_t)'\0') == _name[j] && j != (nNameLen - 1))
{
bIsEqual = false;
break;
}
if (pName[j] != _name[j])
{
bIsEqual = false;
break;
}
}
if (bIsEqual)
{
nIndex = i;
break;
}
}
if (nIndex != -1)
{
const FD_FontMapRecW* pRec = &FD_Unicode_Names[nIndex];
int nFontIndex = -1;
int nStyle = 0;
if (bIsStyle && bItalic)
nStyle |= 1;
if (bIsStyle && bBold)
nStyle |= 2;
switch (nStyle)
{
case 1:
{
if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else
nFontIndex = pRec->m_index_b;
break;
}
case 2:
{
if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else
nFontIndex = pRec->m_index_i;
break;
}
case 3:
{
if (pRec->m_index_bi != -1)
nFontIndex = pRec->m_index_bi;
else if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else
nFontIndex = pRec->m_index_r;
break;
}
case 0:
default:
{
if (pRec->m_index_r != -1)
nFontIndex = pRec->m_index_r;
else if (pRec->m_index_i != -1)
nFontIndex = pRec->m_index_i;
else if (pRec->m_index_b != -1)
nFontIndex = pRec->m_index_b;
else
nFontIndex = pRec->m_index_bi;
break;
}
}
if (nFontIndex != -1)
pFont = &FD_Ascii_Files[nFontIndex];
}
}
if (NULL == pFont)
return false;
// name - делаем ascii, чтобы сработал подбор
wsFamily = (CString(pFont->m_name));
// fixed
bIsFixed = TRUE;
bFixedWidth = pFont->m_bIsFixed == 1 ? TRUE : FALSE;
// panose
bIsPanose = TRUE;
memcpy(pPanose, pFont->m_aPanose, 10);
// ranges
bIsRanges = TRUE;
ulRange1 = pFont->m_ulUnicodeRange1;
ulRange2 = pFont->m_ulUnicodeRange2;
ulRange3 = pFont->m_ulUnicodeRange3;
ulRange4 = pFont->m_ulUnicodeRange4;
ulCodeRange1 = pFont->m_ulCodePageRange1;
ulCodeRange2 = pFont->m_ulCodePageRange2;
bIsWeight = TRUE;
bIsWeight = pFont->m_usWeigth;
bIsWidth = TRUE;
usWidth = pFont->m_usWidth;
bIsAvgWidth = TRUE;
shAvgCharWidth = pFont->m_shAvgCharWidth;
bIsAscent = TRUE;
shAscent = pFont->m_shAscent;
bIsDescent = TRUE;
shDescent = pFont->m_shDescent;
bIsXHeight = TRUE;
shXHeight = pFont->m_shXHeight;
bIsCapHeight = TRUE;
shCapHeight = pFont->m_shCapHeight;
return true;
}
}
#endif /* _FONT_DICTIONARY_WORKER_H */
\ No newline at end of file
QT -= core gui
TARGET = freetype
TEMPLATE = lib
CONFIG += staticlib
CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
include(../../../../Common/base.pri)
FREETYPE_LIB_PATH=$$PWD/../../freetype-2.5.3
INCLUDEPATH += \
$$FREETYPE_LIB_PATH/include
DEFINES += \
FT2_BUILD_LIBRARY
DESTDIR=$$PWD/../build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX
SOURCES += \
$$FREETYPE_LIB_PATH/src/base/ftbbox.c \
$$FREETYPE_LIB_PATH/src/base/ftgxval.c \
$$FREETYPE_LIB_PATH/src/base/ftlcdfil.c \
$$FREETYPE_LIB_PATH/src/base/ftmm.c \
$$FREETYPE_LIB_PATH/src/base/ftotval.c \
$$FREETYPE_LIB_PATH/src/base/ftpatent.c \
$$FREETYPE_LIB_PATH/src/base/ftpfr.c \
$$FREETYPE_LIB_PATH/src/base/ftsynth.c \
$$FREETYPE_LIB_PATH/src/base/fttype1.c \
$$FREETYPE_LIB_PATH/src/base/ftwinfnt.c \
$$FREETYPE_LIB_PATH/src/base/ftxf86.c \
$$FREETYPE_LIB_PATH/src/pcf/pcf.c \
$$FREETYPE_LIB_PATH/src/pfr/pfr.c \
$$FREETYPE_LIB_PATH/src/psaux/psaux.c \
$$FREETYPE_LIB_PATH/src/pshinter/pshinter.c \
$$FREETYPE_LIB_PATH/src/psnames/psmodule.c \
$$FREETYPE_LIB_PATH/src/raster/raster.c \
$$FREETYPE_LIB_PATH/src/sfnt/sfnt.c \
$$FREETYPE_LIB_PATH/src/truetype/truetype.c \
$$FREETYPE_LIB_PATH/src/type1/type1.c \
$$FREETYPE_LIB_PATH/src/cid/type1cid.c \
$$FREETYPE_LIB_PATH/src/type42/type42.c \
$$FREETYPE_LIB_PATH/src/winfonts/winfnt.c \
\
$$FREETYPE_LIB_PATH/src/autofit/autofit.c \
$$FREETYPE_LIB_PATH/src/bdf/bdf.c \
$$FREETYPE_LIB_PATH/src/cff/cff.c \
$$FREETYPE_LIB_PATH/src/base/ftbase.c \
$$FREETYPE_LIB_PATH/src/base/ftbitmap.c \
$$FREETYPE_LIB_PATH/src/cache/ftcache.c \
$$FREETYPE_LIB_PATH/src/base/ftfstype.c \
$$FREETYPE_LIB_PATH/src/base/ftgasp.c \
$$FREETYPE_LIB_PATH/src/base/ftglyph.c \
$$FREETYPE_LIB_PATH/src/gzip/ftgzip.c \
$$FREETYPE_LIB_PATH/src/base/ftinit.c \
$$FREETYPE_LIB_PATH/src/lzw/ftlzw.c \
$$FREETYPE_LIB_PATH/src/base/ftstroke.c \
$$FREETYPE_LIB_PATH/src/base/ftsystem.c \
$$FREETYPE_LIB_PATH/src/smooth/smooth.c
QT -= core gui
TARGET = names
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEFINES += \
BUILD_FONT_NAMES_DICTIONARY
CORE_ROOT_DIR = $$PWD/../../..
PWD_ROOT_DIR = $$PWD
include(../../../Common/base.pri)
FREETYPE_LIB_PATH=$$PWD/../freetype-2.5.3
INCLUDEPATH += \
$$FREETYPE_LIB_PATH/include
LIBS += -L$$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX -lfreetype
DESTDIR=$$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX
SOURCES += \
FontMaps.cpp
#HEADERS += FontDictionary.h
HEADERS += \
$$PWD/../../fontengine/ApplicationFonts.h
SOURCES += \
$$PWD/../../fontengine/ApplicationFonts.cpp \
$$PWD/../../fontengine/FontFile.cpp \
$$PWD/../../fontengine/FontManager.cpp \
$$PWD/../../fontengine/GlyphString.cpp \
$$PWD/../../fontengine/FontPath.cpp
win32 {
LIBS += -ladvapi32 \
-luser32 \
-lshell32
}
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
// stdafx.cpp : source file that includes just the standard includes
// FontMaps.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#ifndef STRICT
#define STRICT
#endif
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
#endif
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _CRT_SECURE_NO_DEPRECATE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off ATL's hiding of some common and often safely ignored warning messages
#define _ATL_ALL_WARNINGS
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <atlstr.h>
using namespace ATL;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment