Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/vml/vmlshapecontainer.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 <oox/vml/vmlshapecontainer.hxx>
21
22
#include <oox/vml/vmldrawing.hxx>
23
#include <oox/vml/vmlshape.hxx>
24
25
#include <osl/diagnose.h>
26
27
namespace oox::vml {
28
29
using namespace ::com::sun::star::awt;
30
using namespace ::com::sun::star::drawing;
31
using namespace ::com::sun::star::uno;
32
33
namespace {
34
35
template< typename ShapeType >
36
void lclMapShapesById( RefMap< OUString, ShapeType >& orMap, const RefVector< ShapeType >& rVector )
37
4.87k
{
38
4.87k
    for (auto const& elem : rVector)
39
5.63k
    {
40
5.63k
        const OUString& rShapeId = elem->getShapeId();
41
5.63k
        OSL_ENSURE( !rShapeId.isEmpty(), "lclMapShapesById - missing shape identifier" );
42
5.63k
        if( !rShapeId.isEmpty() )
43
5.49k
        {
44
5.49k
            OSL_ENSURE(orMap.find(rShapeId) == orMap.end() || orMap[rShapeId] == elem,
45
5.49k
                       "lclMapShapesById - shape identifier already used");
46
5.49k
            orMap[ rShapeId ] = elem;
47
5.49k
        }
48
5.63k
    }
49
4.87k
}
vmlshapecontainer.cxx:void oox::vml::(anonymous namespace)::lclMapShapesById<oox::vml::ShapeType>(oox::RefMap<rtl::OUString, oox::vml::ShapeType, std::__1::less<rtl::OUString> >&, oox::RefVector<oox::vml::ShapeType> const&)
Line
Count
Source
37
2.66k
{
38
2.66k
    for (auto const& elem : rVector)
39
2.18k
    {
40
2.18k
        const OUString& rShapeId = elem->getShapeId();
41
2.18k
        OSL_ENSURE( !rShapeId.isEmpty(), "lclMapShapesById - missing shape identifier" );
42
2.18k
        if( !rShapeId.isEmpty() )
43
2.18k
        {
44
2.18k
            OSL_ENSURE(orMap.find(rShapeId) == orMap.end() || orMap[rShapeId] == elem,
45
2.18k
                       "lclMapShapesById - shape identifier already used");
46
2.18k
            orMap[ rShapeId ] = elem;
47
2.18k
        }
48
2.18k
    }
49
2.66k
}
vmlshapecontainer.cxx:void oox::vml::(anonymous namespace)::lclMapShapesById<oox::vml::ShapeBase>(oox::RefMap<rtl::OUString, oox::vml::ShapeBase, std::__1::less<rtl::OUString> >&, oox::RefVector<oox::vml::ShapeBase> const&)
Line
Count
Source
37
2.21k
{
38
2.21k
    for (auto const& elem : rVector)
39
3.44k
    {
40
3.44k
        const OUString& rShapeId = elem->getShapeId();
41
3.44k
        OSL_ENSURE( !rShapeId.isEmpty(), "lclMapShapesById - missing shape identifier" );
42
3.44k
        if( !rShapeId.isEmpty() )
43
3.30k
        {
44
3.30k
            OSL_ENSURE(orMap.find(rShapeId) == orMap.end() || orMap[rShapeId] == elem,
45
3.30k
                       "lclMapShapesById - shape identifier already used");
46
3.30k
            orMap[ rShapeId ] = elem;
47
3.30k
        }
48
3.44k
    }
49
2.21k
}
50
51
} // namespace
52
53
ShapeContainer::ShapeContainer( Drawing& rDrawing ) :
54
32.2k
    mrDrawing( rDrawing )
55
32.2k
{
56
32.2k
}
57
58
ShapeContainer::~ShapeContainer()
59
32.2k
{
60
32.2k
}
61
62
std::shared_ptr<ShapeType> ShapeContainer::createShapeType()
63
790
{
64
790
    auto xShape = std::make_shared<ShapeType>( mrDrawing );
65
790
    maTypes.push_back( xShape );
66
790
    return xShape;
67
790
}
68
69
void ShapeContainer::finalizeFragmentImport()
70
2.21k
{
71
    // map all shape templates by shape identifier
72
2.21k
    lclMapShapesById( maTypesById, maTypes );
73
    // map all shapes by shape identifier
74
2.21k
    lclMapShapesById( maShapesById, maShapes );
75
    /*  process all shapes (map all children templates/shapes in group shapes,
76
        resolve template references in all shapes) */
77
2.21k
    maShapes.forEachMem( &ShapeBase::finalizeFragmentImport );
78
2.21k
}
79
80
const ShapeType* ShapeContainer::getShapeTypeById( const OUString& rShapeId ) const
81
7.83k
{
82
7.83k
    if (maTypesById.empty() && !maTypes.empty())
83
449
    {
84
449
        lclMapShapesById(const_cast<ShapeTypeMap&>(maTypesById), maTypes);
85
449
    }
86
87
    // search in own shape template list
88
7.83k
    if( const ShapeType* pType = maTypesById.get( rShapeId ).get() )
89
6.95k
        return pType;
90
    // search deep in child shapes
91
879
    for (auto const& shape : maShapes)
92
3.00k
        if( const ShapeType* pType = shape->getChildTypeById( rShapeId ) )
93
19
            return pType;
94
860
    return nullptr;
95
879
}
96
97
const ShapeBase* ShapeContainer::getShapeById( const OUString& rShapeId ) const
98
0
{
99
    // search in own shape list
100
0
    if( const ShapeBase* pShape = maShapesById.get( rShapeId ).get() )
101
0
        return pShape;
102
    // search deep in child shapes
103
0
    for (auto const& shape : maShapes)
104
0
        if( const ShapeBase* pShape = shape->getChildById( rShapeId ) )
105
0
            return pShape;
106
0
    return nullptr;
107
0
}
108
109
std::shared_ptr< ShapeBase > ShapeContainer::takeLastShape()
110
1.90k
{
111
1.90k
    OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::takeLastShape - illegal call, Word filter only" );
112
1.90k
    assert( !markStack.empty());
113
1.90k
    if( markStack.top() >= maShapes.size())
114
86
        return std::shared_ptr< ShapeBase >();
115
1.81k
    std::shared_ptr< ShapeBase > ret = maShapes.back();
116
1.81k
    maShapes.pop_back();
117
1.81k
    return ret;
118
1.90k
}
119
120
void ShapeContainer::pushMark()
121
1.93k
{
122
1.93k
    markStack.push( maShapes.size());
123
1.93k
}
124
125
void ShapeContainer::popMark()
126
1.89k
{
127
1.89k
    assert( !markStack.empty());
128
1.89k
    markStack.pop();
129
1.89k
}
130
131
void ShapeContainer::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
132
37.5k
{
133
37.5k
    for (auto const& shape : maShapes)
134
1.62k
        shape->convertAndInsert( rxShapes, pParentAnchor );
135
37.5k
}
136
137
} // namespace oox::vml
138
139
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */