Coverage Report

Created: 2026-09-28 10:59

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