diff options
Diffstat (limited to 'toolkit/source/awt/vclxgraphics.cxx')
-rw-r--r-- | toolkit/source/awt/vclxgraphics.cxx | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/toolkit/source/awt/vclxgraphics.cxx b/toolkit/source/awt/vclxgraphics.cxx new file mode 100644 index 000000000..9fcb527a0 --- /dev/null +++ b/toolkit/source/awt/vclxgraphics.cxx @@ -0,0 +1,492 @@ +/* -*- 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 <memory> +#include <awt/vclxgraphics.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <toolkit/helper/macros.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <cppuhelper/queryinterface.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <vcl/image.hxx> +#include <vcl/gradient.hxx> +#include <vcl/metric.hxx> +#include <tools/debug.hxx> + +using namespace com::sun::star; + + + +// lang::XUnoTunnel +UNO3_GETIMPLEMENTATION_IMPL( VCLXGraphics ); + +VCLXGraphics::VCLXGraphics() + : mpOutputDevice(nullptr) + , meRasterOp(RasterOp::OverPaint) +{ +} + +VCLXGraphics::~VCLXGraphics() +{ + std::vector< VCLXGraphics* > *pLst = mpOutputDevice ? mpOutputDevice->GetUnoGraphicsList() : nullptr; + if ( pLst ) + { + auto it = std::find(pLst->begin(), pLst->end(), this); + if (it != pLst->end()) + pLst->erase( it ); + } + + mpClipRegion.reset(); + + SolarMutexGuard g; + mpOutputDevice.reset(); +} + +void VCLXGraphics::SetOutputDevice( OutputDevice* pOutDev ) +{ + mpOutputDevice = pOutDev; + mxDevice = nullptr; + initAttrs(); +} + +void VCLXGraphics::Init( OutputDevice* pOutDev ) +{ + DBG_ASSERT( !mpOutputDevice, "VCLXGraphics::Init already has pOutDev !" ); + mpOutputDevice = pOutDev; + + initAttrs(); + mpClipRegion = nullptr; + + // Register at OutputDevice + std::vector< VCLXGraphics* > *pLst = mpOutputDevice->GetUnoGraphicsList(); + if ( !pLst ) + pLst = mpOutputDevice->CreateUnoGraphicsList(); + pLst->push_back( this ); +} + +void VCLXGraphics::initAttrs() +{ + if ( !mpOutputDevice ) + return; + + maFont = mpOutputDevice->GetFont(); + maTextColor = mpOutputDevice->GetTextColor(); /* COL_BLACK */ + maTextFillColor = mpOutputDevice->GetTextFillColor(); /* COL_TRANSPARENT */ + maLineColor = mpOutputDevice->GetLineColor(); /* COL_BLACK */ + maFillColor = mpOutputDevice->GetFillColor(); /* COL_WHITE */ + meRasterOp = mpOutputDevice->GetRasterOp(); /* RasterOp::OverPaint */ +} + +void VCLXGraphics::InitOutputDevice( InitOutDevFlags nFlags ) +{ + if(mpOutputDevice) + { + SolarMutexGuard aVclGuard; + + if ( nFlags & InitOutDevFlags::FONT ) + { + mpOutputDevice->SetFont( maFont ); + mpOutputDevice->SetTextColor( maTextColor ); + mpOutputDevice->SetTextFillColor( maTextFillColor ); + } + + if ( nFlags & InitOutDevFlags::COLORS ) + { + mpOutputDevice->SetLineColor( maLineColor ); + mpOutputDevice->SetFillColor( maFillColor ); + } + + mpOutputDevice->SetRasterOp( meRasterOp ); + + if( mpClipRegion ) + mpOutputDevice->SetClipRegion( *mpClipRegion ); + else + mpOutputDevice->SetClipRegion(); + } +} + +uno::Reference< awt::XDevice > VCLXGraphics::getDevice() +{ + SolarMutexGuard aGuard; + + if( !mxDevice.is() && mpOutputDevice ) + { + VCLXDevice* pDev = new VCLXDevice; + pDev->SetOutputDevice( mpOutputDevice ); + mxDevice = pDev; + } + return mxDevice; +} + +awt::SimpleFontMetric VCLXGraphics::getFontMetric() +{ + SolarMutexGuard aGuard; + + awt::SimpleFontMetric aM; + if( mpOutputDevice ) + { + mpOutputDevice->SetFont( maFont ); + aM = VCLUnoHelper::CreateFontMetric( mpOutputDevice->GetFontMetric() ); + } + return aM; +} + +void VCLXGraphics::setFont( const uno::Reference< awt::XFont >& rxFont ) +{ + SolarMutexGuard aGuard; + + maFont = VCLUnoHelper::CreateFont( rxFont ); +} + +void VCLXGraphics::selectFont( const awt::FontDescriptor& rDescription ) +{ + SolarMutexGuard aGuard; + + maFont = VCLUnoHelper::CreateFont( rDescription, vcl::Font() ); +} + +void VCLXGraphics::setTextColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maTextColor = Color( nColor ); +} + +void VCLXGraphics::setTextFillColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maTextFillColor = Color( nColor ); +} + +void VCLXGraphics::setLineColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maLineColor = Color( nColor ); +} + +void VCLXGraphics::setFillColor( sal_Int32 nColor ) +{ + SolarMutexGuard aGuard; + + maFillColor = Color( nColor ); +} + +void VCLXGraphics::setRasterOp( awt::RasterOperation eROP ) +{ + SolarMutexGuard aGuard; + + meRasterOp = static_cast<RasterOp>(eROP); +} + +void VCLXGraphics::setClipRegion( const uno::Reference< awt::XRegion >& rxRegion ) +{ + SolarMutexGuard aGuard; + + if ( rxRegion.is() ) + mpClipRegion.reset( new vcl::Region( VCLUnoHelper::GetRegion( rxRegion ) ) ); + else + mpClipRegion.reset(); +} + +void VCLXGraphics::intersectClipRegion( const uno::Reference< awt::XRegion >& rxRegion ) +{ + SolarMutexGuard aGuard; + + if ( rxRegion.is() ) + { + vcl::Region aRegion( VCLUnoHelper::GetRegion( rxRegion ) ); + if ( !mpClipRegion ) + mpClipRegion.reset( new vcl::Region( aRegion ) ); + else + mpClipRegion->Intersect( aRegion ); + } +} + +void VCLXGraphics::push( ) +{ + SolarMutexGuard aGuard; + + + if( mpOutputDevice ) + mpOutputDevice->Push(); +} + +void VCLXGraphics::pop( ) +{ + SolarMutexGuard aGuard; + + + if( mpOutputDevice ) + mpOutputDevice->Pop(); +} + +void VCLXGraphics::clear( + const awt::Rectangle& aRect ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + const ::tools::Rectangle aVCLRect = VCLUnoHelper::ConvertToVCLRect( aRect ); + mpOutputDevice->Erase( aVCLRect ); + } +} + +void VCLXGraphics::copy( const uno::Reference< awt::XDevice >& rxSource, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) +{ + SolarMutexGuard aGuard; + + if ( mpOutputDevice ) + { + VCLXDevice* pFromDev = comphelper::getUnoTunnelImplementation<VCLXDevice>( rxSource ); + DBG_ASSERT( pFromDev, "VCLXGraphics::copy - invalid device" ); + if ( pFromDev ) + { + InitOutputDevice( InitOutDevFlags::NONE ); + mpOutputDevice->DrawOutDev( Point( nDestX, nDestY ), Size( nDestWidth, nDestHeight ), + Point( nSourceX, nSourceY ), Size( nSourceWidth, nSourceHeight ), *pFromDev->GetOutputDevice() ); + } + } +} + +void VCLXGraphics::draw( const uno::Reference< awt::XDisplayBitmap >& rxBitmapHandle, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::NONE); + uno::Reference< awt::XBitmap > xBitmap( rxBitmapHandle, uno::UNO_QUERY ); + BitmapEx aBmpEx = VCLUnoHelper::GetBitmap( xBitmap ); + + Point aPos(nDestX - nSourceX, nDestY - nSourceY); + Size aSz = aBmpEx.GetSizePixel(); + + if(nDestWidth != nSourceWidth) + { + float zoomX = static_cast<float>(nDestWidth) / static_cast<float>(nSourceWidth); + aSz.setWidth( static_cast<long>(static_cast<float>(aSz.Width()) * zoomX) ); + } + + if(nDestHeight != nSourceHeight) + { + float zoomY = static_cast<float>(nDestHeight) / static_cast<float>(nSourceHeight); + aSz.setHeight( static_cast<long>(static_cast<float>(aSz.Height()) * zoomY) ); + } + + if(nSourceX || nSourceY || aSz.Width() != nSourceWidth || aSz.Height() != nSourceHeight) + mpOutputDevice->IntersectClipRegion(vcl::Region(tools::Rectangle(nDestX, nDestY, nDestX + nDestWidth - 1, nDestY + nDestHeight - 1))); + + mpOutputDevice->DrawBitmapEx( aPos, aSz, aBmpEx ); + } +} + +void VCLXGraphics::drawPixel( sal_Int32 x, sal_Int32 y ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPixel( Point( x, y ) ); + } +} + +void VCLXGraphics::drawLine( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawLine( Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ) ); + } +} + +void VCLXGraphics::drawRoundedRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 nHorzRound, sal_Int32 nVertRound ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawRect( tools::Rectangle( Point( x, y ), Size( width, height ) ), nHorzRound, nVertRound ); + } +} + +void VCLXGraphics::drawPolyLine( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); + } +} + +void VCLXGraphics::drawPolygon( const uno::Sequence< sal_Int32 >& DataX, const uno::Sequence< sal_Int32 >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); + } +} + +void VCLXGraphics::drawPolyPolygon( const uno::Sequence< uno::Sequence< sal_Int32 > >& DataX, const uno::Sequence< uno::Sequence< sal_Int32 > >& DataY ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + sal_uInt16 nPolys = static_cast<sal_uInt16>(DataX.getLength()); + tools::PolyPolygon aPolyPoly( nPolys ); + for ( sal_uInt16 n = 0; n < nPolys; n++ ) + aPolyPoly[n] = VCLUnoHelper::CreatePolygon( DataX.getConstArray()[n], DataY.getConstArray()[n] ); + + mpOutputDevice->DrawPolyPolygon( aPolyPoly ); + } +} + +void VCLXGraphics::drawEllipse( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawEllipse( tools::Rectangle( Point( x, y ), Size( width, height ) ) ); + } +} + +void VCLXGraphics::drawArc( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawArc( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawPie( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawPie( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawChord( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawChord( tools::Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); + } +} + +void VCLXGraphics::drawGradient( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, const awt::Gradient& rGradient ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + Gradient aGradient(static_cast<GradientStyle>(rGradient.Style), Color(rGradient.StartColor), Color(rGradient.EndColor)); + aGradient.SetAngle(rGradient.Angle); + aGradient.SetBorder(rGradient.Border); + aGradient.SetOfsX(rGradient.XOffset); + aGradient.SetOfsY(rGradient.YOffset); + aGradient.SetStartIntensity(rGradient.StartIntensity); + aGradient.SetEndIntensity(rGradient.EndIntensity); + aGradient.SetSteps(rGradient.StepCount); + mpOutputDevice->DrawGradient( tools::Rectangle( Point( x, y ), Size( width, height ) ), aGradient ); + } +} + +void VCLXGraphics::drawText( sal_Int32 x, sal_Int32 y, const OUString& rText ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS |InitOutDevFlags::FONT); + mpOutputDevice->DrawText( Point( x, y ), rText ); + } +} + +void VCLXGraphics::drawTextArray( sal_Int32 x, sal_Int32 y, const OUString& rText, const uno::Sequence< sal_Int32 >& rLongs ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice ) + { + InitOutputDevice( InitOutDevFlags::COLORS|InitOutDevFlags::FONT ); + std::unique_ptr<long []> pDXA(new long[rText.getLength()]); + for(int i = 0; i < rText.getLength(); i++) + { + pDXA[i] = rLongs[i]; + } + mpOutputDevice->DrawTextArray( Point( x, y ), rText, pDXA.get() ); + } +} + + +void VCLXGraphics::drawImage( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int16 nStyle, const uno::Reference< graphic::XGraphic >& xGraphic ) +{ + SolarMutexGuard aGuard; + + if( mpOutputDevice && xGraphic.is() ) + { + Image aImage( xGraphic ); + if ( !!aImage ) + { + InitOutputDevice( InitOutDevFlags::COLORS ); + mpOutputDevice->DrawImage( Point( x, y ), Size( width, height ), aImage, static_cast<DrawImageFlags>(nStyle) ); + } + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |