Files
libreoffice/vcl/source/outdev/outdevstate.cxx
Caolán McNamara 52052e5b03 coverity#1302690 Uninitialized pointer field
Change-Id: Idea6c8a988cdff9fd7c99fb0d37935f391ba0da2
2015-06-01 17:41:21 +01:00

657 lines
18 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <vcl/outdevstate.hxx>
#include <vcl/outdev.hxx>
#include <vcl/virdev.hxx>
#include <vcl/settings.hxx>
#include <vcl/mapmod.hxx>
#include <vcl/region.hxx>
#include <vcl/font.hxx>
#include <vcl/vclenum.hxx>
#include <tools/gen.hxx>
#include <tools/color.hxx>
#include <tools/fontenum.hxx>
#include "outdev.h"
#include "outdata.hxx"
#include <outdevstatestack.hxx>
#include "salgdi.hxx"
#include "sallayout.hxx"
OutDevState::OutDevState()
: mpMapMode(0)
, mbMapActive(false)
, mpClipRegion(0)
, mpLineColor(0)
, mpFillColor(0)
, mpFont(0)
, mpTextColor(0)
, mpTextFillColor(0)
, mpTextLineColor(0)
, mpOverlineColor(0)
, mpRefPoint(0)
, meTextAlign(ALIGN_TOP)
, meRasterOp(ROP_OVERPAINT)
, mnTextLayoutMode(TEXT_LAYOUT_DEFAULT)
, meTextLanguage(0)
, mnFlags(PushFlags::NONE)
{
}
OutDevState::~OutDevState()
{
delete mpLineColor;
delete mpFillColor;
delete mpFont;
delete mpTextColor;
delete mpTextFillColor;
delete mpTextLineColor;
delete mpOverlineColor;
delete mpMapMode;
delete mpClipRegion;
delete mpRefPoint;
}
void OutputDevice::Push( PushFlags nFlags )
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
OutDevState* pState = new OutDevState;
pState->mnFlags = nFlags;
if (nFlags & PushFlags::LINECOLOR && mbLineColor)
{
pState->mpLineColor = new Color( maLineColor );
}
if (nFlags & PushFlags::FILLCOLOR && mbFillColor)
{
pState->mpFillColor = new Color( maFillColor );
}
if ( nFlags & PushFlags::FONT )
pState->mpFont = new vcl::Font( maFont );
if ( nFlags & PushFlags::TEXTCOLOR )
pState->mpTextColor = new Color( GetTextColor() );
if (nFlags & PushFlags::TEXTFILLCOLOR && IsTextFillColor())
{
pState->mpTextFillColor = new Color( GetTextFillColor() );
}
if (nFlags & PushFlags::TEXTLINECOLOR && IsTextLineColor())
{
pState->mpTextLineColor = new Color( GetTextLineColor() );
}
if (nFlags & PushFlags::OVERLINECOLOR && IsOverlineColor())
{
pState->mpOverlineColor = new Color( GetOverlineColor() );
}
if ( nFlags & PushFlags::TEXTALIGN )
pState->meTextAlign = GetTextAlign();
if( nFlags & PushFlags::TEXTLAYOUTMODE )
pState->mnTextLayoutMode = GetLayoutMode();
if( nFlags & PushFlags::TEXTLANGUAGE )
pState->meTextLanguage = GetDigitLanguage();
if ( nFlags & PushFlags::RASTEROP )
pState->meRasterOp = GetRasterOp();
if ( nFlags & PushFlags::MAPMODE )
{
pState->mpMapMode = new MapMode( maMapMode );
pState->mbMapActive = mbMap;
}
if (nFlags & PushFlags::CLIPREGION && mbClipRegion)
{
pState->mpClipRegion = new vcl::Region( maRegion );
}
if (nFlags & PushFlags::REFPOINT && mbRefPoint)
{
pState->mpRefPoint = new Point( maRefPoint );
}
mpOutDevStateStack->push_back( pState );
if( mpAlphaVDev )
mpAlphaVDev->Push();
}
void OutputDevice::Pop()
{
if( mpMetaFile )
mpMetaFile->AddAction( new MetaPopAction() );
GDIMetaFile* pOldMetaFile = mpMetaFile;
mpMetaFile = NULL;
if ( mpOutDevStateStack->empty() )
{
SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
return;
}
const OutDevState& rState = mpOutDevStateStack->back();
if( mpAlphaVDev )
mpAlphaVDev->Pop();
if ( rState.mnFlags & PushFlags::LINECOLOR )
{
if ( rState.mpLineColor )
SetLineColor( *rState.mpLineColor );
else
SetLineColor();
}
if ( rState.mnFlags & PushFlags::FILLCOLOR )
{
if ( rState.mpFillColor )
SetFillColor( *rState.mpFillColor );
else
SetFillColor();
}
if ( rState.mnFlags & PushFlags::FONT )
SetFont( *rState.mpFont );
if ( rState.mnFlags & PushFlags::TEXTCOLOR )
SetTextColor( *rState.mpTextColor );
if ( rState.mnFlags & PushFlags::TEXTFILLCOLOR )
{
if ( rState.mpTextFillColor )
SetTextFillColor( *rState.mpTextFillColor );
else
SetTextFillColor();
}
if ( rState.mnFlags & PushFlags::TEXTLINECOLOR )
{
if ( rState.mpTextLineColor )
SetTextLineColor( *rState.mpTextLineColor );
else
SetTextLineColor();
}
if ( rState.mnFlags & PushFlags::OVERLINECOLOR )
{
if ( rState.mpOverlineColor )
SetOverlineColor( *rState.mpOverlineColor );
else
SetOverlineColor();
}
if ( rState.mnFlags & PushFlags::TEXTALIGN )
SetTextAlign( rState.meTextAlign );
if( rState.mnFlags & PushFlags::TEXTLAYOUTMODE )
SetLayoutMode( rState.mnTextLayoutMode );
if( rState.mnFlags & PushFlags::TEXTLANGUAGE )
SetDigitLanguage( rState.meTextLanguage );
if ( rState.mnFlags & PushFlags::RASTEROP )
SetRasterOp( rState.meRasterOp );
if ( rState.mnFlags & PushFlags::MAPMODE )
{
if ( rState.mpMapMode )
SetMapMode( *rState.mpMapMode );
else
SetMapMode();
mbMap = rState.mbMapActive;
}
if ( rState.mnFlags & PushFlags::CLIPREGION )
SetDeviceClipRegion( rState.mpClipRegion );
if ( rState.mnFlags & PushFlags::REFPOINT )
{
if ( rState.mpRefPoint )
SetRefPoint( *rState.mpRefPoint );
else
SetRefPoint();
}
mpOutDevStateStack->pop_back();
mpMetaFile = pOldMetaFile;
}
sal_uInt32 OutputDevice::GetGCStackDepth() const
{
return mpOutDevStateStack->size();
}
void OutputDevice::EnableOutput( bool bEnable )
{
mbOutput = bEnable;
if( mpAlphaVDev )
mpAlphaVDev->EnableOutput( bEnable );
}
void OutputDevice::SetAntialiasing( AntialiasingFlags nMode )
{
if ( mnAntialiasing != nMode )
{
mnAntialiasing = nMode;
mbInitFont = true;
if(mpGraphics)
{
mpGraphics->setAntiAliasB2DDraw(bool(mnAntialiasing & AntialiasingFlags::EnableB2dDraw));
}
}
if( mpAlphaVDev )
mpAlphaVDev->SetAntialiasing( nMode );
}
void OutputDevice::SetDrawMode( DrawModeFlags nDrawMode )
{
mnDrawMode = nDrawMode;
if( mpAlphaVDev )
mpAlphaVDev->SetDrawMode( nDrawMode );
}
void OutputDevice::SetLayoutMode( ComplexTextLayoutMode nTextLayoutMode )
{
if( mpMetaFile )
mpMetaFile->AddAction( new MetaLayoutModeAction( nTextLayoutMode ) );
mnTextLayoutMode = nTextLayoutMode;
if( mpAlphaVDev )
mpAlphaVDev->SetLayoutMode( nTextLayoutMode );
}
void OutputDevice::SetDigitLanguage( LanguageType eTextLanguage )
{
if( mpMetaFile )
mpMetaFile->AddAction( new MetaTextLanguageAction( eTextLanguage ) );
meTextLanguage = eTextLanguage;
if( mpAlphaVDev )
mpAlphaVDev->SetDigitLanguage( eTextLanguage );
}
void OutputDevice::SetRasterOp( RasterOp eRasterOp )
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
if ( meRasterOp != eRasterOp )
{
meRasterOp = eRasterOp;
mbInitLineColor = mbInitFillColor = true;
if( mpGraphics || AcquireGraphics() )
mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
}
if( mpAlphaVDev )
mpAlphaVDev->SetRasterOp( eRasterOp );
}
void OutputDevice::SetFillColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaFillColorAction( Color(), false ) );
if ( mbFillColor )
{
mbInitFillColor = true;
mbFillColor = false;
maFillColor = Color( COL_TRANSPARENT );
}
if( mpAlphaVDev )
mpAlphaVDev->SetFillColor();
}
void OutputDevice::SetFillColor( const Color& rColor )
{
Color aColor( rColor );
if( mnDrawMode & ( DrawModeFlags::BlackFill | DrawModeFlags::WhiteFill |
DrawModeFlags::GrayFill | DrawModeFlags::NoFill |
DrawModeFlags::GhostedFill | DrawModeFlags::SettingsFill ) )
{
if( !ImplIsColorTransparent( aColor ) )
{
if( mnDrawMode & DrawModeFlags::BlackFill )
{
aColor = Color( COL_BLACK );
}
else if( mnDrawMode & DrawModeFlags::WhiteFill )
{
aColor = Color( COL_WHITE );
}
else if( mnDrawMode & DrawModeFlags::GrayFill )
{
const sal_uInt8 cLum = aColor.GetLuminance();
aColor = Color( cLum, cLum, cLum );
}
else if( mnDrawMode & DrawModeFlags::NoFill )
{
aColor = Color( COL_TRANSPARENT );
}
else if( mnDrawMode & DrawModeFlags::SettingsFill )
{
aColor = GetSettings().GetStyleSettings().GetWindowColor();
}
if( mnDrawMode & DrawModeFlags::GhostedFill )
{
aColor = Color( (aColor.GetRed() >> 1) | 0x80,
(aColor.GetGreen() >> 1) | 0x80,
(aColor.GetBlue() >> 1) | 0x80);
}
}
}
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaFillColorAction( aColor, true ) );
if ( ImplIsColorTransparent( aColor ) )
{
if ( mbFillColor )
{
mbInitFillColor = true;
mbFillColor = false;
maFillColor = Color( COL_TRANSPARENT );
}
}
else
{
if ( maFillColor != aColor )
{
mbInitFillColor = true;
mbFillColor = true;
maFillColor = aColor;
}
}
if( mpAlphaVDev )
mpAlphaVDev->SetFillColor( COL_BLACK );
}
void OutputDevice::SetLineColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
if ( mbLineColor )
{
mbInitLineColor = true;
mbLineColor = false;
maLineColor = Color( COL_TRANSPARENT );
}
if( mpAlphaVDev )
mpAlphaVDev->SetLineColor();
}
void OutputDevice::SetLineColor( const Color& rColor )
{
Color aColor = ImplDrawModeToColor( rColor );
if( mpMetaFile )
mpMetaFile->AddAction( new MetaLineColorAction( aColor, true ) );
if( ImplIsColorTransparent( aColor ) )
{
if ( mbLineColor )
{
mbInitLineColor = true;
mbLineColor = false;
maLineColor = Color( COL_TRANSPARENT );
}
}
else
{
if( maLineColor != aColor )
{
mbInitLineColor = true;
mbLineColor = true;
maLineColor = aColor;
}
}
if( mpAlphaVDev )
mpAlphaVDev->SetLineColor( COL_BLACK );
}
void OutputDevice::SetBackground()
{
maBackground = Wallpaper();
mbBackground = false;
if( mpAlphaVDev )
mpAlphaVDev->SetBackground();
}
void OutputDevice::SetBackground( const Wallpaper& rBackground )
{
maBackground = rBackground;
if( rBackground.GetStyle() == WALLPAPER_NULL )
mbBackground = false;
else
mbBackground = true;
if( mpAlphaVDev )
mpAlphaVDev->SetBackground( rBackground );
}
void OutputDevice::SetFont( const vcl::Font& rNewFont )
{
vcl::Font aFont( rNewFont );
aFont.SetLanguage(rNewFont.GetLanguage());
if ( mnDrawMode & (DrawModeFlags::BlackText | DrawModeFlags::WhiteText | DrawModeFlags::GrayText | DrawModeFlags::GhostedText | DrawModeFlags::SettingsText |
DrawModeFlags::BlackFill | DrawModeFlags::WhiteFill | DrawModeFlags::GrayFill | DrawModeFlags::NoFill |
DrawModeFlags::GhostedFill | DrawModeFlags::SettingsFill ) )
{
Color aTextColor( aFont.GetColor() );
if ( mnDrawMode & DrawModeFlags::BlackText )
aTextColor = Color( COL_BLACK );
else if ( mnDrawMode & DrawModeFlags::WhiteText )
aTextColor = Color( COL_WHITE );
else if ( mnDrawMode & DrawModeFlags::GrayText )
{
const sal_uInt8 cLum = aTextColor.GetLuminance();
aTextColor = Color( cLum, cLum, cLum );
}
else if ( mnDrawMode & DrawModeFlags::SettingsText )
aTextColor = GetSettings().GetStyleSettings().GetFontColor();
if ( mnDrawMode & DrawModeFlags::GhostedText )
{
aTextColor = Color( (aTextColor.GetRed() >> 1 ) | 0x80,
(aTextColor.GetGreen() >> 1 ) | 0x80,
(aTextColor.GetBlue() >> 1 ) | 0x80 );
}
aFont.SetColor( aTextColor );
bool bTransFill = aFont.IsTransparent();
if ( !bTransFill )
{
Color aTextFillColor( aFont.GetFillColor() );
if ( mnDrawMode & DrawModeFlags::BlackFill )
aTextFillColor = Color( COL_BLACK );
else if ( mnDrawMode & DrawModeFlags::WhiteFill )
aTextFillColor = Color( COL_WHITE );
else if ( mnDrawMode & DrawModeFlags::GrayFill )
{
const sal_uInt8 cLum = aTextFillColor.GetLuminance();
aTextFillColor = Color( cLum, cLum, cLum );
}
else if( mnDrawMode & DrawModeFlags::SettingsFill )
aTextFillColor = GetSettings().GetStyleSettings().GetWindowColor();
else if ( mnDrawMode & DrawModeFlags::NoFill )
{
aTextFillColor = Color( COL_TRANSPARENT );
bTransFill = true;
}
if ( !bTransFill && (mnDrawMode & DrawModeFlags::GhostedFill) )
{
aTextFillColor = Color( (aTextFillColor.GetRed() >> 1) | 0x80,
(aTextFillColor.GetGreen() >> 1) | 0x80,
(aTextFillColor.GetBlue() >> 1) | 0x80 );
}
aFont.SetFillColor( aTextFillColor );
}
}
if ( mpMetaFile )
{
mpMetaFile->AddAction( new MetaFontAction( aFont ) );
// the color and alignment actions don't belong here
// TODO: get rid of them without breaking anything...
mpMetaFile->AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
mpMetaFile->AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
}
if ( !maFont.IsSameInstance( aFont ) )
{
// Optimization MT/HDU: COL_TRANSPARENT means SetFont should ignore the font color,
// because SetTextColor() is used for this.
// #i28759# maTextColor might have been changed behind our back, commit then, too.
if( aFont.GetColor() != COL_TRANSPARENT
&& (aFont.GetColor() != maFont.GetColor() || aFont.GetColor() != maTextColor ) )
{
maTextColor = aFont.GetColor();
mbInitTextColor = true;
if( mpMetaFile )
mpMetaFile->AddAction( new MetaTextColorAction( aFont.GetColor() ) );
}
maFont = aFont;
mbNewFont = true;
if( mpAlphaVDev )
{
// #i30463#
// Since SetFont might change the text color, apply that only
// selectively to alpha vdev (which normally paints opaque text
// with COL_BLACK)
if( aFont.GetColor() != COL_TRANSPARENT )
{
mpAlphaVDev->SetTextColor( COL_BLACK );
aFont.SetColor( COL_TRANSPARENT );
}
mpAlphaVDev->SetFont( aFont );
}
}
}
void OutputDevice::InitLineColor()
{
DBG_TESTSOLARMUTEX();
if( mbLineColor )
{
if( ROP_0 == meRasterOp )
mpGraphics->SetROPLineColor( SAL_ROP_0 );
else if( ROP_1 == meRasterOp )
mpGraphics->SetROPLineColor( SAL_ROP_1 );
else if( ROP_INVERT == meRasterOp )
mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
else
mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
}
else
mpGraphics->SetLineColor();
mbInitLineColor = false;
}
void OutputDevice::InitFillColor()
{
DBG_TESTSOLARMUTEX();
if( mbFillColor )
{
if( ROP_0 == meRasterOp )
mpGraphics->SetROPFillColor( SAL_ROP_0 );
else if( ROP_1 == meRasterOp )
mpGraphics->SetROPFillColor( SAL_ROP_1 );
else if( ROP_INVERT == meRasterOp )
mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
else
mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
}
else
mpGraphics->SetFillColor();
mbInitFillColor = false;
}
void OutputDevice::ImplReleaseFonts()
{
mpGraphics->ReleaseFonts();
mbNewFont = true;
mbInitFont = true;
if ( mpFontEntry )
{
mpFontCache->Release( mpFontEntry );
mpFontEntry = NULL;
}
if ( mpGetDevFontList )
{
delete mpGetDevFontList;
mpGetDevFontList = NULL;
}
if ( mpGetDevSizeList )
{
delete mpGetDevSizeList;
mpGetDevSizeList = NULL;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */