Text Annot to WASM, create Popup annots for PDF

This commit is contained in:
Kulikova Svetlana
2023-08-01 18:36:25 +03:00
parent f2c439d8bc
commit c840748483
8 changed files with 552 additions and 122 deletions

View File

@ -582,6 +582,12 @@
rec["rect"]["x2"] = reader.readDouble2();
rec["rect"]["y2"] = reader.readDouble2();
let flags = reader.readInt();
// Уникальное имя - NM
if (flags & (1 << 0))
rec["UniqueName"] = reader.readString();
// Альтернативный текст аннотации - Contents
if (flags & (1 << 1))
rec["Contents"] = reader.readString();
// Эффекты границы - BE
if (flags & (1 << 2))
rec["borderCloudy"] = reader.readDouble();
@ -607,10 +613,9 @@
rec["dashed"].push(reader.readDouble());
}
}
if (flags & (1 << 17))
{
rec["Parent"] = reader.readInt();
}
// Дата последнего изменения - M
if (flags & (1 << 5))
rec["LastModified"] = reader.readString();
// Widget
let tc = reader.readInt();
if (tc)
@ -660,9 +665,8 @@
// Значение по-умолчанию - DV
if (flags & (1 << 8))
rec["defaultValue"] = reader.readString();
// Альтернативный текст аннотации - Contents
if (flags & (1 << 15))
rec["Contents"] = reader.readString();
if (flags & (1 << 17))
rec["Parent"] = reader.readInt();
if (flags & (1 << 18))
rec["name"] = reader.readString();
// Action

View File

@ -150,7 +150,7 @@ WASM_EXPORT BYTE* GetStructure(CGraphicsFileDrawing* pGraphics)
{
return pGraphics->GetStructure();
}
WASM_EXPORT BYTE* GetInteractiveFormsInfo (CGraphicsFileDrawing* pGraphics)
WASM_EXPORT BYTE* GetInteractiveFormsInfo(CGraphicsFileDrawing* pGraphics)
{
return pGraphics->GetInteractiveFormsInfo();
}
@ -184,6 +184,10 @@ WASM_EXPORT BYTE* GetButtonIcons(CGraphicsFileDrawing* pGraphics, int nRasterW,
return pGraphics->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nButtonWidget, sIconView);
}
WASM_EXPORT BYTE* GetAnnotationsInfo(CGraphicsFileDrawing* pGraphics, int nPageIndex)
{
return pGraphics->GetAnnots(nPageIndex);
}
WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics)
{
return pGraphics->DestroyText();
@ -350,6 +354,106 @@ void ReadAction(BYTE* pWidgets, int& i)
ReadAction(pWidgets, i);
}
void ReadAnnot(BYTE* pWidgets, int& i)
{
DWORD nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Annot - AP " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Flag " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Page " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "X1 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Y1 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "X2 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Y2 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Annot Flags " << nPathLength << ", ";
int nFlags = nPathLength;
if (nFlags & (1 << 0))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Unique name " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 1))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Contents " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 2))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "BE C " << (double)nPathLength / 100.0 << ", ";
}
if (nFlags & (1 << 3))
{
int nCLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "C ";
for (int j = 0; j < nCLength; ++j)
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << (double)nPathLength / 100.0 << " ";
}
std::cout << ", ";
}
if (nFlags & (1 << 4))
{
std::string arrBorder[] = {"solid", "beveled", "dashed", "inset", "underline"};
BYTE nBorderType = READ_BYTE(pWidgets + i);
i += 1;
std::cout << "Border type " << arrBorder[nBorderType] << " ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "width " << (double)nPathLength / 100.0 << ", ";
if (nBorderType == 2)
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Dash Pattern " << (double)nPathLength / 100.0 << " ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << (double)nPathLength / 100.0 << ", ";
}
}
if (nFlags & (1 << 5))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Last modified " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
}
void ReadInteractiveForms(BYTE* pWidgets, int& i)
{
DWORD nCOLength = READ_INT(pWidgets + i);
@ -423,90 +527,11 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
{
// Annot
DWORD nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Annot - AP " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Flag " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Page " << nPathLength << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "X1 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Y1 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "X2 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Y2 " << (double)nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Annot Flags " << nPathLength << ", ";
int nFlags = nPathLength;
if (nFlags & (1 << 2))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "BE C " << (double)nPathLength / 100.0 << ", ";
}
if (nFlags & (1 << 3))
{
int nCLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "C ";
for (int j = 0; j < nCLength; ++j)
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << (double)nPathLength / 100.0 << " ";
}
std::cout << ", ";
}
if (nFlags & (1 << 4))
{
std::string arrBorder[] = {"solid", "beveled", "dashed", "inset", "underline"};
BYTE nBorderType = READ_BYTE(pWidgets + i);
i += 1;
std::cout << "Border type " << arrBorder[nBorderType] << " ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "width " << (double)nPathLength / 100.0 << ", ";
if (nBorderType == 2)
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Dash Pattern " << (double)nPathLength / 100.0 << " ";
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << (double)nPathLength / 100.0 << ", ";
}
}
if (nFlags & (1 << 17))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Parent " << nPathLength << ", ";
}
ReadAnnot(pWidgets, i);
// Widget
DWORD nPathLength;
int nTCLength = READ_INT(pWidgets + i);
i += 4;
if (nTCLength)
@ -538,7 +563,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Flags " << nPathLength << ", ";
nFlags = nPathLength;
DWORD nFlags = nPathLength;
if (nFlags & (1 << 0))
{
@ -602,12 +627,11 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
std::cout << "DV " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 15))
if (nFlags & (1 << 17))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Contents " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
std::cout << "Parent " << nPathLength << ", ";
}
if (nFlags & (1 << 18))
{
@ -1531,6 +1555,120 @@ int main(int argc, char* argv[])
free(pWidgetsMK);
}
// Annots
if (true)
{
BYTE* pAnnots = GetAnnotationsInfo(pGrFile, -1);
nLength = READ_INT(pAnnots);
int i = 4;
nLength -= 4;
std::cout << std::endl;
while (i < nLength)
{
DWORD nPathLength = READ_BYTE(pAnnots + i);
i += 1;
std::string arrAnnots[] = {"Text", "Link", "FreeText", "Line", "Square", "Circle", "Polygon", "PolyLine",
"Highlight", "Underline", "Squiggly", "StrikeOut", "Stamp", "Caret", "Ink",
"Popup", "FileAttachment", "Sound", "Movie", "Widget", "Screen", "PrinterMark",
"TrapNet", "Watermark", "3D", "Redact"};
std::string sType = arrAnnots[nPathLength];
std::cout << "Type " << sType << ", ";
ReadAnnot(pAnnots, i);
// Markup
DWORD nFlags = 0;
if ((nPathLength < 18 && nPathLength != 1 && nPathLength != 15) || nPathLength == 25)
{
nFlags = READ_INT(pAnnots + i);
i += 4;
if (nFlags & (1 << 0))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "Popup " << nPathLength << ", ";
}
if (nFlags & (1 << 1))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "User " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 2))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "CA " << (double)nPathLength / 100.0 << ", ";
}
if (nFlags & (1 << 3))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "RC " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 4))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "CreationDate " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 5))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "Ref to " << nPathLength << ", ";
}
if (nFlags & (1 << 6))
{
nPathLength = READ_BYTE(pAnnots + i);
i += 1;
std::cout << "Reason " << nPathLength << ", ";
}
if (nFlags & (1 << 7))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "Subj " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
}
}
if (sType == "Text")
{
if (nFlags & (1 << 15))
std::cout << "Open true, ";
else
std::cout << "Open false, ";
if (nFlags & (1 << 16))
{
nPathLength = READ_BYTE(pAnnots + i);
i += 1;
std::string arrIcon[] = {"Comment", "Key", "Note", "Help", "NewParagraph", "Paragraph", "Insert", "Unknown"};
std::cout << "Icon " << arrIcon[nPathLength] << ", ";
}
// TODO
}
// TODO
else if (sType == "Popup")
{
}
std::cout << std::endl;
}
if (pAnnots)
free(pAnnots);
}
Close(pGrFile);
RELEASEARRAYOBJECTS(pCMapData);

View File

@ -128,6 +128,12 @@ public:
return ((CPdfFile*)pReader)->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nButtonWidget, sIconView);
return NULL;
}
BYTE* GetAnnots(int nPageIndex = -1)
{
if (nType == 0)
return ((CPdfFile*)pReader)->GetAnnots(nPageIndex);
return NULL;
}
std::wstring GetInfo()
{
return pReader->GetInfo();

View File

@ -842,6 +842,12 @@ BYTE* CPdfFile::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor,
return NULL;
return m_pInternal->pReader->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nButtonWidget, sIconView);
}
BYTE* CPdfFile::GetAnnots(int nPageIndex)
{
if (!m_pInternal->pReader)
return NULL;
return m_pInternal->pReader->GetAnnotations(nPageIndex);
}
// ------------------------------------------------------------------------

View File

@ -127,6 +127,7 @@ public:
BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1);
BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sButtonView = NULL);
BYTE* GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nButtonWidget = -1, const char* sIconView = NULL);
BYTE* GetAnnots (int nPageIndex = -1);
// --- WRITER ---

View File

@ -2758,7 +2758,6 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor
void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex)
{
double dHeight = pdfDoc->getPageCropHeight(nPageIndex + 1);
Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1);
if (!pPage)
return;
@ -2826,6 +2825,7 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex)
sType == "Squiggly" ||
sType == "StrikeOut")
{
/*
double x1 = 0.0, x2 = 0.0, x3 = 0.0, x4 = 0.0;
double y1 = 0.0, y2 = 0.0, y3 = 0.0, y4 = 0.0;
if (oAnnot.dictLookup("QuadPoints", &oObj)->isArray() && oObj.arrayGetLength() == 8)
@ -2849,6 +2849,23 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex)
oRes.AddDouble(y2);
oRes.AddDouble(y3);
oRes.AddDouble(y4);
*/
}
else if (sType == "Stamp")
{
}
else if (sType == "Caret")
{
}
else if (sType == "Ink")
{
}
else if (sType == "Popup")
{
pAnnot = new PdfReader::CAnnotPopup(pdfDoc, &oAnnotRef, nPageIndex);
}
// TODO Все аннотации

View File

@ -839,8 +839,13 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo
}
oObj.free();
// 16 - Альтернативный текст - Contents
DICT_LOOKUP_STRING(pField->fieldLookup, "Contents", 15, m_sContents);
// 18 - Родитель - Parent
if (oField.dictLookupNF("Parent", &oObj)->isRef())
{
m_unRefNumParent = oObj.getRefNum();
m_unFlags |= (1 << 17);
}
oObj.free();
// 19 - Частичное имя поля - T
DICT_LOOKUP_STRING(oField.dictLookup, "T", 18, m_sT);
@ -856,13 +861,109 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo
oAction.free();
}
//------------------------------------------------------------------------
// Popup
//------------------------------------------------------------------------
CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex)
{
m_unFlags = 0;
Object oAnnot, oObj;
XRef* pXref = pdfDoc->getXRef();
oAnnotRef->fetch(pXref, &oAnnot);
// 1 - Отображаться открытой - Open
if (oAnnot.dictLookup("Open", &oObj)->isBool() && oObj.getBool() == gTrue)
m_unFlags |= (1 << 0);
oObj.free();
// 2 - Родитель - Parent
if (oAnnot.dictLookupNF("Parent", &oObj)->isRef())
{
m_unFlags |= (1 << 1);
m_unRefNumParent = oObj.getRefNum();
}
oObj.free();
}
//------------------------------------------------------------------------
// Text
//------------------------------------------------------------------------
CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex)
{
Object oAnnot, oObj;
XRef* pXref = pdfDoc->getXRef();
oAnnotRef->fetch(pXref, &oAnnot);
// 16 - Отображаться открытой - Open
if (oAnnot.dictLookup("Open", &oObj)->isBool() && oObj.getBool() == gTrue)
m_unFlags |= (1 << 15);
oObj.free();
// 17 - Иконка - Name
if (oAnnot.dictLookup("Name", &oObj)->isName())
{
m_unFlags |= (1 << 16);
std::string sName(oObj.getName());
m_nName = 2; // Default: Note
if (sName == "Comment")
m_nName = 0;
else if (sName == "Key")
m_nName = 1;
else if (sName == "Help")
m_nName = 3;
else if (sName == "NewParagraph")
m_nName = 4;
else if (sName == "Paragraph")
m_nName = 5;
else if (sName == "Insert")
m_nName = 6;
}
oObj.free();
// 18 - Состояние - State
if (oAnnot.dictLookup("State", &oObj)->isString())
{
m_unFlags |= (1 << 17);
TextString* s = new TextString(oObj.getString());
std::string sState = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
if (sState == "Marked")
m_nState = 0;
else if (sState == "Unmarked")
m_nState = 1;
else if (sState == "Accepted")
m_nState = 0;
else if (sState == "Rejected")
m_nState = 1;
else if (sState == "Cancelled")
m_nState = 2;
else if (sState == "Completed")
m_nState = 3;
else if (sState == "None")
m_nState = 4;
else
m_nState = 5;
}
oObj.free();
// 19 - Модель состояния - StateModel
if (oAnnot.dictLookup("StateModel", &oObj)->isString())
{
m_unFlags |= (1 << 18);
TextString* s = new TextString(oObj.getString());
std::string sStateModel = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
if (sStateModel == "Marked")
m_nStateModel = 0;
else if (sStateModel == "Review")
m_nStateModel = 1;
else
m_nStateModel = 2;
}
oObj.free();
}
//------------------------------------------------------------------------
@ -986,6 +1087,37 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) :
m_dCA = oObj.getNum();
}
oObj.free();
// 4 - Форматированный текст - RC
if (oAnnot.dictLookup("RC", &oObj)->isStream())
{
// TODO streamGetBlock
}
else
{
oObj.free();
DICT_LOOKUP_STRING(oAnnot.dictLookup, "RC", 3, m_sRC);
}
// 5 - Дата создания - CreationDate
DICT_LOOKUP_STRING(oAnnot.dictLookup, "CreationDate", 4, m_sCreationDate);
// 6 - Ссылка на аннотацию ответ - IRT
if (oAnnot.dictLookupNF("IRT", &oObj)->isRef())
{
m_unFlags |= (1 << 5);
m_unRefNumIRT = oObj.getRefNum();
}
oObj.free();
// 7 - Тип аннотации ответа - RT
// TODO m_nRT
// 8 - Краткое описание - Subj
DICT_LOOKUP_STRING(oAnnot.dictLookup, "Subj", 7, m_sSubj);
// XXX - Назначение аннотации - IT
// TODO m_nIT записывается аннотациями которым это необходимо
}
CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField)
@ -1016,14 +1148,34 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField)
m_pRect[1] = dHeight - m_pRect[3];
m_pRect[3] = dHeight - dTemp;
// 1 - Уникальное имя - NM
if (pField->fieldLookup("NM", &oObj)->isString())
{
m_unAFlags |= (1 << 0);
TextString* s = new TextString(oObj.getString());
m_sNM = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
// 2 - Альтернативный текст - Contents
if (pField->fieldLookup("Contents", &oObj)->isString())
{
m_unAFlags |= (1 << 1);
TextString* s = new TextString(oObj.getString());
m_sContents = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
// 3 - Эффекты границы - BE
Object oBorderBE, oBorderBEI;
if (pField->fieldLookup("BE", &oObj)->isDict() && oObj.dictLookup("S", &oBorderBE)->isName("C") && oObj.dictLookup("I", &oBorderBEI)->isNum())
Object oBorderBEI;
if (pField->fieldLookup("BE", &oObj)->isDict() && oObj.dictLookup("S", &oObj)->isName("C") && oObj.dictLookup("I", &oBorderBEI)->isNum())
{
m_unAFlags |= (1 << 2);
m_dBE = oBorderBEI.getNum();
}
oObj.free(); oBorderBE.free(); oBorderBEI.free();
oObj.free(); oObj.free(); oBorderBEI.free();
// 4 - Специальный цвет для аннотации - C
if (pField->fieldLookup("C", &oObj)->isArray())
@ -1040,27 +1192,28 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField)
oObj.free();
// 5 - Границы и Dash Pattern - Border/BS
Object oBorder;
m_pBorder = NULL;
if (pField->fieldLookup("BS", &oBorder)->isDict())
m_pBorder = getBorder(&oBorder, true);
if (pField->fieldLookup("BS", &oObj)->isDict())
m_pBorder = getBorder(&oObj, true);
else
{
oBorder.free();
if (pField->fieldLookup("Border", &oBorder)->isArray() && oBorder.arrayGetLength() > 2)
m_pBorder = getBorder(&oBorder, false);
oObj.free();
if (pField->fieldLookup("Border", &oObj)->isArray() && oObj.arrayGetLength() > 2)
m_pBorder = getBorder(&oObj, false);
}
oBorder.free();
oObj.free();
if (m_pBorder && m_pBorder->nType != 5)
m_unAFlags |= (1 << 4);
// 18 - Родитель - Parent
if (oField.dictLookupNF("Parent", &oObj)->isRef())
{
m_unRefNumParent = oObj.getRefNum();
m_unAFlags |= (1 << 17);
}
oObj.free();
// 6 - Дата последнего изменения - M
if (pField->fieldLookup("M", &oObj)->isString())
{
m_unAFlags |= (1 << 5);
TextString* s = new TextString(oObj.getString());
m_sM = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
}
CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex)
@ -1107,6 +1260,26 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex)
}
oObj.free();
// 1 - Уникальное имя - NM
if (oAnnot.dictLookup("NM", &oObj)->isString())
{
m_unAFlags |= (1 << 0);
TextString* s = new TextString(oObj.getString());
m_sNM = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
// 2 - Альтернативный текст - Contents
if (oAnnot.dictLookup("Contents", &oObj)->isString())
{
m_unAFlags |= (1 << 1);
TextString* s = new TextString(oObj.getString());
m_sContents = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
// 3 - Эффекты границы - BE
Object oBorderBEI;
if (oAnnot.dictLookup("BE", &oObj)->isDict() && oObj.dictLookup("S", &oObj2)->isName("C") && oObj.dictLookup("I", &oBorderBEI)->isNum())
@ -1143,6 +1316,16 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex)
if (m_pBorder && m_pBorder->nType != 5)
m_unAFlags |= (1 << 4);
// 6 - Дата последнего изменения - M
if (oAnnot.dictLookup("M", &oObj)->isString())
{
m_unAFlags |= (1 << 5);
TextString* s = new TextString(oObj.getString());
m_sM = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
delete s;
}
oObj.free();
oAnnot.free();
}
@ -1194,6 +1377,10 @@ void CAnnot::ToWASM(NSWasm::CData& oRes)
for (int i = 0; i < 4; ++i)
oRes.WriteDouble(m_pRect[i]);
oRes.AddInt(m_unAFlags);
if (m_unAFlags & (1 << 0))
oRes.WriteString(m_sNM);
if (m_unAFlags & (1 << 1))
oRes.WriteString(m_sContents);
if (m_unAFlags & (1 << 2))
oRes.AddDouble(m_dBE);
if (m_unAFlags & (1 << 3))
@ -1204,8 +1391,8 @@ void CAnnot::ToWASM(NSWasm::CData& oRes)
}
if (m_pBorder && (m_unAFlags & (1 << 4)))
m_pBorder->ToWASM(oRes);
if (m_unAFlags & (1 << 17))
oRes.AddInt(m_unRefNumParent);
if (m_unAFlags & (1 << 5))
oRes.WriteString(m_sM);
}
void CBorderType::ToWASM(NSWasm::CData& oRes)
@ -1258,8 +1445,8 @@ void CAnnotWidget::ToWASM(NSWasm::CData& oRes)
}
if (m_unFlags & (1 << 8))
oRes.WriteString(m_sDV);
if (m_unFlags & (1 << 15))
oRes.WriteString(m_sContents);
if (m_unFlags & (1 << 17))
oRes.AddInt(m_unRefNumParent);
if (m_unFlags & (1 << 18))
oRes.WriteString(m_sT);
oRes.AddInt(m_arrAction.size());
@ -1436,4 +1623,52 @@ void CAnnotWidgetSig::ToWASM(NSWasm::CData& oRes)
CAnnotWidget::ToWASM(oRes);
}
void CMarkupAnnot::ToWASM(NSWasm::CData& oRes)
{
CAnnot::ToWASM(oRes);
oRes.AddInt(m_unFlags);
if (m_unFlags & (1 << 0))
oRes.AddInt(m_unRefNumPopup);
if (m_unFlags & (1 << 1))
oRes.WriteString(m_sT);
if (m_unFlags & (1 << 2))
oRes.AddDouble(m_dCA);
if (m_unFlags & (1 << 3))
oRes.WriteString(m_sRC);
if (m_unFlags & (1 << 4))
oRes.WriteString(m_sCreationDate);
if (m_unFlags & (1 << 5))
oRes.AddInt(m_unRefNumIRT);
if (m_unFlags & (1 << 6))
oRes.WriteBYTE(m_nRT);
if (m_unFlags & (1 << 7))
oRes.WriteString(m_sSubj);
}
void CAnnotText::ToWASM(NSWasm::CData& oRes)
{
oRes.WriteBYTE(0); // Text
CMarkupAnnot::ToWASM(oRes);
if (m_unFlags & (1 << 16))
oRes.WriteBYTE(m_nName);
if (m_unFlags & (1 << 17))
oRes.WriteBYTE(m_nState);
if (m_unFlags & (1 << 18))
oRes.WriteBYTE(m_nStateModel);
}
void CAnnotPopup::ToWASM(NSWasm::CData& oRes)
{
oRes.WriteBYTE(15); // Popup
CAnnot::ToWASM(oRes);
oRes.AddInt(m_unFlags);
if (m_unFlags & (1 << 1))
oRes.AddInt(m_unRefNumParent);
}
}

View File

@ -167,10 +167,12 @@ private:
unsigned int m_unAFlags;
unsigned int m_unAnnotFlag; // Флаг аннотации - F
unsigned int m_unRefNum; // Номер ссылки на объект
unsigned int m_unRefNumParent; // Номер ссылки на объект родителя
unsigned int m_unPage; // Страница
double m_pRect[4]; // Координаты
double m_dBE; // Эффекты границы
std::string m_sContents; // Отображаемый текст
std::string m_sNM; // Уникальное имя
std::string m_sM; // Дата последнего изменения
std::vector<double> m_arrC; // Специальный цвет
CBorderType* m_pBorder; // Граница
};
@ -192,6 +194,7 @@ public:
private:
unsigned int m_unR; // Поворот аннотации относительно страницы - R
unsigned int m_unRefNumParent; // Номер ссылки на объект родителя
std::vector<double> m_arrTC; // Цвет текста - из DA
std::vector<double> m_arrBC; // Цвет границ - BC
std::vector<double> m_arrBG; // Цвет фона - BG
@ -200,8 +203,7 @@ private:
BYTE m_nH; // Режим выделения - H
std::string m_sTU; // Альтернативное имя поля, используется во всплывающей подсказке и сообщениях об ошибке - TU
std::string m_sDS; // Строка стиля по умолчанию - DS
std::string m_sDV; // Значение по-умолчанию - DV
std::string m_sContents; // Альтернативный текст - Contents
std::string m_sDV; // Значение по-умолчанию - DV
std::string m_sT; // Частичное имя поля - T
};
@ -256,6 +258,22 @@ public:
void ToWASM(NSWasm::CData& oRes) override;
};
//------------------------------------------------------------------------
// PdfReader::CAnnotPopup
//------------------------------------------------------------------------
class CAnnotPopup final : public CAnnot
{
public:
CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex);
void ToWASM(NSWasm::CData& oRes) override;
private:
unsigned int m_unFlags;
unsigned int m_unRefNumParent; // Номер ссылки на объект родителя
};
//------------------------------------------------------------------------
// PdfReader::CMarkupAnnot
//------------------------------------------------------------------------
@ -267,17 +285,23 @@ public:
virtual void ToWASM(NSWasm::CData& oRes) override;
BYTE m_nIT; // Назначение аннотации
unsigned int m_unFlags;
private:
BYTE m_nRT; // Тип аннотации-ответа
unsigned int m_unRefNumPopup; // Номер ссылки на всплывающую аннотацию
unsigned int m_unRefNumIRT; // Номер ссылки на аннотацию-ответ
double m_dCA; // Значение непрозрачности
std::string m_sT; // Текстовая метка, пользователь добавивший аннотацию
std::string m_sRC; // Форматированный текст для отображения во всплывающем окне
std::string m_sCreationDate; // Дата создания
std::string m_sSubj; // Краткое описание
// TODO ExData Внешние данные, используется только для Markup3D
};
//------------------------------------------------------------------------
// PdfReader::CMarkupAnnot
// PdfReader::CAnnotText
//------------------------------------------------------------------------
class CAnnotText final : public CMarkupAnnot
@ -287,7 +311,6 @@ public:
void ToWASM(NSWasm::CData& oRes) override;
private:
bool m_bOpen; // Отображаться открытой?
BYTE m_nName; // Иконка
BYTE m_nState; // Состояние
BYTE m_nStateModel; // Модель состояния