Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/source/outdev/map.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 <sal/config.h>
21
22
#include <sal/log.hxx>
23
#include <osl/diagnose.h>
24
#include <tools/bigint.hxx>
25
#include <tools/debug.hxx>
26
27
#include <vcl/cursor.hxx>
28
#include <vcl/lineinfo.hxx>
29
#include <vcl/metaact.hxx>
30
#include <vcl/virdev.hxx>
31
#include <vcl/wrkwin.hxx>
32
33
#include <ImplOutDevData.hxx>
34
#include <svdata.hxx>
35
#include <window.h>
36
37
#include <basegfx/matrix/b2dhommatrix.hxx>
38
#include <tools/UnitConversion.hxx>
39
40
static auto setMapRes(ImplMapRes& rMapRes, const o3tl::Length eUnit)
41
11.5M
{
42
11.5M
    const auto [nNum, nDen] = o3tl::getConversionMulDiv(eUnit, o3tl::Length::in);
43
11.5M
    rMapRes.mnMapScNumX = rMapRes.mnMapScNumY = nNum;
44
11.5M
    rMapRes.mnMapScDenomX = rMapRes.mnMapScDenomY = nDen;
45
11.5M
};
46
47
static void ImplCalcMapResolution( const MapMode& rMapMode,
48
                                   tools::Long nDPIX, tools::Long nDPIY, ImplMapRes& rMapRes )
49
11.5M
{
50
11.5M
    switch ( rMapMode.GetMapUnit() )
51
11.5M
    {
52
13.9k
        case MapUnit::MapRelative:
53
13.9k
            break;
54
1.32M
        case MapUnit::Map100thMM:
55
1.32M
            setMapRes(rMapRes, o3tl::Length::mm100);
56
1.32M
            break;
57
239
        case MapUnit::Map10thMM:
58
239
            setMapRes(rMapRes, o3tl::Length::mm10);
59
239
            break;
60
101k
        case MapUnit::MapMM:
61
101k
            setMapRes(rMapRes, o3tl::Length::mm);
62
101k
            break;
63
439
        case MapUnit::MapCM:
64
439
            setMapRes(rMapRes, o3tl::Length::cm);
65
439
            break;
66
73
        case MapUnit::Map1000thInch:
67
73
            setMapRes(rMapRes, o3tl::Length::in1000);
68
73
            break;
69
9
        case MapUnit::Map100thInch:
70
9
            setMapRes(rMapRes, o3tl::Length::in100);
71
9
            break;
72
14
        case MapUnit::Map10thInch:
73
14
            setMapRes(rMapRes, o3tl::Length::in10);
74
14
            break;
75
10.5k
        case MapUnit::MapInch:
76
10.5k
            setMapRes(rMapRes, o3tl::Length::in);
77
10.5k
            break;
78
1.03M
        case MapUnit::MapPoint:
79
1.03M
            setMapRes(rMapRes, o3tl::Length::pt);
80
1.03M
            break;
81
9.03M
        case MapUnit::MapTwip:
82
9.03M
            setMapRes(rMapRes, o3tl::Length::twip);
83
9.03M
            break;
84
29.0k
        case MapUnit::MapPixel:
85
29.0k
            rMapRes.mnMapScNumX   = 1;
86
29.0k
            rMapRes.mnMapScDenomX = nDPIX;
87
29.0k
            rMapRes.mnMapScNumY   = 1;
88
29.0k
            rMapRes.mnMapScDenomY = nDPIY;
89
29.0k
            break;
90
4
        case MapUnit::MapSysFont:
91
10
        case MapUnit::MapAppFont:
92
10
            {
93
10
            ImplSVData* pSVData = ImplGetSVData();
94
10
            if ( !pSVData->maGDIData.mnAppFontX )
95
1
            {
96
1
                if (pSVData->maFrameData.mpFirstFrame)
97
1
                    vcl::Window::ImplInitAppFontData(pSVData->maFrameData.mpFirstFrame);
98
0
                else
99
0
                {
100
0
                    ScopedVclPtrInstance<WorkWindow> pWin( nullptr, 0 );
101
0
                    vcl::Window::ImplInitAppFontData( pWin );
102
0
                }
103
1
            }
104
10
            rMapRes.mnMapScNumX   = pSVData->maGDIData.mnAppFontX;
105
10
            rMapRes.mnMapScDenomX = nDPIX * 40;
106
10
            rMapRes.mnMapScNumY   = pSVData->maGDIData.mnAppFontY;
107
10
            rMapRes.mnMapScDenomY = nDPIY * 80;
108
10
            }
109
10
            break;
110
0
        default:
111
0
            OSL_FAIL( "unhandled MapUnit" );
112
0
            break;
113
11.5M
    }
114
115
11.5M
    const Fraction& aScaleX = rMapMode.GetScaleX();
116
11.5M
    const Fraction& aScaleY = rMapMode.GetScaleY();
117
118
    // set offset according to MapMode
119
11.5M
    Point aOrigin = rMapMode.GetOrigin();
120
11.5M
    if ( rMapMode.GetMapUnit() != MapUnit::MapRelative )
121
11.5M
    {
122
11.5M
        rMapRes.mnMapOfsX = aOrigin.X();
123
11.5M
        rMapRes.mnMapOfsY = aOrigin.Y();
124
11.5M
    }
125
13.9k
    else
126
13.9k
    {
127
13.9k
        auto funcCalcOffset = [](const Fraction& rScale, tools::Long& rnMapOffset, tools::Long nOrigin)
128
27.8k
        {
129
27.8k
            auto nNumerator = rScale.GetNumerator();
130
27.8k
            assert(nNumerator != 0);
131
132
27.8k
            BigInt aX( rnMapOffset );
133
27.8k
            aX *= BigInt( rScale.GetDenominator() );
134
27.8k
            if ( rnMapOffset >= 0 )
135
23.6k
            {
136
23.6k
                if (nNumerator >= 0)
137
22.6k
                    aX += BigInt(nNumerator / 2);
138
922
                else
139
922
                    aX -= BigInt((nNumerator + 1) / 2);
140
23.6k
            }
141
4.21k
            else
142
4.21k
            {
143
4.21k
                if (nNumerator >= 0 )
144
4.06k
                    aX -= BigInt((nNumerator - 1) / 2);
145
156
                else
146
156
                    aX += BigInt(nNumerator / 2);
147
4.21k
            }
148
27.8k
            aX /= BigInt(nNumerator);
149
27.8k
            rnMapOffset = static_cast<tools::Long>(aX) + nOrigin;
150
27.8k
        };
151
152
13.9k
        funcCalcOffset(aScaleX, rMapRes.mnMapOfsX, aOrigin.X());
153
13.9k
        funcCalcOffset(aScaleY, rMapRes.mnMapOfsY, aOrigin.Y());
154
13.9k
    }
155
156
    // calculate scaling factor according to MapMode
157
    // aTemp? = rMapRes.mnMapSc? * aScale?
158
11.5M
    Fraction aTempX = Fraction::MakeFraction( rMapRes.mnMapScNumX,
159
11.5M
                                        aScaleX.GetNumerator(),
160
11.5M
                                        rMapRes.mnMapScDenomX,
161
11.5M
                                        aScaleX.GetDenominator() );
162
11.5M
    Fraction aTempY = Fraction::MakeFraction( rMapRes.mnMapScNumY,
163
11.5M
                                        aScaleY.GetNumerator(),
164
11.5M
                                        rMapRes.mnMapScDenomY,
165
11.5M
                                        aScaleY.GetDenominator() );
166
11.5M
    rMapRes.mnMapScNumX   = aTempX.GetNumerator();
167
11.5M
    rMapRes.mnMapScDenomX = aTempX.GetDenominator();
168
11.5M
    rMapRes.mnMapScNumY   = aTempY.GetNumerator();
169
11.5M
    rMapRes.mnMapScDenomY = aTempY.GetDenominator();
170
11.5M
}
171
172
// #i75163#
173
void OutputDevice::ImplInvalidateViewTransform()
174
4.67M
{
175
4.67M
    if(!mpOutDevData)
176
0
        return;
177
178
4.67M
    if(mpOutDevData->mpViewTransform)
179
61.3k
    {
180
61.3k
        delete mpOutDevData->mpViewTransform;
181
61.3k
        mpOutDevData->mpViewTransform = nullptr;
182
61.3k
    }
183
184
4.67M
    if(mpOutDevData->mpInverseViewTransform)
185
429
    {
186
429
        delete mpOutDevData->mpInverseViewTransform;
187
429
        mpOutDevData->mpInverseViewTransform = nullptr;
188
429
    }
189
4.67M
}
190
191
static tools::Long ImplLogicToPixel(tools::Long n, tools::Long nDPI, tools::Long nMapNum,
192
                                    tools::Long nMapDenom)
193
161M
{
194
161M
    assert(nDPI > 0);
195
161M
    assert(nMapDenom != 0);
196
    if constexpr (sizeof(tools::Long) >= 8)
197
161M
    {
198
161M
        assert(nMapNum >= 0);
199
        //detect overflows
200
161M
        assert(nMapNum == 0
201
161M
               || std::abs(n) < std::numeric_limits<tools::Long>::max() / nMapNum / nDPI);
202
161M
    }
203
161M
    sal_Int64 n64 = n;
204
161M
    n64 *= nMapNum;
205
161M
    n64 *= nDPI;
206
161M
    if (nMapDenom == 1)
207
190k
        n = static_cast<tools::Long>(n64);
208
161M
    else
209
161M
    {
210
161M
        n64 = 2 * n64 / nMapDenom;
211
161M
        if (n64 < 0)
212
22.1M
            --n64;
213
139M
        else
214
139M
            ++n64;
215
161M
        n = static_cast<tools::Long>(n64 / 2);
216
161M
    }
217
161M
    return n;
218
161M
}
219
220
static double ImplLogicToSubPixel(tools::Long n, tools::Long nDPI, tools::Long nMapNum,
221
                                         tools::Long nMapDenom)
222
56.6M
{
223
56.6M
    assert(nDPI > 0);
224
56.6M
    assert(nMapDenom != 0);
225
56.6M
    return static_cast<double>(n) * nMapNum * nDPI / nMapDenom;
226
56.6M
}
227
228
static tools::Long ImplSubPixelToLogic(double n, tools::Long nDPI, tools::Long nMapNum,
229
                                       tools::Long nMapDenom)
230
703k
{
231
703k
    assert(nDPI > 0);
232
703k
    assert(nMapNum != 0);
233
234
703k
    return std::round(n * nMapDenom / nMapNum / nDPI);
235
703k
}
236
237
static tools::Long ImplPixelToLogic(tools::Long n, tools::Long nDPI, tools::Long nMapNum,
238
                                    tools::Long nMapDenom)
239
536M
{
240
536M
    assert(nDPI > 0);
241
536M
    if (nMapNum == 0)
242
3.64k
        return 0;
243
536M
    sal_Int64 nDenom = nDPI;
244
536M
    nDenom *= nMapNum;
245
246
536M
    sal_Int64 n64 = n;
247
536M
    n64 *= nMapDenom;
248
536M
    if (nDenom == 1)
249
0
        n = static_cast<tools::Long>(n64);
250
536M
    else
251
536M
    {
252
536M
        n64 = 2 * n64 / nDenom;
253
536M
        if (n64 < 0)
254
33.0M
            --n64;
255
503M
        else
256
503M
            ++n64;
257
536M
        n = static_cast<tools::Long>(n64 / 2);
258
536M
    }
259
536M
    return n;
260
536M
}
261
262
static double ImplPixelToLogicDouble(double n, tools::Long nDPI, tools::Long nMapNum,
263
                                     tools::Long nMapDenom)
264
621M
{
265
621M
    assert(nDPI > 0);
266
621M
    if (nMapNum == 0)
267
10.1k
        return 0;
268
269
621M
    n *= nMapDenom;
270
621M
    n /= nDPI;
271
621M
    n /= nMapNum;
272
621M
    return n;
273
621M
}
274
275
tools::Long OutputDevice::ImplLogicXToDevicePixel( tools::Long nX ) const
276
520k
{
277
520k
    if ( !mbMap )
278
515k
        return nX+mnOutOffX;
279
280
4.81k
    return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
281
4.81k
                             maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX;
282
520k
}
283
284
tools::Long OutputDevice::ImplLogicYToDevicePixel( tools::Long nY ) const
285
520k
{
286
520k
    if ( !mbMap )
287
515k
        return nY+mnOutOffY;
288
289
4.81k
    return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
290
4.81k
                             maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY;
291
520k
}
292
293
tools::Long OutputDevice::ImplLogicWidthToDevicePixel( tools::Long nWidth ) const
294
50.8k
{
295
50.8k
    if ( !mbMap )
296
26.5k
        return nWidth;
297
298
24.2k
    return ImplLogicToPixel(nWidth, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
299
50.8k
}
300
301
tools::Long OutputDevice::ImplLogicHeightToDevicePixel( tools::Long nHeight ) const
302
41.7k
{
303
41.7k
    if ( !mbMap )
304
23.4k
        return nHeight;
305
306
18.2k
    return ImplLogicToPixel(nHeight, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY);
307
41.7k
}
308
309
tools::Long OutputDevice::ImplDevicePixelToLogicWidth( tools::Long nWidth ) const
310
54.6M
{
311
54.6M
    if ( !mbMap )
312
5.90k
        return nWidth;
313
314
54.6M
    return ImplPixelToLogic(nWidth, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
315
54.6M
}
316
317
SAL_DLLPRIVATE double OutputDevice::ImplDevicePixelToLogicWidthDouble(double nWidth) const
318
622M
{
319
622M
    if (!mbMap)
320
343k
        return nWidth;
321
322
621M
    return ImplPixelToLogicDouble(nWidth, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
323
622M
}
324
325
tools::Long OutputDevice::ImplDevicePixelToLogicHeight( tools::Long nHeight ) const
326
240M
{
327
240M
    if ( !mbMap )
328
13.2k
        return nHeight;
329
330
240M
    return ImplPixelToLogic(nHeight, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY);
331
240M
}
332
333
double OutputDevice::ImplDevicePixelToLogicHeightDouble(double nHeight) const
334
0
{
335
0
    if (!mbMap)
336
0
        return nHeight;
337
338
0
    return ImplPixelToLogicDouble(nHeight, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY);
339
0
}
340
341
Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
342
2.41M
{
343
2.41M
    if ( !mbMap )
344
2.39M
        return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
345
346
22.3k
    return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
347
22.3k
                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
348
22.3k
                  ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
349
22.3k
                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY );
350
2.41M
}
351
352
Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
353
13.6M
{
354
13.6M
    if ( !mbMap )
355
163k
        return rLogicSize;
356
357
13.5M
    return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
358
13.5M
                                   maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ),
359
13.5M
                 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
360
13.5M
                                   maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) );
361
13.6M
}
362
363
tools::Rectangle OutputDevice::ImplLogicToDevicePixel( const tools::Rectangle& rLogicRect ) const
364
1.25M
{
365
    // tdf#141761 IsEmpty() removed
366
    // Even if rLogicRect.IsEmpty(), transform of the Position contained
367
    // in the Rectangle is necessary. Due to Rectangle::Right() returning
368
    // Left() when IsEmpty(), the code *could* stay unchanged (same for Bottom),
369
    // but:
370
    // The Rectangle constructor used with the four tools::Long values does not
371
    // check for IsEmpty(), so to keep that state correct there are two possibilities:
372
    // (1) Add a test to the Rectangle constructor in question
373
    // (2) Do it by hand here
374
    // I have tried (1) first, but test Test::test_rectangle() claims that for
375
    //  tools::Rectangle aRect(1, 1, 1, 1);
376
    //    tools::Long(1) == aRect.GetWidth()
377
    //    tools::Long(0) == aRect.getWidth()
378
    // (remember: this means Left == Right == 1 -> GetWidth => 1, getWidth == 0)
379
    // so indeed the 1's have to go uncommented/unchecked into the data body
380
    // of rectangle. Switching to (2) *is* needed, doing so
381
1.25M
    tools::Rectangle aRetval;
382
383
1.25M
    if ( !mbMap )
384
1.22M
    {
385
1.22M
        aRetval = tools::Rectangle(
386
1.22M
            rLogicRect.Left()+mnOutOffX,
387
1.22M
            rLogicRect.Top()+mnOutOffY,
388
1.22M
            rLogicRect.IsWidthEmpty() ? 0 : rLogicRect.Right()+mnOutOffX,
389
1.22M
            rLogicRect.IsHeightEmpty() ? 0 : rLogicRect.Bottom()+mnOutOffY );
390
1.22M
    }
391
33.1k
    else
392
33.1k
    {
393
33.1k
        aRetval = tools::Rectangle(
394
33.1k
            ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
395
33.1k
            ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY,
396
33.1k
            rLogicRect.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
397
33.1k
            rLogicRect.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY );
398
33.1k
    }
399
400
1.25M
    if(rLogicRect.IsWidthEmpty())
401
728
        aRetval.SetWidthEmpty();
402
403
1.25M
    if(rLogicRect.IsHeightEmpty())
404
692
        aRetval.SetHeightEmpty();
405
406
1.25M
    return aRetval;
407
1.25M
}
408
409
tools::Polygon OutputDevice::ImplLogicToDevicePixel( const tools::Polygon& rLogicPoly ) const
410
324k
{
411
324k
    if ( !mbMap && !mnOutOffX && !mnOutOffY )
412
4.24k
        return rLogicPoly;
413
414
320k
    sal_uInt16  i;
415
320k
    sal_uInt16  nPoints = rLogicPoly.GetSize();
416
320k
    tools::Polygon aPoly( rLogicPoly );
417
418
    // get pointer to Point-array (copy data)
419
320k
    const Point* pPointAry = aPoly.GetConstPointAry();
420
421
320k
    if ( mbMap )
422
320k
    {
423
3.34M
        for ( i = 0; i < nPoints; i++ )
424
3.02M
        {
425
3.02M
            const Point& rPt = pPointAry[i];
426
3.02M
            Point aPt(ImplLogicToPixel( rPt.X()+maMapRes.mnMapOfsX, mnDPIX,
427
3.02M
                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
428
3.02M
                      ImplLogicToPixel( rPt.Y()+maMapRes.mnMapOfsY, mnDPIY,
429
3.02M
                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY);
430
3.02M
            aPoly[i] = aPt;
431
3.02M
        }
432
320k
    }
433
0
    else
434
0
    {
435
0
        for ( i = 0; i < nPoints; i++ )
436
0
        {
437
0
            Point aPt = pPointAry[i];
438
0
            aPt.AdjustX(mnOutOffX );
439
0
            aPt.AdjustY(mnOutOffY );
440
0
            aPoly[i] = aPt;
441
0
        }
442
0
    }
443
444
320k
    return aPoly;
445
324k
}
446
447
basegfx::B2DPolygon OutputDevice::ImplLogicToDevicePixel(const basegfx::B2DPolygon& rLogicPoly) const
448
603
{
449
603
    if (!mbMap && !mnOutOffX && !mnOutOffY)
450
20
        return rLogicPoly;
451
452
583
    sal_uInt32 nPoints = rLogicPoly.count();
453
583
    basegfx::B2DPolygon aPoly(rLogicPoly);
454
455
583
    basegfx::B2DPoint aC1;
456
583
    basegfx::B2DPoint aC2;
457
458
583
    if (mbMap)
459
583
    {
460
73.3k
        for (sal_uInt32 i = 0; i < nPoints; ++i)
461
72.7k
        {
462
72.7k
            const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
463
72.7k
            basegfx::B2DPoint aPt(ImplLogicToPixel( rPt.getX()+maMapRes.mnMapOfsX, mnDPIX,
464
72.7k
                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
465
72.7k
                                  ImplLogicToPixel( rPt.getY()+maMapRes.mnMapOfsY, mnDPIY,
466
72.7k
                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY);
467
468
72.7k
            const bool bC1 = aPoly.isPrevControlPointUsed(i);
469
72.7k
            if (bC1)
470
3.23k
            {
471
3.23k
                const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
472
473
3.23k
                aC1 = basegfx::B2DPoint(ImplLogicToPixel( aB2DC1.getX()+maMapRes.mnMapOfsX, mnDPIX,
474
3.23k
                                            maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
475
3.23k
                                        ImplLogicToPixel( aB2DC1.getY()+maMapRes.mnMapOfsY, mnDPIY,
476
3.23k
                                            maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY);
477
3.23k
            }
478
479
72.7k
            const bool bC2 = aPoly.isNextControlPointUsed(i);
480
72.7k
            if (bC2)
481
3.11k
            {
482
3.11k
                const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
483
484
3.11k
                aC2 = basegfx::B2DPoint(ImplLogicToPixel( aB2DC2.getX()+maMapRes.mnMapOfsX, mnDPIX,
485
3.11k
                                            maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffX+mnOutOffOrigX,
486
3.11k
                                        ImplLogicToPixel( aB2DC2.getY()+maMapRes.mnMapOfsY, mnDPIY,
487
3.11k
                                            maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffY+mnOutOffOrigY);
488
3.11k
            }
489
490
72.7k
            aPoly.setB2DPoint(i, aPt);
491
492
72.7k
            if (bC1)
493
3.23k
                aPoly.setPrevControlPoint(i, aC1);
494
495
72.7k
            if (bC2)
496
3.11k
                aPoly.setNextControlPoint(i, aC2);
497
72.7k
        }
498
583
    }
499
0
    else
500
0
    {
501
0
        for (sal_uInt32 i = 0; i < nPoints; ++i)
502
0
        {
503
0
            const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
504
0
            basegfx::B2DPoint aPt(rPt.getX() + mnOutOffX, rPt.getY() + mnOutOffY);
505
506
0
            const bool bC1 = aPoly.isPrevControlPointUsed(i);
507
0
            if (bC1)
508
0
            {
509
0
                const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
510
511
0
                aC1 = basegfx::B2DPoint(aB2DC1.getX() + mnOutOffX, aB2DC1.getY() + mnOutOffY);
512
0
            }
513
514
0
            const bool bC2 = aPoly.isNextControlPointUsed(i);
515
0
            if (bC2)
516
0
            {
517
0
                const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
518
519
0
                aC1 = basegfx::B2DPoint(aB2DC2.getX() + mnOutOffX, aB2DC2.getY() + mnOutOffY);
520
0
            }
521
522
0
            aPoly.setB2DPoint(i, aPt);
523
524
0
            if (bC1)
525
0
                aPoly.setPrevControlPoint(i, aC1);
526
527
0
            if (bC2)
528
0
                aPoly.setNextControlPoint(i, aC2);
529
0
        }
530
0
    }
531
532
583
    return aPoly;
533
603
}
534
535
tools::PolyPolygon OutputDevice::ImplLogicToDevicePixel( const tools::PolyPolygon& rLogicPolyPoly ) const
536
335k
{
537
335k
    if ( !mbMap && !mnOutOffX && !mnOutOffY )
538
15.5k
        return rLogicPolyPoly;
539
540
319k
    tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
541
319k
    sal_uInt16      nPoly = aPolyPoly.Count();
542
639k
    for( sal_uInt16 i = 0; i < nPoly; i++ )
543
320k
    {
544
320k
        tools::Polygon& rPoly = aPolyPoly[i];
545
320k
        rPoly = ImplLogicToDevicePixel( rPoly );
546
320k
    }
547
319k
    return aPolyPoly;
548
335k
}
549
550
LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
551
1.98k
{
552
1.98k
    LineInfo aInfo( rLineInfo );
553
554
1.98k
    if( aInfo.GetStyle() == LineStyle::Dash )
555
1.48k
    {
556
1.48k
        if( aInfo.GetDotCount() && aInfo.GetDotLen() )
557
907
            aInfo.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), tools::Long(1) ) );
558
579
        else
559
579
            aInfo.SetDotCount( 0 );
560
561
1.48k
        if( aInfo.GetDashCount() && aInfo.GetDashLen() )
562
1.02k
            aInfo.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), tools::Long(1) ) );
563
460
        else
564
460
            aInfo.SetDashCount( 0 );
565
566
1.48k
        aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
567
568
1.48k
        if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
569
1.18k
            aInfo.SetStyle( LineStyle::Solid );
570
1.48k
    }
571
572
1.98k
    aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
573
574
1.98k
    return aInfo;
575
1.98k
}
576
577
tools::Rectangle OutputDevice::ImplDevicePixelToLogic( const tools::Rectangle& rPixelRect ) const
578
909k
{
579
    // tdf#141761 see comments above, IsEmpty() removed
580
909k
    tools::Rectangle aRetval;
581
582
909k
    if ( !mbMap )
583
0
    {
584
0
        aRetval = tools::Rectangle(
585
0
            rPixelRect.Left()-mnOutOffX,
586
0
            rPixelRect.Top()-mnOutOffY,
587
0
            rPixelRect.IsWidthEmpty() ? 0 : rPixelRect.Right()-mnOutOffX,
588
0
            rPixelRect.IsHeightEmpty() ? 0 : rPixelRect.Bottom()-mnOutOffY );
589
0
    }
590
909k
    else
591
909k
    {
592
909k
        aRetval = tools::Rectangle(
593
909k
            ImplPixelToLogic( rPixelRect.Left()-mnOutOffX-mnOutOffOrigX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )-maMapRes.mnMapOfsX,
594
909k
            ImplPixelToLogic( rPixelRect.Top()-mnOutOffY-mnOutOffOrigY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )-maMapRes.mnMapOfsY,
595
909k
            rPixelRect.IsWidthEmpty() ? 0 : ImplPixelToLogic( rPixelRect.Right()-mnOutOffX-mnOutOffOrigX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )-maMapRes.mnMapOfsX,
596
909k
            rPixelRect.IsHeightEmpty() ? 0 : ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY-mnOutOffOrigY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )-maMapRes.mnMapOfsY );
597
909k
    }
598
599
909k
    if(rPixelRect.IsWidthEmpty())
600
0
        aRetval.SetWidthEmpty();
601
602
909k
    if(rPixelRect.IsHeightEmpty())
603
0
        aRetval.SetHeightEmpty();
604
605
909k
    return aRetval;
606
909k
}
607
608
vcl::Region OutputDevice::ImplPixelToDevicePixel( const vcl::Region& rRegion ) const
609
42.9k
{
610
42.9k
    if ( !mnOutOffX && !mnOutOffY )
611
42.9k
        return rRegion;
612
613
0
    vcl::Region aRegion( rRegion );
614
0
    aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
615
0
    return aRegion;
616
42.9k
}
617
618
void OutputDevice::EnableMapMode( bool bEnable )
619
54.1k
{
620
54.1k
    mbMap = bEnable;
621
54.1k
}
622
623
void OutputDevice::SetMapMode()
624
34.2k
{
625
34.2k
    if ( mpMetaFile )
626
0
        mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
627
628
34.2k
    if ( mbMap || !maMapMode.IsDefault() )
629
34.2k
    {
630
34.2k
        mbMap       = false;
631
34.2k
        maMapMode   = MapMode();
632
633
        // create new objects (clip region are not re-scaled)
634
34.2k
        mbNewFont   = true;
635
34.2k
        mbInitFont  = true;
636
34.2k
        ImplInitMapModeObjects();
637
638
        // #106426# Adapt logical offset when changing mapmode
639
34.2k
        mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
640
34.2k
        mnOutOffLogicY = mnOutOffOrigY;
641
642
        // #i75163#
643
34.2k
        ImplInvalidateViewTransform();
644
34.2k
    }
645
34.2k
}
646
647
void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
648
9.90M
{
649
650
9.90M
    bool bRelMap = (rNewMapMode.GetMapUnit() == MapUnit::MapRelative);
651
652
9.90M
    if ( mpMetaFile )
653
250k
    {
654
250k
        mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
655
250k
    }
656
657
    // do nothing if MapMode was not changed
658
9.90M
    if ( maMapMode == rNewMapMode )
659
6.85M
        return;
660
661
     // if default MapMode calculate nothing
662
3.05M
    bool bOldMap = mbMap;
663
3.05M
    mbMap = !rNewMapMode.IsDefault();
664
3.05M
    if ( mbMap )
665
2.96M
    {
666
        // if only the origin is converted, do not scale new
667
2.96M
        if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
668
189k
             (rNewMapMode.GetScaleX()  == maMapMode.GetScaleX())  &&
669
188k
             (rNewMapMode.GetScaleY()  == maMapMode.GetScaleY())  &&
670
188k
             (bOldMap                  == mbMap) )
671
188k
        {
672
            // set offset
673
188k
            Point aOrigin = rNewMapMode.GetOrigin();
674
188k
            maMapRes.mnMapOfsX = aOrigin.X();
675
188k
            maMapRes.mnMapOfsY = aOrigin.Y();
676
188k
            maMapMode = rNewMapMode;
677
678
            // #i75163#
679
188k
            ImplInvalidateViewTransform();
680
681
188k
            return;
682
188k
        }
683
2.77M
        if ( !bOldMap && bRelMap )
684
966
        {
685
966
            maMapRes.mnMapScNumX    = 1;
686
966
            maMapRes.mnMapScNumY    = 1;
687
966
            maMapRes.mnMapScDenomX  = mnDPIX;
688
966
            maMapRes.mnMapScDenomY  = mnDPIY;
689
966
            maMapRes.mnMapOfsX      = 0;
690
966
            maMapRes.mnMapOfsY      = 0;
691
966
        }
692
693
        // calculate new MapMode-resolution
694
2.77M
        ImplCalcMapResolution(rNewMapMode, mnDPIX, mnDPIY, maMapRes);
695
2.77M
    }
696
697
    // set new MapMode
698
2.86M
    if (bRelMap)
699
13.9k
    {
700
13.9k
        maMapMode.SetScaleX(Fraction::MakeFraction(
701
13.9k
            maMapMode.GetScaleX().GetNumerator(), rNewMapMode.GetScaleX().GetNumerator(),
702
13.9k
            maMapMode.GetScaleX().GetDenominator(), rNewMapMode.GetScaleX().GetDenominator()));
703
704
13.9k
        maMapMode.SetScaleY(Fraction::MakeFraction(
705
13.9k
            maMapMode.GetScaleY().GetNumerator(), rNewMapMode.GetScaleY().GetNumerator(),
706
13.9k
            maMapMode.GetScaleY().GetDenominator(), rNewMapMode.GetScaleY().GetDenominator()));
707
708
13.9k
        maMapMode.SetOrigin(Point(maMapRes.mnMapOfsX, maMapRes.mnMapOfsY));
709
13.9k
    }
710
2.84M
    else
711
2.84M
    {
712
2.84M
        maMapMode = rNewMapMode;
713
2.84M
    }
714
715
    // create new objects (clip region are not re-scaled)
716
2.86M
    mbNewFont   = true;
717
2.86M
    mbInitFont  = true;
718
2.86M
    ImplInitMapModeObjects();
719
720
    // #106426# Adapt logical offset when changing mapmode
721
2.86M
    mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
722
2.86M
                                       maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX );
723
2.86M
    mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
724
2.86M
                                       maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY );
725
726
    // #i75163#
727
2.86M
    ImplInvalidateViewTransform();
728
2.86M
}
729
730
void OutputDevice::SetMetafileMapMode(const MapMode& rNewMapMode, bool bIsRecord)
731
828
{
732
828
    if (bIsRecord)
733
0
        SetRelativeMapMode(rNewMapMode);
734
828
    else
735
828
        SetMapMode(rNewMapMode);
736
828
}
737
738
2.89M
void OutputDevice::ImplInitMapModeObjects() {}
739
740
void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
741
139
{
742
    // do nothing if MapMode did not change
743
139
    if ( maMapMode == rNewMapMode )
744
0
        return;
745
746
139
    MapUnit eOld = maMapMode.GetMapUnit();
747
139
    MapUnit eNew = rNewMapMode.GetMapUnit();
748
749
    // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
750
139
    Fraction aXF = Fraction::MakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
751
139
                                     maMapMode.GetScaleX().GetDenominator(),
752
139
                                     rNewMapMode.GetScaleX().GetDenominator(),
753
139
                                     maMapMode.GetScaleX().GetNumerator() );
754
139
    Fraction aYF = Fraction::MakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
755
139
                                     maMapMode.GetScaleY().GetDenominator(),
756
139
                                     rNewMapMode.GetScaleY().GetDenominator(),
757
139
                                     maMapMode.GetScaleY().GetNumerator() );
758
759
139
    Point aPt( LogicToLogic( Point(), nullptr, &rNewMapMode ) );
760
139
    if ( eNew != eOld )
761
0
    {
762
0
        if ( eOld > MapUnit::MapPixel )
763
0
        {
764
0
            SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
765
0
        }
766
0
        else if ( eNew > MapUnit::MapPixel )
767
0
        {
768
0
            SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
769
0
        }
770
0
        else
771
0
        {
772
0
            const auto eFrom = MapToO3tlLength(eOld, o3tl::Length::in);
773
0
            const auto eTo = MapToO3tlLength(eNew, o3tl::Length::in);
774
0
            const auto [mul, div] = o3tl::getConversionMulDiv(eFrom, eTo);
775
0
            Fraction aF(div, mul);
776
777
            // a?F =  a?F * aF
778
0
            aXF = Fraction::MakeFraction( aXF.GetNumerator(),   aF.GetNumerator(),
779
0
                                    aXF.GetDenominator(), aF.GetDenominator() );
780
0
            aYF = Fraction::MakeFraction( aYF.GetNumerator(),   aF.GetNumerator(),
781
0
                                    aYF.GetDenominator(), aF.GetDenominator() );
782
0
            if ( eOld == MapUnit::MapPixel )
783
0
            {
784
0
                aXF *= Fraction( mnDPIX, 1 );
785
0
                aYF *= Fraction( mnDPIY, 1 );
786
0
            }
787
0
            else if ( eNew == MapUnit::MapPixel )
788
0
            {
789
0
                aXF *= Fraction( 1, mnDPIX );
790
0
                aYF *= Fraction( 1, mnDPIY );
791
0
            }
792
0
        }
793
0
    }
794
795
139
    MapMode aNewMapMode( MapUnit::MapRelative, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
796
139
    SetMapMode( aNewMapMode );
797
798
139
    if ( eNew != eOld )
799
0
        maMapMode = rNewMapMode;
800
801
    // #106426# Adapt logical offset when changing MapMode
802
139
    mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
803
139
                                       maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX );
804
139
    mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
805
139
                                       maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY );
806
139
}
807
808
// #i75163#
809
basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
810
863k
{
811
863k
    if(mbMap && mpOutDevData)
812
250k
    {
813
250k
        if(!mpOutDevData->mpViewTransform)
814
61.3k
        {
815
61.3k
            mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
816
817
61.3k
            const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(maMapRes.mnMapScNumX) / static_cast<double>(maMapRes.mnMapScDenomX));
818
61.3k
            const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(maMapRes.mnMapScNumY) / static_cast<double>(maMapRes.mnMapScDenomY));
819
61.3k
            const double fZeroPointX((static_cast<double>(maMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
820
61.3k
            const double fZeroPointY((static_cast<double>(maMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
821
822
61.3k
            mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
823
61.3k
            mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
824
61.3k
            mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
825
61.3k
            mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
826
61.3k
        }
827
828
250k
        return *mpOutDevData->mpViewTransform;
829
250k
    }
830
612k
    else
831
612k
    {
832
612k
        return basegfx::B2DHomMatrix();
833
612k
    }
834
863k
}
835
836
// #i75163#
837
basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
838
2.50M
{
839
2.50M
    if(mbMap && mpOutDevData)
840
2.49M
    {
841
2.49M
        if(!mpOutDevData->mpInverseViewTransform)
842
430
        {
843
430
            GetViewTransformation();
844
430
            mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
845
430
            mpOutDevData->mpInverseViewTransform->invert();
846
430
        }
847
848
2.49M
        return *mpOutDevData->mpInverseViewTransform;
849
2.49M
    }
850
8.80k
    else
851
8.80k
    {
852
8.80k
        return basegfx::B2DHomMatrix();
853
8.80k
    }
854
2.50M
}
855
856
// #i75163#
857
basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const
858
487k
{
859
    // #i82615#
860
487k
    ImplMapRes          aMapRes;
861
487k
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
862
863
487k
    basegfx::B2DHomMatrix aTransform;
864
865
487k
    const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(aMapRes.mnMapScNumX) / static_cast<double>(aMapRes.mnMapScDenomX));
866
487k
    const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(aMapRes.mnMapScNumY) / static_cast<double>(aMapRes.mnMapScDenomY));
867
487k
    const double fZeroPointX((static_cast<double>(aMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
868
487k
    const double fZeroPointY((static_cast<double>(aMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
869
870
487k
    aTransform.set(0, 0, fScaleFactorX);
871
487k
    aTransform.set(1, 1, fScaleFactorY);
872
487k
    aTransform.set(0, 2, fZeroPointX);
873
487k
    aTransform.set(1, 2, fZeroPointY);
874
875
487k
    return aTransform;
876
487k
}
877
878
// #i75163#
879
basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const
880
243k
{
881
243k
    basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
882
243k
    aMatrix.invert();
883
243k
    return aMatrix;
884
243k
}
885
886
basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
887
617k
{
888
617k
    basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
889
    // TODO: is it worth to cache the transformed result?
890
617k
    if( mnOutOffX || mnOutOffY )
891
0
        aTransformation.translate( mnOutOffX, mnOutOffY );
892
617k
    return aTransformation;
893
617k
}
894
895
Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
896
31.8k
{
897
898
31.8k
    if ( !mbMap )
899
11.8k
        return rLogicPt;
900
901
20.0k
    return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
902
20.0k
                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffOrigX,
903
20.0k
                  ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
904
20.0k
                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffOrigY );
905
31.8k
}
906
907
Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
908
9.48k
{
909
910
9.48k
    if ( !mbMap )
911
5.26k
        return rLogicSize;
912
913
4.22k
    return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
914
4.22k
                                   maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ),
915
4.22k
                 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
916
4.22k
                                   maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) );
917
9.48k
}
918
919
tools::Rectangle OutputDevice::LogicToPixel( const tools::Rectangle& rLogicRect ) const
920
31.9M
{
921
    // tdf#141761 see comments above, IsEmpty() removed
922
31.9M
    if ( !mbMap )
923
84.9k
        return rLogicRect;
924
925
31.8M
    tools::Rectangle aRetval(
926
31.8M
        ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffOrigX,
927
31.8M
        ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffOrigY,
928
31.8M
        rLogicRect.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffOrigX,
929
31.8M
        rLogicRect.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffOrigY );
930
931
31.8M
    if(rLogicRect.IsWidthEmpty())
932
23.7k
        aRetval.SetWidthEmpty();
933
934
31.8M
    if(rLogicRect.IsHeightEmpty())
935
25.9k
        aRetval.SetHeightEmpty();
936
937
31.8M
    return aRetval;
938
31.9M
}
939
940
tools::Polygon OutputDevice::LogicToPixel( const tools::Polygon& rLogicPoly ) const
941
2.70k
{
942
943
2.70k
    if ( !mbMap )
944
0
        return rLogicPoly;
945
946
2.70k
    sal_uInt16  i;
947
2.70k
    sal_uInt16  nPoints = rLogicPoly.GetSize();
948
2.70k
    tools::Polygon aPoly( rLogicPoly );
949
950
    // get pointer to Point-array (copy data)
951
2.70k
    const Point* pPointAry = aPoly.GetConstPointAry();
952
953
124k
    for ( i = 0; i < nPoints; i++ )
954
121k
    {
955
121k
        const Point* pPt = &(pPointAry[i]);
956
121k
        Point aPt;
957
121k
        aPt.setX( ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
958
121k
                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX )+mnOutOffOrigX );
959
121k
        aPt.setY( ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
960
121k
                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY )+mnOutOffOrigY );
961
121k
        aPoly[i] = aPt;
962
121k
    }
963
964
2.70k
    return aPoly;
965
2.70k
}
966
967
tools::PolyPolygon OutputDevice::LogicToPixel( const tools::PolyPolygon& rLogicPolyPoly ) const
968
2.17k
{
969
970
2.17k
    if ( !mbMap )
971
236
        return rLogicPolyPoly;
972
973
1.94k
    tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
974
1.94k
    sal_uInt16      nPoly = aPolyPoly.Count();
975
4.64k
    for( sal_uInt16 i = 0; i < nPoly; i++ )
976
2.70k
    {
977
2.70k
        tools::Polygon& rPoly = aPolyPoly[i];
978
2.70k
        rPoly = LogicToPixel( rPoly );
979
2.70k
    }
980
1.94k
    return aPolyPoly;
981
2.17k
}
982
983
basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const
984
151
{
985
151
    basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
986
151
    const basegfx::B2DHomMatrix aTransformationMatrix = GetViewTransformation();
987
151
    aTransformedPoly.transform( aTransformationMatrix );
988
151
    return aTransformedPoly;
989
151
}
990
991
vcl::Region OutputDevice::LogicToPixel( const vcl::Region& rLogicRegion ) const
992
204k
{
993
994
204k
    if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
995
17.2k
    {
996
17.2k
        return rLogicRegion;
997
17.2k
    }
998
999
186k
    vcl::Region aRegion;
1000
1001
186k
    if(rLogicRegion.getB2DPolyPolygon())
1002
151
    {
1003
151
        aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
1004
151
    }
1005
186k
    else if(rLogicRegion.getPolyPolygon())
1006
814
    {
1007
814
        aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
1008
814
    }
1009
185k
    else if(rLogicRegion.getRegionBand())
1010
185k
    {
1011
185k
        RectangleVector aRectangles;
1012
185k
        rLogicRegion.GetRegionRectangles(aRectangles);
1013
185k
        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1014
1015
        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1016
373k
        for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1017
187k
        {
1018
187k
            aRegion.Union(LogicToPixel(*aRectIter));
1019
187k
        }
1020
185k
    }
1021
1022
186k
    return aRegion;
1023
204k
}
1024
1025
Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1026
                                  const MapMode& rMapMode ) const
1027
57.4k
{
1028
1029
57.4k
    if ( rMapMode.IsDefault() )
1030
0
        return rLogicPt;
1031
1032
    // convert MapMode resolution and convert
1033
57.4k
    ImplMapRes          aMapRes;
1034
57.4k
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1035
1036
57.4k
    return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1037
57.4k
                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1038
57.4k
                  ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1039
57.4k
                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1040
57.4k
}
1041
1042
Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1043
                                 const MapMode& rMapMode ) const
1044
227k
{
1045
1046
227k
    if ( rMapMode.IsDefault() )
1047
32.1k
        return rLogicSize;
1048
1049
    // convert MapMode resolution and convert
1050
195k
    ImplMapRes          aMapRes;
1051
195k
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1052
1053
195k
    return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1054
195k
                                   aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1055
195k
                 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1056
195k
                                   aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1057
227k
}
1058
1059
tools::Rectangle OutputDevice::LogicToPixel( const tools::Rectangle& rLogicRect,
1060
                                      const MapMode& rMapMode ) const
1061
0
{
1062
    // tdf#141761 see comments above, IsEmpty() removed
1063
0
    if ( rMapMode.IsDefault() )
1064
0
        return rLogicRect;
1065
1066
    // convert MapMode resolution and convert
1067
0
    ImplMapRes          aMapRes;
1068
0
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1069
1070
0
    tools::Rectangle aRetval(
1071
0
        ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1072
0
        ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY,
1073
0
        rLogicRect.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,   aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1074
0
        rLogicRect.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1075
1076
0
    if(rLogicRect.IsWidthEmpty())
1077
0
        aRetval.SetWidthEmpty();
1078
1079
0
    if(rLogicRect.IsHeightEmpty())
1080
0
        aRetval.SetHeightEmpty();
1081
1082
0
    return aRetval;
1083
0
}
1084
1085
tools::Polygon OutputDevice::LogicToPixel( const tools::Polygon& rLogicPoly,
1086
                                           const MapMode& rMapMode ) const
1087
0
{
1088
1089
0
    if ( rMapMode.IsDefault() )
1090
0
        return rLogicPoly;
1091
1092
    // convert MapMode resolution and convert
1093
0
    ImplMapRes          aMapRes;
1094
0
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1095
1096
0
    sal_uInt16  i;
1097
0
    sal_uInt16  nPoints = rLogicPoly.GetSize();
1098
0
    tools::Polygon aPoly( rLogicPoly );
1099
1100
    // get pointer to Point-array (copy data)
1101
0
    const Point* pPointAry = aPoly.GetConstPointAry();
1102
1103
0
    for ( i = 0; i < nPoints; i++ )
1104
0
    {
1105
0
        const Point* pPt = &(pPointAry[i]);
1106
0
        Point aPt;
1107
0
        aPt.setX( ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1108
0
                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX );
1109
0
        aPt.setY( ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1110
0
                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1111
0
        aPoly[i] = aPt;
1112
0
    }
1113
1114
0
    return aPoly;
1115
0
}
1116
1117
basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1118
                                                    const MapMode& rMapMode ) const
1119
0
{
1120
0
    basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1121
0
    const basegfx::B2DHomMatrix aTransformationMatrix = GetViewTransformation( rMapMode );
1122
0
    aTransformedPoly.transform( aTransformationMatrix );
1123
0
    return aTransformedPoly;
1124
0
}
1125
1126
Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1127
21.4k
{
1128
1129
21.4k
    if ( !mbMap )
1130
10.4k
        return rDevicePt;
1131
1132
10.9k
    return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1133
10.9k
                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1134
10.9k
                  ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1135
10.9k
                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1136
21.4k
}
1137
1138
Point OutputDevice::SubPixelToLogic(const basegfx::B2DPoint& rDevicePt) const
1139
351k
{
1140
351k
    if (!mbMap)
1141
0
    {
1142
0
        assert(floor(rDevicePt.getX() == rDevicePt.getX()) && floor(rDevicePt.getY() == rDevicePt.getY()));
1143
0
        return Point(rDevicePt.getX(), rDevicePt.getY());
1144
0
    }
1145
1146
351k
    return Point(ImplSubPixelToLogic(rDevicePt.getX(), mnDPIX,
1147
351k
                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1148
351k
                 ImplSubPixelToLogic(rDevicePt.getY(), mnDPIY,
1149
351k
                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY) - maMapRes.mnMapOfsY - mnOutOffLogicY);
1150
351k
}
1151
1152
Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1153
31.4M
{
1154
1155
31.4M
    if ( !mbMap )
1156
163k
        return rDeviceSize;
1157
1158
31.3M
    return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1159
31.3M
                                   maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ),
1160
31.3M
                 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1161
31.3M
                                   maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) );
1162
31.4M
}
1163
1164
tools::Rectangle OutputDevice::PixelToLogic( const tools::Rectangle& rDeviceRect ) const
1165
39.1M
{
1166
    // tdf#141761 see comments above, IsEmpty() removed
1167
39.1M
    if ( !mbMap )
1168
20.8k
        return rDeviceRect;
1169
1170
39.0M
    tools::Rectangle aRetval(
1171
39.0M
        ImplPixelToLogic( rDeviceRect.Left(), mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1172
39.0M
        ImplPixelToLogic( rDeviceRect.Top(), mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1173
39.0M
        rDeviceRect.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Right(), mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1174
39.0M
        rDeviceRect.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1175
1176
39.0M
    if(rDeviceRect.IsWidthEmpty())
1177
298
        aRetval.SetWidthEmpty();
1178
1179
39.0M
    if(rDeviceRect.IsHeightEmpty())
1180
298
        aRetval.SetHeightEmpty();
1181
1182
39.0M
    return aRetval;
1183
39.1M
}
1184
1185
tools::Polygon OutputDevice::PixelToLogic( const tools::Polygon& rDevicePoly ) const
1186
0
{
1187
1188
0
    if ( !mbMap )
1189
0
        return rDevicePoly;
1190
1191
0
    sal_uInt16  i;
1192
0
    sal_uInt16  nPoints = rDevicePoly.GetSize();
1193
0
    tools::Polygon aPoly( rDevicePoly );
1194
1195
    // get pointer to Point-array (copy data)
1196
0
    const Point* pPointAry = aPoly.GetConstPointAry();
1197
1198
0
    for ( i = 0; i < nPoints; i++ )
1199
0
    {
1200
0
        const Point* pPt = &(pPointAry[i]);
1201
0
        Point aPt;
1202
0
        aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1203
0
                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX ) - maMapRes.mnMapOfsX - mnOutOffLogicX );
1204
0
        aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1205
0
                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1206
0
        aPoly[i] = aPt;
1207
0
    }
1208
1209
0
    return aPoly;
1210
0
}
1211
1212
tools::PolyPolygon OutputDevice::PixelToLogic( const tools::PolyPolygon& rDevicePolyPoly ) const
1213
0
{
1214
1215
0
    if ( !mbMap )
1216
0
        return rDevicePolyPoly;
1217
1218
0
    tools::PolyPolygon aPolyPoly( rDevicePolyPoly );
1219
0
    sal_uInt16      nPoly = aPolyPoly.Count();
1220
0
    for( sal_uInt16 i = 0; i < nPoly; i++ )
1221
0
    {
1222
0
        tools::Polygon& rPoly = aPolyPoly[i];
1223
0
        rPoly = PixelToLogic( rPoly );
1224
0
    }
1225
0
    return aPolyPoly;
1226
0
}
1227
1228
basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const
1229
0
{
1230
0
    basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1231
0
    const basegfx::B2DHomMatrix aTransformationMatrix = GetInverseViewTransformation();
1232
0
    aTransformedPoly.transform( aTransformationMatrix );
1233
0
    return aTransformedPoly;
1234
0
}
1235
1236
basegfx::B2DRectangle OutputDevice::PixelToLogic(const basegfx::B2DRectangle& rDeviceRect) const
1237
2.50M
{
1238
2.50M
    basegfx::B2DRectangle aTransformedRect = rDeviceRect;
1239
2.50M
    const basegfx::B2DHomMatrix aTransformationMatrix = GetInverseViewTransformation();
1240
2.50M
    aTransformedRect.transform(aTransformationMatrix);
1241
2.50M
    return aTransformedRect;
1242
2.50M
}
1243
1244
vcl::Region OutputDevice::PixelToLogic( const vcl::Region& rDeviceRegion ) const
1245
189
{
1246
1247
189
    if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1248
0
    {
1249
0
        return rDeviceRegion;
1250
0
    }
1251
1252
189
    vcl::Region aRegion;
1253
1254
189
    if(rDeviceRegion.getB2DPolyPolygon())
1255
0
    {
1256
0
        aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
1257
0
    }
1258
189
    else if(rDeviceRegion.getPolyPolygon())
1259
0
    {
1260
0
        aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
1261
0
    }
1262
189
    else if(rDeviceRegion.getRegionBand())
1263
189
    {
1264
189
        RectangleVector aRectangles;
1265
189
        rDeviceRegion.GetRegionRectangles(aRectangles);
1266
189
        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1267
1268
        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1269
378
        for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1270
189
        {
1271
189
            aRegion.Union(PixelToLogic(*aRectIter));
1272
189
        }
1273
189
    }
1274
1275
189
    return aRegion;
1276
189
}
1277
1278
Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1279
                                  const MapMode& rMapMode ) const
1280
29.1k
{
1281
1282
    // calculate nothing if default-MapMode
1283
29.1k
    if ( rMapMode.IsDefault() )
1284
0
        return rDevicePt;
1285
1286
    // calculate MapMode-resolution and convert
1287
29.1k
    ImplMapRes          aMapRes;
1288
29.1k
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1289
1290
29.1k
    return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1291
29.1k
                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1292
29.1k
                  ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1293
29.1k
                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1294
29.1k
}
1295
1296
Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1297
                                 const MapMode& rMapMode ) const
1298
6.52M
{
1299
1300
    // calculate nothing if default-MapMode
1301
6.52M
    if ( rMapMode.IsDefault() )
1302
0
        return rDeviceSize;
1303
1304
    // calculate MapMode-resolution and convert
1305
6.52M
    ImplMapRes          aMapRes;
1306
6.52M
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1307
1308
6.52M
    return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1309
6.52M
                                   aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1310
6.52M
                 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1311
6.52M
                                   aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1312
6.52M
}
1313
1314
tools::Rectangle OutputDevice::PixelToLogic( const tools::Rectangle& rDeviceRect,
1315
                                      const MapMode& rMapMode ) const
1316
1.77k
{
1317
    // calculate nothing if default-MapMode
1318
    // tdf#141761 see comments above, IsEmpty() removed
1319
1.77k
    if ( rMapMode.IsDefault() )
1320
0
        return rDeviceRect;
1321
1322
    // calculate MapMode-resolution and convert
1323
1.77k
    ImplMapRes          aMapRes;
1324
1.77k
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1325
1326
1.77k
    tools::Rectangle aRetval(
1327
1.77k
        ImplPixelToLogic( rDeviceRect.Left(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1328
1.77k
        ImplPixelToLogic( rDeviceRect.Top(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1329
1.77k
        rDeviceRect.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Right(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1330
1.77k
        rDeviceRect.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1331
1332
1.77k
    if(rDeviceRect.IsWidthEmpty())
1333
0
        aRetval.SetWidthEmpty();
1334
1335
1.77k
    if(rDeviceRect.IsHeightEmpty())
1336
0
        aRetval.SetHeightEmpty();
1337
1338
1.77k
    return aRetval;
1339
1.77k
}
1340
1341
tools::Polygon OutputDevice::PixelToLogic( const tools::Polygon& rDevicePoly,
1342
                                           const MapMode& rMapMode ) const
1343
26
{
1344
1345
    // calculate nothing if default-MapMode
1346
26
    if ( rMapMode.IsDefault() )
1347
0
        return rDevicePoly;
1348
1349
    // calculate MapMode-resolution and convert
1350
26
    ImplMapRes          aMapRes;
1351
26
    ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1352
1353
26
    sal_uInt16  i;
1354
26
    sal_uInt16  nPoints = rDevicePoly.GetSize();
1355
26
    tools::Polygon aPoly( rDevicePoly );
1356
1357
    // get pointer to Point-array (copy data)
1358
26
    const Point* pPointAry = aPoly.GetConstPointAry();
1359
1360
178
    for ( i = 0; i < nPoints; i++ )
1361
152
    {
1362
152
        const Point* pPt = &(pPointAry[i]);
1363
152
        Point aPt;
1364
152
        aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1365
152
                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX );
1366
152
        aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1367
152
                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1368
152
        aPoly[i] = aPt;
1369
152
    }
1370
1371
26
    return aPoly;
1372
26
}
1373
1374
basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
1375
                                                const MapMode& rMapMode ) const
1376
0
{
1377
0
    basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1378
0
    const basegfx::B2DHomMatrix aTransformationMatrix = GetInverseViewTransformation( rMapMode );
1379
0
    aTransformedPoly.transform( aTransformationMatrix );
1380
0
    return aTransformedPoly;
1381
0
}
1382
1383
basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly,
1384
                                                    const MapMode& rMapMode ) const
1385
0
{
1386
0
    basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1387
0
    const basegfx::B2DHomMatrix aTransformationMatrix = GetInverseViewTransformation( rMapMode );
1388
0
    aTransformedPoly.transform( aTransformationMatrix );
1389
0
    return aTransformedPoly;
1390
0
}
1391
1392
#define ENTER1( rSource, pMapModeSource, pMapModeDest )                 \
1393
9.80k
    if ( !pMapModeSource )                                              \
1394
9.80k
        pMapModeSource = &maMapMode;                                    \
1395
9.80k
    if ( !pMapModeDest )                                                \
1396
9.80k
        pMapModeDest = &maMapMode;                                      \
1397
9.80k
    if ( *pMapModeSource == *pMapModeDest )                             \
1398
9.80k
        return rSource;                                                 \
1399
9.80k
                                                                        \
1400
9.80k
    ImplMapRes aMapResSource;                                           \
1401
9.80k
    ImplMapRes aMapResDest;                                             \
1402
9.80k
                                                                        \
1403
9.80k
    if ( !mbMap || pMapModeSource != &maMapMode )                       \
1404
9.80k
    {                                                                   \
1405
9.66k
        if ( pMapModeSource->GetMapUnit() == MapUnit::MapRelative )     \
1406
9.66k
            aMapResSource = maMapRes;                                   \
1407
9.66k
        ImplCalcMapResolution( *pMapModeSource,                         \
1408
9.66k
                               mnDPIX, mnDPIY, aMapResSource );         \
1409
9.66k
    }                                                                   \
1410
9.80k
    else                                                                \
1411
9.80k
        aMapResSource = maMapRes;                                       \
1412
9.80k
    if ( !mbMap || pMapModeDest != &maMapMode )                         \
1413
9.80k
    {                                                                   \
1414
9.80k
        if ( pMapModeDest->GetMapUnit() == MapUnit::MapRelative )               \
1415
9.80k
            aMapResDest = maMapRes;                                     \
1416
9.80k
        ImplCalcMapResolution( *pMapModeDest,                           \
1417
9.80k
                               mnDPIX, mnDPIY, aMapResDest );           \
1418
9.80k
    }                                                                   \
1419
9.80k
    else                                                                \
1420
9.80k
        aMapResDest = maMapRes
1421
1422
static void verifyUnitSourceDest( MapUnit eUnitSource, MapUnit eUnitDest )
1423
1.58M
{
1424
1.58M
    DBG_ASSERT( eUnitSource != MapUnit::MapSysFont
1425
1.58M
                && eUnitSource != MapUnit::MapAppFont
1426
1.58M
                && eUnitSource != MapUnit::MapRelative,
1427
1.58M
                "Source MapUnit is not permitted" );
1428
1.58M
    DBG_ASSERT( eUnitDest != MapUnit::MapSysFont
1429
1.58M
                && eUnitDest != MapUnit::MapAppFont
1430
1.58M
                && eUnitDest != MapUnit::MapRelative,
1431
1.58M
                "Destination MapUnit is not permitted" );
1432
1.58M
}
1433
1434
namespace
1435
{
1436
auto getCorrectedUnit(MapUnit eMapSrc, MapUnit eMapDst)
1437
851k
{
1438
851k
    o3tl::Length eSrc = o3tl::Length::invalid;
1439
851k
    o3tl::Length eDst = o3tl::Length::invalid;
1440
851k
    if (eMapSrc > MapUnit::MapPixel)
1441
851k
        SAL_WARN("vcl.gdi", "Invalid source map unit");
1442
851k
    else if (eMapDst > MapUnit::MapPixel)
1443
851k
        SAL_WARN("vcl.gdi", "Invalid destination map unit");
1444
851k
    else if (eMapSrc != eMapDst)
1445
851k
    {
1446
        // Here 72 PPI is assumed for MapPixel
1447
851k
        eSrc = MapToO3tlLength(eMapSrc, o3tl::Length::pt);
1448
851k
        eDst = MapToO3tlLength(eMapDst, o3tl::Length::pt);
1449
851k
    }
1450
851k
    return std::make_pair(eSrc, eDst);
1451
851k
}
1452
1453
std::pair<ImplMapRes, ImplMapRes> ENTER4(const MapMode& rMMSource, const MapMode& rMMDest)
1454
734k
{
1455
734k
    std::pair<ImplMapRes, ImplMapRes> result;
1456
734k
    ImplCalcMapResolution(rMMSource, 72, 72, result.first);
1457
734k
    ImplCalcMapResolution(rMMDest, 72, 72, result.second);
1458
734k
    return result;
1459
734k
}
1460
}
1461
1462
// return (n1 * n2 * n3) / (n4 * n5)
1463
static tools::Long fn5( const tools::Long n1,
1464
                 const tools::Long n2,
1465
                 const tools::Long n3,
1466
                 const tools::Long n4,
1467
                 const tools::Long n5 )
1468
1.48M
{
1469
1.48M
    if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1470
11.7k
        return 0;
1471
1.47M
    if (std::numeric_limits<tools::Long>::max() / std::abs(n2) < std::abs(n3))
1472
0
    {
1473
        // a6 is skipped
1474
0
        BigInt a7 = n2;
1475
0
        a7 *= n3;
1476
0
        a7 *= n1;
1477
1478
0
        if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1479
0
        {
1480
0
            BigInt a8 = n4;
1481
0
            a8 *= n5;
1482
1483
0
            BigInt a9 = a8;
1484
0
            a9 /= 2;
1485
0
            if ( a7.IsNeg() )
1486
0
                a7 -= a9;
1487
0
            else
1488
0
                a7 += a9;
1489
1490
0
            a7 /= a8;
1491
0
        } // of if
1492
0
        else
1493
0
        {
1494
0
            tools::Long n8 = n4 * n5;
1495
1496
0
            if ( a7.IsNeg() )
1497
0
                a7 -= n8 / 2;
1498
0
            else
1499
0
                a7 += n8 / 2;
1500
1501
0
            a7 /= n8;
1502
0
        } // of else
1503
0
        return static_cast<tools::Long>(a7);
1504
0
    } // of if
1505
1.47M
    else
1506
1.47M
    {
1507
1.47M
        tools::Long n6 = n2 * n3;
1508
1509
1.47M
        if (std::numeric_limits<tools::Long>::max() / std::abs(n1) < std::abs(n6))
1510
0
        {
1511
0
            BigInt a7 = n1;
1512
0
            a7 *= n6;
1513
1514
0
            if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1515
0
            {
1516
0
                BigInt a8 = n4;
1517
0
                a8 *= n5;
1518
1519
0
                BigInt a9 = a8;
1520
0
                a9 /= 2;
1521
0
                if ( a7.IsNeg() )
1522
0
                    a7 -= a9;
1523
0
                else
1524
0
                    a7 += a9;
1525
1526
0
                a7 /= a8;
1527
0
            } // of if
1528
0
            else
1529
0
            {
1530
0
                tools::Long n8 = n4 * n5;
1531
1532
0
                if ( a7.IsNeg() )
1533
0
                    a7 -= n8 / 2;
1534
0
                else
1535
0
                    a7 += n8 / 2;
1536
1537
0
                a7 /= n8;
1538
0
            } // of else
1539
0
            return static_cast<tools::Long>(a7);
1540
0
        } // of if
1541
1.47M
        else
1542
1.47M
        {
1543
1.47M
            tools::Long n7 = n1 * n6;
1544
1545
1.47M
            if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1546
0
            {
1547
0
                BigInt a7 = n7;
1548
0
                BigInt a8 = n4;
1549
0
                a8 *= n5;
1550
1551
0
                BigInt a9 = a8;
1552
0
                a9 /= 2;
1553
0
                if ( a7.IsNeg() )
1554
0
                    a7 -= a9;
1555
0
                else
1556
0
                    a7 += a9;
1557
1558
0
                a7 /= a8;
1559
0
                return static_cast<tools::Long>(a7);
1560
0
            } // of if
1561
1.47M
            else
1562
1.47M
            {
1563
1.47M
                const tools::Long n8 = n4 * n5;
1564
1.47M
                const tools::Long n8_2 = n8 / 2;
1565
1566
1.47M
                if( n7 < 0 )
1567
38
                {
1568
38
                    if ((n7 - std::numeric_limits<tools::Long>::min()) >= n8_2)
1569
38
                        n7 -= n8_2;
1570
38
                }
1571
1.47M
                else if ((std::numeric_limits<tools::Long>::max() - n7) >= n8_2)
1572
1.47M
                    n7 += n8_2;
1573
1574
1.47M
                return n7 / n8;
1575
1.47M
            } // of else
1576
1.47M
        } // of else
1577
1.47M
    } // of else
1578
1.47M
}
1579
1580
static tools::Long fn3(const tools::Long n1, const o3tl::Length eFrom, const o3tl::Length eTo)
1581
1.25M
{
1582
1.25M
    if (n1 == 0 || eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid)
1583
141k
        return 0;
1584
1.11M
    bool bOverflow;
1585
1.11M
    const auto nResult = o3tl::convert(n1, eFrom, eTo, bOverflow);
1586
1.11M
    if (bOverflow)
1587
1
    {
1588
1
        const auto [n2, n3] = o3tl::getConversionMulDiv(eFrom, eTo);
1589
1
        BigInt a4 = n1;
1590
1
        a4 *= n2;
1591
1592
1
        if ( a4.IsNeg() )
1593
0
            a4 -= n3 / 2;
1594
1
        else
1595
1
            a4 += n3 / 2;
1596
1597
1
        a4 /= n3;
1598
1
        return static_cast<tools::Long>(a4);
1599
1
    } // of if
1600
1.11M
    else
1601
1.11M
        return nResult;
1602
1.11M
}
1603
1604
Point OutputDevice::LogicToLogic( const Point& rPtSource,
1605
                                  const MapMode* pMapModeSource,
1606
                                  const MapMode* pMapModeDest ) const
1607
139
{
1608
139
    ENTER1( rPtSource, pMapModeSource, pMapModeDest );
1609
1610
139
    return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1611
139
                       aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1612
139
                       aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1613
139
                  aMapResDest.mnMapOfsX,
1614
139
                  fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1615
139
                       aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1616
139
                       aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1617
139
                  aMapResDest.mnMapOfsY );
1618
139
}
1619
1620
Size OutputDevice::LogicToLogic( const Size& rSzSource,
1621
                                 const MapMode* pMapModeSource,
1622
                                 const MapMode* pMapModeDest ) const
1623
9.66k
{
1624
9.66k
    ENTER1( rSzSource, pMapModeSource, pMapModeDest );
1625
1626
9.66k
    return Size( fn5( rSzSource.Width(),
1627
9.66k
                      aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1628
9.66k
                      aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1629
9.66k
                 fn5( rSzSource.Height(),
1630
9.66k
                      aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1631
9.66k
                      aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1632
9.66k
}
1633
1634
tools::Rectangle OutputDevice::LogicToLogic( const tools::Rectangle& rRectSource,
1635
                                      const MapMode* pMapModeSource,
1636
                                      const MapMode* pMapModeDest ) const
1637
0
{
1638
0
    ENTER1( rRectSource, pMapModeSource, pMapModeDest );
1639
1640
0
    return tools::Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1641
0
                           aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1642
0
                           aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1643
0
                      aMapResDest.mnMapOfsX,
1644
0
                      fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1645
0
                           aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1646
0
                           aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1647
0
                      aMapResDest.mnMapOfsY,
1648
0
                      fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1649
0
                           aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1650
0
                           aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1651
0
                      aMapResDest.mnMapOfsX,
1652
0
                      fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1653
0
                           aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1654
0
                           aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1655
0
                      aMapResDest.mnMapOfsY );
1656
0
}
1657
1658
Point OutputDevice::LogicToLogic( const Point& rPtSource,
1659
                                  const MapMode& rMapModeSource,
1660
                                  const MapMode& rMapModeDest )
1661
362k
{
1662
362k
    if ( rMapModeSource == rMapModeDest )
1663
0
        return rPtSource;
1664
1665
362k
    MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1666
362k
    MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
1667
362k
    verifyUnitSourceDest( eUnitSource, eUnitDest );
1668
1669
362k
    if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1670
0
    {
1671
0
        const auto [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1672
0
        return Point(fn3(rPtSource.X(), eFrom, eTo), fn3(rPtSource.Y(), eFrom, eTo));
1673
0
    }
1674
362k
    else
1675
362k
    {
1676
362k
        const auto [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1677
1678
362k
        return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1679
362k
                           aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1680
362k
                           aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1681
362k
                      aMapResDest.mnMapOfsX,
1682
362k
                      fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1683
362k
                           aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1684
362k
                           aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1685
362k
                      aMapResDest.mnMapOfsY );
1686
362k
    }
1687
362k
}
1688
1689
Size OutputDevice::LogicToLogic( const Size& rSzSource,
1690
                                 const MapMode& rMapModeSource,
1691
                                 const MapMode& rMapModeDest )
1692
3.01M
{
1693
3.01M
    if ( rMapModeSource == rMapModeDest )
1694
2.18M
        return rSzSource;
1695
1696
826k
    MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1697
826k
    MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
1698
826k
    verifyUnitSourceDest( eUnitSource, eUnitDest );
1699
1700
826k
    if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1701
453k
    {
1702
453k
        const auto [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1703
453k
        return Size(fn3(rSzSource.Width(), eFrom, eTo), fn3(rSzSource.Height(), eFrom, eTo));
1704
453k
    }
1705
372k
    else
1706
372k
    {
1707
372k
        const auto [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1708
1709
372k
        return Size( fn5( rSzSource.Width(),
1710
372k
                          aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1711
372k
                          aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1712
372k
                     fn5( rSzSource.Height(),
1713
372k
                          aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1714
372k
                          aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1715
372k
    }
1716
826k
}
1717
1718
basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource,
1719
                                                const MapMode& rMapModeSource,
1720
                                                const MapMode& rMapModeDest )
1721
121k
{
1722
121k
    if(rMapModeSource == rMapModeDest)
1723
60.7k
    {
1724
60.7k
        return rPolySource;
1725
60.7k
    }
1726
1727
60.5k
    const basegfx::B2DHomMatrix aTransform(LogicToLogic(rMapModeSource, rMapModeDest));
1728
60.5k
    basegfx::B2DPolygon aPoly(rPolySource);
1729
1730
60.5k
    aPoly.transform(aTransform);
1731
60.5k
    return aPoly;
1732
121k
}
1733
1734
basegfx::B2DHomMatrix OutputDevice::LogicToLogic(const MapMode& rMapModeSource, const MapMode& rMapModeDest)
1735
60.7k
{
1736
60.7k
    basegfx::B2DHomMatrix aTransform;
1737
1738
60.7k
    if(rMapModeSource == rMapModeDest)
1739
0
    {
1740
0
        return aTransform;
1741
0
    }
1742
1743
60.7k
    MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1744
60.7k
    MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
1745
60.7k
    verifyUnitSourceDest(eUnitSource, eUnitDest);
1746
1747
60.7k
    if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1748
60.7k
    {
1749
60.7k
        const auto [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1750
60.7k
        const double fScaleFactor(eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid
1751
60.7k
                                      ? std::numeric_limits<double>::quiet_NaN()
1752
60.7k
                                      : o3tl::convert(1.0, eFrom, eTo));
1753
60.7k
        aTransform.set(0, 0, fScaleFactor);
1754
60.7k
        aTransform.set(1, 1, fScaleFactor);
1755
60.7k
    }
1756
0
    else
1757
0
    {
1758
0
        const auto [aMapResSource, aMapResDest] = ENTER4(rMapModeSource, rMapModeDest);
1759
1760
0
        const double fScaleFactorX((double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX)) / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)));
1761
0
        const double fScaleFactorY((double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY)) / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)));
1762
0
        const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
1763
0
        const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
1764
1765
0
        aTransform.set(0, 0, fScaleFactorX);
1766
0
        aTransform.set(1, 1, fScaleFactorY);
1767
0
        aTransform.set(0, 2, fZeroPointX);
1768
0
        aTransform.set(1, 2, fZeroPointY);
1769
0
    }
1770
1771
60.7k
    return aTransform;
1772
60.7k
}
1773
1774
tools::Rectangle OutputDevice::LogicToLogic( const tools::Rectangle& rRectSource,
1775
                                      const MapMode& rMapModeSource,
1776
                                      const MapMode& rMapModeDest )
1777
12.8k
{
1778
12.8k
    if ( rMapModeSource == rMapModeDest )
1779
6.86k
        return rRectSource;
1780
1781
5.96k
    MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1782
5.96k
    MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
1783
5.96k
    verifyUnitSourceDest( eUnitSource, eUnitDest );
1784
1785
5.96k
    tools::Rectangle aRetval;
1786
1787
5.96k
    if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1788
5.96k
    {
1789
5.96k
        const auto [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1790
1791
5.96k
        auto left = fn3(rRectSource.Left(), eFrom, eTo);
1792
5.96k
        auto top = fn3(rRectSource.Top(), eFrom, eTo);
1793
1794
        // tdf#141761 see comments above, IsEmpty() removed
1795
5.96k
        auto right = rRectSource.IsWidthEmpty() ? 0 : fn3(rRectSource.Right(), eFrom, eTo);
1796
5.96k
        auto bottom = rRectSource.IsHeightEmpty() ? 0 : fn3(rRectSource.Bottom(), eFrom, eTo);
1797
1798
5.96k
        aRetval = tools::Rectangle(left, top, right, bottom);
1799
5.96k
    }
1800
0
    else
1801
0
    {
1802
0
        const auto [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1803
1804
0
        auto left = fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1805
0
                               aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1806
0
                               aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1807
0
                          aMapResDest.mnMapOfsX;
1808
0
        auto top = fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1809
0
                               aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1810
0
                               aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1811
0
                          aMapResDest.mnMapOfsY;
1812
1813
        // tdf#141761 see comments above, IsEmpty() removed
1814
0
        auto right = rRectSource.IsWidthEmpty() ? 0 : fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1815
0
                               aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1816
0
                               aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1817
0
                          aMapResDest.mnMapOfsX;
1818
0
        auto bottom = rRectSource.IsHeightEmpty() ? 0 : fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1819
0
                               aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1820
0
                               aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1821
0
                          aMapResDest.mnMapOfsY;
1822
1823
0
        aRetval = tools::Rectangle(left, top, right, bottom);
1824
0
    }
1825
1826
5.96k
    if(rRectSource.IsWidthEmpty())
1827
1.62k
        aRetval.SetWidthEmpty();
1828
1829
5.96k
    if(rRectSource.IsHeightEmpty())
1830
1.40k
        aRetval.SetHeightEmpty();
1831
1832
5.96k
    return aRetval;
1833
12.8k
}
1834
1835
tools::Long OutputDevice::LogicToLogic( tools::Long nLongSource,
1836
                                 MapUnit eUnitSource, MapUnit eUnitDest )
1837
330k
{
1838
330k
    if ( eUnitSource == eUnitDest )
1839
0
        return nLongSource;
1840
1841
330k
    verifyUnitSourceDest( eUnitSource, eUnitDest );
1842
330k
    const auto [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1843
330k
    return fn3(nLongSource, eFrom, eTo);
1844
330k
}
1845
1846
void OutputDevice::SetPixelOffset( const Size& rOffset )
1847
1.65k
{
1848
1.65k
    mnOutOffOrigX  = rOffset.Width();
1849
1.65k
    mnOutOffOrigY  = rOffset.Height();
1850
1851
1.65k
    mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
1852
1.65k
                                       maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX );
1853
1.65k
    mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
1854
1.65k
                                       maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY );
1855
1.65k
}
1856
1857
1858
double OutputDevice::ImplLogicWidthToDeviceSubPixel(tools::Long nWidth) const
1859
8.13M
{
1860
8.13M
    if (!mbMap)
1861
1.00k
        return nWidth;
1862
1863
8.13M
    return ImplLogicToSubPixel(nWidth, mnDPIX,
1864
8.13M
                               maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
1865
8.13M
}
1866
1867
double OutputDevice::ImplLogicHeightToDeviceSubPixel(tools::Long nHeight) const
1868
13.6M
{
1869
13.6M
    if (!mbMap)
1870
163k
        return nHeight;
1871
1872
13.5M
    return ImplLogicToSubPixel(nHeight, mnDPIY,
1873
13.5M
                               maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY);
1874
13.6M
}
1875
1876
basegfx::B2DPoint OutputDevice::ImplLogicToDeviceSubPixel(const Point& rPoint) const
1877
17.4M
{
1878
17.4M
    if (!mbMap)
1879
0
        return basegfx::B2DPoint(rPoint.X() + mnOutOffX, rPoint.Y() + mnOutOffY);
1880
1881
17.4M
    return basegfx::B2DPoint(ImplLogicToSubPixel(rPoint.X() + maMapRes.mnMapOfsX, mnDPIX,
1882
17.4M
                                           maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX)
1883
17.4M
                                           + mnOutOffX + mnOutOffOrigX,
1884
17.4M
                       ImplLogicToSubPixel(rPoint.Y() + maMapRes.mnMapOfsY, mnDPIY,
1885
17.4M
                                           maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY)
1886
17.4M
                                           + mnOutOffY + mnOutOffOrigY);
1887
17.4M
}
1888
1889
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */