summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc116
1 files changed, 86 insertions, 30 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
index 18534401946..3b88270c798 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
@@ -25,6 +25,7 @@
#include "GfxFont.h"
#include "Zoox.h"
#include "PDF417Barcode.h"
+#include "UTF8.h"
#include "XFAForm.h"
#ifdef _WIN32
@@ -446,7 +447,7 @@ XFAForm *XFAForm::load(PDFDoc *docA, Catalog *catalog,
fullNameIdx = new GHash();
xfaForm->scanNode(tmpl, name, fullName, gFalse, NULL,
nameCount, nameIdx, fullNameCount, fullNameIdx,
- catalog);
+ NULL, catalog);
delete nameCount;
delete nameIdx;
delete fullNameCount;
@@ -504,11 +505,6 @@ XFAForm::~XFAForm() {
gfree(pageOffsetY);
}
-//~ need to handle exclGroup
-//~ - fields in an exclGroup may/must(?) not have names
-//~ - each field has an items element with the the value when that
-//~ field is selected
-
// Scan <elem>. Constructs the node's name and full name. If <elem>
// is a field, creates an XFAFormField; else scans <elem>'s children.
void XFAForm::scanNode(ZxElement *elem,
@@ -516,7 +512,7 @@ void XFAForm::scanNode(ZxElement *elem,
GBool inPageSet, XFATableInfo *tableInfo,
GHash *nameCount, GHash *nameIdx,
GHash *fullNameCount, GHash *fullNameIdx,
- Catalog *catalog) {
+ GString *exclGroupName, Catalog *catalog) {
ZxAttr *attr;
GString *name, *fullName, *namePart, *fullNamePart;
GHash *childNameCount, *childNameIdx, *childFullNameCount, *childFullNameIdx;
@@ -575,7 +571,8 @@ void XFAForm::scanNode(ZxElement *elem,
}
if (elem->isElement("field")) {
- scanField(elem, name, fullName, inPageSet, tableInfo, colSpan, catalog);
+ scanField(elem, name, fullName, exclGroupName,
+ inPageSet, tableInfo, colSpan, catalog);
} else {
scanNonField(elem, name, fullName, inPageSet, tableInfo, colSpan,
childNameCount, childNameIdx,
@@ -652,7 +649,7 @@ void XFAForm::scanFullNames(ZxElement *elem, GHash *fullNameCount) {
}
void XFAForm::scanField(ZxElement *elem, GString *name, GString *fullName,
- GBool inPageSet,
+ GString *exclGroupName, GBool inPageSet,
XFATableInfo *tableInfo, int colSpan,
Catalog *catalog) {
double xSubOffset, ySubOffset, columnWidth, rowHeight;
@@ -679,6 +676,8 @@ void XFAForm::scanField(ZxElement *elem, GString *name, GString *fullName,
}
fields->append(new XFAFormField(this, elem, name->copy(), fullName->copy(),
+ exclGroupName ? exclGroupName->copy()
+ : (GString *)NULL,
curPageNum, curXOffset, curYOffset,
columnWidth, rowHeight));
@@ -699,6 +698,7 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
ZxNode *child;
ZxAttr *attr;
PDFRectangle *box;
+ GString *exclGroupName;
double xSubOffset, ySubOffset;
int savedPageNum;
@@ -744,7 +744,8 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
curXOffset += xSubOffset;
curYOffset += ySubOffset;
- } else if (elem->isElement("area")) {
+ } else if (elem->isElement("area") ||
+ elem->isElement("exclGroup")) {
xSubOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
ySubOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
curXOffset += xSubOffset;
@@ -780,11 +781,17 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
}
}
+ if (elem->isElement("exclGroup")) {
+ exclGroupName = name;
+ } else {
+ exclGroupName = NULL;
+ }
+
for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
if (child->isElement()) {
scanNode((ZxElement *)child, name, fullName, inPageSet,
newTableInfo, nameCount, nameIdx, fullNameCount, fullNameIdx,
- catalog);
+ exclGroupName, catalog);
}
}
@@ -871,12 +878,14 @@ FormField *XFAForm::getField(int idx) {
XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
GString *nameA, GString *fullNameA,
+ GString *exclGroupNameA,
int pageNumA, double xOffsetA, double yOffsetA,
double columnWidthA, double rowHeightA) {
xfaForm = xfaFormA;
xml = xmlA;
name = nameA;
fullName = fullNameA;
+ exclGroupName = exclGroupNameA;
pageNum = pageNumA;
xOffset = xOffsetA;
yOffset = yOffsetA;
@@ -887,6 +896,9 @@ XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
XFAFormField::~XFAFormField() {
delete name;
delete fullName;
+ if (exclGroupName) {
+ delete exclGroupName;
+ }
}
int XFAFormField::getPageNum() {
@@ -943,7 +955,9 @@ Unicode *XFAFormField::getValue(int *length) {
s = getFieldValue("text");
break;
} else if (node->isElement("checkButton")) {
- s = getFieldValue("integer");
+ if (!(s = getFieldValue("integer"))) {
+ s = getFieldValue("text");
+ }
break;
} else if (node->isElement("barcode")) {
s = getFieldValue("text");
@@ -1921,6 +1935,22 @@ GString *XFAFormField::getFieldValue(const char *valueChildType) {
}
}
}
+ if (exclGroupName) {
+ p = exclGroupName->getCString();
+ if (xfaForm->xml->getRoot() && !strncmp(p, "form.", 5)) {
+ if ((datasets =
+ xfaForm->xml->getRoot()->findFirstChildElement("xfa:datasets")) &&
+ (data = datasets->findFirstChildElement("xfa:data"))) {
+ elem = findFieldInDatasets(data, p + 5);
+ if (elem &&
+ elem->getFirstChild() &&
+ elem->getFirstChild()->isCharData() &&
+ ((ZxCharData *)elem->getFirstChild())->getData()->getLength() > 0) {
+ return ((ZxCharData *)elem->getFirstChild())->getData();
+ }
+ }
+ }
+ }
// check the <form> element
p = fullName->getCString();
@@ -1955,7 +1985,9 @@ GString *XFAFormField::getFieldValue(const char *valueChildType) {
ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
ZxNode *node;
+ ZxElement *result;
GString *nodeName;
+ char *next;
int curIdx, idx, n;
curIdx = 0;
@@ -1976,11 +2008,21 @@ ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
if (!partName[n]) {
return (ZxElement *)node;
} else if (partName[n] == '.') {
- return findFieldInDatasets((ZxElement *)node, partName + n + 1);
+ if ((result = findFieldInDatasets((ZxElement *)node,
+ partName + n + 1))) {
+ return result;
+ }
+ break;
}
}
}
}
+
+ // search for an "ancestor match"
+ if ((next = strchr(partName, '.'))) {
+ return findFieldInDatasets(elem, next + 1);
+ }
+
return NULL;
}
@@ -2054,14 +2096,26 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
double x, double y, double w, double h,
GBool whiteBackground,
GfxFontDict *fontDict, GString *appearBuf) {
+ GString *text2;
GfxFont *font;
const char *fontTag;
GString *s;
+ Unicode u;
double yTop, xx, yy, tw, charWidth, lineHeight;
double ascent, descent, rectX, rectY, rectW, rectH, blkH;
int nLines, line, i, j, k, c, rectI;
- //~ deal with Unicode text (is it UTF-8?)
+ // convert UTF-8 to Latin1
+ //~ this currently drops all non-Latin1 characters
+ text2 = new GString();
+ i = 0;
+ while (getUTF8(text, &i, &u)) {
+ if (u <= 0xff) {
+ text2->append((char)u);
+ } else {
+ text2->append('?');
+ }
+ }
// find the font
if ((font = findFont(fontDict, fontName, bold, italic))) {
@@ -2093,8 +2147,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
if (vAlign == xfaVAlignBottom || vAlign == xfaVAlignMiddle) {
nLines = 0;
i = 0;
- while (i < text->getLength()) {
- getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+ while (i < text2->getLength()) {
+ getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
++nLines;
i = k;
}
@@ -2114,9 +2168,9 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// write a series of lines of text
line = 0;
i = 0;
- while (i < text->getLength()) {
+ while (i < text2->getLength()) {
- getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+ getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
if (tw > rectW) {
rectW = tw;
}
@@ -2140,7 +2194,7 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", xx, yy);
appearBuf->append('(');
for (; i < j; ++i) {
- c = text->getChar(i) & 0xff;
+ c = text2->getChar(i) & 0xff;
if (c == '(' || c == ')' || c == '\\') {
appearBuf->append('\\');
appearBuf->append((char)c);
@@ -2172,13 +2226,13 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
xx = x;
break;
case xfaHAlignCenter:
- xx = x + (int)(0.5 * (combCells - text->getLength())) * tw;
+ xx = x + (int)(0.5 * (combCells - text2->getLength())) * tw;
break;
case xfaHAlignRight:
- xx = x + w - text->getLength() * tw;
+ xx = x + w - text2->getLength() * tw;
break;
}
- rectW = text->getLength() * tw;
+ rectW = text2->getLength() * tw;
switch (vAlign) {
case xfaVAlignTop:
default:
@@ -2195,8 +2249,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
rectH = ascent - descent;
// write the text string
- for (i = 0; i < text->getLength(); ++i) {
- c = text->getChar(i) & 0xff;
+ for (i = 0; i < text2->getLength(); ++i) {
+ c = text2->getChar(i) & 0xff;
if (font && !font->isCIDFont()) {
charWidth = fontSize * ((Gfx8BitFont *)font)->getWidth((Guchar)c);
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n",
@@ -2223,12 +2277,12 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// compute string width
if (font && !font->isCIDFont()) {
tw = 0;
- for (i = 0; i < text->getLength(); ++i) {
- tw += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));
+ for (i = 0; i < text2->getLength(); ++i) {
+ tw += ((Gfx8BitFont *)font)->getWidth(text2->getChar(i));
}
} else {
// otherwise, make a crude estimate
- tw = text->getLength() * 0.5;
+ tw = text2->getLength() * 0.5;
}
tw *= fontSize;
rectW = tw;
@@ -2264,8 +2318,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// write the text string
appearBuf->append('(');
- for (i = 0; i < text->getLength(); ++i) {
- c = text->getChar(i) & 0xff;
+ for (i = 0; i < text2->getLength(); ++i) {
+ c = text2->getChar(i) & 0xff;
if (c == '(' || c == ')' || c == '\\') {
appearBuf->append('\\');
appearBuf->append((char)c);
@@ -2304,6 +2358,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
appearBuf->insert(rectI, s);
delete s;
}
+
+ delete text2;
}
// Searches <fontDict> for a font matching(<fontName>, <bold>,
@@ -2734,7 +2790,7 @@ GString *XFAFormField::pictureFormatDateTime(GString *value, GString *picture) {
u <<= 4;
if (c >= '0' && c <= '9') {
u += c - '0';
- } else if (c >= 'a' && c <= 'F') {
+ } else if (c >= 'a' && c <= 'f') {
u += c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
u += c - 'A' + 10;