Avoid potential negative array index access to cached text.
[LibreOffice.git] / vcl / quartz / salgdicommon.cxx
blob98ff40a7dc54d56219c27f8bf357ab0431b60407
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <cassert>
24 #include <cstring>
25 #include <numeric>
27 #include <basegfx/polygon/b2dpolygon.hxx>
28 #include <basegfx/polygon/b2dpolygontools.hxx>
29 #include <basegfx/polygon/b2dpolypolygontools.hxx>
30 #include <osl/endian.h>
31 #include <osl/file.hxx>
32 #include <sal/types.h>
33 #include <tools/long.hxx>
34 #include <vcl/sysdata.hxx>
36 #include <quartz/salbmp.h>
37 #ifdef MACOSX
38 #include <quartz/salgdi.h>
39 #endif
40 #include <quartz/utils.h>
41 #ifdef IOS
42 #include <svdata.hxx>
43 #endif
45 using namespace vcl;
47 #ifndef IOS
49 void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
51 if (!rGraphics.mnRealDPIY && rGraphics.maShared.mbWindow && rGraphics.maShared.mpFrame)
53 rGraphics.initResolution(rGraphics.maShared.mpFrame->getNSWindow());
55 mnRealDPIX = rGraphics.mnRealDPIX;
56 mnRealDPIY = rGraphics.mnRealDPIY;
59 #endif
61 SystemGraphicsData AquaSalGraphics::GetGraphicsData() const
63 SystemGraphicsData aRes;
64 aRes.nSize = sizeof(aRes);
65 aRes.rCGContext = maShared.maContextHolder.get();
66 return aRes;
69 #ifndef IOS
71 void AquaSalGraphics::initResolution(NSWindow* nsWindow)
73 if (!nsWindow)
75 if (Application::IsBitmapRendering())
76 mnRealDPIX = mnRealDPIY = 96;
77 return;
80 // #i100617# read DPI only once; there is some kind of weird caching going on
81 // if the main screen changes
82 // FIXME: this is really unfortunate and needs to be investigated
84 SalData* pSalData = GetSalData();
85 if( pSalData->mnDPIX == 0 || pSalData->mnDPIY == 0 )
87 NSScreen* pScreen = nil;
89 /* #i91301#
90 many woes went into the try to have different resolutions
91 on different screens. The result of these trials is that OOo is not ready
92 for that yet, vcl and applications would need to be adapted.
94 Unfortunately this is not possible in the 3.0 timeframe.
95 So let's stay with one resolution for all Windows and VirtualDevices
96 which is the resolution of the main screen
98 This of course also means that measurements are exact only on the main screen.
99 For activating different resolutions again just comment out the two lines below.
101 if( pWin )
102 pScreen = [pWin screen];
104 if( pScreen == nil )
106 NSArray* pScreens = [NSScreen screens];
107 if( pScreens && [pScreens count] > 0)
109 pScreen = [pScreens objectAtIndex: 0];
113 mnRealDPIX = mnRealDPIY = 96;
114 if( pScreen )
116 NSDictionary* pDev = [pScreen deviceDescription];
117 if( pDev )
119 NSNumber* pVal = [pDev objectForKey: @"NSScreenNumber"];
120 if( pVal )
122 // FIXME: casting a long to CGDirectDisplayID is evil, but
123 // Apple suggest to do it this way
124 const CGDirectDisplayID nDisplayID = static_cast<CGDirectDisplayID>([pVal longValue]);
125 const CGSize aSize = CGDisplayScreenSize( nDisplayID ); // => result is in millimeters
126 mnRealDPIX = static_cast<sal_Int32>((CGDisplayPixelsWide( nDisplayID ) * 25.4) / aSize.width);
127 mnRealDPIY = static_cast<sal_Int32>((CGDisplayPixelsHigh( nDisplayID ) * 25.4) / aSize.height);
129 else
131 OSL_FAIL( "no resolution found in device description" );
134 else
136 OSL_FAIL( "no device description" );
139 else
141 OSL_FAIL( "no screen found" );
144 // #i107076# maintaining size-WYSIWYG-ness causes many problems for
145 // low-DPI, high-DPI or for mis-reporting devices
146 // => it is better to limit the calculation result then
147 static const int nMinDPI = 72;
148 if( (mnRealDPIX < nMinDPI) || (mnRealDPIY < nMinDPI) )
150 mnRealDPIX = mnRealDPIY = nMinDPI;
152 // Note that on a Retina display, the "mnRealDPIX" as
153 // calculated above is not the true resolution of the display,
154 // but the "logical" one, or whatever the correct terminology
155 // is. (For instance on a 5K 27in iMac, it's 108.) So at
156 // least currently, it won't be over 200. I don't know whether
157 // this test is a "sanity check", or whether there is some
158 // real reason to limit this to 200.
159 static const int nMaxDPI = 200;
160 if( (mnRealDPIX > nMaxDPI) || (mnRealDPIY > nMaxDPI) )
162 mnRealDPIX = mnRealDPIY = nMaxDPI;
164 // for OSX any anisotropy reported for the display resolution is best ignored (e.g. TripleHead2Go)
165 mnRealDPIX = mnRealDPIY = (mnRealDPIX + mnRealDPIY + 1) / 2;
167 pSalData->mnDPIX = mnRealDPIX;
168 pSalData->mnDPIY = mnRealDPIY;
170 else
172 mnRealDPIX = pSalData->mnDPIX;
173 mnRealDPIY = pSalData->mnDPIY;
177 #endif
179 void AquaSharedAttributes::setState()
181 maContextHolder.restoreState();
182 maContextHolder.saveState();
184 // setup clipping
185 if (mxClipPath)
187 CGContextBeginPath(maContextHolder.get()); // discard any existing path
188 CGContextAddPath(maContextHolder.get(), mxClipPath); // set the current path to the clipping path
189 CGContextClip(maContextHolder.get()); // use it for clipping
192 // set RGB colorspace and line and fill colors
193 CGContextSetFillColor(maContextHolder.get(), maFillColor.AsArray() );
195 CGContextSetStrokeColor(maContextHolder.get(), maLineColor.AsArray() );
196 CGContextSetShouldAntialias(maContextHolder.get(), false );
197 if (mnXorMode == 2)
199 CGContextSetBlendMode(maContextHolder.get(), kCGBlendModeDifference );
203 #ifndef IOS
205 void AquaSalGraphics::updateResolution()
207 SAL_WARN_IF(!maShared.mbWindow, "vcl", "updateResolution on inappropriate graphics");
209 initResolution((maShared.mbWindow && maShared.mpFrame) ? maShared.mpFrame->getNSWindow() : nil);
212 #endif
214 XorEmulation::XorEmulation()
215 : m_xTargetLayer( nullptr )
216 , m_xTargetContext( nullptr )
217 , m_xMaskContext( nullptr )
218 , m_xTempContext( nullptr )
219 , m_pMaskBuffer( nullptr )
220 , m_pTempBuffer( nullptr )
221 , m_nBufferLongs( 0 )
222 , m_bIsEnabled( false )
224 SAL_INFO( "vcl.quartz", "XorEmulation::XorEmulation() this=" << this );
227 XorEmulation::~XorEmulation()
229 SAL_INFO( "vcl.quartz", "XorEmulation::~XorEmulation() this=" << this );
230 Disable();
231 SetTarget( 0, 0, 0, nullptr, nullptr );
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */