1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #include "ConversionHelper.hxx"
20 #include "GraphicHelpers.hxx"
21 #include <dmapper/GraphicZOrderHelper.hxx>
22 #include "PropertyIds.hxx"
24 #include <ooxml/resourceids.hxx>
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>
31 #include <oox/drawingml/drawingmltypes.hxx>
35 namespace writerfilter
{
38 using namespace com::sun::star
;
40 PositionHandler::PositionHandler( std::pair
<OUString
, OUString
>& rPositionOffsets
, std::pair
<OUString
, OUString
>& rAligns
) :
41 LoggedProperties("PositionHandler"),
42 m_nOrient(text::VertOrientation::NONE
),
44 m_rPositionOffsets(rPositionOffsets
),
47 m_nRelation
= text::RelOrientation::FRAME
;
50 PositionHandler::~PositionHandler( )
54 void PositionHandler::lcl_attribute( Id aName
, Value
& rVal
)
56 sal_Int32 nIntValue
= rVal
.getInt( );
59 case NS_ooxml::LN_CT_PosV_relativeFrom
:
61 // TODO There are some other unhandled values
62 static const Id pVertRelValues
[] =
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
70 static const sal_Int16 pVertRelations
[] =
72 text::RelOrientation::PAGE_PRINT_AREA
,
73 text::RelOrientation::PAGE_FRAME
,
74 text::RelOrientation::FRAME
,
75 text::RelOrientation::TEXT_LINE
78 for ( int i
= 0; i
< 4; i
++ )
80 if ( pVertRelValues
[i
] == sal_uInt32( nIntValue
) )
81 m_nRelation
= pVertRelations
[i
];
85 case NS_ooxml::LN_CT_PosH_relativeFrom
:
87 // TODO There are some other unhandled values
88 static const Id pHoriRelValues
[] =
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
96 static const sal_Int16 pHoriRelations
[] =
98 text::RelOrientation::PAGE_PRINT_AREA
,
99 text::RelOrientation::PAGE_FRAME
,
100 text::RelOrientation::FRAME
,
101 text::RelOrientation::CHAR
,
104 for ( int i
= 0; i
< 4; i
++ )
106 if ( pHoriRelValues
[i
] == sal_uInt32( nIntValue
) )
107 m_nRelation
= pHoriRelations
[i
];
112 #ifdef DEBUG_WRITERFILTER
113 TagLogger::getInstance().element("unhandled");
119 void PositionHandler::lcl_sprm(Sprm
& rSprm
)
121 sal_uInt32 nSprmId
= rSprm
.getId();
125 case NS_ooxml::LN_CT_PosH_posOffset
:
126 m_nPosition
= oox::drawingml::convertEmuToHmm(m_rPositionOffsets
.first
.toInt32());
128 case NS_ooxml::LN_CT_PosV_posOffset
:
129 m_nPosition
= oox::drawingml::convertEmuToHmm(m_rPositionOffsets
.second
.toInt32());
131 case NS_ooxml::LN_CT_PosH_align
:
133 OUString
& rAlign
= m_rAligns
.first
;
134 if (rAlign
== "left")
135 m_nOrient
= text::HoriOrientation::LEFT
;
136 else if (rAlign
== "right")
137 m_nOrient
= text::HoriOrientation::RIGHT
;
138 else if (rAlign
== "center")
139 m_nOrient
= text::HoriOrientation::CENTER
;
140 else if (rAlign
== "inside")
141 m_nOrient
= text::HoriOrientation::INSIDE
;
142 else if (rAlign
== "outside")
143 m_nOrient
= text::HoriOrientation::OUTSIDE
;
146 case NS_ooxml::LN_CT_PosV_align
:
148 OUString
& rAlign
= m_rAligns
.second
;
150 m_nOrient
= text::VertOrientation::TOP
;
151 else if (rAlign
== "bottom")
152 m_nOrient
= text::VertOrientation::BOTTOM
;
153 else if (rAlign
== "center")
154 m_nOrient
= text::VertOrientation::CENTER
;
155 else if (rAlign
== "inside")
156 m_nOrient
= text::VertOrientation::NONE
;
157 else if (rAlign
== "outside")
158 m_nOrient
= text::VertOrientation::NONE
;
164 sal_Int16
PositionHandler::orientation() const
166 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 if( m_nOrient
== text::VertOrientation::TOP
)
170 return text::VertOrientation::BOTTOM
;
171 else if( m_nOrient
== text::VertOrientation::BOTTOM
)
172 return text::VertOrientation::TOP
;
177 WrapHandler::WrapHandler( ) :
178 LoggedProperties("WrapHandler"),
184 WrapHandler::~WrapHandler( )
188 void WrapHandler::lcl_attribute( Id aName
, Value
& rVal
)
192 case NS_ooxml::LN_CT_Wrap_type
:
193 m_nType
= sal_Int32( rVal
.getInt( ) );
195 case NS_ooxml::LN_CT_Wrap_side
:
196 m_nSide
= sal_Int32( rVal
.getInt( ) );
202 void WrapHandler::lcl_sprm( Sprm
& )
206 sal_Int32
WrapHandler::getWrapMode( )
208 // The wrap values do not map directly to our wrap mode,
209 // e.g. none in .docx actually means through in LO.
210 sal_Int32 nMode
= text::WrapTextMode_THROUGHT
;
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
:
221 case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left
:
222 nMode
= text::WrapTextMode_LEFT
;
224 case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right
:
225 nMode
= text::WrapTextMode_RIGHT
;
228 nMode
= text::WrapTextMode_PARALLEL
;
232 case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom
:
233 nMode
= text::WrapTextMode_NONE
;
235 case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none
:
237 nMode
= text::WrapTextMode_THROUGHT
;
244 void GraphicZOrderHelper::addItem(uno::Reference
<beans::XPropertySet
> const& props
, sal_Int32
const relativeHeight
)
246 items
[ relativeHeight
] = props
;
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 sal_Int32
GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight
, bool bOldStyle
)
254 Items::const_iterator it
= items
.begin();
255 while( it
!= items
.end())
257 // std::map is iterated sorted by key
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 bool bCond
= bOldStyle
? (it
->first
> relativeHeight
) : (it
->first
>= relativeHeight
);
264 break; // this is the first one higher, we belong right before it
268 if( it
== items
.end()) // we're topmost
272 sal_Int32
itemZOrder(0);
274 if( it
->second
->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
275 .GetName( PROP_Z_ORDER
)) >>= itemZOrder
)
276 return itemZOrder
+ 1; // after the topmost
280 sal_Int32
itemZOrder(0);
281 if( it
->second
->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
282 .GetName( PROP_Z_ORDER
)) >>= itemZOrder
)
283 return itemZOrder
; // before the item
285 SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" );
286 return 0; // this should not(?) happen
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */