Compare commits

..

1 Commits

Author SHA1 Message Date
8cdaf43001 Feature/font bugs (#202)
* Fonts bugs

* Move fonts_check version to src file
2019-10-16 14:07:24 +03:00
6 changed files with 226 additions and 201 deletions

View File

@ -1409,6 +1409,24 @@ void CFontList::LoadFromFolder(const std::wstring& strDirectory)
this->LoadFromArrayFiles(oArray);
}
void CFontList::InitializeRanges(unsigned char* data)
{
RELEASEARRAYOBJECTS(m_pRanges)
NSMemoryUtils::CByteReader oReader(data);
m_nRangesCount = oReader.GetInt();
if (m_nRangesCount > 0)
m_pRanges = new CFontRange[m_nRangesCount];
for (int nIndex = 0; nIndex < m_nRangesCount; ++nIndex)
{
m_pRanges[nIndex].Name = oReader.GetStringUTF8();
m_pRanges[nIndex].Start = oReader.GetInt();
m_pRanges[nIndex].End = oReader.GetInt();
}
}
bool CFontList::CheckLoadFromFolderBin(const std::wstring& strDirectory)
{
std::wstring strPath = strDirectory + L"/font_selection.bin";
@ -1435,18 +1453,7 @@ bool CFontList::CheckLoadFromFolderBin(const std::wstring& strDirectory)
if ((_pBuffer - pBuffer) < dwLen1)
{
NSMemoryUtils::CByteReader oReader(_pBuffer);
m_nRangesCount = oReader.GetInt();
if (m_nRangesCount > 0)
m_pRanges = new CFontRange[m_nRangesCount];
for (int nIndex = 0; nIndex < m_nRangesCount; ++nIndex)
{
m_pRanges[nIndex].Name = oReader.GetStringUTF8();
m_pRanges[nIndex].Start = oReader.GetInt();
m_pRanges[nIndex].End = oReader.GetInt();
}
InitializeRanges(_pBuffer);
}
RELEASEARRAYOBJECTS(pBuffer);
@ -1533,6 +1540,11 @@ void CApplicationFonts::Initialize(bool bIsCheckSelection)
m_oCache.m_pApplicationFontStreams = &m_oStreams;
}
void CApplicationFonts::InitializeRanges(unsigned char* data)
{
m_oList.InitializeRanges(data);
}
NSFonts::IFontManager* CApplicationFonts::GenerateFontManager()
{
CFontManager* pManager = new CFontManager();

View File

@ -302,6 +302,7 @@ public:
std::vector<NSFonts::CFontInfo*> GetAllByName (const std::wstring& strFontName);
std::wstring GetFontBySymbol(int symbol);
void InitializeRanges(unsigned char* data);
};
class CApplicationFonts : public NSFonts::IApplicationFonts
@ -322,6 +323,7 @@ public:
void InitializeFromFolder(std::wstring strFolder, bool bIsCheckSelection = true);
void Initialize(bool bIsCheckSelection = true);
void InitializeRanges(unsigned char* data);
std::vector<std::wstring> GetSetupFontFiles();
void InitializeFromArrayFiles(std::vector<std::wstring>& files, int nFlag = 0);

View File

