QXPContentCollector.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /*
00003  * This file is part of the libqxp project.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this
00007  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
00008  */
00009 
00010 #ifndef QXPCONTENTCOLLECTOR_H_INCLUDED
00011 #define QXPCONTENTCOLLECTOR_H_INCLUDED
00012 
00013 #include "QXPCollector.h"
00014 #include <vector>
00015 #include <unordered_map>
00016 #include <memory>
00017 #include <functional>
00018 #include <type_traits>
00019 
00020 #include "QXPTypes.h"
00021 
00022 namespace libqxp
00023 {
00024 
00025 class QXPContentCollector : public QXPCollector
00026 {
00027   // disable copying
00028   QXPContentCollector(const QXPContentCollector &other) = delete;
00029   QXPContentCollector &operator=(const QXPContentCollector &other) = delete;
00030 
00031 public:
00032   QXPContentCollector(librevenge::RVNGDrawingInterface *painter);
00033   ~QXPContentCollector();
00034 
00035   void startDocument() override;
00036   void endDocument() override;
00037 
00038   void startPage(const Page &page) override;
00039   void endPage() override;
00040 
00041   void collectDocumentProperties(const QXPDocumentProperties &props) override;
00042 
00043   void collectLine(const std::shared_ptr<Line> &line) override;
00044   void collectBox(const std::shared_ptr<Box> &box) override;
00045   void collectTextBox(const std::shared_ptr<TextBox> &box) override;
00046   void collectTextPath(const std::shared_ptr<TextPath> &textPath) override;
00047   void collectGroup(const std::shared_ptr<Group> &group) override;
00048 
00049   void collectText(const std::shared_ptr<Text> &text, const unsigned linkId) override;
00050 
00051 private:
00052   struct CollectedPage;
00053 
00054   template<typename T>
00055   using ObjectHandler = std::function<void(const std::shared_ptr<T> &obj, const CollectedPage &)>;
00056 
00057   template<typename T, typename TThis>
00058   using ObjectHandlerMember = std::function<void(TThis *, const std::shared_ptr<T> &obj, const CollectedPage &)>;
00059 
00060   class CollectedObjectInterface
00061   {
00062   public:
00063     virtual ~CollectedObjectInterface() = default;
00064 
00065     virtual void draw(const CollectedPage &page) = 0;
00066 
00067     virtual unsigned zIndex() const = 0;
00068     virtual void setZIndex(unsigned value) = 0;
00069   };
00070 
00071   template<typename T>
00072   class CollectedObject : public CollectedObjectInterface
00073   {
00074     static_assert(std::is_base_of<Object, T>::value, "T is not Object");
00075   public:
00076     const std::shared_ptr<T> object;
00077 
00078     CollectedObject(const std::shared_ptr<T> &obj, const ObjectHandler<T> &handler)
00079       : object(obj), m_handler(handler), m_isProcessed(false)
00080     { }
00081 
00082     void draw(const CollectedPage &page) override
00083     {
00084       if (!m_isProcessed)
00085       {
00086         m_handler(object, page);
00087       }
00088       m_isProcessed = true;
00089     }
00090 
00091     unsigned zIndex() const override
00092     {
00093       return object->zIndex;
00094     }
00095 
00096     void setZIndex(unsigned value) override
00097     {
00098       object->zIndex = value;
00099     }
00100 
00101   private:
00102     const ObjectHandler<T> m_handler;
00103     bool m_isProcessed;
00104   };
00105 
00106   struct CollectedPage
00107   {
00108     const PageSettings settings;
00109     std::vector<std::shared_ptr<CollectedObject<Group>>> groups;
00110     std::vector<std::shared_ptr<TextObject>> linkedTextObjects;
00111     std::vector<std::shared_ptr<CollectedObjectInterface>> objects;
00112 
00113     CollectedPage(const PageSettings &pageSettings)
00114       : settings(pageSettings), groups(), linkedTextObjects(), objects()
00115     { }
00116 
00117     double getX(const double x) const;
00118     double getX(const std::shared_ptr<Object> &obj) const;
00119     double getY(const double y) const;
00120     double getY(const std::shared_ptr<Object> &obj) const;
00121     Point getPoint(const Point &p) const;
00122   };
00123 
00124   librevenge::RVNGDrawingInterface *m_painter;
00125 
00126   bool m_isDocumentStarted;
00127   bool m_isCollectingFacingPage;
00128 
00129   std::vector<CollectedPage> m_unprocessedPages;
00130 
00131   std::unordered_map<unsigned, std::shared_ptr<Text>> m_linkTextMap;
00132   std::unordered_map<unsigned, std::unordered_map<unsigned, std::shared_ptr<TextObject>>> m_linkIndexedTextObjectsMap;
00133 
00134   QXPDocumentProperties m_docProps;
00135 
00136   CollectedPage &getInsertionPage(const std::shared_ptr<Object> &obj);
00137 
00138   template<typename T>
00139   std::shared_ptr<CollectedObject<T>> addObject(const std::shared_ptr<T> &obj, const ObjectHandlerMember<T, QXPContentCollector> &handler)
00140   {
00141     auto collectedObj = std::make_shared<CollectedObject<T>>(obj, std::bind(handler, this, std::placeholders::_1, std::placeholders::_2));
00142     getInsertionPage(obj).objects.push_back(collectedObj);
00143     return collectedObj;
00144   }
00145 
00146   void draw(bool force = false);
00147 
00148   void collectTextObject(const std::shared_ptr<TextObject> &textObj, CollectedPage &page);
00149   void updateLinkedTexts();
00150   bool hasUnfinishedLinkedTexts();
00151 
00152   void drawLine(const std::shared_ptr<Line> &line, const CollectedPage &page);
00153   void drawBox(const std::shared_ptr<Box> &box, const CollectedPage &page);
00154   void drawRectangle(const std::shared_ptr<Box> &box, const CollectedPage &page);
00155   void drawOval(const std::shared_ptr<Box> &oval, const CollectedPage &page);
00156   void drawPolygon(const std::shared_ptr<Box> &polygon, const CollectedPage &page);
00157   void drawBezierBox(const std::shared_ptr<Box> &box, const CollectedPage &page);
00158   void drawTextBox(const std::shared_ptr<TextBox> &textbox, const CollectedPage &page);
00159   void drawTextPath(const std::shared_ptr<TextPath> &textPath, const CollectedPage &page);
00160   void drawText(const std::shared_ptr<Text> &text, const LinkedTextSettings &linkSettings);
00161   void drawGroup(const std::shared_ptr<Group> &group, const CollectedPage &page);
00162 
00163   void writeFill(librevenge::RVNGPropertyList &propList, const boost::optional<Fill> &fill);
00164   void writeFrame(librevenge::RVNGPropertyList &propList, const Frame &frame, const bool runaround, const bool allowHairline = false);
00165 };
00166 
00167 }
00168 
00169 #endif // QXPCONTENTCOLLECTOR_H_INCLUDED
00170 
00171 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */