office-gobmx/canvas/source/vcl/spritehelper.cxx
Rafał Dobrakowski c8b8a2c2cb tdf#141908 - CppUnittests: replace usage of sal_Int32 with colors
Conversion of hex/dec colour notation
(example entry Color( 255, 255, 255), Color(0xFFFFFF) - COL_WHITE)
For the other available colour definitions.

Change-Id: I9eed0cd64adcbc8d25e1c22143a000906a457586
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163729
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
2024-03-14 02:33:03 +01:00

233 lines
8.6 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 <sal/config.h>
#include <sal/log.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/utils/canvastools.hxx>
#include <rtl/math.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <vcl/alpha.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/outdev.hxx>
#include <canvas/canvastools.hxx>
#include "spritehelper.hxx"
using namespace ::com::sun::star;
namespace vclcanvas
{
SpriteHelper::SpriteHelper() :
mbShowSpriteBounds(false)
{
}
void SpriteHelper::init( const geometry::RealSize2D& rSpriteSize,
const ::canvas::SpriteSurface::Reference& rOwningSpriteCanvas,
const BackBufferSharedPtr& rBackBuffer,
const BackBufferSharedPtr& rBackBufferMask,
bool bShowSpriteBounds )
{
ENSURE_OR_THROW( rOwningSpriteCanvas && rBackBuffer && rBackBufferMask,
"SpriteHelper::init(): Invalid sprite canvas or back buffer" );
mpBackBuffer = rBackBuffer;
mpBackBufferMask = rBackBufferMask;
mbShowSpriteBounds = bShowSpriteBounds;
init( rSpriteSize, rOwningSpriteCanvas );
}
void SpriteHelper::disposing()
{
mpBackBuffer.reset();
mpBackBufferMask.reset();
// forward to parent
CanvasCustomSpriteHelper::disposing();
}
void SpriteHelper::redraw( OutputDevice& rTargetSurface,
const ::basegfx::B2DPoint& rPos,
bool& io_bSurfacesDirty,
bool /*bBufferedUpdate*/ ) const
{
if( !mpBackBuffer ||
!mpBackBufferMask )
{
return; // we're disposed
}
// log output pos in device pixel
SAL_INFO("canvas.vcl", "SpriteHelper::redraw(): output pos is (" <<
rPos.getX() << "," << rPos.getY() << ")");
const double fAlpha( getAlpha() );
if( !isActive() || ::basegfx::fTools::equalZero( fAlpha ) )
return;
const ::basegfx::B2DVector& rOrigOutputSize( getSizePixel() );
// might get changed below (e.g. adapted for
// transformations). IMPORTANT: both position and size are
// rounded to integer values. From now on, only those
// rounded values are used, to keep clip and content in
// sync.
::Size aOutputSize( vcl::unotools::sizeFromB2DSize( rOrigOutputSize ) );
::Point aOutPos( vcl::unotools::pointFromB2DPoint( rPos ) );
// TODO(F3): Support for alpha-VDev
// Do we have to update our bitmaps (necessary if virdev
// was painted to, or transformation changed)?
const bool bNeedBitmapUpdate( io_bSurfacesDirty ||
hasTransformChanged() ||
maContent->IsEmpty() );
// updating content of sprite cache - surface is no
// longer dirty in relation to our cache
io_bSurfacesDirty = false;
transformUpdated();
if( bNeedBitmapUpdate )
{
const Point aEmptyPoint;
BitmapEx aBmp( mpBackBuffer->getOutDev().GetBitmapEx( aEmptyPoint,
aOutputSize ) );
if( isContentFullyOpaque() )
{
// optimized case: content canvas is fully
// opaque. Note: since we retrieved aBmp directly
// from an OutDev, it's already a 'display bitmap'
// on windows.
maContent = aBmp;
}
else
{
// sprite content might contain alpha, create
// BmpEx, then.
BitmapEx aMask( mpBackBufferMask->getOutDev().GetBitmapEx( aEmptyPoint,
aOutputSize ) );
AlphaMask aAlpha( aMask.GetBitmap() );
aAlpha.Invert();
// Note: since we retrieved aBmp and aMask
// directly from an OutDev, it's already a
// 'display bitmap' on windows.
maContent = BitmapEx( aBmp.GetBitmap(), aAlpha );
}
}
::basegfx::B2DHomMatrix aTransform( getTransformation() );
rTargetSurface.Push( vcl::PushFlags::CLIPREGION );
// apply clip (if any)
if( getClip().is() )
{
::basegfx::B2DPolyPolygon aClipPoly(
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
getClip() ));
if( aClipPoly.count() )
{
// Move the clip to the final sprite output position.
::basegfx::B2DHomMatrix aClipTransform( aTransform );
aClipTransform.translate( aOutPos.X(), aOutPos.Y() );
aClipPoly.transform( aClipTransform );
if( mbShowSpriteBounds )
{
// Paint green sprite clip area
rTargetSurface.SetLineColor( COL_LIGHTGREEN );
rTargetSurface.SetFillColor();
rTargetSurface.DrawPolyPolygon(::tools::PolyPolygon(aClipPoly)); // #i76339#
}
vcl::Region aClipRegion( aClipPoly );
rTargetSurface.SetClipRegion( aClipRegion );
}
}
::basegfx::B2DHomMatrix aSizeTransform, aMoveTransform;
aSizeTransform.scale( aOutputSize.Width(), aOutputSize.Height() );
aMoveTransform.translate( aOutPos.X(), aOutPos.Y() );
aTransform = aMoveTransform * aTransform * aSizeTransform;
rTargetSurface.DrawTransformedBitmapEx( aTransform, *maContent, fAlpha );
rTargetSurface.Pop();
if( !mbShowSpriteBounds )
return;
::tools::PolyPolygon aMarkerPoly(
::canvas::tools::getBoundMarksPolyPolygon(
::basegfx::B2DRectangle(aOutPos.X(),
aOutPos.Y(),
aOutPos.X() + aOutputSize.Width()-1,
aOutPos.Y() + aOutputSize.Height()-1) ) );
// Paint little red sprite area markers
rTargetSurface.SetLineColor( COL_RED );
rTargetSurface.SetFillColor();
for( int i=0; i<aMarkerPoly.Count(); ++i )
{
rTargetSurface.DrawPolyLine( aMarkerPoly.GetObject(static_cast<sal_uInt16>(i)) );
}
// paint sprite prio
vcl::Font aVCLFont;
aVCLFont.SetFontHeight( std::min(::tools::Long(20),aOutputSize.Height()) );
aVCLFont.SetColor( COL_RED );
rTargetSurface.SetTextAlign(ALIGN_TOP);
rTargetSurface.SetTextColor( COL_RED );
rTargetSurface.SetFont( aVCLFont );
OUString text( ::rtl::math::doubleToUString( getPriority(),
rtl_math_StringFormat_F,
2,'.',nullptr,' ') );
rTargetSurface.DrawText( aOutPos+Point(2,2), text );
SAL_INFO( "canvas.vcl",
"sprite " << this << " has prio " << getPriority());
}
::basegfx::B2DPolyPolygon SpriteHelper::polyPolygonFromXPolyPolygon2D( uno::Reference< rendering::XPolyPolygon2D >& xPoly ) const
{
return ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( xPoly );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */