mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-13 10:10:42 +01:00
3D PDF annotation beginning
This commit is contained in:
parent
6d9744886a
commit
a87670df1d
@ -31,6 +31,74 @@ constexpr const std::array<std::pair<const char*, RichMediaType>, 4> richMediaTy
|
||||
std::pair<const char*, RichMediaType>{ "Video", RichMediaType::Video }
|
||||
};
|
||||
|
||||
class PDF3DAuxiliaryParser
|
||||
{
|
||||
public:
|
||||
PDF3DAuxiliaryParser() = delete;
|
||||
|
||||
/// Parses 4x4 transformation matrix
|
||||
/// \param storage Storage
|
||||
/// \param object Object
|
||||
static QMatrix4x4 parseMatrix4x4(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
/// Parses 3D annotation color
|
||||
static QColor parseColor(const PDFObjectStorage* storage, PDFObject object, QColor defaultColor);
|
||||
};
|
||||
|
||||
QMatrix4x4 PDF3DAuxiliaryParser::parseMatrix4x4(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
QMatrix4x4 matrix;
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
std::vector<PDFReal> elements = loader.readNumberArray(object);
|
||||
if (elements.size() == 12)
|
||||
{
|
||||
const PDFReal a = elements[ 0];
|
||||
const PDFReal b = elements[ 1];
|
||||
const PDFReal c = elements[ 2];
|
||||
const PDFReal d = elements[ 3];
|
||||
const PDFReal e = elements[ 4];
|
||||
const PDFReal f = elements[ 5];
|
||||
const PDFReal g = elements[ 6];
|
||||
const PDFReal h = elements[ 7];
|
||||
const PDFReal i = elements[ 8];
|
||||
const PDFReal tx = elements[ 9];
|
||||
const PDFReal ty = elements[10];
|
||||
const PDFReal tz = elements[11];
|
||||
|
||||
matrix = QMatrix4x4(a, b, c, 0,
|
||||
d, e, f, 0,
|
||||
g, h, i, 0,
|
||||
tx, ty, tz, 1.0);
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
QColor PDF3DAuxiliaryParser::parseColor(const PDFObjectStorage* storage, PDFObject object, QColor defaultColor)
|
||||
{
|
||||
object = storage->getObject(object);
|
||||
|
||||
// If color is invalid according to the specification, then return default value
|
||||
if (object.isArray())
|
||||
{
|
||||
const PDFArray* array = object.getArray();
|
||||
if (array->getCount() == 4)
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
if (loader.readName(array->getItem(0)) == "DeviceRGB")
|
||||
{
|
||||
const PDFReal r = loader.readNumber(array->getItem(1), 0.0);
|
||||
const PDFReal g = loader.readNumber(array->getItem(2), 0.0);
|
||||
const PDFReal b = loader.readNumber(array->getItem(3), 0.0);
|
||||
return QColor::fromRgbF(r, g, b, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
PDFSound PDFSound::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDFSound result;
|
||||
@ -876,7 +944,7 @@ PDF3DActivation PDF3DActivation::parse(const PDFObjectStorage* storage, PDFObjec
|
||||
std::pair<const char*, TriggerMode>{ "PV", TriggerMode::PageVisibility }
|
||||
};
|
||||
|
||||
constexpr const std::array<std::pair<const char*, ActivationMode>, 3> deactivationModes = {
|
||||
constexpr const std::array<std::pair<const char*, TriggerMode>, 3> deactivationModes = {
|
||||
std::pair<const char*, TriggerMode>{ "XD", TriggerMode::ExplicitlyByUserAction },
|
||||
std::pair<const char*, TriggerMode>{ "PC", TriggerMode::PageFocus },
|
||||
std::pair<const char*, TriggerMode>{ "PI", TriggerMode::PageVisibility }
|
||||
@ -908,4 +976,219 @@ PDF3DActivation PDF3DActivation::parse(const PDFObjectStorage* storage, PDFObjec
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DRenderMode PDF3DRenderMode::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DRenderMode result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
constexpr const std::array<std::pair<const char*, RenderMode>, 15> renderModes = {
|
||||
std::pair<const char*, RenderMode>{ "Solid", RenderMode::Solid },
|
||||
std::pair<const char*, RenderMode>{ "SolidWireframe", RenderMode::SolidWireframe },
|
||||
std::pair<const char*, RenderMode>{ "Transparent", RenderMode::Transparent },
|
||||
std::pair<const char*, RenderMode>{ "TransparentWireframe", RenderMode::TransparentWireframe },
|
||||
std::pair<const char*, RenderMode>{ "BoundingBox", RenderMode::BoundingBox },
|
||||
std::pair<const char*, RenderMode>{ "TransparentBoundingBox", RenderMode::TransparentBoundingBox },
|
||||
std::pair<const char*, RenderMode>{ "TransparentBoundingBoxOutline", RenderMode::TransparentBoundingBoxOutline },
|
||||
std::pair<const char*, RenderMode>{ "Wireframe", RenderMode::Wireframe },
|
||||
std::pair<const char*, RenderMode>{ "ShadedWireframe", RenderMode::ShadedWireframe },
|
||||
std::pair<const char*, RenderMode>{ "HiddenWireframe", RenderMode::HiddenWireframe },
|
||||
std::pair<const char*, RenderMode>{ "Vertices", RenderMode::Vertices },
|
||||
std::pair<const char*, RenderMode>{ "ShadedVertices", RenderMode::ShadedVertices },
|
||||
std::pair<const char*, RenderMode>{ "Illustration", RenderMode::Illustration },
|
||||
std::pair<const char*, RenderMode>{ "SolidOutline", RenderMode::SolidOutline },
|
||||
std::pair<const char*, RenderMode>{ "ShadedIllustration", RenderMode::ShadedIllustration }
|
||||
};
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
result.m_renderMode = loader.readEnumByName(dictionary->get("Subtype"), renderModes.cbegin(), renderModes.cend(), RenderMode::Solid);
|
||||
result.m_auxiliaryColor = PDF3DAuxiliaryParser::parseColor(storage, dictionary->get("AC"), Qt::black);
|
||||
result.m_faceColor = PDF3DAuxiliaryParser::parseColor(storage, dictionary->get("FC"), Qt::black);
|
||||
result.m_faceColorMode = (loader.readName(dictionary->get("FC")) != "BG") ? FaceColorMode::Color : FaceColorMode::BG;
|
||||
result.m_opacity = loader.readNumberFromDictionary(dictionary, "O", 0.5);
|
||||
result.m_creaseAngle = loader.readNumberFromDictionary(dictionary, "CV", 45.0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DNode PDF3DNode::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DNode result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
result.m_name = loader.readTextStringFromDictionary(dictionary, "N", QString());
|
||||
if (dictionary->hasKey("O"))
|
||||
{
|
||||
result.m_opacity = loader.readNumberFromDictionary(dictionary, "O", 1.0);
|
||||
}
|
||||
if (dictionary->hasKey("V"))
|
||||
{
|
||||
result.m_visibility = loader.readBooleanFromDictionary(dictionary, "V", true);
|
||||
}
|
||||
if (dictionary->hasKey("M"))
|
||||
{
|
||||
result.m_matrix = PDF3DAuxiliaryParser::parseMatrix4x4(storage, dictionary->get("M"));
|
||||
}
|
||||
result.m_instance = loader.readReferenceFromDictionary(dictionary, "Instance");
|
||||
result.m_data = loader.readTextStringFromDictionary(dictionary, "Data", QString());
|
||||
if (dictionary->hasKey("RM"))
|
||||
{
|
||||
result.m_renderMode = PDF3DRenderMode::parse(storage, dictionary->get("RM"));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DCrossSection PDF3DCrossSection::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DCrossSection result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
loader.readNumberArray(dictionary->get("C"), result.m_centerOfRotation.begin(), result.m_centerOfRotation.end());
|
||||
|
||||
PDFObject axesRotation = storage->getObject(dictionary->get("O"));
|
||||
if (const PDFArray* rotations = axesRotation.getArray())
|
||||
{
|
||||
if (rotations->getCount() == 3)
|
||||
{
|
||||
PDFObject xObject = storage->getObject(rotations->getItem(0));
|
||||
PDFObject yObject = storage->getObject(rotations->getItem(1));
|
||||
PDFObject zObject = storage->getObject(rotations->getItem(2));
|
||||
|
||||
auto readValue = [&result, &loader](const PDFObject& object, int index, Direction direction)
|
||||
{
|
||||
if (object.isNull())
|
||||
{
|
||||
result.m_perpendicularDirection = direction;
|
||||
result.m_rotationAngles[index] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.m_rotationAngles[index] = loader.readNumber(object, 0.0);
|
||||
}
|
||||
};
|
||||
|
||||
readValue(xObject, 0, Direction::X);
|
||||
readValue(yObject, 1, Direction::Y);
|
||||
readValue(zObject, 2, Direction::Z);
|
||||
}
|
||||
}
|
||||
|
||||
result.m_cutPlaneOpacity = loader.readNumberFromDictionary(dictionary, "PO", 0.5);
|
||||
result.m_cutPlaneColor = PDF3DAuxiliaryParser::parseColor(storage, dictionary->get("PC"), Qt::white);
|
||||
result.m_intersectionVisibility = loader.readBooleanFromDictionary(dictionary, "IV", false);
|
||||
result.m_intersectionColor = PDF3DAuxiliaryParser::parseColor(storage, dictionary->get("IC"), Qt::green);
|
||||
result.m_showTransparent = loader.readBooleanFromDictionary(dictionary, "ST", false);
|
||||
result.m_sectionCapping = loader.readBooleanFromDictionary(dictionary, "SC", false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DLightingScheme PDF3DLightingScheme::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DLightingScheme result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
constexpr const std::array<std::pair<const char*, LightingScheme>, 12> lightingSchemes = {
|
||||
std::pair<const char*, LightingScheme>{ "Artwork", LightingScheme::Artwork },
|
||||
std::pair<const char*, LightingScheme>{ "None", LightingScheme::None },
|
||||
std::pair<const char*, LightingScheme>{ "White", LightingScheme::White },
|
||||
std::pair<const char*, LightingScheme>{ "Day", LightingScheme::Day },
|
||||
std::pair<const char*, LightingScheme>{ "Night", LightingScheme::Night },
|
||||
std::pair<const char*, LightingScheme>{ "Hard", LightingScheme::Hard },
|
||||
std::pair<const char*, LightingScheme>{ "Primary", LightingScheme::Primary },
|
||||
std::pair<const char*, LightingScheme>{ "Blue", LightingScheme::Blue },
|
||||
std::pair<const char*, LightingScheme>{ "Red", LightingScheme::Red },
|
||||
std::pair<const char*, LightingScheme>{ "Cube", LightingScheme::Cube },
|
||||
std::pair<const char*, LightingScheme>{ "CAD", LightingScheme::CAD },
|
||||
std::pair<const char*, LightingScheme>{ "Headlamp", LightingScheme::Headlamp }
|
||||
};
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
result.m_scheme = loader.readEnumByName(dictionary->get("Subtype"), lightingSchemes.cbegin(), lightingSchemes.cend(), LightingScheme::Artwork);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DBackground PDF3DBackground::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DBackground result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
|
||||
// This is a hack to parse color in same way as in another objects
|
||||
PDFObject colorSpace = dictionary->get("CS");
|
||||
if (colorSpace.isNull())
|
||||
{
|
||||
colorSpace = PDFObject::createName(std::make_shared<PDFString>("DeviceRGB"));
|
||||
}
|
||||
std::vector<PDFReal> color = loader.readNumberArrayFromDictionary(dictionary, "C", { 1.0, 1.0, 1.0});
|
||||
PDFArray array;
|
||||
array.appendItem(colorSpace);
|
||||
for (PDFReal colorComponent : color)
|
||||
{
|
||||
array.appendItem(PDFObject::createReal(colorComponent));
|
||||
}
|
||||
PDFObject colorObject = PDFObject::createArray(std::make_shared<PDFArray>(qMove(array)));
|
||||
|
||||
result.m_color = PDF3DAuxiliaryParser::parseColor(storage, colorObject, Qt::white);
|
||||
result.m_entireAnnotation = loader.readBooleanFromDictionary(dictionary, "EA", false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDF3DProjection PDF3DProjection::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDF3DProjection result;
|
||||
|
||||
if (const PDFDictionary* dictionary = storage->getDictionaryFromObject(object))
|
||||
{
|
||||
constexpr const std::array<std::pair<const char*, Projection>, 2> projections = {
|
||||
std::pair<const char*, Projection>{ "O", Projection::Orthographic },
|
||||
std::pair<const char*, Projection>{ "P", Projection::Perspective }
|
||||
};
|
||||
|
||||
constexpr const std::array<std::pair<const char*, ClippingStyle>, 2> clippingStyles = {
|
||||
std::pair<const char*, ClippingStyle>{ "XNF", ClippingStyle::Explicit },
|
||||
std::pair<const char*, ClippingStyle>{ "ANF", ClippingStyle::Automatic }
|
||||
};
|
||||
|
||||
constexpr const std::array<std::pair<const char*, ScaleMode>, 5> scaleModes = {
|
||||
std::pair<const char*, ScaleMode>{ "W", ScaleMode::W },
|
||||
std::pair<const char*, ScaleMode>{ "H", ScaleMode::H },
|
||||
std::pair<const char*, ScaleMode>{ "Min", ScaleMode::Min },
|
||||
std::pair<const char*, ScaleMode>{ "Max", ScaleMode::Max },
|
||||
std::pair<const char*, ScaleMode>{ "Absolute", ScaleMode::Absolute }
|
||||
};
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
result.m_projection = loader.readEnumByName(dictionary->get("Subtype"), projections.cbegin(), projections.cend(), Projection::Orthographic);
|
||||
result.m_clippingStyle = loader.readEnumByName(dictionary->get("CS"), clippingStyles.cbegin(), clippingStyles.cend(), ClippingStyle::Automatic);
|
||||
result.m_near = loader.readNumberFromDictionary(dictionary, "N", 0.0);
|
||||
result.m_far = loader.readNumberFromDictionary(dictionary, "F", qInf());
|
||||
result.m_fieldOfViewAngle = loader.readNumberFromDictionary(dictionary, "FOV", 90.0);
|
||||
if (dictionary->hasKey("PS"))
|
||||
{
|
||||
result.m_projectionScalingDiameter = loader.readNumberFromDictionary(dictionary, "PS", 0.0);
|
||||
result.m_projectionScaleMode = loader.readEnumByName(dictionary->get("PS"), scaleModes.cbegin(), scaleModes.cend(), ScaleMode::Value);
|
||||
}
|
||||
result.m_scaleFactor = loader.readNumberFromDictionary(dictionary, "OS", 1.0);
|
||||
result.m_scaleMode = result.m_projectionScaleMode = loader.readEnumByName(dictionary->get("OB"), scaleModes.cbegin(), scaleModes.cend(), ScaleMode::Absolute);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pdffile.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
#include <map>
|
||||
#include <array>
|
||||
@ -31,6 +32,8 @@ namespace pdf
|
||||
{
|
||||
class PDFObjectStorage;
|
||||
|
||||
using PDFPoint3D = std::array<PDFReal, 3>;
|
||||
|
||||
struct PDFMediaMultiLanguageTexts
|
||||
{
|
||||
static PDFMediaMultiLanguageTexts parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
@ -899,8 +902,8 @@ public:
|
||||
Windowed
|
||||
};
|
||||
|
||||
TriggerMode getActivationTriggerMode() const { return m_activationMode; }
|
||||
TriggerMode getDeactivationTriggerMode() const { return m_deactivationMode; }
|
||||
TriggerMode getActivationTriggerMode() const { return m_activationTriggerMode; }
|
||||
TriggerMode getDeactivationTriggerMode() const { return m_deactivationTriggerMode; }
|
||||
ActivationMode getActivationMode() const { return m_activationMode; }
|
||||
ActivationMode getDeactivationMode() const { return m_deactivationMode; }
|
||||
bool hasToolbar() const { return m_toolbar; }
|
||||
@ -925,6 +928,228 @@ private:
|
||||
bool m_transparent = false;
|
||||
};
|
||||
|
||||
/// 3D PDF render mode
|
||||
class PDF3DRenderMode
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DRenderMode() = default;
|
||||
|
||||
enum class RenderMode
|
||||
{
|
||||
Solid,
|
||||
SolidWireframe,
|
||||
Transparent,
|
||||
TransparentWireframe,
|
||||
BoundingBox,
|
||||
TransparentBoundingBox,
|
||||
TransparentBoundingBoxOutline,
|
||||
Wireframe,
|
||||
ShadedWireframe,
|
||||
HiddenWireframe,
|
||||
Vertices,
|
||||
ShadedVertices,
|
||||
Illustration,
|
||||
SolidOutline,
|
||||
ShadedIllustration
|
||||
};
|
||||
|
||||
enum class FaceColorMode
|
||||
{
|
||||
BG, ///< Current background color
|
||||
Color ///< Color specified
|
||||
};
|
||||
|
||||
RenderMode getRenderMode() const { return m_renderMode; }
|
||||
QColor getAuxiliaryColor() const { return m_auxiliaryColor; }
|
||||
QColor getFaceColor() const { return m_faceColor; }
|
||||
FaceColorMode getFaceColorMode() const { return m_faceColorMode; }
|
||||
PDFReal getOpacity() const { return m_opacity; }
|
||||
PDFReal getCreaseAngle() const { return m_creaseAngle; }
|
||||
|
||||
/// Creates a new 3D render mode from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DRenderMode parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
RenderMode m_renderMode = RenderMode::Solid;
|
||||
QColor m_auxiliaryColor = Qt::black;
|
||||
QColor m_faceColor = Qt::black;
|
||||
FaceColorMode m_faceColorMode = FaceColorMode::BG;
|
||||
PDFReal m_opacity = 0.5;
|
||||
PDFReal m_creaseAngle = 45.0;
|
||||
};
|
||||
|
||||
/// 3D PDF node (part of 3D structure)
|
||||
class PDF3DNode
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DNode() = default;
|
||||
|
||||
const QString& getName() const { return m_name; }
|
||||
const std::optional<PDFReal>& getOpacity() const { return m_opacity; }
|
||||
const std::optional<bool>& getVisibility() const { return m_visibility; }
|
||||
const std::optional<QMatrix4x4>& getMatrix() const { return m_matrix; }
|
||||
PDFObjectReference getInstance() const { return m_instance; }
|
||||
const QString& getData() const { return m_data; }
|
||||
const std::optional<PDF3DRenderMode>& getRenderMode() const { return m_renderMode; }
|
||||
|
||||
/// Creates a new 3D node from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DNode parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
std::optional<PDFReal> m_opacity;
|
||||
std::optional<bool> m_visibility;
|
||||
std::optional<QMatrix4x4> m_matrix;
|
||||
PDFObjectReference m_instance;
|
||||
QString m_data;
|
||||
std::optional<PDF3DRenderMode> m_renderMode;
|
||||
};
|
||||
|
||||
/// 3D PDF Cross section
|
||||
class PDF3DCrossSection
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DCrossSection() = default;
|
||||
|
||||
enum class Direction
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z
|
||||
};
|
||||
|
||||
PDFPoint3D getCenterOfRotation() const { return m_centerOfRotation; }
|
||||
PDFPoint3D getRotationAngles() const { return m_rotationAngles; }
|
||||
Direction getPerpendicularDirection() const { return m_perpendicularDirection; }
|
||||
PDFReal getCutPlaneOpacity() const { return m_cutPlaneOpacity; }
|
||||
QColor getCutPlaneColor() const { return m_cutPlaneColor; }
|
||||
bool getIntersectionVisibility() const { return m_intersectionVisibility; }
|
||||
QColor getIntersectionColor() const { return m_intersectionColor; }
|
||||
bool getShowTransparent() const { return m_showTransparent; }
|
||||
bool getSectionCapping() const { return m_sectionCapping; }
|
||||
|
||||
/// Creates a new 3D cross section from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DCrossSection parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
PDFPoint3D m_centerOfRotation{};
|
||||
PDFPoint3D m_rotationAngles{};
|
||||
Direction m_perpendicularDirection = Direction::X;
|
||||
PDFReal m_cutPlaneOpacity = 0.5;
|
||||
QColor m_cutPlaneColor = Qt::white;
|
||||
bool m_intersectionVisibility = false;
|
||||
QColor m_intersectionColor = Qt::green;
|
||||
bool m_showTransparent = false;
|
||||
bool m_sectionCapping = false;
|
||||
};
|
||||
|
||||
/// 3D PDF lighting scheme
|
||||
class PDF3DLightingScheme
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DLightingScheme() = default;
|
||||
|
||||
enum class LightingScheme
|
||||
{
|
||||
Artwork,
|
||||
None,
|
||||
White,
|
||||
Day,
|
||||
Night,
|
||||
Hard,
|
||||
Primary,
|
||||
Blue,
|
||||
Red,
|
||||
Cube,
|
||||
CAD,
|
||||
Headlamp
|
||||
};
|
||||
|
||||
LightingScheme getLightingScheme() const { return m_scheme; }
|
||||
|
||||
/// Creates a new 3D lighting scheme from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DLightingScheme parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
LightingScheme m_scheme = LightingScheme::Artwork;
|
||||
};
|
||||
|
||||
/// 3D PDF background
|
||||
class PDF3DBackground
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DBackground() = default;
|
||||
|
||||
QColor getColor() const { return m_color; }
|
||||
bool getEntireAnnotation() const { return m_entireAnnotation; }
|
||||
|
||||
/// Creates a new 3D background from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DBackground parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
QColor m_color;
|
||||
bool m_entireAnnotation = false;
|
||||
};
|
||||
|
||||
/// 3D PDF projection
|
||||
class PDF3DProjection
|
||||
{
|
||||
public:
|
||||
explicit inline PDF3DProjection() = default;
|
||||
|
||||
enum class Projection
|
||||
{
|
||||
Orthographic,
|
||||
Perspective
|
||||
};
|
||||
|
||||
enum class ClippingStyle
|
||||
{
|
||||
Explicit,
|
||||
Automatic
|
||||
};
|
||||
|
||||
enum class ScaleMode
|
||||
{
|
||||
W,
|
||||
H,
|
||||
Min,
|
||||
Max,
|
||||
Absolute,
|
||||
Value ///< This means projection scaling diameter is defined
|
||||
};
|
||||
|
||||
Projection getProjection() const { return m_projection; }
|
||||
ClippingStyle getClippingStyle() const { return m_clippingStyle; }
|
||||
PDFReal getNearPlane() const { return m_near; }
|
||||
PDFReal getFarPlane() const { return m_far; }
|
||||
PDFReal getFieldOfViewAngle() const { return m_fieldOfViewAngle; }
|
||||
PDFReal getProjectionScalingDiameter() const { return m_projectionScalingDiameter; }
|
||||
ScaleMode getProjectionScaleMode() const { return m_projectionScaleMode; }
|
||||
PDFReal getScaleFactor() const { return m_scaleFactor; }
|
||||
ScaleMode getScaleMode() const { return m_scaleMode; }
|
||||
|
||||
/// Creates a new 3D projection from the object. If data are invalid, then invalid object
|
||||
/// is returned, no exception is thrown.
|
||||
static PDF3DProjection parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
private:
|
||||
Projection m_projection = Projection::Orthographic;
|
||||
ClippingStyle m_clippingStyle = ClippingStyle::Automatic;
|
||||
PDFReal m_near = 0.0;
|
||||
PDFReal m_far = qInf();
|
||||
PDFReal m_fieldOfViewAngle = 90.0;
|
||||
PDFReal m_projectionScalingDiameter = 0.0;
|
||||
ScaleMode m_projectionScaleMode = ScaleMode::W;
|
||||
PDFReal m_scaleFactor = 1.0;
|
||||
ScaleMode m_scaleMode = ScaleMode::Absolute;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFMULTIMEDIA_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user