Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx
Warning:line 619, column 13
Use of memory after it is freed

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 fntcap.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 /usr/include/libxml2 -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 SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -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/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -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/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -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/UnoApiHeadersTarget/oovbaapi/normal -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/sw/source/core/txtnode/fntcap.cxx

/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.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 <editeng/svxfont.hxx>
21
22#include <vcl/outdev.hxx>
23#include <com/sun/star/i18n/CharType.hpp>
24#include <com/sun/star/i18n/WordType.hpp>
25#include <com/sun/star/i18n/XBreakIterator.hpp>
26
27#include <fntcache.hxx>
28#include <swfont.hxx>
29#include <breakit.hxx>
30#include <txtfrm.hxx>
31#include <scriptinfo.hxx>
32#include <fntcap.hxx>
33
34using namespace ::com::sun::star::i18n;
35
36namespace {
37
38// The information encapsulated in SwCapitalInfo is required
39// by the ::Do functions. They contain the information about
40// the original string, whereas rDo.GetInf() contains information
41// about the display string.
42class SwCapitalInfo
43{
44public:
45 explicit SwCapitalInfo( const OUString& rOrigText ) :
46 rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {};
47 const OUString& rString;
48 TextFrameIndex nIdx;
49 TextFrameIndex nLen;
50};
51
52}
53
54// rFnt: required for CalcCaseMap
55// rOrigString: The original string
56// nOfst: Position of the substring in rOrigString
57// nLen: Length if the substring in rOrigString
58// nIdx: Refers to a position in the display string and should be mapped
59// to a position in rOrigString
60TextFrameIndex sw_CalcCaseMap(const SwFont& rFnt,
61 const OUString& rOrigString,
62 TextFrameIndex const nOfst,
63 TextFrameIndex const nLen,
64 TextFrameIndex const nIdx)
65{
66 int j = 0;
67 const TextFrameIndex nEnd = nOfst + nLen;
68 OSL_ENSURE( sal_Int32(nEnd) <= rOrigString.getLength(), "sw_CalcCaseMap: Wrong parameters" )do { if (true && (!(sal_Int32(nEnd) <= rOrigString
.getLength()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx"
":" "68" ": "), "%s", "sw_CalcCaseMap: Wrong parameters"); }
} while (false)
;
69
70 // special case for title case:
71 const bool bTitle = SvxCaseMap::Capitalize == rFnt.GetCaseMap();
72 for (TextFrameIndex i = nOfst; i < nEnd; ++i)
73 {
74 OUString aTmp(rOrigString.copy(sal_Int32(i), 1));
75
76 if ( !bTitle ||
77 g_pBreakIt->GetBreakIter()->isBeginWord(
78 rOrigString, sal_Int32(i),
79 g_pBreakIt->GetLocale( rFnt.GetLanguage() ),
80 WordType::ANYWORD_IGNOREWHITESPACES ) )
81 aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp );
82
83 j += aTmp.getLength();
84
85 if (TextFrameIndex(j) > nIdx)
86 return i;
87 }
88
89 return nOfst + nLen;
90}
91
92class SwDoCapitals
93{
94protected:
95 SwDrawTextInfo &rInf;
96 SwCapitalInfo* pCapInf; // refers to additional information
97 // required by the ::Do function
98 explicit SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( nullptr ) { }
99 ~SwDoCapitals() {}
100public:
101 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0;
102 virtual void Do() = 0;
103 OutputDevice& GetOut() { return rInf.GetOut(); }
104 SwDrawTextInfo& GetInf() { return rInf; }
105 SwCapitalInfo* GetCapInf() const { return pCapInf; }
106 void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; }
107};
108
109namespace {
110
111class SwDoGetCapitalSize : public SwDoCapitals
112{
113protected:
114 Size aTextSize;
115public:
116 explicit SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { }
117 virtual ~SwDoGetCapitalSize() {}
118 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
119 virtual void Do() override;
120 const Size &GetSize() const { return aTextSize; }
121};
122
123}
124
125void SwDoGetCapitalSize::Init( SwFntObj *, SwFntObj * )
126{
127 aTextSize.setHeight( 0 );
128 aTextSize.setWidth( 0 );
129}
130
131void SwDoGetCapitalSize::Do()
132{
133 aTextSize.AdjustWidth(rInf.GetSize().Width() );
134 if( rInf.GetUpper() )
135 aTextSize.setHeight( rInf.GetSize().Height() );
136}
137
138Size SwSubFont::GetCapitalSize( SwDrawTextInfo& rInf )
139{
140 // Start:
141 const long nOldKern = rInf.GetKern();
142 rInf.SetKern( CheckKerning() );
143 rInf.SetPos( Point() );
144 rInf.SetSpace( 0 );
145 rInf.SetDrawSpace( false );
146 SwDoGetCapitalSize aDo( rInf );
147 DoOnCapitals( aDo );
148 Size aTextSize( aDo.GetSize() );
149
150 // End:
151 if( !aTextSize.Height() )
152 {
153 SV_STAT( nGetTextSize );
154 aTextSize.setHeight( short ( rInf.GetpOut()->GetTextHeight() ) );
155 }
156 rInf.SetKern( nOldKern );
157 return aTextSize;
158}
159
160namespace {
161
162class SwDoGetCapitalBreak : public SwDoCapitals
163{
164protected:
165 long nTextWidth;
166 TextFrameIndex m_nBreak;
167
168public:
169 SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long const nWidth)
170 : SwDoCapitals ( rInfo )
171 , nTextWidth( nWidth )
172 , m_nBreak( -1 )
173 { }
174 virtual ~SwDoGetCapitalBreak() {}
175 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
176 virtual void Do() override;
177 TextFrameIndex getBreak() const { return m_nBreak; }
178};
179
180}
181
182void SwDoGetCapitalBreak::Init( SwFntObj *, SwFntObj * )
183{
184}
185
186void SwDoGetCapitalBreak::Do()
187{
188 if ( !nTextWidth )
189 return;
190
191 if ( rInf.GetSize().Width() < nTextWidth )
192 nTextWidth -= rInf.GetSize().Width();
193 else
194 {
195 TextFrameIndex nEnd = rInf.GetEnd();
196 m_nBreak = TextFrameIndex(GetOut().GetTextBreak(
197 rInf.GetText(), nTextWidth, sal_Int32(rInf.GetIdx()),
198 sal_Int32(rInf.GetLen()), rInf.GetKern()));
199
200 if (m_nBreak > nEnd || m_nBreak < TextFrameIndex(0))
201 m_nBreak = nEnd;
202
203 // m_nBreak may be relative to the display string. It has to be
204 // calculated relative to the original string:
205 if ( GetCapInf() )
206 {
207 if ( GetCapInf()->nLen != rInf.GetLen() )
208 m_nBreak = sw_CalcCaseMap( *rInf.GetFont(),
209 GetCapInf()->rString,
210 GetCapInf()->nIdx,
211 GetCapInf()->nLen, m_nBreak );
212 else
213 m_nBreak = m_nBreak + GetCapInf()->nIdx;
214 }
215
216 nTextWidth = 0;
217 }
218}
219
220TextFrameIndex SwFont::GetCapitalBreak( SwViewShell const * pSh, const OutputDevice* pOut,
221 const SwScriptInfo* pScript, const OUString& rText, long const nTextWidth,
222 TextFrameIndex const nIdx, TextFrameIndex const nLen)
223{
224 // Start:
225 Point aPos( 0, 0 );
226 SwDrawTextInfo aInfo(pSh, *const_cast<OutputDevice*>(pOut), pScript, rText, nIdx, nLen,
227 0, false);
228 aInfo.SetPos( aPos );
229 aInfo.SetSpace( 0 );
230 aInfo.SetWrong( nullptr );
231 aInfo.SetGrammarCheck( nullptr );
232 aInfo.SetSmartTags( nullptr );
233 aInfo.SetDrawSpace( false );
234 aInfo.SetKern( CheckKerning() );
235 aInfo.SetKanaComp( pScript ? 0 : 100 );
236 aInfo.SetFont( this );
237
238 SwDoGetCapitalBreak aDo(aInfo, nTextWidth);
239 DoOnCapitals( aDo );
240 return aDo.getBreak();
241}
242
243namespace {
244
245class SwDoDrawCapital : public SwDoCapitals
246{
247protected:
248 SwFntObj *pUpperFnt;
249 SwFntObj *pLowerFnt;
250public:
251 explicit SwDoDrawCapital( SwDrawTextInfo &rInfo ) :
252 SwDoCapitals( rInfo ), pUpperFnt(nullptr), pLowerFnt(nullptr)
253 { }
254 virtual ~SwDoDrawCapital() {}
255 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
256 virtual void Do() override;
257 void DrawSpace( Point &rPos );
258};
259
260}
261
262void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
263{
264 pUpperFnt = pUpperFont;
265 pLowerFnt = pLowerFont;
266}
267
268void SwDoDrawCapital::Do()
269{
270 SV_STAT( nDrawText );
271 const sal_uInt16 nOrgWidth = rInf.GetWidth();
272 rInf.SetWidth( sal_uInt16(rInf.GetSize().Width()) );
273 if ( rInf.GetUpper() )
274 pUpperFnt->DrawText( rInf );
275 else
276 {
277 bool bOldBullet = rInf.GetBullet();
278 rInf.SetBullet( false );
279 pLowerFnt->DrawText( rInf );
280 rInf.SetBullet( bOldBullet );
281 }
282
283 OSL_ENSURE( pUpperFnt, "No upper font, dying soon!")do { if (true && (!(pUpperFnt))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx"
":" "283" ": "), "%s", "No upper font, dying soon!"); } } while
(false)
;
284 rInf.Shift( pUpperFnt->GetFont().GetOrientation() );
285 rInf.SetWidth( nOrgWidth );
286}
287
288void SwDoDrawCapital::DrawSpace( Point &rPos )
289{
290 long nDiff = rInf.GetPos().X() - rPos.X();
291
292 Point aPos( rPos );
293 const bool bSwitchL2R = rInf.GetFrame()->IsRightToLeft() &&
294 ! rInf.IsIgnoreFrameRTL();
295
296 if ( bSwitchL2R )
297 rInf.GetFrame()->SwitchLTRtoRTL( aPos );
298
299 const ComplexTextLayoutFlags nMode = rInf.GetpOut()->GetLayoutMode();
300 const bool bBidiPor = ( bSwitchL2R !=
301 ( ComplexTextLayoutFlags::Default != ( ComplexTextLayoutFlags::BiDiRtl & nMode ) ) );
302
303 if ( bBidiPor )
304 nDiff = -nDiff;
305
306 if ( rInf.GetFrame()->IsVertical() )
307 rInf.GetFrame()->SwitchHorizontalToVertical( aPos );
308
309 if ( nDiff )
310 {
311 rInf.ApplyAutoColor();
312 GetOut().DrawStretchText( aPos, nDiff,
313 " ", 0, 2 );
314 }
315 rPos.setX( rInf.GetPos().X() + rInf.GetWidth() );
316}
317
318void SwSubFont::DrawCapital( SwDrawTextInfo &rInf )
319{
320 // Precondition: rInf.GetPos() has already been calculated
321
322 rInf.SetDrawSpace( GetUnderline() != LINESTYLE_NONE ||
323 GetOverline() != LINESTYLE_NONE ||
324 GetStrikeout() != STRIKEOUT_NONE );
325 SwDoDrawCapital aDo( rInf );
326 DoOnCapitals( aDo );
327}
328
329namespace {
330
331class SwDoCapitalCursorOfst : public SwDoCapitals
332{
333protected:
334 SwFntObj *pUpperFnt;
335 SwFntObj *pLowerFnt;
336 TextFrameIndex nCursor;
337 sal_uInt16 nOfst;
338public:
339 SwDoCapitalCursorOfst( SwDrawTextInfo &rInfo, const sal_uInt16 nOfs ) :
340 SwDoCapitals( rInfo ), pUpperFnt(nullptr), pLowerFnt(nullptr), nCursor( 0 ), nOfst( nOfs )
341 { }
342 virtual ~SwDoCapitalCursorOfst() {}
343 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
344 virtual void Do() override;
345
346 TextFrameIndex GetCursor() const { return nCursor; }
347};
348
349}
350
351void SwDoCapitalCursorOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
352{
353 pUpperFnt = pUpperFont;
354 pLowerFnt = pLowerFont;
355}
356
357void SwDoCapitalCursorOfst::Do()
358{
359 if ( !nOfst )
360 return;
361
362 if ( static_cast<long>(nOfst) > rInf.GetSize().Width() )
363 {
364 nOfst -= rInf.GetSize().Width();
365 nCursor = nCursor + rInf.GetLen();
366 }
367 else
368 {
369 SwDrawTextInfo aDrawInf( rInf.GetShell(), *rInf.GetpOut(),
370 rInf.GetScriptInfo(),
371 rInf.GetText(),
372 rInf.GetIdx(),
373 rInf.GetLen(), 0, false );
374 aDrawInf.SetOffset( nOfst );
375 aDrawInf.SetKern( rInf.GetKern() );
376 aDrawInf.SetKanaComp( rInf.GetKanaComp() );
377 aDrawInf.SetFrame( rInf.GetFrame() );
378 aDrawInf.SetFont( rInf.GetFont() );
379
380 if ( rInf.GetUpper() )
381 {
382 aDrawInf.SetSpace( 0 );
383 nCursor = nCursor + pUpperFnt->GetModelPositionForViewPoint( aDrawInf );
384 }
385 else
386 {
387 aDrawInf.SetSpace( rInf.GetSpace() );
388 nCursor = nCursor + pLowerFnt->GetModelPositionForViewPoint( aDrawInf );
389 }
390 nOfst = 0;
391 }
392}
393
394TextFrameIndex SwSubFont::GetCapitalCursorOfst( SwDrawTextInfo& rInf )
395{
396 const long nOldKern = rInf.GetKern();
397 rInf.SetKern( CheckKerning() );
398 SwDoCapitalCursorOfst aDo( rInf, rInf.GetOffset() );
399 rInf.SetPos( Point() );
400 rInf.SetDrawSpace( false );
401 DoOnCapitals( aDo );
402 rInf.SetKern( nOldKern );
403 return aDo.GetCursor();
404}
405
406namespace {
407
408class SwDoDrawStretchCapital : public SwDoDrawCapital
409{
410 const TextFrameIndex nStrLen;
411 const sal_uInt16 nCapWidth;
412 const sal_uInt16 nOrgWidth;
413public:
414 virtual void Do() override;
415
416 SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const sal_uInt16 nCapitalWidth )
417 : SwDoDrawCapital( rInfo ),
418 nStrLen( rInfo.GetLen() ),
419 nCapWidth( nCapitalWidth ),
420 nOrgWidth( rInfo.GetWidth() )
421 { }
422};
423
424}
425
426void SwDoDrawStretchCapital::Do()
427{
428 SV_STAT( nDrawStretchText );
429 long nPartWidth = rInf.GetSize().Width();
430
431 if( rInf.GetLen() )
432 {
433 // small caps and kerning
434 long nDiff = long(nOrgWidth) - long(nCapWidth);
435 if( nDiff )
436 {
437 nDiff *= sal_Int32(rInf.GetLen());
438 nDiff /= sal_Int32(nStrLen);
439 nDiff += nPartWidth;
440 if( 0 < nDiff )
441 nPartWidth = nDiff;
442 }
443
444 rInf.ApplyAutoColor();
445
446 Point aPos( rInf.GetPos() );
447 const bool bSwitchL2R = rInf.GetFrame()->IsRightToLeft() &&
448 ! rInf.IsIgnoreFrameRTL();
449
450 if ( bSwitchL2R )
451 rInf.GetFrame()->SwitchLTRtoRTL( aPos );
452
453 if ( rInf.GetFrame()->IsVertical() )
454 rInf.GetFrame()->SwitchHorizontalToVertical( aPos );
455
456 // Optimise:
457 if (TextFrameIndex(1) >= rInf.GetLen())
458 GetOut().DrawText(aPos, rInf.GetText(), sal_Int32(rInf.GetIdx()),
459 sal_Int32(rInf.GetLen()));
460 else
461 GetOut().DrawStretchText(aPos, nPartWidth, rInf.GetText(),
462 sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
463 }
464 const_cast<Point&>(rInf.GetPos()).AdjustX(nPartWidth );
465}
466
467void SwSubFont::DrawStretchCapital( SwDrawTextInfo &rInf )
468{
469 // Precondition: rInf.GetPos() has already been calculated
470
471 if (rInf.GetLen() == TextFrameIndex(COMPLETE_STRING))
472 rInf.SetLen(TextFrameIndex(rInf.GetText().getLength()));
473
474 const Point aOldPos = rInf.GetPos();
475 const sal_uInt16 nCapWidth = static_cast<sal_uInt16>( GetCapitalSize( rInf ).Width() );
476 rInf.SetPos(aOldPos);
477
478 rInf.SetDrawSpace( GetUnderline() != LINESTYLE_NONE ||
479 GetOverline() != LINESTYLE_NONE ||
480 GetStrikeout() != STRIKEOUT_NONE );
481 SwDoDrawStretchCapital aDo( rInf, nCapWidth );
482 DoOnCapitals( aDo );
483}
484
485void SwSubFont::DoOnCapitals( SwDoCapitals &rDo )
486{
487 OSL_ENSURE( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" )do { if (true && (!(pLastFont))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx"
":" "487" ": "), "%s", "SwFont::DoOnCapitals: No LastFont?!"
); } } while (false)
;
1
Assuming 'pLastFont' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
488
489 long nKana = 0;
490 const OUString aText( CalcCaseMap( rDo.GetInf().GetText() ) );
491 TextFrameIndex nMaxPos = std::min(
492 TextFrameIndex(rDo.GetInf().GetText().getLength()) - rDo.GetInf().GetIdx(),
493 rDo.GetInf().GetLen() );
494 rDo.GetInf().SetLen( nMaxPos );
495
496 const OUString oldText = rDo.GetInf().GetText();
497 rDo.GetInf().SetText( aText );
498 TextFrameIndex nPos = rDo.GetInf().GetIdx();
499 TextFrameIndex nOldPos = nPos;
500 nMaxPos = nMaxPos + nPos;
501
502 // Look if the length of the original text and the ToUpper-converted
503 // text is different. If yes, do special handling.
504 SwCapitalInfo aCapInf(oldText);
505 bool bCaseMapLengthDiffers(aText.getLength() != oldText.getLength());
4
Assuming the condition is false
506 if ( bCaseMapLengthDiffers
4.1
'bCaseMapLengthDiffers' is false
4.1
'bCaseMapLengthDiffers' is false
4.1
'bCaseMapLengthDiffers' is false
4.1
'bCaseMapLengthDiffers' is false
4.1
'bCaseMapLengthDiffers' is false
)
5
Taking false branch
507 rDo.SetCapInf( aCapInf );
508
509 SwFntObj *pOldLast = pLastFont;
510 std::unique_ptr<SwFntAccess> pBigFontAccess;
511 SwFntObj *pBigFont;
512 std::unique_ptr<SwFntAccess> pSpaceFontAccess;
513 SwFntObj *pSpaceFont = nullptr;
514
515 const void* nFontCacheId2 = nullptr;
516 sal_uInt16 nIndex2 = 0;
517 SwSubFont aFont( *this );
518 Point aStartPos( rDo.GetInf().GetPos() );
519
520 const bool bTextLines = aFont.GetUnderline() != LINESTYLE_NONE
6
Assuming the condition is false
521 || aFont.GetOverline() != LINESTYLE_NONE
7
Assuming the condition is false
522 || aFont.GetStrikeout() != STRIKEOUT_NONE;
8
Assuming the condition is false
523 const bool bWordWise = bTextLines
8.1
'bTextLines' is false
8.1
'bTextLines' is false
8.1
'bTextLines' is false
8.1
'bTextLines' is false
8.1
'bTextLines' is false
&& aFont.IsWordLineMode() &&
524 rDo.GetInf().GetDrawSpace();
525 const long nTmpKern = rDo.GetInf().GetKern();
526
527 if ( bTextLines
8.2
'bTextLines' is false
8.2
'bTextLines' is false
8.2
'bTextLines' is false
8.2
'bTextLines' is false
8.2
'bTextLines' is false
)
9
Taking false branch
528 {
529 if ( bWordWise )
530 {
531 aFont.SetWordLineMode( false );
532 pSpaceFontAccess.reset(new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
533 rDo.GetInf().GetShell() ));
534 pSpaceFont = pSpaceFontAccess->Get();
535 }
536 else
537 pSpaceFont = pLastFont;
538
539 // Construct a font for the capitals:
540 aFont.SetUnderline( LINESTYLE_NONE );
541 aFont.SetOverline( LINESTYLE_NONE );
542 aFont.SetStrikeout( STRIKEOUT_NONE );
543 nFontCacheId2 = nullptr;
544 nIndex2 = 0;
545 pBigFontAccess.reset(new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
546 rDo.GetInf().GetShell() ));
547 pBigFont = pBigFontAccess->Get();
548 }
549 else
550 pBigFont = pLastFont;
551
552 // Older LO versions had 66 as the small caps percentage size, later changed to 80,
553 // therefore a backwards compatibility option is kept (otherwise layout is changed).
554 // NOTE: There are more uses of SMALL_CAPS_PERCENTAGE in editeng, but it seems they
555 // do not matter for Writer (and if they did it'd be pretty ugly to propagate
556 // the option there).
557 int smallCapsPercentage = m_bSmallCapsPercentage66 ? 66 : SMALL_CAPS_PERCENTAGE80;
10
Assuming field 'm_bSmallCapsPercentage66' is false
11
'?' condition is false
558 aFont.SetProportion( (aFont.GetPropr() * smallCapsPercentage ) / 100 );
559 nFontCacheId2 = nullptr;
560 nIndex2 = 0;
561 std::unique_ptr<SwFntAccess> pSmallFontAccess( new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
562 rDo.GetInf().GetShell() ));
563 SwFntObj *pSmallFont = pSmallFontAccess->Get();
564
565 rDo.Init( pBigFont, pSmallFont );
566 OutputDevice* pOutSize = pSmallFont->GetPrt();
567 if( !pOutSize )
12
Assuming 'pOutSize' is non-null
13
Taking false branch
568 pOutSize = &rDo.GetOut();
569 OutputDevice* pOldOut = &rDo.GetOut();
570
571 const LanguageType eLng = LANGUAGE_DONTKNOWLanguageType(0x03FF) == GetLanguage()
14
'?' condition is false
572 ? LANGUAGE_SYSTEMLanguageType(0x0000) : GetLanguage();
573
574 if( nPos < nMaxPos )
15
Taking true branch
575 {
576 nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->endOfCharBlock(
577 oldText, sal_Int32(nPos),
578 g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
579 if (nPos < TextFrameIndex(0))
16
Taking false branch
580 nPos = nOldPos;
581 else if( nPos > nMaxPos )
17
Taking false branch
582 nPos = nMaxPos;
583 }
584
585 while( nOldPos < nMaxPos )
18
Loop condition is true. Entering loop body
586 {
587
588 // The lower ones...
589 if( nOldPos != nPos )
19
Taking true branch
590 {
591 SV_STAT( nGetTextSize );
592 pLastFont = pSmallFont;
593 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
594
595 // #107816#, #i14820#
596 if( bCaseMapLengthDiffers
19.1
'bCaseMapLengthDiffers' is false
19.1
'bCaseMapLengthDiffers' is false
19.1
'bCaseMapLengthDiffers' is false
19.1
'bCaseMapLengthDiffers' is false
19.1
'bCaseMapLengthDiffers' is false
)
20
Taking false branch
597 {
598 // Build an own 'changed' string for the given part of the
599 // source string and use it. That new string may differ in length
600 // from the source string.
601 const OUString aNewText = CalcCaseMap(
602 oldText.copy(sal_Int32(nOldPos), sal_Int32(nPos-nOldPos)));
603 aCapInf.nIdx = nOldPos;
604 aCapInf.nLen = nPos - nOldPos;
605 rDo.GetInf().SetIdx(TextFrameIndex(0));
606 rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
607 rDo.GetInf().SetText( aNewText );
608 }
609 else
610 {
611 rDo.GetInf().SetIdx( nOldPos );
612 rDo.GetInf().SetLen( nPos - nOldPos );
613 }
614
615 rDo.GetInf().SetUpper( false );
616 rDo.GetInf().SetOut( *pOutSize );
21
Calling 'SwDrawTextInfo::SetOut'
33
Returning; memory was released
617 Size aPartSize = pSmallFont->GetTextSize( rDo.GetInf() );
618 nKana += rDo.GetInf().GetKanaDiff();
619 rDo.GetInf().SetOut( *pOldOut );
34
Use of memory after it is freed
620 if( nTmpKern && nPos < nMaxPos )
621 aPartSize.AdjustWidth(nTmpKern );
622 rDo.GetInf().SetSize( aPartSize );
623 rDo.Do();
624 nOldPos = nPos;
625 }
626 nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->nextCharBlock(
627 oldText, sal_Int32(nPos),
628 g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
629 if (nPos < TextFrameIndex(0) || nPos > nMaxPos)
630 nPos = nMaxPos;
631 OSL_ENSURE( nPos, "nextCharBlock not implemented?" )do { if (true && (!(nPos))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx"
":" "631" ": "), "%s", "nextCharBlock not implemented?"); } }
while (false)
;
632#if OSL_DEBUG_LEVEL1 > 1
633 if( !nPos )
634 nPos = nMaxPos;
635#endif
636 // The upper ones...
637 if( nOldPos != nPos )
638 {
639 const long nSpaceAdd = rDo.GetInf().GetSpace() / SPACING_PRECISION_FACTOR100;
640
641 do
642 {
643 rDo.GetInf().SetUpper( true );
644 pLastFont = pBigFont;
645 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
646 TextFrameIndex nTmp;
647 if( bWordWise )
648 {
649 nTmp = nOldPos;
650 while (nTmp < nPos && CH_BLANK == oldText[sal_Int32(nTmp)])
651 ++nTmp;
652 if( nOldPos < nTmp )
653 {
654 pLastFont = pSpaceFont;
655 pLastFont->SetDevFont( rDo.GetInf().GetShell(),
656 rDo.GetOut() );
657 static_cast<SwDoDrawCapital&>(rDo).DrawSpace( aStartPos );
658 pLastFont = pBigFont;
659 pLastFont->SetDevFont( rDo.GetInf().GetShell(),
660 rDo.GetOut() );
661
662 // #107816#, #i14820#
663 if( bCaseMapLengthDiffers )
664 {
665 // Build an own 'changed' string for the given part of the
666 // source string and use it. That new string may differ in length
667 // from the source string.
668 const OUString aNewText = CalcCaseMap(
669 oldText.copy(sal_Int32(nOldPos), sal_Int32(nTmp-nOldPos)));
670 aCapInf.nIdx = nOldPos;
671 aCapInf.nLen = nTmp - nOldPos;
672 rDo.GetInf().SetIdx(TextFrameIndex(0));
673 rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
674 rDo.GetInf().SetText( aNewText );
675 }
676 else
677 {
678 rDo.GetInf().SetIdx( nOldPos );
679 rDo.GetInf().SetLen( nTmp - nOldPos );
680 }
681
682 rDo.GetInf().SetOut( *pOutSize );
683 Size aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
684 nKana += rDo.GetInf().GetKanaDiff();
685 rDo.GetInf().SetOut( *pOldOut );
686 if( nSpaceAdd )
687 aPartSize.AdjustWidth(nSpaceAdd * sal_Int32(nTmp - nOldPos));
688 if( nTmpKern && nPos < nMaxPos )
689 aPartSize.AdjustWidth(nTmpKern );
690 rDo.GetInf().SetSize( aPartSize );
691 rDo.Do();
692 aStartPos = rDo.GetInf().GetPos();
693 nOldPos = nTmp;
694 }
695
696 while (nTmp < nPos && CH_BLANK != oldText[sal_Int32(nTmp)])
697 ++nTmp;
698 }
699 else
700 nTmp = nPos;
701 if( nTmp > nOldPos )
702 {
703 // #107816#, #i14820#
704 if( bCaseMapLengthDiffers )
705 {
706 // Build an own 'changed' string for the given part of the
707 // source string and use it. That new string may differ in length
708 // from the source string.
709 const OUString aNewText = CalcCaseMap(
710 oldText.copy(sal_Int32(nOldPos), sal_Int32(nTmp-nOldPos)));
711 aCapInf.nIdx = nOldPos;
712 aCapInf.nLen = nTmp - nOldPos;
713 rDo.GetInf().SetIdx(TextFrameIndex(0));
714 rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
715 rDo.GetInf().SetText( aNewText );
716 }
717 else
718 {
719 rDo.GetInf().SetIdx( nOldPos );
720 rDo.GetInf().SetLen( nTmp - nOldPos );
721 }
722
723 rDo.GetInf().SetOut( *pOutSize );
724 Size aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
725 nKana += rDo.GetInf().GetKanaDiff();
726 rDo.GetInf().SetOut( *pOldOut );
727 if( !bWordWise && rDo.GetInf().GetSpace() )
728 {
729 for (TextFrameIndex nI = nOldPos; nI < nPos; ++nI)
730 {
731 if (CH_BLANK == oldText[sal_Int32(nI)])
732 aPartSize.AdjustWidth(nSpaceAdd );
733 }
734 }
735 if( nTmpKern && nPos < nMaxPos )
736 aPartSize.AdjustWidth(nTmpKern );
737 rDo.GetInf().SetSize( aPartSize );
738 rDo.Do();
739 nOldPos = nTmp;
740 }
741 } while( nOldPos != nPos );
742 }
743 nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->endOfCharBlock(
744 oldText, sal_Int32(nPos),
745 g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
746 if (nPos < TextFrameIndex(0) || nPos > nMaxPos)
747 nPos = nMaxPos;
748 OSL_ENSURE( nPos, "endOfCharBlock not implemented?" )do { if (true && (!(nPos))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/fntcap.cxx"
":" "748" ": "), "%s", "endOfCharBlock not implemented?"); }
} while (false)
;
749#if OSL_DEBUG_LEVEL1 > 1
750 if( !nPos )
751 nPos = nMaxPos;
752#endif
753 }
754
755 // clean up:
756 if( pBigFont != pOldLast )
757 pBigFontAccess.reset();
758
759 if( bTextLines )
760 {
761 if( rDo.GetInf().GetDrawSpace() )
762 {
763 pLastFont = pSpaceFont;
764 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
765 static_cast<SwDoDrawCapital&>( rDo ).DrawSpace( aStartPos );
766 }
767 if ( bWordWise )
768 pSpaceFontAccess.reset();
769 }
770 pLastFont = pOldLast;
771 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
772
773 pSmallFontAccess.reset();
774 rDo.GetInf().SetText(oldText);
775 rDo.GetInf().SetKanaDiff( nKana );
776}
777
778/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.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_SW_SOURCE_CORE_INC_DRAWFONT_HXX
21#define INCLUDED_SW_SOURCE_CORE_INC_DRAWFONT_HXX
22
23#include <osl/diagnose.h>
24#include <vcl/vclptr.hxx>
25#include <vcl/outdev.hxx>
26#include "TextFrameIndex.hxx"
27#include <swdllapi.h>
28
29class SwTextFrame;
30class SwViewShell;
31class SwScriptInfo;
32namespace sw { class WrongListIterator; }
33class SwFont;
34namespace vcl {
35 class Font;
36 class TextLayoutCache;
37 typedef OutputDevice RenderContext;
38}
39class SwUnderlineFont;
40
41// encapsulates information for drawing text
42class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwDrawTextInfo
43{
44 const SwTextFrame* m_pFrame;
45 VclPtr<OutputDevice> m_pOut;
46 SwViewShell const * m_pSh;
47 const SwScriptInfo* m_pScriptInfo;
48 Point m_aPos;
49 vcl::TextLayoutCache const* m_pCachedVclData;
50 OUString m_aText;
51 sw::WrongListIterator* m_pWrong;
52 sw::WrongListIterator* m_pGrammarCheck;
53 sw::WrongListIterator* m_pSmartTags;
54 Size m_aSize;
55 SwFont *m_pFnt;
56 SwUnderlineFont* m_pUnderFnt;
57 TextFrameIndex* m_pHyphPos;
58 long m_nKanaDiff;
59 TextFrameIndex m_nIdx;
60 TextFrameIndex m_nLen;
61 /// this is not a string index
62 sal_Int32 m_nOfst;
63 sal_uInt16 m_nWidth;
64 sal_uInt16 m_nAscent;
65 sal_uInt16 m_nCompress;
66 long m_nSperren;
67 long m_nSpace;
68 long m_nKern;
69 TextFrameIndex m_nNumberOfBlanks;
70 sal_uInt8 m_nCursorBidiLevel;
71 bool m_bBullet : 1;
72 bool m_bUpper : 1; // for small caps: upper case flag
73 bool m_bDrawSpace : 1; // for small caps: underline/ line through
74 bool m_bGreyWave : 1; // grey wave line for extended text input
75 // For underlining we need to know, if a section is right in front of a
76 // whole block or a fix margin section.
77 bool m_bSpaceStop : 1;
78 bool m_bSnapToGrid : 1; // Does paragraph snap to grid?
79 // Paint text as if text has LTR direction, used for line numbering
80 bool m_bIgnoreFrameRTL : 1;
81 // GetModelPositionForViewPoint should not return the next position if screen position is
82 // inside second half of bound rect, used for Accessibility
83 bool m_bPosMatchesBounds :1;
84
85public:
86
87#ifdef DBG_UTIL
88 // These flags should control that the appropriate Set-function has been
89 // called before calling the Get-function of a member
90 bool m_bPos : 1;
91 bool m_bWrong : 1;
92 bool m_bGrammarCheck : 1;
93 bool m_bSize : 1;
94 bool m_bFnt : 1;
95 bool m_bHyph : 1;
96 bool m_bKana : 1;
97 bool m_bOfst : 1;
98 bool m_bAscent: 1;
99 bool m_bSperr : 1;
100 bool m_bSpace : 1;
101 bool m_bNumberOfBlanks : 1;
102 bool m_bUppr : 1;
103 bool m_bDrawSp: 1;
104#endif
105
106 /// constructor for simple strings
107 SwDrawTextInfo( SwViewShell const *pSh, OutputDevice &rOut,
108 const OUString &rText, sal_Int32 const nIdx, sal_Int32 const nLen,
109 sal_uInt16 nWidth = 0, bool bBullet = false)
110 : SwDrawTextInfo(pSh, rOut, nullptr, rText, TextFrameIndex(nIdx), TextFrameIndex(nLen), nWidth, bBullet)
111 {}
112 /// constructor for text frame contents
113 SwDrawTextInfo( SwViewShell const *pSh, OutputDevice &rOut, const SwScriptInfo* pSI,
114 const OUString &rText, TextFrameIndex const nIdx, TextFrameIndex const nLen,
115 sal_uInt16 nWidth = 0, bool bBullet = false,
116 vcl::TextLayoutCache const*const pCachedVclData = nullptr)
117 : m_pCachedVclData(pCachedVclData)
118 {
119 m_pFrame = nullptr;
120 m_pSh = pSh;
121 m_pOut = &rOut;
122 m_pScriptInfo = pSI;
123 m_aText = rText;
124 m_nIdx = nIdx;
125 m_nLen = nLen;
126 m_nKern = 0;
127 m_nCompress = 0;
128 m_nWidth = nWidth;
129 m_nNumberOfBlanks = TextFrameIndex(0);
130 m_nCursorBidiLevel = 0;
131 m_bBullet = bBullet;
132 m_pUnderFnt = nullptr;
133 m_bGreyWave = false;
134 m_bSpaceStop = false;
135 m_bSnapToGrid = false;
136 m_bIgnoreFrameRTL = false;
137 m_bPosMatchesBounds = false;
138
139 // These values are initialized but have to be set explicitly via their
140 // Set-function before they may be accessed by their Get-function:
141 m_pWrong = nullptr;
142 m_pGrammarCheck = nullptr;
143 m_pSmartTags = nullptr;
144 m_pFnt = nullptr;
145 m_pHyphPos = nullptr;
146 m_nKanaDiff = 0;
147 m_nOfst = 0;
148 m_nAscent = 0;
149 m_nSperren = 0;
150 m_nSpace = 0;
151 m_bUpper = false;
152 m_bDrawSpace = false;
153
154#ifdef DBG_UTIL
155 // these flags control whether the matching member variables have been
156 // set by using the Set-function before they may be accessed by their
157 // Get-function:
158 m_bPos = m_bWrong = m_bGrammarCheck = m_bSize = m_bFnt = m_bAscent =
159 m_bSpace = m_bNumberOfBlanks = m_bUppr =
160 m_bDrawSp = m_bKana = m_bOfst = m_bHyph =
161 m_bSperr = false;
162#endif
163 }
164
165 const SwTextFrame* GetFrame() const
166 {
167 return m_pFrame;
168 }
169
170 void SetFrame( const SwTextFrame* pNewFrame )
171 {
172 m_pFrame = pNewFrame;
173 }
174
175 SwViewShell const *GetShell() const
176 {
177 return m_pSh;
178 }
179
180 vcl::RenderContext& GetOut() const
181 {
182 return *m_pOut;
183 }
184
185 vcl::RenderContext *GetpOut() const
186 {
187 return m_pOut;
188 }
189
190 const SwScriptInfo* GetScriptInfo() const
191 {
192 return m_pScriptInfo;
193 }
194
195 const Point &GetPos() const
196 {
197#ifdef DBG_UTIL
198 OSL_ENSURE( m_bPos, "DrawTextInfo: Undefined Position" )do { if (true && (!(m_bPos))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "198" ": "), "%s", "DrawTextInfo: Undefined Position"); }
} while (false)
;
199#endif
200 return m_aPos;
201 }
202
203 TextFrameIndex *GetHyphPos() const
204 {
205#ifdef DBG_UTIL
206 OSL_ENSURE( m_bHyph, "DrawTextInfo: Undefined Hyph Position" )do { if (true && (!(m_bHyph))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "206" ": "), "%s", "DrawTextInfo: Undefined Hyph Position"
); } } while (false)
;
207#endif
208 return m_pHyphPos;
209 }
210
211 vcl::TextLayoutCache const* GetVclCache() const
212 {
213 return m_pCachedVclData;
214 }
215
216 const OUString &GetText() const
217 {
218 return m_aText;
219 }
220
221 sw::WrongListIterator* GetWrong() const
222 {
223#ifdef DBG_UTIL
224 OSL_ENSURE( m_bWrong, "DrawTextInfo: Undefined WrongList" )do { if (true && (!(m_bWrong))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "224" ": "), "%s", "DrawTextInfo: Undefined WrongList");
} } while (false)
;
225#endif
226 return m_pWrong;
227 }
228
229 sw::WrongListIterator* GetGrammarCheck() const
230 {
231#ifdef DBG_UTIL
232 OSL_ENSURE( m_bGrammarCheck, "DrawTextInfo: Undefined GrammarCheck List" )do { if (true && (!(m_bGrammarCheck))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "232" ": "), "%s", "DrawTextInfo: Undefined GrammarCheck List"
); } } while (false)
;
233#endif
234 return m_pGrammarCheck;
235 }
236
237 sw::WrongListIterator* GetSmartTags() const
238 {
239 return m_pSmartTags;
240 }
241
242 const Size &GetSize() const
243 {
244#ifdef DBG_UTIL
245 OSL_ENSURE( m_bSize, "DrawTextInfo: Undefined Size" )do { if (true && (!(m_bSize))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "245" ": "), "%s", "DrawTextInfo: Undefined Size"); } } while
(false)
;
246#endif
247 return m_aSize;
248 }
249
250 SwFont* GetFont() const
251 {
252#ifdef DBG_UTIL
253 OSL_ENSURE( m_bFnt, "DrawTextInfo: Undefined Font" )do { if (true && (!(m_bFnt))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "253" ": "), "%s", "DrawTextInfo: Undefined Font"); } } while
(false)
;
254#endif
255 return m_pFnt;
256 }
257
258 SwUnderlineFont* GetUnderFnt() const
259 {
260 return m_pUnderFnt;
261 }
262
263 TextFrameIndex GetIdx() const
264 {
265 return m_nIdx;
266 }
267
268 TextFrameIndex GetLen() const
269 {
270 return m_nLen;
271 }
272
273 sal_Int32 GetOffset() const
274 {
275#ifdef DBG_UTIL
276 OSL_ENSURE( m_bOfst, "DrawTextInfo: Undefined Offset" )do { if (true && (!(m_bOfst))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "276" ": "), "%s", "DrawTextInfo: Undefined Offset"); } }
while (false)
;
277#endif
278 return m_nOfst;
279 }
280
281 TextFrameIndex GetEnd() const
282 {
283 return m_nIdx + m_nLen;
284 }
285
286 long GetKanaDiff() const
287 {
288#ifdef DBG_UTIL
289 OSL_ENSURE( m_bKana, "DrawTextInfo: Undefined kana difference" )do { if (true && (!(m_bKana))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "289" ": "), "%s", "DrawTextInfo: Undefined kana difference"
); } } while (false)
;
290#endif
291 return m_nKanaDiff;
292 }
293
294 sal_uInt16 GetWidth() const
295 {
296 return m_nWidth;
297 }
298
299 sal_uInt16 GetAscent() const
300 {
301#ifdef DBG_UTIL
302 OSL_ENSURE( m_bAscent, "DrawTextInfo: Undefined Ascent" )do { if (true && (!(m_bAscent))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "302" ": "), "%s", "DrawTextInfo: Undefined Ascent"); } }
while (false)
;
303#endif
304 return m_nAscent;
305 }
306
307 sal_uInt16 GetKanaComp() const
308 {
309 return m_nCompress;
310 }
311
312 long GetSperren() const
313 {
314#ifdef DBG_UTIL
315 OSL_ENSURE( m_bSperr, "DrawTextInfo: Undefined >Sperren<" )do { if (true && (!(m_bSperr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "315" ": "), "%s", "DrawTextInfo: Undefined >Sperren<"
); } } while (false)
;
316#endif
317 return m_nSperren;
318 }
319
320 long GetKern() const
321 {
322 return m_nKern;
323 }
324
325 long GetSpace() const
326 {
327#ifdef DBG_UTIL
328 OSL_ENSURE( m_bSpace, "DrawTextInfo: Undefined Spacing" )do { if (true && (!(m_bSpace))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "328" ": "), "%s", "DrawTextInfo: Undefined Spacing"); }
} while (false)
;
329#endif
330 return m_nSpace;
331 }
332
333 TextFrameIndex GetNumberOfBlanks() const
334 {
335#ifdef DBG_UTIL
336 OSL_ENSURE( m_bNumberOfBlanks, "DrawTextInfo::Undefined NumberOfBlanks" )do { if (true && (!(m_bNumberOfBlanks))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "336" ": "), "%s", "DrawTextInfo::Undefined NumberOfBlanks"
); } } while (false)
;
337#endif
338 return m_nNumberOfBlanks;
339 }
340
341 sal_uInt8 GetCursorBidiLevel() const
342 {
343 return m_nCursorBidiLevel;
344 }
345
346 bool GetBullet() const
347 {
348 return m_bBullet;
349 }
350
351 bool GetUpper() const
352 {
353#ifdef DBG_UTIL
354 OSL_ENSURE( m_bUppr, "DrawTextInfo: Undefined Upperflag" )do { if (true && (!(m_bUppr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "354" ": "), "%s", "DrawTextInfo: Undefined Upperflag");
} } while (false)
;
355#endif
356 return m_bUpper;
357 }
358
359 bool GetDrawSpace() const
360 {
361#ifdef DBG_UTIL
362 OSL_ENSURE( m_bDrawSp, "DrawTextInfo: Undefined DrawSpaceflag" )do { if (true && (!(m_bDrawSp))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/inc/drawfont.hxx"
":" "362" ": "), "%s", "DrawTextInfo: Undefined DrawSpaceflag"
); } } while (false)
;
363#endif
364 return m_bDrawSpace;
365 }
366
367 bool GetGreyWave() const
368 {
369 return m_bGreyWave;
370 }
371
372 bool IsSpaceStop() const
373 {
374 return m_bSpaceStop;
375 }
376
377 bool SnapToGrid() const
378 {
379 return m_bSnapToGrid;
380 }
381
382 bool IsIgnoreFrameRTL() const
383 {
384 return m_bIgnoreFrameRTL;
385 }
386
387 bool IsPosMatchesBounds() const
388 {
389 return m_bPosMatchesBounds;
390 }
391
392 void SetOut( OutputDevice &rNew )
393 {
394 m_pOut = &rNew;
22
Calling 'VclPtr::operator='
32
Returning; memory was released
395 }
396
397 void SetPos( const Point &rNew )
398 {
399 m_aPos = rNew;
400#ifdef DBG_UTIL
401 m_bPos = true;
402#endif
403 }
404
405 void SetHyphPos(TextFrameIndex *const pNew)
406 {
407 m_pHyphPos = pNew;
408#ifdef DBG_UTIL
409 m_bHyph = true;
410#endif
411 }
412
413 void SetText( const OUString &rNew )
414 {
415 m_aText = rNew;
416 m_pCachedVclData = nullptr; // would any case benefit from save/restore?
417 }
418
419 void SetWrong(sw::WrongListIterator *const pNew)
420 {
421 m_pWrong = pNew;
422#ifdef DBG_UTIL
423 m_bWrong = true;
424#endif
425 }
426
427 void SetGrammarCheck(sw::WrongListIterator *const pNew)
428 {
429 m_pGrammarCheck = pNew;
430#ifdef DBG_UTIL
431 m_bGrammarCheck = true;
432#endif
433 }
434
435 void SetSmartTags(sw::WrongListIterator *const pNew)
436 {
437 m_pSmartTags = pNew;
438 }
439
440 void SetSize( const Size &rNew )
441 {
442 m_aSize = rNew;
443#ifdef DBG_UTIL
444 m_bSize = true;
445#endif
446 }
447
448 void SetFont( SwFont* pNew )
449 {
450 m_pFnt = pNew;
451#ifdef DBG_UTIL
452 m_bFnt = true;
453#endif
454 }
455
456 void SetIdx(TextFrameIndex const nNew)
457 {
458 m_nIdx = nNew;
459 }
460
461 void SetLen(TextFrameIndex const nNew)
462 {
463 m_nLen = nNew;
464 }
465
466 void SetOffset( sal_Int32 nNew )
467 {
468 m_nOfst = nNew;
469#ifdef DBG_UTIL
470 m_bOfst = true;
471#endif
472 }
473
474 void SetKanaDiff( long nNew )
475 {
476 m_nKanaDiff = nNew;
477#ifdef DBG_UTIL
478 m_bKana = true;
479#endif
480 }
481
482 void SetWidth( sal_uInt16 nNew )
483 {
484 m_nWidth = nNew;
485 }
486
487 void SetAscent( sal_uInt16 nNew )
488 {
489 m_nAscent = nNew;
490#ifdef DBG_UTIL
491 m_bAscent = true;
492#endif
493 }
494
495 void SetKern( long nNew )
496 {
497 m_nKern = nNew;
498 }
499
500 void SetSpace( long nNew )
501 {
502 if( nNew < 0 )
503 {
504 m_nSperren = -nNew;
505 m_nSpace = 0;
506 }
507 else
508 {
509 m_nSpace = nNew;
510 m_nSperren = 0;
511 }
512#ifdef DBG_UTIL
513 m_bSpace = true;
514 m_bSperr = true;
515#endif
516 }
517
518 void SetNumberOfBlanks( TextFrameIndex const nNew )
519 {
520#ifdef DBG_UTIL
521 m_bNumberOfBlanks = true;
522#endif
523 m_nNumberOfBlanks = nNew;
524 }
525
526 void SetCursorBidiLevel( sal_uInt8 nNew )
527 {
528 m_nCursorBidiLevel = nNew;
529 }
530
531 void SetKanaComp( short nNew )
532 {
533 m_nCompress = nNew;
534 }
535
536 void SetBullet( bool bNew )
537 {
538 m_bBullet = bNew;
539 }
540
541 void SetUnderFnt( SwUnderlineFont* pULFnt )
542 {
543 m_pUnderFnt = pULFnt;
544 }
545
546 void SetUpper( bool bNew )
547 {
548 m_bUpper = bNew;
549#ifdef DBG_UTIL
550 m_bUppr = true;
551#endif
552 }
553
554 void SetDrawSpace( bool bNew )
555 {
556 m_bDrawSpace = bNew;
557#ifdef DBG_UTIL
558 m_bDrawSp = true;
559#endif
560 }
561
562 void SetGreyWave( bool bNew )
563 {
564 m_bGreyWave = bNew;
565 }
566
567 void SetSpaceStop( bool bNew )
568 {
569 m_bSpaceStop = bNew;
570 }
571
572 void SetSnapToGrid( bool bNew )
573 {
574 m_bSnapToGrid = bNew;
575 }
576
577 void SetIgnoreFrameRTL( bool bNew )
578 {
579 m_bIgnoreFrameRTL = bNew;
580 }
581
582 void SetPosMatchesBounds( bool bNew )
583 {
584 m_bPosMatchesBounds = bNew;
585 }
586
587 void Shift( sal_uInt16 nDir );
588
589 // sets a new color at the output device if necessary if a font is passed
590 // as argument, the change if made to the font otherwise the font at the
591 // output device is changed returns if the font has been changed
592 bool ApplyAutoColor( vcl::Font* pFnt = nullptr );
593};
594
595#endif
596
597/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.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_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
23
Calling 'Reference::set'
31
Returning; memory was released
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.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_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody
23.1
'pBody' is non-null
23.1
'pBody' is non-null
23.1
'pBody' is non-null
23.1
'pBody' is non-null
23.1
'pBody' is non-null
)
24
Taking true branch
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld
24.1
'pOld' is non-null
24.1
'pOld' is non-null
24.1
'pOld' is non-null
24.1
'pOld' is non-null
24.1
'pOld' is non-null
)
25
Taking true branch
127 pOld->release();
26
Calling 'VclReferenceBase::release'
30
Returning; memory was released
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.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_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
27
Assuming the condition is true
28
Taking true branch
40 delete this;
29
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif