Fix calculating glyph widths for Base14 fonts

This commit is contained in:
Svetlana Kulikova
2024-05-17 16:00:23 +03:00
parent c24c78267b
commit d853d42090
12 changed files with 108 additions and 18 deletions

View File

@ -886,16 +886,6 @@ bool CPdfEditor::EditPage(int nPageIndex)
oAnnot.free(); oSubtype.free();
continue;
}
else if (oSubtype.isName("FreeText"))
{
//TODO добавление шрифтов FreeText в общий m_pAppAplication чтобы writer мог использовать шрифты из reader
oAnnot.free(); oSubtype.free();
oTemp.arrayGetNF(nIndex, &oAnnot);
std::map<std::wstring, std::wstring> mapFont = pReader->AnnotFonts(&oAnnot);
m_mFonts.insert(mapFont.begin(), mapFont.end());
DictToCDictObject(&oAnnot, pArray, false, "");
oAnnot.free();
}
oAnnot.free(); oSubtype.free();
oTemp.arrayGetNF(nIndex, &oAnnot);
DictToCDictObject(&oAnnot, pArray, false, "");
@ -1027,7 +1017,11 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
else if (oType.isName("Polygon") || oType.isName("PolyLine"))
pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref);
else if (oType.isName("FreeText"))
{
std::map<std::wstring, std::wstring> mapFont = pReader->AnnotFonts(&oAnnotRef);
m_mFonts.insert(mapFont.begin(), mapFont.end());
pAnnot = new PdfWriter::CFreeTextAnnotation(pXref);
}
else if (oType.isName("Caret"))
pAnnot = new PdfWriter::CCaretAnnotation(pXref);
else if (oType.isName("Popup"))

View File

@ -58,6 +58,7 @@ public:
bool IsEditPage() { return false; }
void AddShapeXML(const std::string& sXML) {}
void EndMarkedContent() {}
bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; }
};
#endif // BUILDING_WASM_MODULE

View File

@ -40,6 +40,7 @@
#include "SrcWriter/Font.h"
#include "SrcWriter/FontCidTT.h"
#include "SrcWriter/FontTT.h"
#include "SrcWriter/Font14.h"
#include "SrcWriter/Destination.h"
#include "SrcWriter/Field.h"
@ -748,8 +749,16 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned
if (m_pFont14)
{
bool bNew = false;
m_pFont14->EncodeUnicode(unGid, *pUnicodes, bNew);
if (bNew)
{
TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes);
double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0;
m_pFont14->AddWidth(dWidth);
}
unsigned char* pCodes = new unsigned char[2];
pCodes[0] = 0;
pCodes[0] = (*pUnicodes >> 8) & 0xFF;
pCodes[1] = *pUnicodes & 0xFF;
return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE;
}
@ -2916,7 +2925,10 @@ bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, cons
m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy));
CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY));
pText->SetFont(m_pFont14 ? m_pFont : m_pFont);
PdfWriter::CFontDict* pFont = m_pFont;
if (m_pFont14)
pFont = m_pFont14;
pText->SetFont(pFont);
pText->SetSize(m_oFont.GetSize());
pText->SetColor(m_oBrush.GetColor1());
pText->SetAlpha((BYTE)m_oBrush.GetAlpha1());
@ -2990,7 +3002,8 @@ bool CPdfWriter::GetBaseFont14(const std::wstring& wsFontName, int nBase14)
return false;
if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, m_oFont.GetSize(), 72, 72))
return false;
m_pFont14 = m_pDocument->CreateFont14((PdfWriter::EStandard14Fonts)nBase14);
PdfWriter::EStandard14Fonts nType = (PdfWriter::EStandard14Fonts)nBase14;
m_pFont14 = m_pDocument->CreateFont14(wsFontPath, lFaceIndex, nType);
return !!m_pFont14;
}
bool CPdfWriter::UpdateFont()

View File

@ -785,9 +785,25 @@ namespace PdfWriter
return pForm;
}
CFont14* CDocument::CreateFont14(EStandard14Fonts eType)
CFont14* CDocument::CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType)
{
return new CFont14(m_pXref, this, eType);
CFont14* pFont = FindFont14(wsFontPath, unIndex);
if (pFont)
return pFont;
pFont = new CFont14(m_pXref, this, eType);
m_vFonts14.push_back(TFontInfo(wsFontPath, unIndex, pFont));
return pFont;
}
CFont14* CDocument::FindFont14(const std::wstring& wsFontPath, unsigned int unIndex)
{
for (int nIndex = 0, nCount = m_vFonts14.size(); nIndex < nCount; nIndex++)
{
TFontInfo& oInfo = m_vFonts14.at(nIndex);
if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex)
return (CFont14*)oInfo.pFont;
}
return NULL;
}
CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex)
{

View File

@ -157,7 +157,8 @@ namespace PdfWriter
CImageDict* CreateImage();
CXObject* CreateForm(CImageDict* pImage, const std::string& sName);
CFont14* CreateFont14(EStandard14Fonts eType);
CFont14* CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType);
CFont14* FindFont14 (const std::wstring& wsFontPath, unsigned int unIndex);
CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);
CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);
CFontTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);
@ -291,6 +292,7 @@ namespace PdfWriter
std::vector<CShading*> m_vShadings;
std::vector<TFontInfo> m_vCidTTFonts;
std::vector<TFontInfo> m_vTTFonts;
std::vector<TFontInfo> m_vFonts14;
CFont14* m_pDefaultCheckBoxFont;
CDictObject* m_pTransparencyGroup;
std::vector<CFontCidTrueType*> m_vFreeTypeFonts;

View File

@ -51,6 +51,10 @@ namespace PdfWriter
{
return fontUnknownType;
}
virtual unsigned int GetWidth(unsigned short ushCode)
{
return 0;
}
protected:

View File

@ -57,5 +57,46 @@ namespace PdfWriter
Add("Type", "Font");
Add("Subtype", "Type1");
Add("BaseFont", c_sStandardFontNames[(int)eType]);
m_ushCodesCount = 0;
}
unsigned int CFont14::GetWidth(unsigned short ushCode)
{
std::map<unsigned int, unsigned short>::const_iterator oIter = m_mUnicodeToCode.find(ushCode);
if (oIter == m_mUnicodeToCode.end())
return 0;
ushCode = oIter->second;
if (ushCode >= m_vWidths.size())
return 0;
return m_vWidths.at(ushCode);
}
void CFont14::AddWidth(unsigned int nWidth)
{
m_vWidths.push_back(nWidth);
}
unsigned short CFont14::EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew)
{
std::map<unsigned int, unsigned short>::const_iterator oIter = m_mUnicodeToCode.find(unUnicode);
if (oIter != m_mUnicodeToCode.end())
return oIter->second;
unsigned short ushCode = EncodeGID(unGID, bNew);
m_mUnicodeToCode.insert(std::pair<unsigned int, unsigned short>(unUnicode, ushCode));
return ushCode;
}
unsigned short CFont14::EncodeGID(const unsigned int& unGID, bool& bNew)
{
for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++)
{
if (unGID == m_vCodeToGid.at(ushCurCode))
return ushCurCode;
}
unsigned short ushCode = m_ushCodesCount++;
m_vCodeToGid.push_back(unGID);
bNew = true;
return ushCode;
}
}

View File

@ -46,6 +46,16 @@ namespace PdfWriter
{
return fontType1;
}
unsigned int GetWidth(unsigned short ushCode);
void AddWidth(unsigned int nWidth);
unsigned short EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew);
unsigned short EncodeGID(const unsigned int& unGID, bool& bNew);
private:
unsigned short m_ushCodesCount;
std::map<unsigned int, unsigned short> m_mUnicodeToCode;
std::vector<unsigned int> m_vCodeToGid;
std::vector<unsigned int> m_vWidths;
};
}

View File

@ -58,7 +58,6 @@ namespace PdfWriter
CFontTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex);
~CFontTrueType();
unsigned int GetWidth(unsigned short ushCode);
int GetLineHeight() const
{
return m_nLineHeight;

View File

@ -1199,6 +1199,15 @@ namespace PdfWriter
m_pStream->WriteBinary(sText, unLen, NULL);
m_pStream->WriteChar('>');
}
else if (fontType1 == eType)
{
unLen = unLen / 2;
BYTE* sText2 = new BYTE[unLen];
for (int i = 0; i < unLen; ++i)
sText2[i] = sText[i * 2 + 1];
m_pStream->WriteEscapeText(sText2, unLen);
RELEASEARRAYOBJECTS(sText2);
}
else
{
m_pStream->WriteEscapeText(sText, unLen);

View File

@ -177,7 +177,7 @@ void CCommandManager::Flush()
double dX = pText->GetX();
double dY = pText->GetY();
double dTextSize = pText->GetSize();
double dWidth = ((PdfWriter::CFontCidTrueType*)pText->GetFont())->GetWidth(ushCode) / 1000.0 * dTextSize;
double dWidth = pText->GetFont()->GetWidth(ushCode) / 1000.0 * dTextSize;
if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize))
{