Finishing of actions

This commit is contained in:
Jakub Melka 2019-11-24 15:43:27 +01:00
parent 18ac9166c0
commit a857e061b8
7 changed files with 339 additions and 4 deletions

View File

@ -46,6 +46,7 @@ SOURCES += \
sources/pdfobject.cpp \ sources/pdfobject.cpp \
sources/pdfoptionalcontent.cpp \ sources/pdfoptionalcontent.cpp \
sources/pdfoutline.cpp \ sources/pdfoutline.cpp \
sources/pdfpagetransition.cpp \
sources/pdfparser.cpp \ sources/pdfparser.cpp \
sources/pdfdocument.cpp \ sources/pdfdocument.cpp \
sources/pdfdocumentreader.cpp \ sources/pdfdocumentreader.cpp \
@ -83,6 +84,7 @@ HEADERS += \
sources/pdfobject.h \ sources/pdfobject.h \
sources/pdfoptionalcontent.h \ sources/pdfoptionalcontent.h \
sources/pdfoutline.h \ sources/pdfoutline.h \
sources/pdfpagetransition.h \
sources/pdfparser.h \ sources/pdfparser.h \
sources/pdfglobal.h \ sources/pdfglobal.h \
sources/pdfconstants.h \ sources/pdfconstants.h \

View File

@ -241,6 +241,38 @@ PDFActionPtr PDFAction::parseImpl(const PDFDocument* document, PDFObject object,
return PDFActionPtr(new PDFActionSetOCGState(qMove(items), isRadioButtonsPreserved)); return PDFActionPtr(new PDFActionSetOCGState(qMove(items), isRadioButtonsPreserved));
} }
else if (name == "Rendition")
{
PDFObject annotationObject = dictionary->get("AN");
std::optional<PDFRendition> rendition;
PDFObjectReference annotation = annotationObject.isReference() ? annotationObject.getReference() : PDFObjectReference();
PDFActionRendition::Operation operation = static_cast<PDFActionRendition::Operation>(loader.readIntegerFromDictionary(dictionary, "OP", 4));
QString javascript;
if (dictionary->hasKey("R"))
{
rendition = PDFRendition::parse(document, dictionary->get("R"));
}
PDFObject javascriptObject = document->getObject(dictionary->get("JS"));
if (javascriptObject.isString())
{
javascript = PDFEncoding::convertTextString(javascriptObject.getString());
}
else if (javascriptObject.isStream())
{
javascript = PDFEncoding::convertTextString(document->getDecodedStream(javascriptObject.getStream()));
}
return PDFActionPtr(new PDFActionRendition(qMove(rendition), annotation, operation, qMove(javascript)));
}
else if (name == "Trans")
{
return PDFActionPtr(new PDFActionTransition(PDFPageTransition::parse(document, dictionary->get("Trans"))));
}
else if (name == "GoTo3DView")
{
return PDFActionPtr(new PDFActionGoTo3DView(dictionary->get("TA"), dictionary->get("V")));
}
return PDFActionPtr(); return PDFActionPtr();
} }

View File

@ -22,6 +22,7 @@
#include "pdfobject.h" #include "pdfobject.h"
#include "pdffile.h" #include "pdffile.h"
#include "pdfmultimedia.h" #include "pdfmultimedia.h"
#include "pdfpagetransition.h"
#include <QSharedPointer> #include <QSharedPointer>
@ -46,7 +47,10 @@ enum class ActionType
Movie, Movie,
Hide, Hide,
Named, Named,
SetOCGState SetOCGState,
Rendition,
Transition,
GoTo3DView
}; };
enum class DestinationType enum class DestinationType
@ -388,9 +392,9 @@ public:
enum class SwitchType enum class SwitchType
{ {
ON, ON = 0,
OFF, OFF = 1,
Toggle Toggle = 2
}; };
using StateChangeItem = std::pair<SwitchType, PDFObjectReference>; using StateChangeItem = std::pair<SwitchType, PDFObjectReference>;
@ -413,6 +417,79 @@ private:
bool m_isRadioButtonsPreserved; bool m_isRadioButtonsPreserved;
}; };
class PDFActionRendition : public PDFAction
{
public:
enum class Operation
{
PlayAndAssociate = 0,
Stop = 1,
Pause = 2,
Resume = 3,
Play = 4
};
explicit inline PDFActionRendition(std::optional<PDFRendition>&& rendition, PDFObjectReference annotation, Operation operation, QString javascript) :
m_rendition(qMove(rendition)),
m_annotation(annotation),
m_operation(operation),
m_javascript(qMove(javascript))
{
}
virtual ActionType getType() const override { return ActionType::Rendition; }
const PDFRendition* getRendition() const { return m_rendition.has_value() ? &m_rendition.value() : nullptr; }
PDFObjectReference getAnnotation() const { return m_annotation; }
Operation getOperation() const { return m_operation; }
const QString& getJavascript() const { return m_javascript; }
private:
std::optional<PDFRendition> m_rendition;
PDFObjectReference m_annotation;
Operation m_operation;
QString m_javascript;
};
class PDFActionTransition : public PDFAction
{
public:
explicit inline PDFActionTransition(PDFPageTransition&& transition) :
m_transition(qMove(transition))
{
}
virtual ActionType getType() const override { return ActionType::Transition; }
const PDFPageTransition& getTransition() const { return m_transition; }
private:
PDFPageTransition m_transition;
};
class PDFActionGoTo3DView : public PDFAction
{
public:
explicit PDFActionGoTo3DView(PDFObject annotation, PDFObject view) :
m_annotation(qMove(annotation)),
m_view(qMove(view))
{
}
virtual ActionType getType() const override { return ActionType::GoTo3DView; }
const PDFObject& getAnnotation() const { return m_annotation; }
const PDFObject& getView() const { return m_view; }
private:
PDFObject m_annotation;
PDFObject m_view;
};
} // namespace pdf } // namespace pdf
#endif // PDFACTION_H #endif // PDFACTION_H

View File

@ -71,6 +71,23 @@ void PDFOutlineItem::parseImpl(const PDFDocument* document,
currentOutlineItem->setTitle(PDFEncoding::convertTextString(titleObject.getString())); currentOutlineItem->setTitle(PDFEncoding::convertTextString(titleObject.getString()));
} }
currentOutlineItem->setAction(PDFAction::parse(document, dictionary->get("A"))); currentOutlineItem->setAction(PDFAction::parse(document, dictionary->get("A")));
if (!currentOutlineItem->getAction() && dictionary->hasKey("Dest"))
{
currentOutlineItem->setAction(PDFActionPtr(new PDFActionGoTo(PDFDestination::parse(document, dictionary->get("Dest")))));
}
PDFDocumentDataLoaderDecorator loader(document);
std::vector<PDFReal> colors = loader.readNumberArrayFromDictionary(dictionary, "C", { 0.0, 0.0, 0.0 });
colors.resize(3, 0.0);
currentOutlineItem->setTextColor(QColor::fromRgbF(colors[0], colors[1], colors[2]));
PDFInteger flag = loader.readIntegerFromDictionary(dictionary, "F", 0);
currentOutlineItem->setFontItalics(flag & 0x1);
currentOutlineItem->setFontBold(flag & 0x2);
PDFObject structureElementObject = dictionary->get("SE");
if (structureElementObject.isReference())
{
currentOutlineItem->setStructureElement(structureElementObject.getReference());
}
// Parse children of this item // Parse children of this item
const PDFObject& firstItem = dictionary->get("First"); const PDFObject& firstItem = dictionary->get("First");
@ -97,6 +114,46 @@ void PDFOutlineItem::parseImpl(const PDFDocument* document,
} }
} }
PDFObjectReference PDFOutlineItem::getStructureElement() const
{
return m_structureElement;
}
void PDFOutlineItem::setStructureElement(PDFObjectReference structureElement)
{
m_structureElement = structureElement;
}
bool PDFOutlineItem::isFontBold() const
{
return m_fontBold;
}
void PDFOutlineItem::setFontBold(bool fontBold)
{
m_fontBold = fontBold;
}
bool PDFOutlineItem::isFontItalics() const
{
return m_fontItalics;
}
void PDFOutlineItem::setFontItalics(bool fontItalics)
{
m_fontItalics = fontItalics;
}
QColor PDFOutlineItem::getTextColor() const
{
return m_textColor;
}
void PDFOutlineItem::setTextColor(const QColor& textColor)
{
m_textColor = textColor;
}
const PDFAction* PDFOutlineItem::getAction() const const PDFAction* PDFOutlineItem::getAction() const
{ {
return m_action.get(); return m_action.get();

View File

@ -48,6 +48,18 @@ public:
const PDFAction* getAction() const; const PDFAction* getAction() const;
void setAction(const PDFActionPtr& action); void setAction(const PDFActionPtr& action);
QColor getTextColor() const;
void setTextColor(const QColor& textColor);
bool isFontItalics() const;
void setFontItalics(bool fontItalics);
bool isFontBold() const;
void setFontBold(bool fontBold);
PDFObjectReference getStructureElement() const;
void setStructureElement(PDFObjectReference structureElement);
private: private:
static void parseImpl(const PDFDocument* document, static void parseImpl(const PDFDocument* document,
PDFOutlineItem* parent, PDFOutlineItem* parent,
@ -57,6 +69,10 @@ private:
QString m_title; QString m_title;
std::vector<QSharedPointer<PDFOutlineItem>> m_children; std::vector<QSharedPointer<PDFOutlineItem>> m_children;
PDFActionPtr m_action; PDFActionPtr m_action;
PDFObjectReference m_structureElement;
QColor m_textColor;
bool m_fontItalics = false;
bool m_fontBold = false;
}; };
} // namespace pdf } // namespace pdf

View File

@ -0,0 +1,69 @@
// Copyright (C) 2019 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#include "pdfpagetransition.h"
#include "pdfdocument.h"
namespace pdf
{
PDFPageTransition PDFPageTransition::parse(const PDFDocument* document, PDFObject object)
{
PDFPageTransition result;
if (const PDFDictionary* dictionary = document->getDictionaryFromObject(object))
{
PDFDocumentDataLoaderDecorator loader(document);
constexpr const std::array<std::pair<const char*, Style>, 12> styles = {
std::pair<const char*, Style>{ "Split", Style::Split },
std::pair<const char*, Style>{ "Blinds", Style::Blinds },
std::pair<const char*, Style>{ "Box", Style::Box },
std::pair<const char*, Style>{ "Wipe", Style::Wipe },
std::pair<const char*, Style>{ "Dissolve", Style::Dissolve },
std::pair<const char*, Style>{ "Glitter", Style::Glitter },
std::pair<const char*, Style>{ "R", Style::R },
std::pair<const char*, Style>{ "Fly", Style::Fly },
std::pair<const char*, Style>{ "Push", Style::Push },
std::pair<const char*, Style>{ "Cover", Style::Cover },
std::pair<const char*, Style>{ "Uncover", Style::Uncover },
std::pair<const char*, Style>{ "Fade", Style::Fade }
};
constexpr const std::array<std::pair<const char*, Orientation>, 2> orientations = {
std::pair<const char*, Orientation>{ "H", Orientation::Horizontal },
std::pair<const char*, Orientation>{ "V", Orientation::Vertical }
};
constexpr const std::array<std::pair<const char*, Direction>, 2> directions = {
std::pair<const char*, Direction>{ "I", Direction::Inward },
std::pair<const char*, Direction>{ "O", Direction::Outward }
};
result.m_style = loader.readEnumByName(dictionary->get("S"), styles.cbegin(), styles.cend(), Style::R);
result.m_duration = loader.readNumberFromDictionary(dictionary, "D", 1.0);
result.m_orientation = loader.readEnumByName(dictionary->get("Dm"), orientations.cbegin(), orientations.cend(), Orientation::Horizontal);
result.m_direction = loader.readEnumByName(dictionary->get("M"), directions.cbegin(), directions.cend(), Direction::Inward);
result.m_angle = loader.readNumberFromDictionary(dictionary, "Di", 0.0);
result.m_scale = loader.readNumberFromDictionary(dictionary, "SS", 1.0);
result.m_rectangular = loader.readBooleanFromDictionary(dictionary, "B", false);
}
return result;
}
} // namespace pdf

View File

@ -0,0 +1,82 @@
// Copyright (C) 2019 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFPAGETRANSITION_H
#define PDFPAGETRANSITION_H
#include "pdfobject.h"
namespace pdf
{
class PDFDocument;
/// Page transition during presentation settings.
class PDFPageTransition
{
public:
enum class Style
{
Split,
Blinds,
Box,
Wipe,
Dissolve,
Glitter,
R,
Fly,
Push,
Cover,
Uncover,
Fade
};
enum class Orientation
{
Horizontal,
Vertical
};
enum class Direction
{
Inward,
Outward
};
static PDFPageTransition parse(const PDFDocument* document, PDFObject object);
Style getStyle() const { return m_style; }
PDFReal getDuration() const { return m_duration; }
Orientation getOrientation() const { return m_orientation; }
Direction getDirection() const { return m_direction; }
PDFReal getAngle() const { return m_angle; }
PDFReal getScale() const { return m_scale; }
bool getRectangular() const { return m_rectangular; }
private:
Style m_style = Style::R;
PDFReal m_duration = 1.0;
Orientation m_orientation = Orientation::Horizontal;
Direction m_direction = Direction::Inward;
PDFReal m_angle = 0.0;
PDFReal m_scale = 1.0;
bool m_rectangular = false;
};
} // namespace pdf
#endif // PDFPAGETRANSITION_H