Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice 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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #include "ConversionHelper.hxx"
20 : #include "GraphicHelpers.hxx"
21 : #include <dmapper/GraphicZOrderHelper.hxx>
22 : #include "PropertyIds.hxx"
23 :
24 : #include <ooxml/resourceids.hxx>
25 :
26 : #include <com/sun/star/text/HoriOrientation.hpp>
27 : #include <com/sun/star/text/VertOrientation.hpp>
28 : #include <com/sun/star/text/RelOrientation.hpp>
29 : #include <com/sun/star/text/WrapTextMode.hpp>
30 :
31 : #include <oox/drawingml/drawingmltypes.hxx>
32 :
33 : #include <iostream>
34 :
35 : namespace writerfilter {
36 : namespace dmapper {
37 :
38 : using namespace com::sun::star;
39 :
40 1914 : PositionHandler::PositionHandler( std::pair<OUString, OUString>& rPositionOffsets, std::pair<OUString, OUString>& rAligns ) :
41 : LoggedProperties("PositionHandler"),
42 : m_nOrient(text::VertOrientation::NONE),
43 : m_nPosition(0),
44 : m_rPositionOffsets(rPositionOffsets),
45 1914 : m_rAligns(rAligns)
46 : {
47 1914 : m_nRelation = text::RelOrientation::FRAME;
48 1914 : }
49 :
50 3828 : PositionHandler::~PositionHandler( )
51 : {
52 3828 : }
53 :
54 1880 : void PositionHandler::lcl_attribute( Id aName, Value& rVal )
55 : {
56 1880 : sal_Int32 nIntValue = rVal.getInt( );
57 1880 : switch ( aName )
58 : {
59 : case NS_ooxml::LN_CT_PosV_relativeFrom:
60 : {
61 : // TODO There are some other unhandled values
62 : static const Id pVertRelValues[] =
63 : {
64 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_margin,
65 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page,
66 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph,
67 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_line
68 : };
69 :
70 : static const sal_Int16 pVertRelations[] =
71 : {
72 : text::RelOrientation::PAGE_PRINT_AREA,
73 : text::RelOrientation::PAGE_FRAME,
74 : text::RelOrientation::FRAME,
75 : text::RelOrientation::TEXT_LINE
76 : };
77 :
78 4700 : for ( int i = 0; i < 4; i++ )
79 : {
80 3760 : if ( pVertRelValues[i] == sal_uInt32( nIntValue ) )
81 940 : m_nRelation = pVertRelations[i];
82 : }
83 : }
84 940 : break;
85 : case NS_ooxml::LN_CT_PosH_relativeFrom:
86 : {
87 : // TODO There are some other unhandled values
88 : static const Id pHoriRelValues[] =
89 : {
90 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_margin,
91 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page,
92 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_column,
93 : NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_character
94 : };
95 :
96 : static const sal_Int16 pHoriRelations[] =
97 : {
98 : text::RelOrientation::PAGE_PRINT_AREA,
99 : text::RelOrientation::PAGE_FRAME,
100 : text::RelOrientation::FRAME,
101 : text::RelOrientation::CHAR,
102 : };
103 :
104 4700 : for ( int i = 0; i < 4; i++ )
105 : {
106 3760 : if ( pHoriRelValues[i] == sal_uInt32( nIntValue ) )
107 940 : m_nRelation = pHoriRelations[i];
108 : }
109 : }
110 940 : break;
111 : default:
112 : #ifdef DEBUG_WRITERFILTER
113 : TagLogger::getInstance().element("unhandled");
114 : #endif
115 0 : break;
116 : }
117 1880 : }
118 :
119 1906 : void PositionHandler::lcl_sprm(Sprm& rSprm)
120 : {
121 1906 : sal_uInt32 nSprmId = rSprm.getId();
122 :
123 1906 : switch (nSprmId)
124 : {
125 : case NS_ooxml::LN_CT_PosH_posOffset:
126 885 : m_nPosition = oox::drawingml::convertEmuToHmm(m_rPositionOffsets.first.toInt32());
127 885 : break;
128 : case NS_ooxml::LN_CT_PosV_posOffset:
129 905 : m_nPosition = oox::drawingml::convertEmuToHmm(m_rPositionOffsets.second.toInt32());
130 905 : break;
131 : case NS_ooxml::LN_CT_PosH_align:
132 : {
133 69 : OUString& rAlign = m_rAligns.first;
134 69 : if (rAlign == "left")
135 4 : m_nOrient = text::HoriOrientation::LEFT;
136 65 : else if (rAlign == "right")
137 16 : m_nOrient = text::HoriOrientation::RIGHT;
138 49 : else if (rAlign == "center")
139 49 : m_nOrient = text::HoriOrientation::CENTER;
140 0 : else if (rAlign == "inside")
141 0 : m_nOrient = text::HoriOrientation::INSIDE;
142 0 : else if (rAlign == "outside")
143 0 : m_nOrient = text::HoriOrientation::OUTSIDE;
144 69 : break;
145 : }
146 : case NS_ooxml::LN_CT_PosV_align:
147 : {
148 47 : OUString& rAlign = m_rAligns.second;
149 47 : if (rAlign == "top")
150 35 : m_nOrient = text::VertOrientation::TOP;
151 12 : else if (rAlign == "bottom")
152 3 : m_nOrient = text::VertOrientation::BOTTOM;
153 9 : else if (rAlign == "center")
154 9 : m_nOrient = text::VertOrientation::CENTER;
155 0 : else if (rAlign == "inside")
156 0 : m_nOrient = text::VertOrientation::NONE;
157 0 : else if (rAlign == "outside")
158 0 : m_nOrient = text::VertOrientation::NONE;
159 47 : break;
160 : }
161 : }
162 1906 : }
163 :
164 1914 : sal_Int16 PositionHandler::orientation() const
165 : {
166 1914 : if( m_nRelation == text::RelOrientation::TEXT_LINE )
167 : { // It appears that to 'line of text' alignment is backwards to other alignments,
168 : // 'top' meaning putting on top of the line instead of having top at the line.
169 6 : if( m_nOrient == text::VertOrientation::TOP )
170 3 : return text::VertOrientation::BOTTOM;
171 3 : else if( m_nOrient == text::VertOrientation::BOTTOM )
172 0 : return text::VertOrientation::TOP;
173 : }
174 1911 : return m_nOrient;
175 : }
176 :
177 37 : WrapHandler::WrapHandler( ) :
178 : LoggedProperties("WrapHandler"),
179 : m_nType( 0 ),
180 37 : m_nSide( 0 )
181 : {
182 37 : }
183 :
184 74 : WrapHandler::~WrapHandler( )
185 : {
186 74 : }
187 :
188 72 : void WrapHandler::lcl_attribute( Id aName, Value& rVal )
189 : {
190 72 : switch ( aName )
191 : {
192 : case NS_ooxml::LN_CT_Wrap_type:
193 9 : m_nType = sal_Int32( rVal.getInt( ) );
194 9 : break;
195 : case NS_ooxml::LN_CT_Wrap_side:
196 0 : m_nSide = sal_Int32( rVal.getInt( ) );
197 0 : break;
198 : default:;
199 : }
200 72 : }
201 :
202 0 : void WrapHandler::lcl_sprm( Sprm& )
203 : {
204 0 : }
205 :
206 37 : sal_Int32 WrapHandler::getWrapMode( )
207 : {
208 : // The wrap values do not map directly to our wrap mode,
209 : // e.g. none in .docx actually means through in LO.
210 37 : sal_Int32 nMode = text::WrapTextMode_THROUGHT;
211 :
212 37 : switch ( m_nType )
213 : {
214 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_square:
215 : // through and tight are somewhat complicated, approximate
216 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_tight:
217 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_through:
218 : {
219 7 : switch ( m_nSide )
220 : {
221 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left:
222 0 : nMode = text::WrapTextMode_LEFT;
223 0 : break;
224 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right:
225 0 : nMode = text::WrapTextMode_RIGHT;
226 0 : break;
227 : default:
228 7 : nMode = text::WrapTextMode_PARALLEL;
229 : }
230 : }
231 7 : break;
232 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom:
233 2 : nMode = text::WrapTextMode_NONE;
234 2 : break;
235 : case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none:
236 : default:
237 28 : nMode = text::WrapTextMode_THROUGHT;
238 : }
239 :
240 37 : return nMode;
241 : }
242 :
243 :
244 1141 : void GraphicZOrderHelper::addItem(uno::Reference<beans::XPropertySet> const& props, sal_Int32 const relativeHeight)
245 : {
246 1141 : items[ relativeHeight ] = props;
247 1141 : }
248 :
249 : // The relativeHeight value in .docx is an arbitrary number, where only the relative ordering matters.
250 : // But in Writer, the z-order is index in 0..(numitems-1) range, so whenever a new item needs to be
251 : // added in the proper z-order, it is necessary to find the proper index.
252 1143 : sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight, bool bOldStyle )
253 : {
254 1143 : Items::const_iterator it = items.begin();
255 9038 : while( it != items.end())
256 : {
257 : // std::map is iterated sorted by key
258 :
259 : // Old-style ordering differs in what should happen when there is already an item with the same z-order:
260 : // we belong under it in case of new-style, but we belong below it in case of old-style.
261 7191 : bool bCond = bOldStyle ? (it->first > relativeHeight) : (it->first >= relativeHeight);
262 :
263 7191 : if( bCond )
264 439 : break; // this is the first one higher, we belong right before it
265 : else
266 6752 : ++it;
267 : }
268 1143 : if( it == items.end()) // we're topmost
269 : {
270 704 : if( items.empty())
271 1186 : return 0;
272 216 : sal_Int32 itemZOrder(0);
273 216 : --it;
274 864 : if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
275 648 : .GetName( PROP_Z_ORDER )) >>= itemZOrder )
276 210 : return itemZOrder + 1; // after the topmost
277 : }
278 : else
279 : {
280 439 : sal_Int32 itemZOrder(0);
281 1752 : if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
282 1317 : .GetName( PROP_Z_ORDER )) >>= itemZOrder )
283 427 : return itemZOrder; // before the item
284 : }
285 : SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" );
286 16 : return 0; // this should not(?) happen
287 : }
288 :
289 72 : } }
290 :
291 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|