Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/themeelementscontext.cxx
Line
Count
Source
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
20
#include <drawingml/themeelementscontext.hxx>
21
#include <drawingml/clrschemecontext.hxx>
22
#include <drawingml/lineproperties.hxx>
23
#include <drawingml/linepropertiescontext.hxx>
24
#include <drawingml/fillproperties.hxx>
25
#include <drawingml/misccontexts.hxx>
26
#include <drawingml/textcharacterproperties.hxx>
27
#include <oox/drawingml/theme.hxx>
28
#include <oox/helper/attributelist.hxx>
29
#include <drawingml/effectproperties.hxx>
30
#include <drawingml/effectpropertiescontext.hxx>
31
#include <oox/token/namespaces.hxx>
32
#include <oox/token/tokens.hxx>
33
34
using namespace ::oox::core;
35
using namespace ::com::sun::star::uno;
36
37
namespace oox::drawingml {
38
39
namespace {
40
41
class FillStyleListContext : public ContextHandler2
42
{
43
public:
44
    FillStyleListContext(ContextHandler2Helper const & rParent, FillStyleList& rFillStyleList, model::FormatScheme& rFormatScheme);
45
    virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
46
47
protected:
48
    FillStyleList& mrFillStyleList;
49
    model::FormatScheme& mrFormatScheme;
50
    virtual model::FillStyle* createAndAddFillStyle()
51
13.3k
    {
52
13.3k
        return mrFormatScheme.addFillStyle();
53
13.3k
    }
54
};
55
56
}
57
58
FillStyleListContext::FillStyleListContext(ContextHandler2Helper const & rParent, FillStyleList& rFillStyleList, model::FormatScheme& rFormatScheme)
59
8.93k
    : ContextHandler2(rParent)
60
8.93k
    , mrFillStyleList(rFillStyleList)
61
8.93k
    , mrFormatScheme(rFormatScheme)
62
8.93k
{
63
8.93k
}
64
65
ContextHandlerRef FillStyleListContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
66
26.7k
{
67
26.7k
    switch (nElement)
68
26.7k
    {
69
0
        case A_TOKEN( noFill ):
70
9.62k
        case A_TOKEN( solidFill ):
71
26.7k
        case A_TOKEN( gradFill ):
72
26.7k
        case A_TOKEN( blipFill ):
73
26.7k
        case A_TOKEN( pattFill ):
74
26.7k
        case A_TOKEN( grpFill ):
75
26.7k
        {
76
26.7k
            mrFillStyleList.push_back(std::make_shared<FillProperties>());
77
26.7k
            model::FillStyle* pFillStyle = createAndAddFillStyle();
78
26.7k
            return FillPropertiesContext::createFillContext(*this, nElement, rAttribs, *mrFillStyleList.back(), pFillStyle);
79
26.7k
        }
80
26.7k
    }
81
0
    return nullptr;
82
26.7k
}
83
84
namespace
85
{
86
87
class BackgroundFillStyleListContext : public FillStyleListContext
88
{
89
public:
90
    BackgroundFillStyleListContext(ContextHandler2Helper const & rParent, FillStyleList& rFillStyleList, model::FormatScheme& rFormatScheme)
91
4.46k
        : FillStyleListContext(rParent, rFillStyleList, rFormatScheme)
92
4.46k
    {}
93
94
protected:
95
    model::FillStyle* createAndAddFillStyle() override
96
13.3k
    {
97
13.3k
        return mrFormatScheme.addBackgroundFillStyle();
98
13.3k
    }
99
};
100
101
} // end anonymous ns
102
103
namespace {
104
105
class LineStyleListContext : public ContextHandler2
106
{
107
public:
108
    LineStyleListContext(ContextHandler2Helper const & rParent, LineStyleList& rLineStyleList, model::FormatScheme& rFormatScheme);
109
    virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
110
111
private:
112
    model::FormatScheme& mrFormatScheme;
113
    LineStyleList& mrLineStyleList;
114
};
115
116
}
117
118
LineStyleListContext::LineStyleListContext( ContextHandler2Helper const & rParent, LineStyleList& rLineStyleList, model::FormatScheme& rFormatScheme)
119
4.46k
    : ContextHandler2(rParent)
120
4.46k
    , mrFormatScheme(rFormatScheme)
121
4.46k
    , mrLineStyleList(rLineStyleList)
122
4.46k
{
123
4.46k
}
124
125
ContextHandlerRef LineStyleListContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
126
13.3k
{
127
13.3k
    switch (nElement)
128
13.3k
    {
129
13.3k
        case A_TOKEN(ln):
130
13.3k
        {
131
13.3k
            mrLineStyleList.push_back( std::make_shared<LineProperties>( ) );
132
13.3k
            model::LineStyle* pLineStyle = mrFormatScheme.addLineStyle();
133
13.3k
            return new LinePropertiesContext(*this, rAttribs, *mrLineStyleList.back(), pLineStyle);
134
0
        }
135
13.3k
    }
136
0
    return nullptr;
137
13.3k
}
138
139
namespace {
140
141
class EffectStyleListContext : public ContextHandler2
142
{
143
public:
144
    EffectStyleListContext(ContextHandler2Helper const & rParent, EffectStyleList& rEffectStyleList, model::FormatScheme& rFormatScheme);
145
    virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
146
147
private:
148
    model::FormatScheme& mrFormatScheme;
149
    model::EffectStyle* mpEffectStyle;
150
    EffectStyleList& mrEffectStyleList;
151
};
152
153
}
154
155
EffectStyleListContext::EffectStyleListContext( ContextHandler2Helper const & rParent, EffectStyleList& rEffectStyleList, model::FormatScheme& rFormatScheme)
156
4.46k
    : ContextHandler2(rParent)
157
4.46k
    , mrFormatScheme(rFormatScheme)
158
4.46k
    , mpEffectStyle(nullptr)
159
4.46k
    , mrEffectStyleList(rEffectStyleList)
160
4.46k
{
161
4.46k
}
162
163
ContextHandlerRef EffectStyleListContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
164
34.3k
{
165
34.3k
    switch( nElement )
166
34.3k
    {
167
13.3k
        case A_TOKEN( effectStyle ):
168
13.3k
        {
169
13.3k
            mpEffectStyle = mrFormatScheme.addEffectStyle();
170
13.3k
            mrEffectStyleList.push_back( std::make_shared<EffectProperties>( ) );
171
13.3k
            return this;
172
0
        }
173
13.3k
        case A_TOKEN( effectLst ):  // CT_EffectList
174
13.3k
        {
175
13.3k
            if( mrEffectStyleList.back() )
176
13.3k
                return new EffectPropertiesContext(*this, *mrEffectStyleList.back(), mpEffectStyle);
177
13.3k
        }
178
0
        break;
179
34.3k
    }
180
7.54k
    return nullptr;
181
34.3k
}
182
183
namespace
184
{
185
186
class FontSchemeContext : public ContextHandler2
187
{
188
public:
189
    FontSchemeContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, FontScheme& rFontScheme,
190
                      std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>>& rSupplementalFontMap,
191
                      model::Theme& rTheme);
192
    ~FontSchemeContext();
193
    virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
194
    virtual void onEndElement() override;
195
196
private:
197
    FontScheme& mrFontScheme;
198
    TextCharacterPropertiesPtr mxCharProps;
199
    std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>>& mrSupplementalFontMap;
200
    sal_Int32 maCurrentFont = 0;
201
    model::Theme& mrTheme;
202
    model::FontScheme maFontScheme;
203
};
204
205
} // end anonymous ns
206
207
FontSchemeContext::FontSchemeContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, FontScheme& rFontScheme,
208
                                     std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>>& rSupplementalFontMap,
209
                                     model::Theme& rTheme)
210
4.46k
    : ContextHandler2(rParent)
211
4.46k
    , mrFontScheme(rFontScheme)
212
4.46k
    , mrSupplementalFontMap(rSupplementalFontMap)
213
4.46k
    , mrTheme(rTheme)
214
4.46k
    , maFontScheme(rAttribs.getStringDefaulted(XML_name))
215
4.46k
{
216
4.46k
}
217
218
FontSchemeContext::~FontSchemeContext()
219
4.46k
{
220
4.46k
    mrTheme.setFontScheme(maFontScheme);
221
4.46k
}
222
223
namespace
224
{
225
226
void fillThemeFont(model::ThemeFont& rThemeFont, const AttributeList& rAttribs)
227
26.7k
{
228
26.7k
    rThemeFont.maTypeface = rAttribs.getStringDefaulted(XML_typeface);
229
26.7k
    rThemeFont.maPanose = rAttribs.getStringDefaulted(XML_panose);
230
26.7k
    rThemeFont.maCharset = rAttribs.getInteger(XML_charset, WINDOWS_CHARSET_DEFAULT);
231
26.7k
    sal_Int32 nPitchFamily = rAttribs.getInteger(XML_pitchFamily, 0);
232
26.7k
    TextFont::resolvePitch(nPitchFamily, rThemeFont.maPitch, rThemeFont.maFamily);
233
26.7k
}
234
235
} // end anonymous ns
236
237
ContextHandlerRef FontSchemeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
238
228k
{
239
228k
    switch( nElement )
240
228k
    {
241
4.46k
        case A_TOKEN( majorFont ):
242
4.46k
            mxCharProps = std::make_shared<TextCharacterProperties>();
243
4.46k
            mrFontScheme[ XML_major ] = mxCharProps;
244
4.46k
            maCurrentFont = XML_major;
245
4.46k
            return this;
246
4.46k
        case A_TOKEN( minorFont ):
247
4.46k
            mxCharProps = std::make_shared<TextCharacterProperties>();
248
4.46k
            mrFontScheme[ XML_minor ] = mxCharProps;
249
4.46k
            maCurrentFont = XML_minor;
250
4.46k
            return this;
251
8.93k
        case A_TOKEN( latin ):
252
8.93k
        {
253
8.93k
            if (mxCharProps)
254
8.93k
                mxCharProps->maLatinFont.setAttributes(rAttribs);
255
256
8.93k
            model::ThemeFont aThemeFont;
257
8.93k
            fillThemeFont(aThemeFont, rAttribs);
258
8.93k
            if (maCurrentFont == XML_major)
259
4.46k
                maFontScheme.setMajorLatin(aThemeFont);
260
4.46k
            else if (maCurrentFont == XML_minor)
261
4.46k
                maFontScheme.setMinorLatin(aThemeFont);
262
8.93k
        }
263
8.93k
        break;
264
8.93k
        case A_TOKEN( ea ):
265
8.93k
        {
266
8.93k
            if( mxCharProps )
267
8.93k
                mxCharProps->maAsianFont.setAttributes( rAttribs );
268
8.93k
            model::ThemeFont aThemeFont;
269
8.93k
            fillThemeFont(aThemeFont, rAttribs);
270
8.93k
            if (maCurrentFont == XML_major)
271
4.46k
                maFontScheme.setMajorAsian(aThemeFont);
272
4.46k
            else if (maCurrentFont == XML_minor)
273
4.46k
                maFontScheme.setMinorAsian(aThemeFont);
274
8.93k
        }
275
8.93k
        break;
276
8.93k
        case A_TOKEN( cs ):
277
8.93k
        {
278
8.93k
            if( mxCharProps )
279
8.93k
                mxCharProps->maComplexFont.setAttributes( rAttribs );
280
8.93k
            model::ThemeFont aThemeFont;
281
8.93k
            fillThemeFont(aThemeFont, rAttribs);
282
8.93k
            if (maCurrentFont == XML_major)
283
4.46k
                maFontScheme.setMajorComplex(aThemeFont);
284
4.46k
            else if (maCurrentFont == XML_minor)
285
4.46k
                maFontScheme.setMinorComplex(aThemeFont);
286
8.93k
        }
287
8.93k
        break;
288
192k
        case A_TOKEN(font):
289
192k
        {
290
192k
            OUString aScript = rAttribs.getStringDefaulted(XML_script);
291
192k
            OUString aTypeface = rAttribs.getStringDefaulted(XML_typeface);
292
192k
            mrSupplementalFontMap[maCurrentFont].emplace_back(std::pair<OUString, OUString>{aScript, aTypeface});
293
192k
            if (maCurrentFont == XML_major)
294
96.3k
                maFontScheme.addMajorSupplementalFont({aScript, aTypeface});
295
96.3k
            else if (maCurrentFont == XML_minor)
296
96.3k
                maFontScheme.addMinorSupplementalFont({aScript, aTypeface});
297
192k
        }
298
192k
        break;
299
228k
    }
300
219k
    return nullptr;
301
228k
}
302
303
void FontSchemeContext::onEndElement()
304
13.3k
{
305
13.3k
    switch( getCurrentElement() )
306
13.3k
    {
307
4.46k
        case A_TOKEN( majorFont ):
308
8.93k
        case A_TOKEN( minorFont ):
309
8.93k
            mxCharProps.reset();
310
8.93k
        break;
311
13.3k
    }
312
13.3k
}
313
314
ThemeElementsContext::ThemeElementsContext(ContextHandler2Helper const & rParent, Theme& rOoxTheme, model::Theme& rTheme)
315
4.46k
    : ContextHandler2(rParent)
316
4.46k
    , mrOoxTheme(rOoxTheme)
317
4.46k
    , mrTheme(rTheme)
318
4.46k
{
319
4.46k
}
320
321
ContextHandlerRef ThemeElementsContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs)
322
31.2k
{
323
    // CT_BaseStyles
324
31.2k
    switch (nElement)
325
31.2k
    {
326
4.46k
        case A_TOKEN( clrScheme ):  // CT_ColorScheme
327
4.46k
        {
328
4.46k
            OUString aColorSchemeName = rAttribs.getStringDefaulted(XML_name);
329
4.46k
            mrTheme.setColorSet(std::make_shared<model::ColorSet>(aColorSchemeName));
330
4.46k
            if (rAttribs.hasAttribute(XML_name))
331
4.46k
                mrOoxTheme.getClrScheme().SetName(rAttribs.getStringDefaulted(XML_name));
332
4.46k
            return new clrSchemeContext(*this, mrOoxTheme.getClrScheme(), *mrTheme.getColorSet());
333
0
        }
334
4.46k
        case A_TOKEN( fontScheme ): // CT_FontScheme
335
4.46k
        {
336
4.46k
            if (rAttribs.hasAttribute(XML_name))
337
4.46k
                mrOoxTheme.setFontSchemeName(rAttribs.getStringDefaulted(XML_name));
338
339
4.46k
            return new FontSchemeContext(*this, rAttribs, mrOoxTheme.getFontScheme(), mrOoxTheme.getSupplementalFontMap(), mrTheme);
340
0
        }
341
342
4.46k
        case A_TOKEN( fmtScheme ):  // CT_StyleMatrix
343
4.46k
        {
344
4.46k
            if (rAttribs.hasAttribute(XML_name))
345
4.46k
                mrOoxTheme.setFormatSchemeName(rAttribs.getStringDefaulted(XML_name));
346
4.46k
            return this;
347
0
        }
348
349
4.46k
        case A_TOKEN( fillStyleLst ):   // CT_FillStyleList
350
4.46k
            return new FillStyleListContext(*this, mrOoxTheme.getFillStyleList(), mrTheme.getFormatScheme());
351
4.46k
        case A_TOKEN( lnStyleLst ):    // CT_LineStyleList
352
4.46k
            return new LineStyleListContext(*this, mrOoxTheme.getLineStyleList(), mrTheme.getFormatScheme());
353
4.46k
        case A_TOKEN( effectStyleLst ): // CT_EffectStyleList
354
4.46k
            return new EffectStyleListContext(*this, mrOoxTheme.getEffectStyleList(), mrTheme.getFormatScheme());
355
4.46k
        case A_TOKEN( bgFillStyleLst ): // CT_BackgroundFillStyleList
356
4.46k
            return new BackgroundFillStyleListContext( *this, mrOoxTheme.getBgFillStyleList(), mrTheme.getFormatScheme());
357
31.2k
    }
358
0
    return nullptr;
359
31.2k
}
360
361
} // namespace oox::drawingml
362
363
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */