Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/xoutdev/xattrbmp.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 <com/sun/star/awt/XBitmap.hpp>
21
#include <com/sun/star/graphic/XGraphic.hpp>
22
23
#include <comphelper/propertyvalue.hxx>
24
#include <tools/debug.hxx>
25
#include <vcl/virdev.hxx>
26
#include <vcl/bitmap.hxx>
27
#include <svl/style.hxx>
28
#include <editeng/memberids.h>
29
#include <svx/strings.hrc>
30
#include <svx/xtable.hxx>
31
#include <svx/xdef.hxx>
32
#include <svx/unomid.hxx>
33
#include <svx/unoapi.hxx>
34
#include <svx/svdmodel.hxx>
35
#include <svx/xbitmap.hxx>
36
#include <svx/xbtmpit.hxx>
37
#include <com/sun/star/beans/PropertyValue.hpp>
38
#include <vcl/BitmapTools.hxx>
39
#include <vcl/GraphicLoader.hxx>
40
41
#include <libxml/xmlwriter.h>
42
43
using namespace ::com::sun::star;
44
45
XOBitmap::XOBitmap( const Bitmap& rBmp ) :
46
7.53k
    m_xGraphicObject  (new GraphicObject(rBmp)),
47
7.53k
    m_bGraphicDirty   ( false )
48
7.53k
{
49
7.53k
}
50
51
XOBitmap::~XOBitmap()
52
7.53k
{
53
7.53k
}
54
55
Bitmap XOBitmap::GetBitmap() const
56
15.0k
{
57
15.0k
    return GetGraphicObject().GetGraphic().GetBitmap();
58
15.0k
}
59
60
const GraphicObject& XOBitmap::GetGraphicObject() const
61
15.0k
{
62
15.0k
    if( m_bGraphicDirty )
63
0
        const_cast<XOBitmap*>(this)->Array2Bitmap();
64
65
15.0k
    return *m_xGraphicObject;
66
15.0k
}
67
68
void XOBitmap::Bitmap2Array()
69
7.53k
{
70
7.53k
    ScopedVclPtrInstance< VirtualDevice > pVDev;
71
7.53k
    bool            bPixelColor = false;
72
7.53k
    const Bitmap    aBitmap( GetBitmap() );
73
7.53k
    const sal_Int32 nLines = 8; // type dependent
74
75
7.53k
    if( !m_pPixelArray )
76
7.52k
        m_pPixelArray.reset( new sal_uInt16[ nLines * nLines ] );
77
78
7.53k
    pVDev->SetOutputSizePixel( aBitmap.GetSizePixel() );
79
7.53k
    pVDev->DrawBitmap( Point(), aBitmap );
80
7.53k
    m_aPixelColor = m_aBckgrColor = pVDev->GetPixel( Point() );
81
82
    // create array and determine foreground and background color
83
67.7k
    for (sal_Int32 i = 0; i < nLines; ++i)
84
60.2k
    {
85
542k
        for (sal_Int32 j = 0; j < nLines; ++j)
86
481k
        {
87
481k
            if ( pVDev->GetPixel( Point( j, i ) ) == m_aBckgrColor )
88
446k
                m_pPixelArray[ j + i * nLines ] = 0;
89
35.0k
            else
90
35.0k
            {
91
35.0k
                m_pPixelArray[ j + i * nLines ] = 1;
92
35.0k
                if( !bPixelColor )
93
7.52k
                {
94
7.52k
                    m_aPixelColor = pVDev->GetPixel( Point( j, i ) );
95
7.52k
                    bPixelColor = true;
96
7.52k
                }
97
35.0k
            }
98
481k
        }
99
60.2k
    }
100
7.53k
}
101
102
/// convert array, fore- and background color into a bitmap
103
void XOBitmap::Array2Bitmap()
104
7.52k
{
105
7.52k
    if (!m_pPixelArray)
106
0
        return;
107
108
7.52k
    ScopedVclPtrInstance< VirtualDevice > pVDev;
109
7.52k
    const sal_Int32 nLines = 8; // type dependent
110
111
7.52k
    pVDev->SetOutputSizePixel( Size( nLines, nLines ) );
112
113
    // create bitmap
114
67.7k
    for (sal_Int32 i = 0; i < nLines; ++i)
115
60.2k
    {
116
542k
        for (sal_Int32 j = 0; j < nLines; ++j)
117
481k
        {
118
481k
            if( m_pPixelArray[ j + i * nLines ] == 0 )
119
446k
                pVDev->DrawPixel( Point( j, i ), m_aBckgrColor );
120
35.0k
            else
121
35.0k
                pVDev->DrawPixel( Point( j, i ), m_aPixelColor );
122
481k
        }
123
60.2k
    }
124
125
7.52k
    m_xGraphicObject.reset(new GraphicObject(pVDev->GetBitmap(Point(), Size(nLines, nLines))));
126
7.52k
    m_bGraphicDirty = false;
127
7.52k
}
128
129
130
0
SfxPoolItem* XFillBitmapItem::CreateDefault() { return new XFillBitmapItem; }
131
132
XFillBitmapItem::XFillBitmapItem(const OUString& rName, const GraphicObject& rGraphicObject)
133
20.5k
:   NameOrIndex(XATTR_FILLBITMAP, rName),
134
20.5k
    maGraphicObject(rGraphicObject)
135
20.5k
{
136
20.5k
}
137
138
XFillBitmapItem::XFillBitmapItem(const XFillBitmapItem& rItem)
139
28.0k
:   NameOrIndex(rItem),
140
28.0k
    maGraphicObject(rItem.maGraphicObject)
141
28.0k
{
142
28.0k
}
143
144
XFillBitmapItem::XFillBitmapItem(const GraphicObject& rGraphicObject)
145
161k
    : NameOrIndex(XATTR_FILLBITMAP, -1)
146
161k
    , maGraphicObject(rGraphicObject)
147
161k
{
148
161k
}
149
150
XFillBitmapItem* XFillBitmapItem::Clone(SfxItemPool* /*pPool*/) const
151
28.0k
{
152
28.0k
    return new XFillBitmapItem(*this);
153
28.0k
}
154
155
bool XFillBitmapItem::operator==(const SfxPoolItem& rItem) const
156
19.9k
{
157
19.9k
    return (NameOrIndex::operator==(rItem)
158
10.1k
        && maGraphicObject == static_cast<const XFillBitmapItem&>(rItem).maGraphicObject);
159
19.9k
}
160
161
162
bool XFillBitmapItem::isPattern() const
163
46.9k
{
164
46.9k
    Color aBack, aFront;
165
46.9k
    return vcl::bitmap::isHistorical8x8(GetGraphicObject().GetGraphic().GetBitmap(), aBack, aFront);
166
46.9k
}
167
168
bool XFillBitmapItem::GetPresentation(
169
    SfxItemPresentation /*ePres*/,
170
    MapUnit /*eCoreUnit*/,
171
    MapUnit /*ePresUnit*/,
172
    OUString& rText,
173
    const IntlWrapper&) const
174
0
{
175
0
    rText += GetName();
176
0
    return true;
177
0
}
178
179
bool XFillBitmapItem::QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId) const
180
1.24k
{
181
1.24k
    nMemberId &= ~CONVERT_TWIPS;
182
183
    // needed for MID_NAME
184
1.24k
    OUString aApiName;
185
    // needed for complete item (MID 0)
186
1.24k
    OUString aInternalName;
187
188
1.24k
    css::uno::Reference< css::awt::XBitmap > xBmp;
189
190
1.24k
    if( nMemberId == MID_NAME )
191
62
    {
192
62
         aApiName = SvxUnogetApiNameForItem(Which(), GetName());
193
62
    }
194
1.17k
    else if( nMemberId == 0  )
195
0
    {
196
0
        aInternalName = GetName();
197
0
    }
198
199
1.24k
    if (nMemberId == MID_BITMAP ||
200
62
        nMemberId == 0)
201
1.17k
    {
202
1.17k
        xBmp.set(GetGraphicObject().GetGraphic().GetXGraphic(), uno::UNO_QUERY);
203
1.17k
    }
204
205
1.24k
    if( nMemberId == MID_NAME )
206
62
        rVal <<= aApiName;
207
1.17k
    else if( nMemberId == MID_BITMAP )
208
1.17k
        rVal <<= xBmp;
209
0
    else
210
0
    {
211
        // member-id 0 => complete item (e.g. for toolbars)
212
0
        DBG_ASSERT( nMemberId == 0, "invalid member-id" );
213
0
        uno::Sequence< beans::PropertyValue > aPropSeq{
214
0
            comphelper::makePropertyValue(u"Name"_ustr, aInternalName),
215
0
            comphelper::makePropertyValue(u"Bitmap"_ustr, xBmp)
216
0
        };
217
218
0
        rVal <<= aPropSeq;
219
0
    }
220
221
1.24k
    return true;
222
1.24k
}
223
224
bool XFillBitmapItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId )
225
688
{
226
688
    nMemberId &= ~CONVERT_TWIPS;
227
228
688
    OUString aName;
229
688
    OUString aURL;
230
688
    css::uno::Reference< css::awt::XBitmap > xBmp;
231
688
    css::uno::Reference< css::graphic::XGraphic > xGraphic;
232
233
688
    bool bSetURL    = false;
234
688
    bool bSetName   = false;
235
688
    bool bSetBitmap = false;
236
237
688
    if( nMemberId == MID_NAME )
238
0
        bSetName = (rVal >>= aName);
239
688
    else if( nMemberId == MID_BITMAP )
240
688
    {
241
688
        if (rVal.has<OUString>())
242
0
        {
243
0
            bSetURL = true;
244
0
            aURL = rVal.get<OUString>();
245
0
        }
246
688
        else if (rVal.has<uno::Reference<awt::XBitmap>>())
247
688
        {
248
688
            bSetBitmap = true;
249
688
            xBmp = rVal.get<uno::Reference<awt::XBitmap>>();
250
688
        }
251
0
        else if (rVal.has<uno::Reference<graphic::XGraphic>>())
252
0
        {
253
0
            bSetBitmap = true;
254
0
            xGraphic = rVal.get<uno::Reference<graphic::XGraphic>>();
255
0
        }
256
688
    }
257
0
    else
258
0
    {
259
0
        DBG_ASSERT( nMemberId == 0, "invalid member-id" );
260
0
        uno::Sequence< beans::PropertyValue >   aPropSeq;
261
0
        if( rVal >>= aPropSeq )
262
0
        {
263
0
            for (const auto& rProp : aPropSeq)
264
0
            {
265
0
                if ( rProp.Name == "Name" )
266
0
                    bSetName = (rProp.Value >>= aName);
267
0
                else if ( rProp.Name == "Bitmap" )
268
0
                    bSetBitmap = (rProp.Value >>= xBmp);
269
0
                else if ( rProp.Name == "FillBitmapURL" )
270
0
                    bSetURL = (rProp.Value >>= aURL);
271
0
            }
272
0
        }
273
0
    }
274
275
688
    if( bSetName )
276
0
    {
277
0
        SetName( aName );
278
0
    }
279
688
    if (bSetURL && !aURL.isEmpty())
280
0
    {
281
0
        Graphic aGraphic = vcl::graphic::loadFromURL(aURL);
282
0
        if (!aGraphic.IsNone())
283
0
        {
284
0
            maGraphicObject.SetGraphic(aGraphic.GetXGraphic());
285
0
        }
286
0
    }
287
688
    else if( bSetBitmap )
288
688
    {
289
688
        if (xBmp.is())
290
44
        {
291
44
            xGraphic.set(xBmp, uno::UNO_QUERY);
292
44
        }
293
688
        if (xGraphic.is())
294
44
        {
295
44
            maGraphicObject.SetGraphic(xGraphic);
296
44
        }
297
688
    }
298
299
688
    return (bSetURL || bSetName || bSetBitmap);
300
688
}
301
302
bool XFillBitmapItem::CompareValueFunc( const NameOrIndex* p1, const NameOrIndex* p2 )
303
37.2k
{
304
37.2k
    const GraphicObject& aGraphicObjectA(static_cast<const XFillBitmapItem*>(p1)->GetGraphicObject());
305
37.2k
    const GraphicObject& aGraphicObjectB(static_cast<const XFillBitmapItem*>(p2)->GetGraphicObject());
306
307
37.2k
    return aGraphicObjectA == aGraphicObjectB;
308
37.2k
}
309
310
std::unique_ptr<XFillBitmapItem> XFillBitmapItem::checkForUniqueItem( SdrModel& rModel ) const
311
46.9k
{
312
46.9k
    XPropertyListType aListType = XPropertyListType::Bitmap;
313
46.9k
    if(isPattern())
314
7.60k
        aListType = XPropertyListType::Pattern;
315
46.9k
    const OUString aUniqueName(CheckNamedItem(
316
46.9k
        XATTR_FILLBITMAP, &rModel.GetItemPool(),
317
46.9k
        XFillBitmapItem::CompareValueFunc, RID_SVXSTR_BMP21,
318
46.9k
        rModel.GetPropertyList(aListType)));
319
320
    // if the given name is not valid, replace it!
321
46.9k
    if( aUniqueName != GetName() )
322
9.43k
    {
323
9.43k
        return std::make_unique<XFillBitmapItem>(aUniqueName, maGraphicObject);
324
9.43k
    }
325
326
37.5k
    return nullptr;
327
46.9k
}
328
329
void XFillBitmapItem::dumpAsXml(xmlTextWriterPtr pWriter) const
330
0
{
331
0
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBitmapItem"));
332
0
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
333
334
0
    NameOrIndex::dumpAsXml(pWriter);
335
336
0
    (void)xmlTextWriterEndElement(pWriter);
337
0
}
338
339
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */