Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx
Warning:line 207, column 9
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name window2.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx

/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx

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 <limits.h>
21
22#include <o3tl/float_int_conversion.hxx>
23#include <sal/log.hxx>
24
25#include <vcl/toolkit/dialog.hxx>
26#include <vcl/event.hxx>
27#include <vcl/toolkit/fixed.hxx>
28#include <vcl/layout.hxx>
29#include <vcl/timer.hxx>
30#include <vcl/window.hxx>
31#include <vcl/scrbar.hxx>
32#include <vcl/dockwin.hxx>
33#include <vcl/settings.hxx>
34#include <vcl/builder.hxx>
35
36#include <window.h>
37#include <svdata.hxx>
38#include <salgdi.hxx>
39#include <salframe.hxx>
40#include <scrwnd.hxx>
41
42#include <com/sun/star/accessibility/AccessibleRelation.hpp>
43#include <com/sun/star/accessibility/AccessibleRole.hpp>
44
45using namespace com::sun::star;
46
47namespace vcl {
48
49void Window::ShowFocus( const tools::Rectangle& rRect )
50{
51 if( mpWindowImpl->mbInShowFocus )
52 return;
53 mpWindowImpl->mbInShowFocus = true;
54
55 ImplWinData* pWinData = ImplGetWinData();
56
57 // native themeing suggest not to use focus rects
58 if( ! ( mpWindowImpl->mbUseNativeFocus &&
59 IsNativeWidgetEnabled() ) )
60 {
61 if ( !mpWindowImpl->mbInPaint )
62 {
63 if ( mpWindowImpl->mbFocusVisible )
64 {
65 if ( *pWinData->mpFocusRect == rRect )
66 {
67 mpWindowImpl->mbInShowFocus = false;
68 return;
69 }
70
71 ImplInvertFocus( *pWinData->mpFocusRect );
72 }
73
74 ImplInvertFocus( rRect );
75 }
76 pWinData->mpFocusRect = rRect;
77 mpWindowImpl->mbFocusVisible = true;
78 }
79 else
80 {
81 if( ! mpWindowImpl->mbNativeFocusVisible )
82 {
83 mpWindowImpl->mbNativeFocusVisible = true;
84 if ( !mpWindowImpl->mbInPaint )
85 Invalidate();
86 }
87 }
88 mpWindowImpl->mbInShowFocus = false;
89}
90
91void Window::HideFocus()
92{
93
94 if( mpWindowImpl->mbInHideFocus )
95 return;
96 mpWindowImpl->mbInHideFocus = true;
97
98 // native themeing can suggest not to use focus rects
99 if( ! ( mpWindowImpl->mbUseNativeFocus &&
100 IsNativeWidgetEnabled() ) )
101 {
102 if ( !mpWindowImpl->mbFocusVisible )
103 {
104 mpWindowImpl->mbInHideFocus = false;
105 return;
106 }
107
108 if ( !mpWindowImpl->mbInPaint )
109 ImplInvertFocus( *ImplGetWinData()->mpFocusRect );
110 mpWindowImpl->mbFocusVisible = false;
111 }
112 else
113 {
114 if( mpWindowImpl->mbNativeFocusVisible )
115 {
116 mpWindowImpl->mbNativeFocusVisible = false;
117 if ( !mpWindowImpl->mbInPaint )
118 Invalidate();
119 }
120 }
121 mpWindowImpl->mbInHideFocus = false;
122}
123
124void Window::ShowTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
125{
126 ImplWinData* pWinData = ImplGetWinData();
127
128 if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
129 {
130 if ( mpWindowImpl->mbTrackVisible )
131 {
132 if ( (*pWinData->mpTrackRect == rRect) &&
133 (pWinData->mnTrackFlags == nFlags) )
134 return;
135
136 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
137 }
138
139 InvertTracking( rRect, nFlags );
140 }
141
142 pWinData->mpTrackRect = rRect;
143 pWinData->mnTrackFlags = nFlags;
144 mpWindowImpl->mbTrackVisible = true;
145}
146
147void Window::HideTracking()
148{
149 if ( mpWindowImpl->mbTrackVisible )
1
Assuming field 'mbTrackVisible' is true
2
Taking true branch
150 {
151 ImplWinData* pWinData = ImplGetWinData();
152 if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
3
Assuming field 'mbInPaint' is false
4
Taking true branch
153 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
5
Calling 'Window::InvertTracking'
154 mpWindowImpl->mbTrackVisible = false;
155 }
156}
157
158void Window::InvertTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
159{
160 OutputDevice *pOutDev = GetOutDev();
6
Value assigned to field 'mpGraphics'
161 tools::Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
162
163 if ( aRect.IsEmpty() )
7
Calling 'Rectangle::IsEmpty'
11
Returning from 'Rectangle::IsEmpty'
12
Taking false branch
164 return;
165 aRect.Justify();
166
167 SalGraphics* pGraphics;
168
169 if ( nFlags & ShowTrackFlags::TrackWindow )
13
Calling 'Wrap::operator bool'
16
Returning from 'Wrap::operator bool'
17
Taking true branch
170 {
171 if ( !IsDeviceOutputNecessary() )
18
Calling 'OutputDevice::IsDeviceOutputNecessary'
21
Returning from 'OutputDevice::IsDeviceOutputNecessary'
22
Assuming the condition is false
23
Taking false branch
172 return;
173
174 // we need a graphics
175 if ( !mpGraphics )
24
Assuming field 'mpGraphics' is null
25
Taking true branch
176 {
177 if ( !pOutDev->AcquireGraphics() )
26
Assuming the condition is false
27
Taking false branch
178 return;
179 }
180
181 if ( mbInitClipRegion )
28
Assuming field 'mbInitClipRegion' is false
29
Taking false branch
182 InitClipRegion();
183
184 if ( mbOutputClipped )
30
Assuming field 'mbOutputClipped' is false
31
Taking false branch
185 return;
186
187 pGraphics = mpGraphics;
32
Null pointer value stored to 'pGraphics'
188 }
189 else
190 {
191 pGraphics = ImplGetFrameGraphics();
192
193 if ( nFlags & ShowTrackFlags::Clip )
194 {
195 Point aPoint( mnOutOffX, mnOutOffY );
196 vcl::Region aRegion( tools::Rectangle( aPoint,
197 Size( mnOutWidth, mnOutHeight ) ) );
198 ImplClipBoundaries( aRegion, false, false );
199 pOutDev->SelectClipRegion( aRegion, pGraphics );
200 }
201 }
202
203 ShowTrackFlags nStyle = nFlags & ShowTrackFlags::StyleMask;
204 if ( nStyle == ShowTrackFlags::Object )
33
Assuming 'nStyle' is not equal to Object
34
Taking false branch
205 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::TrackFrame, this );
206 else if ( nStyle == ShowTrackFlags::Split )
35
Assuming 'nStyle' is equal to Split
36
Taking true branch
207 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, this );
37
Called C++ object pointer is null
208 else
209 {
210 long nBorder = 1;
211 if ( nStyle == ShowTrackFlags::Big )
212 nBorder = 5;
213 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SalInvert::N50, this );
214 pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, this );
215 pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
216 pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
217 }
218}
219
220IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )void Window::LinkStubImplTrackTimerHdl(void * instance, Timer
* data) { return static_cast<Window *>(instance)->ImplTrackTimerHdl
(data); } void Window::ImplTrackTimerHdl(Timer* pTimer)
221{
222 ImplSVData* pSVData = ImplGetSVData();
223
224 // if Button-Repeat we have to change the timeout
225 if ( pSVData->mpWinData->mnTrackFlags & StartTrackingFlags::ButtonRepeat )
226 pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
227
228 // create Tracking-Event
229 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
230 if( ImplIsAntiparallel() )
231 {
232 // re-mirror frame pos at pChild
233 const OutputDevice *pOutDev = GetOutDev();
234 pOutDev->ReMirror( aMousePos );
235 }
236 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
237 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
238 mpWindowImpl->mpFrameData->mnMouseCode,
239 mpWindowImpl->mpFrameData->mnMouseCode );
240 TrackingEvent aTEvt( aMEvt, TrackingEventFlags::Repeat );
241 Tracking( aTEvt );
242}
243
244void Window::StartTracking( StartTrackingFlags nFlags )
245{
246 ImplSVData* pSVData = ImplGetSVData();
247
248 if ( pSVData->mpWinData->mpTrackWin.get() != this )
249 {
250 if ( pSVData->mpWinData->mpTrackWin )
251 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
252 }
253
254 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
255 {
256 pSVData->mpWinData->mpTrackTimer = new AutoTimer;
257
258 if ( nFlags & StartTrackingFlags::ScrollRepeat )
259 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260 else
261 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262 pSVData->mpWinData->mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl )::tools::detail::makeLink( ::tools::detail::castTo<Window *
>(this), &Window::LinkStubImplTrackTimerHdl)
);
263 pSVData->mpWinData->mpTrackTimer->SetDebugName( "vcl::Window pSVData->mpWinData->mpTrackTimer" );
264 pSVData->mpWinData->mpTrackTimer->Start();
265 }
266
267 pSVData->mpWinData->mpTrackWin = this;
268 pSVData->mpWinData->mnTrackFlags = nFlags;
269 CaptureMouse();
270}
271
272void Window::EndTracking( TrackingEventFlags nFlags )
273{
274 ImplSVData* pSVData = ImplGetSVData();
275
276 if ( pSVData->mpWinData->mpTrackWin.get() != this )
277 return;
278
279 if ( pSVData->mpWinData->mpTrackTimer )
280 {
281 delete pSVData->mpWinData->mpTrackTimer;
282 pSVData->mpWinData->mpTrackTimer = nullptr;
283 }
284
285 pSVData->mpWinData->mpTrackWin = nullptr;
286 pSVData->mpWinData->mnTrackFlags = StartTrackingFlags::NONE;
287 ReleaseMouse();
288
289 // call EndTracking if required
290 {
291 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
292 if( ImplIsAntiparallel() )
293 {
294 // re-mirror frame pos at pChild
295 const OutputDevice *pOutDev = GetOutDev();
296 pOutDev->ReMirror( aMousePos );
297 }
298
299 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
300 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
301 mpWindowImpl->mpFrameData->mnMouseCode,
302 mpWindowImpl->mpFrameData->mnMouseCode );
303 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
304 // CompatTracking effectively
305 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
306 return Window::Tracking( aTEvt );
307 else
308 return Tracking( aTEvt );
309 }
310}
311
312bool Window::IsTracking() const
313{
314 return (ImplGetSVData()->mpWinData->mpTrackWin == this);
315}
316
317void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
318{
319 ImplSVData* pSVData = ImplGetSVData();
320
321 if ( pSVData->mpWinData->mpAutoScrollWin.get() != this )
322 {
323 if ( pSVData->mpWinData->mpAutoScrollWin )
324 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
325 }
326
327 pSVData->mpWinData->mpAutoScrollWin = this;
328 pSVData->mpWinData->mnAutoScrollFlags = nFlags;
329 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
330}
331
332void Window::EndAutoScroll()
333{
334 ImplSVData* pSVData = ImplGetSVData();
335
336 if ( pSVData->mpWinData->mpAutoScrollWin.get() == this )
337 {
338 pSVData->mpWinData->mpAutoScrollWin = nullptr;
339 pSVData->mpWinData->mnAutoScrollFlags = StartAutoScrollFlags::NONE;
340 pSVData->maAppData.mpWheelWindow->ImplStop();
341 pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
342 pSVData->maAppData.mpWheelWindow.disposeAndClear();
343 }
344}
345
346VclPtr<vcl::Window> Window::SaveFocus()
347{
348 ImplSVData* pSVData = ImplGetSVData();
349 if ( pSVData->mpWinData->mpFocusWin )
350 {
351 return pSVData->mpWinData->mpFocusWin;
352 }
353 else
354 return nullptr;
355}
356
357void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
358{
359 if (xFocusWin && !xFocusWin->IsDisposed())
360 {
361 xFocusWin->GrabFocus();
362 }
363}
364
365void Window::SetZoom( const Fraction& rZoom )
366{
367 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
368 {
369 mpWindowImpl->maZoom = rZoom;
370 CompatStateChanged( StateChangedType::Zoom );
371 }
372}
373
374static long WinFloatRound( double fVal )
375{
376 return( fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<long>( -fVal + 0.5 ) );
377}
378
379void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
380{
381 const Fraction& rZoom = GetZoom();
382 if (rZoom.GetNumerator() != rZoom.GetDenominator())
383 {
384 vcl::Font aFont(rFont);
385 Size aSize = aFont.GetFontSize();
386 aSize.setWidth( WinFloatRound(double(aSize.Width() * rZoom)) );
387 aSize.setHeight( WinFloatRound(double(aSize.Height() * rZoom)) );
388 aFont.SetFontSize(aSize);
389 SetPointFont(rRenderContext, aFont);
390 }
391 else
392 {
393 SetPointFont(rRenderContext, rFont);
394 }
395}
396
397long Window::CalcZoom( long nCalc ) const
398{
399
400 const Fraction& rZoom = GetZoom();
401 if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
402 {
403 double n = double(nCalc * rZoom);
404 nCalc = WinFloatRound( n );
405 }
406 return nCalc;
407}
408
409void Window::SetControlFont()
410{
411 if (mpWindowImpl && mpWindowImpl->mpControlFont)
412 {
413 mpWindowImpl->mpControlFont.reset();
414 CompatStateChanged(StateChangedType::ControlFont);
415 }
416}
417
418void Window::SetControlFont(const vcl::Font& rFont)
419{
420 if (rFont == vcl::Font())
421 {
422 SetControlFont();
423 return;
424 }
425
426 if (mpWindowImpl->mpControlFont)
427 {
428 if (*mpWindowImpl->mpControlFont == rFont)
429 return;
430 *mpWindowImpl->mpControlFont = rFont;
431 }
432 else
433 mpWindowImpl->mpControlFont.reset( new vcl::Font(rFont) );
434
435 CompatStateChanged(StateChangedType::ControlFont);
436}
437
438vcl::Font Window::GetControlFont() const
439{
440 if (mpWindowImpl->mpControlFont)
441 return *mpWindowImpl->mpControlFont;
442 else
443 {
444 vcl::Font aFont;
445 return aFont;
446 }
447}
448
449void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
450{
451 vcl::Font aFont(rFont);
452 if (IsControlFont())
453 aFont.Merge(GetControlFont());
454 SetZoomedPointFont(rRenderContext, aFont);
455}
456
457void Window::SetControlForeground()
458{
459 if (mpWindowImpl->mbControlForeground)
460 {
461 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
462 mpWindowImpl->mbControlForeground = false;
463 CompatStateChanged(StateChangedType::ControlForeground);
464 }
465}
466
467void Window::SetControlForeground(const Color& rColor)
468{
469 if (rColor.GetTransparency())
470 {
471 if (mpWindowImpl->mbControlForeground)
472 {
473 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
474 mpWindowImpl->mbControlForeground = false;
475 CompatStateChanged(StateChangedType::ControlForeground);
476 }
477 }
478 else
479 {
480 if (mpWindowImpl->maControlForeground != rColor)
481 {
482 mpWindowImpl->maControlForeground = rColor;
483 mpWindowImpl->mbControlForeground = true;
484 CompatStateChanged(StateChangedType::ControlForeground);
485 }
486 }
487}
488
489void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
490{
491 Color aTextColor(rDefaultColor);
492 if (IsControlForeground())
493 aTextColor = GetControlForeground();
494 rRenderContext.SetTextColor(aTextColor);
495}
496
497void Window::SetControlBackground()
498{
499 if (mpWindowImpl->mbControlBackground)
500 {
501 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
502 mpWindowImpl->mbControlBackground = false;
503 CompatStateChanged(StateChangedType::ControlBackground);
504 }
505}
506
507void Window::SetControlBackground(const Color& rColor)
508{
509 if (rColor.GetTransparency())
510 {
511 if (mpWindowImpl->mbControlBackground)
512 {
513 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
514 mpWindowImpl->mbControlBackground = false;
515 CompatStateChanged(StateChangedType::ControlBackground);
516 }
517 }
518 else
519 {
520 if (mpWindowImpl->maControlBackground != rColor)
521 {
522 mpWindowImpl->maControlBackground = rColor;
523 mpWindowImpl->mbControlBackground = true;
524 CompatStateChanged(StateChangedType::ControlBackground);
525 }
526 }
527}
528
529void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
530{
531 Color aColor(rDefaultColor);
532 if (IsControlBackground())
533 aColor = GetControlBackground();
534 rRenderContext.SetBackground(aColor);
535}
536
537Size Window::CalcWindowSize( const Size& rOutSz ) const
538{
539 Size aSz = rOutSz;
540 aSz.AdjustWidth(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder );
541 aSz.AdjustHeight(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
542 return aSz;
543}
544
545Size Window::CalcOutputSize( const Size& rWinSz ) const
546{
547 Size aSz = rWinSz;
548 aSz.AdjustWidth( -(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder) );
549 aSz.AdjustHeight( -(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder) );
550 return aSz;
551}
552
553vcl::Font Window::GetDrawPixelFont(OutputDevice const * pDev) const
554{
555 vcl::Font aFont = GetPointFont(*const_cast<Window*>(this));
556 Size aFontSize = aFont.GetFontSize();
557 MapMode aPtMapMode(MapUnit::MapPoint);
558 aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
559 aFont.SetFontSize( aFontSize );
560 return aFont;
561}
562
563long Window::GetDrawPixel( OutputDevice const * pDev, long nPixels ) const
564{
565 long nP = nPixels;
566 if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
567 {
568 MapMode aMap( MapUnit::Map100thMM );
569 Size aSz( nP, 0 );
570 aSz = PixelToLogic( aSz, aMap );
571 aSz = pDev->LogicToPixel( aSz, aMap );
572 nP = aSz.Width();
573 }
574 return nP;
575}
576
577static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
578{
579 if ( !pScrl || !nN || !pScrl->IsEnabled() || !pScrl->IsInputEnabled() || pScrl->IsInModalMode() )
580 return;
581
582 long nNewPos = pScrl->GetThumbPos();
583
584 if ( nN == double(-LONG_MAX9223372036854775807L) )
585 nNewPos += pScrl->GetPageSize();
586 else if ( nN == double(LONG_MAX9223372036854775807L) )
587 nNewPos -= pScrl->GetPageSize();
588 else
589 {
590 // allowing both chunked and continuous scrolling
591 if(isMultiplyByLineSize){
592 nN*=pScrl->GetLineSize();
593 }
594
595 const double fVal = nNewPos - nN;
596
597 if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN(-9223372036854775807L -1L)) )
598 nNewPos = LONG_MIN(-9223372036854775807L -1L);
599 else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX9223372036854775807L) )
600 nNewPos = LONG_MAX9223372036854775807L;
601 else
602 nNewPos = static_cast<long>(fVal);
603 }
604
605 pScrl->DoScroll( nNewPos );
606
607}
608
609bool Window::HandleScrollCommand( const CommandEvent& rCmd,
610 ScrollBar* pHScrl, ScrollBar* pVScrl )
611{
612 bool bRet = false;
613
614 if ( pHScrl || pVScrl )
615 {
616 switch( rCmd.GetCommand() )
617 {
618 case CommandEventId::StartAutoScroll:
619 {
620 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
621 if ( pHScrl )
622 {
623 if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
624 pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
625 nFlags |= StartAutoScrollFlags::Horz;
626 }
627 if ( pVScrl )
628 {
629 if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
630 pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
631 nFlags |= StartAutoScrollFlags::Vert;
632 }
633
634 if ( nFlags != StartAutoScrollFlags::NONE )
635 {
636 StartAutoScroll( nFlags );
637 bRet = true;
638 }
639 }
640 break;
641
642 case CommandEventId::Wheel:
643 {
644 const CommandWheelData* pData = rCmd.GetWheelData();
645
646 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
647 {
648 if (!pData->IsDeltaPixel())
649 {
650 double nScrollLines = pData->GetScrollLines();
651 double nLines;
652 if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL(sal_uLong(0xFFFFFFFF)) )
653 {
654 if ( pData->GetDelta() < 0 )
655 nLines = double(-LONG_MAX9223372036854775807L);
656 else
657 nLines = double(LONG_MAX9223372036854775807L);
658 }
659 else
660 nLines = pData->GetNotchDelta() * nScrollLines;
661 if ( nLines )
662 {
663 ImplHandleScroll( nullptr,
664 0L,
665 pData->IsHorz() ? pHScrl : pVScrl,
666 nLines );
667 bRet = true;
668 }
669 }
670 else
671 {
672 // Mobile / touch scrolling section
673 const Point & deltaPoint = rCmd.GetMousePosPixel();
674
675 double deltaXInPixels = double(deltaPoint.X());
676 double deltaYInPixels = double(deltaPoint.Y());
677 Size winSize = GetOutputSizePixel();
678
679 if(pHScrl)
680 {
681 double visSizeX = double(pHScrl->GetVisibleSize());
682 double ratioX = deltaXInPixels / double(winSize.getWidth());
683 long deltaXInLogic = long(visSizeX * ratioX);
684 // Touch need to work by pixels. Did not apply this to
685 // Android, as android code may require adaptations
686 // to work with this scrolling code
687#ifndef IOS
688 long lineSizeX = pHScrl->GetLineSize();
689
690 if(lineSizeX)
691 {
692 deltaXInLogic /= lineSizeX;
693 }
694 else
695 {
696 deltaXInLogic = 0;
697 }
698#endif
699 if ( deltaXInLogic)
700 {
701#ifndef IOS
702 bool const isMultiplyByLineSize = true;
703#else
704 bool const isMultiplyByLineSize = false;
705#endif
706 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
707 bRet = true;
708 }
709 }
710 if(pVScrl)
711 {
712 double visSizeY = double(pVScrl->GetVisibleSize());
713 double ratioY = deltaYInPixels / double(winSize.getHeight());
714 long deltaYInLogic = long(visSizeY * ratioY);
715
716 // Touch need to work by pixels. Did not apply this to
717 // Android, as android code may require adaptations
718 // to work with this scrolling code
719#ifndef IOS
720 long lineSizeY = pVScrl->GetLineSize();
721 if(lineSizeY)
722 {
723 deltaYInLogic /= lineSizeY;
724 }
725 else
726 {
727 deltaYInLogic = 0;
728 }
729#endif
730 if ( deltaYInLogic )
731 {
732#ifndef IOS
733 bool const isMultiplyByLineSize = true;
734#else
735 bool const isMultiplyByLineSize = false;
736#endif
737 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
738
739 bRet = true;
740 }
741 }
742 }
743 }
744 }
745 break;
746
747 case CommandEventId::Gesture:
748 {
749 if (pVScrl)
750 {
751 const CommandGestureData* pData = rCmd.GetGestureData();
752 if (pData->meEventType == GestureEventType::PanningBegin)
753 {
754 mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
755 }
756 else if(pData->meEventType == GestureEventType::PanningUpdate)
757 {
758 long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
759 pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
760 }
761 if (pData->meEventType == GestureEventType::PanningEnd)
762 {
763 mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
764 }
765 bRet = true;
766 }
767 break;
768 }
769
770 case CommandEventId::AutoScroll:
771 {
772 const CommandScrollData* pData = rCmd.GetAutoScrollData();
773 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
774 {
775 ImplHandleScroll( pHScrl, pData->GetDeltaX(),
776 pVScrl, pData->GetDeltaY() );
777 bRet = true;
778 }
779 }
780 break;
781
782 default:
783 break;
784 }
785 }
786
787 return bRet;
788}
789
790// Note that when called for CommandEventId::Wheel above, despite its name,
791// pVScrl isn't necessarily the vertical scroll bar. Depending on
792// whether the scroll is horizontal or vertical, it is either the
793// horizontal or vertical scroll bar. nY is correspondingly either
794// the horizontal or vertical scroll amount.
795
796void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
797 ScrollBar* pVScrl, double nY )
798{
799 lcl_HandleScrollHelper( pHScrl, nX, true );
800 lcl_HandleScrollHelper( pVScrl, nY, true );
801}
802
803DockingManager* Window::GetDockingManager()
804{
805 return ImplGetDockingManager();
806}
807
808void Window::EnableDocking( bool bEnable )
809{
810 // update list of dockable windows
811 if( bEnable )
812 ImplGetDockingManager()->AddWindow( this );
813 else
814 ImplGetDockingManager()->RemoveWindow( this );
815}
816
817// retrieves the list of owner draw decorated windows for this window hierarchy
818::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
819{
820 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
821}
822
823void Window::SetHelpId( const OString& rHelpId )
824{
825 mpWindowImpl->maHelpId = rHelpId;
826}
827
828const OString& Window::GetHelpId() const
829{
830 return mpWindowImpl->maHelpId;
831}
832
833// --------- old inline methods ---------------
834
835vcl::Window* Window::ImplGetWindow() const
836{
837 if ( mpWindowImpl->mpClientWindow )
838 return mpWindowImpl->mpClientWindow;
839 else
840 return const_cast<vcl::Window*>(this);
841}
842
843ImplFrameData* Window::ImplGetFrameData()
844{
845 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
846}
847
848SalFrame* Window::ImplGetFrame() const
849{
850 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
851}
852
853weld::Window* Window::GetFrameWeld() const
854{
855 SalFrame* pFrame = ImplGetFrame();
856 return pFrame ? pFrame->GetFrameWeld() : nullptr;
857}
858
859vcl::Window* Window::GetFrameWindow() const
860{
861 SalFrame* pFrame = ImplGetFrame();
862 return pFrame ? pFrame->GetWindow() : nullptr;
863}
864
865vcl::Window* Window::ImplGetParent() const
866{
867 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
868}
869
870vcl::Window* Window::ImplGetClientWindow() const
871{
872 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
873}
874
875vcl::Window* Window::ImplGetBorderWindow() const
876{
877 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
878}
879
880vcl::Window* Window::ImplGetFirstOverlapWindow()
881{
882 if (!mpWindowImpl)
883 {
884 return nullptr;
885 }
886
887 if ( mpWindowImpl->mbOverlapWin )
888 return this;
889 else
890 return mpWindowImpl->mpOverlapWindow;
891}
892
893const vcl::Window* Window::ImplGetFirstOverlapWindow() const
894{
895 if ( mpWindowImpl->mbOverlapWin )
896 return this;
897 else
898 return mpWindowImpl->mpOverlapWindow;
899}
900
901vcl::Window* Window::ImplGetFrameWindow() const
902{
903 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
904}
905
906bool Window::IsDockingWindow() const
907{
908 return mpWindowImpl && mpWindowImpl->mbDockWin;
909}
910
911bool Window::ImplIsFloatingWindow() const
912{
913 return mpWindowImpl && mpWindowImpl->mbFloatWin;
914}
915
916bool Window::ImplIsSplitter() const
917{
918 return mpWindowImpl && mpWindowImpl->mbSplitter;
919}
920
921bool Window::ImplIsPushButton() const
922{
923 return mpWindowImpl && mpWindowImpl->mbPushButton;
924}
925
926bool Window::ImplIsOverlapWindow() const
927{
928 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
929}
930
931void Window::ImplSetMouseTransparent( bool bTransparent )
932{
933 if (mpWindowImpl)
934 mpWindowImpl->mbMouseTransparent = bTransparent;
935}
936
937Point Window::ImplOutputToFrame( const Point& rPos )
938{
939 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
940}
941
942Point Window::ImplFrameToOutput( const Point& rPos )
943{
944 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
945}
946
947void Window::SetCompoundControl( bool bCompound )
948{
949 if (mpWindowImpl)
950 mpWindowImpl->mbCompoundControl = bCompound;
951}
952
953WinBits Window::GetStyle() const
954{
955 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
956}
957
958WinBits Window::GetPrevStyle() const
959{
960 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
961}
962
963WindowExtendedStyle Window::GetExtendedStyle() const
964{
965 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
966}
967
968void Window::SetType( WindowType nType )
969{
970 if (mpWindowImpl)
971 mpWindowImpl->mnType = nType;
972}
973
974WindowType Window::GetType() const
975{
976 if (mpWindowImpl)
977 return mpWindowImpl->mnType;
978 else
979 return WindowType::NONE;
980}
981
982Dialog* Window::GetParentDialog() const
983{
984 const vcl::Window *pWindow = this;
985
986 while( pWindow )
987 {
988 if( pWindow->IsDialog() )
989 break;
990
991 pWindow = pWindow->GetParent();
992 }
993
994 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
995}
996
997bool Window::IsSystemWindow() const
998{
999 return mpWindowImpl && mpWindowImpl->mbSysWin;
1000}
1001
1002bool Window::IsDialog() const
1003{
1004 return mpWindowImpl && mpWindowImpl->mbDialog;
1005}
1006
1007bool Window::IsMenuFloatingWindow() const
1008{
1009 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1010}
1011
1012bool Window::IsToolbarFloatingWindow() const
1013{
1014 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1015}
1016
1017void Window::EnableAllResize()
1018{
1019 mpWindowImpl->mbAllResize = true;
1020}
1021
1022void Window::EnableChildTransparentMode( bool bEnable )
1023{
1024 mpWindowImpl->mbChildTransparent = bEnable;
1025}
1026
1027bool Window::IsChildTransparentModeEnabled() const
1028{
1029 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1030}
1031
1032bool Window::IsMouseTransparent() const
1033{
1034 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1035}
1036
1037bool Window::IsPaintTransparent() const
1038{
1039 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1040}
1041
1042void Window::SetDialogControlStart( bool bStart )
1043{
1044 mpWindowImpl->mbDlgCtrlStart = bStart;
1045}
1046
1047bool Window::IsDialogControlStart() const
1048{
1049 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1050}
1051
1052void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1053{
1054 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1055}
1056
1057DialogControlFlags Window::GetDialogControlFlags() const
1058{
1059 return mpWindowImpl->mnDlgCtrlFlags;
1060}
1061
1062const InputContext& Window::GetInputContext() const
1063{
1064 return mpWindowImpl->maInputContext;
1065}
1066
1067bool Window::IsControlFont() const
1068{
1069 return bool(mpWindowImpl->mpControlFont);
1070}
1071
1072const Color& Window::GetControlForeground() const
1073{
1074 return mpWindowImpl->maControlForeground;
1075}
1076
1077bool Window::IsControlForeground() const
1078{
1079 return mpWindowImpl->mbControlForeground;
1080}
1081
1082const Color& Window::GetControlBackground() const
1083{
1084 return mpWindowImpl->maControlBackground;
1085}
1086
1087bool Window::IsControlBackground() const
1088{
1089 return mpWindowImpl->mbControlBackground;
1090}
1091
1092bool Window::IsInPaint() const
1093{
1094 return mpWindowImpl && mpWindowImpl->mbInPaint;
1095}
1096
1097vcl::Window* Window::GetParent() const
1098{
1099 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1100}
1101
1102bool Window::IsVisible() const
1103{
1104 return mpWindowImpl && mpWindowImpl->mbVisible;
1105}
1106
1107bool Window::IsReallyVisible() const
1108{
1109 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1110}
1111
1112bool Window::IsReallyShown() const
1113{
1114 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1115}
1116
1117bool Window::IsInInitShow() const
1118{
1119 return mpWindowImpl->mbInInitShow;
1120}
1121
1122bool Window::IsEnabled() const
1123{
1124 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1125}
1126
1127bool Window::IsInputEnabled() const
1128{
1129 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1130}
1131
1132bool Window::IsAlwaysEnableInput() const
1133{
1134 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1135}
1136
1137ActivateModeFlags Window::GetActivateMode() const
1138{
1139 return mpWindowImpl->mnActivateMode;
1140
1141}
1142
1143bool Window::IsAlwaysOnTopEnabled() const
1144{
1145 return mpWindowImpl->mbAlwaysOnTop;
1146}
1147
1148bool Window::IsDefaultPos() const
1149{
1150 return mpWindowImpl->mbDefPos;
1151}
1152
1153bool Window::IsDefaultSize() const
1154{
1155 return mpWindowImpl->mbDefSize;
1156}
1157
1158Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1159{
1160 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1161}
1162
1163void Window::EnablePaint( bool bEnable )
1164{
1165 mpWindowImpl->mbPaintDisabled = !bEnable;
1166}
1167
1168bool Window::IsPaintEnabled() const
1169{
1170 return !mpWindowImpl->mbPaintDisabled;
1171}
1172
1173bool Window::IsUpdateMode() const
1174{
1175 return !mpWindowImpl->mbNoUpdate;
1176}
1177
1178void Window::SetParentUpdateMode( bool bUpdate )
1179{
1180 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1181}
1182
1183bool Window::IsActive() const
1184{
1185 return mpWindowImpl->mbActive;
1186}
1187
1188GetFocusFlags Window::GetGetFocusFlags() const
1189{
1190 return mpWindowImpl->mnGetFocusFlags;
1191}
1192
1193bool Window::IsCompoundControl() const
1194{
1195 return mpWindowImpl->mbCompoundControl;
1196}
1197
1198bool Window::IsWait() const
1199{
1200 return (mpWindowImpl->mnWaitCount != 0);
1201}
1202
1203vcl::Cursor* Window::GetCursor() const
1204{
1205 if (!mpWindowImpl)
1206 return nullptr;
1207 return mpWindowImpl->mpCursor;
1208}
1209
1210const Fraction& Window::GetZoom() const
1211{
1212 return mpWindowImpl->maZoom;
1213}
1214
1215bool Window::IsZoom() const
1216{
1217 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1218}
1219
1220void Window::SetHelpText( const OUString& rHelpText )
1221{
1222 mpWindowImpl->maHelpText = rHelpText;
1223 mpWindowImpl->mbHelpTextDynamic = true;
1224}
1225
1226void Window::SetQuickHelpText( const OUString& rHelpText )
1227{
1228 if (mpWindowImpl)
1229 mpWindowImpl->maQuickHelpText = rHelpText;
1230}
1231
1232const OUString& Window::GetQuickHelpText() const
1233{
1234 return mpWindowImpl->maQuickHelpText;
1235}
1236
1237bool Window::IsCreatedWithToolkit() const
1238{
1239 return mpWindowImpl->mbCreatedWithToolkit;
1240}
1241
1242void Window::SetCreatedWithToolkit( bool b )
1243{
1244 mpWindowImpl->mbCreatedWithToolkit = b;
1245}
1246
1247PointerStyle Window::GetPointer() const
1248{
1249 return mpWindowImpl->maPointer;
1250}
1251
1252VCLXWindow* Window::GetWindowPeer() const
1253{
1254 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1255}
1256
1257void Window::SetPosPixel( const Point& rNewPos )
1258{
1259 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1260}
1261
1262void Window::SetSizePixel( const Size& rNewSize )
1263{
1264 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1265 PosSizeFlags::Size );
1266}
1267
1268void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1269{
1270 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1271 rNewSize.Width(), rNewSize.Height());
1272}
1273
1274void Window::SetOutputSizePixel( const Size& rNewSize )
1275{
1276 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1277 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1278}
1279
1280//When a widget wants to renegotiate layout, get toplevel parent dialog and call
1281//resize on it. Mark all intermediate containers (or container-alike) widgets
1282//as dirty for the size remains unchanged, but layout changed circumstances
1283namespace
1284{
1285 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1286 {
1287 bool bSomeoneCares = false;
1288
1289 vcl::Window *pWindow = pOrigWindow->GetParent();
1290 if (pWindow)
1291 {
1292 if (isContainerWindow(*pWindow))
1293 {
1294 bSomeoneCares = true;
1295 }
1296 else if (pWindow->GetType() == WindowType::TABCONTROL)
1297 {
1298 bSomeoneCares = true;
1299 }
1300 pWindow->queue_resize();
1301 }
1302
1303 return bSomeoneCares;
1304 }
1305}
1306
1307void Window::InvalidateSizeCache()
1308{
1309 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1310 pWindowImpl->mnOptimalWidthCache = -1;
1311 pWindowImpl->mnOptimalHeightCache = -1;
1312}
1313
1314void Window::queue_resize(StateChangedType eReason)
1315{
1316 if (IsDisposed())
1317 return;
1318
1319 bool bSomeoneCares = queue_ungrouped_resize(this);
1320
1321 if (eReason != StateChangedType::Visible)
1322 {
1323 InvalidateSizeCache();
1324 }
1325
1326 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1327 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1328 {
1329 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1330 for (VclPtr<vcl::Window> const & pOther : rWindows)
1331 {
1332 if (pOther == this)
1333 continue;
1334 queue_ungrouped_resize(pOther);
1335 }
1336 }
1337
1338 if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1339 {
1340 //fdo#57090 force a resync of the borders of the borderwindow onto this
1341 //window in case they have changed
1342 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1343 if (pBorderWindow)
1344 pBorderWindow->Resize();
1345 }
1346 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1347 {
1348 Size aSize = GetSizePixel();
1349 if (!aSize.IsEmpty() && GetParentDialog() && !pParent->IsInInitShow())
1350 LogicInvalidate(nullptr);
1351 }
1352}
1353
1354namespace
1355{
1356 VclAlign toAlign(const OUString &rValue)
1357 {
1358 VclAlign eRet = VclAlign::Fill;
1359
1360 if (rValue == "fill")
1361 eRet = VclAlign::Fill;
1362 else if (rValue == "start")
1363 eRet = VclAlign::Start;
1364 else if (rValue == "end")
1365 eRet = VclAlign::End;
1366 else if (rValue == "center")
1367 eRet = VclAlign::Center;
1368 return eRet;
1369 }
1370}
1371
1372bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1373{
1374 if (rKey == "weight")
1375 {
1376 vcl::Font aFont(GetControlFont());
1377 if (rValue == "thin")
1378 aFont.SetWeight(WEIGHT_THIN);
1379 else if (rValue == "ultralight")
1380 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1381 else if (rValue == "light")
1382 aFont.SetWeight(WEIGHT_LIGHT);
1383 else if (rValue == "book")
1384 aFont.SetWeight(WEIGHT_SEMILIGHT);
1385 else if (rValue == "normal")
1386 aFont.SetWeight(WEIGHT_NORMAL);
1387 else if (rValue == "medium")
1388 aFont.SetWeight(WEIGHT_MEDIUM);
1389 else if (rValue == "semibold")
1390 aFont.SetWeight(WEIGHT_SEMIBOLD);
1391 else if (rValue == "bold")
1392 aFont.SetWeight(WEIGHT_BOLD);
1393 else if (rValue == "ultrabold")
1394 aFont.SetWeight(WEIGHT_ULTRABOLD);
1395 else
1396 aFont.SetWeight(WEIGHT_BLACK);
1397 SetControlFont(aFont);
1398 }
1399 else if (rKey == "style")
1400 {
1401 vcl::Font aFont(GetControlFont());
1402 if (rValue == "normal")
1403 aFont.SetItalic(ITALIC_NONE);
1404 else if (rValue == "oblique")
1405 aFont.SetItalic(ITALIC_OBLIQUE);
1406 else if (rValue == "italic")
1407 aFont.SetItalic(ITALIC_NORMAL);
1408 SetControlFont(aFont);
1409 }
1410 else if (rKey == "underline")
1411 {
1412 vcl::Font aFont(GetControlFont());
1413 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1414 SetControlFont(aFont);
1415 }
1416 else if (rKey == "size")
1417 {
1418 vcl::Font aFont(GetControlFont());
1419 sal_Int32 nHeight = rValue.toInt32() / 1000;
1420 aFont.SetFontHeight(nHeight);
1421 SetControlFont(aFont);
1422 }
1423 else
1424 {
1425 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unhandled font attribute: "
<< rKey) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled font attribute: " <<
rKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled font attribute: " << rKey; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), (
"/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unhandled font attribute: " << rKey) == 1)
{ ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled font attribute: " <<
rKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled font attribute: " << rKey; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), (
"/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1426 return false;
1427 }
1428 return true;
1429}
1430
1431bool Window::set_property(const OString &rKey, const OUString &rValue)
1432{
1433 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1434 {
1435 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1436 }
1437 else if (rKey == "visible")
1438 Show(toBool(rValue));
1439 else if (rKey == "sensitive")
1440 Enable(toBool(rValue));
1441 else if (rKey == "resizable")
1442 {
1443 WinBits nBits = GetStyle();
1444 nBits &= ~WB_SIZEABLE;
1445 if (toBool(rValue))
1446 nBits |= WB_SIZEABLE;
1447 SetStyle(nBits);
1448 }
1449 else if (rKey == "xalign")
1450 {
1451 WinBits nBits = GetStyle();
1452 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1453
1454 float f = rValue.toFloat();
1455 if (f == 0.0)
1456 nBits |= WB_LEFT;
1457 else if (f == 1.0)
1458 nBits |= WB_RIGHT;
1459 else if (f == 0.5)
1460 nBits |= WB_CENTER;
1461
1462 SetStyle(nBits);
1463 }
1464 else if (rKey == "justification")
1465 {
1466 WinBits nBits = GetStyle();
1467 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1468
1469 if (rValue == "left")
1470 nBits |= WB_LEFT;
1471 else if (rValue == "right")
1472 nBits |= WB_RIGHT;
1473 else if (rValue == "center")
1474 nBits |= WB_CENTER;
1475
1476 SetStyle(nBits);
1477 }
1478 else if (rKey == "yalign")
1479 {
1480 WinBits nBits = GetStyle();
1481 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1482
1483 float f = rValue.toFloat();
1484 if (f == 0.0)
1485 nBits |= WB_TOP;
1486 else if (f == 1.0)
1487 nBits |= WB_BOTTOM;
1488 else if (f == 0.5)
1489 nBits |= WB_CENTER;
1490
1491 SetStyle(nBits);
1492 }
1493 else if (rKey == "wrap")
1494 {
1495 WinBits nBits = GetStyle();
1496 nBits &= ~WB_WORDBREAK;
1497 if (toBool(rValue))
1498 nBits |= WB_WORDBREAK;
1499 SetStyle(nBits);
1500 }
1501 else if (rKey == "height-request")
1502 set_height_request(rValue.toInt32());
1503 else if (rKey == "width-request")
1504 set_width_request(rValue.toInt32());
1505 else if (rKey == "hexpand")
1506 set_hexpand(toBool(rValue));
1507 else if (rKey == "vexpand")
1508 set_vexpand(toBool(rValue));
1509 else if (rKey == "halign")
1510 set_halign(toAlign(rValue));
1511 else if (rKey == "valign")
1512 set_valign(toAlign(rValue));
1513 else if (rKey == "tooltip-markup")
1514 SetQuickHelpText(rValue);
1515 else if (rKey == "tooltip-text")
1516 SetQuickHelpText(rValue);
1517 else if (rKey == "border-width")
1518 set_border_width(rValue.toInt32());
1519 else if (rKey == "margin-start" || rKey == "margin-left")
1520 set_margin_left(rValue.toInt32());
1521 else if (rKey == "margin-end" || rKey == "margin-right")
1522 set_margin_right(rValue.toInt32());
1523 else if (rKey == "margin-top")
1524 set_margin_top(rValue.toInt32());
1525 else if (rKey == "margin-bottom")
1526 set_margin_bottom(rValue.toInt32());
1527 else if (rKey == "hscrollbar-policy")
1528 {
1529 WinBits nBits = GetStyle();
1530 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1531 if (rValue == "always")
1532 nBits |= WB_HSCROLL;
1533 else if (rValue == "automatic")
1534 nBits |= WB_AUTOHSCROLL;
1535 SetStyle(nBits);
1536 }
1537 else if (rKey == "vscrollbar-policy")
1538 {
1539 WinBits nBits = GetStyle();
1540 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1541 if (rValue == "always")
1542 nBits |= WB_VSCROLL;
1543 else if (rValue == "automatic")
1544 nBits |= WB_AUTOVSCROLL;
1545 SetStyle(nBits);
1546 }
1547 else if (rKey == "accessible-name")
1548 {
1549 SetAccessibleName(rValue);
1550 }
1551 else if (rKey == "accessible-description")
1552 {
1553 SetAccessibleDescription(rValue);
1554 }
1555 else if (rKey == "accessible-role")
1556 {
1557 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1558 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1559 SetAccessibleRole(role);
1560 }
1561 else if (rKey == "use-markup")
1562 {
1563 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1564 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up")do { if (true && (toBool(rValue))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Use pango attributes instead of mark-up"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Use pango attributes instead of mark-up"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Use pango attributes instead of mark-up"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Use pango attributes instead of mark-up") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Use pango attributes instead of mark-up"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Use pango attributes instead of mark-up"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1565 }
1566 else if (rKey == "has-focus")
1567 {
1568 if (toBool(rValue))
1569 GrabFocus();
1570 }
1571 else if (rKey == "can-focus")
1572 {
1573 WinBits nBits = GetStyle();
1574 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1575 if (toBool(rValue))
1576 nBits |= WB_TABSTOP;
1577 else
1578 nBits |= WB_NOTABSTOP;
1579 SetStyle(nBits);
1580 }
1581 else
1582 {
1583 SAL_INFO("vcl.layout", "unhandled property: " << rKey)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unhandled property: "
<< rKey) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled property: " << rKey
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled property: " << rKey; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unhandled property: " << rKey) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled property: " << rKey
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled property: " << rKey; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1584 return false;
1585 }
1586 return true;
1587}
1588
1589void Window::set_height_request(sal_Int32 nHeightRequest)
1590{
1591 if (!mpWindowImpl)
1592 return;
1593
1594 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1595
1596 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1597 {
1598 pWindowImpl->mnHeightRequest = nHeightRequest;
1599 queue_resize();
1600 }
1601}
1602
1603void Window::set_width_request(sal_Int32 nWidthRequest)
1604{
1605 if (!mpWindowImpl)
1606 return;
1607
1608 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1609
1610 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1611 {
1612 pWindowImpl->mnWidthRequest = nWidthRequest;
1613 queue_resize();
1614 }
1615}
1616
1617Size Window::get_ungrouped_preferred_size() const
1618{
1619 Size aRet(get_width_request(), get_height_request());
1620 if (aRet.Width() == -1 || aRet.Height() == -1)
1621 {
1622 //cache gets blown away by queue_resize
1623 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1624 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1625 {
1626 Size aOptimal(GetOptimalSize());
1627 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1628 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1629 }
1630
1631 if (aRet.Width() == -1)
1632 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1633 if (aRet.Height() == -1)
1634 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1635 }
1636 return aRet;
1637}
1638
1639Size Window::get_preferred_size() const
1640{
1641 Size aRet(get_ungrouped_preferred_size());
1642
1643 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1644 if (pWindowImpl->m_xSizeGroup)
1645 {
1646 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1647 if (eMode != VclSizeGroupMode::NONE)
1648 {
1649 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1650 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1651 for (auto const& window : rWindows)
1652 {
1653 const vcl::Window *pOther = window;
1654 if (pOther == this)
1655 continue;
1656 if (bIgnoreInHidden && !pOther->IsVisible())
1657 continue;
1658 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1659 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1660 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1661 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1662 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1663 }
1664 }
1665 }
1666
1667 return aRet;
1668}
1669
1670VclAlign Window::get_halign() const
1671{
1672 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1673 return pWindowImpl->meHalign;
1674}
1675
1676void Window::set_halign(VclAlign eAlign)
1677{
1678 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1679 pWindowImpl->meHalign = eAlign;
1680}
1681
1682VclAlign Window::get_valign() const
1683{
1684 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1685 return pWindowImpl->meValign;
1686}
1687
1688void Window::set_valign(VclAlign eAlign)
1689{
1690 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1691 pWindowImpl->meValign = eAlign;
1692}
1693
1694bool Window::get_hexpand() const
1695{
1696 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1697 return pWindowImpl->mbHexpand;
1698}
1699
1700void Window::set_hexpand(bool bExpand)
1701{
1702 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1703 pWindowImpl->mbHexpand = bExpand;
1704}
1705
1706bool Window::get_vexpand() const
1707{
1708 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1709 return pWindowImpl->mbVexpand;
1710}
1711
1712void Window::set_vexpand(bool bExpand)
1713{
1714 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1715 pWindowImpl->mbVexpand = bExpand;
1716}
1717
1718bool Window::get_expand() const
1719{
1720 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1721 return pWindowImpl->mbExpand;
1722}
1723
1724void Window::set_expand(bool bExpand)
1725{
1726 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1727 pWindowImpl->mbExpand = bExpand;
1728}
1729
1730VclPackType Window::get_pack_type() const
1731{
1732 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1733 return pWindowImpl->mePackType;
1734}
1735
1736void Window::set_pack_type(VclPackType ePackType)
1737{
1738 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1739 pWindowImpl->mePackType = ePackType;
1740}
1741
1742sal_Int32 Window::get_padding() const
1743{
1744 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1745 return pWindowImpl->mnPadding;
1746}
1747
1748void Window::set_padding(sal_Int32 nPadding)
1749{
1750 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1751 pWindowImpl->mnPadding = nPadding;
1752}
1753
1754bool Window::get_fill() const
1755{
1756 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1757 return pWindowImpl->mbFill;
1758}
1759
1760void Window::set_fill(bool bFill)
1761{
1762 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1763 pWindowImpl->mbFill = bFill;
1764}
1765
1766sal_Int32 Window::get_grid_width() const
1767{
1768 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1769 return pWindowImpl->mnGridWidth;
1770}
1771
1772void Window::set_grid_width(sal_Int32 nCols)
1773{
1774 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1775 pWindowImpl->mnGridWidth = nCols;
1776}
1777
1778sal_Int32 Window::get_grid_left_attach() const
1779{
1780 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1781 return pWindowImpl->mnGridLeftAttach;
1782}
1783
1784void Window::set_grid_left_attach(sal_Int32 nAttach)
1785{
1786 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1787 pWindowImpl->mnGridLeftAttach = nAttach;
1788}
1789
1790sal_Int32 Window::get_grid_height() const
1791{
1792 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1793 return pWindowImpl->mnGridHeight;
1794}
1795
1796void Window::set_grid_height(sal_Int32 nRows)
1797{
1798 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1799 pWindowImpl->mnGridHeight = nRows;
1800}
1801
1802sal_Int32 Window::get_grid_top_attach() const
1803{
1804 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1805 return pWindowImpl->mnGridTopAttach;
1806}
1807
1808void Window::set_grid_top_attach(sal_Int32 nAttach)
1809{
1810 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1811 pWindowImpl->mnGridTopAttach = nAttach;
1812}
1813
1814void Window::set_border_width(sal_Int32 nBorderWidth)
1815{
1816 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1817 pWindowImpl->mnBorderWidth = nBorderWidth;
1818}
1819
1820sal_Int32 Window::get_border_width() const
1821{
1822 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1823 return pWindowImpl->mnBorderWidth;
1824}
1825
1826void Window::set_margin_left(sal_Int32 nWidth)
1827{
1828 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1829 if (pWindowImpl->mnMarginLeft != nWidth)
1830 {
1831 pWindowImpl->mnMarginLeft = nWidth;
1832 queue_resize();
1833 }
1834}
1835
1836sal_Int32 Window::get_margin_left() const
1837{
1838 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1839 return pWindowImpl->mnMarginLeft;
1840}
1841
1842void Window::set_margin_right(sal_Int32 nWidth)
1843{
1844 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1845 if (pWindowImpl->mnMarginRight != nWidth)
1846 {
1847 pWindowImpl->mnMarginRight = nWidth;
1848 queue_resize();
1849 }
1850}
1851
1852sal_Int32 Window::get_margin_right() const
1853{
1854 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1855 return pWindowImpl->mnMarginRight;
1856}
1857
1858void Window::set_margin_top(sal_Int32 nWidth)
1859{
1860 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1861 if (pWindowImpl->mnMarginTop != nWidth)
1862 {
1863 pWindowImpl->mnMarginTop = nWidth;
1864 queue_resize();
1865 }
1866}
1867
1868sal_Int32 Window::get_margin_top() const
1869{
1870 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1871 return pWindowImpl->mnMarginTop;
1872}
1873
1874void Window::set_margin_bottom(sal_Int32 nWidth)
1875{
1876 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1877 if (pWindowImpl->mnMarginBottom != nWidth)
1878 {
1879 pWindowImpl->mnMarginBottom = nWidth;
1880 queue_resize();
1881 }
1882}
1883
1884sal_Int32 Window::get_margin_bottom() const
1885{
1886 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1887 return pWindowImpl->mnMarginBottom;
1888}
1889
1890sal_Int32 Window::get_height_request() const
1891{
1892 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1893 return pWindowImpl->mnHeightRequest;
1894}
1895
1896sal_Int32 Window::get_width_request() const
1897{
1898 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1899 return pWindowImpl->mnWidthRequest;
1900}
1901
1902bool Window::get_secondary() const
1903{
1904 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1905 return pWindowImpl->mbSecondary;
1906}
1907
1908void Window::set_secondary(bool bSecondary)
1909{
1910 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1911 pWindowImpl->mbSecondary = bSecondary;
1912}
1913
1914bool Window::get_non_homogeneous() const
1915{
1916 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1917 return pWindowImpl->mbNonHomogeneous;
1918}
1919
1920void Window::set_non_homogeneous(bool bNonHomogeneous)
1921{
1922 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1923 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1924}
1925
1926void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1927{
1928 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1929 //To-Do, multiple groups
1930 pWindowImpl->m_xSizeGroup = xGroup;
1931 pWindowImpl->m_xSizeGroup->insert(this);
1932 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1933 queue_resize();
1934}
1935
1936void Window::remove_from_all_size_groups()
1937{
1938 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1939 //To-Do, multiple groups
1940 if (pWindowImpl->m_xSizeGroup)
1941 {
1942 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1943 queue_resize();
1944 pWindowImpl->m_xSizeGroup->erase(this);
1945 pWindowImpl->m_xSizeGroup.reset();
1946 }
1947}
1948
1949void Window::add_mnemonic_label(FixedText *pLabel)
1950{
1951 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1952 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1953 return;
1954 v.emplace_back(pLabel);
1955 pLabel->set_mnemonic_widget(this);
1956}
1957
1958void Window::remove_mnemonic_label(FixedText *pLabel)
1959{
1960 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1961 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1962 if (aFind == v.end())
1963 return;
1964 v.erase(aFind);
1965 pLabel->set_mnemonic_widget(nullptr);
1966}
1967
1968const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1969{
1970 return mpWindowImpl->m_aMnemonicLabels;
1971}
1972
1973} /* namespace vcl */
1974
1975void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1976{
1977 const int nBorder = 1;
1978 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1979 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1980 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1981 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1982}
1983
1984/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/gen.hxx

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#ifndef INCLUDED_TOOLS_GEN_HXX
20#define INCLUDED_TOOLS_GEN_HXX
21
22#include <tools/toolsdllapi.h>
23
24#include <limits.h>
25#include <algorithm>
26#include <ostream>
27#include <config_options.h>
28
29class SvStream;
30namespace rtl
31{
32 class OString;
33}
34
35enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET };
36
37// Pair
38
39class SAL_WARN_UNUSED__attribute__((warn_unused)) Pair
40{
41public:
42 Pair() : nA(0), nB(0) {}
43 Pair( long _nA, long _nB ) : nA(_nA), nB(_nB) {}
44
45 long A() const { return nA; }
46 long B() const { return nB; }
47
48 long& A() { return nA; }
49 long& B() { return nB; }
50
51 TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) rtl::OString toString() const;
52
53protected:
54 long nA;
55 long nB;
56};
57
58namespace tools::detail {
59
60// Used to implement operator == for subclasses of Pair:
61inline bool equal(Pair const & p1, Pair const & p2)
62{
63 return p1.A() == p2.A() && p1.B() == p2.B();
64}
65
66}
67
68// Point
69
70class Size;
71class SAL_WARN_UNUSED__attribute__((warn_unused)) UNLESS_MERGELIBS(SAL_DLLPUBLIC_EXPORT)__attribute__ ((visibility("default"))) Point final : protected Pair
72{
73public:
74 Point() {}
75 Point( long nX, long nY ) : Pair( nX, nY ) {}
76
77 long X() const { return nA; }
78 long Y() const { return nB; }
79
80 void Move( long nHorzMove, long nVertMove );
81 void Move( Size const & s );
82 long AdjustX( long nHorzMove ) { nA += nHorzMove; return nA; }
83 long AdjustY( long nVertMove ) { nB += nVertMove; return nB; }
84
85 void RotateAround( long& rX, long& rY, short nOrientation ) const;
86 void RotateAround( Point&, short nOrientation ) const;
87
88 Point& operator += ( const Point& rPoint );
89 Point& operator -= ( const Point& rPoint );
90 Point& operator *= ( const long nVal );
91 Point& operator /= ( const long nVal );
92
93 friend inline Point operator+( const Point &rVal1, const Point &rVal2 );
94 friend inline Point operator-( const Point &rVal1, const Point &rVal2 );
95 friend inline Point operator*( const Point &rVal1, const long nVal2 );
96 friend inline Point operator/( const Point &rVal1, const long nVal2 );
97
98 long getX() const { return X(); }
99 long getY() const { return Y(); }
100 void setX(long nX) { nA = nX; }
101 void setY(long nY) { nB = nY; }
102
103 Pair const & toPair() const { return *this; }
104 Pair & toPair() { return *this; }
105
106 using Pair::toString;
107};
108
109inline void Point::Move( long nHorzMove, long nVertMove )
110{
111 nA += nHorzMove;
112 nB += nVertMove;
113}
114
115inline Point& Point::operator += ( const Point& rPoint )
116{
117 nA += rPoint.nA;
118 nB += rPoint.nB;
119 return *this;
120}
121
122inline Point& Point::operator -= ( const Point& rPoint )
123{
124 nA -= rPoint.nA;
125 nB -= rPoint.nB;
126 return *this;
127}
128
129inline Point& Point::operator *= ( const long nVal )
130{
131 nA *= nVal;
132 nB *= nVal;
133 return *this;
134}
135
136inline Point& Point::operator /= ( const long nVal )
137{
138 nA /= nVal;
139 nB /= nVal;
140 return *this;
141}
142
143inline Point operator+( const Point &rVal1, const Point &rVal2 )
144{
145 return Point( rVal1.nA+rVal2.nA, rVal1.nB+rVal2.nB );
146}
147
148inline Point operator-( const Point &rVal1, const Point &rVal2 )
149{
150 return Point( rVal1.nA-rVal2.nA, rVal1.nB-rVal2.nB );
151}
152
153inline Point operator*( const Point &rVal1, const long nVal2 )
154{
155 return Point( rVal1.nA*nVal2, rVal1.nB*nVal2 );
156}
157
158inline Point operator/( const Point &rVal1, const long nVal2 )
159{
160 return Point( rVal1.nA/nVal2, rVal1.nB/nVal2 );
161}
162
163inline bool operator ==(Point const & p1, Point const & p2)
164{
165 return tools::detail::equal(p1.toPair(), p2.toPair());
166}
167
168inline bool operator !=(Point const & p1, Point const & p2)
169{
170 return !(p1 == p2);
171}
172
173template< typename charT, typename traits >
174inline std::basic_ostream<charT, traits> & operator <<(
175 std::basic_ostream<charT, traits> & stream, const Point& point )
176{
177 return stream << point.X() << ',' << point.Y();
178}
179
180// Size
181
182class SAL_WARN_UNUSED__attribute__((warn_unused)) Size final : protected Pair
183{
184public:
185 Size() {}
186 Size( long nWidth, long nHeight ) : Pair( nWidth, nHeight ) {}
187
188 long Width() const { return nA; }
189 long Height() const { return nB; }
190
191 long AdjustWidth( long n ) { nA += n; return nA; }
192 long AdjustHeight( long n ) { nB += n; return nB; }
193
194 long getWidth() const { return Width(); }
195 long getHeight() const { return Height(); }
196 void setWidth(long nWidth) { nA = nWidth; }
197 void setHeight(long nHeight) { nB = nHeight; }
198
199 bool IsEmpty() const { return nA <= 0 || nB <= 0; }
200
201 void extendBy(long x, long y)
202 {
203 nA += x;
204 nB += y;
205 }
206
207 Pair const & toPair() const { return *this; }
208 Pair & toPair() { return *this; }
209
210 using Pair::toString;
211};
212
213inline bool operator ==(Size const & s1, Size const & s2)
214{
215 return tools::detail::equal(s1.toPair(), s2.toPair());
216}
217
218inline bool operator !=(Size const & s1, Size const & s2)
219{
220 return !(s1 == s2);
221}
222
223template< typename charT, typename traits >
224inline std::basic_ostream<charT, traits> & operator <<(
225 std::basic_ostream<charT, traits> & stream, const Size& size )
226{
227 return stream << size.Width() << 'x' << size.Height();
228}
229
230inline void Point::Move( Size const & s )
231{
232 AdjustX(s.Width());
233 AdjustY(s.Height());
234}
235
236// Range
237
238#define RANGE_MAX9223372036854775807L LONG_MAX9223372036854775807L
239
240class SAL_WARN_UNUSED__attribute__((warn_unused)) Range final : protected Pair
241{
242public:
243 Range() {}
244 Range( long nMin, long nMax ) : Pair( nMin, nMax ) {}
245
246 long Min() const { return nA; }
247 long Max() const { return nB; }
248 long Len() const { return nB - nA + 1; }
249
250 long& Min() { return nA; }
251 long& Max() { return nB; }
252
253 bool IsInside( long nIs ) const;
254
255 void Justify();
256
257 Pair const & toPair() const { return *this; }
258 Pair & toPair() { return *this; }
259
260 using Pair::toString;
261};
262
263inline bool Range::IsInside( long nIs ) const
264{
265 return ((nA <= nIs) && (nIs <= nB ));
266}
267
268inline void Range::Justify()
269{
270 if ( nA > nB )
271 {
272 long nHelp = nA;
273 nA = nB;
274 nB = nHelp;
275 }
276}
277
278inline bool operator ==(Range const & r1, Range const & r2)
279{
280 return tools::detail::equal(r1.toPair(), r2.toPair());
281}
282
283inline bool operator !=(Range const & r1, Range const & r2)
284{
285 return !(r1 == r2);
286}
287
288template< typename charT, typename traits >
289inline std::basic_ostream<charT, traits> & operator <<(
290 std::basic_ostream<charT, traits> & stream, const Range& range )
291{
292 return stream << range.Min() << '-' << range.Max();
293}
294
295// Selection
296
297#define SELECTION_MIN(-9223372036854775807L -1L) LONG_MIN(-9223372036854775807L -1L)
298#define SELECTION_MAX9223372036854775807L LONG_MAX9223372036854775807L
299
300class SAL_WARN_UNUSED__attribute__((warn_unused)) Selection final : protected Pair
301{
302public:
303 Selection() {}
304 Selection( long nPos ) : Pair( nPos, nPos ) {}
305 Selection( long nMin, long nMax ) : Pair( nMin, nMax ) {}
306
307 long Min() const { return nA; }
308 long Max() const { return nB; }
309 long Len() const { return nB - nA; }
310
311 long& Min() { return nA; }
312 long& Max() { return nB; }
313
314 bool IsInside( long nIs ) const;
315
316 void Justify();
317
318 bool operator !() const { return !Len(); }
319
320 long getMin() const { return Min(); }
321 void setMin(long nMin) { Min() = nMin; }
322 void setMax(long nMax) { Max() = nMax; }
323
324 Pair const & toPair() const { return *this; }
325 Pair & toPair() { return *this; }
326
327 using Pair::toString;
328};
329
330inline bool Selection::IsInside( long nIs ) const
331{
332 return ((nA <= nIs) && (nIs < nB ));
333}
334
335inline void Selection::Justify()
336{
337 if ( nA > nB )
338 {
339 long nHelp = nA;
340 nA = nB;
341 nB = nHelp;
342 }
343}
344
345inline bool operator ==(Selection const & s1, Selection const & s2)
346{
347 return tools::detail::equal(s1.toPair(), s2.toPair());
348}
349
350inline bool operator !=(Selection const & s1, Selection const & s2)
351{
352 return !(s1 == s2);
353}
354
355template< typename charT, typename traits >
356inline std::basic_ostream<charT, traits> & operator <<(
357 std::basic_ostream<charT, traits> & stream, const Selection& selection )
358{
359 return stream << selection.Min() << '-' << selection.Max();
360}
361// Rectangle
362
363#define RECT_MAX9223372036854775807L LONG_MAX9223372036854775807L
364#define RECT_MIN(-9223372036854775807L -1L) LONG_MIN(-9223372036854775807L -1L)
365
366/// Note: this class is a true marvel of engineering: because the author
367/// could not decide whether it's better to have a closed or half-open
368/// interval, they just implemented *both* in the same class!
369///
370/// If you have the misfortune of having to use this class, don't immediately
371/// despair but first take note that the uppercase GetWidth() / GetHeight()
372/// etc. methods interpret the interval as closed, while the lowercase
373/// getWidth() / getHeight() etc. methods interpret the interval as half-open.
374/// Ok, now is the time for despair.
375namespace tools
376{
377class SAL_WARN_UNUSED__attribute__((warn_unused)) TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) Rectangle final
378{
379 static constexpr short RECT_EMPTY = -32767;
380public:
381 Rectangle();
382 Rectangle( const Point& rLT, const Point& rRB );
383 Rectangle( long nLeft, long nTop,
384 long nRight, long nBottom );
385 /// Constructs an empty Rectangle, with top/left at the specified params
386 Rectangle( long nLeft, long nTop );
387 Rectangle( const Point& rLT, const Size& rSize );
388
389 static Rectangle Justify( const Point& rLT, const Point& rRB );
390
391 long Left() const { return nLeft; }
392 long Right() const;
393 long Top() const { return nTop; }
394 long Bottom() const;
395
396 void SetLeft(long v) { nLeft = v; }
397 void SetRight(long v) { nRight = v; }
398 void SetTop(long v) { nTop = v; }
399 void SetBottom(long v) { nBottom = v; }
400
401 inline Point TopLeft() const;
402 inline Point TopRight() const;
403 inline Point TopCenter() const;
404 inline Point BottomLeft() const;
405 inline Point BottomRight() const;
406 inline Point BottomCenter() const;
407 inline Point LeftCenter() const;
408 inline Point RightCenter() const;
409 inline Point Center() const;
410
411 /// Move the top and left edges by a delta, preserving width and height
412 inline void Move( long nHorzMoveDelta, long nVertMoveDelta );
413 void Move( Size const & s ) { Move(s.Width(), s.Height()); }
414 long AdjustLeft( long nHorzMoveDelta ) { nLeft += nHorzMoveDelta; return nLeft; }
415 long AdjustRight( long nHorzMoveDelta );
416 long AdjustTop( long nVertMoveDelta ) { nTop += nVertMoveDelta; return nTop; }
417 long AdjustBottom( long nVertMoveDelta );
418 inline void SetPos( const Point& rPoint );
419 void SetSize( const Size& rSize );
420 inline Size GetSize() const;
421
422 /// Returns the difference between right and left, assuming the range is inclusive.
423 inline long GetWidth() const;
424 /// Returns the difference between bottom and top, assuming the range is inclusive.
425 inline long GetHeight() const;
426
427 tools::Rectangle& Union( const tools::Rectangle& rRect );
428 tools::Rectangle& Intersection( const tools::Rectangle& rRect );
429 inline tools::Rectangle GetUnion( const tools::Rectangle& rRect ) const;
430 inline tools::Rectangle GetIntersection( const tools::Rectangle& rRect ) const;
431
432 void Justify();
433
434 bool IsInside( const Point& rPOINT ) const;
435 bool IsInside( const tools::Rectangle& rRect ) const;
436 bool IsOver( const tools::Rectangle& rRect ) const;
437
438 void SetEmpty() { nRight = nBottom = RECT_EMPTY; }
439 void SetWidthEmpty() { nRight = RECT_EMPTY; }
440 void SetHeightEmpty() { nBottom = RECT_EMPTY; }
441 inline bool IsEmpty() const;
442 bool IsWidthEmpty() const { return nRight == RECT_EMPTY; }
443 bool IsHeightEmpty() const { return nBottom == RECT_EMPTY; }
444
445 inline bool operator == ( const tools::Rectangle& rRect ) const;
446 inline bool operator != ( const tools::Rectangle& rRect ) const;
447
448 inline tools::Rectangle& operator += ( const Point& rPt );
449 inline tools::Rectangle& operator -= ( const Point& rPt );
450
451 friend inline tools::Rectangle operator + ( const tools::Rectangle& rRect, const Point& rPt );
452 friend inline tools::Rectangle operator - ( const tools::Rectangle& rRect, const Point& rPt );
453
454 // ONE
455 long getX() const { return nLeft; }
456 long getY() const { return nTop; }
457 /// Returns the difference between right and left, assuming the range includes one end, but not the other.
458 long getWidth() const;
459 /// Returns the difference between bottom and top, assuming the range includes one end, but not the other.
460 long getHeight() const;
461 /// Set the left edge of the rectangle to x, preserving the width
462 void setX( long x );
463 /// Set the top edge of the rectangle to y, preserving the height
464 void setY( long y );
465 void setWidth( long n ) { nRight = nLeft + n; }
466 void setHeight( long n ) { nBottom = nTop + n; }
467 /// Returns the string representation of the rectangle, format is "x, y, width, height".
468 rtl::OString toString() const;
469
470 /**
471 * Expands the rectangle in all directions by the input value.
472 */
473 void expand(long nExpandBy);
474 void shrink(long nShrinkBy);
475
476 /**
477 * Sanitizing variants for handling data from the outside
478 */
479 void SaturatingSetSize(const Size& rSize);
480 void SaturatingSetX(long x);
481 void SaturatingSetY(long y);
482
483private:
484 long nLeft;
485 long nTop;
486 long nRight;
487 long nBottom;
488};
489}
490
491inline tools::Rectangle::Rectangle()
492{
493 nLeft = nTop = 0;
494 nRight = nBottom = RECT_EMPTY;
495}
496
497inline tools::Rectangle::Rectangle( const Point& rLT, const Point& rRB )
498{
499 nLeft = rLT.X();
500 nTop = rLT.Y();
501 nRight = rRB.X();
502 nBottom = rRB.Y();
503}
504
505inline tools::Rectangle::Rectangle( long _nLeft, long _nTop,
506 long _nRight, long _nBottom )
507{
508 nLeft = _nLeft;
509 nTop = _nTop;
510 nRight = _nRight;
511 nBottom = _nBottom;
512}
513
514inline tools::Rectangle::Rectangle( long _nLeft, long _nTop )
515{
516 nLeft = _nLeft;
517 nTop = _nTop;
518 nRight = nBottom = RECT_EMPTY;
519}
520
521inline tools::Rectangle::Rectangle( const Point& rLT, const Size& rSize )
522{
523 nLeft = rLT.X();
524 nTop = rLT.Y();
525 nRight = rSize.Width() ? nLeft+(rSize.Width()-1) : RECT_EMPTY;
526 nBottom = rSize.Height() ? nTop+(rSize.Height()-1) : RECT_EMPTY;
527}
528
529inline bool tools::Rectangle::IsEmpty() const
530{
531 return (nRight == RECT_EMPTY) || (nBottom == RECT_EMPTY);
8
Assuming 'RECT_EMPTY' is not equal to field 'nRight'
9
Assuming 'RECT_EMPTY' is not equal to field 'nBottom'
10
Returning zero, which participates in a condition later
532}
533
534inline Point tools::Rectangle::TopLeft() const
535{
536 return Point( nLeft, nTop );
537}
538
539inline Point tools::Rectangle::TopRight() const
540{
541 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, nTop );
542}
543
544inline Point tools::Rectangle::BottomLeft() const
545{
546 return Point( nLeft, (nBottom == RECT_EMPTY) ? nTop : nBottom );
547}
548
549inline Point tools::Rectangle::BottomRight() const
550{
551 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight,
552 (nBottom == RECT_EMPTY) ? nTop : nBottom );
553}
554
555inline Point tools::Rectangle::TopCenter() const
556{
557 if ( IsEmpty() )
558 return Point( nLeft, nTop );
559 else
560 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
561 std::min( nTop, nBottom) );
562}
563
564inline Point tools::Rectangle::BottomCenter() const
565{
566 if ( IsEmpty() )
567 return Point( nLeft, nTop );
568 else
569 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
570 std::max( nTop, nBottom) );
571}
572
573inline Point tools::Rectangle::LeftCenter() const
574{
575 if ( IsEmpty() )
576 return Point( nLeft, nTop );
577 else
578 return Point( std::min( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
579}
580
581inline Point tools::Rectangle::RightCenter() const
582{
583 if ( IsEmpty() )
584 return Point( nLeft, nTop );
585 else
586 return Point( std::max( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
587}
588
589inline Point tools::Rectangle::Center() const
590{
591 if ( IsEmpty() )
592 return Point( nLeft, nTop );
593 else
594 return Point( nLeft+(nRight-nLeft)/2 , nTop+(nBottom-nTop)/2 );
595}
596
597inline void tools::Rectangle::Move( long nHorzMove, long nVertMove )
598{
599 nLeft += nHorzMove;
600 nTop += nVertMove;
601 if ( nRight != RECT_EMPTY )
602 nRight += nHorzMove;
603 if ( nBottom != RECT_EMPTY )
604 nBottom += nVertMove;
605}
606
607inline void tools::Rectangle::SetPos( const Point& rPoint )
608{
609 if ( nRight != RECT_EMPTY )
610 nRight += rPoint.X() - nLeft;
611 if ( nBottom != RECT_EMPTY )
612 nBottom += rPoint.Y() - nTop;
613 nLeft = rPoint.X();
614 nTop = rPoint.Y();
615}
616
617inline long tools::Rectangle::GetWidth() const
618{
619 long n;
620 if ( nRight == RECT_EMPTY )
621 n = 0;
622 else
623 {
624 n = nRight - nLeft;
625 if( n < 0 )
626 n--;
627 else
628 n++;
629 }
630
631 return n;
632}
633
634inline long tools::Rectangle::GetHeight() const
635{
636 long n;
637 if ( nBottom == RECT_EMPTY )
638 n = 0;
639 else
640 {
641 n = nBottom - nTop;
642 if ( n < 0 )
643 n--;
644 else
645 n++;
646 }
647
648 return n;
649}
650
651inline Size tools::Rectangle::GetSize() const
652{
653 return Size( GetWidth(), GetHeight() );
654}
655
656inline tools::Rectangle tools::Rectangle::GetUnion( const tools::Rectangle& rRect ) const
657{
658 tools::Rectangle aTmpRect( *this );
659 return aTmpRect.Union( rRect );
660}
661
662inline tools::Rectangle tools::Rectangle::GetIntersection( const tools::Rectangle& rRect ) const
663{
664 tools::Rectangle aTmpRect( *this );
665 return aTmpRect.Intersection( rRect );
666}
667
668inline bool tools::Rectangle::operator == ( const tools::Rectangle& rRect ) const
669{
670 return (nLeft == rRect.nLeft ) &&
671 (nTop == rRect.nTop ) &&
672 (nRight == rRect.nRight ) &&
673 (nBottom == rRect.nBottom );
674}
675
676inline bool tools::Rectangle::operator != ( const tools::Rectangle& rRect ) const
677{
678 return (nLeft != rRect.nLeft ) ||
679 (nTop != rRect.nTop ) ||
680 (nRight != rRect.nRight ) ||
681 (nBottom != rRect.nBottom );
682}
683
684inline tools::Rectangle& tools::Rectangle::operator +=( const Point& rPt )
685{
686 nLeft += rPt.X();
687 nTop += rPt.Y();
688 if ( nRight != RECT_EMPTY )
689 nRight += rPt.X();
690 if ( nBottom != RECT_EMPTY )
691 nBottom += rPt.Y();
692 return *this;
693}
694
695inline tools::Rectangle& tools::Rectangle::operator -= ( const Point& rPt )
696{
697 nLeft -= rPt.X();
698 nTop -= rPt.Y();
699 if ( nRight != RECT_EMPTY )
700 nRight -= rPt.X();
701 if ( nBottom != RECT_EMPTY )
702 nBottom -= rPt.Y();
703 return *this;
704}
705
706namespace tools
707{
708inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt )
709{
710 return rRect.IsEmpty()
711 ? Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y() )
712 : Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y(),
713 rRect.nRight + rPt.X(), rRect.nBottom + rPt.Y() );
714}
715
716inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt )
717{
718 return rRect.IsEmpty()
719 ? Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y() )
720 : Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y(),
721 rRect.nRight - rPt.X(), rRect.nBottom - rPt.Y() );
722}
723}
724
725template< typename charT, typename traits >
726inline std::basic_ostream<charT, traits> & operator <<(
727 std::basic_ostream<charT, traits> & stream, const tools::Rectangle& rectangle )
728{
729 if (rectangle.IsEmpty())
730 return stream << "EMPTY";
731 else
732 return stream << rectangle.getWidth() << 'x' << rectangle.getHeight()
733 << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")";
734}
735
736#endif
737
738/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx

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#ifndef INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
21#define INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
22
23#include <sal/config.h>
24
25#include <cassert>
26#include <type_traits>
27
28#include <o3tl/underlyingenumvalue.hxx>
29#include <sal/types.h>
30
31namespace o3tl {
32
33namespace detail {
34
35template<typename T> constexpr
36typename std::enable_if<std::is_signed<T>::value, bool>::type isNonNegative(
37 T value)
38{
39 return value >= 0;
40}
41
42template<typename T> constexpr
43typename std::enable_if<std::is_unsigned<T>::value, bool>::type isNonNegative(T)
44{
45 return true;
46}
47
48}
49
50template<typename T> struct typed_flags {};
51
52/// Mark a (scoped) enumeration as a set of bit flags, with accompanying
53/// operations.
54///
55/// template<>
56/// struct o3tl::typed_flags<TheE>: o3tl::is_typed_flags<TheE, TheM> {};
57///
58/// All relevant values must be non-negative. (Typically, the enumeration's
59/// underlying type will either be fixed and unsigned, or it will be unfixed---
60/// and can thus default to a signed type---and all enumerators will have non-
61/// negative values.)
62///
63/// \param E the enumeration type.
64/// \param M the all-bits-set value for the bit flags.
65template<typename E, typename std::underlying_type<E>::type M>
66struct is_typed_flags {
67 static_assert(
68 M >= 0, "is_typed_flags expects only non-negative bit values");
69
70 typedef E Self;
71
72 class Wrap {
73 public:
74 typedef is_typed_flags Unwrapped;
75
76 explicit constexpr Wrap(typename std::underlying_type<E>::type value):
77 value_(value)
78 {
79 assert(detail::isNonNegative(value))(static_cast <bool> (detail::isNonNegative(value)) ? void
(0) : __assert_fail ("detail::isNonNegative(value)", "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 79, __extension__ __PRETTY_FUNCTION__))
;
80 assert((static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
81 static_cast<typename std::underlying_type<E>::type>(~0) == M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
82 // avoid "operands don't affect result" warnings when M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
83 // covers all bits of the underlying type(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
84 || (value & ~M) == 0)(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
;
85 }
86
87 constexpr operator E() const { return static_cast<E>(value_); }
88
89 explicit constexpr operator typename std::underlying_type<E>::type()
90 const
91 { return value_; }
92
93 explicit constexpr operator bool() const { return value_ != 0; }
14
Assuming field 'value_' is not equal to 0
15
Returning the value 1, which participates in a condition later
94
95 private:
96 typename std::underlying_type<E>::type value_;
97 };
98
99 static typename std::underlying_type<E>::type const mask = M;
100};
101
102}
103
104template<typename E>
105constexpr typename o3tl::typed_flags<E>::Wrap operator ~(E rhs) {
106 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
107 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
108 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
;
109 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
110 o3tl::typed_flags<E>::mask
111 & ~o3tl::underlyingEnumValue(rhs));
112}
113
114template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ~(
115 typename o3tl::typed_flags<E>::Wrap rhs)
116{
117 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
118 o3tl::typed_flags<E>::mask
119 & ~o3tl::underlyingEnumValue<E>(rhs));
120}
121
122template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
123 E lhs, E rhs)
124{
125 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
126 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
127 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
;
128 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
129 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
130 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
;
131 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
132 o3tl::underlyingEnumValue(lhs)
133 ^ o3tl::underlyingEnumValue(rhs));
134}
135
136template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
137 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
138{
139 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
140 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
141 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
143 o3tl::underlyingEnumValue(lhs)
144 ^ o3tl::underlyingEnumValue<E>(rhs));
145}
146
147template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
148 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
149{
150 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
151 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
152 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
;
153 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
154 o3tl::underlyingEnumValue<E>(lhs)
155 ^ o3tl::underlyingEnumValue(rhs));
156}
157
158template<typename W> constexpr
159typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator ^(
160 W lhs, W rhs)
161{
162 return static_cast<W>(
163 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
164 ^ o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
165}
166
167template<typename E>
168constexpr typename o3tl::typed_flags<E>::Wrap operator &(E lhs, E rhs) {
169 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
170 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
171 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
;
172 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
173 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
174 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
;
175 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
176 o3tl::underlyingEnumValue(lhs)
177 & o3tl::underlyingEnumValue(rhs));
178}
179
180template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
181 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
182{
183 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
184 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
185 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
;
186 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
187 o3tl::underlyingEnumValue(lhs)
188 & o3tl::underlyingEnumValue<E>(rhs));
189}
190
191template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
192 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
193{
194 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
195 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
196 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
;
197 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
198 o3tl::underlyingEnumValue<E>(lhs)
199 & o3tl::underlyingEnumValue(rhs));
200}
201
202template<typename W> constexpr
203typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator &(
204 W lhs, W rhs)
205{
206 return static_cast<W>(
207 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
208 & o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
209}
210
211template<typename E>
212constexpr typename o3tl::typed_flags<E>::Wrap operator |(E lhs, E rhs) {
213 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
214 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
215 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
;
216 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
217 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
218 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
;
219 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
220 o3tl::underlyingEnumValue(lhs)
221 | o3tl::underlyingEnumValue(rhs));
222}
223
224template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
225 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
226{
227 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
228 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
229 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
;
230 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
231 o3tl::underlyingEnumValue(lhs)
232 | o3tl::underlyingEnumValue<E>(rhs));
233}
234
235template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
236 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
237{
238 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
239 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
240 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
;
241 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
242 o3tl::underlyingEnumValue<E>(lhs)
243 | o3tl::underlyingEnumValue(rhs));
244}
245
246template<typename W> constexpr
247typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator |(
248 W lhs, W rhs)
249{
250 return static_cast<W>(
251 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
252 | o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
253}
254
255template<typename E>
256inline typename o3tl::typed_flags<E>::Self operator &=(E & lhs, E rhs) {
257 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
258 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
259 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
;
260 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
261 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
262 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
;
263 lhs = lhs & rhs;
264 return lhs;
265}
266
267template<typename E>
268inline typename o3tl::typed_flags<E>::Self operator &=(
269 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
270{
271 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
272 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
273 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
;
274 lhs = lhs & rhs;
275 return lhs;
276}
277
278template<typename E>
279inline typename o3tl::typed_flags<E>::Self operator |=(E & lhs, E rhs) {
280 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
281 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
282 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
;
283 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
284 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
285 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
;
286 lhs = lhs | rhs;
287 return lhs;
288}
289
290template<typename E>
291inline typename o3tl::typed_flags<E>::Self operator |=(
292 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
293{
294 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
295 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
296 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
;
297 lhs = lhs | rhs;
298 return lhs;
299}
300
301template<typename E>
302inline typename o3tl::typed_flags<E>::Self operator ^=(E & lhs, E rhs) {
303 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
304 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
305 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
;
306 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
307 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
308 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
;
309 lhs = lhs ^ rhs;
310 return lhs;
311}
312
313template<typename E>
314inline typename o3tl::typed_flags<E>::Self operator ^=(
315 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
316{
317 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
318 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
319 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
;
320 lhs = lhs ^ rhs;
321 return lhs;
322}
323
324#endif /* INCLUDED_O3TL_TYPED_FLAGS_SET_HXX */
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/outdev.hxx

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#ifndef INCLUDED_VCL_OUTDEV_HXX
21#define INCLUDED_VCL_OUTDEV_HXX
22
23#include <tools/gen.hxx>
24#include <tools/ref.hxx>
25#include <tools/solar.h>
26#include <tools/color.hxx>
27#include <tools/poly.hxx>
28#include <o3tl/typed_flags_set.hxx>
29#include <vcl/bitmap.hxx>
30#include <vcl/cairo.hxx>
31#include <vcl/devicecoordinate.hxx>
32#include <vcl/dllapi.h>
33#include <vcl/font.hxx>
34#include <vcl/region.hxx>
35#include <vcl/mapmod.hxx>
36#include <vcl/wall.hxx>
37#include <vcl/metaactiontypes.hxx>
38#include <vcl/salnativewidgets.hxx>
39#include <vcl/outdevstate.hxx>
40#include <vcl/outdevmap.hxx>
41#include <vcl/vclreferencebase.hxx>
42
43#include <basegfx/numeric/ftools.hxx>
44#include <basegfx/vector/b2enums.hxx>
45#include <basegfx/polygon/b2dpolypolygon.hxx>
46
47#include <unotools/fontdefs.hxx>
48
49#include <com/sun/star/drawing/LineCap.hpp>
50#include <com/sun/star/uno/Reference.h>
51
52#include <memory>
53#include <vector>
54
55struct ImplOutDevData;
56class LogicalFontInstance;
57struct SystemGraphicsData;
58class ImplFontCache;
59class PhysicalFontCollection;
60class ImplDeviceFontList;
61class ImplDeviceFontSizeList;
62class ImplMultiTextLineInfo;
63class SalGraphics;
64class Gradient;
65class Hatch;
66class AllSettings;
67class BitmapReadAccess;
68class BitmapEx;
69class Image;
70class TextRectInfo;
71class FontMetric;
72class GDIMetaFile;
73class GfxLink;
74namespace tools {
75 class Line;
76}
77class LineInfo;
78class AlphaMask;
79class FontCharMap;
80class SalLayout;
81class ImplLayoutArgs;
82class VirtualDevice;
83struct SalTwoRect;
84class Printer;
85class VCLXGraphics;
86class OutDevStateStack;
87class SalLayoutGlyphs;
88
89namespace vcl
90{
91 class ExtOutDevData;
92 class ITextLayout;
93 struct FontCapabilities;
94 class TextLayoutCache;
95 class Window;
96 namespace font {
97 struct Feature;
98 }
99}
100
101namespace basegfx {
102 class B2DHomMatrix;
103 class B2DPolygon;
104 class B2IVector;
105 typedef B2IVector B2ISize;
106}
107
108namespace com::sun::star::awt {
109 class XGraphics;
110}
111
112#if defined UNX1
113#define GLYPH_FONT_HEIGHT128 128
114#else
115#define GLYPH_FONT_HEIGHT128 256
116#endif
117
118// Text Layout options
119enum class SalLayoutFlags
120{
121 NONE = 0x0000,
122 BiDiRtl = 0x0001,
123 BiDiStrong = 0x0002,
124 RightAlign = 0x0004,
125 DisableKerning = 0x0010,
126 KerningAsian = 0x0020,
127 Vertical = 0x0040,
128 KashidaJustification = 0x0800,
129 ForFallback = 0x2000,
130 GlyphItemsOnly = 0x4000,
131};
132namespace o3tl
133{
134 template<> struct typed_flags<SalLayoutFlags> : is_typed_flags<SalLayoutFlags, 0x6877> {};
135}
136
137typedef std::vector< tools::Rectangle > MetricVector;
138
139// OutputDevice-Types
140
141// Flags for DrawText()
142enum class DrawTextFlags
143{
144 NONE = 0x00000000,
145 Disable = 0x00000001,
146 Mnemonic = 0x00000002,
147 Mono = 0x00000004,
148 Clip = 0x00000008,
149 Left = 0x00000010,
150 Center = 0x00000020,
151 Right = 0x00000040,
152 Top = 0x00000080,
153 VCenter = 0x00000100,
154 Bottom = 0x00000200,
155 EndEllipsis = 0x00000400,
156 PathEllipsis = 0x00000800,
157 MultiLine = 0x00001000,
158 WordBreak = 0x00002000,
159 NewsEllipsis = 0x00004000,
160 WordBreakHyphenation = 0x00008000 | WordBreak,
161 CenterEllipsis = 0x00010000,
162 HideMnemonic = 0x00020000,
163};
164namespace o3tl
165{
166 template<> struct typed_flags<DrawTextFlags> : is_typed_flags<DrawTextFlags, 0x3ffff> {};
167}
168
169// Flags for DrawImage(), these must match the definitions in css::awt::ImageDrawMode
170enum class DrawImageFlags
171{
172 NONE = 0x0000,
173 Disable = 0x0001,
174 Highlight = 0x0002,
175 Deactive = 0x0004,
176 ColorTransform = 0x0008,
177 SemiTransparent = 0x0010,
178};
179namespace o3tl
180{
181 template<> struct typed_flags<DrawImageFlags> : is_typed_flags<DrawImageFlags, 0x001f> {};
182}
183
184// Flags for DrawGrid()
185enum class DrawGridFlags
186{
187 NONE = 0x0000,
188 Dots = 0x0001,
189 HorzLines = 0x0002,
190 VertLines = 0x0004
191};
192namespace o3tl
193{
194 template<> struct typed_flags<DrawGridFlags> : is_typed_flags<DrawGridFlags, 0x0007> {};
195}
196
197// DrawModes
198enum class DrawModeFlags : sal_uInt32
199{
200 Default = 0x00000000,
201 BlackLine = 0x00000001,
202 BlackFill = 0x00000002,
203 BlackText = 0x00000004,
204 BlackBitmap = 0x00000008,
205 BlackGradient = 0x00000010,
206 GrayLine = 0x00000020,
207 GrayFill = 0x00000040,
208 GrayText = 0x00000080,
209 GrayBitmap = 0x00000100,
210 GrayGradient = 0x00000200,
211 NoFill = 0x00000400,
212 WhiteLine = 0x00000800,
213 WhiteFill = 0x00001000,
214 WhiteText = 0x00002000,
215 WhiteBitmap = 0x00004000,
216 WhiteGradient = 0x00008000,
217 SettingsLine = 0x00010000,
218 SettingsFill = 0x00020000,
219 SettingsText = 0x00040000,
220 SettingsGradient = 0x00080000,
221 NoTransparency = 0x00100000,
222};
223namespace o3tl
224{
225 template<> struct typed_flags<DrawModeFlags> : is_typed_flags<DrawModeFlags, 0x1fffff> {};
226}
227
228// Antialiasing
229enum class AntialiasingFlags
230{
231 NONE = 0x0000,
232 DisableText = 0x0001,
233 Enable = 0x0002,
234 PixelSnapHairline = 0x0004,
235};
236namespace o3tl
237{
238 template<> struct typed_flags<AntialiasingFlags> : is_typed_flags<AntialiasingFlags, 0x07> {};
239}
240
241// AddFontSubstitute() flags
242enum class AddFontSubstituteFlags
243{
244 NONE = 0x00,
245 ALWAYS = 0x01,
246 ScreenOnly = 0x02,
247};
248namespace o3tl
249{
250 template<> struct typed_flags<AddFontSubstituteFlags> : is_typed_flags<AddFontSubstituteFlags, 0x03> {};
251}
252
253// GetDefaultFont() flags
254enum class GetDefaultFontFlags
255{
256 NONE = 0x0000,
257 OnlyOne = 0x0001,
258};
259namespace o3tl
260{
261 template<> struct typed_flags<GetDefaultFontFlags> : is_typed_flags<GetDefaultFontFlags, 0x01> {};
262}
263
264// Flags for Invert()
265enum class InvertFlags
266{
267 NONE = 0x0000,
268 N50 = 0x0001,
269 TrackFrame = 0x0002
270};
271namespace o3tl
272{
273 template<> struct typed_flags<InvertFlags> : is_typed_flags<InvertFlags, 0x0003> {};
274}
275
276enum OutDevType { OUTDEV_WINDOW, OUTDEV_PRINTER, OUTDEV_VIRDEV, OUTDEV_PDF };
277
278enum class OutDevViewType { DontKnow, PrintPreview, SlideShow };
279
280// OutputDevice
281
282typedef tools::SvRef<FontCharMap> FontCharMapRef;
283
284BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix );
285void AdjustTwoRect( SalTwoRect& rTwoRect, const tools::Rectangle& rValidSrcRect );
286
287class OutputDevice;
288
289namespace vcl {
290 typedef OutputDevice RenderContext;
291}
292
293VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect);
294
295typedef struct _cairo_surface cairo_surface_t;
296
297/**
298* Some things multiple-inherit from VclAbstractDialog and OutputDevice,
299* so we need to use virtual inheritance to keep the referencing counting
300* OK.
301*/
302class SAL_WARN_UNUSED__attribute__((warn_unused)) VCL_DLLPUBLIC__attribute__ ((visibility("default"))) OutputDevice : public virtual VclReferenceBase
303{
304 friend class Printer;
305 friend class VirtualDevice;
306 friend class vcl::Window;
307 friend class WorkWindow;
308 friend void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight );
309
310private:
311 OutputDevice(const OutputDevice&) = delete;
312 OutputDevice& operator=(const OutputDevice&) = delete;
313
314 mutable SalGraphics* mpGraphics; ///< Graphics context to draw on
315 mutable VclPtr<OutputDevice> mpPrevGraphics; ///< Previous output device in list
316 mutable VclPtr<OutputDevice> mpNextGraphics; ///< Next output device in list
317 GDIMetaFile* mpMetaFile;
318 mutable rtl::Reference<LogicalFontInstance> mpFontInstance;
319 mutable std::shared_ptr<ImplFontCache> mxFontCache;
320 mutable std::shared_ptr<PhysicalFontCollection> mxFontCollection;
321 mutable std::unique_ptr<ImplDeviceFontList> mpDeviceFontList;
322 mutable std::unique_ptr<ImplDeviceFontSizeList> mpDeviceFontSizeList;
323 std::vector<OutDevState> maOutDevStateStack;
324 std::unique_ptr<ImplOutDevData> mpOutDevData;
325 std::vector< VCLXGraphics* >* mpUnoGraphicsList;
326 vcl::ExtOutDevData* mpExtOutDevData;
327
328 // TEMP TEMP TEMP
329 VclPtr<VirtualDevice> mpAlphaVDev;
330
331 /// Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset)
332 long mnOutOffOrigX;
333 /// Additional output offset in _logical_ coordinates, applied in PixelToLogic (used by SetPixelOffset/GetPixelOffset)
334 long mnOutOffLogicX;
335 /// Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset)
336 long mnOutOffOrigY;
337 /// Additional output offset in _logical_ coordinates, applied in PixelToLogic (used by SetPixelOffset/GetPixelOffset)
338 long mnOutOffLogicY;
339 /// Output offset for device output in pixel (pseudo window offset within window system's frames)
340 long mnOutOffX;
341 /// Output offset for device output in pixel (pseudo window offset within window system's frames)
342 long mnOutOffY;
343 long mnOutWidth;
344 long mnOutHeight;
345 sal_Int32 mnDPIX;
346 sal_Int32 mnDPIY;
347 sal_Int32 mnDPIScalePercentage; ///< For HiDPI displays, we want to draw elements for a percentage larger
348 /// font specific text alignment offsets in pixel units
349 mutable long mnTextOffX;
350 mutable long mnTextOffY;
351 mutable long mnEmphasisAscent;
352 mutable long mnEmphasisDescent;
353 DrawModeFlags mnDrawMode;
354 ComplexTextLayoutFlags mnTextLayoutMode;
355 ImplMapRes maMapRes;
356 ImplThresholdRes maThresRes;
357 const OutDevType meOutDevType;
358 OutDevViewType meOutDevViewType;
359 vcl::Region maRegion; // contains the clip region, see SetClipRegion(...)
360 Color maLineColor;
361 Color maFillColor;
362 vcl::Font maFont;
363 Color maTextColor;
364 Color maTextLineColor;
365 Color maOverlineColor;
366 RasterOp meRasterOp;
367 Wallpaper maBackground;
368 std::unique_ptr<AllSettings> mxSettings;
369 MapMode maMapMode;
370 Point maRefPoint;
371 AntialiasingFlags mnAntialiasing;
372 LanguageType meTextLanguage;
373
374 mutable bool mbMap : 1;
375 mutable bool mbClipRegion : 1;
376 mutable bool mbBackground : 1;
377 mutable bool mbOutput : 1;
378 mutable bool mbDevOutput : 1;
379 mutable bool mbOutputClipped : 1;
380 mutable bool mbLineColor : 1;
381 mutable bool mbFillColor : 1;
382 mutable bool mbInitLineColor : 1;
383 mutable bool mbInitFillColor : 1;
384 mutable bool mbInitFont : 1;
385 mutable bool mbInitTextColor : 1;
386 mutable bool mbInitClipRegion : 1;
387 mutable bool mbClipRegionSet : 1;
388 mutable bool mbNewFont : 1;
389 mutable bool mbTextLines : 1;
390 mutable bool mbTextSpecial : 1;
391 mutable bool mbRefPoint : 1;
392 mutable bool mbEnableRTL : 1;
393
394 /** @name Initialization and accessor functions
395 */
396 ///@{
397
398protected:
399 OutputDevice(OutDevType eOutDevType);
400 virtual ~OutputDevice() override;
401 virtual void dispose() override;
402
403public:
404
405 /** Get the graphic context that the output device uses to draw on.
406
407 If no graphics device exists, then initialize it.
408
409 @returns SalGraphics instance.
410 */
411 SalGraphics const *GetGraphics() const;
412 SalGraphics* GetGraphics();
413
414 void SetConnectMetaFile( GDIMetaFile* pMtf );
415 GDIMetaFile* GetConnectMetaFile() const { return mpMetaFile; }
416
417 virtual void SetSettings( const AllSettings& rSettings );
418 const AllSettings& GetSettings() const { return *mxSettings; }
419
420 SystemGraphicsData GetSystemGfxData() const;
421 bool SupportsCairo() const;
422 /// Create Surface from given cairo surface
423 cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const;
424 /// Create surface with given dimensions
425 cairo::SurfaceSharedPtr CreateSurface(int x, int y, int width, int height) const;
426 /// Create Surface for given bitmap data
427 cairo::SurfaceSharedPtr CreateBitmapSurface(const BitmapSystemData& rData, const Size& rSize) const;
428 /// Return native handle for underlying surface
429 css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const;
430 css::uno::Any GetSystemGfxDataAny() const;
431
432 void SetRefPoint();
433 void SetRefPoint( const Point& rRefPoint );
434 const Point& GetRefPoint() const { return maRefPoint; }
435 bool IsRefPoint() const { return mbRefPoint; }
436
437 virtual bool IsScreenComp() const { return true; }
438
439 virtual sal_uInt16 GetBitCount() const;
440
441 Size GetOutputSizePixel() const
442 { return Size( mnOutWidth, mnOutHeight ); }
443 long GetOutputWidthPixel() const { return mnOutWidth; }
444 long GetOutputHeightPixel() const { return mnOutHeight; }
445 long GetOutOffXPixel() const { return mnOutOffX; }
446 long GetOutOffYPixel() const { return mnOutOffY; }
447 void SetOutOffXPixel(long nOutOffX);
448 void SetOutOffYPixel(long nOutOffY);
449
450 Size GetOutputSize() const
451 { return PixelToLogic( GetOutputSizePixel() ); }
452
453 css::uno::Reference< css::awt::XGraphics >
454 CreateUnoGraphics();
455 std::vector< VCLXGraphics* > *GetUnoGraphicsList() const { return mpUnoGraphicsList; }
456 std::vector< VCLXGraphics* > *CreateUnoGraphicsList();
457
458 virtual size_t GetSyncCount() const { return 0xffffffff; }
459
460protected:
461
462 /** Acquire a graphics device that the output device uses to draw on.
463
464 There is an LRU of OutputDevices that is used to get the graphics. The
465 actual creation of a SalGraphics instance is done via the SalFrame
466 implementation.
467
468 However, the SalFrame instance will only return a valid SalGraphics
469 instance if it is not in use or there wasn't one in the first place. When
470 this happens, AcquireGraphics finds the least recently used OutputDevice
471 in a different frame and "steals" it (releases it then starts using it).
472
473 If there are no frames to steal an OutputDevice's SalGraphics instance from
474 then it blocks until the graphics is released.
475
476 Once it has acquired a graphics instance, then we add the OutputDevice to
477 the LRU.
478
479 @returns true if was able to initialize the graphics device, false otherwise.
480 */
481 virtual bool AcquireGraphics() const = 0;
482
483 /** Release the graphics device, and remove it from the graphics device
484 list.
485
486 @param bRelease Determines whether to release the fonts of the
487 physically released graphics device.
488 */
489 virtual void ReleaseGraphics( bool bRelease = true ) = 0;
490 ///@}
491
492
493 /** @name Helper functions
494 */
495 ///@{
496
497public:
498
499 /** Get the output device's DPI x-axis value.
500
501 @returns x-axis DPI value
502 */
503 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) sal_Int32 GetDPIX() const { return mnDPIX; }
504
505 /** Get the output device's DPI y-axis value.
506
507 @returns y-axis DPI value
508 */
509 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) sal_Int32 GetDPIY() const { return mnDPIY; }
510
511 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void SetDPIX( sal_Int32 nDPIX ) { mnDPIX = nDPIX; }
512 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void SetDPIY( sal_Int32 nDPIY ) { mnDPIY = nDPIY; }
513
514 float GetDPIScaleFactor() const
515 {
516 return mnDPIScalePercentage / 100.0f;
517 }
518
519 sal_Int32 GetDPIScalePercentage() const
520 {
521 return mnDPIScalePercentage;
522 }
523
524 OutDevType GetOutDevType() const { return meOutDevType; }
525 virtual bool IsVirtual() const;
526
527 /** Query an OutputDevice to see whether it supports a specific operation
528
529 @returns true if operation supported, else false
530 */
531 bool SupportsOperation( OutDevSupportType ) const;
532
533 void SetExtOutDevData( vcl::ExtOutDevData* pExtOutDevData ) { mpExtOutDevData = pExtOutDevData; }
534 vcl::ExtOutDevData* GetExtOutDevData() const { return mpExtOutDevData; }
535
536 ///@}
537
538public:
539 virtual Size GetButtonBorderSize() { return Size(1, 1); };
540 virtual Color GetMonochromeButtonColor() { return COL_WHITE; }
541
542 /** @name Direct OutputDevice drawing functions
543 */
544 ///@{
545
546public:
547 virtual void Flush() {}
548
549 virtual void DrawOutDev(
550 const Point& rDestPt, const Size& rDestSize,
551 const Point& rSrcPt, const Size& rSrcSize );
552
553 virtual void DrawOutDev(
554 const Point& rDestPt, const Size& rDestSize,
555 const Point& rSrcPt, const Size& rSrcSize,
556 const OutputDevice& rOutDev );
557
558 virtual void CopyArea(
559 const Point& rDestPt,
560 const Point& rSrcPt, const Size& rSrcSize,
561 bool bWindowInvalidate = false );
562
563protected:
564
565 virtual void CopyDeviceArea( SalTwoRect& aPosAry, bool bWindowInvalidate);
566
567 virtual tools::Rectangle GetBackgroundComponentBounds() const;
568
569 virtual const OutputDevice* DrawOutDevDirectCheck(const OutputDevice* pSrcDev) const;
570
571 virtual void DrawOutDevDirectProcess( const OutputDevice* pSrcDev, SalTwoRect& rPosAry, SalGraphics* pSrcGraphics );
572
573 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void drawOutDevDirect ( const OutputDevice* pSrcDev, SalTwoRect& rPosAry );
574
575 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool is_double_buffered_window() const;
576
577private:
578
579 // not implemented; to detect misuses of DrawOutDev(...OutputDevice&);
580 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawOutDev( const Point&, const Size&, const Point&, const Size&, const Printer&) = delete;
581 ///@}
582
583
584 /** @name OutputDevice state functions
585 */
586 ///@{
587
588public:
589
590 void Push( PushFlags nFlags = PushFlags::ALL );
591 void Pop();
592
593 // returns the current stack depth; that is the number of Push() calls minus the number of Pop() calls
594 // this should not normally be used since Push and Pop must always be used symmetrically
595 // however this may be e.g. a help when debugging code in which this somehow is not the case
596 sal_uInt32 GetGCStackDepth() const;
597 void ClearStack();
598
599 void EnableOutput( bool bEnable = true );
600 bool IsOutputEnabled() const { return mbOutput; }
601 bool IsDeviceOutputNecessary() const { return (mbOutput && mbDevOutput); }
19
Assuming field 'mbOutput' is true
20
Returning value, which participates in a condition later
602
603 void SetAntialiasing( AntialiasingFlags nMode );
604 AntialiasingFlags GetAntialiasing() const { return mnAntialiasing; }
605
606 void SetDrawMode( DrawModeFlags nDrawMode );
607 DrawModeFlags GetDrawMode() const { return mnDrawMode; }
608
609 void SetLayoutMode( ComplexTextLayoutFlags nTextLayoutMode );
610 ComplexTextLayoutFlags GetLayoutMode() const { return mnTextLayoutMode; }
611
612 void SetDigitLanguage( LanguageType );
613 LanguageType GetDigitLanguage() const { return meTextLanguage; }
614
615 void SetRasterOp( RasterOp eRasterOp );
616 RasterOp GetRasterOp() const { return meRasterOp; }
617
618 /**
619 If this OutputDevice is used for displaying a Print Preview
620 the OutDevViewType should be set to 'OutDevViewType::PrintPreview'.
621
622 A View can then make painting decisions dependent on this OutDevViewType.
623 E.g. text colors need to be handled differently, dependent on whether it's a PrintPreview or not. (see #106611# for more)
624 */
625 void SetOutDevViewType( OutDevViewType eOutDevViewType ) { meOutDevViewType=eOutDevViewType; }
626 OutDevViewType GetOutDevViewType() const { return meOutDevViewType; }
627
628 void SetLineColor();
629 void SetLineColor( const Color& rColor );
630 const Color& GetLineColor() const { return maLineColor; }
631 bool IsLineColor() const { return mbLineColor; }
632
633 void SetFillColor();
634 void SetFillColor( const Color& rColor );
635 const Color& GetFillColor() const { return maFillColor; }
636 bool IsFillColor() const { return mbFillColor; }
637
638 void SetBackground();
639 void SetBackground( const Wallpaper& rBackground );
640 virtual void SaveBackground(VirtualDevice& rSaveDevice,
641 const Point& rPos, const Size& rSize, const Size& rBackgroundSize) const;
642
643 const Wallpaper& GetBackground() const { return maBackground; }
644 virtual Color GetBackgroundColor() const;
645 virtual Color GetReadableFontColor(const Color& rFontColor, const Color& rBgColor) const;
646 bool IsBackground() const { return mbBackground; }
647
648 void SetFont( const vcl::Font& rNewFont );
649 const vcl::Font& GetFont() const { return maFont; }
650
651protected:
652
653 virtual void ImplReleaseFonts();
654
655private:
656
657 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void InitLineColor();
658
659 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void InitFillColor();
660
661 ///@}
662
663
664 /** @name Clipping functions
665 */
666 ///@{
667
668public:
669
670 vcl::Region GetClipRegion() const;
671 void SetClipRegion();
672 void SetClipRegion( const vcl::Region& rRegion );
673 bool SelectClipRegion( const vcl::Region&, SalGraphics* pGraphics = nullptr );
674
675 bool IsClipRegion() const { return mbClipRegion; }
676
677 void MoveClipRegion( long nHorzMove, long nVertMove );
678 void IntersectClipRegion( const tools::Rectangle& rRect );
679 void IntersectClipRegion( const vcl::Region& rRegion );
680
681 virtual vcl::Region GetActiveClipRegion() const;
682 virtual vcl::Region GetOutputBoundsClipRegion() const;
683
684protected:
685
686 virtual void InitClipRegion();
687
688 /** Perform actual rect clip against outdev dimensions, to generate
689 empty clips whenever one of the values is completely off the device.
690
691 @param aRegion region to be clipped to the device dimensions
692 @returns region clipped to the device bounds
693 **/
694 virtual vcl::Region ClipToDeviceBounds(vcl::Region aRegion) const;
695 virtual void ClipToPaintRegion ( tools::Rectangle& rDstRect );
696
697private:
698
699 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void SetDeviceClipRegion( const vcl::Region* pRegion );
700 ///@}
701
702public:
703 virtual void DrawBorder(tools::Rectangle aBorderRect);
704
705
706 /** @name Pixel functions
707 */
708 ///@{
709
710public:
711
712 void DrawPixel( const Point& rPt );
713 void DrawPixel( const Point& rPt, const Color& rColor );
714
715 Color GetPixel( const Point& rPt ) const;
716 ///@}
717
718
719 /** @name Rectangle functions
720 */
721 ///@{
722
723public:
724
725 void DrawRect( const tools::Rectangle& rRect );
726 void DrawRect( const tools::Rectangle& rRect,
727 sal_uLong nHorzRount, sal_uLong nVertRound );
728
729 /// Fill the given rectangle with checkered rectangles of size nLen x nLen using the colors aStart and aEnd
730 void DrawCheckered(
731 const Point& rPos,
732 const Size& rSize,
733 sal_uInt32 nLen = 8,
734 Color aStart = COL_WHITE,
735 Color aEnd = COL_BLACK);
736
737 void DrawGrid( const tools::Rectangle& rRect, const Size& rDist, DrawGridFlags nFlags );
738
739 ///@}
740
741 /** @name Invert functions
742 */
743 ///@{
744public:
745 void Invert( const tools::Rectangle& rRect, InvertFlags nFlags = InvertFlags::NONE );
746 void Invert( const tools::Polygon& rPoly, InvertFlags nFlags = InvertFlags::NONE );
747 ///@}
748
749 /** @name Line functions
750 */
751 ///@{
752
753public:
754
755 void DrawLine( const Point& rStartPt, const Point& rEndPt );
756
757 void DrawLine( const Point& rStartPt, const Point& rEndPt,
758 const LineInfo& rLineInfo );
759
760protected:
761 virtual void DrawHatchLine_DrawLine(const Point& rStartPoint, const Point& rEndPoint);
762
763private:
764
765 /** Helper for line geometry paint with support for graphic expansion (pattern and fat_to_area)
766 */
767 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void drawLine( basegfx::B2DPolyPolygon aLinePolyPolygon, const LineInfo& rInfo );
768 ///@}
769
770
771 /** @name Polyline functions
772 */
773 ///@{
774
775public:
776
777 /** Render the given polygon as a line stroke
778
779 The given polygon is stroked with the current LineColor, start
780 and end point are not automatically connected
781
782 @see DrawPolygon
783 @see DrawPolyPolygon
784 */
785 void DrawPolyLine( const tools::Polygon& rPoly );
786
787 void DrawPolyLine(
788 const basegfx::B2DPolygon&,
789 double fLineWidth = 0.0,
790 basegfx::B2DLineJoin eLineJoin = basegfx::B2DLineJoin::Round,
791 css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT,
792 double fMiterMinimumAngle = basegfx::deg2rad(15.0));
793
794 /** Render the given polygon as a line stroke
795
796 The given polygon is stroked with the current LineColor, start
797 and end point are not automatically connected. The line is
798 rendered according to the specified LineInfo, e.g. supplying a
799 dash pattern, or a line thickness.
800
801 @see DrawPolygon
802 @see DrawPolyPolygon
803 */
804 void DrawPolyLine( const tools::Polygon& rPoly,
805 const LineInfo& rLineInfo );
806
807 // #i101491#
808 // Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool.
809 bool DrawPolyLineDirect(
810 const basegfx::B2DHomMatrix& rObjectTransform,
811 const basegfx::B2DPolygon& rB2DPolygon,
812 double fLineWidth = 0.0,
813 double fTransparency = 0.0,
814 const std::vector< double >* = nullptr, // MM01
815 basegfx::B2DLineJoin eLineJoin = basegfx::B2DLineJoin::NONE,
816 css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT,
817 double fMiterMinimumAngle = basegfx::deg2rad(15.0));
818
819private:
820
821 // #i101491#
822 // Helper which holds the old line geometry creation and is extended to use AA when
823 // switched on. Advantage is that line geometry is only temporarily used for paint
824 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void drawPolyLine(const tools::Polygon& rPoly, const LineInfo& rLineInfo);
825
826 ///@}
827
828 bool DrawPolyLineDirectInternal(
829 const basegfx::B2DHomMatrix& rObjectTransform,
830 const basegfx::B2DPolygon& rB2DPolygon,
831 double fLineWidth = 0.0,
832 double fTransparency = 0.0,
833 const std::vector< double >* = nullptr, // MM01
834 basegfx::B2DLineJoin eLineJoin = basegfx::B2DLineJoin::NONE,
835 css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT,
836 double fMiterMinimumAngle = basegfx::deg2rad(15.0));
837
838 /** @name Polygon functions
839 */
840 ///@{
841
842public:
843
844 /** Render the given polygon
845
846 The given polygon is stroked with the current LineColor, and
847 filled with the current FillColor. If one of these colors are
848 transparent, the corresponding stroke or fill stays
849 invisible. Start and end point of the polygon are
850 automatically connected.
851
852 @see DrawPolyLine
853 */
854 void DrawPolygon( const tools::Polygon& rPoly );
855 void DrawPolygon( const basegfx::B2DPolygon& );
856
857 /** Render the given poly-polygon
858
859 The given poly-polygon is stroked with the current LineColor,
860 and filled with the current FillColor. If one of these colors
861 are transparent, the corresponding stroke or fill stays
862 invisible. Start and end points of the contained polygons are
863 automatically connected.
864
865 @see DrawPolyLine
866 */
867 void DrawPolyPolygon( const tools::PolyPolygon& rPolyPoly );
868 void DrawPolyPolygon( const basegfx::B2DPolyPolygon& );
869
870private:
871
872 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawPolygon( const tools::Polygon& rPoly, const tools::PolyPolygon* pClipPolyPoly = nullptr );
873 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawPolyPolygon( const tools::PolyPolygon& rPolyPoly, const tools::PolyPolygon* pClipPolyPoly );
874 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawPolyPolygon( sal_uInt16 nPoly, const tools::PolyPolygon& rPolyPoly );
875 // #i101491#
876 // Helper who implements the DrawPolyPolygon functionality for basegfx::B2DPolyPolygon
877 // without MetaFile processing
878 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly);
879 ///@}
880
881
882 /** @name Curved shape functions
883 */
884 ///@{
885
886public:
887
888 void DrawEllipse( const tools::Rectangle& rRect );
889
890 void DrawArc(
891 const tools::Rectangle& rRect,
892 const Point& rStartPt, const Point& rEndPt );
893
894 void DrawPie(
895 const tools::Rectangle& rRect,
896 const Point& rStartPt, const Point& rEndPt );
897
898 void DrawChord(
899 const tools::Rectangle& rRect,
900 const Point& rStartPt, const Point& rEndPt );
901
902 ///@}
903
904
905 /** @name Gradient functions
906 */
907 ///@{
908
909public:
910 void DrawGradient( const tools::Rectangle& rRect, const Gradient& rGradient );
911 void DrawGradient( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient );
912
913 void AddGradientActions(
914 const tools::Rectangle& rRect,
915 const Gradient& rGradient,
916 GDIMetaFile& rMtf );
917
918protected:
919
920 virtual bool UsePolyPolygonForComplexGradient() = 0;
921
922 virtual long GetGradientStepCount( long nMinRect );
923
924private:
925
926 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawLinearGradient( const tools::Rectangle& rRect, const Gradient& rGradient, const tools::PolyPolygon* pClipPolyPoly );
927 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawComplexGradient( const tools::Rectangle& rRect, const Gradient& rGradient, const tools::PolyPolygon* pClipPolyPoly );
928
929 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawGradientToMetafile( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient );
930 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawLinearGradientToMetafile( const tools::Rectangle& rRect, const Gradient& rGradient );
931 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawComplexGradientToMetafile( const tools::Rectangle& rRect, const Gradient& rGradient );
932
933 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long GetGradientSteps( const Gradient& rGradient, const tools::Rectangle& rRect, bool bMtf, bool bComplex=false );
934
935 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Color GetSingleColorGradientFill();
936 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void SetGrayscaleColors( Gradient &rGradient );
937 ///@}
938
939
940 /** @name Hatch functions
941 */
942 ///@{
943
944public:
945
946#ifdef _MSC_VER
947 void DrawHatch( const tools::PolyPolygon& rPolyPoly, const ::Hatch& rHatch );
948 void AddHatchActions( const tools::PolyPolygon& rPolyPoly,
949 const ::Hatch& rHatch,
950 GDIMetaFile& rMtf );
951#else
952 void DrawHatch( const tools::PolyPolygon& rPolyPoly, const Hatch& rHatch );
953 void AddHatchActions( const tools::PolyPolygon& rPolyPoly,
954 const Hatch& rHatch,
955 GDIMetaFile& rMtf );
956#endif
957
958 void DrawHatch( const tools::PolyPolygon& rPolyPoly, const Hatch& rHatch, bool bMtf );
959
960private:
961
962 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void CalcHatchValues( const tools::Rectangle& rRect, long nDist, sal_uInt16 nAngle10, Point& rPt1, Point& rPt2, Size& rInc, Point& rEndPt1 );
963 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawHatchLine( const tools::Line& rLine, const tools::PolyPolygon& rPolyPoly, Point* pPtBuffer, bool bMtf );
964 ///@}
965
966
967 /** @name Wallpaper functions
968 */
969 ///@{
970
971public:
972 void DrawWallpaper( const tools::Rectangle& rRect, const Wallpaper& rWallpaper );
973
974 void Erase();
975 void Erase(const tools::Rectangle& rRect);
976
977protected:
978 void DrawGradientWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper );
979
980private:
981 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper );
982 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawColorWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper );
983 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawBitmapWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper );
984 ///@}
985
986
987 /** @name Text functions
988 */
989 ///@{
990
991public:
992
993 void DrawText( const Point& rStartPt, const OUString& rStr,
994 sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
995 MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr,
996 const SalLayoutGlyphs* pLayoutCache = nullptr );
997
998 void DrawText( const tools::Rectangle& rRect,
999 const OUString& rStr, DrawTextFlags nStyle = DrawTextFlags::NONE,
1000 MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr,
1001 vcl::ITextLayout* _pTextLayout = nullptr );
1002
1003 static void ImplDrawText( OutputDevice& rTargetDevice, const tools::Rectangle& rRect,
1004 const OUString& rOrigStr, DrawTextFlags nStyle,
1005 MetricVector* pVector, OUString* pDisplayText, vcl::ITextLayout& _rLayout );
1006
1007 void ImplDrawText( SalLayout& );
1008
1009 void ImplDrawTextBackground( const SalLayout& );
1010
1011 void DrawCtrlText( const Point& rPos, const OUString& rStr,
1012 sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
1013 DrawTextFlags nStyle = DrawTextFlags::Mnemonic, MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr,
1014 const SalLayoutGlyphs* pGlyphs = nullptr);
1015
1016 void DrawTextLine( const Point& rPos, long nWidth,
1017 FontStrikeout eStrikeout,
1018 FontLineStyle eUnderline,
1019 FontLineStyle eOverline,
1020 bool bUnderlineAbove = false );
1021
1022 void ImplDrawTextLine( long nBaseX, long nX, long nY, DeviceCoordinate nWidth,
1023 FontStrikeout eStrikeout, FontLineStyle eUnderline,
1024 FontLineStyle eOverline, bool bUnderlineAbove );
1025
1026 void ImplDrawTextLines( SalLayout&, FontStrikeout eStrikeout, FontLineStyle eUnderline,
1027 FontLineStyle eOverline, bool bWordLine, bool bUnderlineAbove );
1028
1029 void DrawWaveLine( const Point& rStartPos, const Point& rEndPos, long nLineWidth = 1 );
1030
1031 bool ImplDrawRotateText( SalLayout& );
1032
1033 tools::Rectangle GetTextRect( const tools::Rectangle& rRect,
1034 const OUString& rStr, DrawTextFlags nStyle = DrawTextFlags::WordBreak,
1035 TextRectInfo* pInfo = nullptr,
1036 const vcl::ITextLayout* _pTextLayout = nullptr ) const;
1037
1038 /** Return the exact bounding rectangle of rStr.
1039
1040 The text is then drawn exactly from rRect.TopLeft() to
1041 rRect.BottomRight(), don't assume that rRect.TopLeft() is [0, 0].
1042
1043 Please note that you don't always want to use GetTextBoundRect(); in
1044 many cases you actually want to use GetTextHeight(), because
1045 GetTextBoundRect() gives you the exact bounding rectangle regardless
1046 what is the baseline of the text.
1047
1048 Code snippet to get just exactly the text (no filling around that) as
1049 a bitmap via a VirtualDevice (regardless what is the baseline):
1050
1051 <code>
1052 VirtualDevice aDevice;
1053 vcl::Font aFont = aDevice.GetFont();
1054 aFont.SetSize(Size(0, 96));
1055 aFont.SetColor(COL_BLACK);
1056 aDevice.SetFont(aFont);
1057 aDevice.Erase();
1058
1059 tools::Rectangle aRect;
1060 aDevice.GetTextBoundRect(aRect, aText);
1061 aDevice.SetOutputSize(Size(aRect.BottomRight().X() + 1, aRect.BottomRight().Y() + 1));
1062 aDevice.SetBackground(Wallpaper(COL_TRANSPARENT));
1063 aDevice.DrawText(Point(0,0), aText);
1064
1065 // exactly only the text, regardless of the baseline
1066 Bitmap aBitmap(aDevice.GetBitmap(aRect.TopLeft(), aRect.GetSize()));
1067 </code>
1068
1069 Code snippet to get the text as a bitmap via a Virtual device that
1070 contains even the filling so that the baseline is always preserved
1071 (ie. the text will not jump up and down according to whether it
1072 contains 'y' or not etc.)
1073
1074 <code>
1075 VirtualDevice aDevice;
1076 // + the appropriate font / device setup, see above
1077
1078 aDevice.SetOutputSize(Size(aDevice.GetTextWidth(aText), aDevice.GetTextHeight()));
1079 aDevice.SetBackground(Wallpaper(COL_TRANSPARENT));
1080 aDevice.DrawText(Point(0,0), aText);
1081
1082 // bitmap that contains even the space around the text,
1083 // that means, preserves the baseline etc.
1084 Bitmap aBitmap(aDevice.GetBitmap(Point(0, 0), aDevice.GetOutputSize()));
1085 </code>
1086 */
1087 bool GetTextBoundRect( tools::Rectangle& rRect,
1088 const OUString& rStr, sal_Int32 nBase = 0, sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
1089 sal_uLong nLayoutWidth = 0, const long* pDXArray = nullptr,
1090 const SalLayoutGlyphs* pGlyphs = nullptr ) const;
1091
1092 tools::Rectangle ImplGetTextBoundRect( const SalLayout& );
1093
1094 bool GetTextOutline( tools::PolyPolygon&,
1095 const OUString& rStr ) const;
1096
1097 bool GetTextOutlines( PolyPolyVector&,
1098 const OUString& rStr, sal_Int32 nBase = 0, sal_Int32 nIndex = 0,
1099 sal_Int32 nLen = -1,
1100 sal_uLong nLayoutWidth = 0, const long* pDXArray = nullptr ) const;
1101
1102 bool GetTextOutlines( basegfx::B2DPolyPolygonVector &rVector,
1103 const OUString& rStr, sal_Int32 nBase, sal_Int32 nIndex = 0,
1104 sal_Int32 nLen = -1,
1105 sal_uLong nLayoutWidth = 0, const long* pDXArray = nullptr ) const;
1106
1107
1108 OUString GetEllipsisString( const OUString& rStr, long nMaxWidth,
1109 DrawTextFlags nStyle = DrawTextFlags::EndEllipsis ) const;
1110
1111 long GetCtrlTextWidth( const OUString& rStr,
1112 const SalLayoutGlyphs* pLayoutCache = nullptr ) const;
1113
1114 static OUString GetNonMnemonicString( const OUString& rStr, sal_Int32& rMnemonicPos );
1115
1116 static OUString GetNonMnemonicString( const OUString& rStr )
1117 { sal_Int32 nDummy; return GetNonMnemonicString( rStr, nDummy ); }
1118
1119 /** Generate MetaTextActions for the text rect
1120
1121 This method splits up the text rect into multiple
1122 MetaTextActions, one for each line of text. This is comparable
1123 to AddGradientActions(), which splits up a gradient into its
1124 constituent polygons. Parameter semantics fully compatible to
1125 DrawText().
1126 */
1127 void AddTextRectActions( const tools::Rectangle& rRect,
1128 const OUString& rOrigStr,
1129 DrawTextFlags nStyle,
1130 GDIMetaFile& rMtf );
1131
1132 void SetTextColor( const Color& rColor );
1133 const Color& GetTextColor() const { return maTextColor; }
1134
1135 void SetTextFillColor();
1136 void SetTextFillColor( const Color& rColor );
1137 Color GetTextFillColor() const;
1138 bool IsTextFillColor() const { return !maFont.IsTransparent(); }
1139
1140 void SetTextLineColor();
1141 void SetTextLineColor( const Color& rColor );
1142 const Color& GetTextLineColor() const { return maTextLineColor; }
1143 bool IsTextLineColor() const { return (maTextLineColor.GetTransparency() == 0); }
1144
1145 void SetOverlineColor();
1146 void SetOverlineColor( const Color& rColor );
1147 const Color& GetOverlineColor() const { return maOverlineColor; }
1148 bool IsOverlineColor() const { return (maOverlineColor.GetTransparency() == 0); }
1149
1150 void SetTextAlign( TextAlign eAlign );
1151 TextAlign GetTextAlign() const { return maFont.GetAlignment(); }
1152
1153 /** Width of the text.
1154
1155 See also GetTextBoundRect() for more explanation + code examples.
1156 */
1157 long GetTextWidth( const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
1158 vcl::TextLayoutCache const* = nullptr,
1159 SalLayoutGlyphs const*const pLayoutCache = nullptr) const;
1160
1161 /** Height where any character of the current font fits; in logic coordinates.
1162
1163 See also GetTextBoundRect() for more explanation + code examples.
1164 */
1165 long GetTextHeight() const;
1166 float approximate_digit_width() const;
1167
1168 void DrawTextArray( const Point& rStartPt, const OUString& rStr,
1169 const long* pDXAry,
1170 sal_Int32 nIndex = 0,
1171 sal_Int32 nLen = -1,
1172 SalLayoutFlags flags = SalLayoutFlags::NONE,
1173 const SalLayoutGlyphs* pLayoutCache = nullptr);
1174 long GetTextArray( const OUString& rStr, long* pDXAry,
1175 sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
1176 vcl::TextLayoutCache const* = nullptr,
1177 SalLayoutGlyphs const*const pLayoutCache = nullptr) const;
1178
1179 void GetCaretPositions( const OUString&, long* pCaretXArray,
1180 sal_Int32 nIndex, sal_Int32 nLen,
1181 const SalLayoutGlyphs* pGlyphs = nullptr ) const;
1182 void DrawStretchText( const Point& rStartPt, sal_uLong nWidth,
1183 const OUString& rStr,
1184 sal_Int32 nIndex = 0, sal_Int32 nLen = -1);
1185 sal_Int32 GetTextBreak( const OUString& rStr, long nTextWidth,
1186 sal_Int32 nIndex, sal_Int32 nLen = -1,
1187 long nCharExtra = 0,
1188 vcl::TextLayoutCache const* = nullptr,
1189 const SalLayoutGlyphs* pGlyphs = nullptr) const;
1190 sal_Int32 GetTextBreak( const OUString& rStr, long nTextWidth,
1191 sal_Unicode nExtraChar, sal_Int32& rExtraCharPos,
1192 sal_Int32 nIndex, sal_Int32 nLen,
1193 long nCharExtra,
1194 vcl::TextLayoutCache const* = nullptr) const;
1195 static std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&);
1196
1197protected:
1198 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplInitTextLineSize();
1199 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplInitAboveTextLineSize();
1200 static
1201 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo, long nWidth, const OUString& rStr, DrawTextFlags nStyle, const vcl::ITextLayout& _rLayout );
1202 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) float approximate_char_width() const;
1203private:
1204 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplInitTextColor();
1205
1206 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawTextDirect( SalLayout&, bool bTextLines);
1207 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawSpecialText( SalLayout& );
1208 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawTextRect( long nBaseX, long nBaseY, long nX, long nY, long nWidth, long nHeight );
1209
1210 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static void ImplDrawWavePixel( long nOriginX, long nOriginY, long nCurX, long nCurY, short nOrientation, SalGraphics* pGraphics, OutputDevice const * pOutDev,
1211 bool bDrawPixAsRect, long nPixWidth, long nPixHeight );
1212 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawWaveLine( long nBaseX, long nBaseY, long nStartX, long nStartY, long nWidth, long nHeight, long nLineWidth, short nOrientation, const Color& rColor );
1213 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawWaveTextLine( long nBaseX, long nBaseY, long nX, long nY, long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove );
1214 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawStraightTextLine( long nBaseX, long nBaseY, long nX, long nY, long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove );
1215 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawStrikeoutLine( long nBaseX, long nBaseY, long nX, long nY, long nWidth, FontStrikeout eStrikeout, Color aColor );
1216 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawStrikeoutChar( long nBaseX, long nBaseY, long nX, long nY, long nWidth, FontStrikeout eStrikeout, Color aColor );
1217 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawMnemonicLine( long nX, long nY, long nWidth );
1218
1219
1220 ///@}
1221
1222
1223 /** @name Font functions
1224 */
1225 ///@{
1226
1227public:
1228
1229 FontMetric GetDevFont( int nDevFontIndex ) const;
1230 int GetDevFontCount() const;
1231
1232 bool IsFontAvailable( const OUString& rFontName ) const;
1233
1234 Size GetDevFontSize( const vcl::Font& rFont, int nSizeIndex ) const;
1235 int GetDevFontSizeCount( const vcl::Font& ) const;
1236
1237 bool AddTempDevFont( const OUString& rFileURL, const OUString& rFontName );
1238 void RefreshFontData( const bool bNewFontLists );
1239
1240 FontMetric GetFontMetric() const;
1241 FontMetric GetFontMetric( const vcl::Font& rFont ) const;
1242
1243 bool GetFontCharMap( FontCharMapRef& rxFontCharMap ) const;
1244 bool GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities ) const;
1245
1246 bool GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const;
1247
1248 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplGetEmphasisMark( tools::PolyPolygon& rPolyPoly, bool& rPolyLine, tools::Rectangle& rRect1, tools::Rectangle& rRect2,
1249 long& rYOff, long& rWidth, FontEmphasisMark eEmphasis, long nHeight );
1250 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static FontEmphasisMark
1251 ImplGetEmphasisMarkStyle( const vcl::Font& rFont );
1252
1253 bool GetGlyphBoundRects( const Point& rOrigin, const OUString& rStr, int nIndex,
1254 int nLen, MetricVector& rVector );
1255
1256 sal_Int32 HasGlyphs( const vcl::Font& rFont, const OUString& rStr,
1257 sal_Int32 nIndex = 0, sal_Int32 nLen = -1 ) const;
1258
1259 long GetMinKashida() const;
1260
1261 // i60594
1262 // validate kashida positions against the current font
1263 // returns count of invalid kashida positions
1264 sal_Int32 ValidateKashidas( const OUString& rTxt, sal_Int32 nIdx, sal_Int32 nLen,
1265 sal_Int32 nKashCount, // number of suggested kashida positions (in)
1266 const sal_Int32* pKashidaPos, // suggested kashida positions (in)
1267 sal_Int32* pKashidaPosDropped // invalid kashida positions (out)
1268 ) const;
1269
1270 static void BeginFontSubstitution();
1271 static void EndFontSubstitution();
1272 static void AddFontSubstitute( const OUString& rFontName,
1273 const OUString& rReplaceFontName,
1274 AddFontSubstituteFlags nFlags );
1275 static void RemoveFontsSubstitute();
1276
1277 static vcl::Font GetDefaultFont( DefaultFontType nType,
1278 LanguageType eLang,
1279 GetDefaultFontFlags nFlags,
1280 const OutputDevice* pOutDev = nullptr );
1281
1282 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplInitFontList() const;
1283 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplUpdateFontData();
1284
1285 //drop font data for all outputdevices.
1286 //If bNewFontLists is true then empty lists of system fonts
1287 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static void ImplClearAllFontData( bool bNewFontLists );
1288 //fetch font data for all outputdevices
1289 //If bNewFontLists is true then fetch lists of system fonts
1290 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static void ImplRefreshAllFontData( bool bNewFontLists );
1291 //drop and fetch font data for all outputdevices
1292 //If bNewFontLists is true then drop and refetch lists of system fonts
1293 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static void ImplUpdateAllFontData( bool bNewFontLists );
1294
1295 // Lock font updates for all output devices
1296 static void LockFontUpdates(bool bLock);
1297
1298protected:
1299 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) const LogicalFontInstance* GetFontInstance() const;
1300 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long GetEmphasisAscent() const { return mnEmphasisAscent; }
1301 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long GetEmphasisDescent() const { return mnEmphasisDescent; }
1302
1303 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool InitFont() const;
1304 virtual void SetFontOrientation( LogicalFontInstance* const pFontInstance ) const;
1305 virtual long GetFontExtLeading() const;
1306
1307 virtual void ImplClearFontData(bool bNewFontLists);
1308 virtual void ImplRefreshFontData(bool bNewFontLists);
1309 void ReleaseFontCache();
1310 void ReleaseFontCollection();
1311 void SetFontCollectionFromSVData();
1312 void ResetNewFontCache();
1313
1314private:
1315
1316 typedef void ( OutputDevice::* FontUpdateHandler_t )( bool );
1317
1318 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool ImplNewFont() const;
1319
1320 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static void ImplUpdateFontDataForAllFrames( FontUpdateHandler_t pHdl, bool bNewFontLists );
1321
1322 static
1323 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) OUString ImplGetEllipsisString( const OutputDevice& rTargetDevice, const OUString& rStr,
1324 long nMaxWidth, DrawTextFlags nStyle, const vcl::ITextLayout& _rLayout );
1325
1326 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawEmphasisMark( long nBaseX, long nX, long nY, const tools::PolyPolygon& rPolyPoly, bool bPolyLine, const tools::Rectangle& rRect1, const tools::Rectangle& rRect2 );
1327 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplDrawEmphasisMarks( SalLayout& );
1328 ///@}
1329
1330
1331 /** @name Layout functions
1332 */
1333 ///@{
1334
1335public:
1336
1337 // tells whether this output device is RTL in an LTR UI or LTR in a RTL UI
1338 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool ImplIsAntiparallel() const ;
1339 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ReMirror( Point &rPoint ) const;
1340 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ReMirror( tools::Rectangle &rRect ) const;
1341 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ReMirror( vcl::Region &rRegion ) const;
1342 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool ImplIsRecordLayout() const;
1343 virtual bool HasMirroredGraphics() const;
1344 std::unique_ptr<SalLayout>
1345 ImplLayout( const OUString&, sal_Int32 nIndex, sal_Int32 nLen,
1346 const Point& rLogicPos = Point(0,0), long nLogicWidth=0,
1347 const long* pLogicDXArray=nullptr, SalLayoutFlags flags = SalLayoutFlags::NONE,
1348 vcl::TextLayoutCache const* = nullptr,
1349 const SalLayoutGlyphs* pGlyphs = nullptr) const;
1350 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) ImplLayoutArgs ImplPrepareLayoutArgs( OUString&, const sal_Int32 nIndex, const sal_Int32 nLen,
1351 DeviceCoordinate nPixelWidth, const DeviceCoordinate* pPixelDXArray,
1352 SalLayoutFlags flags = SalLayoutFlags::NONE,
1353 vcl::TextLayoutCache const* = nullptr) const;
1354 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) std::unique_ptr<SalLayout>
1355 ImplGlyphFallbackLayout( std::unique_ptr<SalLayout>, ImplLayoutArgs& ) const;
1356 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) std::unique_ptr<SalLayout>
1357 getFallbackLayout(
1358 LogicalFontInstance* pLogicalFont, int nFallbackLevel,
1359 ImplLayoutArgs& rLayoutArgs) const;
1360
1361
1362 // Enabling/disabling RTL only makes sense for OutputDevices that use a mirroring SalGraphicsLayout
1363 virtual void EnableRTL( bool bEnable = true);
1364 bool IsRTLEnabled() const { return mbEnableRTL; }
1365
1366 bool GetTextIsRTL( const OUString&, sal_Int32 nIndex, sal_Int32 nLen ) const;
1367
1368 ///@}
1369
1370
1371 /** @name Bitmap functions
1372 */
1373 ///@{
1374
1375public:
1376
1377 /** @overload
1378 void DrawBitmap(
1379 const Point& rDestPt,
1380 const Size& rDestSize,
1381 const Point& rSrcPtPixel,
1382 const Size& rSecSizePixel,
1383 const Bitmap& rBitmap,
1384 MetaActionType nAction = MetaActionType::BMPSCALEPART)
1385 */
1386 void DrawBitmap(
1387 const Point& rDestPt,
1388 const Bitmap& rBitmap );
1389
1390 /** @overload
1391 void DrawBitmap(
1392 const Point& rDestPt,
1393 const Size& rDestSize,
1394 const Point& rSrcPtPixel,
1395 const Size& rSecSizePixel,
1396 const Bitmap& rBitmap,
1397 MetaActionType nAction = MetaActionType::BMPSCALEPART)
1398 */
1399 void DrawBitmap(
1400 const Point& rDestPt,
1401 const Size& rDestSize,
1402 const Bitmap& rBitmap );
1403
1404 void DrawBitmap(
1405 const Point& rDestPt,
1406 const Size& rDestSize,
1407 const Point& rSrcPtPixel,
1408 const Size& rSrcSizePixel,
1409 const Bitmap& rBitmap,
1410 MetaActionType nAction = MetaActionType::BMPSCALEPART );
1411
1412 /** @overload
1413 void DrawBitmapEx(
1414 const Point& rDestPt,
1415 const Size& rDestSize,
1416 const Point& rSrcPtPixel,
1417 const Size& rSecSizePixel,
1418 const BitmapEx& rBitmapEx,
1419 MetaActionType nAction = MetaActionType::BMPEXSCALEPART)
1420 */
1421 void DrawBitmapEx(
1422 const Point& rDestPt,
1423 const BitmapEx& rBitmapEx );
1424
1425
1426 /** @overload
1427 void DrawBitmapEx(
1428 const Point& rDestPt,
1429 const Size& rDestSize,
1430 const Point& rSrcPtPixel,
1431 const Size& rSecSizePixel,
1432 const BitmapEx& rBitmapEx,
1433 MetaActionType nAction = MetaActionType::BMPEXSCALEPART)
1434 */
1435 void DrawBitmapEx(
1436 const Point& rDestPt,
1437 const Size& rDestSize,
1438 const BitmapEx& rBitmapEx );
1439
1440 void DrawBitmapEx(
1441 const Point& rDestPt,
1442 const Size& rDestSize,
1443 const Point& rSrcPtPixel,
1444 const Size& rSrcSizePixel,
1445 const BitmapEx& rBitmapEx,
1446 MetaActionType nAction = MetaActionType::BMPEXSCALEPART );
1447
1448 /** @overload
1449 virtual void DrawImage(
1450 const Point& rPos,
1451 const Size& rSize,
1452 const Image& rImage,
1453 sal_uInt16 nStyle = 0)
1454 */
1455 void DrawImage(
1456 const Point& rPos,
1457 const Image& rImage,
1458 DrawImageFlags nStyle = DrawImageFlags::NONE );
1459
1460 void DrawImage(
1461 const Point& rPos,
1462 const Size& rSize,
1463 const Image& rImage,
1464 DrawImageFlags nStyle = DrawImageFlags::NONE );
1465
1466
1467 virtual Bitmap GetBitmap( const Point& rSrcPt, const Size& rSize ) const;
1468
1469 /** Query extended bitmap (with alpha channel, if available).
1470 */
1471 BitmapEx GetBitmapEx( const Point& rSrcPt, const Size& rSize ) const;
1472
1473
1474 /** Draw BitmapEx transformed
1475
1476 @param rTransformation
1477 The transformation describing the target positioning of the given bitmap. Transforming
1478 the unit object coordinates (0, 0, 1, 1) with this matrix is the transformation to
1479 discrete coordinates
1480
1481 @param rBitmapEx
1482 The BitmapEx to be painted
1483 */
1484 void DrawTransformedBitmapEx(
1485 const basegfx::B2DHomMatrix& rTransformation,
1486 const BitmapEx& rBitmapEx);
1487
1488 void DrawShadowBitmapEx(
1489 const BitmapEx& rBitmapEx,
1490 ::Color aShadowColor);
1491protected:
1492
1493 virtual void DrawDeviceBitmap(
1494 const Point& rDestPt, const Size& rDestSize,
1495 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
1496 BitmapEx& rBitmapEx );
1497
1498 virtual void ScaleBitmap ( Bitmap &rBmp, SalTwoRect &rPosAry );
1499
1500 /** Transform and draw a bitmap directly
1501
1502 @param aFullTransform The B2DHomMatrix used for the transformation
1503 @param rBitmapEx Reference to the bitmap to be transformed and drawn
1504
1505 @return true if it was able to draw the bitmap, false if not
1506 */
1507 virtual bool DrawTransformBitmapExDirect(
1508 const basegfx::B2DHomMatrix& aFullTransform,
1509 const BitmapEx& rBitmapEx);
1510
1511 /** Transform and reduce the area that needs to be drawn of the bitmap and return the new
1512 visible range and the maximum area.
1513
1514
1515 @param aFullTransform B2DHomMatrix used for transformation
1516 @param aVisibleRange The new visible area of the bitmap
1517 @param fMaximumArea The maximum area of the bitmap
1518
1519 @returns true if there is an area to be drawn, otherwise nothing is left to be drawn
1520 so return false
1521 */
1522 virtual bool TransformAndReduceBitmapExToTargetRange(
1523 const basegfx::B2DHomMatrix& aFullTransform,
1524 basegfx::B2DRange &aVisibleRange,
1525 double &fMaximumArea);
1526
1527private:
1528
1529 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawDeviceAlphaBitmap(
1530 const Bitmap& rBmp,
1531 const AlphaMask& rAlpha,
1532 const Point& rDestPt,
1533 const Size& rDestSize,
1534 const Point& rSrcPtPixel,
1535 const Size& rSrcSizePixel );
1536
1537 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void DrawDeviceAlphaBitmapSlowPath(
1538 const Bitmap& rBitmap, const AlphaMask& rAlpha,
1539 tools::Rectangle aDstRect, tools::Rectangle aBmpRect,
1540 Size const & aOutSz, Point const & aOutPt);
1541
1542
1543 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void BlendBitmap(
1544 const SalTwoRect& rPosAry,
1545 const Bitmap& rBmp );
1546
1547 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Bitmap BlendBitmap(
1548 Bitmap& aBmp,
1549 BitmapReadAccess const * pP,
1550 BitmapReadAccess const * pA,
1551 const sal_Int32 nOffY,
1552 const sal_Int32 nDstHeight,
1553 const sal_Int32 nOffX,
1554 const sal_Int32 nDstWidth,
1555 const tools::Rectangle& aBmpRect,
1556 const Size& aOutSz,
1557 const bool bHMirr,
1558 const bool bVMirr,
1559 const long* pMapX,
1560 const long* pMapY );
1561
1562 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Bitmap BlendBitmapWithAlpha(
1563 Bitmap& aBmp,
1564 BitmapReadAccess const * pP,
1565 BitmapReadAccess const * pA,
1566 const tools::Rectangle& aDstRect,
1567 const sal_Int32 nOffY,
1568 const sal_Int32 nDstHeight,
1569 const sal_Int32 nOffX,
1570 const sal_Int32 nDstWidth,
1571 const long* pMapX,
1572 const long* pMapY );
1573
1574 /** Retrieve downsampled and cropped bitmap
1575
1576 @attention This method ignores negative rDstSz values, thus
1577 mirroring must happen outside this method (e.g. in DrawBitmap)
1578 */
1579 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Bitmap GetDownsampledBitmap(
1580 const Size& rDstSz,
1581 const Point& rSrcPt,
1582 const Size& rSrcSz,
1583 const Bitmap& rBmp,
1584 long nMaxBmpDPIX,
1585 long nMaxBmpDPIY );
1586
1587 ///@}
1588
1589
1590 /** @name Transparency functions
1591 */
1592 ///@{
1593
1594public:
1595
1596 /** helper method removing transparencies from a metafile (e.g. for printing)
1597
1598 @returns
1599 true: transparencies were removed
1600 false: output metafile is unchanged input metafile
1601
1602 @attention this is a member method, so current state can influence the result !
1603 @attention the output metafile is prepared in pixel mode for the currentOutputDevice
1604 state. It can not be moved or rotated reliably anymore.
1605 */
1606 bool RemoveTransparenciesFromMetaFile(
1607 const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf,
1608 long nMaxBmpDPIX, long nMaxBmpDPIY,
1609 bool bReduceTransparency,
1610 bool bTransparencyAutoMode,
1611 bool bDownsampleBitmaps,
1612 const Color& rBackground = COL_TRANSPARENT );
1613
1614 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplPrintTransparent (
1615 const Bitmap& rBmp, const Bitmap& rMask,
1616 const Point& rDestPt, const Size& rDestSize,
1617 const Point& rSrcPtPixel, const Size& rSrcSizePixel );
1618
1619 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Color ImplDrawModeToColor ( const Color& rColor ) const;
1620
1621
1622 void DrawTransparent( const tools::PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent );
1623
1624 void DrawTransparent(
1625 const basegfx::B2DHomMatrix& rObjectTransform,
1626 const basegfx::B2DPolyPolygon& rB2DPolyPoly,
1627 double fTransparency);
1628
1629 void DrawTransparent(
1630 const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize,
1631 const Gradient& rTransparenceGradient );
1632
1633protected:
1634
1635 virtual void EmulateDrawTransparent( const tools::PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent );
1636 void DrawInvisiblePolygon( const tools::PolyPolygon& rPolyPoly );
1637
1638 virtual void ClipAndDrawGradientMetafile ( const Gradient &rGradient, const tools::PolyPolygon &rPolyPoly );
1639
1640private:
1641
1642 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool DrawTransparentNatively( const tools::PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent );
1643 ///@}
1644
1645
1646 /** @name Mask functions
1647 */
1648 ///@{
1649
1650public:
1651
1652 void DrawMask( const Point& rDestPt,
1653 const Bitmap& rBitmap, const Color& rMaskColor );
1654
1655 void DrawMask( const Point& rDestPt, const Size& rDestSize,
1656 const Bitmap& rBitmap, const Color& rMaskColor );
1657
1658 void DrawMask( const Point& rDestPt, const Size& rDestSize,
1659 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
1660 const Bitmap& rBitmap, const Color& rMaskColor,
1661 MetaActionType nAction );
1662
1663protected:
1664
1665 virtual void DrawDeviceMask (
1666 const Bitmap& rMask, const Color& rMaskColor,
1667 const Point& rDestPt, const Size& rDestSize,
1668 const Point& rSrcPtPixel, const Size& rSrcSizePixel );
1669 ///@}
1670
1671
1672 /** @name Map functions
1673 */
1674 ///@{
1675
1676public:
1677
1678 void EnableMapMode( bool bEnable = true );
1679 bool IsMapModeEnabled() const { return mbMap; }
1680
1681 void SetMapMode();
1682 virtual void SetMapMode( const MapMode& rNewMapMode );
1683 void SetRelativeMapMode( const MapMode& rNewMapMode );
1684 virtual void SetMetafileMapMode(const MapMode& rNewMapMode, bool bIsRecord);
1685 const MapMode& GetMapMode() const { return maMapMode; }
1686
1687protected:
1688 virtual void ImplInitMapModeObjects();
1689
1690public:
1691 // #i75163#
1692 basegfx::B2DHomMatrix GetViewTransformation() const;
1693 basegfx::B2DHomMatrix GetInverseViewTransformation() const;
1694
1695 basegfx::B2DHomMatrix GetViewTransformation( const MapMode& rMapMode ) const;
1696 basegfx::B2DHomMatrix GetInverseViewTransformation( const MapMode& rMapMode ) const;
1697
1698
1699 /** Set an offset in pixel
1700
1701 This method offsets every drawing operation that converts its
1702 coordinates to pixel by the given value. Normally, the effect
1703 can be achieved by setting a MapMode with a different
1704 origin. Unfortunately, this origin is in logical coordinates
1705 and can lead to rounding errors (see #102532# for details).
1706
1707 @attention This offset is only applied when converting to
1708 pixel, i.e. some output modes such as metafile recordings
1709 might be completely unaffected by this method! Use with
1710 care. Furthermore, if the OutputDevice's MapMode is the
1711 default (that's MapUnit::MapPixel), then any pixel offset set is
1712 ignored also. This might be unintuitive for cases, but would
1713 have been far more fragile to implement. What's more, the
1714 reason why the pixel offset was introduced (avoiding rounding
1715 errors) does not apply for MapUnit::MapPixel, because one can always
1716 use the MapMode origin then.
1717
1718 @param rOffset
1719 The offset in pixel
1720 */
1721 void SetPixelOffset( const Size& rOffset );
1722
1723 /** Get the offset in pixel
1724
1725 @see OutputDevice::SetPixelOffset for details
1726
1727 @return the current offset in pixel
1728 */
1729 Size GetPixelOffset() const { return Size(mnOutOffOrigX, mnOutOffOrigY);}
1730
1731 Point LogicToPixel( const Point& rLogicPt ) const;
1732 Size LogicToPixel( const Size& rLogicSize ) const;
1733 tools::Rectangle LogicToPixel( const tools::Rectangle& rLogicRect ) const;
1734 tools::Polygon LogicToPixel( const tools::Polygon& rLogicPoly ) const;
1735 tools::PolyPolygon LogicToPixel( const tools::PolyPolygon& rLogicPolyPoly ) const;
1736 basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const;
1737 vcl::Region LogicToPixel( const vcl::Region& rLogicRegion )const;
1738 Point LogicToPixel( const Point& rLogicPt,
1739 const MapMode& rMapMode ) const;
1740 Size LogicToPixel( const Size& rLogicSize,
1741 const MapMode& rMapMode ) const;
1742 tools::Rectangle LogicToPixel( const tools::Rectangle& rLogicRect,
1743 const MapMode& rMapMode ) const;
1744 tools::Polygon LogicToPixel( const tools::Polygon& rLogicPoly,
1745 const MapMode& rMapMode ) const;
1746 basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1747 const MapMode& rMapMode ) const;
1748
1749 Point PixelToLogic( const Point& rDevicePt ) const;
1750 Size PixelToLogic( const Size& rDeviceSize ) const;
1751 tools::Rectangle PixelToLogic( const tools::Rectangle& rDeviceRect ) const;
1752 tools::Polygon PixelToLogic( const tools::Polygon& rDevicePoly ) const;
1753 tools::PolyPolygon PixelToLogic( const tools::PolyPolygon& rDevicePolyPoly ) const;
1754 basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly ) const;
1755 vcl::Region PixelToLogic( const vcl::Region& rDeviceRegion ) const;
1756 Point PixelToLogic( const Point& rDevicePt,
1757 const MapMode& rMapMode ) const;
1758 Size PixelToLogic( const Size& rDeviceSize,
1759 const MapMode& rMapMode ) const;
1760 tools::Rectangle PixelToLogic( const tools::Rectangle& rDeviceRect,
1761 const MapMode& rMapMode ) const;
1762 tools::Polygon PixelToLogic( const tools::Polygon& rDevicePoly,
1763 const MapMode& rMapMode ) const;
1764 basegfx::B2DPolygon PixelToLogic( const basegfx::B2DPolygon& rDevicePoly,
1765 const MapMode& rMapMode ) const;
1766 basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly,
1767 const MapMode& rMapMode ) const;
1768
1769 Point LogicToLogic( const Point& rPtSource,
1770 const MapMode* pMapModeSource,
1771 const MapMode* pMapModeDest ) const;
1772 Size LogicToLogic( const Size& rSzSource,
1773 const MapMode* pMapModeSource,
1774 const MapMode* pMapModeDest ) const;
1775 tools::Rectangle LogicToLogic( const tools::Rectangle& rRectSource,
1776 const MapMode* pMapModeSource,
1777 const MapMode* pMapModeDest ) const;
1778 static Point LogicToLogic( const Point& rPtSource,
1779 const MapMode& rMapModeSource,
1780 const MapMode& rMapModeDest );
1781 static Size LogicToLogic( const Size& rSzSource,
1782 const MapMode& rMapModeSource,
1783 const MapMode& rMapModeDest );
1784 static tools::Rectangle LogicToLogic( const tools::Rectangle& rRectSource,
1785 const MapMode& rMapModeSource,
1786 const MapMode& rMapModeDest );
1787 static long LogicToLogic( long nLongSource,
1788 MapUnit eUnitSource,
1789 MapUnit eUnitDest );
1790
1791 static basegfx::B2DPolygon LogicToLogic( const basegfx::B2DPolygon& rPoly,
1792 const MapMode& rMapModeSource,
1793 const MapMode& rMapModeDest );
1794
1795 // create a mapping transformation from rMapModeSource to rMapModeDest (the above methods
1796 // for B2DPoly/Polygons use this internally anyway to transform the B2DPolygon)
1797 static basegfx::B2DHomMatrix LogicToLogic(const MapMode& rMapModeSource, const MapMode& rMapModeDest);
1798
1799 /** Convert a logical rectangle to a rectangle in physical device pixel units.
1800
1801 @param rLogicRect Const reference to a rectangle in logical units
1802
1803 @returns Rectangle based on physical device pixel coordinates and units.
1804 */
1805 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) tools::Rectangle ImplLogicToDevicePixel( const tools::Rectangle& rLogicRect ) const;
1806
1807 /** Convert a logical point to a physical point on the device.
1808
1809 @param rLogicPt Const reference to a point in logical units.
1810
1811 @returns Physical point on the device.
1812 */
1813 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Point ImplLogicToDevicePixel( const Point& rLogicPt ) const;
1814
1815 /** Convert a logical width to a width in units of device pixels.
1816
1817 To get the number of device pixels, it must calculate the X-DPI of the device and
1818 the map scaling factor. If there is no mapping, then it just returns the
1819 width as nothing more needs to be done.
1820
1821 @param nWidth Logical width
1822
1823 @returns Width in units of device pixels.
1824 */
1825 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplLogicWidthToDevicePixel( long nWidth ) const;
1826
1827 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) DeviceCoordinate LogicWidthToDeviceCoordinate( long nWidth ) const;
1828
1829 /** Convert a logical X coordinate to a device pixel's X coordinate.
1830
1831 To get the device's X coordinate, it must calculate the mapping offset
1832 coordinate X position (if there is one - if not then it just adds
1833 the pseudo-window offset to the logical X coordinate), the X-DPI of
1834 the device and the mapping's X scaling factor.
1835
1836 @param nX Logical X coordinate
1837
1838 @returns Device's X pixel coordinate
1839 */
1840 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplLogicXToDevicePixel( long nX ) const;
1841
1842 /** Convert a logical Y coordinate to a device pixel's Y coordinate.
1843
1844 To get the device's Y coordinate, it must calculate the mapping offset
1845 coordinate Y position (if there is one - if not then it just adds
1846 the pseudo-window offset to the logical Y coordinate), the Y-DPI of
1847 the device and the mapping's Y scaling factor.
1848
1849 @param nY Logical Y coordinate
1850
1851 @returns Device's Y pixel coordinate
1852 */
1853 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplLogicYToDevicePixel( long nY ) const;
1854
1855 /** Convert a logical height to a height in units of device pixels.
1856
1857 To get the number of device pixels, it must calculate the Y-DPI of the device and
1858 the map scaling factor. If there is no mapping, then it just returns the
1859 height as nothing more needs to be done.
1860
1861 @param nHeight Logical height
1862
1863 @returns Height in units of device pixels.
1864 */
1865 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplLogicHeightToDevicePixel( long nHeight ) const;
1866
1867 /** Convert device pixels to a width in logical units.
1868
1869 To get the logical width, it must calculate the X-DPI of the device and the
1870 map scaling factor.
1871
1872 @param nWidth Width in device pixels
1873
1874 @returns Width in logical units.
1875 */
1876 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplDevicePixelToLogicWidth( long nWidth ) const;
1877
1878 /** Convert device pixels to a height in logical units.
1879
1880 To get the logical height, it must calculate the Y-DPI of the device and the
1881 map scaling factor.
1882
1883 @param nHeight Height in device pixels
1884
1885 @returns Height in logical units.
1886 */
1887 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) long ImplDevicePixelToLogicHeight( long nHeight ) const;
1888
1889 /** Convert logical height to device pixels, with exact sub-pixel value.
1890
1891 To get the \em exact pixel height, it must calculate the Y-DPI of the device and the
1892 map scaling factor.
1893
1894 @param fLogicHeight Exact height in logical units.
1895
1896 @returns Exact height in pixels - returns as a float to provide for subpixel value.
1897 */
1898 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) float ImplFloatLogicHeightToDevicePixel( float fLogicHeight ) const;
1899
1900 /** Convert a logical size to the size on the physical device.
1901
1902 @param rLogicSize Const reference to a size in logical units
1903
1904 @returns Physical size on the device.
1905 */
1906 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) Size ImplLogicToDevicePixel( const Size& rLogicSize ) const;
1907
1908 /** Convert a rectangle in physical pixel units to a rectangle in physical pixel units and coords.
1909
1910 @param rPixelRect Const reference to rectangle in logical units and coords.
1911
1912 @returns Rectangle based on logical coordinates and units.
1913 */
1914 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) tools::Rectangle ImplDevicePixelToLogic( const tools::Rectangle& rPixelRect ) const;
1915
1916 /** Convert a logical polygon to a polygon in physical device pixel units.
1917
1918 @param rLogicPoly Const reference to a polygon in logical units
1919
1920 @returns Polygon based on physical device pixel coordinates and units.
1921 */
1922 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) tools::Polygon ImplLogicToDevicePixel( const tools::Polygon& rLogicPoly ) const;
1923
1924 /** Convert a logical polypolygon to a polypolygon in physical device pixel units.
1925
1926 @param rLogicPolyPoly Const reference to a polypolygon in logical units
1927
1928 @returns Polypolygon based on physical device pixel coordinates and units.
1929 */
1930 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) tools::PolyPolygon ImplLogicToDevicePixel( const tools::PolyPolygon& rLogicPolyPoly ) const;
1931
1932 /** Convert a line in logical units to a line in physical device pixel units.
1933
1934 @param rLineInfo Const reference to a line in logical units
1935
1936 @returns Line based on physical device pixel coordinates and units.
1937 */
1938 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) LineInfo ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const;
1939
1940 /** Convert a region in pixel units to a region in device pixel units and coords.
1941
1942 @param rRegion Const reference to region.
1943
1944 @returns vcl::Region based on device pixel coordinates and units.
1945 */
1946 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) vcl::Region ImplPixelToDevicePixel( const vcl::Region& rRegion ) const;
1947
1948 /** Invalidate the view transformation.
1949
1950 @since AOO bug 75163 (OpenOffice.org 2.4.3 - OOH 680 milestone 212)
1951 */
1952 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplInvalidateViewTransform();
1953
1954 /** Get device transformation.
1955
1956 @since AOO bug 75163 (OpenOffice.org 2.4.3 - OOH 680 milestone 212)
1957 */
1958 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) basegfx::B2DHomMatrix ImplGetDeviceTransformation() const;
1959 ///@}
1960
1961
1962 /** @name Native Widget Rendering functions
1963
1964 These all just call through to the private mpGraphics functions of the same name.
1965 */
1966 ///@{
1967
1968public:
1969
1970 /** Query the platform layer for control support
1971 */
1972 bool IsNativeControlSupported( ControlType nType, ControlPart nPart ) const;
1973
1974 /** Query the native control to determine if it was acted upon
1975 */
1976 bool HitTestNativeScrollbar(
1977 ControlPart nPart,
1978 const tools::Rectangle& rControlRegion,
1979 const Point& aPos,
1980 bool& rIsInside ) const;
1981
1982 /** Request rendering of a particular control and/or part
1983 */
1984 bool DrawNativeControl(
1985 ControlType nType,
1986 ControlPart nPart,
1987 const tools::Rectangle& rControlRegion,
1988 ControlState nState,
1989 const ImplControlValue& aValue,
1990 const OUString& aCaption,
1991 const Color& rBackgroundColor = COL_AUTO );
1992
1993 /** Query the native control's actual drawing region (including adornment)
1994 */
1995 bool GetNativeControlRegion(
1996 ControlType nType,
1997 ControlPart nPart,
1998 const tools::Rectangle& rControlRegion,
1999 ControlState nState,
2000 const ImplControlValue& aValue,
2001 tools::Rectangle &rNativeBoundingRegion,
2002 tools::Rectangle &rNativeContentRegion ) const;
2003 ///@}
2004
2005 /** @name EPS functions
2006 */
2007 ///@{
2008
2009public:
2010
2011 /** @returns boolean value to see if EPS could be painted directly.
2012 Theoretically, handing over a matrix would be needed to handle
2013 painting rotated EPS files (e.g. contained in Metafiles). This
2014 would then need to be supported for Mac and PS printers, but
2015 that's too much for now, wrote \#i107046# for this */
2016 bool DrawEPS(
2017 const Point& rPt, const Size& rSz,
2018 const GfxLink& rGfxLink, GDIMetaFile* pSubst = nullptr );
2019 ///@}
2020};
2021
2022#endif // INCLUDED_VCL_OUTDEV_HXX
2023
2024/* vim:set shiftwidth=4 softtabstop=4 expandtab: */