1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libetonyek project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "IWORKImageElement.h"
11 
12 #include <memory>
13 
14 #include "libetonyek_xml.h"
15 #include "IWORKBinaryElement.h"
16 #include "IWORKCollector.h"
17 #include "IWORKDataElement.h"
18 #include "IWORKDictionary.h"
19 #include "IWORKFilteredImageElement.h"
20 #include "IWORKGeometryElement.h"
21 #include "IWORKRefContext.h"
22 #include "IWORKSizeElement.h"
23 #include "IWORKStyleContainer.h"
24 #include "IWORKToken.h"
25 #include "IWORKXMLParserState.h"
26 
27 namespace libetonyek
28 {
29 
30 namespace
31 {
32 typedef IWORKStyleContainer<IWORKToken::NS_URI_SF | IWORKToken::graphic_style, IWORKToken::NS_URI_SF | IWORKToken::graphic_style_ref> GraphicStyleContext;
33 }
34 
IWORKImageElement(IWORKXMLParserState & state,IWORKMediaContentPtr_t & content)35 IWORKImageElement::IWORKImageElement(IWORKXMLParserState &state, IWORKMediaContentPtr_t &content)
36   : IWORKXMLElementContextBase(state)
37   , m_locked()
38   , m_content(content)
39   , m_localContent()
40   , m_filteredImage()
41   , m_size()
42   , m_data()
43   , m_fillColor()
44   , m_binaryRef()
45   , m_style()
46   , m_cropGeometry()
47   , m_placeholderSize()
48 {
49 }
50 
IWORKImageElement(IWORKXMLParserState & state)51 IWORKImageElement::IWORKImageElement(IWORKXMLParserState &state)
52   : IWORKXMLElementContextBase(state)
53   , m_locked()
54   , m_content(m_localContent)
55   , m_localContent()
56   , m_filteredImage()
57   , m_size()
58   , m_data()
59   , m_fillColor()
60   , m_binaryRef()
61   , m_style()
62   , m_cropGeometry()
63   , m_placeholderSize()
64 {
65 }
66 
startOfElement()67 void IWORKImageElement::startOfElement()
68 {
69   if (isCollector())
70     getCollector().startLevel();
71 }
72 
attribute(const int name,const char * const value)73 void IWORKImageElement::attribute(const int name, const char *const value)
74 {
75   switch (name)
76   {
77   case IWORKToken::NS_URI_SFA | IWORKToken::version :
78     break;
79   case IWORKToken::NS_URI_SF | IWORKToken::locked :
80     m_locked = bool_cast(value);
81     break;
82   default :
83     IWORKXMLElementContextBase::attribute(name, value);
84     break;
85   }
86 }
87 
element(const int name)88 IWORKXMLContextPtr_t IWORKImageElement::element(const int name)
89 {
90   switch (name)
91   {
92   case IWORKToken::NS_URI_SF | IWORKToken::binary :
93     return std::make_shared<IWORKBinaryElement>(getState(), m_content);
94   case IWORKToken::NS_URI_SF | IWORKToken::binary_ref :
95     return std::make_shared<IWORKRefContext>(getState(), m_binaryRef);
96   case IWORKToken::NS_URI_SF | IWORKToken::crop_geometry :
97     return std::make_shared<IWORKGeometryElement>(getState(), m_cropGeometry);
98   case IWORKToken::NS_URI_SF | IWORKToken::data :
99     return std::make_shared<IWORKDataElement>(getState(), m_data, m_fillColor);
100   case IWORKToken::NS_URI_SF | IWORKToken::filtered_image :
101     return std::make_shared<IWORKFilteredImageElement>(getState(), m_filteredImage);
102   case IWORKToken::NS_URI_SF | IWORKToken::geometry :
103     return std::make_shared<IWORKGeometryElement>(getState());
104   case IWORKToken::NS_URI_SF | IWORKToken::masking_shape_path_source :
105   {
106     static bool first=true;
107     if (first)
108     {
109       ETONYEK_DEBUG_MSG(("IWORKImageElement::element: find some masking shape's paths\n"));
110       first=false;
111     }
112     break;
113   }
114   case IWORKToken::NS_URI_SF | IWORKToken::placeholder_size : // USEME
115     return std::make_shared<IWORKSizeElement>(getState(),m_placeholderSize);
116   case IWORKToken::NS_URI_SF | IWORKToken::size :
117     return std::make_shared<IWORKSizeElement>(getState(),m_size);
118   case IWORKToken::NS_URI_SF | IWORKToken::style : // USEME
119     return std::make_shared<GraphicStyleContext>(getState(), m_style, getState().getDictionary().m_graphicStyles);
120   default:
121     ETONYEK_DEBUG_MSG(("IWORKImageElement::element: find some unknown element\n"));
122     break;
123   }
124 
125   return IWORKXMLContextPtr_t();
126 }
127 
endOfElement()128 void IWORKImageElement::endOfElement()
129 {
130   if (m_binaryRef)
131   {
132     const IWORKMediaContentMap_t::const_iterator it = getState().getDictionary().m_binaries.find(get(m_binaryRef));
133     if (getState().getDictionary().m_binaries.end() != it)
134       m_content = it->second;
135     else
136     {
137       ETONYEK_DEBUG_MSG(("IWORKImageElement::endOfElement: can not find image %s\n", get(m_binaryRef).c_str()));
138     }
139   }
140   if (!m_content && m_filteredImage)
141     m_content=m_filteredImage;
142   else if (!m_content && (bool(m_data) || bool(m_fillColor)))
143   {
144     m_content = std::make_shared<IWORKMediaContent>();
145     m_content->m_size = m_size;
146     m_content->m_data = m_data;
147     m_content->m_fillColor = m_fillColor;
148   }
149   if (getId() && m_content)
150     getState().getDictionary().m_images[get(getId())]=m_content;
151   if (isCollector())
152   {
153     if (m_style) getCollector().setGraphicStyle(m_style);
154     getCollector().collectImage(m_content, m_cropGeometry, boost::none, m_locked ? get(m_locked) : false);
155     getCollector().endLevel();
156   }
157 }
158 
159 }
160 
161 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
162