mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
XFA: layout algorithm (WIP)
This commit is contained in:
@ -89,16 +89,51 @@ private:
|
|||||||
class XFA_ParagraphSettings
|
class XFA_ParagraphSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PDFReal getFontEmSize() const;
|
PDFReal getFontEmSize() const;
|
||||||
void setFontEmSize(const PDFReal& fontEmSize);
|
void setFontEmSize(const PDFReal& fontEmSize);
|
||||||
|
|
||||||
PDFReal getFontSpaceSize() const;
|
PDFReal getFontSpaceSize() const;
|
||||||
void setFontSpaceSize(const PDFReal& fontSpaceSize);
|
void setFontSpaceSize(const PDFReal& fontSpaceSize);
|
||||||
|
|
||||||
|
Qt::Alignment getAlignment() const;
|
||||||
|
void setAlignment(const Qt::Alignment& alignment);
|
||||||
|
|
||||||
|
PDFReal getLineHeight() const;
|
||||||
|
void setLineHeight(const PDFReal& lineHeight);
|
||||||
|
|
||||||
|
QMarginsF getMargins() const;
|
||||||
|
void setMargins(const QMarginsF& margins);
|
||||||
|
|
||||||
|
PDFInteger getOrphans() const;
|
||||||
|
void setOrphans(const PDFInteger& orphans);
|
||||||
|
|
||||||
|
PDFReal getRadixOffset() const;
|
||||||
|
void setRadixOffset(const PDFReal& radixOffset);
|
||||||
|
|
||||||
|
PDFReal getTextIndent() const;
|
||||||
|
void setTextIndent(const PDFReal& textIndent);
|
||||||
|
|
||||||
|
PDFInteger getWidows() const;
|
||||||
|
void setWidows(const PDFInteger& widows);
|
||||||
|
|
||||||
|
QString getTabDefault() const;
|
||||||
|
void setTabDefault(const QString& tabDefault);
|
||||||
|
|
||||||
|
QString getTabStops() const;
|
||||||
|
void setTabStops(const QString& tabStops);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PDFReal m_lineHeight = 0.0;
|
||||||
PDFReal m_fontEmSize = 0.0;
|
PDFReal m_fontEmSize = 0.0;
|
||||||
PDFReal m_fontSpaceSize = 0.0;
|
PDFReal m_fontSpaceSize = 0.0;
|
||||||
|
PDFReal m_radixOffset = 0.0;
|
||||||
|
PDFReal m_textIndent = 0.0;
|
||||||
|
Qt::Alignment m_alignment = Qt::AlignLeft | Qt::AlignTop;
|
||||||
|
QMarginsF m_margins = QMarginsF();
|
||||||
|
PDFInteger m_orphans = 0;
|
||||||
|
PDFInteger m_widows = 0;
|
||||||
|
QString m_tabDefault;
|
||||||
|
QString m_tabStops;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
@ -376,6 +411,96 @@ void XFA_ParagraphSettings::setFontSpaceSize(const PDFReal& fontSpaceSize)
|
|||||||
m_fontSpaceSize = fontSpaceSize;
|
m_fontSpaceSize = fontSpaceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::Alignment XFA_ParagraphSettings::getAlignment() const
|
||||||
|
{
|
||||||
|
return m_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setAlignment(const Qt::Alignment& alignment)
|
||||||
|
{
|
||||||
|
m_alignment = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFReal XFA_ParagraphSettings::getLineHeight() const
|
||||||
|
{
|
||||||
|
return m_lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setLineHeight(const PDFReal& lineHeight)
|
||||||
|
{
|
||||||
|
m_lineHeight = lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMarginsF XFA_ParagraphSettings::getMargins() const
|
||||||
|
{
|
||||||
|
return m_margins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setMargins(const QMarginsF& margins)
|
||||||
|
{
|
||||||
|
m_margins = margins;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFInteger XFA_ParagraphSettings::getOrphans() const
|
||||||
|
{
|
||||||
|
return m_orphans;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setOrphans(const PDFInteger& orphans)
|
||||||
|
{
|
||||||
|
m_orphans = orphans;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFReal XFA_ParagraphSettings::getRadixOffset() const
|
||||||
|
{
|
||||||
|
return m_radixOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setRadixOffset(const PDFReal& radixOffset)
|
||||||
|
{
|
||||||
|
m_radixOffset = radixOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFReal XFA_ParagraphSettings::getTextIndent() const
|
||||||
|
{
|
||||||
|
return m_textIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setTextIndent(const PDFReal& textIndent)
|
||||||
|
{
|
||||||
|
m_textIndent = textIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFInteger XFA_ParagraphSettings::getWidows() const
|
||||||
|
{
|
||||||
|
return m_widows;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setWidows(const PDFInteger& widows)
|
||||||
|
{
|
||||||
|
m_widows = widows;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XFA_ParagraphSettings::getTabDefault() const
|
||||||
|
{
|
||||||
|
return m_tabDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setTabDefault(const QString& tabDefault)
|
||||||
|
{
|
||||||
|
m_tabDefault = tabDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XFA_ParagraphSettings::getTabStops() const
|
||||||
|
{
|
||||||
|
return m_tabStops;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFA_ParagraphSettings::setTabStops(const QString& tabStops)
|
||||||
|
{
|
||||||
|
m_tabStops = tabStops;
|
||||||
|
}
|
||||||
|
|
||||||
PDFReal XFA_Measurement::getValuePt(const XFA_ParagraphSettings* paragraphSettings) const
|
PDFReal XFA_Measurement::getValuePt(const XFA_ParagraphSettings* paragraphSettings) const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
@ -9504,6 +9629,9 @@ public:
|
|||||||
virtual void visit(const xfa::XFA_pageSet* node) override;
|
virtual void visit(const xfa::XFA_pageSet* node) override;
|
||||||
virtual void visit(const xfa::XFA_subformSet* node) override;
|
virtual void visit(const xfa::XFA_subformSet* node) override;
|
||||||
virtual void visit(const xfa::XFA_subform* node) override;
|
virtual void visit(const xfa::XFA_subform* node) override;
|
||||||
|
virtual void visit(const xfa::XFA_area* node) override;
|
||||||
|
virtual void visit(const xfa::XFA_draw* node) override;
|
||||||
|
virtual void visit(const xfa::XFA_field* node) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class ContentAreaScope
|
enum class ContentAreaScope
|
||||||
@ -9521,15 +9649,23 @@ private:
|
|||||||
|
|
||||||
PDFInteger getCurrentPageIndex() const { return isCurrentPageValid() ? m_pages[m_currentPageIndex].pageIndex : -1; }
|
PDFInteger getCurrentPageIndex() const { return isCurrentPageValid() ? m_pages[m_currentPageIndex].pageIndex : -1; }
|
||||||
|
|
||||||
|
void handleMargin(const xfa::XFA_margin* margin);
|
||||||
|
void handleBorder(const xfa::XFA_border* border);
|
||||||
|
void handlePara(const xfa::XFA_para* para);
|
||||||
|
|
||||||
void handleBreak(const xfa::XFA_break* node, bool isBeforeLayout);
|
void handleBreak(const xfa::XFA_break* node, bool isBeforeLayout);
|
||||||
void handleBreak(const xfa::XFA_breakBefore* node);
|
void handleBreak(const xfa::XFA_breakBefore* node);
|
||||||
void handleBreak(const xfa::XFA_breakAfter* node);
|
void handleBreak(const xfa::XFA_breakAfter* node);
|
||||||
void handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakBefore>>& nodes);
|
void handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakBefore>>& nodes);
|
||||||
void handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakAfter>>& nodes);
|
void handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakAfter>>& nodes);
|
||||||
|
|
||||||
|
QMarginsF createMargin(const xfa::XFA_margin* margin);
|
||||||
PDFInteger getOccurenceCount(const xfa::XFA_occur* occur);
|
PDFInteger getOccurenceCount(const xfa::XFA_occur* occur);
|
||||||
PDFInteger getPageOrPageSetMaxOccurenceCount(const xfa::XFA_occur* occur);
|
PDFInteger getPageOrPageSetMaxOccurenceCount(const xfa::XFA_occur* occur);
|
||||||
|
|
||||||
|
QSizeF getSizeFromMeasurement(const xfa::XFA_Measurement& w, const xfa::XFA_Measurement& h) const;
|
||||||
|
QPointF getPointFromMeasurement(const xfa::XFA_Measurement& x, const xfa::XFA_Measurement& y) const;
|
||||||
|
|
||||||
struct PageInfo
|
struct PageInfo
|
||||||
{
|
{
|
||||||
const xfa::XFA_pageArea* pageArea = nullptr;
|
const xfa::XFA_pageArea* pageArea = nullptr;
|
||||||
@ -9539,9 +9675,71 @@ private:
|
|||||||
QRectF contentBox;
|
QRectF contentBox;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents single item layouted onto page (for example,
|
||||||
|
/// field, graphics etc.). Nominal extent can be relative to the
|
||||||
|
/// parent, or it can be absolute (if parent is a page).
|
||||||
|
struct LayoutItem
|
||||||
|
{
|
||||||
|
void translate(PDFReal dx, PDFReal dy) { nominalExtent.translate(dx, dy); }
|
||||||
|
|
||||||
|
/// Nominal extent for this item (relative to the parent item)
|
||||||
|
QRectF nominalExtent;
|
||||||
|
xfa::XFA_BaseNode::PRESENCE presence = xfa::XFA_BaseNode::PRESENCE::Visible;
|
||||||
|
const xfa::XFA_draw* draw = nullptr;
|
||||||
|
const xfa::XFA_field* field = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Layout
|
||||||
|
{
|
||||||
|
void translate(PDFReal dx, PDFReal dy)
|
||||||
|
{
|
||||||
|
nominalExtent.translate(dx, dy);
|
||||||
|
std::for_each(items.begin(), items.end(), [dx, dy](auto& item) { item.translate(dx, dy); });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Page index (or, more precisely, index of content area)
|
||||||
|
size_t pageIndex = 0;
|
||||||
|
|
||||||
|
/// Nominal extent of the parent node (where items are children
|
||||||
|
/// of this node).
|
||||||
|
QRectF nominalExtent;
|
||||||
|
std::vector<LayoutItem> items;
|
||||||
|
};
|
||||||
|
|
||||||
struct LayoutParameters
|
struct LayoutParameters
|
||||||
{
|
{
|
||||||
xfa::XFA_BaseNode::PRESENCE presence = xfa::XFA_BaseNode::PRESENCE::Visible;
|
xfa::XFA_BaseNode::PRESENCE presence = xfa::XFA_BaseNode::PRESENCE::Visible;
|
||||||
|
xfa::XFA_BaseNode::ANCHORTYPE anchorType = xfa::XFA_BaseNode::ANCHORTYPE::TopLeft;
|
||||||
|
const xfa::XFA_border* border = nullptr;
|
||||||
|
xfa::XFA_ParagraphSettings paragraphSettings;
|
||||||
|
QMarginsF margins;
|
||||||
|
|
||||||
|
/// Type of layout for actual item (so, if some subitems are being
|
||||||
|
/// layouted, then this layout is used - for direct subitems)
|
||||||
|
xfa::XFA_BaseNode::LAYOUT layoutType = xfa::XFA_BaseNode::LAYOUT::Position;
|
||||||
|
|
||||||
|
/// Size of actual item
|
||||||
|
QSizeF size;
|
||||||
|
|
||||||
|
/// Minimal size of actual item
|
||||||
|
QSizeF minSize;
|
||||||
|
|
||||||
|
/// Maximal size of actual item
|
||||||
|
QSizeF maxSize;
|
||||||
|
|
||||||
|
/// Actual x-offset relative to the parent container (in case of positional
|
||||||
|
/// layout settings)
|
||||||
|
PDFReal xOffset = 0.0;
|
||||||
|
|
||||||
|
/// Actual x-offset relative to the parent container (in case of positional
|
||||||
|
/// layout settings)
|
||||||
|
PDFReal yOffset = 0.0;
|
||||||
|
|
||||||
|
/// Actual column span if this item is a table cell
|
||||||
|
int columnSpan = 0;
|
||||||
|
|
||||||
|
/// Layout of the subitems
|
||||||
|
std::vector<Layout> layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LayoutParametersStackGuard
|
class LayoutParametersStackGuard
|
||||||
@ -9556,20 +9754,37 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_engine->m_layoutParameters.push(m_engine->m_layoutParameters.top());
|
LayoutParameters oldParameters = m_engine->m_layoutParameters.top();
|
||||||
|
LayoutParameters newParameters;
|
||||||
|
m_engine->m_layoutParameters.push(newParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~LayoutParametersStackGuard()
|
inline ~LayoutParametersStackGuard()
|
||||||
{
|
{
|
||||||
|
LayoutParameters parameters = std::move(m_engine->m_layoutParameters.top());
|
||||||
m_engine->m_layoutParameters.pop();
|
m_engine->m_layoutParameters.pop();
|
||||||
|
|
||||||
|
if (!m_engine->m_layoutParameters.empty())
|
||||||
|
{
|
||||||
|
m_engine->layout(std::move(parameters));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFXFALayoutEngine* m_engine;
|
PDFXFALayoutEngine* m_engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Initializes single layout item
|
||||||
|
Layout initializeSingleLayout(QRectF nominalExtent);
|
||||||
|
|
||||||
|
/// Performs layout (so, using current layout parameters
|
||||||
|
/// and given layouts, it layouts them to the current layout node)
|
||||||
|
/// \param layoutParameters Parameters, which will be lay out
|
||||||
|
void layout(LayoutParameters layoutParameters);
|
||||||
|
|
||||||
LayoutParameters& getLayoutParameters() { return m_layoutParameters.top(); }
|
LayoutParameters& getLayoutParameters() { return m_layoutParameters.top(); }
|
||||||
|
const LayoutParameters& getLayoutParameters() const { return m_layoutParameters.top(); }
|
||||||
|
|
||||||
std::vector<PageInfo> m_pages;
|
std::vector<PageInfo> m_pages;
|
||||||
std::stack<LayoutParameters> m_layoutParameters;
|
std::stack<LayoutParameters> m_layoutParameters;
|
||||||
@ -9577,6 +9792,102 @@ private:
|
|||||||
size_t m_maximalPageCount = 128;
|
size_t m_maximalPageCount = 128;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::visit(const xfa::XFA_area* node)
|
||||||
|
{
|
||||||
|
LayoutParametersStackGuard guard(this);
|
||||||
|
|
||||||
|
LayoutParameters& parameters = getLayoutParameters();
|
||||||
|
parameters.xOffset = node->getX().getValuePt(¶meters.paragraphSettings);
|
||||||
|
parameters.yOffset = node->getY().getValuePt(¶meters.paragraphSettings);
|
||||||
|
|
||||||
|
xfa::XFA_AbstractNode::acceptOrdered(this,
|
||||||
|
node->getArea(),
|
||||||
|
node->getDraw(),
|
||||||
|
node->getExclGroup(),
|
||||||
|
node->getExclGroup(),
|
||||||
|
node->getField(),
|
||||||
|
node->getSubform(),
|
||||||
|
node->getSubformSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFXFALayoutEngine::Layout PDFXFALayoutEngine::initializeSingleLayout(QRectF nominalExtent)
|
||||||
|
{
|
||||||
|
Layout layout;
|
||||||
|
layout.pageIndex = getCurrentPageIndex();
|
||||||
|
layout.nominalExtent = nominalExtent;
|
||||||
|
|
||||||
|
LayoutItem item;
|
||||||
|
item.nominalExtent = nominalExtent;
|
||||||
|
layout.items.push_back(std::move(item));
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::layout(LayoutParameters layoutParameters)
|
||||||
|
{
|
||||||
|
std::map<size_t, std::vector<Layout>> layoutsPerPage;
|
||||||
|
|
||||||
|
for (Layout& layout : layoutParameters.layout)
|
||||||
|
{
|
||||||
|
layoutsPerPage[layout.pageIndex] = std::move(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::visit(const xfa::XFA_draw* node)
|
||||||
|
{
|
||||||
|
switch (node->getPresence())
|
||||||
|
{
|
||||||
|
case xfa::XFA_BaseNode::PRESENCE::Visible:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case xfa::XFA_BaseNode::PRESENCE::Hidden:
|
||||||
|
case xfa::XFA_BaseNode::PRESENCE::Inactive:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case xfa::XFA_BaseNode::PRESENCE::Invisible:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF size = getSizeFromMeasurement(node->getW(), node->getH());
|
||||||
|
QSizeF minSize = getSizeFromMeasurement(node->getMinW(), node->getMinH());
|
||||||
|
QSizeF maxSize = getSizeFromMeasurement(node->getMaxW(), node->getMaxH());
|
||||||
|
|
||||||
|
if (size.isNull())
|
||||||
|
{
|
||||||
|
size = minSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size.isNull())
|
||||||
|
{
|
||||||
|
// Empty draw, do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF point = getPointFromMeasurement(node->getX(), node->getY());
|
||||||
|
QRectF nominalExtent(QPoint(0, 0), size);
|
||||||
|
|
||||||
|
LayoutParametersStackGuard guard(this);
|
||||||
|
LayoutParameters& parameters = getLayoutParameters();
|
||||||
|
parameters.xOffset = point.x();
|
||||||
|
parameters.yOffset = point.y();
|
||||||
|
parameters.anchorType = node->getAnchorType();
|
||||||
|
parameters.presence = node->getPresence();
|
||||||
|
parameters.size = size;
|
||||||
|
parameters.minSize = minSize;
|
||||||
|
parameters.maxSize = maxSize;
|
||||||
|
|
||||||
|
Layout layout = initializeSingleLayout(nominalExtent);
|
||||||
|
layout.items.back().presence = node->getPresence();
|
||||||
|
layout.items.back().draw = node;
|
||||||
|
|
||||||
|
parameters.layout.emplace_back(std::move(layout));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::visit(const xfa::XFA_field* node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PDFXFALayoutEngine::visit(const xfa::XFA_pageArea* node)
|
void PDFXFALayoutEngine::visit(const xfa::XFA_pageArea* node)
|
||||||
{
|
{
|
||||||
auto isPageAddPossible = [this, node]()
|
auto isPageAddPossible = [this, node]()
|
||||||
@ -9722,6 +10033,11 @@ void PDFXFALayoutEngine::visit(const xfa::XFA_subform* node)
|
|||||||
handleBreak(node->getBreak(), true);
|
handleBreak(node->getBreak(), true);
|
||||||
handleBreak(node->getBreakBefore());
|
handleBreak(node->getBreakBefore());
|
||||||
|
|
||||||
|
// Handle settings
|
||||||
|
handlePara(node->getPara());
|
||||||
|
handleBorder(node->getBorder());
|
||||||
|
handleMargin(node->getMargin());
|
||||||
|
|
||||||
// Perform layout, layout subforms so many times
|
// Perform layout, layout subforms so many times
|
||||||
const PDFInteger occurenceCount = getOccurenceCount(node->getOccur());
|
const PDFInteger occurenceCount = getOccurenceCount(node->getOccur());
|
||||||
for (PDFInteger index = 0; index < occurenceCount; ++index)
|
for (PDFInteger index = 0; index < occurenceCount; ++index)
|
||||||
@ -9739,11 +10055,6 @@ void PDFXFALayoutEngine::visit(const xfa::XFA_subform* node)
|
|||||||
// Handle break after
|
// Handle break after
|
||||||
handleBreak(node->getBreak(), false);
|
handleBreak(node->getBreak(), false);
|
||||||
handleBreak(node->getBreakAfter());
|
handleBreak(node->getBreakAfter());
|
||||||
|
|
||||||
/*
|
|
||||||
const XFA_border* getBorder() const { return m_border.getValue(); }
|
|
||||||
const XFA_margin* getMargin() const { return m_margin.getValue(); }
|
|
||||||
const XFA_para* getPara() const { return m_para.getValue(); }*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFXFALayoutEngine::moveToNextArea(ContentAreaScope scope)
|
void PDFXFALayoutEngine::moveToNextArea(ContentAreaScope scope)
|
||||||
@ -9777,6 +10088,97 @@ void PDFXFALayoutEngine::moveToNextArea(ContentAreaScope scope)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMarginsF PDFXFALayoutEngine::createMargin(const xfa::XFA_margin* margin)
|
||||||
|
{
|
||||||
|
if (!margin)
|
||||||
|
{
|
||||||
|
return QMarginsF();
|
||||||
|
}
|
||||||
|
|
||||||
|
const xfa::XFA_ParagraphSettings* paragraphSettings = &getLayoutParameters().paragraphSettings;
|
||||||
|
|
||||||
|
const PDFReal leftMargin = margin->getLeftInset().getValuePt(paragraphSettings);
|
||||||
|
const PDFReal topMargin = margin->getTopInset().getValuePt(paragraphSettings);
|
||||||
|
const PDFReal rightMargin = margin->getRightInset().getValuePt(paragraphSettings);
|
||||||
|
const PDFReal bottomMargin = margin->getBottomInset().getValuePt(paragraphSettings);
|
||||||
|
|
||||||
|
QMarginsF margins(leftMargin, topMargin, rightMargin, bottomMargin);
|
||||||
|
return margins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::handleMargin(const xfa::XFA_margin* margin)
|
||||||
|
{
|
||||||
|
getLayoutParameters().margins = createMargin(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::handleBorder(const xfa::XFA_border* border)
|
||||||
|
{
|
||||||
|
getLayoutParameters().border = border;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFXFALayoutEngine::handlePara(const xfa::XFA_para* para)
|
||||||
|
{
|
||||||
|
if (!para)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfa::XFA_ParagraphSettings& settings = getLayoutParameters().paragraphSettings;
|
||||||
|
settings.setWidows(para->getWidows());
|
||||||
|
settings.setTextIndent(para->getTextIndent().getValuePt(&settings));
|
||||||
|
settings.setTabDefault(para->getTabDefault());
|
||||||
|
settings.setTabStops(para->getTabStops());
|
||||||
|
settings.setOrphans(para->getOrphans());
|
||||||
|
settings.setLineHeight(para->getLineHeight().getValuePt(&settings));
|
||||||
|
settings.setRadixOffset(para->getRadixOffset().getValuePt(&settings));
|
||||||
|
|
||||||
|
QMarginsF margins(para->getMarginLeft().getValuePt(&settings),
|
||||||
|
para->getSpaceAbove().getValuePt(&settings),
|
||||||
|
para->getMarginRight().getValuePt(&settings),
|
||||||
|
para->getSpaceBelow().getValuePt(&settings));
|
||||||
|
|
||||||
|
settings.setMargins(margins);
|
||||||
|
|
||||||
|
Qt::Alignment alignment = Qt::Alignment();
|
||||||
|
|
||||||
|
switch (para->getHAlign())
|
||||||
|
{
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::Left:
|
||||||
|
alignment |= Qt::AlignLeft;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::Center:
|
||||||
|
alignment |= Qt::AlignHCenter;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::Justify:
|
||||||
|
alignment |= Qt::AlignJustify;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::JustifyAll:
|
||||||
|
alignment |= Qt::AlignJustify;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::Radix:
|
||||||
|
alignment |= Qt::AlignRight;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::HALIGN::Right:
|
||||||
|
alignment |= Qt::AlignRight;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (para->getVAlign())
|
||||||
|
{
|
||||||
|
case pdf::xfa::XFA_BaseNode::VALIGN::Top:
|
||||||
|
alignment |= Qt::AlignTop;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::VALIGN::Bottom:
|
||||||
|
alignment |= Qt::AlignBottom;
|
||||||
|
break;
|
||||||
|
case pdf::xfa::XFA_BaseNode::VALIGN::Middle:
|
||||||
|
alignment |= Qt::AlignVCenter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setAlignment(alignment);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFXFALayoutEngine::handleBreak(const xfa::XFA_break* node, bool isBeforeLayout)
|
void PDFXFALayoutEngine::handleBreak(const xfa::XFA_break* node, bool isBeforeLayout)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
@ -9861,6 +10263,28 @@ PDFInteger PDFXFALayoutEngine::getPageOrPageSetMaxOccurenceCount(const xfa::XFA_
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSizeF PDFXFALayoutEngine::getSizeFromMeasurement(const xfa::XFA_Measurement& w,
|
||||||
|
const xfa::XFA_Measurement& h) const
|
||||||
|
{
|
||||||
|
const xfa::XFA_ParagraphSettings& paragraphSettings = getLayoutParameters().paragraphSettings;
|
||||||
|
|
||||||
|
const PDFReal width = w.getValuePt(¶graphSettings);
|
||||||
|
const PDFReal height = h.getValuePt(¶graphSettings);
|
||||||
|
|
||||||
|
return QSizeF(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PDFXFALayoutEngine::getPointFromMeasurement(const xfa::XFA_Measurement& x,
|
||||||
|
const xfa::XFA_Measurement& y) const
|
||||||
|
{
|
||||||
|
const xfa::XFA_ParagraphSettings& paragraphSettings = getLayoutParameters().paragraphSettings;
|
||||||
|
|
||||||
|
const PDFReal xPos = x.getValuePt(¶graphSettings);
|
||||||
|
const PDFReal yPos = y.getValuePt(¶graphSettings);
|
||||||
|
|
||||||
|
return QPointF(xPos, yPos);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFXFALayoutEngine::handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakBefore>>& nodes)
|
void PDFXFALayoutEngine::handleBreak(const std::vector<xfa::XFA_Node<xfa::XFA_breakBefore>>& nodes)
|
||||||
{
|
{
|
||||||
for (const auto& node : nodes)
|
for (const auto& node : nodes)
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<file>resources/previous.svg</file>
|
<file>resources/previous.svg</file>
|
||||||
<file>resources/previous-page.svg</file>
|
<file>resources/previous-page.svg</file>
|
||||||
<file>resources/previous-start.svg</file>
|
<file>resources/previous-start.svg</file>
|
||||||
<file>resources/options.svg</file>
|
|
||||||
<file>resources/quit.svg</file>
|
<file>resources/quit.svg</file>
|
||||||
<file>resources/rendering-errors.svg</file>
|
<file>resources/rendering-errors.svg</file>
|
||||||
<file>resources/settings.svg</file>
|
<file>resources/settings.svg</file>
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="30mm"
|
|
||||||
height="30mm"
|
|
||||||
viewBox="0 0 30 30"
|
|
||||||
version="1.1"
|
|
||||||
id="svg5291"
|
|
||||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
|
||||||
sodipodi:docname="options.svg">
|
|
||||||
<defs
|
|
||||||
id="defs5285" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="5.6568542"
|
|
||||||
inkscape:cx="101.46447"
|
|
||||||
inkscape:cy="10.379569"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:window-width="3840"
|
|
||||||
inkscape:window-height="2035"
|
|
||||||
inkscape:window-x="-13"
|
|
||||||
inkscape:window-y="-13"
|
|
||||||
inkscape:window-maximized="1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata5288">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
<dc:creator>
|
|
||||||
<cc:Agent>
|
|
||||||
<dc:title>Jakub Melka</dc:title>
|
|
||||||
</cc:Agent>
|
|
||||||
</dc:creator>
|
|
||||||
<cc:license
|
|
||||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
|
||||||
</cc:Work>
|
|
||||||
<cc:License
|
|
||||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
|
||||||
<cc:permits
|
|
||||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
|
||||||
<cc:permits
|
|
||||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
|
||||||
<cc:requires
|
|
||||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
|
||||||
<cc:requires
|
|
||||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
|
||||||
<cc:permits
|
|
||||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
|
||||||
<cc:requires
|
|
||||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
|
||||||
</cc:License>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Vrstva 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-267)">
|
|
||||||
<flowRoot
|
|
||||||
xml:space="preserve"
|
|
||||||
id="flowRoot5913"
|
|
||||||
style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion
|
|
||||||
id="flowRegion5915"><rect
|
|
||||||
id="rect5917"
|
|
||||||
width="129.22377"
|
|
||||||
height="91.747108"
|
|
||||||
x="-13.788582"
|
|
||||||
y="-33.515606" /></flowRegion><flowPara
|
|
||||||
id="flowPara5919"></flowPara></flowRoot> </g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.0 KiB |
Reference in New Issue
Block a user