@ -32,6 +32,8 @@
#include "ApplicationFontsWorker.h"
#include "application_generate_fonts.h"
#define ONLYOFFICE_FONTS_VERSION_ 3
CApplicationFontsWorker::CApplicationFontsWorker()
{
m_bIsUseSystemFonts = true;
@ -52,11 +54,12 @@ NSFonts::IApplicationFonts* CApplicationFontsWorker::Check()
std::wstring strFontsSelectionBin = m_sDirectory + L"/font_selection.bin";
std::vector<std::string> strFonts;
std::wstring strFontsCheckPath = m_sDirectory + L"/fonts.log";
if (true)
{
NSFile::CFileBinary oFile;
if (oFile.OpenFile(m_sDirectory + L"/fonts.log"))
if (oFile.OpenFile(strFontsCheckPath))
{
int nSize = oFile.GetFileSize();
char* pBuffer = new char[nSize];
@ -141,28 +144,16 @@ NSFonts::IApplicationFonts* CApplicationFontsWorker::Check()
if (!bIsEqual)
{
if (NSFile::CFileBinary::Exists(strFontsCheckPath))
NSFile::CFileBinary::Remove(strFontsCheckPath);
if (NSFile::CFileBinary::Exists(strAllFontsJSPath))
NSFile::CFileBinary::Remove(strAllFontsJSPath);
if (NSFile::CFileBinary::Exists(strFontsSelectionBin))
NSFile::CFileBinary::Remove(strFontsSelectionBin);
if (strFonts.size() != 0)
NSFile::CFileBinary::Remove(m_sDirectory + L"/fonts.log");
NSFile::CFileBinary oFile;
oFile.CreateFileW(m_sDirectory + L"/fonts.log");
#ifdef ONLYOFFICE_FONTS_VERSION_
oFile.WriteStringUTF8(L"ONLYOFFICE_FONTS_VERSION_");
oFile.WriteStringUTF8(std::to_wstring(ONLYOFFICE_FONTS_VERSION_));
oFile.WriteFile((BYTE*)"\n", 1);
#endif
int nCount = (int)strFontsW_Cur.size();
for (int i = 0; i < nCount; ++i)
{
oFile.WriteStringUTF8(strFontsW_Cur[i]);
oFile.WriteFile((BYTE*)"\n", 1);
}
oFile.CloseFile();
if (NSFile::CFileBinary::Exists(m_sDirectory + L"/fonts_thumbnail.png"))
NSFile::CFileBinary::Remove(m_sDirectory + L"/fonts_thumbnail.png");
if (NSFile::CFileBinary::Exists(m_sDirectory + L"/fonts_thumbnail@2x.png"))
NSFile::CFileBinary::Remove(m_sDirectory + L"/fonts_thumbnail@2x.png");
int nFlag = 3;
if (!m_bIsUseOpenType)
@ -173,6 +164,21 @@ NSFonts::IApplicationFonts* CApplicationFontsWorker::Check()
NSCommon::SaveAllFontsJS(pApplicationF, strAllFontsJSPath, m_bIsNeedThumbnails ? m_sDirectory : L"", strFontsSelectionBin);
}
NSFile::CFileBinary oFile;
oFile.CreateFileW(strFontsCheckPath);
#ifdef ONLYOFFICE_FONTS_VERSION_
oFile.WriteStringUTF8(L"ONLYOFFICE_FONTS_VERSION_");
oFile.WriteStringUTF8(std::to_wstring(ONLYOFFICE_FONTS_VERSION_));
oFile.WriteFile((BYTE*)"\n", 1);
#endif
int nCount = (int)strFontsW_Cur.size();
for (int i = 0; i < nCount; ++i)
{
oFile.WriteStringUTF8(strFontsW_Cur[i]);
oFile.WriteFile((BYTE*)"\n", 1);
}
oFile.CloseFile();
pApplicationF->Release();
pApplicationF = NSFonts::NSApplication::Create();
pApplicationF->InitializeFromFolder(m_sDirectory);

View File

@ -1,4 +1,4 @@
/*
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* This program is a free software product. You can redistribute it and/or
@ -59,8 +59,8 @@ static std::wstring GetCorrectSfntName(const char* name)
bool isUtf8 = false;
if (6 < name_len)
{
if ('<' == name[0] || 'u' == name[1] || 't' == name[2] ||
'f' == name[3] || '8' == name[4] || '>' == name[5])
if ('<' == name[0] && 'u' == name[1] && 't' == name[2] &&
'f' == name[3] && '8' == name[4] && '>' == name[5])
{
name_cur = name + 6;
name_len -= 6;

View File

@ -52,7 +52,7 @@
//#define _GENERATE_FONT_MAP_
#ifdef _GENERATE_FONT_MAP_
#include "../../freetype_names/FontMaps/FontDictionary.h"
#include "./../freetype_names/FontMaps/FontDictionary.h"
#endif
namespace NSCommon
@ -460,172 +460,6 @@ namespace NSCommon
}
}
}
// -------------------------------------------
#ifndef ASC_APPLICATION_FONTS_NO_THUMBNAILS
if (L"" != strFolderThumbnails)
{
NSFonts::IFontManager* pManager = applicationFonts->GenerateFontManager();
NSFonts::IFontsCache* pCache = NSFonts::NSFontCache::Create();
pCache->SetStreams(applicationFonts->GetStreams());
pManager->SetOwnerCache(pCache);
for (int iX = 1; iX <= 2; ++iX)
{
// создаем картинку для табнейлов
double dDpi = 96 * iX;
double dW_mm = 80;
LONG lH1_px = LONG(7 * dDpi / 25.4);
LONG lWidthPix = (LONG)(dW_mm * dDpi / 25.4);
LONG lHeightPix = (LONG)(nCountFonts * lH1_px);
LONG lCountPixels = 4 * lWidthPix * lHeightPix;
BYTE* pImageData = new BYTE[lCountPixels];
memset(pImageData, 0xFF, lCountPixels);
CBgraFrame oFrame;
oFrame.put_Data(pImageData);
oFrame.put_Width((int)lWidthPix);
oFrame.put_Height((int)lHeightPix);
oFrame.put_Stride(4 * (int)lWidthPix);
for (LONG i = 3; i < lWidthPix * lHeightPix * 4; i += 4)
{
pImageData[i] = 0;
}
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetFontManager(pManager);
pRenderer->put_Width(lWidthPix * 25.4 / dDpi);
pRenderer->put_Height(lHeightPix * 25.4 / dDpi);
for (int index = 0; index < nCountFonts; ++index)
{
std::map<std::wstring, CFontInfoJS>::iterator pPair = mapFonts.find(arrFonts[index]);
// thumbnail
int lFontIndex = 0;
int lFaceIndex = 0;
if (pPair->second.m_lIndexR != -1)
{
lFontIndex = pPair->second.m_lIndexR;
lFaceIndex = pPair->second.m_lFaceIndexR;
}
else if (pPair->second.m_lIndexI != -1)
{
lFontIndex = pPair->second.m_lIndexI;
lFaceIndex = pPair->second.m_lFaceIndexI;
}
else if (pPair->second.m_lIndexB != -1)
{
lFontIndex = pPair->second.m_lIndexB;
lFaceIndex = pPair->second.m_lFaceIndexB;
}
else if (pPair->second.m_lIndexBI != -1)
{
lFontIndex = pPair->second.m_lIndexBI;
lFaceIndex = pPair->second.m_lFaceIndexBI;
}
std::map<LONG, std::wstring>::iterator pPair2 = mapFontFiles2.find(lFontIndex);
std::wstring strFontPath = L"";
if (mapFontFiles2.end() != pPair2)
strFontPath = pPair2->second;
pRenderer->put_FontPath(strFontPath);
pRenderer->put_FontFaceIndex(lFaceIndex);
pManager->LoadFontFromFile(strFontPath, lFaceIndex, 14, dDpi, dDpi);
bool bIsSymbol = false;
NSFonts::IFontFile* pFile = pManager->GetFile();
if (pFile)
bIsSymbol = pFile->IsSymbolic(false);
std::wstring sFontName = pPair->second.m_sName;
if (bIsSymbol)
{
NSFonts::CFontSelectFormat oSelectFormat;
oSelectFormat.wsName = new std::wstring(L"Courier New");
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
if (NULL != pInfoCur)
{
pManager->LoadFontFromFile(pInfoCur->m_wsFontPath, 0, 14, dDpi, dDpi);
}
pRenderer->put_FontPath(pInfoCur->m_wsFontPath);
pRenderer->put_FontFaceIndex(0);
}
else if (pFile)
{
// у нас режим "без квадратов"
// но есть шрифты, в которых символы есть, но нулевой ширины.
// только из-за таких шрифтов делаем заглушку
int nFontNameLen = (int)sFontName.length();
bool bIsExistEmpty = false;
for (int nC = 0; nC < nFontNameLen; nC++)
{
int nCMapIndex = 0;
int nGid = pFile->SetCMapForCharCode(sFontName.at(nC), &nCMapIndex);
if (0 < nGid && 0.0001 > pFile->GetCharWidth(nGid))
{
bIsExistEmpty = true;
break;
}
}
if (bIsExistEmpty)
{
NSFonts::CFontSelectFormat oSelectFormat;
oSelectFormat.wsName = new std::wstring(L"Arial");
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
if (NULL != pInfoCur)
{
pManager->LoadFontFromFile(pInfoCur->m_wsFontPath, 0, 14, dDpi, dDpi);
}
pRenderer->put_FontPath(pInfoCur->m_wsFontPath);
pRenderer->put_FontFaceIndex(0);
}
}
pRenderer->PathCommandStart();
pRenderer->BeginCommand(c_nClipType);
pRenderer->PathCommandRect(0, 25.4 * (index * lH1_px) / dDpi, dW_mm, 25.4 * lH1_px / dDpi);
pRenderer->EndCommand(c_nClipType);
pRenderer->PathCommandEnd();
pRenderer->put_FontStringGID(FALSE);
pRenderer->put_FontCharSpace(0);
pRenderer->put_FontSize(14);
pRenderer->CommandDrawText(sFontName, 5, 25.4 * (index * lH1_px + lH1_px) / dDpi - 2, 0, 0);
pRenderer->BeginCommand(c_nResetClipType);
pRenderer->EndCommand(c_nResetClipType);
pRenderer->CloseFont();
pCache->Clear();
applicationFonts->GetStreams()->Clear();
}
RELEASEOBJECT(pRenderer);
std::wstring strThumbnailPath = strFolderThumbnails + L"/fonts_thumbnail";
if (iX == 1)
strThumbnailPath += L".png";
else
strThumbnailPath += L"@2x.png";
oFrame.SaveFile(strThumbnailPath, 4);
}
RELEASEOBJECT(pManager);
}
#endif
NSMemoryUtils::CByteBuilder* pRangeBuilder = NULL;
int nRangeBuilderCount = 0;
@ -1028,6 +862,9 @@ namespace NSCommon
pRangeBuilder->WriteInt(nRangeBuilderCount);
pRangeBuilder->SetCurSize(nPosCur);
oFile.WriteFile(pRangeBuilder->GetData(), (DWORD)pRangeBuilder->GetCurSize());
// init ranges
applicationFonts->InitializeRanges(pRangeBuilder->GetData());
}
oFile.CloseFile();
@ -1036,6 +873,173 @@ namespace NSCommon
}
RELEASEOBJECT(pRangeBuilder);
// -------------------------------------------
#ifndef ASC_APPLICATION_FONTS_NO_THUMBNAILS
if (L"" != strFolderThumbnails)
{
NSFonts::IFontManager* pManager = applicationFonts->GenerateFontManager();
NSFonts::IFontsCache* pCache = NSFonts::NSFontCache::Create();
pCache->SetStreams(applicationFonts->GetStreams());
pManager->SetOwnerCache(pCache);
for (int iX = 1; iX <= 2; ++iX)
{
// создаем картинку для табнейлов
double dDpi = 96 * iX;
double dW_mm = 80;
LONG lH1_px = LONG(7 * dDpi / 25.4);
LONG lWidthPix = (LONG)(dW_mm * dDpi / 25.4);
LONG lHeightPix = (LONG)(nCountFonts * lH1_px);
LONG lCountPixels = 4 * lWidthPix * lHeightPix;
BYTE* pImageData = new BYTE[lCountPixels];
memset(pImageData, 0xFF, lCountPixels);
CBgraFrame oFrame;
oFrame.put_Data(pImageData);
oFrame.put_Width((int)lWidthPix);
oFrame.put_Height((int)lHeightPix);
oFrame.put_Stride(4 * (int)lWidthPix);
for (LONG i = 3; i < lWidthPix * lHeightPix * 4; i += 4)
{
pImageData[i] = 0;
}
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetFontManager(pManager);
pRenderer->put_Width(lWidthPix * 25.4 / dDpi);
pRenderer->put_Height(lHeightPix * 25.4 / dDpi);
for (int index = 0; index < nCountFonts; ++index)
{
std::map<std::wstring, CFontInfoJS>::iterator pPair = mapFonts.find(arrFonts[index]);
// thumbnail
int lFontIndex = 0;
int lFaceIndex = 0;
if (pPair->second.m_lIndexR != -1)
{
lFontIndex = pPair->second.m_lIndexR;
lFaceIndex = pPair->second.m_lFaceIndexR;
}
else if (pPair->second.m_lIndexI != -1)
{
lFontIndex = pPair->second.m_lIndexI;
lFaceIndex = pPair->second.m_lFaceIndexI;
}
else if (pPair->second.m_lIndexB != -1)
{
lFontIndex = pPair->second.m_lIndexB;
lFaceIndex = pPair->second.m_lFaceIndexB;
}
else if (pPair->second.m_lIndexBI != -1)
{
lFontIndex = pPair->second.m_lIndexBI;
lFaceIndex = pPair->second.m_lFaceIndexBI;
}
std::map<LONG, std::wstring>::iterator pPair2 = mapFontFiles2.find(lFontIndex);
std::wstring strFontPath = L"";
if (mapFontFiles2.end() != pPair2)
strFontPath = pPair2->second;
pRenderer->put_FontPath(strFontPath);
pRenderer->put_FontFaceIndex(lFaceIndex);
pManager->LoadFontFromFile(strFontPath, lFaceIndex, 14, dDpi, dDpi);
bool bIsSymbol = false;
NSFonts::IFontFile* pFile = pManager->GetFile();
if (pFile)
bIsSymbol = pFile->IsSymbolic(false);
std::wstring sFontName = pPair->second.m_sName;
if (bIsSymbol)
{
NSFonts::CFontSelectFormat oSelectFormat;
oSelectFormat.wsName = new std::wstring(L"Courier New");
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
if (NULL != pInfoCur)
{
pManager->LoadFontFromFile(pInfoCur->m_wsFontPath, 0, 14, dDpi, dDpi);
}
pRenderer->put_FontPath(pInfoCur->m_wsFontPath);
pRenderer->put_FontFaceIndex(0);
}
else if (pFile)
{
// у нас режим "без квадратов"
// но есть шрифты, в которых символы есть, но нулевой ширины.
// только из-за таких шрифтов делаем заглушку
int nFontNameLen = (int)sFontName.length();
bool bIsExistEmpty = false;
for (int nC = 0; nC < nFontNameLen; nC++)
{
int nCMapIndex = 0;
int nGid = pFile->SetCMapForCharCode(sFontName.at(nC), &nCMapIndex);
if (0 < nGid && 0.0001 > pFile->GetCharWidth(nGid))
{
bIsExistEmpty = true;
break;
}
}
if (bIsExistEmpty)
{
NSFonts::CFontSelectFormat oSelectFormat;
oSelectFormat.wsName = new std::wstring(L"Arial");
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
if (NULL != pInfoCur)
{
pManager->LoadFontFromFile(pInfoCur->m_wsFontPath, 0, 14, dDpi, dDpi);
}
pRenderer->put_FontPath(pInfoCur->m_wsFontPath);
pRenderer->put_FontFaceIndex(0);
}
}
pRenderer->PathCommandStart();
pRenderer->BeginCommand(c_nClipType);
pRenderer->PathCommandRect(0, 25.4 * (index * lH1_px) / dDpi, dW_mm, 25.4 * lH1_px / dDpi);
pRenderer->EndCommand(c_nClipType);
pRenderer->PathCommandEnd();
pRenderer->put_FontStringGID(FALSE);
pRenderer->put_FontCharSpace(0);
pRenderer->put_FontSize(14);
pRenderer->CommandDrawText(sFontName, 5, 25.4 * (index * lH1_px + lH1_px) / dDpi - 2, 0, 0);
pRenderer->BeginCommand(c_nResetClipType);
pRenderer->EndCommand(c_nResetClipType);
pRenderer->CloseFont();
pCache->Clear();
applicationFonts->GetStreams()->Clear();
}
RELEASEOBJECT(pRenderer);
std::wstring strThumbnailPath = strFolderThumbnails + L"/fonts_thumbnail";
if (iX == 1)
strThumbnailPath += L".png";
else
strThumbnailPath += L"@2x.png";
oFrame.SaveFile(strThumbnailPath, 4);
}
RELEASEOBJECT(pManager);
}
#endif
}
#ifdef _GENERATE_FONT_MAP_

View File

@ -623,6 +623,7 @@ namespace NSFonts
virtual void InitializeFromFolder(std::wstring strFolder, bool bIsCheckSelection = true) = 0;
virtual void Initialize(bool bIsCheckSelection = true) = 0;
virtual void InitializeRanges(unsigned char* data) = 0;
virtual std::vector<std::wstring> GetSetupFontFiles() = 0;
virtual void InitializeFromArrayFiles(std::vector<std::wstring>& files, int nFlag = 0) = 0;