Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/svdraw/svdoutl.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 <optional>
21
#include <svx/svdoutl.hxx>
22
#include <editeng/outliner.hxx>
23
#include <svx/svdmodel.hxx>
24
#include <svx/svdotext.hxx>
25
#include <svx/svdpage.hxx>
26
#include <editeng/editstat.hxx>
27
#include <svl/itempool.hxx>
28
#include <editeng/editview.hxx>
29
#include <editeng/editeng.hxx>
30
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
31
32
33
SdrOutliner::SdrOutliner( SfxItemPool* pItemPool, OutlinerMode nMode )
34
699k
:   Outliner( pItemPool, nMode ),
35
699k
    mpVisualizedPage(nullptr)
36
699k
{
37
699k
}
38
39
40
SdrOutliner::~SdrOutliner()
41
699k
{
42
699k
}
43
44
45
void SdrOutliner::SetTextObj( const SdrTextObj* pObj )
46
4.74M
{
47
4.74M
    if( pObj && pObj != mxWeakTextObj.get().get() )
48
1.41M
    {
49
1.41M
        SetUpdateLayout(false);
50
1.41M
        OutlinerMode nOutlinerMode2 = OutlinerMode::OutlineObject;
51
1.41M
        if ( !pObj->IsOutlText() )
52
1.19M
            nOutlinerMode2 = OutlinerMode::TextObject;
53
1.41M
        Init( nOutlinerMode2 );
54
55
1.41M
        resetScalingParameters();
56
57
1.41M
        EEControlBits nStat = GetControlWord();
58
1.41M
        nStat &= ~EEControlBits( EEControlBits::STRETCHING | EEControlBits::AUTOPAGESIZE );
59
1.41M
        SetControlWord(nStat);
60
61
1.41M
        Size aMaxSize( 100000,100000 );
62
1.41M
        SetMinAutoPaperSize( Size() );
63
1.41M
        SetMaxAutoPaperSize( aMaxSize );
64
1.41M
        SetPaperSize( aMaxSize );
65
1.41M
        SetTextColumns(pObj->GetTextColumnsNumber(), pObj->GetTextColumnsSpacing());
66
1.41M
        ClearPolygon();
67
68
1.41M
        if (pObj->GetTextEditOutliner())
69
0
            SetBackgroundColor(pObj->GetTextEditOutliner()->GetEditEngine().GetBackgroundColor());
70
1.41M
    }
71
72
4.74M
    mxWeakTextObj = const_cast< SdrTextObj* >(pObj);
73
4.74M
}
74
75
void SdrOutliner::SetTextObjNoInit( const SdrTextObj* pObj )
76
93.8k
{
77
93.8k
    mxWeakTextObj = const_cast< SdrTextObj* >(pObj);
78
93.8k
}
79
80
OUString SdrOutliner::CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos,
81
                                     std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor,
82
                                     std::optional<FontLineStyle>& rpFldLineStyle)
83
3.61M
{
84
3.61M
    bool bOk = false;
85
3.61M
    OUString aRet;
86
87
3.61M
    if(auto pTextObj = mxWeakTextObj.get())
88
3.04M
        bOk = pTextObj->CalcFieldValue(rField, nPara, nPos, false, rpTxtColor, rpFldColor, rpFldLineStyle, aRet);
89
90
3.61M
    if (!bOk)
91
3.61M
        aRet = Outliner::CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor, rpFldLineStyle);
92
93
3.61M
    return aRet;
94
3.61M
}
95
96
const SdrTextObj* SdrOutliner::GetTextObj() const
97
3.61M
{
98
3.61M
    return mxWeakTextObj.get().get();
99
3.61M
}
100
101
bool SdrOutliner::hasEditViewCallbacks() const
102
0
{
103
0
    for (size_t a(0); a < GetViewCount(); a++)
104
0
    {
105
0
        OutlinerView* pOutlinerView = GetView(a);
106
107
0
        if (pOutlinerView && pOutlinerView->GetEditView().getEditViewCallbacks())
108
0
        {
109
0
            return true;
110
0
        }
111
0
    }
112
113
0
    return false;
114
0
}
115
116
std::optional<bool> SdrOutliner::GetCompatFlag(SdrCompatibilityFlag eFlag) const
117
0
{
118
0
    if( mpVisualizedPage )
119
0
    {
120
0
        return {mpVisualizedPage->getSdrModelFromSdrPage().GetCompatibilityFlag(eFlag)};
121
0
    }
122
0
    return {};
123
0
}
124
125
void TextHierarchyBreakupBlockText::processDrawPortionInfo(const DrawPortionInfo& rDrawPortionInfo)
126
1.39k
{
127
    // Is clipping wanted? This is text clipping; only accept a portion
128
    // if it's completely in the range
129
1.39k
    if(!mrClipRange.isEmpty())
130
0
    {
131
        // Test start position first; this allows to not get the text range at
132
        // all if text is far outside
133
0
        const basegfx::B2DPoint aStartPosition(rDrawPortionInfo.mrStartPos.X(), rDrawPortionInfo.mrStartPos.Y());
134
135
0
        if(!mrClipRange.isInside(aStartPosition))
136
0
        {
137
0
            return;
138
0
        }
139
140
        // Start position is inside. Get TextBoundRect and TopLeft next
141
0
        drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
142
0
        aTextLayouterDevice.setFont(rDrawPortionInfo.mrFont);
143
144
0
        const basegfx::B2DRange aTextBoundRect(
145
0
            aTextLayouterDevice.getTextBoundRect(
146
0
                rDrawPortionInfo.maText, rDrawPortionInfo.mnTextStart, rDrawPortionInfo.mnTextLen));
147
0
        const basegfx::B2DPoint aTopLeft(aTextBoundRect.getMinimum() + aStartPosition);
148
149
0
        if(!mrClipRange.isInside(aTopLeft))
150
0
        {
151
0
            return;
152
0
        }
153
154
        // TopLeft is inside. Get BottomRight and check
155
0
        const basegfx::B2DPoint aBottomRight(aTextBoundRect.getMaximum() + aStartPosition);
156
157
0
        if(!mrClipRange.isInside(aBottomRight))
158
0
        {
159
0
            return;
160
0
        }
161
162
        // all inside, clip was successful
163
0
    }
164
165
1.39k
    TextHierarchyBreakupOutliner::processDrawPortionInfo(rDrawPortionInfo);
166
1.39k
}
167
168
TextHierarchyBreakupBlockText::TextHierarchyBreakupBlockText(
169
    SdrOutliner& rOutliner,
170
    const basegfx::B2DHomMatrix& rNewTransformA,
171
    const basegfx::B2DHomMatrix& rNewTransformB,
172
    const basegfx::B2DRange& rClipRange)
173
483
: TextHierarchyBreakupOutliner(
174
483
    rOutliner,
175
483
    rNewTransformA,
176
483
    rNewTransformB)
177
483
, mrClipRange(rClipRange)
178
483
{
179
483
}
180
181
void TextHierarchyBreakupContourText::processDrawPortionInfo(const DrawPortionInfo& rDrawPortionInfo)
182
0
    {
183
        // for contour text, ignore (clip away) all portions which are below
184
        // the visible area given by maScale
185
0
        if(static_cast<double>(rDrawPortionInfo.mrStartPos.Y()) < maScale.getY())
186
0
        {
187
0
            TextHierarchyBreakupOutliner::processDrawPortionInfo(rDrawPortionInfo);
188
0
        }
189
0
    }
190
191
TextHierarchyBreakupContourText::TextHierarchyBreakupContourText(
192
    SdrOutliner& rOutliner,
193
    const basegfx::B2DHomMatrix& rNewTransformA,
194
    const basegfx::B2DHomMatrix& rNewTransformB,
195
    const basegfx::B2DVector& rScale)
196
0
: TextHierarchyBreakupOutliner(
197
0
    rOutliner,
198
0
    rNewTransformA,
199
0
    rNewTransformB)
200
0
, maScale(rScale)
201
0
{
202
0
}
203
204
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */