GoTo action creation

This commit is contained in:
Jakub Melka
2020-11-12 18:50:40 +01:00
parent 1382ead109
commit 2cdad1482d
6 changed files with 665 additions and 258 deletions

View File

@@ -469,6 +469,210 @@ PDFDestination PDFDestination::parse(const PDFObjectStorage* storage, PDFObject
return result;
}
void PDFDestination::setDestinationType(DestinationType destinationType)
{
m_destinationType = destinationType;
}
void PDFDestination::setLeft(PDFReal left)
{
m_left = left;
}
void PDFDestination::setTop(PDFReal top)
{
m_top = top;
}
void PDFDestination::setRight(PDFReal right)
{
m_right = right;
}
void PDFDestination::setBottom(PDFReal bottom)
{
m_bottom = bottom;
}
void PDFDestination::setZoom(PDFReal zoom)
{
m_zoom = zoom;
}
void PDFDestination::setName(const QByteArray& name)
{
m_name = name;
}
void PDFDestination::setPageReference(PDFObjectReference pageReference)
{
m_pageReference = pageReference;
}
void PDFDestination::setPageIndex(PDFInteger pageIndex)
{
m_pageIndex = pageIndex;
}
PDFDestination PDFDestination::createXYZ(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal zoom)
{
PDFDestination result;
result.setDestinationType(DestinationType::XYZ);
result.setPageReference(page);
result.setLeft(left);
result.setTop(top);
result.setZoom(zoom);
return result;
}
PDFDestination PDFDestination::createFit(PDFObjectReference page)
{
PDFDestination result;
result.setDestinationType(DestinationType::Fit);
result.setPageReference(page);
return result;
}
PDFDestination PDFDestination::createFitH(PDFObjectReference page, PDFReal top)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitH);
result.setPageReference(page);
result.setTop(top);
return result;
}
PDFDestination PDFDestination::createFitV(PDFObjectReference page, PDFReal left)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitV);
result.setPageReference(page);
result.setLeft(left);
return result;
}
PDFDestination PDFDestination::createFitR(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal right, PDFReal bottom)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitR);
result.setPageReference(page);
result.setLeft(left);
result.setTop(top);
result.setRight(right);
result.setBottom(bottom);
return result;
}
PDFDestination PDFDestination::createFitB(PDFObjectReference page)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitB);
result.setPageReference(page);
return result;
}
PDFDestination PDFDestination::createFitBH(PDFObjectReference page, PDFReal top)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitBH);
result.setPageReference(page);
result.setTop(top);
return result;
}
PDFDestination PDFDestination::createFitBV(PDFObjectReference page, PDFReal left)
{
PDFDestination result;
result.setDestinationType(DestinationType::FitBV);
result.setPageReference(page);
result.setLeft(left);
return result;
}
PDFDestination PDFDestination::createNamed(const QByteArray& name)
{
PDFDestination result;
result.setDestinationType(DestinationType::Named);
result.setName(name);
return result;
}
bool PDFDestination::hasLeft() const
{
switch (m_destinationType)
{
case DestinationType::XYZ:
case DestinationType::FitV:
case DestinationType::FitBV:
case DestinationType::FitR:
return true;
default:
break;
}
return false;
}
bool PDFDestination::hasTop() const
{
switch (m_destinationType)
{
case DestinationType::XYZ:
case DestinationType::FitH:
case DestinationType::FitBH:
case DestinationType::FitR:
return true;
default:
break;
}
return false;
}
bool PDFDestination::hasRight() const
{
switch (m_destinationType)
{
case DestinationType::FitR:
return true;
default:
break;
}
return false;
}
bool PDFDestination::hasBottom() const
{
switch (m_destinationType)
{
case DestinationType::FitR:
return true;
default:
break;
}
return false;
}
bool PDFDestination::hasZoom() const
{
switch (m_destinationType)
{
case DestinationType::XYZ:
return true;
default:
break;
}
return false;
}
PDFFormAction::FieldList PDFFormAction::parseFieldList(const PDFObjectStorage* storage, PDFObject object, FieldScope& fieldScope)
{
FieldList result;

View File

@@ -79,7 +79,7 @@ enum class DestinationType
/// destination has almost exactly same syntax as page destination, it should be checked,
/// if indirect reference returned by function \p getPageReference references really page,
/// or some structure element.
class PDFDestination
class PDFFORQTLIBSHARED_EXPORT PDFDestination
{
public:
explicit inline PDFDestination() = default;
@@ -100,6 +100,35 @@ public:
/// \param object Destination object
static PDFDestination parse(const PDFObjectStorage* storage, PDFObject object);
void setDestinationType(DestinationType destinationType);
void setLeft(PDFReal left);
void setTop(PDFReal top);
void setRight(PDFReal right);
void setBottom(PDFReal bottom);
void setZoom(PDFReal zoom);
void setName(const QByteArray& name);
void setPageReference(PDFObjectReference pageReference);
void setPageIndex(PDFInteger pageIndex);
static PDFDestination createXYZ(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal zoom);
static PDFDestination createFit(PDFObjectReference page);
static PDFDestination createFitH(PDFObjectReference page, PDFReal top);
static PDFDestination createFitV(PDFObjectReference page, PDFReal left);
static PDFDestination createFitR(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal right, PDFReal bottom);
static PDFDestination createFitB(PDFObjectReference page);
static PDFDestination createFitBH(PDFObjectReference page, PDFReal top);
static PDFDestination createFitBV(PDFObjectReference page, PDFReal left);
static PDFDestination createNamed(const QByteArray& name);
bool hasLeft() const;
bool hasTop() const;
bool hasRight() const;
bool hasBottom() const;
bool hasZoom() const;
bool isValid() const { return m_destinationType != DestinationType::Invalid; }
bool isNamedDestination() const { return m_destinationType == DestinationType::Named; }
private:
DestinationType m_destinationType = DestinationType::Invalid;
PDFReal m_left = 0.0;

View File

@@ -71,6 +71,82 @@ void PDFObjectFactory::endDictionaryItem()
std::get<PDFDictionary>(dictionaryItem.object).addEntry(PDFInplaceOrMemoryString(qMove(topItem.itemName)), qMove(std::get<PDFObject>(topItem.object)));
}
PDFObjectFactory& PDFObjectFactory::operator<<(const PDFDestination& destination)
{
if (!destination.isValid())
{
*this << PDFObject();
return *this;
}
if (destination.isNamedDestination())
{
*this << WrapName(destination.getName());
}
else
{
beginArray();
// Destination
if (destination.getPageReference().isValid())
{
*this << destination.getPageReference();
}
else
{
*this << destination.getPageIndex();
}
// Type
QByteArray type;
switch (destination.getDestinationType())
{
case DestinationType::XYZ:
type = "XYZ";
break;
case DestinationType::Fit:
type = "Fit";
break;
case DestinationType::FitH:
type = "FitH";
break;
case DestinationType::FitV:
type = "FitV";
break;
case DestinationType::FitR:
type = "FitR";
break;
case DestinationType::FitB:
type = "FitB";
break;
case DestinationType::FitBH:
type = "FitBH";
break;
case DestinationType::FitBV:
type = "FitBV";
break;
default:
Q_ASSERT(false);
break;
}
*this << WrapName(type);
endArray();
}
return *this;
}
PDFObjectFactory& PDFObjectFactory::operator<<(FileAttachmentIcon icon)
{
switch (icon)
@@ -1288,6 +1364,26 @@ PDFObjectReference PDFDocumentBuilder::appendPage(QRectF mediaBox)
}
PDFObjectReference PDFDocumentBuilder::createActionGoTo(PDFDestination destination)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Action");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("S");
objectBuilder << WrapName("GoTo");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("D");
objectBuilder << destination;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference actionReference = addObject(objectBuilder.takeObject());
return actionReference;
}
PDFObjectReference PDFDocumentBuilder::createActionURI(QString URL)
{
PDFObjectFactory objectBuilder;

View File

@@ -115,6 +115,7 @@ public:
PDFObjectFactory& operator<<(const PDFObject& object);
PDFObjectFactory& operator<<(Stamp stamp);
PDFObjectFactory& operator<<(FileAttachmentIcon icon);
PDFObjectFactory& operator<<(const PDFDestination& destination);
/// Treat containers - write them as array
template<typename Container, typename ValueType = decltype(*std::begin(std::declval<Container>()))>
@@ -367,6 +368,11 @@ public:
PDFObjectReference appendPage(QRectF mediaBox);
/// Creates GoTo action. This action changes view to a specific destination in the same document.
/// \param destination Destination
PDFObjectReference createActionGoTo(PDFDestination destination);
/// Creates URI action.
/// \param URL Target URL
PDFObjectReference createActionURI(QString URL);