Commit 0e91a397 authored by Inigo Martínez's avatar Inigo Martínez Committed by Albert Astals Cid

AnnotTextMarkup support and improved AnnotQuadrilaterals

parent c13952cd
......@@ -163,7 +163,117 @@ AnnotCalloutMultiLine::AnnotCalloutMultiLine(double x1, double y1, double x2,
// AnnotQuadrilateral
//------------------------------------------------------------------------
AnnotQuadrilateral::AnnotQuadrilateral(double x1, double y1,
AnnotQuadrilaterals::AnnotQuadrilaterals(Array *array, PDFRectangle *rect) {
int arrayLength = array->getLength();
GBool correct = gTrue;
int quadsLength = 0;
AnnotQuadrilateral **quads;
double *quadArray;
// default values
quadrilaterals = NULL;
quadrilateralsLength = 0;
if ((arrayLength % 8) == 0) {
int i = 0;
quadsLength = arrayLength / 8;
quads = (AnnotQuadrilateral **) gmallocn
((quadsLength), sizeof(AnnotQuadrilateral *));
quadArray = (double *) gmallocn (8, sizeof(double));
while (i < (quadsLength) && correct) {
for (int j = 0; j < 8 && correct; j++) {
Object obj;
if (array->get(i * 8 + j, &obj)->isNum()) {
quadArray[j] = obj.getNum();
if (quadArray[j] < rect->x1 || quadArray[j] > rect->x2 ||
quadArray[j] < rect->y1 || quadArray[j] < rect->y2)
correct = gFalse;
} else {
correct = gFalse;
}
}
if (correct)
quads[i] = new AnnotQuadrilateral(quadArray[0], quadArray[1],
quadArray[2], quadArray[3],
quadArray[4], quadArray[5],
quadArray[6], quadArray[7]);
i++;
}
gfree (quadArray);
if (correct) {
quadrilateralsLength = quadsLength;
quadrilaterals = quads;
} else {
for (int j = 0; j < i; j++)
delete quads[j];
gfree (quads);
}
}
}
AnnotQuadrilaterals::~AnnotQuadrilaterals() {
if (quadrilaterals) {
for(int i = 0; i < quadrilateralsLength; i++)
delete quadrilaterals[i];
gfree (quadrilaterals);
}
}
double AnnotQuadrilaterals::getX1(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getX1();
return 0;
}
double AnnotQuadrilaterals::getY1(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getY1();
return 0;
}
double AnnotQuadrilaterals::getX2(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getX2();
return 0;
}
double AnnotQuadrilaterals::getY2(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getY2();
return 0;
}
double AnnotQuadrilaterals::getX3(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getX3();
return 0;
}
double AnnotQuadrilaterals::getY3(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getY3();
return 0;
}
double AnnotQuadrilaterals::getX4(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getX4();
return 0;
}
double AnnotQuadrilaterals::getY4(int quadrilateral) {
if (quadrilateral >= 0 && quadrilateral < quadrilateralsLength)
return quadrilaterals[quadrilateral]->getY4();
return 0;
}
AnnotQuadrilaterals::AnnotQuadrilateral::AnnotQuadrilateral(double x1, double y1,
double x2, double y2, double x3, double y3, double x4, double y4) {
this->x1 = x1;
this->y1 = y1;
......@@ -2129,12 +2239,8 @@ AnnotLink::~AnnotLink() {
if (uriAction)
delete uriAction;
*/
if (quadrilaterals) {
for(int i = 0; i < quadrilateralsLength; i++)
delete quadrilaterals[i];
gfree (quadrilaterals);
}
if (quadrilaterals)
delete quadrilaterals;
}
void AnnotLink::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
......@@ -2174,74 +2280,14 @@ void AnnotLink::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
}
obj1.free();
*/
/*
* TODO:
* QuadPoints should be ignored if any coordinate in the array lies outside
* the region specified by Rect.
*/
if (dict->lookup("QuadPoints", &obj1)->isArray()) {
parseQuadPointsArray(obj1.getArray());
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
} else {
quadrilaterals = NULL;
}
obj1.free();
}
GBool AnnotLink::parseQuadPointsArray(Array *array) {
int arrayLength = array->getLength();
GBool correct = gTrue;
int quadsLength = 0, i = 0;
AnnotQuadrilateral **quads;
double *quadArray;
// default values
quadrilaterals = NULL;
quadrilateralsLength = 0;
if ((arrayLength % 8) != 0)
return gFalse;
quadsLength = arrayLength / 8;
quads = (AnnotQuadrilateral **) gmallocn
((quadsLength), sizeof(AnnotQuadrilateral *));
quadArray = (double *) gmallocn (8, sizeof(double));
while (i < (quadsLength) && correct) {
for (int j = 0; j < 8 && correct; j++) {
Object obj;
if (array->get(i * 8 + j, &obj)->isNum()) {
quadArray[j] = obj.getNum();
if (quadArray[j] < rect->x1 || quadArray[j] > rect->x2 ||
quadArray[j] < rect->y1 || quadArray[j] < rect->y2)
correct = gFalse;
} else {
correct = gFalse;
}
}
if (correct)
quads[i] = new AnnotQuadrilateral(quadArray[0], quadArray[1],
quadArray[2], quadArray[3],
quadArray[4], quadArray[5],
quadArray[6], quadArray[7]);
i++;
}
gfree (quadArray);
if (!correct) {
for (int j = 0; j < i; j++)
delete quads[j];
gfree (quads);
return gFalse;
}
quadrilateralsLength = quadsLength;
quadrilaterals = quads;
return gTrue;
}
//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------
......@@ -2395,6 +2441,180 @@ void AnnotFreeText::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
obj1.free();
}
//------------------------------------------------------------------------
// AnnotLine
//------------------------------------------------------------------------
AnnotLine::AnnotLine(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj) :
Annot(xrefA, acroForm, dict, catalog, obj), AnnotMarkup(xref, acroForm, dict, catalog, obj) {
type = typeLine;
initialize(xrefA, catalog, dict);
}
AnnotLine::~AnnotLine() {
if (interiorColor)
delete interiorColor;
if (measure)
delete measure;
}
void AnnotLine::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
Object obj1;
if (dict->lookup("L", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
Object obj2;
(obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
obj2.free();
(obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
obj2.free();
(obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
obj2.free();
(obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
obj2.free();
} else {
x1 = y1 = x2 = y2 = 0;
}
obj1.free();
if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
Object obj2;
if(obj1.arrayGet(0, &obj2)->isString())
startStyle = parseAnnotLineEndingStyle(obj2.getString());
else
startStyle = annotLineEndingNone;
obj2.free();
if(obj1.arrayGet(1, &obj2)->isString())
endStyle = parseAnnotLineEndingStyle(obj2.getString());
else
endStyle = annotLineEndingNone;
obj2.free();
} else {
startStyle = endStyle = annotLineEndingNone;
}
obj1.free();
if (dict->lookup("IC", &obj1)->isArray()) {
interiorColor = new AnnotColor(obj1.getArray());
} else {
interiorColor = NULL;
}
obj1.free();
if (dict->lookup("LL", &obj1)->isNum()) {
leaderLineLength = obj1.getNum();
} else {
leaderLineLength = 0;
}
obj1.free();
if (dict->lookup("LLE", &obj1)->isNum()) {
leaderLineExtension = obj1.getNum();
if (leaderLineExtension < 0)
leaderLineExtension = 0;
} else {
leaderLineExtension = 0;
}
obj1.free();
if (dict->lookup("Cap", &obj1)->isBool()) {
caption = obj1.getBool();
} else {
caption = gFalse;
}
obj1.free();
if (dict->lookup("IT", &obj1)->isName()) {
GooString *intentName = new GooString(obj1.getName());
if(!intentName->cmp("LineArrow")) {
intent = intentLineArrow;
} else if(!intentName->cmp("LineDimension")) {
intent = intentLineDimension;
} else {
intent = intentLineArrow;
}
delete intentName;
} else {
intent = intentLineArrow;
}
obj1.free();
if (dict->lookup("LLO", &obj1)->isNum()) {
leaderLineOffset = obj1.getNum();
if (leaderLineOffset < 0)
leaderLineOffset = 0;
} else {
leaderLineOffset = 0;
}
obj1.free();
if (dict->lookup("CP", &obj1)->isName()) {
GooString *captionName = new GooString(obj1.getName());
if(!captionName->cmp("Inline")) {
captionPos = captionPosInline;
} else if(!captionName->cmp("Top")) {
captionPos = captionPosTop;
} else {
captionPos = captionPosInline;
}
delete captionName;
} else {
captionPos = captionPosInline;
}
obj1.free();
if (dict->lookup("Measure", &obj1)->isDict()) {
measure = NULL;
} else {
measure = NULL;
}
obj1.free();
if ((dict->lookup("CO", &obj1)->isArray()) && (obj1.arrayGetLength() == 2)) {
Object obj2;
(obj1.arrayGet(0, &obj2)->isNum() ? captionTextHorizontal = obj2.getNum() :
captionTextHorizontal = 0);
obj2.free();
(obj1.arrayGet(1, &obj2)->isNum() ? captionTextVertical = obj2.getNum() :
captionTextVertical = 0);
obj2.free();
} else {
captionTextHorizontal = captionTextVertical = 0;
}
obj1.free();
}
//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
void AnnotTextMarkup::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
Object obj1;
if(dict->lookup("QuadPoints", &obj1)->isArray()) {
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
} else {
quadrilaterals = NULL;
}
obj1.free();
}
AnnotTextMarkup::~AnnotTextMarkup() {
if(quadrilaterals) {
delete quadrilaterals;
}
}
//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
......
......@@ -105,23 +105,43 @@ private:
// AnnotQuadrilateral
//------------------------------------------------------------------------
class AnnotQuadrilateral {
public:
AnnotQuadrilateral(double x1, double y1, double x2, double y2, double x3,
class AnnotQuadrilaterals {
class AnnotQuadrilateral {
public:
AnnotQuadrilateral(double x1, double y1, double x2, double y2, double x3,
double y3, double x4, double y4);
double getX1() const { return x1; }
double getY1() const { return y1; }
double getX2() const { return x2; }
double getY2() const { return y2; }
double getX3() const { return x3; }
double getY3() const { return y3; }
double getX4() const { return x4; }
double getY4() const { return y4; }
double getX1() const { return x1; }
double getY1() const { return y1; }
double getX2() const { return x2; }
double getY2() const { return y2; }
double getX3() const { return x3; }
double getY3() const { return y3; }
double getX4() const { return x4; }
double getY4() const { return y4; }
protected:
double x1, y1, x2, y2, x3, y3, x4, y4;
};
public:
AnnotQuadrilaterals(Array *array, PDFRectangle *rect);
virtual ~AnnotQuadrilaterals();
double getX1(int quadrilateral);
double getY1(int quadrilateral);
double getX2(int quadrilateral);
double getY2(int quadrilateral);
double getX3(int quadrilateral);
double getY3(int quadrilateral);
double getX4(int quadrilateral);
double getY4(int quadrilateral);
int getQuadrilateralsLength() const { return quadrilateralsLength; }
protected:
double x1, y1, x2, y2, x3, y3, x4, y4;
AnnotQuadrilateral** quadrilaterals;
int quadrilateralsLength;
};
//------------------------------------------------------------------------
......@@ -546,21 +566,18 @@ public:
// getDest
AnnotLinkEffect getLinkEffect() const { return linkEffect; }
Dict *getUriAction() const { return uriAction; }
AnnotQuadrilateral **getQuadrilaterals() const { return quadrilaterals; }
int getQuadrilateralsLength() const { return quadrilateralsLength; }
AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }
protected:
void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
GBool parseQuadPointsArray(Array *array);
Dict *actionDict; // A
//Dest
AnnotLinkEffect linkEffect; // H (Default I)
Dict *uriAction; // PA
AnnotQuadrilateral **quadrilaterals; // QuadPoints
int quadrilateralsLength;
AnnotQuadrilaterals *quadrilaterals; // QuadPoints
};
//------------------------------------------------------------------------
......@@ -616,6 +633,83 @@ protected:
AnnotLineEndingStyle endStyle; // LE (Default None)
};
//------------------------------------------------------------------------
// AnnotLine
//------------------------------------------------------------------------
class AnnotLine: public Annot, public AnnotMarkup {
public:
enum AnnotLineIntent {
intentLineArrow, // LineArrow
intentLineDimension // LineDimension
};
enum AnnotLineCaptionPos {
captionPosInline, // Inline
captionPosTop // Top
};
AnnotLine(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
virtual ~AnnotLine();
// getters
AnnotLineEndingStyle getStartStyle() const { return startStyle; }
AnnotLineEndingStyle getEndStyle() const { return endStyle; }
AnnotColor *getInteriorColor() const { return interiorColor; }
double getLeaderLineLength() const { return leaderLineLength; }
double getLeaderLineExtension() const { return leaderLineExtension; }
bool getCaption() const { return caption; }
AnnotLineIntent getIntent() const { return intent; }
double getLeaderLineOffset() const { return leaderLineOffset; }
AnnotLineCaptionPos getCaptionPos() const { return captionPos; }
Dict *getMeasure() const { return measure; }
double getCaptionTextHorizontal() const { return captionTextHorizontal; }
double getCaptionTextVertical() const { return captionTextVertical; }
protected:
void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
// required
double x1, y1, x2, y2; // L
// optional
// inherited from Annot
// AnnotBorderBS border; // BS
AnnotLineEndingStyle startStyle; // LE (Default [/None /None])
AnnotLineEndingStyle endStyle; //
AnnotColor *interiorColor; // IC
double leaderLineLength; // LL (Default 0)
double leaderLineExtension; // LLE (Default 0)
bool caption; // Cap (Default false)
AnnotLineIntent intent; // IT
double leaderLineOffset; // LLO
AnnotLineCaptionPos captionPos; // CP (Default Inline)
Dict *measure; // Measure
double captionTextHorizontal; // CO (Default [0, 0])
double captionTextVertical; //
};
//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
class AnnotTextMarkup: public Annot, public AnnotMarkup {
public:
AnnotTextMarkup(XRef *xrefA, Catalog *catalog, Dict *dict);
virtual ~AnnotTextMarkup();
AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }
protected:
void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
AnnotQuadrilaterals *quadrilaterals; // QuadPoints
};
//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
......
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