Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svx/source/svdraw/svdograf.cxx
Line
Count
Source (jump to first uncovered line)
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 <unotools/streamwrap.hxx>
21
22
#include <sfx2/lnkbase.hxx>
23
#include <rtl/ustrbuf.hxx>
24
#include <tools/helpers.hxx>
25
#include <tools/stream.hxx>
26
#include <sot/exchange.hxx>
27
#include <sot/formats.hxx>
28
#include <vcl/GraphicObject.hxx>
29
#include <vcl/svapp.hxx>
30
31
#include <sfx2/linkmgr.hxx>
32
#include <svx/dialmgr.hxx>
33
#include <svx/strings.hrc>
34
#include <svx/svdhdl.hxx>
35
#include <svx/svdmodel.hxx>
36
#include <svx/svdpage.hxx>
37
#include <svx/svdograf.hxx>
38
#include <svx/svdogrp.hxx>
39
#include <svx/xbtmpit.hxx>
40
#include <svx/xfillit0.hxx>
41
#include <svx/xflbmtit.hxx>
42
#include "svdfmtf.hxx"
43
#include <sdgcoitm.hxx>
44
#include <svx/sdgcpitm.hxx>
45
#include <svx/sdggaitm.hxx>
46
#include <sdginitm.hxx>
47
#include <svx/sdgluitm.hxx>
48
#include <svx/sdgmoitm.hxx>
49
#include <sdgtritm.hxx>
50
#include <sdr/properties/graphicproperties.hxx>
51
#include <sdr/contact/viewcontactofgraphic.hxx>
52
#include <basegfx/matrix/b2dhommatrixtools.hxx>
53
#include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
54
#include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
55
#include <memory>
56
57
using namespace ::com::sun::star;
58
59
class SdrGraphicLink : public sfx2::SvBaseLink
60
{
61
    SdrGrafObj&         rGrafObj;
62
63
public:
64
    explicit            SdrGraphicLink(SdrGrafObj& rObj);
65
66
    virtual void        Closed() override;
67
68
    virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
69
        const OUString& rMimeType, const uno::Any & rValue ) override;
70
71
307
    void                Connect() { GetRealObject(); }
72
};
73
74
SdrGraphicLink::SdrGraphicLink(SdrGrafObj& rObj)
75
307
: ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB )
76
307
, rGrafObj( rObj )
77
307
{
78
307
    SetSynchron( false );
79
307
}
80
81
::sfx2::SvBaseLink::UpdateResult SdrGraphicLink::DataChanged(
82
    const OUString& rMimeType, const uno::Any & rValue )
83
307
{
84
307
    SdrModel& rModel(rGrafObj.getSdrModelFromSdrObject());
85
307
    sfx2::LinkManager* pLinkManager(rModel.GetLinkManager());
86
87
307
    if( pLinkManager && rValue.hasValue() )
88
307
    {
89
307
        sfx2::LinkManager::GetDisplayNames( this, nullptr, &rGrafObj.m_aFileName, nullptr, &rGrafObj.m_aFilterName );
90
91
307
        Graphic aGraphic;
92
307
        if (pLinkManager->GetGraphicFromAny(rMimeType, rValue, aGraphic, nullptr))
93
307
        {
94
307
            rGrafObj.ImpSetLinkedGraphic(aGraphic);
95
307
        }
96
0
        else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
97
0
        {
98
            // broadcasting, to update slide sorter
99
0
            rGrafObj.BroadcastObjectChange();
100
0
        }
101
307
    }
102
307
    return SUCCESS;
103
307
}
104
105
void SdrGraphicLink::Closed()
106
0
{
107
    // close connection; set pLink of the object to NULL, as link instance is just about getting destructed.
108
0
    rGrafObj.ForceSwapIn();
109
0
    rGrafObj.m_pGraphicLink=nullptr;
110
0
    rGrafObj.ReleaseGraphicLink();
111
0
    SvBaseLink::Closed();
112
0
}
113
114
std::unique_ptr<sdr::properties::BaseProperties> SdrGrafObj::CreateObjectSpecificProperties()
115
27.3k
{
116
27.3k
    return std::make_unique<sdr::properties::GraphicProperties>(*this);
117
27.3k
}
118
119
120
// DrawContact section
121
122
std::unique_ptr<sdr::contact::ViewContact> SdrGrafObj::CreateObjectSpecificViewContact()
123
27.7k
{
124
27.7k
    return std::make_unique<sdr::contact::ViewContactOfGraphic>(*this);
125
27.7k
}
126
127
128
// check if SVG and if try to get ObjectInfoPrimitive2D and extract info
129
130
void SdrGrafObj::onGraphicChanged()
131
47.1k
{
132
47.1k
    if (!mpGraphicObject || !mpGraphicObject->GetGraphic().isAvailable())
133
5.32k
        return;
134
135
41.8k
    auto const & rVectorGraphicDataPtr = mpGraphicObject->GetGraphic().getVectorGraphicData();
136
137
41.8k
    if (!rVectorGraphicDataPtr)
138
39.5k
        return;
139
140
    // Skip for PDF as it is only a bitmap primitive in a sequence and
141
    // doesn't contain metadata. However getting the primitive sequence
142
    // will also trigger a premature rendering of the PDF.
143
2.24k
    if (rVectorGraphicDataPtr->getType() == VectorGraphicDataType::Pdf)
144
0
        return;
145
146
2.24k
    const std::deque<uno::Reference<graphic::XPrimitive2D>>& rContainer(rVectorGraphicDataPtr->getPrimitive2DSequence());
147
148
2.24k
    if (rContainer.empty())
149
1.24k
        return;
150
151
994
    drawinglayer::geometry::ViewInformation2D aViewInformation2D;
152
994
    drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
153
154
994
    aProcessor.process(rContainer);
155
156
994
    const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
157
158
994
    if (!pResult)
159
994
        return;
160
161
0
    OUString aName = pResult->getName();
162
0
    OUString aTitle = pResult->getTitle();
163
0
    OUString aDesc = pResult->getDesc();
164
165
0
    if(!aName.isEmpty())
166
0
    {
167
0
        SetName(aName);
168
0
    }
169
170
0
    if(!aTitle.isEmpty())
171
0
    {
172
0
        SetTitle(aTitle);
173
0
    }
174
175
0
    if(!aDesc.isEmpty())
176
0
    {
177
0
        SetDescription(aDesc);
178
0
    }
179
0
}
180
181
SdrGrafObj::SdrGrafObj(SdrModel& rSdrModel)
182
27.3k
:   SdrRectObj(rSdrModel)
183
27.3k
    ,mpGraphicObject(new GraphicObject)
