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