LibreOffice Module writerfilter (master) 1
CellColorHandler.cxx
Go to the documentation of this file.
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 "TDefTableHandler.hxx"
22#include <ooxml/resourceids.hxx>
23#include <com/sun/star/drawing/FillStyle.hpp>
24#include <com/sun/star/drawing/ShadingPattern.hpp>
27#include <tools/color.hxx>
29
30namespace writerfilter::dmapper {
31
32using namespace ::com::sun::star;
33
35LoggedProperties("CellColorHandler"),
36m_nShadingPattern( drawing::ShadingPattern::CLEAR ),
37m_nColor( 0xffffffff ),
38m_nFillColor( 0xffffffff ),
39m_bAutoFillColor( true ),
40m_bFillSpecified( false ),
41 m_OutputFormat( Form )
42{
43}
44
46{
47}
48
49// ST_Shd strings are converted to integers by the tokenizer, store strings in
50// the InteropGrabBag
51static uno::Any lcl_ConvertShd(sal_Int32 nIntValue)
52{
53 OUString aRet;
54 // This should be in sync with the ST_Shd list in ooxml's model.xml.
55 switch (nIntValue)
56 {
57 case NS_ooxml::LN_Value_ST_Shd_clear: aRet = "clear"; break;
58 case NS_ooxml::LN_Value_ST_Shd_solid: aRet = "solid"; break;
59 case NS_ooxml::LN_Value_ST_Shd_pct5: aRet = "pct5"; break;
60 case NS_ooxml::LN_Value_ST_Shd_pct10: aRet = "pct10"; break;
61 case NS_ooxml::LN_Value_ST_Shd_pct20: aRet = "pct20"; break;
62 case NS_ooxml::LN_Value_ST_Shd_pct25: aRet = "pct25"; break;
63 case NS_ooxml::LN_Value_ST_Shd_pct30: aRet = "pct30"; break;
64 case NS_ooxml::LN_Value_ST_Shd_pct40: aRet = "pct40"; break;
65 case NS_ooxml::LN_Value_ST_Shd_pct50: aRet = "pct50"; break;
66 case NS_ooxml::LN_Value_ST_Shd_pct60: aRet = "pct60"; break;
67 case NS_ooxml::LN_Value_ST_Shd_pct70: aRet = "pct70"; break;
68 case NS_ooxml::LN_Value_ST_Shd_pct75: aRet = "pct75"; break;
69 case NS_ooxml::LN_Value_ST_Shd_pct80: aRet = "pct80"; break;
70 case NS_ooxml::LN_Value_ST_Shd_pct90: aRet = "pct90"; break;
71 case NS_ooxml::LN_Value_ST_Shd_horzStripe: aRet = "horzStripe"; break;
72 case NS_ooxml::LN_Value_ST_Shd_vertStripe: aRet = "vertStripe"; break;
73 case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: aRet = "reverseDiagStripe"; break;
74 case NS_ooxml::LN_Value_ST_Shd_diagStripe: aRet = "diagStripe"; break;
75 case NS_ooxml::LN_Value_ST_Shd_horzCross: aRet = "horzCross"; break;
76 case NS_ooxml::LN_Value_ST_Shd_diagCross: aRet = "diagCross"; break;
77 case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: aRet = "thinHorzStripe"; break;
78 case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: aRet = "thinVertStripe"; break;
79 case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: aRet = "thinReverseDiagStripe"; break;
80 case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: aRet = "thinDiagStripe"; break;
81 case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: aRet = "thinHorzCross"; break;
82 case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: aRet = "thinDiagCross"; break;
83 case NS_ooxml::LN_Value_ST_Shd_pct12: aRet = "pct12"; break;
84 case NS_ooxml::LN_Value_ST_Shd_pct15: aRet = "pct15"; break;
85 case NS_ooxml::LN_Value_ST_Shd_pct35: aRet = "pct35"; break;
86 case NS_ooxml::LN_Value_ST_Shd_pct37: aRet = "pct37"; break;
87 case NS_ooxml::LN_Value_ST_Shd_pct45: aRet = "pct45"; break;
88 case NS_ooxml::LN_Value_ST_Shd_pct55: aRet = "pct55"; break;
89 case NS_ooxml::LN_Value_ST_Shd_pct62: aRet = "pct62"; break;
90 case NS_ooxml::LN_Value_ST_Shd_pct65: aRet = "pct65"; break;
91 case NS_ooxml::LN_Value_ST_Shd_pct85: aRet = "pct85"; break;
92 case NS_ooxml::LN_Value_ST_Shd_pct87: aRet = "pct87"; break;
93 case NS_ooxml::LN_Value_ST_Shd_pct95: aRet = "pct95"; break;
94 case NS_ooxml::LN_Value_ST_Shd_nil: aRet = "nil"; break;
95 }
96 return uno::Any(aRet);
97}
98
100{
101 sal_Int32 nIntValue = rVal.getInt();
102 switch( rName )
103 {
104 case NS_ooxml::LN_CT_Shd_val:
105 {
106 createGrabBag("val", lcl_ConvertShd(nIntValue));
107 m_nShadingPattern = nIntValue;
108 }
109 break;
110 case NS_ooxml::LN_CT_Shd_fill:
112 if( nIntValue == sal_Int32(COL_AUTO) )
113 nIntValue = 0xffffff; //fill color auto means white
114 else
115 m_bAutoFillColor = false;
116
117 m_nFillColor = nIntValue;
118 m_bFillSpecified = true;
119 break;
120 case NS_ooxml::LN_CT_Shd_color:
122 if( nIntValue == sal_Int32(COL_AUTO) )
123 nIntValue = 0; //shading color auto means black
124 //color of the shading
125 m_nColor = nIntValue;
126 break;
127 case NS_ooxml::LN_CT_Shd_themeFill:
130 break;
131 case NS_ooxml::LN_CT_Shd_themeFillShade:
132 m_nFillThemeColorShade = nIntValue;
133 createGrabBag("themeFillShade", uno::Any(OUString::number(nIntValue, 16)));
134 break;
135 case NS_ooxml::LN_CT_Shd_themeFillTint:
136 m_nFillThemeColorTint = nIntValue;
137 createGrabBag("themeFillTint", uno::Any(OUString::number(nIntValue, 16)));
138 break;
139 case NS_ooxml::LN_CT_Shd_themeColor:
142 break;
143 case NS_ooxml::LN_CT_Shd_themeShade:
144 m_nThemeColorShade = nIntValue;
145 createGrabBag("themeShade", uno::Any(OUString::number(nIntValue, 16)));
146 break;
147 case NS_ooxml::LN_CT_Shd_themeTint:
148 m_nThemeColorTint = nIntValue;
149 createGrabBag("themeTint", uno::Any(OUString::number(nIntValue, 16)));
150 break;
151 default:
152 OSL_FAIL( "unknown attribute");
153 }
154}
155
157
159{
160 TablePropertyMapPtr pPropertyMap(new TablePropertyMap);
161
162 // Code from binary word filter (the values are out of 1000)
163 sal_Int32 nWW8BrushStyle = 0;
164 switch (m_nShadingPattern)
165 {
166 // Clear-Brush
167 case NS_ooxml::LN_Value_ST_Shd_clear: nWW8BrushStyle = 0; break;
168 // Solid-Brush
169 case NS_ooxml::LN_Value_ST_Shd_solid: nWW8BrushStyle = 1000; break;
170 // Percent values
171 case NS_ooxml::LN_Value_ST_Shd_pct5: nWW8BrushStyle = 50; break;
172 case NS_ooxml::LN_Value_ST_Shd_pct10: nWW8BrushStyle = 100; break;
173 case NS_ooxml::LN_Value_ST_Shd_pct20: nWW8BrushStyle = 200; break;
174 case NS_ooxml::LN_Value_ST_Shd_pct25: nWW8BrushStyle = 250; break;
175 case NS_ooxml::LN_Value_ST_Shd_pct30: nWW8BrushStyle = 300; break;
176 case NS_ooxml::LN_Value_ST_Shd_pct40: nWW8BrushStyle = 400; break;
177 case NS_ooxml::LN_Value_ST_Shd_pct50: nWW8BrushStyle = 500; break;
178 case NS_ooxml::LN_Value_ST_Shd_pct60: nWW8BrushStyle = 600; break;
179 case NS_ooxml::LN_Value_ST_Shd_pct70: nWW8BrushStyle = 700; break;
180 case NS_ooxml::LN_Value_ST_Shd_pct75: nWW8BrushStyle = 750; break;
181 case NS_ooxml::LN_Value_ST_Shd_pct80: nWW8BrushStyle = 800; break;
182 case NS_ooxml::LN_Value_ST_Shd_pct90: nWW8BrushStyle = 900; break;
183 // Special cases
184 case NS_ooxml::LN_Value_ST_Shd_horzStripe: nWW8BrushStyle = 333; break; // Dark Horizontal
185 case NS_ooxml::LN_Value_ST_Shd_vertStripe: nWW8BrushStyle = 333; break; // Dark Vertical
186 case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nWW8BrushStyle = 333; break; // Dark Forward Diagonal
187 case NS_ooxml::LN_Value_ST_Shd_diagStripe: nWW8BrushStyle = 333; break; // Dark Backward Diagonal
188 case NS_ooxml::LN_Value_ST_Shd_horzCross: nWW8BrushStyle = 333; break; // Dark Cross
189 case NS_ooxml::LN_Value_ST_Shd_diagCross: nWW8BrushStyle = 333; break; // Dark Diagonal Cross
190 case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nWW8BrushStyle = 333; break; // Horizontal
191 case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nWW8BrushStyle = 333; break; // Vertical
192 case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nWW8BrushStyle = 333; break; // Forward Diagonal
193 case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nWW8BrushStyle = 333; break; // Backward Diagonal
194 case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nWW8BrushStyle = 333; break; // Cross
195 case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nWW8BrushStyle = 333; break; // 25 Diagonal Cross
196 // Different shading types
197 case NS_ooxml::LN_Value_ST_Shd_pct12: nWW8BrushStyle = 125; break;
198 case NS_ooxml::LN_Value_ST_Shd_pct15: nWW8BrushStyle = 150; break;
199 case NS_ooxml::LN_Value_ST_Shd_pct35: nWW8BrushStyle = 350; break;
200 case NS_ooxml::LN_Value_ST_Shd_pct37: nWW8BrushStyle = 375; break;
201 case NS_ooxml::LN_Value_ST_Shd_pct45: nWW8BrushStyle = 450; break;
202 case NS_ooxml::LN_Value_ST_Shd_pct55: nWW8BrushStyle = 550; break;
203 case NS_ooxml::LN_Value_ST_Shd_pct62: nWW8BrushStyle = 625; break;
204 case NS_ooxml::LN_Value_ST_Shd_pct65: nWW8BrushStyle = 650; break;
205 case NS_ooxml::LN_Value_ST_Shd_pct85: nWW8BrushStyle = 850; break;
206 case NS_ooxml::LN_Value_ST_Shd_pct87: nWW8BrushStyle = 875; break;
207 case NS_ooxml::LN_Value_ST_Shd_pct95: nWW8BrushStyle = 950; break;
208 }
209
210 sal_Int32 nApplyColor = 0;
211 if( !nWW8BrushStyle )
212 {
213 // Clear-Brush
215 nApplyColor = sal_Int32(COL_AUTO);
216 else
217 nApplyColor = m_nFillColor;
218 }
219 else
220 {
221 sal_Int32 nFore = m_nColor;
222 sal_Int32 nBack = m_nFillColor;
223
224 sal_uInt32 nRed = ((nFore & 0xff0000)>>0x10) * nWW8BrushStyle;
225 sal_uInt32 nGreen = ((nFore & 0xff00)>>0x8) * nWW8BrushStyle;
226 sal_uInt32 nBlue = (nFore & 0xff) * nWW8BrushStyle;
227 nRed += ((nBack & 0xff0000)>>0x10) * (1000L - nWW8BrushStyle);
228 nGreen += ((nBack & 0xff00)>>0x8)* (1000L - nWW8BrushStyle);
229 nBlue += (nBack & 0xff) * (1000L - nWW8BrushStyle);
230
231 nApplyColor = ( (nRed/1000) << 0x10 ) + ((nGreen/1000) << 8) + nBlue/1000;
232 }
233
234 // Check if it is a 'Character'
236 {
237 sal_Int32 nShadingPattern = drawing::ShadingPattern::CLEAR;
238 switch (m_nShadingPattern)
239 {
240 case NS_ooxml::LN_Value_ST_Shd_clear: nShadingPattern = drawing::ShadingPattern::CLEAR; break;
241 case NS_ooxml::LN_Value_ST_Shd_solid: nShadingPattern = drawing::ShadingPattern::SOLID; break;
242 case NS_ooxml::LN_Value_ST_Shd_pct5: nShadingPattern = drawing::ShadingPattern::PCT5; break;
243 case NS_ooxml::LN_Value_ST_Shd_pct10: nShadingPattern = drawing::ShadingPattern::PCT10; break;
244 case NS_ooxml::LN_Value_ST_Shd_pct20: nShadingPattern = drawing::ShadingPattern::PCT20; break;
245 case NS_ooxml::LN_Value_ST_Shd_pct25: nShadingPattern = drawing::ShadingPattern::PCT25; break;
246 case NS_ooxml::LN_Value_ST_Shd_pct30: nShadingPattern = drawing::ShadingPattern::PCT30; break;
247 case NS_ooxml::LN_Value_ST_Shd_pct40: nShadingPattern = drawing::ShadingPattern::PCT40; break;
248 case NS_ooxml::LN_Value_ST_Shd_pct50: nShadingPattern = drawing::ShadingPattern::PCT50; break;
249 case NS_ooxml::LN_Value_ST_Shd_pct60: nShadingPattern = drawing::ShadingPattern::PCT60; break;
250 case NS_ooxml::LN_Value_ST_Shd_pct70: nShadingPattern = drawing::ShadingPattern::PCT70; break;
251 case NS_ooxml::LN_Value_ST_Shd_pct75: nShadingPattern = drawing::ShadingPattern::PCT75; break;
252 case NS_ooxml::LN_Value_ST_Shd_pct80: nShadingPattern = drawing::ShadingPattern::PCT80; break;
253 case NS_ooxml::LN_Value_ST_Shd_pct90: nShadingPattern = drawing::ShadingPattern::PCT90; break;
254 case NS_ooxml::LN_Value_ST_Shd_horzStripe: nShadingPattern = drawing::ShadingPattern::HORZ_STRIPE; break;
255 case NS_ooxml::LN_Value_ST_Shd_vertStripe: nShadingPattern = drawing::ShadingPattern::VERT_STRIPE; break;
256 case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nShadingPattern = drawing::ShadingPattern::REVERSE_DIAG_STRIPE; break;
257 case NS_ooxml::LN_Value_ST_Shd_diagStripe: nShadingPattern = drawing::ShadingPattern::DIAG_STRIPE; break;
258 case NS_ooxml::LN_Value_ST_Shd_horzCross: nShadingPattern = drawing::ShadingPattern::HORZ_CROSS; break;
259 case NS_ooxml::LN_Value_ST_Shd_diagCross: nShadingPattern = drawing::ShadingPattern::DIAG_CROSS; break;
260 case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_STRIPE; break;
261 case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nShadingPattern = drawing::ShadingPattern::THIN_VERT_STRIPE; break;
262 case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_REVERSE_DIAG_STRIPE; break;
263 case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_STRIPE; break;
264 case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_CROSS; break;
265 case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_CROSS; break;
266 case NS_ooxml::LN_Value_ST_Shd_pct12: nShadingPattern = drawing::ShadingPattern::PCT12; break;
267 case NS_ooxml::LN_Value_ST_Shd_pct15: nShadingPattern = drawing::ShadingPattern::PCT15; break;
268 case NS_ooxml::LN_Value_ST_Shd_pct35: nShadingPattern = drawing::ShadingPattern::PCT35; break;
269 case NS_ooxml::LN_Value_ST_Shd_pct37: nShadingPattern = drawing::ShadingPattern::PCT37; break;
270 case NS_ooxml::LN_Value_ST_Shd_pct45: nShadingPattern = drawing::ShadingPattern::PCT45; break;
271 case NS_ooxml::LN_Value_ST_Shd_pct55: nShadingPattern = drawing::ShadingPattern::PCT55; break;
272 case NS_ooxml::LN_Value_ST_Shd_pct62: nShadingPattern = drawing::ShadingPattern::PCT62; break;
273 case NS_ooxml::LN_Value_ST_Shd_pct65: nShadingPattern = drawing::ShadingPattern::PCT65; break;
274 case NS_ooxml::LN_Value_ST_Shd_pct85: nShadingPattern = drawing::ShadingPattern::PCT85; break;
275 case NS_ooxml::LN_Value_ST_Shd_pct87: nShadingPattern = drawing::ShadingPattern::PCT87; break;
276 case NS_ooxml::LN_Value_ST_Shd_pct95: nShadingPattern = drawing::ShadingPattern::PCT95; break;
277 }
278
279 // Write the shading pattern property
280 pPropertyMap->Insert(PROP_CHAR_SHADING_VALUE, uno::Any( nShadingPattern ));
281 }
282
283 if (m_OutputFormat == Paragraph && m_nShadingPattern != NS_ooxml::LN_Value_ST_Shd_nil)
284 {
285 if (nWW8BrushStyle || !m_bAutoFillColor)
286 pPropertyMap->Insert(PROP_FILL_STYLE, uno::Any(drawing::FillStyle_SOLID));
287 else if (m_bFillSpecified) // m_bAutoFillColor == true
288 pPropertyMap->Insert(PROP_FILL_STYLE, uno::Any(drawing::FillStyle_NONE));
289
290 pPropertyMap->Insert(PROP_FILL_COLOR, uno::Any(nApplyColor));
292 pPropertyMap->Insert(PROP_FILL_COMPLEX_COLOR, uno::Any(xComplexColor));
293 }
294 else if ( nWW8BrushStyle || !m_bAutoFillColor || m_bFillSpecified )
295 {
296 if (m_OutputFormat == Form)
297 {
298 pPropertyMap->Insert(PROP_BACK_COLOR, uno::Any(nApplyColor));
299 }
300 else
301 {
302 pPropertyMap->Insert(PROP_CHAR_BACK_COLOR, uno::Any(nApplyColor));
303 auto aComplexColor = getFillComplexColor();
304 if (aComplexColor.getType() != model::ColorType::Unused)
305 {
306 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
307 pPropertyMap->Insert(PROP_CHAR_BACKGROUND_COMPLEX_COLOR, uno::Any(xComplexColor));
308 }
309 }
310 }
312
313 return pPropertyMap;
314}
315
316void CellColorHandler::createGrabBag(const OUString& aName, const uno::Any& rAny)
317{
318 if (m_aInteropGrabBagName.isEmpty())
319 return;
320
321 beans::PropertyValue aValue;
322 aValue.Name = aName;
323 aValue.Value = rAny;
324 m_aInteropGrabBag.push_back(aValue);
325}
326
327void CellColorHandler::enableInteropGrabBag(const OUString& aName)
328{
330}
331
333{
334 beans::PropertyValue aRet;
335 aRet.Name = m_aInteropGrabBagName;
337 return aRet;
338}
339
341{
342 m_aInteropGrabBagName.clear();
343 m_aInteropGrabBag.clear();
344}
345
347{
348 return !(m_aInteropGrabBagName.isEmpty());
349}
350
352{
353 model::ComplexColor aComplexColor;
355 {
356 aComplexColor.setSchemeColor(m_eThemeColorType);
357
358 if (m_nThemeColorTint > 0 )
359 {
360 sal_Int16 nTint = sal_Int16((255.0 - m_nThemeColorTint) * 10000.0 / 255.0);
362 }
363 if (m_nThemeColorShade > 0)
364 {
365 sal_Int16 nShade = sal_Int16((255.0 - m_nThemeColorShade) * 10000 / 255.0);
367 }
368 }
369 return aComplexColor;
370}
371
373{
374 model::ComplexColor aComplexColor;
376 {
378
379 if (m_nFillThemeColorTint > 0 )
380 {
381 sal_Int16 nTint = sal_Int16((255.0 - m_nFillThemeColorTint) * 10000.0 / 255.0);
383 }
385 {
386 sal_Int16 nShade = sal_Int16((255.0 - m_nFillThemeColorShade) * 10000.0 / 255.0);
388 }
389 }
390 return aComplexColor;
391}
392
393} //namespace writerfilter
394
395/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void setSchemeColor(ThemeColorType eType)
void addTransformation(Transformation const &rTransform)
An SPRM: Section, Paragraph and Run Modifier.
virtual int getInt() const =0
Returns integer representation of the value.
model::ComplexColor getComplexColor() const
void createGrabBag(const OUString &aName, const css::uno::Any &rValue)
void enableInteropGrabBag(const OUString &aName)
virtual void lcl_attribute(Id Name, Value &val) override
css::beans::PropertyValue getInteropGrabBag()
virtual void lcl_sprm(Sprm &sprm) override
std::vector< css::beans::PropertyValue > m_aInteropGrabBag
model::ComplexColor getFillComplexColor() const
static model::ThemeColorType getThemeColorTypeIndex(sal_Int32 nType)
static OUString getThemeColorTypeString(sal_Int32 nType)
ColorTransparency
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
OUString aName
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
uno::Reference< util::XComplexColor > createXComplexColor(model::ComplexColor const &rColor)
OUString ConvertColorOU(const Color &rColor)
static uno::Any lcl_ConvertShd(sal_Int32 nIntValue)
sal_uInt32 Id