184
27.3k
    ,m_pGraphicLink(nullptr)
185
27.3k
    ,m_bMirrored(false)
186
27.3k
    ,mbIsSignatureLine(false)
187
27.3k
    ,mbIsSignatureLineShowSignDate(true)
188
27.3k
    ,mbIsSignatureLineCanAddComment(false)
189
27.3k
    ,mbSignatureLineIsSigned(false)
190
27.3k
{
191
27.3k
    onGraphicChanged();
192
193
    // #i118485# Shear allowed and possible now
194
27.3k
    mbNoShear = false;
195
196
27.3k
    mbGrafAnimationAllowed = true;
197
198
    // #i25616#
199
27.3k
    mbLineIsOutsideGeometry = true;
200
201
    // #i25616#
202
27.3k
    mbSupportTextIndentingOnLineWidthChange = false;
203
27.3k
}
204
205
SdrGrafObj::SdrGrafObj(SdrModel& rSdrModel, SdrGrafObj const & rSource)
206
422
:   SdrRectObj(rSdrModel, rSource)
207
422
    ,mpGraphicObject(new GraphicObject)
208
422
    ,m_pGraphicLink(nullptr)
209
422
{
210
422
    onGraphicChanged();
211
212
    // #i118485# Shear allowed and possible now
213
422
    mbNoShear = false;
214
215
422
    mbGrafAnimationAllowed = true;
216
217
    // #i25616#
218
422
    mbLineIsOutsideGeometry = true;
219
220
    // #i25616#
221
422
    mbSupportTextIndentingOnLineWidthChange = false;
222
223
422
    m_aFileName = rSource.m_aFileName;
224
422
    m_bMirrored = rSource.m_bMirrored;
225
226
422
    mbIsSignatureLine = rSource.mbIsSignatureLine;
227
422
    maSignatureLineId = rSource.maSignatureLineId;
228
422
    maSignatureLineSuggestedSignerName = rSource.maSignatureLineSuggestedSignerName;
229
422
    maSignatureLineSuggestedSignerTitle = rSource.maSignatureLineSuggestedSignerTitle;
230
422
    maSignatureLineSuggestedSignerEmail = rSource.maSignatureLineSuggestedSignerEmail;
231
422
    maSignatureLineSigningInstructions = rSource.maSignatureLineSigningInstructions;
232
422
    mbIsSignatureLineShowSignDate = rSource.mbIsSignatureLineShowSignDate;
233
422
    mbIsSignatureLineCanAddComment = rSource.mbIsSignatureLineCanAddComment;
234
422
    mbSignatureLineIsSigned = false;
235
422
    mpSignatureLineUnsignedGraphic = rSource.mpSignatureLineUnsignedGraphic;
236
237
422
    if(rSource.mpBarCode)
238
0
    {
239
0
        mpBarCode = std::make_unique<drawing::BarCode>(*rSource.mpBarCode);
240
0
    }
241
422
    else
242
422
    {
243
422
        mpBarCode.reset();
244
422
    }
245
246
422
    if (mbIsSignatureLine && rSource.mpSignatureLineUnsignedGraphic)
247
0
        mpGraphicObject->SetGraphic(rSource.mpSignatureLineUnsignedGraphic);
248
422
    else
249
422
        mpGraphicObject->SetGraphic( rSource.GetGraphic() );
250
251
422
    if( rSource.IsLinkedGraphic() )
252
0
    {
253
0
        SetGraphicLink( m_aFileName );
254
0
    }
255
422
}
256
257
SdrGrafObj::SdrGrafObj(
258
    SdrModel& rSdrModel,
259
    const Graphic& rGraphic,
260
    const tools::Rectangle& rRect)
261
0
:   SdrRectObj(rSdrModel, rRect)
262
0
    ,mpGraphicObject(new GraphicObject(rGraphic))
263
0
    ,m_pGraphicLink(nullptr)
264
0
    ,m_bMirrored(false)
265
0
    ,mbIsSignatureLine(false)
266
0
    ,mbIsSignatureLineShowSignDate(true)
267
0
    ,mbIsSignatureLineCanAddComment(false)
268
0
    ,mbSignatureLineIsSigned(false)
269
0
{
270
0
    onGraphicChanged();
271
272
    // #i118485# Shear allowed and possible now
273
0
    mbNoShear = false;
274
275
0
    mbGrafAnimationAllowed = true;
276
277
    // #i25616#
278
0
    mbLineIsOutsideGeometry = true;
279
280
    // #i25616#
281
0
    mbSupportTextIndentingOnLineWidthChange = false;
282
0
}
283
284
SdrGrafObj::SdrGrafObj(
285
    SdrModel& rSdrModel,
286
    const Graphic& rGraphic)
287
0
:   SdrRectObj(rSdrModel)
288
0
    ,mpGraphicObject(new GraphicObject(rGraphic))
289
0
    ,m_pGraphicLink(nullptr)
290
0
    ,m_bMirrored(false)
291
0
    ,mbIsSignatureLine(false)
292
0
    ,mbIsSignatureLineShowSignDate(true)
293
0
    ,mbIsSignatureLineCanAddComment(false)
294
0
    ,mbSignatureLineIsSigned(false)
295
0
{
296
0
    onGraphicChanged();
297
298
    // #i118485# Shear allowed and possible now
299
0
    mbNoShear = false;
300
301
0
    mbGrafAnimationAllowed = true;
302
303
    // #i25616#
304
0
    mbLineIsOutsideGeometry = true;
305
306
    // #i25616#
307
0
    mbSupportTextIndentingOnLineWidthChange = false;
308
0
}
309
310
SdrGrafObj::~SdrGrafObj()
311
27.7k
{
312
27.7k
    ImpDeregisterLink();
313
27.7k
}
314
315
void SdrGrafObj::SetGraphicObject(const GraphicObject& rGraphicObject)
316
0
{
317
0
    mpGraphicObject.reset(new GraphicObject(rGraphicObject));
318
0
    mpReplacementGraphicObject.reset();
319
0
    mpGraphicObject->SetUserData();
320
0
    SetChanged();
321
0
    BroadcastObjectChange();
322
0
    onGraphicChanged();
323
0
}
324
325
const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
326
1.16k
{
327
1.16k
    if (bForceSwapIn)
328
0
        ForceSwapIn();
329
1.16k
    return *mpGraphicObject;
330
1.16k
}
331
332
const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
333
0
{
334
0
    if (!mpReplacementGraphicObject && mpGraphicObject)
335
0
    {
336
0
        auto const & rVectorGraphicDataPtr = mpGraphicObject->GetGraphic().getVectorGraphicData();
337
338
0
        if (rVectorGraphicDataPtr)
339
0
        {
340
0
            const_cast< SdrGrafObj* >(this)->mpReplacementGraphicObject.reset(new GraphicObject(rVectorGraphicDataPtr->getReplacement()));
341
0
        }
342
0
        else if (mpGraphicObject->GetGraphic().GetType() == GraphicType::GdiMetafile)
343
0
        {
344
            // Replacement graphic for PDF and metafiles is just the bitmap.
345
0
            const_cast<SdrGrafObj*>(this)->mpReplacementGraphicObject.reset(new GraphicObject(mpGraphicObject->GetGraphic().GetBitmapEx()));
346
0
        }
347
0
    }
348
349
0
    return mpReplacementGraphicObject.get();
350
0
}
351
352
void SdrGrafObj::NbcSetGraphic(const Graphic& rGraphic)
353
19.4k
{
354
19.4k
    mpGraphicObject->SetGraphic(rGraphic);
355
19.4k
    mpReplacementGraphicObject.reset();
356
19.4k
    mpGraphicObject->SetUserData();
357
19.4k
    onGraphicChanged();
358
19.4k
}
359
360
void SdrGrafObj::SetGraphic( const Graphic& rGraphic )
361
19.1k
{
362
19.1k
    if (!rGraphic.getOriginURL().isEmpty())
363
307
    {
364
307
        ImpDeregisterLink();
365
307
        m_aFileName = rGraphic.getOriginURL();
366
307
        m_aFilterName = "";
367
307
    }
368
19.1k
    NbcSetGraphic(rGraphic);
369
19.1k
    if (!rGraphic.getOriginURL().isEmpty())
370
307
    {
371
307
        ImpRegisterLink();
372
307
        mpGraphicObject->SetUserData();
373
307
    }
374
19.1k
    SetChanged();
375
19.1k
    BroadcastObjectChange();
376
19.1k
    ForceSwapIn();
377
19.1k
}
378
379
const Graphic& SdrGrafObj::GetGraphic() const
380
1.61k
{
381
1.61k
    return mpGraphicObject->GetGraphic();
382
1.61k
}
383
384
Graphic SdrGrafObj::GetTransformedGraphic( SdrGrafObjTransformsAttrs nTransformFlags ) const
385
0
{
386
    // Refactored most of the code to GraphicObject, where
387
    // everybody can use e.g. the cropping functionality
388
0
    MapMode aDestMap(getSdrModelFromSdrObject().GetScaleUnit());
389
0
    const Size aDestSize( GetLogicRect().GetSize() );
390
0
    GraphicAttr aActAttr = GetGraphicAttr(nTransformFlags);
391
392
    // Delegate to moved code in GraphicObject
393
0
    return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
394
0
}
395
396
GraphicType SdrGrafObj::GetGraphicType() const
397
0
{
398
0
    return mpGraphicObject->GetType();
399
0
}
400
401
GraphicAttr SdrGrafObj::GetGraphicAttr( SdrGrafObjTransformsAttrs nTransformFlags ) const
402
0
{
403
0
    GraphicAttr aActAttr;
404
405
0
    GraphicType eType = GetGraphicType();
406
0
    if( SdrGrafObjTransformsAttrs::NONE != nTransformFlags &&
407
0
        GraphicType::NONE != eType )
408
0
    {
409
0
        const bool      bMirror = bool( nTransformFlags & SdrGrafObjTransformsAttrs::MIRROR );
410
0
        const bool      bRotate = bool( nTransformFlags & SdrGrafObjTransformsAttrs::ROTATE ) &&
411
0
            (maGeo.m_nRotationAngle && maGeo.m_nRotationAngle != 18000_deg100);
412
413
        // Actually transform the graphic only in this case.
414
        // Cropping always happens, though.
415
0
        const SfxItemSet& rSet = GetObjectItemSet();
416
0
        const sal_uInt16 nTrans = rSet.Get( SDRATTR_GRAFTRANSPARENCE ).GetValue();
417
0
        const SdrGrafCropItem&  rCrop = rSet.Get( SDRATTR_GRAFCROP );
418
419
0
        aActAttr.SetLuminance( rSet.Get( SDRATTR_GRAFLUMINANCE ).GetValue() );
420
0
        aActAttr.SetContrast( rSet.Get( SDRATTR_GRAFCONTRAST ).GetValue() );
421
0
        aActAttr.SetChannelR( rSet.Get( SDRATTR_GRAFRED ).GetValue() );
422
0
        aActAttr.SetChannelG( rSet.Get( SDRATTR_GRAFGREEN ).GetValue() );
423
0
        aActAttr.SetChannelB( rSet.Get( SDRATTR_GRAFBLUE ).GetValue() );
424
0
        aActAttr.SetGamma( rSet.Get( SDRATTR_GRAFGAMMA ).GetValue() * 0.01 );
425
0
        aActAttr.SetAlpha(255 - basegfx::fround<sal_uInt8>(nTrans * 2.55));
426
0
        aActAttr.SetInvert( rSet.Get( SDRATTR_GRAFINVERT ).GetValue() );
427
0
        aActAttr.SetDrawMode( rSet.Get( SDRATTR_GRAFMODE ).GetValue() );
428
0
        aActAttr.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
429
430
0
        if( bMirror )
431
0
        {
432
0
            sal_uInt16      nMirrorCase = ( maGeo.m_nRotationAngle == 18000_deg100 ) ? ( m_bMirrored ? 3 : 4 ) : ( m_bMirrored ? 2 : 1 );
433
0
            bool bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
434
0
            bool bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
435
436
0
            aActAttr.SetMirrorFlags( ( bHMirr ? BmpMirrorFlags::Horizontal : BmpMirrorFlags::NONE ) | ( bVMirr ? BmpMirrorFlags::Vertical : BmpMirrorFlags::NONE ) );
437
0
        }
438
439
0
        if( bRotate )
440
0
            aActAttr.SetRotation( to<Degree10>(maGeo.m_nRotationAngle ) );
441
0
    }
442
443
0
    return aActAttr;
444
0
}
445
446
bool SdrGrafObj::IsAnimated() const
447
0
{
448
0
    return mpGraphicObject->IsAnimated();
449
0
}
450
451
bool SdrGrafObj::IsEPS() const
452
0
{
453
0
    return mpGraphicObject->IsEPS();
454
0
}
455
456
MapMode SdrGrafObj::GetGrafPrefMapMode() const
457
0
{
458
0
    return mpGraphicObject->GetPrefMapMode();
459
0
}
460
461
Size SdrGrafObj::GetGrafPrefSize() const
462
0
{
463
0
    return mpGraphicObject->GetPrefSize();
464
0
}
465
466
void SdrGrafObj::SetGrafStreamURL( const OUString& rGraphicStreamURL )
467
0
{
468
0
    if( rGraphicStreamURL.isEmpty() )
469
0
    {
470
0
        mpGraphicObject->SetUserData();
471
0
    }
472
0
    else if(getSdrModelFromSdrObject().IsSwapGraphics() )
473
0
    {
474
0
        mpGraphicObject->SetUserData( rGraphicStreamURL );
475
0
    }
476
0
}
477
478
OUString const & SdrGrafObj::GetGrafStreamURL() const
479
0
{
480
0
    return mpGraphicObject->GetUserData();
481
0
}
482
483
Size SdrGrafObj::getOriginalSize() const
484
0
{
485
0
    Size aSize = GetGrafPrefSize();
486
487
0
    if (GetGrafPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
488
0
        aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapMode(getSdrModelFromSdrObject().GetScaleUnit()));
489
0
    else
490
0
        aSize = OutputDevice::LogicToLogic(aSize, GetGrafPrefMapMode(), MapMode(getSdrModelFromSdrObject().GetScaleUnit()));
491
492
0
    const SfxItemSet& rSet = GetObjectItemSet();
493
0
    const SdrGrafCropItem&  rCrop = rSet.Get( SDRATTR_GRAFCROP );
494
0
    if ( rCrop.GetLeft() != 0 || rCrop.GetTop() != 0 || rCrop.GetRight() != 0 || rCrop.GetBottom() != 0 ) // if is cropped
495
0
    {
496
0
        const tools::Long aCroppedWidth(aSize.getWidth() - rCrop.GetLeft()
497
0
                                        - rCrop.GetRight());
498
0
        const tools::Long aCroppedHeight(aSize.getHeight() - rCrop.GetTop()
499
0
                                         - rCrop.GetBottom());
500
501
0
        aSize = Size(aCroppedWidth, aCroppedHeight);
502
0
    }
503
504
0
    return aSize;
505
0
}
506
507
// TODO Remove
508
void SdrGrafObj::ForceSwapIn() const
509
19.1k
{
510
19.1k
    if (m_pGraphicLink && (mpGraphicObject->GetType() == GraphicType::NONE  ||
511
307
                         mpGraphicObject->GetType() == GraphicType::Default) )
512
307
    {
513
307
        m_pGraphicLink->Update();
514
307
    }
515
19.1k
}
516
517
void SdrGrafObj::ImpRegisterLink()
518
511
{
519
511
    sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
520
521
511
    if( pLinkManager != nullptr && m_pGraphicLink == nullptr )
522
307
    {
523
307
        if (!m_aFileName.isEmpty())
524
307
        {
525
307
            m_pGraphicLink = new SdrGraphicLink( *this );
526
307
            pLinkManager->InsertFileLink(
527
307
                *m_pGraphicLink, sfx2::SvBaseLinkObjectType::ClientGraphic, m_aFileName, (m_aFilterName.isEmpty() ? nullptr : &m_aFilterName));
528
307
            m_pGraphicLink->Connect();
529
307
        }
530
307
    }
531
511
}
532
533
void SdrGrafObj::ImpDeregisterLink()
534
28.1k
{
535
28.1k
    sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
536
537
28.1k
    if( pLinkManager != nullptr && m_pGraphicLink!=nullptr)
538
307
    {
539
        // When using Remove, the *pGraphicLink is implicitly deleted
540
307
        pLinkManager->Remove( m_pGraphicLink );
541
307
        m_pGraphicLink=nullptr;
542
307
    }
543
28.1k
}
544
545
void SdrGrafObj::SetGraphicLink(const OUString& rFileName)
546
208
{
547
208
    Graphic aGraphic;
548
208
    aGraphic.setOriginURL(rFileName);
549
208
    SetGraphic(aGraphic);
550
208
}
551
552
void SdrGrafObj::ReleaseGraphicLink()
553
0
{
554
0
    ImpDeregisterLink();
555
0
    m_aFileName.clear();
556
0
    m_aFilterName.clear();
557
558
0
    auto aGraphic = mpGraphicObject->GetGraphic();
559
0
    aGraphic.setOriginURL(u""_ustr);
560
0
    SetGraphic(aGraphic);
561
0
}
562
563
bool SdrGrafObj::IsLinkedGraphic() const
564
427
{
565
427
    return !mpGraphicObject->GetGraphic().getOriginURL().isEmpty();
566
427
}
567
568
void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
569
0
{
570
0
    bool bNoPresGrf = ( mpGraphicObject->GetType() != GraphicType::NONE ) && !m_bEmptyPresObj;
571
572
0
    rInfo.bResizeFreeAllowed = maGeo.m_nRotationAngle.get() % 9000 == 0 ||
573
0
                               maGeo.m_nRotationAngle.get() % 18000 == 0 ||
574
0
                               maGeo.m_nRotationAngle.get() % 27000 == 0;
575
576
0
    rInfo.bResizePropAllowed = true;
577
0
    rInfo.bRotateFreeAllowed = bNoPresGrf;
578
0
    rInfo.bRotate90Allowed = bNoPresGrf;
579
0
    rInfo.bMirrorFreeAllowed = bNoPresGrf;
580
0
    rInfo.bMirror45Allowed = bNoPresGrf;
581
0
    rInfo.bMirror90Allowed = !m_bEmptyPresObj;
582
0
    rInfo.bTransparenceAllowed = false;
583
584
    // #i118485# Shear allowed and possible now
585
0
    rInfo.bShearAllowed = true;
586
587
0
    rInfo.bEdgeRadiusAllowed=false;
588
0
    rInfo.bCanConvToPath = !IsEPS();
589
0
    rInfo.bCanConvToPathLineToArea = false;
590
0
    rInfo.bCanConvToPolyLineToArea = false;
591
0
    rInfo.bCanConvToPoly = !IsEPS();
592
0
    rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
593
0
}
594
595
SdrObjKind SdrGrafObj::GetObjIdentifier() const
596
199k
{
597
199k
    return SdrObjKind::Graphic;
598
199k
}
599
600
void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
601
307
{
602
307
    const bool bIsChanged(getSdrModelFromSdrObject().IsChanged());
603
307
    NbcSetGraphic( rGraphic );
604
307
    ActionChanged();
605
307
    BroadcastObjectChange();
606
307
    getSdrModelFromSdrObject().SetChanged(bIsChanged);
607
307
}
608
609
OUString SdrGrafObj::TakeObjNameSingul() const
610
0
{
611
0
    if (!mpGraphicObject)
612
0
        return OUString();
613
614
0
    auto const & rVectorGraphicDataPtr = mpGraphicObject->GetGraphic().getVectorGraphicData();
615
616
0
    OUStringBuffer sName;
617
618
0
    if (rVectorGraphicDataPtr)
619
0
    {
620
0
        switch (rVectorGraphicDataPtr->getType())
621
0
        {
622
0
        case VectorGraphicDataType::Svg:
623
0
        {
624
0
            sName.append(SvxResId(STR_ObjNameSingulGRAFSVG));
625
0
            break;
626
0
        }
627
0
        case VectorGraphicDataType::Wmf:
628
0
        {
629
0
            sName.append(SvxResId(STR_ObjNameSingulGRAFWMF));
630
0
            break;
631
0
        }
632
0
        case VectorGraphicDataType::Emf:
633
0
        {
634
0
            sName.append(SvxResId(STR_ObjNameSingulGRAFEMF));
635
0
            break;
636
0
        }
637
0
        case VectorGraphicDataType::Pdf:
638
0
        {
639
0
            sName.append(SvxResId(STR_ObjNameSingulGRAFPDF));
640
0
            break;
641
0
        }
642
0
        } //no default, see tdf#137813
643
0
    }
644
0
    else
645
0
    {
646
0
        switch( mpGraphicObject->GetType() )
647
0
        {
648
0
            case GraphicType::Bitmap:
649
0
            {
650
0
                TranslateId pId = ( ( mpGraphicObject->IsTransparent() || GetObjectItem( SDRATTR_GRAFTRANSPARENCE ).GetValue() ) ?
651
0
                                     ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
652
0
                                     ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
653
654
0
                sName.append(SvxResId(pId));
655
0
            }
656
0
            break;
657
658
0
            case GraphicType::GdiMetafile:
659
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF));
660
0
            break;
661
662
0
            case GraphicType::NONE:
663
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE));
664
0
            break;
665
666
0
            default:
667
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF));
668
0
            break;
669
0
        }
670
0
    }
671
672
0
    const OUString aName(GetName());
673
674
0
    if (!aName.isEmpty())
675
0
    {
676
0
        sName.append(" '" + aName + "\'" );
677
0
    }
678
679
0
    return sName.makeStringAndClear();
680
0
}
681
682
OUString SdrGrafObj::TakeObjNamePlural() const
683
0
{
684
0
    if (!mpGraphicObject)
685
0
        return OUString();
686
687
0
    auto const & rVectorGraphicDataPtr = mpGraphicObject->GetGraphic().getVectorGraphicData();
688
689
0
    OUStringBuffer sName;
690
691
0
    if (rVectorGraphicDataPtr)
692
0
    {
693
0
        switch (rVectorGraphicDataPtr->getType())
694
0
        {
695
0
        case VectorGraphicDataType::Svg:
696
0
        {
697
0
            sName.append(SvxResId(STR_ObjNamePluralGRAFSVG));
698
0
            break;
699
0
        }
700
0
        case VectorGraphicDataType::Wmf:
701
0
        {
702
0
            sName.append(SvxResId(STR_ObjNamePluralGRAFWMF));
703
0
            break;
704
0
        }
705
0
        case VectorGraphicDataType::Emf:
706
0
        {
707
0
            sName.append(SvxResId(STR_ObjNamePluralGRAFEMF));
708
0
            break;
709
0
        }
710
0
        case VectorGraphicDataType::Pdf:
711
0
        {
712
0
            sName.append(SvxResId(STR_ObjNamePluralGRAFPDF));
713
0
            break;
714
0
        }
715
0
        } //no default, see tdf#137813
716
0
    }
717
0
    else
718
0
    {
719
0
        switch(mpGraphicObject->GetType())
720
0
        {
721
0
            case GraphicType::Bitmap:
722
0
            {
723
0
                TranslateId pId = ( ( mpGraphicObject->IsTransparent() || GetObjectItem( SDRATTR_GRAFTRANSPARENCE ).GetValue() ) ?
724
0
                                     ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
725
0
                                     ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
726
727
0
                sName.append(SvxResId(pId));
728
0
            }
729
0
            break;
730
731
0
            case GraphicType::GdiMetafile:
732
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF));
733
0
            break;
734
735
0
            case GraphicType::NONE:
736
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE));
737
0
            break;
738
739
0
            default:
740
0
                sName.append(SvxResId(IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF));
741
0
            break;
742
0
        }
743
0
    }
744
745
0
    const OUString aName(GetName());
746
747
0
    if (!aName.isEmpty())
748
0
    {
749
0
        sName.append(" '" + aName + "\'");
750
0
    }
751
752
0
    return sName.makeStringAndClear();
753
0
}
754
755
rtl::Reference<SdrObject> SdrGrafObj::getFullDragClone() const
756
0
{
757
    // call parent
758
0
    rtl::Reference<SdrObject> pRetval = SdrRectObj::getFullDragClone();
759
760
    // #i103116# the full drag clone leads to problems
761
    // with linked graphics, so reset the link in this
762
    // temporary interaction object and load graphic
763
0
    if(pRetval && IsLinkedGraphic())
764
0
    {
765
0
        static_cast< SdrGrafObj* >(pRetval.get())->ReleaseGraphicLink();
766
0
    }
767
768
0
    return pRetval;
769
0
}
770
771
rtl::Reference<SdrObject> SdrGrafObj::CloneSdrObject(SdrModel& rTargetModel) const
772
422
{
773
422
    return new SdrGrafObj(rTargetModel, *this);
774
422
}
775
776
sal_uInt32 SdrGrafObj::GetHdlCount() const
777
0
{
778
0
    return 8;
779
0
}
780
781
void SdrGrafObj::AddToHdlList(SdrHdlList& rHdlList) const
782
0
{
783
0
    SdrHdlList tempList(nullptr);
784
0
    SdrRectObj::AddToHdlList( tempList );
785
0
    tempList.RemoveHdl(0);
786
0
    tempList.MoveTo(rHdlList);
787
0
}
788
789
void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
790
1.32k
{
791
1.32k
    SdrRectObj::NbcResize( rRef, xFact, yFact );
792
793
1.32k
    bool bMirrX = xFact.GetNumerator() < 0;
794
1.32k
    bool bMirrY = yFact.GetNumerator() < 0;
795
796
1.32k
    if( bMirrX != bMirrY )
797
181
        m_bMirrored = !m_bMirrored;
798
1.32k
}
799
800
void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
801
3.02k
{
802
3.02k
    SdrRectObj::NbcMirror(rRef1,rRef2);
803
3.02k
    m_bMirrored = !m_bMirrored;
804
3.02k
}
805
806
std::unique_ptr<SdrObjGeoData> SdrGrafObj::NewGeoData() const
807
0
{
808
0
    return std::make_unique<SdrGrafObjGeoData>();
809
0
}
810
811
void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
812
0
{
813
0
    SdrRectObj::SaveGeoData(rGeo);
814
0
    SdrGrafObjGeoData& rGGeo=static_cast<SdrGrafObjGeoData&>(rGeo);
815
0
    rGGeo.bMirrored=m_bMirrored;
816
0
}
817
818
void SdrGrafObj::RestoreGeoData(const SdrObjGeoData& rGeo)
819
0
{
820
0
    SdrRectObj::RestoreGeoData(rGeo);
821
0
    const SdrGrafObjGeoData& rGGeo=static_cast<const SdrGrafObjGeoData&>(rGeo);
822
0
    m_bMirrored=rGGeo.bMirrored;
823
0
}
824
825
void SdrGrafObj::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage)
826
29.3k
{
827
29.3k
    const bool bRemove(pNewPage == nullptr && pOldPage != nullptr);
828
29.3k
    const bool bInsert(pNewPage != nullptr && pOldPage == nullptr);
829
830
29.3k
    if( bRemove )
831
1.79k
    {
832
        // No SwapIn necessary here, because if something's not loaded, it can't be animated either.
833
1.79k
        if( mpGraphicObject->IsAnimated())
834
0
            mpGraphicObject->StopAnimation();
835
836
1.79k
        if( m_pGraphicLink != nullptr )
837
99
            ImpDeregisterLink();
838
1.79k
    }
839
840
    // call parent
841
29.3k
    SdrRectObj::handlePageChange(pOldPage, pNewPage);
842
843
29.3k
    if (!m_aFileName.isEmpty() && bInsert)
844
204
    {
845
204
        ImpRegisterLink();
846
204
    }
847
29.3k
}
848
849
void SdrGrafObj::StartAnimation()
850
0
{
851
0
    SetGrafAnimationAllowed(true);
852
0
}
853
854
bool SdrGrafObj::HasGDIMetaFile() const
855
7
{
856
7
    return( mpGraphicObject->GetType() == GraphicType::GdiMetafile );
857
7
}
858
859
bool SdrGrafObj::isEmbeddedVectorGraphicData() const
860
0
{
861
0
    return GraphicType::Bitmap == GetGraphicType() && GetGraphic().getVectorGraphicData();
862
0
}
863
864
GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedVectorGraphicData() const
865
0
{
866
0
    GDIMetaFile aRetval;
867
868
0
    if(isEmbeddedVectorGraphicData())
869
0
    {
870
0
        ScopedVclPtrInstance< VirtualDevice > pOut;
871
0
        const tools::Rectangle aBoundRect(GetCurrentBoundRect());
872
0
        const MapMode aMap(getSdrModelFromSdrObject().GetScaleUnit());
873
874
0
        pOut->EnableOutput(false);
875
0
        pOut->SetMapMode(aMap);
876
0
        aRetval.Record(pOut);
877
0
        SingleObjectPainter(*pOut);
878
0
        aRetval.Stop();
879
0
        aRetval.WindStart();
880
0
        aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
881
0
        aRetval.SetPrefMapMode(aMap);
882
0
        aRetval.SetPrefSize(aBoundRect.GetSize());
883
0
    }
884
885
0
    return aRetval;
886
0
}
887
888
GDIMetaFile SdrGrafObj::GetMetaFile(GraphicType &rGraphicType) const
889
0
{
890
0
    if (isEmbeddedVectorGraphicData())
891
0
    {
892
        // Embedded Vector Graphic Data
893
        // There is currently no helper to create SdrObjects from primitives (even if I'm thinking
894
        // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to
895
        // use the old converter path over the MetaFile mechanism. Create Metafile from Svg
896
        // primitives here pretty directly
897
0
        rGraphicType = GraphicType::GdiMetafile;
898
0
        return getMetafileFromEmbeddedVectorGraphicData();
899
0
    }
900
0
    else if (GraphicType::GdiMetafile == rGraphicType)
901
0
    {
902
0
        return GetTransformedGraphic(SdrGrafObjTransformsAttrs::MIRROR).GetGDIMetaFile();
903
0
    }
904
0
    return GDIMetaFile();
905
0
}
906
907
rtl::Reference<SdrObject> SdrGrafObj::DoConvertToPolyObj(bool bBezier, bool bAddText ) const
908
0
{
909
0
    rtl::Reference<SdrObject> pRetval;
910
0
    GraphicType aGraphicType(GetGraphicType());
911
0
    GDIMetaFile aMtf(GetMetaFile(aGraphicType));
912
0
    switch(aGraphicType)
913
0
    {
914
0
        case GraphicType::GdiMetafile:
915
0
        {
916
            // Sort into group and return ONLY those objects that can be created from the MetaFile.
917
0
            ImpSdrGDIMetaFileImport aFilter(
918
0
                getSdrModelFromSdrObject(),
919
0
                GetLayer(),
920
0
                getRectangle());
921
0
            rtl::Reference<SdrObjGroup> pGrp = new SdrObjGroup(getSdrModelFromSdrObject());
922
923
0
            if(aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0))
924
0
            {
925
0
                {
926
                        // copy transformation
927
0
                    GeoStat aGeoStat(GetGeoStat());
928
929
0
                    if(aGeoStat.m_nShearAngle)
930
0
                    {
931
0
                        aGeoStat.RecalcTan();
932
0
                        pGrp->NbcShear(getRectangle().TopLeft(), aGeoStat.m_nShearAngle, aGeoStat.mfTanShearAngle, false);
933
0
                    }
934
935
0
                    if(aGeoStat.m_nRotationAngle)
936
0
                    {
937
0
                        aGeoStat.RecalcSinCos();
938
0
                        pGrp->NbcRotate(getRectangle().TopLeft(), aGeoStat.m_nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle);
939
0
                    }
940
0
                }
941
942
0
                pRetval = pGrp;
943
0
                pGrp->NbcSetLayer(GetLayer());
944
945
0
                if(bAddText)
946
0
                {
947
0
                    pRetval = ImpConvertAddText(pRetval, bBezier);
948
0
                }
949
950
                // convert all children
951
0
                if( pRetval )
952
0
                {
953
0
                    pRetval = pRetval->DoConvertToPolyObj(bBezier, bAddText);
954
955
0
                    if( pRetval )
956
0
                    {
957
                        // flatten subgroups. As we call
958
                        // DoConvertToPolyObj() on the resulting group
959
                        // objects, subgroups can exist (e.g. text is
960
                        // a group object for every line).
961
0
                        SdrObjList* pList = pRetval->GetSubList();
962
0
                        if( pList )
963
0
                            pList->FlattenGroups();
964
0
                    }
965
0
                }
966
0
            }
967
0
            else
968
0
                pGrp.clear();
969
970
            // #i118485# convert line and fill
971
0
            rtl::Reference<SdrObject> pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
972
973
0
            if(pLineFill)
974
0
            {
975
0
                if(pRetval)
976
0
                {
977
0
                    pGrp = dynamic_cast< SdrObjGroup* >(pRetval.get());
978
979
0
                    if(!pGrp)
980
0
                    {
981
0
                        pGrp = new SdrObjGroup(getSdrModelFromSdrObject());
982
0
                        pGrp->NbcSetLayer(GetLayer());
983
0
                        pGrp->GetSubList()->NbcInsertObject(pRetval.get());
984
0
                    }
985
986
0
                    pGrp->GetSubList()->NbcInsertObject(pLineFill.get(), 0);
987
0
                }
988
0
                else
989
0
                {
990
0
                    pRetval = std::move(pLineFill);
991
0
                }
992
0
            }
993
994
0
            break;
995
0
        }
996
0
        case GraphicType::Bitmap:
997
0
        {
998
            // create basic object and add fill
999
0
            pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1000
1001
            // save bitmap as an attribute
1002
0
            if(pRetval)
1003
0
            {
1004
                // retrieve bitmap for the fill
1005
0
                SfxItemSet aSet(GetObjectItemSet());
1006
1007
0
                aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1008
0
                const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx());
1009
0
                aSet.Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
1010
0
                aSet.Put(XFillBmpTileItem(false));
1011
1012
0
                pRetval->SetMergedItemSet(aSet);
1013
0
            }
1014
0
            break;
1015
0
        }
1016
0
        case GraphicType::NONE:
1017
0
        case GraphicType::Default:
1018
0
        {
1019
0
            pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1020
0
            break;
1021
0
        }
1022
0
    }
1023
1024
0
    return pRetval;
1025
0
}
1026
1027
void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1028
140k
{
1029
140k
    SetXPolyDirty();
1030
140k
    SdrRectObj::Notify( rBC, rHint );
1031
140k
}
1032
1033
1034
void SdrGrafObj::SetMirrored( bool _bMirrored )
1035
25
{
1036
25
    m_bMirrored = _bMirrored;
1037
25
}
1038
1039
void SdrGrafObj::AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrinkOnly )
1040
0
{
1041
0
    Size aSize;
1042
0
    Size aMaxSize( rMaxRect.GetSize() );
1043
0
    if (mpGraphicObject->GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
1044
0
        aSize = Application::GetDefaultDevice()->PixelToLogic(mpGraphicObject->GetPrefSize(), MapMode(MapUnit::Map100thMM));
1045
0
    else
1046
0
        aSize = OutputDevice::LogicToLogic( mpGraphicObject->GetPrefSize(),
1047
0
                                            mpGraphicObject->GetPrefMapMode(),
1048
0
                                            MapMode( MapUnit::Map100thMM ) );
1049
1050
0
    if( aSize.IsEmpty() )
1051
0
        return;
1052
1053
0
    Point aPos( rMaxRect.TopLeft() );
1054
1055
    // if the graphic is too large, fit it to page
1056
0
    if ( (!bShrinkOnly                          ||
1057
0
         ( aSize.Height() > aMaxSize.Height() ) ||
1058
0
         ( aSize.Width()  > aMaxSize.Width()  ) )&&
1059
0
         aSize.Height() && aMaxSize.Height() )
1060
0
    {
1061
0
        float fGrfWH =  static_cast<float>(aSize.Width()) /
1062
0
                        static_cast<float>(aSize.Height());
1063
0
        float fWinWH =  static_cast<float>(aMaxSize.Width()) /
1064
0
                        static_cast<float>(aMaxSize.Height());
1065
1066
        // Scale graphic to page size
1067
0
        if ( fGrfWH < fWinWH )
1068
0
        {
1069
0
            aSize.setWidth( static_cast<tools::Long>(aMaxSize.Height() * fGrfWH) );
1070
0
            aSize.setHeight( aMaxSize.Height() );
1071
0
        }
1072
0
        else if ( fGrfWH > 0.F )
1073
0
        {
1074
0
            aSize.setWidth( aMaxSize.Width() );
1075
0
            aSize.setHeight( static_cast<tools::Long>(aMaxSize.Width() / fGrfWH) );
1076
0
        }
1077
1078
0
        aPos = rMaxRect.Center();
1079
0
    }
1080
1081
0
    if( bShrinkOnly )
1082
0
        aPos = getRectangle().TopLeft();
1083
1084
0
    aPos.AdjustX( -(aSize.Width() / 2) );
1085
0
    aPos.AdjustY( -(aSize.Height() / 2) );
1086
0
    SetLogicRect( tools::Rectangle( aPos, aSize ) );
1087
0
}
1088
1089
void SdrGrafObj::SetGrafAnimationAllowed(bool bNew)
1090
0
{
1091
0
    if(mbGrafAnimationAllowed != bNew)
1092
0
    {
1093
0
        mbGrafAnimationAllowed = bNew;
1094
0
        ActionChanged();
1095
0
    }
1096
0
}
1097
1098
uno::Reference<io::XInputStream> SdrGrafObj::getInputStream() const
1099
0
{
1100
0
    uno::Reference<io::XInputStream> xStream;
1101
1102
0
    if (mpGraphicObject && GetGraphic().IsGfxLink())
1103
0
    {
1104
0
        Graphic aGraphic( GetGraphic() );
1105
0
        GfxLink aLink( aGraphic.GetGfxLink() );
1106
0
        sal_uInt32 nSize = aLink.GetDataSize();
1107
0
        const void* pSourceData = static_cast<const void*>(aLink.GetData());
1108
0
        if( nSize && pSourceData )
1109
0
        {
1110
0
            sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1111
0
            memcpy( pBuffer, pSourceData, nSize );
1112
1113
0
            SvMemoryStream* pStream = new SvMemoryStream( static_cast<void*>(pBuffer), static_cast<std::size_t>(nSize), StreamMode::READ );
1114
0
            pStream->ObjectOwnsMemory( true );
1115
0
            xStream.set( new utl::OInputStreamWrapper( pStream, true ) );
1116
0
        }
1117
0
    }
1118
1119
0
    if (!xStream.is() && !m_aFileName.isEmpty())
1120
0
    {
1121
0
        SvFileStream* pStream = new SvFileStream( m_aFileName, StreamMode::READ );
1122
0
        xStream.set( new utl::OInputStreamWrapper( pStream ) );
1123
0
    }
1124
1125
0
    return xStream;
1126
0
}
1127
1128
// moved crop handle creation here; this is the object type using them
1129
void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const
1130
0
{
1131
0
    basegfx::B2DHomMatrix aMatrix;
1132
0
    basegfx::B2DPolyPolygon aPolyPolygon;
1133
1134
    // get object transformation
1135
0
    TRGetBaseGeometry(aMatrix, aPolyPolygon);
1136
1137
    // part of object transformation correction, but used later, so defined outside next scope
1138
0
    double fShearX(0.0), fRotate(0.0);
1139
1140
0
    {   // TTTT correct shear, it comes currently mirrored from TRGetBaseGeometry, can be removed with aw080
1141
0
        basegfx::B2DTuple aScale;
1142
0
        basegfx::B2DTuple aTranslate;
1143
1144
0
        aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1145
1146
0
        aMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
1147
0
            aScale,
1148
0
            -fShearX,
1149
0
            fRotate,
1150
0
            aTranslate);
1151
0
    }
1152
1153
0
    basegfx::B2DPoint aPos;
1154
0
    aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0);
1155
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate));
1156
0
    aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0);
1157
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate));
1158
0
    aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0);
1159
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate));
1160
0
    aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5);
1161
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate));
1162
0
    aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5);
1163
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate));
1164
0
    aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0);
1165
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate));
1166
0
    aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0);
1167
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate));
1168
0
    aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0);
1169
0
    rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate));
1170
1171
    // get crop values
1172
0
    const SdrGrafCropItem& rCrop = GetMergedItem(SDRATTR_GRAFCROP);
1173
0
    if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom())
1174
0
    {
1175
        // decompose object transformation to have current translate and scale
1176
0
        basegfx::B2DVector aScale, aTranslate;
1177
0
        double fLclRotate, fLclShearX;
1178
1179
0
        aMatrix.decompose(aScale, aTranslate, fLclRotate, fLclShearX);
1180
1181
0
        if(!aScale.equalZero())
1182
0
        {
1183
            // get crop scale
1184
0
            const basegfx::B2DVector aCropScaleFactor(
1185
0
                GetGraphicObject().calculateCropScaling(
1186
0
                    aScale.getX(),
1187
0
                    aScale.getY(),
1188
0
                    rCrop.GetLeft(),
1189
0
                    rCrop.GetTop(),
1190
0
                    rCrop.GetRight(),
1191
0
                    rCrop.GetBottom()));
1192
1193
            // apply crop scale
1194
0
            const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX());
1195
0
            const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY());
1196
0
            const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX());
1197
0
            const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY());
1198
0
            basegfx::B2DHomMatrix aMatrixForCropViewHdl(aMatrix);
1199
1200
0
            if(IsMirrored())
1201
0
            {
1202
                // create corrected new matrix, TTTT can be removed with aw080
1203
                // the old mirror only can mirror horizontally; the vertical mirror
1204
                // is faked by using the horizontal and 180 degree rotation. Since
1205
                // the object can be rotated differently from 180 degree, this is
1206
                // not safe to detect. Just correct horizontal mirror (which is
1207
                // in IsMirrored()) and keep the rotation angle
1208
                // caution: Do not modify aMatrix, it is used below to calculate
1209
                // the exact handle positions
1210
0
                basegfx::B2DHomMatrix aPreMultiply;
1211
1212
                // mirrored X, apply
1213
0
                aPreMultiply.translate(-0.5, 0.0);
1214
0
                aPreMultiply.scale(-1.0, 1.0);
1215
0
                aPreMultiply.translate(0.5, 0.0);
1216
1217
0
                aMatrixForCropViewHdl = aMatrixForCropViewHdl * aPreMultiply;
1218
0
            }
1219
1220
0
            rTarget.AddHdl(std::make_unique<SdrCropViewHdl>(
1221
0
                aMatrixForCropViewHdl, GetGraphicObject().GetGraphic(), fCropLeft, fCropTop,
1222
0
                fCropRight, fCropBottom));
1223
0
        }
1224
0
    }
1225
0
}
1226
1227
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */