Bug Summary

File:home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx
Warning:line 591, column 5
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 svxfont.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 EDITENG_DLLIMPLEMENTATION -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/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/editeng/inc -I /home/maarten/src/libreoffice/core/editeng/source/editeng -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/editeng/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/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/editeng/source/items/svxfont.cxx

/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.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 <vcl/metric.hxx>
21#include <vcl/outdev.hxx>
22#include <vcl/print.hxx>
23#include <tools/debug.hxx>
24#include <tools/gen.hxx>
25#include <tools/poly.hxx>
26#include <unotools/charclass.hxx>
27#include <com/sun/star/i18n/KCharacterType.hpp>
28#include <editeng/svxfont.hxx>
29#include <editeng/escapementitem.hxx>
30#include <sal/log.hxx>
31
32SvxFont::SvxFont()
33{
34 nKern = nEsc = 0;
35 nPropr = 100;
36 eCaseMap = SvxCaseMap::NotMapped;
37 SetLanguage(LANGUAGE_SYSTEMLanguageType(0x0000));
38}
39
40SvxFont::SvxFont( const vcl::Font &rFont )
41 : Font( rFont )
42{
43 nKern = nEsc = 0;
44 nPropr = 100;
45 eCaseMap = SvxCaseMap::NotMapped;
46 SetLanguage(LANGUAGE_SYSTEMLanguageType(0x0000));
47}
48
49SvxFont::SvxFont( const SvxFont &rFont )
50 : Font( rFont )
51{
52 nKern = rFont.GetFixKerning();
53 nEsc = rFont.GetEscapement();
54 nPropr = rFont.GetPropr();
55 eCaseMap = rFont.GetCaseMap();
56 SetLanguage(rFont.GetLanguage());
57}
58
59void SvxFont::SetNonAutoEscapement(short nNewEsc, const OutputDevice* pOutDev)
60{
61 nEsc = nNewEsc;
62 if ( abs(nEsc) == DFLT_ESC_AUTO_SUPER(13999 +1) )
63 {
64 double fAutoAscent = .8;
65 double fAutoDescent = .2;
66 if ( pOutDev )
67 {
68 const FontMetric& rFontMetric = pOutDev->GetFontMetric();
69 double fFontHeight = rFontMetric.GetAscent() + rFontMetric.GetDescent();
70 if ( fFontHeight )
71 {
72 fAutoAscent = rFontMetric.GetAscent() / fFontHeight;
73 fAutoDescent = rFontMetric.GetDescent() / fFontHeight;
74 }
75 }
76
77 if ( nEsc == DFLT_ESC_AUTO_SUPER(13999 +1) )
78 nEsc = fAutoAscent * (100 - nPropr);
79 else //DFLT_ESC_AUTO_SUB
80 nEsc = fAutoDescent * -(100 - nPropr);
81 }
82
83 if ( nEsc > MAX_ESC_POS13999 )
84 nEsc = MAX_ESC_POS13999;
85 else if ( nEsc < -MAX_ESC_POS13999 )
86 nEsc = -MAX_ESC_POS13999;
87}
88
89void SvxFont::DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
90 const Size& rSize, const Color& rCol, bool bLeft )
91{
92 long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
93 long nRight = nLeft + rSize.Width();
94 long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
95 long nTop = nMid - rSize.Height() / 2;
96 long nBottom = nTop + rSize.Height();
97 if( nLeft < rRect.Left() )
98 {
99 nLeft = rRect.Left();
100 nRight = rRect.Right();
101 }
102 if( nTop < rRect.Top() )
103 {
104 nTop = rRect.Top();
105 nBottom = rRect.Bottom();
106 }
107 tools::Polygon aPoly;
108 Point aTmp( bLeft ? nLeft : nRight, nMid );
109 Point aNxt( bLeft ? nRight : nLeft, nTop );
110 aPoly.Insert( 0, aTmp );
111 aPoly.Insert( 0, aNxt );
112 aNxt.setY( nBottom );
113 aPoly.Insert( 0, aNxt );
114 aPoly.Insert( 0, aTmp );
115 Color aOldLineColor = rOut.GetLineColor();
116 Color aOldFillColor = rOut.GetFillColor();
117 rOut.SetFillColor( rCol );
118 rOut.SetLineColor( COL_BLACK );
119 rOut.DrawPolygon( aPoly );
120 rOut.DrawLine( aTmp, aNxt );
121 rOut.SetLineColor( aOldLineColor );
122 rOut.SetFillColor( aOldFillColor );
123}
124
125
126OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
127{
128 if (!IsCaseMap() || rTxt.isEmpty())
129 return rTxt;
130 OUString aTxt(rTxt);
131 // I still have to get the language
132 const LanguageType eLang = LANGUAGE_DONTKNOWLanguageType(0x03FF) == GetLanguage()
133 ? LANGUAGE_SYSTEMLanguageType(0x0000) : GetLanguage();
134
135 LanguageTag aLanguageTag(eLang);
136 CharClass aCharClass( aLanguageTag );
137
138 switch( eCaseMap )
139 {
140 case SvxCaseMap::SmallCaps:
141 case SvxCaseMap::Uppercase:
142 {
143 aTxt = aCharClass.uppercase( aTxt );
144 break;
145 }
146
147 case SvxCaseMap::Lowercase:
148 {
149 aTxt = aCharClass.lowercase( aTxt );
150 break;
151 }
152 case SvxCaseMap::Capitalize:
153 {
154 // Every beginning of a word is capitalized, the rest of the word
155 // is taken over as is.
156 // Bug: if the attribute starts in the middle of the word.
157 bool bBlank = true;
158
159 for (sal_Int32 i = 0; i < aTxt.getLength(); ++i)
160 {
161 if( aTxt[i] == ' ' || aTxt[i] == '\t')
162 bBlank = true;
163 else
164 {
165 if (bBlank)
166 {
167 OUString sTitle(aCharClass.uppercase(OUString(aTxt[i])));
168 aTxt = aTxt.replaceAt(i, 1, sTitle);
169 }
170 bBlank = false;
171 }
172 }
173 break;
174 }
175 default:
176 {
177 SAL_WARN( "editeng", "SvxFont::CaseMapTxt: unknown casemap")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "editeng")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SvxFont::CaseMapTxt: unknown casemap"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng"
), ("/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
":" "177" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SvxFont::CaseMapTxt: unknown casemap"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SvxFont::CaseMapTxt: unknown casemap"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng"), ("/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
":" "177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SvxFont::CaseMapTxt: unknown casemap") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng"), (
"/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
":" "177" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SvxFont::CaseMapTxt: unknown casemap"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SvxFont::CaseMapTxt: unknown casemap"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng"), ("/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
":" "177" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
178 break;
179 }
180 }
181 return aTxt;
182}
183
184/*************************************************************************
185 * class SvxDoCapitals
186 * The virtual Method Do si called by SvxFont::DoOnCapitals alternately
187 * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills
188 * this method with life.
189 *************************************************************************/
190
191class SvxDoCapitals
192{
193protected:
194 VclPtr<OutputDevice> pOut;
195 const OUString &rTxt;
196 const sal_Int32 nIdx;
197 const sal_Int32 nLen;
198
199public:
200 SvxDoCapitals( OutputDevice *_pOut, const OUString &_rTxt,
201 const sal_Int32 _nIdx, const sal_Int32 _nLen )
202 : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
203 { }
204
205 virtual ~SvxDoCapitals() {}
11
Calling implicit destructor for 'VclPtr<OutputDevice>'
12
Calling '~Reference'
19
Returning from '~Reference'
20
Returning from destructor for 'VclPtr<OutputDevice>'
206
207 virtual void DoSpace( const bool bDraw );
208 virtual void SetSpace();
209 virtual void Do( const OUString &rTxt,
210 const sal_Int32 nIdx, const sal_Int32 nLen,
211 const bool bUpper ) = 0;
212
213 const OUString &GetTxt() const { return rTxt; }
214 sal_Int32 GetIdx() const { return nIdx; }
215 sal_Int32 GetLen() const { return nLen; }
216};
217
218void SvxDoCapitals::DoSpace( const bool /*bDraw*/ ) { }
219
220void SvxDoCapitals::SetSpace() { }
221
222/*************************************************************************
223 * SvxFont::DoOnCapitals() const
224 * Decomposes the String into uppercase and lowercase letters and then
225 * calls the method SvxDoCapitals::Do( ).
226 *************************************************************************/
227
228void SvxFont::DoOnCapitals(SvxDoCapitals &rDo) const
229{
230 const OUString &rTxt = rDo.GetTxt();
231 const sal_Int32 nIdx = rDo.GetIdx();
232 const sal_Int32 nLen = rDo.GetLen();
233
234 const OUString aTxt( CalcCaseMap( rTxt ) );
235 const sal_Int32 nTxtLen = std::min( rTxt.getLength(), nLen );
236 sal_Int32 nPos = 0;
237 sal_Int32 nOldPos = nPos;
238
239 // Test if string length differ between original and CaseMapped
240 bool bCaseMapLengthDiffers(aTxt.getLength() != rTxt.getLength());
241
242 const LanguageType eLang = LANGUAGE_DONTKNOWLanguageType(0x03FF) == GetLanguage()
243 ? LANGUAGE_SYSTEMLanguageType(0x0000) : GetLanguage();
244
245 LanguageTag aLanguageTag(eLang);
246 CharClass aCharClass( aLanguageTag );
247 OUString aCharString;
248
249 while( nPos < nTxtLen )
250 {
251 // first in turn are the uppercase letters
252
253 // There are characters that are both upper- and lower-case L (eg blank)
254 // Such ambiguities lead to chaos, this is why these characters are
255 // allocated to the lowercase characters!
256
257 while( nPos < nTxtLen )
258 {
259 aCharString = rTxt.copy( nPos + nIdx, 1 );
260 sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
261 if ( nCharacterType & css::i18n::KCharacterType::LOWER )
262 break;
263 if ( ! ( nCharacterType & css::i18n::KCharacterType::UPPER ) )
264 break;
265 ++nPos;
266 }
267 if( nOldPos != nPos )
268 {
269 if(bCaseMapLengthDiffers)
270 {
271 // If strings differ work preparing the necessary snippet to address that
272 // potential difference
273 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos-nOldPos);
274 OUString aNewText = CalcCaseMap(aSnippet);
275
276 rDo.Do( aNewText, 0, aNewText.getLength(), true );
277 }
278 else
279 {
280 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, true );
281 }
282
283 nOldPos = nPos;
284 }
285 // Now the lowercase are processed (without blanks)
286 while( nPos < nTxtLen )
287 {
288 sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
289 if ( nCharacterType & css::i18n::KCharacterType::UPPER )
290 break;
291 if ( aCharString == " " )
292 break;
293 if( ++nPos < nTxtLen )
294 aCharString = rTxt.copy( nPos + nIdx, 1 );
295 }
296 if( nOldPos != nPos )
297 {
298 if(bCaseMapLengthDiffers)
299 {
300 // If strings differ work preparing the necessary snippet to address that
301 // potential difference
302 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
303 OUString aNewText = CalcCaseMap(aSnippet);
304
305 rDo.Do( aNewText, 0, aNewText.getLength(), false );
306 }
307 else
308 {
309 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, false );
310 }
311
312 nOldPos = nPos;
313 }
314 // Now the blanks are<processed
315 while( nPos < nTxtLen && aCharString == " " && ++nPos < nTxtLen )
316 aCharString = rTxt.copy( nPos + nIdx, 1 );
317
318 if( nOldPos != nPos )
319 {
320 rDo.DoSpace( false );
321
322 if(bCaseMapLengthDiffers)
323 {
324 // If strings differ work preparing the necessary snippet to address that
325 // potential difference
326 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
327 OUString aNewText = CalcCaseMap(aSnippet);
328
329 rDo.Do( aNewText, 0, aNewText.getLength(), false );
330 }
331 else
332 {
333 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, false );
334 }
335
336 nOldPos = nPos;
337 rDo.SetSpace();
338 }
339 }
340 rDo.DoSpace( true );
341}
342
343
344void SvxFont::SetPhysFont( OutputDevice *pOut ) const
345{
346 const vcl::Font& rCurrentFont = pOut->GetFont();
347 if ( nPropr == 100 )
348 {
349 if ( !rCurrentFont.IsSameInstance( *this ) )
350 pOut->SetFont( *this );
351 }
352 else
353 {
354 Font aNewFont( *this );
355 Size aSize( aNewFont.GetFontSize() );
356 aNewFont.SetFontSize( Size( aSize.Width() * nPropr / 100,
357 aSize.Height() * nPropr / 100 ) );
358 if ( !rCurrentFont.IsSameInstance( aNewFont ) )
359 pOut->SetFont( aNewFont );
360 }
361}
362
363
364vcl::Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
365{
366 vcl::Font aOldFont( pOut->GetFont() );
367 SetPhysFont( pOut );
368 return aOldFont;
369}
370
371
372Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt,
373 const sal_Int32 nIdx, const sal_Int32 nLen ) const
374{
375 if ( !IsCaseMap() && !IsKern() )
376 return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
377 pOut->GetTextHeight() );
378
379 Size aTxtSize;
380 aTxtSize.setHeight( pOut->GetTextHeight() );
381 if ( !IsCaseMap() )
382 aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
383 else
384 {
385 const OUString aNewText = CalcCaseMap(rTxt);
386 bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
387 sal_Int32 nWidth(0);
388
389 if(bCaseMapLengthDiffers)
390 {
391 // If strings differ work preparing the necessary snippet to address that
392 // potential difference
393 const OUString aSnippet = rTxt.copy(nIdx, nLen);
394 OUString _aNewText = CalcCaseMap(aSnippet);
395 nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.getLength() );
396 }
397 else
398 {
399 nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
400 }
401
402 aTxtSize.setWidth(nWidth);
403 }
404
405 if( IsKern() && ( nLen > 1 ) )
406 aTxtSize.AdjustWidth( ( nLen-1 ) * long( nKern ) );
407
408 return aTxtSize;
409}
410
411Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut )
412{
413 if ( !IsCaseMap() && !IsKern() )
414 return Size( pOut->GetTextWidth( "" ), pOut->GetTextHeight() );
415
416 Size aTxtSize;
417 aTxtSize.setHeight( pOut->GetTextHeight() );
418 if ( !IsCaseMap() )
419 aTxtSize.setWidth( pOut->GetTextWidth( "" ) );
420 else
421 aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( "" ) ) );
422
423 return aTxtSize;
424}
425
426Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt,
427 const sal_Int32 nIdx, const sal_Int32 nLen, long* pDXArray ) const
428{
429 if ( !IsCaseMap() && !IsKern() )
430 return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
431 pOut->GetTextHeight() );
432
433 Size aTxtSize;
434 aTxtSize.setHeight( pOut->GetTextHeight() );
435 if ( !IsCaseMap() )
436 aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
437 else
438 aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
439 pDXArray, nIdx, nLen ) );
440
441 if( IsKern() && ( nLen > 1 ) )
442 {
443 aTxtSize.AdjustWidth( ( nLen-1 ) * long( nKern ) );
444
445 if ( pDXArray )
446 {
447 for ( sal_Int32 i = 0; i < nLen; i++ )
448 pDXArray[i] += ( (i+1) * long( nKern ) );
449 // The last one is a nKern too big:
450 pDXArray[nLen-1] -= nKern;
451 }
452 }
453 return aTxtSize;
454}
455
456
457Size SvxFont::GetTextSize( const OutputDevice *pOut, const OUString &rTxt,
458 const sal_Int32 nIdx, const sal_Int32 nLen ) const
459{
460 sal_Int32 nTmp = nLen;
461 if ( nTmp == SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF) ) // already initialized?
462 nTmp = rTxt.getLength();
463 Font aOldFont( ChgPhysFont(const_cast<OutputDevice *>(pOut)) );
464 Size aTxtSize;
465 if( IsCapital() && !rTxt.isEmpty() )
466 {
467 aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
468 }
469 else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
470 const_cast<OutputDevice *>(pOut)->SetFont( aOldFont );
471 return aTxtSize;
472}
473
474
475void SvxFont::QuickDrawText( OutputDevice *pOut,
476 const Point &rPos, const OUString &rTxt,
477 const sal_Int32 nIdx, const sal_Int32 nLen, const long* pDXArray ) const
478{
479
480 // Font has to be selected in OutputDevice...
481 if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
482 {
483 pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
484 return;
485 }
486
487 Point aPos( rPos );
488
489 if ( nEsc )
490 {
491 long nDiff = GetFontSize().Height();
492 nDiff *= nEsc;
493 nDiff /= 100;
494
495 if ( !IsVertical() )
496 aPos.AdjustY( -nDiff );
497 else
498 aPos.AdjustX(nDiff );
499 }
500
501 if( IsCapital() )
502 {
503 DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" )do { if (true && (!(!pDXArray))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
":" "503" ": "), "%s", "DrawCapital not for TextArray!"); } }
while (false)
;
504 DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
505 }
506 else
507 {
508 if ( IsKern() && !pDXArray )
509 {
510 Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
511
512 if ( !IsCaseMap() )
513 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
514 else
515 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
516 }
517 else
518 {
519 if ( !IsCaseMap() )
520 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
521 else
522 pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
523 }
524 }
525}
526
527
528void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
529 const Point &rPos, const OUString &rTxt,
530 const sal_Int32 nIdx, const sal_Int32 nLen ) const
531{
532 if ( !nLen || rTxt.isEmpty() )
1
Assuming 'nLen' is not equal to 0
2
Taking false branch
533 return;
534 sal_Int32 nTmp = nLen;
535
536 if ( nTmp == SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF) ) // already initialized?
3
Assuming 'nTmp' is not equal to SAL_MAX_INT32
4
Taking false branch
537 nTmp = rTxt.getLength();
538 Point aPos( rPos );
539
540 if ( nEsc )
5
Assuming field 'nEsc' is 0
6
Taking false branch
541 {
542 short nTmpEsc;
543 if( DFLT_ESC_AUTO_SUPER(13999 +1) == nEsc )
544 {
545 nTmpEsc = .8 * (100 - nPropr);
546 assert (nTmpEsc == DFLT_ESC_SUPER && "I'm sure this formula needs to be changed, but how to confirm that???")(static_cast <bool> (nTmpEsc == 33 && "I'm sure this formula needs to be changed, but how to confirm that???"
) ? void (0) : __assert_fail ("nTmpEsc == DFLT_ESC_SUPER && \"I'm sure this formula needs to be changed, but how to confirm that???\""
, "/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
, 546, __extension__ __PRETTY_FUNCTION__))
;
547 nTmpEsc = DFLT_ESC_SUPER33;
548 }
549 else if( DFLT_ESC_AUTO_SUB-(13999 +1) == nEsc )
550 {
551 nTmpEsc = .2 * -(100 - nPropr);
552 assert (nTmpEsc == -20 && "I'm sure this formula needs to be changed, but how to confirm that???")(static_cast <bool> (nTmpEsc == -20 && "I'm sure this formula needs to be changed, but how to confirm that???"
) ? void (0) : __assert_fail ("nTmpEsc == -20 && \"I'm sure this formula needs to be changed, but how to confirm that???\""
, "/home/maarten/src/libreoffice/core/editeng/source/items/svxfont.cxx"
, 552, __extension__ __PRETTY_FUNCTION__))
;
553 nTmpEsc = -20;
554 }
555 else
556 nTmpEsc = nEsc;
557 Size aSize = GetFontSize();
558 aPos.AdjustY( -(( nTmpEsc * aSize.Height() ) / 100) );
559 }
560 Font aOldFont( ChgPhysFont( pOut ) );
561 Font aOldPrnFont( ChgPhysFont( pPrinter ) );
562
563 if ( IsCapital() )
7
Taking true branch
564 DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
8
Calling 'SvxFont::DrawCapital'
23
Returning; memory was released via 1st parameter
565 else
566 {
567 Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
568
569 if ( !IsCaseMap() )
570 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
571 else
572 {
573 const OUString aNewText = CalcCaseMap(rTxt);
574 bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
575
576 if(bCaseMapLengthDiffers)
577 {
578 // If strings differ work preparing the necessary snippet to address that
579 // potential difference
580 const OUString aSnippet(rTxt.copy( nIdx, nTmp));
581 OUString _aNewText = CalcCaseMap(aSnippet);
582
583 pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.getLength() );
584 }
585 else
586 {
587 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
588 }
589 }
590 }
591 pOut->SetFont(aOldFont);
24
Use of memory after it is freed
592 pPrinter->SetFont( aOldPrnFont );
593}
594
595
596SvxFont& SvxFont::operator=( const vcl::Font& rFont )
597{
598 Font::operator=( rFont );
599 return *this;
600}
601
602SvxFont& SvxFont::operator=( const SvxFont& rFont )
603{
604 Font::operator=( rFont );
605 eCaseMap = rFont.eCaseMap;
606 nEsc = rFont.nEsc;
607 nPropr = rFont.nPropr;
608 nKern = rFont.nKern;
609 return *this;
610}
611
612namespace {
613
614class SvxDoGetCapitalSize : public SvxDoCapitals
615{
616protected:
617 SvxFont* pFont;
618 Size aTxtSize;
619 short nKern;
620public:
621 SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
622 const OUString &_rTxt, const sal_Int32 _nIdx,
623 const sal_Int32 _nLen, const short _nKrn )
624 : SvxDoCapitals( const_cast<OutputDevice*>(_pOut), _rTxt, _nIdx, _nLen ),
625 pFont( _pFnt ),
626 nKern( _nKrn )
627 { }
628
629 virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
630 const sal_Int32 nLen, const bool bUpper ) override;
631
632 const Size &GetSize() const { return aTxtSize; };
633};
634
635}
636
637void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
638 const sal_Int32 _nLen, const bool bUpper )
639{
640 Size aPartSize;
641 if ( !bUpper )
642 {
643 sal_uInt8 nProp = pFont->GetPropr();
644 pFont->SetProprRel( SMALL_CAPS_PERCENTAGE80 );
645 pFont->SetPhysFont( pOut );
646 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
647 aPartSize.setHeight( pOut->GetTextHeight() );
648 aTxtSize.setHeight( aPartSize.Height() );
649 pFont->SetPropr( nProp );
650 pFont->SetPhysFont( pOut );
651 }
652 else
653 {
654 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
655 aPartSize.setHeight( pOut->GetTextHeight() );
656 }
657 aTxtSize.AdjustWidth(aPartSize.Width() );
658 aTxtSize.AdjustWidth( _nLen * long( nKern ) );
659}
660
661Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt,
662 const sal_Int32 nIdx, const sal_Int32 nLen) const
663{
664 // Start:
665 SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, nIdx, nLen, nKern );
666 DoOnCapitals( aDo );
667 Size aTxtSize( aDo.GetSize() );
668
669 // End:
670 if( !aTxtSize.Height() )
671 {
672 aTxtSize.setWidth( 0 );
673 aTxtSize.setHeight( pOut->GetTextHeight() );
674 }
675 return aTxtSize;
676}
677
678namespace {
679
680class SvxDoDrawCapital : public SvxDoCapitals
681{
682protected:
683 SvxFont *pFont;
684 Point aPos;
685 Point aSpacePos;
686 short nKern;
687public:
688 SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt,
689 const sal_Int32 _nIdx, const sal_Int32 _nLen,
690 const Point &rPos, const short nKrn )
691 : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
692 pFont( pFnt ),
693 aPos( rPos ),
694 aSpacePos( rPos ),
695 nKern( nKrn )
696 { }
697 virtual void DoSpace( const bool bDraw ) override;
698 virtual void SetSpace() override;
699 virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
700 const sal_Int32 nLen, const bool bUpper ) override;
701};
702
703}
704
705void SvxDoDrawCapital::DoSpace( const bool bDraw )
706{
707 if ( !(bDraw || pFont->IsWordLineMode()) )
708 return;
709
710 sal_uLong nDiff = static_cast<sal_uLong>(aPos.X() - aSpacePos.X());
711 if ( nDiff )
712 {
713 bool bWordWise = pFont->IsWordLineMode();
714 bool bTrans = pFont->IsTransparent();
715 pFont->SetWordLineMode( false );
716 pFont->SetTransparent( true );
717 pFont->SetPhysFont( pOut );
718 pOut->DrawStretchText( aSpacePos, nDiff, " ", 0, 2 );
719 pFont->SetWordLineMode( bWordWise );
720 pFont->SetTransparent( bTrans );
721 pFont->SetPhysFont( pOut );
722 }
723}
724
725void SvxDoDrawCapital::SetSpace()
726{
727 if ( pFont->IsWordLineMode() )
728 aSpacePos.setX( aPos.X() );
729}
730
731void SvxDoDrawCapital::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
732 const sal_Int32 _nLen, const bool bUpper)
733{
734 sal_uInt8 nProp = 0;
735 Size aPartSize;
736
737 // Set the desired font
738 FontLineStyle eUnder = pFont->GetUnderline();
739 FontStrikeout eStrike = pFont->GetStrikeout();
740 pFont->SetUnderline( LINESTYLE_NONE );
741 pFont->SetStrikeout( STRIKEOUT_NONE );
742 if ( !bUpper )
743 {
744 nProp = pFont->GetPropr();
745 pFont->SetProprRel( SMALL_CAPS_PERCENTAGE80 );
746 }
747 pFont->SetPhysFont( pOut );
748
749 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
750 aPartSize.setHeight( pOut->GetTextHeight() );
751 long nWidth = aPartSize.Width();
752 if ( nKern )
753 {
754 aPos.AdjustX(nKern/2);
755 if ( _nLen ) nWidth += (_nLen*long(nKern));
756 }
757 pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
758
759 // Restore Font
760 pFont->SetUnderline( eUnder );
761 pFont->SetStrikeout( eStrike );
762 if ( !bUpper )
763 pFont->SetPropr( nProp );
764 pFont->SetPhysFont( pOut );
765
766 aPos.AdjustX(nWidth-(nKern/2) );
767}
768
769/*************************************************************************
770 * SvxFont::DrawCapital() draws the uppercase letter.
771 *************************************************************************/
772
773void SvxFont::DrawCapital( OutputDevice *pOut,
774 const Point &rPos, const OUString &rTxt,
775 const sal_Int32 nIdx, const sal_Int32 nLen ) const
776{
777 SvxDoDrawCapital aDo( const_cast<SvxFont *>(this),pOut,rTxt,nIdx,nLen,rPos,nKern );
778 DoOnCapitals( aDo );
779}
9
Calling implicit destructor for 'SvxDoDrawCapital'
10
Calling '~SvxDoCapitals'
21
Returning from '~SvxDoCapitals'
22
Returning from destructor for 'SvxDoDrawCapital'
780
781/* 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
12.1
Field 'm_pBody' is non-null
12.1
Field 'm_pBody' is non-null
12.1
Field 'm_pBody' is non-null
)
13
Taking true branch
113 m_pBody->release();
14
Calling 'VclReferenceBase::release'
18
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
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)
15
Assuming the condition is true
16
Taking true branch
40 delete this;
17
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