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 <CellColorHandler.hxx>
20 : #include <PropertyMap.hxx>
21 : #include <ConversionHelper.hxx>
22 : #include <TDefTableHandler.hxx>
23 : #include <ooxml/resourceids.hxx>
24 : #include <com/sun/star/drawing/FillStyle.hpp>
25 : #include <com/sun/star/drawing/ShadingPattern.hpp>
26 : #include <sal/macros.h>
27 : #include <filter/msfilter/util.hxx>
28 : #include <comphelper/sequence.hxx>
29 :
30 : namespace writerfilter {
31 : namespace dmapper {
32 :
33 : using namespace ::com::sun::star;
34 :
35 5962 : CellColorHandler::CellColorHandler() :
36 : LoggedProperties("CellColorHandler"),
37 : m_nShadingPattern( drawing::ShadingPattern::CLEAR ),
38 : m_nColor( 0xffffffff ),
39 : m_nFillColor( 0xffffffff ),
40 5962 : m_OutputFormat( Form )
41 : {
42 5962 : }
43 :
44 11924 : CellColorHandler::~CellColorHandler()
45 : {
46 11924 : }
47 :
48 : // ST_Shd strings are converted to integers by the tokenizer, store strings in
49 : // the InteropGrabBag
50 5914 : uno::Any lcl_ConvertShd(sal_Int32 nIntValue)
51 : {
52 5914 : OUString aRet;
53 : // This should be in sync with the ST_Shd list in ooxml's model.xml.
54 5914 : switch (nIntValue)
55 : {
56 5090 : case NS_ooxml::LN_Value_ST_Shd_clear: aRet = "clear"; break;
57 480 : case NS_ooxml::LN_Value_ST_Shd_solid: aRet = "solid"; break;
58 10 : case NS_ooxml::LN_Value_ST_Shd_pct5: aRet = "pct5"; break;
59 25 : case NS_ooxml::LN_Value_ST_Shd_pct10: aRet = "pct10"; break;
60 72 : case NS_ooxml::LN_Value_ST_Shd_pct20: aRet = "pct20"; break;
61 114 : case NS_ooxml::LN_Value_ST_Shd_pct25: aRet = "pct25"; break;
62 41 : case NS_ooxml::LN_Value_ST_Shd_pct30: aRet = "pct30"; break;
63 0 : case NS_ooxml::LN_Value_ST_Shd_pct40: aRet = "pct40"; break;
64 61 : case NS_ooxml::LN_Value_ST_Shd_pct50: aRet = "pct50"; break;
65 0 : case NS_ooxml::LN_Value_ST_Shd_pct60: aRet = "pct60"; break;
66 0 : case NS_ooxml::LN_Value_ST_Shd_pct70: aRet = "pct70"; break;
67 10 : case NS_ooxml::LN_Value_ST_Shd_pct75: aRet = "pct75"; break;
68 0 : case NS_ooxml::LN_Value_ST_Shd_pct80: aRet = "pct80"; break;
69 0 : case NS_ooxml::LN_Value_ST_Shd_pct90: aRet = "pct90"; break;
70 3 : case NS_ooxml::LN_Value_ST_Shd_horzStripe: aRet = "horzStripe"; break;
71 0 : case NS_ooxml::LN_Value_ST_Shd_vertStripe: aRet = "vertStripe"; break;
72 0 : case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: aRet = "reverseDiagStripe"; break;
73 0 : case NS_ooxml::LN_Value_ST_Shd_diagStripe: aRet = "diagStripe"; break;
74 0 : case NS_ooxml::LN_Value_ST_Shd_horzCross: aRet = "horzCross"; break;
75 0 : case NS_ooxml::LN_Value_ST_Shd_diagCross: aRet = "diagCross"; break;
76 3 : case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: aRet = "thinHorzStripe"; break;
77 0 : case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: aRet = "thinVertStripe"; break;
78 0 : case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: aRet = "thinReverseDiagStripe"; break;
79 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: aRet = "thinDiagStripe"; break;
80 0 : case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: aRet = "thinHorzCross"; break;
81 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: aRet = "thinDiagCross"; break;
82 0 : case NS_ooxml::LN_Value_ST_Shd_pct12: aRet = "pct12"; break;
83 5 : case NS_ooxml::LN_Value_ST_Shd_pct15: aRet = "pct15"; break;
84 0 : case NS_ooxml::LN_Value_ST_Shd_pct35: aRet = "pct35"; break;
85 0 : case NS_ooxml::LN_Value_ST_Shd_pct37: aRet = "pct37"; break;
86 0 : case NS_ooxml::LN_Value_ST_Shd_pct45: aRet = "pct45"; break;
87 0 : case NS_ooxml::LN_Value_ST_Shd_pct55: aRet = "pct55"; break;
88 0 : case NS_ooxml::LN_Value_ST_Shd_pct62: aRet = "pct62"; break;
89 0 : case NS_ooxml::LN_Value_ST_Shd_pct65: aRet = "pct65"; break;
90 0 : case NS_ooxml::LN_Value_ST_Shd_pct85: aRet = "pct85"; break;
91 0 : case NS_ooxml::LN_Value_ST_Shd_pct87: aRet = "pct87"; break;
92 0 : case NS_ooxml::LN_Value_ST_Shd_pct95: aRet = "pct95"; break;
93 0 : case NS_ooxml::LN_Value_ST_Shd_nil: aRet = "nil"; break;
94 : }
95 5914 : return uno::makeAny(aRet);
96 : }
97 :
98 16414 : void CellColorHandler::lcl_attribute(Id rName, Value & rVal)
99 : {
100 16414 : sal_Int32 nIntValue = rVal.getInt();
101 16414 : switch( rName )
102 : {
103 : case NS_ooxml::LN_CT_Shd_val:
104 : {
105 5914 : createGrabBag("val", lcl_ConvertShd(nIntValue));
106 5914 : m_nShadingPattern = nIntValue;
107 : }
108 5914 : break;
109 : case NS_ooxml::LN_CT_Shd_fill:
110 5962 : createGrabBag("fill", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true))));
111 5962 : if( nIntValue == OOXML_COLOR_AUTO )
112 2742 : nIntValue = 0xffffff; //fill color auto means white
113 5962 : m_nFillColor = nIntValue;
114 5962 : break;
115 : case NS_ooxml::LN_CT_Shd_color:
116 3858 : createGrabBag("color", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true))));
117 3858 : if( nIntValue == OOXML_COLOR_AUTO )
118 2858 : nIntValue = 0; //shading color auto means black
119 : //color of the shading
120 3858 : m_nColor = nIntValue;
121 3858 : break;
122 : case NS_ooxml::LN_CT_Shd_themeFill:
123 396 : createGrabBag("themeFill", uno::makeAny(TDefTableHandler::getThemeColorTypeString(nIntValue)));
124 396 : break;
125 : case NS_ooxml::LN_CT_Shd_themeFillShade:
126 108 : createGrabBag("themeFillShade", uno::makeAny(OUString::number(nIntValue, 16)));
127 108 : break;
128 : case NS_ooxml::LN_CT_Shd_themeFillTint:
129 154 : createGrabBag("themeFillTint", uno::makeAny(OUString::number(nIntValue, 16)));
130 154 : break;
131 : case NS_ooxml::LN_CT_Shd_themeColor:
132 6 : createGrabBag("themeColor", uno::makeAny(TDefTableHandler::getThemeColorTypeString(nIntValue)));
133 6 : break;
134 : case NS_ooxml::LN_CT_Shd_themeShade:
135 8 : createGrabBag("themeShade", uno::makeAny(OUString::number(nIntValue, 16)));
136 8 : break;
137 : case NS_ooxml::LN_CT_Shd_themeTint:
138 8 : createGrabBag("themeTint", uno::makeAny(OUString::number(nIntValue, 16)));
139 8 : break;
140 : default:
141 : OSL_FAIL( "unknown attribute");
142 : }
143 16414 : }
144 :
145 0 : void CellColorHandler::lcl_sprm(Sprm & rSprm)
146 : {
147 : (void)rSprm;
148 0 : }
149 :
150 5962 : TablePropertyMapPtr CellColorHandler::getProperties()
151 : {
152 5962 : TablePropertyMapPtr pPropertyMap(new TablePropertyMap);
153 :
154 : // Code from binary word filter (the values are out of 1000)
155 5962 : sal_Int32 nWW8BrushStyle = 0;
156 5962 : switch (m_nShadingPattern)
157 : {
158 : // Clear-Brush
159 5090 : case NS_ooxml::LN_Value_ST_Shd_clear: nWW8BrushStyle = 0; break;
160 : // Solid-Brush
161 480 : case NS_ooxml::LN_Value_ST_Shd_solid: nWW8BrushStyle = 1000; break;
162 : // Percent values
163 10 : case NS_ooxml::LN_Value_ST_Shd_pct5: nWW8BrushStyle = 50; break;
164 25 : case NS_ooxml::LN_Value_ST_Shd_pct10: nWW8BrushStyle = 100; break;
165 72 : case NS_ooxml::LN_Value_ST_Shd_pct20: nWW8BrushStyle = 200; break;
166 114 : case NS_ooxml::LN_Value_ST_Shd_pct25: nWW8BrushStyle = 250; break;
167 41 : case NS_ooxml::LN_Value_ST_Shd_pct30: nWW8BrushStyle = 300; break;
168 0 : case NS_ooxml::LN_Value_ST_Shd_pct40: nWW8BrushStyle = 400; break;
169 61 : case NS_ooxml::LN_Value_ST_Shd_pct50: nWW8BrushStyle = 500; break;
170 0 : case NS_ooxml::LN_Value_ST_Shd_pct60: nWW8BrushStyle = 600; break;
171 0 : case NS_ooxml::LN_Value_ST_Shd_pct70: nWW8BrushStyle = 700; break;
172 10 : case NS_ooxml::LN_Value_ST_Shd_pct75: nWW8BrushStyle = 750; break;
173 0 : case NS_ooxml::LN_Value_ST_Shd_pct80: nWW8BrushStyle = 800; break;
174 0 : case NS_ooxml::LN_Value_ST_Shd_pct90: nWW8BrushStyle = 900; break;
175 : // Special cases
176 3 : case NS_ooxml::LN_Value_ST_Shd_horzStripe: nWW8BrushStyle = 333; break; // Dark Horizontal
177 0 : case NS_ooxml::LN_Value_ST_Shd_vertStripe: nWW8BrushStyle = 333; break; // Dark Vertical
178 0 : case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nWW8BrushStyle = 333; break; // Dark Forward Diagonal
179 0 : case NS_ooxml::LN_Value_ST_Shd_diagStripe: nWW8BrushStyle = 333; break; // Dark Backward Diagonal
180 0 : case NS_ooxml::LN_Value_ST_Shd_horzCross: nWW8BrushStyle = 333; break; // Dark Cross
181 0 : case NS_ooxml::LN_Value_ST_Shd_diagCross: nWW8BrushStyle = 333; break; // Dark Diagonal Cross
182 3 : case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nWW8BrushStyle = 333; break; // Horizontal
183 0 : case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nWW8BrushStyle = 333; break; // Vertical
184 0 : case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nWW8BrushStyle = 333; break; // Forward Diagonal
185 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nWW8BrushStyle = 333; break; // Backward Diagonal
186 0 : case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nWW8BrushStyle = 333; break; // Cross
187 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nWW8BrushStyle = 333; break; // 25 Diagonal Cross
188 : // Different shading types
189 0 : case NS_ooxml::LN_Value_ST_Shd_pct12: nWW8BrushStyle = 125; break;
190 5 : case NS_ooxml::LN_Value_ST_Shd_pct15: nWW8BrushStyle = 150; break;
191 0 : case NS_ooxml::LN_Value_ST_Shd_pct35: nWW8BrushStyle = 350; break;
192 0 : case NS_ooxml::LN_Value_ST_Shd_pct37: nWW8BrushStyle = 375; break;
193 0 : case NS_ooxml::LN_Value_ST_Shd_pct45: nWW8BrushStyle = 450; break;
194 0 : case NS_ooxml::LN_Value_ST_Shd_pct55: nWW8BrushStyle = 550; break;
195 0 : case NS_ooxml::LN_Value_ST_Shd_pct62: nWW8BrushStyle = 625; break;
196 0 : case NS_ooxml::LN_Value_ST_Shd_pct65: nWW8BrushStyle = 650; break;
197 0 : case NS_ooxml::LN_Value_ST_Shd_pct85: nWW8BrushStyle = 850; break;
198 0 : case NS_ooxml::LN_Value_ST_Shd_pct87: nWW8BrushStyle = 875; break;
199 0 : case NS_ooxml::LN_Value_ST_Shd_pct95: nWW8BrushStyle = 950; break;
200 : };
201 :
202 5962 : sal_Int32 nApplyColor = 0;
203 5962 : if( !nWW8BrushStyle )
204 : {
205 : // Clear-Brush
206 5138 : nApplyColor = m_nFillColor;
207 : }
208 : else
209 : {
210 824 : sal_Int32 nFore = m_nColor;
211 824 : sal_Int32 nBack = m_nFillColor;
212 :
213 824 : sal_uInt32 nRed = ((nFore & 0xff0000)>>0x10) * nWW8BrushStyle;
214 824 : sal_uInt32 nGreen = ((nFore & 0xff00)>>0x8) * nWW8BrushStyle;
215 824 : sal_uInt32 nBlue = (nFore & 0xff) * nWW8BrushStyle;
216 824 : nRed += ((nBack & 0xff0000)>>0x10) * (1000L - nWW8BrushStyle);
217 824 : nGreen += ((nBack & 0xff00)>>0x8)* (1000L - nWW8BrushStyle);
218 824 : nBlue += (nBack & 0xff) * (1000L - nWW8BrushStyle);
219 :
220 824 : nApplyColor = ( (nRed/1000) << 0x10 ) + ((nGreen/1000) << 8) + nBlue/1000;
221 : }
222 :
223 : // Check if it is a 'Character'
224 5962 : if (m_OutputFormat == Character)
225 : {
226 694 : sal_Int32 nShadingPattern = drawing::ShadingPattern::CLEAR;
227 694 : switch (m_nShadingPattern)
228 : {
229 649 : case NS_ooxml::LN_Value_ST_Shd_clear: nShadingPattern = drawing::ShadingPattern::CLEAR; break;
230 2 : case NS_ooxml::LN_Value_ST_Shd_solid: nShadingPattern = drawing::ShadingPattern::SOLID; break;
231 0 : case NS_ooxml::LN_Value_ST_Shd_pct5: nShadingPattern = drawing::ShadingPattern::PCT5; break;
232 0 : case NS_ooxml::LN_Value_ST_Shd_pct10: nShadingPattern = drawing::ShadingPattern::PCT10; break;
233 2 : case NS_ooxml::LN_Value_ST_Shd_pct20: nShadingPattern = drawing::ShadingPattern::PCT20; break;
234 0 : case NS_ooxml::LN_Value_ST_Shd_pct25: nShadingPattern = drawing::ShadingPattern::PCT25; break;
235 0 : case NS_ooxml::LN_Value_ST_Shd_pct30: nShadingPattern = drawing::ShadingPattern::PCT30; break;
236 0 : case NS_ooxml::LN_Value_ST_Shd_pct40: nShadingPattern = drawing::ShadingPattern::PCT40; break;
237 0 : case NS_ooxml::LN_Value_ST_Shd_pct50: nShadingPattern = drawing::ShadingPattern::PCT50; break;
238 0 : case NS_ooxml::LN_Value_ST_Shd_pct60: nShadingPattern = drawing::ShadingPattern::PCT60; break;
239 0 : case NS_ooxml::LN_Value_ST_Shd_pct70: nShadingPattern = drawing::ShadingPattern::PCT70; break;
240 0 : case NS_ooxml::LN_Value_ST_Shd_pct75: nShadingPattern = drawing::ShadingPattern::PCT75; break;
241 0 : case NS_ooxml::LN_Value_ST_Shd_pct80: nShadingPattern = drawing::ShadingPattern::PCT80; break;
242 0 : case NS_ooxml::LN_Value_ST_Shd_pct90: nShadingPattern = drawing::ShadingPattern::PCT90; break;
243 0 : case NS_ooxml::LN_Value_ST_Shd_horzStripe: nShadingPattern = drawing::ShadingPattern::HORZ_STRIPE; break;
244 0 : case NS_ooxml::LN_Value_ST_Shd_vertStripe: nShadingPattern = drawing::ShadingPattern::VERT_STRIPE; break;
245 0 : case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nShadingPattern = drawing::ShadingPattern::REVERSE_DIAG_STRIPE; break;
246 0 : case NS_ooxml::LN_Value_ST_Shd_diagStripe: nShadingPattern = drawing::ShadingPattern::DIAG_STRIPE; break;
247 0 : case NS_ooxml::LN_Value_ST_Shd_horzCross: nShadingPattern = drawing::ShadingPattern::HORZ_CROSS; break;
248 0 : case NS_ooxml::LN_Value_ST_Shd_diagCross: nShadingPattern = drawing::ShadingPattern::DIAG_CROSS; break;
249 0 : case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_STRIPE; break;
250 0 : case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nShadingPattern = drawing::ShadingPattern::THIN_VERT_STRIPE; break;
251 0 : case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_REVERSE_DIAG_STRIPE; break;
252 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_STRIPE; break;
253 0 : case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_CROSS; break;
254 0 : case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_CROSS; break;
255 0 : case NS_ooxml::LN_Value_ST_Shd_pct12: nShadingPattern = drawing::ShadingPattern::PCT12; break;
256 3 : case NS_ooxml::LN_Value_ST_Shd_pct15: nShadingPattern = drawing::ShadingPattern::PCT15; break;
257 0 : case NS_ooxml::LN_Value_ST_Shd_pct35: nShadingPattern = drawing::ShadingPattern::PCT35; break;
258 0 : case NS_ooxml::LN_Value_ST_Shd_pct37: nShadingPattern = drawing::ShadingPattern::PCT37; break;
259 0 : case NS_ooxml::LN_Value_ST_Shd_pct45: nShadingPattern = drawing::ShadingPattern::PCT45; break;
260 0 : case NS_ooxml::LN_Value_ST_Shd_pct55: nShadingPattern = drawing::ShadingPattern::PCT55; break;
261 0 : case NS_ooxml::LN_Value_ST_Shd_pct62: nShadingPattern = drawing::ShadingPattern::PCT62; break;
262 0 : case NS_ooxml::LN_Value_ST_Shd_pct65: nShadingPattern = drawing::ShadingPattern::PCT65; break;
263 0 : case NS_ooxml::LN_Value_ST_Shd_pct85: nShadingPattern = drawing::ShadingPattern::PCT85; break;
264 0 : case NS_ooxml::LN_Value_ST_Shd_pct87: nShadingPattern = drawing::ShadingPattern::PCT87; break;
265 0 : case NS_ooxml::LN_Value_ST_Shd_pct95: nShadingPattern = drawing::ShadingPattern::PCT95; break;
266 : };
267 :
268 : // Write the shading pattern property
269 694 : pPropertyMap->Insert(PROP_CHAR_SHADING_VALUE, uno::makeAny( nShadingPattern ));
270 : }
271 :
272 5962 : if (m_OutputFormat == Paragraph)
273 : {
274 287 : pPropertyMap->Insert(PROP_FILL_STYLE, uno::makeAny(drawing::FillStyle_SOLID));
275 287 : pPropertyMap->Insert(PROP_FILL_COLOR, uno::makeAny(nApplyColor));
276 : }
277 : else
278 11350 : pPropertyMap->Insert( m_OutputFormat == Form ? PROP_BACK_COLOR
279 17025 : : PROP_CHAR_BACK_COLOR, uno::makeAny( nApplyColor ));
280 :
281 5962 : createGrabBag("originalColor", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nApplyColor, true))));
282 :
283 5962 : return pPropertyMap;
284 : }
285 :
286 22376 : void CellColorHandler::createGrabBag(const OUString& aName, const uno::Any& rAny)
287 : {
288 22376 : if (m_aInteropGrabBagName.isEmpty())
289 25335 : return;
290 :
291 19417 : beans::PropertyValue aValue;
292 19417 : aValue.Name = aName;
293 19417 : aValue.Value = rAny;
294 19417 : m_aInteropGrabBag.push_back(aValue);
295 : }
296 :
297 5172 : void CellColorHandler::enableInteropGrabBag(const OUString& aName)
298 : {
299 5172 : m_aInteropGrabBagName = aName;
300 5172 : }
301 :
302 5172 : beans::PropertyValue CellColorHandler::getInteropGrabBag()
303 : {
304 5172 : beans::PropertyValue aRet;
305 5172 : aRet.Name = m_aInteropGrabBagName;
306 5172 : aRet.Value = uno::makeAny(comphelper::containerToSequence(m_aInteropGrabBag));
307 5172 : return aRet;
308 : }
309 :
310 287 : void CellColorHandler::disableInteropGrabBag()
311 : {
312 287 : m_aInteropGrabBagName.clear();
313 287 : m_aInteropGrabBag.clear();
314 287 : }
315 :
316 287 : bool CellColorHandler::isInteropGrabBagEnabled()
317 : {
318 287 : return !(m_aInteropGrabBagName.isEmpty());
319 : }
320 :
321 : } //namespace dmapper
322 : } //namespace writerfilter
323 :
324 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|