loplugin:flatten in canvas

Change-Id: If14af63ab4f8fc7b9807319a2100f371ee103465
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92481
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2020-04-18 14:13:49 +02:00
parent cd0ab2cf50
commit 7fa4f64098
14 changed files with 674 additions and 674 deletions

View File

@@ -59,30 +59,30 @@ namespace cairocanvas
maFont->SetLanguage( LanguageTag::convertToLanguageType( rFontRequest.Locale, false));
// adjust to stretched/shrunk font
if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) )
{
VclPtr<OutputDevice> pOutDev( mpRefDevice->getOutputDevice() );
if( ::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) )
return;
if( pOutDev )
{
const bool bOldMapState( pOutDev->IsMapModeEnabled() );
pOutDev->EnableMapMode(false);
VclPtr<OutputDevice> pOutDev( mpRefDevice->getOutputDevice() );
const Size aSize = pOutDev->GetFontMetric( *maFont ).GetFontSize();
if( !pOutDev )
return;
const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 );
double fStretch = rFontMatrix.m00 + rFontMatrix.m01;
const bool bOldMapState( pOutDev->IsMapModeEnabled() );
pOutDev->EnableMapMode(false);
if( !::basegfx::fTools::equalZero( fDividend) )
fStretch /= fDividend;
const Size aSize = pOutDev->GetFontMetric( *maFont ).GetFontSize();
const long nNewWidth = ::basegfx::fround( aSize.Width() * fStretch );
const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 );
double fStretch = rFontMatrix.m00 + rFontMatrix.m01;
maFont->SetAverageFontWidth( nNewWidth );
if( !::basegfx::fTools::equalZero( fDividend) )
fStretch /= fDividend;
pOutDev->EnableMapMode(bOldMapState);
}
}
const long nNewWidth = ::basegfx::fround( aSize.Width() * fStretch );
maFont->SetAverageFontWidth( nNewWidth );
pOutDev->EnableMapMode(bOldMapState);
}
void SAL_CALL CanvasFont::disposing()

View File

@@ -216,25 +216,25 @@ namespace cairocanvas
{
SAL_INFO( "canvas.cairo", "clear whole area: " << maSize.getX() << " x " << maSize.getY() );
if( mpCairo )
{
cairo_save( mpCairo.get() );
if( !mpCairo )
return;
cairo_identity_matrix( mpCairo.get() );
// this does not really differ from all-zero, as cairo
// internally converts to premultiplied alpha. but anyway,
// this keeps it consistent with the other canvas impls
if( mbHaveAlpha )
cairo_set_source_rgba( mpCairo.get(), 1.0, 1.0, 1.0, 0.0 );
else
cairo_set_source_rgb( mpCairo.get(), 1.0, 1.0, 1.0 );
cairo_set_operator( mpCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_save( mpCairo.get() );
cairo_rectangle( mpCairo.get(), 0, 0, maSize.getX(), maSize.getY() );
cairo_fill( mpCairo.get() );
cairo_identity_matrix( mpCairo.get() );
// this does not really differ from all-zero, as cairo
// internally converts to premultiplied alpha. but anyway,
// this keeps it consistent with the other canvas impls
if( mbHaveAlpha )
cairo_set_source_rgba( mpCairo.get(), 1.0, 1.0, 1.0, 0.0 );
else
cairo_set_source_rgb( mpCairo.get(), 1.0, 1.0, 1.0 );
cairo_set_operator( mpCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_restore( mpCairo.get() );
}
cairo_rectangle( mpCairo.get(), 0, 0, maSize.getX(), maSize.getY() );
cairo_fill( mpCairo.get() );
cairo_restore( mpCairo.get() );
}
void CanvasHelper::drawLine( const rendering::XCanvas* /*pCanvas*/,
@@ -243,20 +243,20 @@ namespace cairocanvas
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
{
if( mpCairo )
{
cairo_save( mpCairo.get() );
if( !mpCairo )
return;
cairo_set_line_width( mpCairo.get(), 1 );
cairo_save( mpCairo.get() );
useStates( viewState, renderState, true );
cairo_set_line_width( mpCairo.get(), 1 );
cairo_move_to( mpCairo.get(), aStartPoint.X + 0.5, aStartPoint.Y + 0.5 );
cairo_line_to( mpCairo.get(), aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
cairo_stroke( mpCairo.get() );
useStates( viewState, renderState, true );
cairo_restore( mpCairo.get() );
}
cairo_move_to( mpCairo.get(), aStartPoint.X + 0.5, aStartPoint.Y + 0.5 );
cairo_line_to( mpCairo.get(), aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
cairo_stroke( mpCairo.get() );
cairo_restore( mpCairo.get() );
}
void CanvasHelper::drawBezier( const rendering::XCanvas* ,
@@ -265,25 +265,25 @@ namespace cairocanvas
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
{
if( mpCairo )
{
cairo_save( mpCairo.get() );
if( !mpCairo )
return;
cairo_set_line_width( mpCairo.get(), 1 );
cairo_save( mpCairo.get() );
useStates( viewState, renderState, true );
cairo_set_line_width( mpCairo.get(), 1 );
cairo_move_to( mpCairo.get(), aBezierSegment.Px + 0.5, aBezierSegment.Py + 0.5 );
// tdf#99165 correction of control points not needed here, only hairlines drawn
// (see cairo_set_line_width above)
cairo_curve_to( mpCairo.get(),
aBezierSegment.C1x + 0.5, aBezierSegment.C1y + 0.5,
aBezierSegment.C2x + 0.5, aBezierSegment.C2y + 0.5,
aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
cairo_stroke( mpCairo.get() );
useStates( viewState, renderState, true );
cairo_restore( mpCairo.get() );
}
cairo_move_to( mpCairo.get(), aBezierSegment.Px + 0.5, aBezierSegment.Py + 0.5 );
// tdf#99165 correction of control points not needed here, only hairlines drawn
// (see cairo_set_line_width above)
cairo_curve_to( mpCairo.get(),
aBezierSegment.C1x + 0.5, aBezierSegment.C1y + 0.5,
aBezierSegment.C2x + 0.5, aBezierSegment.C2y + 0.5,
aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
cairo_stroke( mpCairo.get() );
cairo_restore( mpCairo.get() );
}
#define PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME "Canvas::ParametricPolyPolygon"

View File

@@ -232,21 +232,21 @@ namespace cairocanvas
{
static sal_Int32 nFilePostfixCount(0);
if( mpRefDevice )
{
OUString aFilename = "dbg_frontbuffer" + OUString::number(nFilePostfixCount) + ".bmp";
if( !mpRefDevice )
return;
SvFileStream aStream( aFilename, StreamMode::STD_READWRITE );
OUString aFilename = "dbg_frontbuffer" + OUString::number(nFilePostfixCount) + ".bmp";
const ::Point aEmptyPoint;
bool bOldMap( mpRefDevice->IsMapModeEnabled() );
mpRefDevice->EnableMapMode( false );
const ::BitmapEx aTempBitmap(mpRefDevice->GetBitmapEx(aEmptyPoint, mpRefDevice->GetOutputSizePixel()));
WriteDIB(aTempBitmap, aStream, false);
mpRefDevice->EnableMapMode( bOldMap );
SvFileStream aStream( aFilename, StreamMode::STD_READWRITE );
++nFilePostfixCount;
}
const ::Point aEmptyPoint;
bool bOldMap( mpRefDevice->IsMapModeEnabled() );
mpRefDevice->EnableMapMode( false );
const ::BitmapEx aTempBitmap(mpRefDevice->GetBitmapEx(aEmptyPoint, mpRefDevice->GetOutputSizePixel()));
WriteDIB(aTempBitmap, aStream, false);
mpRefDevice->EnableMapMode( bOldMap );
++nFilePostfixCount;
}
SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, int aContent )

View File

@@ -83,75 +83,75 @@ namespace cairocanvas
const double fAlpha( getAlpha() );
const ::basegfx::B2DHomMatrix aTransform( getTransformation() );
if( isActive() && !::basegfx::fTools::equalZero( fAlpha ) )
if( !(isActive() && !::basegfx::fTools::equalZero( fAlpha )) )
return;
SAL_INFO( "canvas.cairo", "CanvasCustomSprite::redraw called");
if( !pCairo )
return;
basegfx::B2DVector aSize = getSizePixel();
cairo_save( pCairo.get() );
double fX, fY;
fX = rPos.getX();
fY = rPos.getY();
if( !aTransform.isIdentity() )
{
SAL_INFO( "canvas.cairo", "CanvasCustomSprite::redraw called");
if( pCairo )
{
basegfx::B2DVector aSize = getSizePixel();
cairo_save( pCairo.get() );
cairo_matrix_t aMatrix, aInverseMatrix;
cairo_matrix_init( &aMatrix,
aTransform.get( 0, 0 ), aTransform.get( 1, 0 ), aTransform.get( 0, 1 ),
aTransform.get( 1, 1 ), aTransform.get( 0, 2 ), aTransform.get( 1, 2 ) );
double fX, fY;
aMatrix.x0 = basegfx::fround( aMatrix.x0 );
aMatrix.y0 = basegfx::fround( aMatrix.y0 );
fX = rPos.getX();
fY = rPos.getY();
cairo_matrix_init( &aInverseMatrix, aMatrix.xx, aMatrix.yx, aMatrix.xy, aMatrix.yy, aMatrix.x0, aMatrix.y0 );
cairo_matrix_invert( &aInverseMatrix );
cairo_matrix_transform_distance( &aInverseMatrix, &fX, &fY );
if( !aTransform.isIdentity() )
{
cairo_matrix_t aMatrix, aInverseMatrix;
cairo_matrix_init( &aMatrix,
aTransform.get( 0, 0 ), aTransform.get( 1, 0 ), aTransform.get( 0, 1 ),
aTransform.get( 1, 1 ), aTransform.get( 0, 2 ), aTransform.get( 1, 2 ) );
aMatrix.x0 = basegfx::fround( aMatrix.x0 );
aMatrix.y0 = basegfx::fround( aMatrix.y0 );
cairo_matrix_init( &aInverseMatrix, aMatrix.xx, aMatrix.yx, aMatrix.xy, aMatrix.yy, aMatrix.x0, aMatrix.y0 );
cairo_matrix_invert( &aInverseMatrix );
cairo_matrix_transform_distance( &aInverseMatrix, &fX, &fY );
cairo_set_matrix( pCairo.get(), &aMatrix );
}
fX = basegfx::fround( fX );
fY = basegfx::fround( fY );
cairo_matrix_t aOrigMatrix;
cairo_get_matrix( pCairo.get(), &aOrigMatrix );
cairo_translate( pCairo.get(), fX, fY );
if( getClip().is() )
{
const uno::Reference<rendering::XPolyPolygon2D>& rClip( getClip() );
::basegfx::B2DPolyPolygon aClipPoly(
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
rClip ));
doPolyPolygonImplementation( aClipPoly, Clip, pCairo.get(),
nullptr, SurfaceProviderRef(mpSpriteCanvas.get()),
rClip->getFillRule() );
}
SAL_INFO( "canvas.cairo","aSize " << aSize.getX() << " x " << aSize.getY() << " position: " << fX << "," << fY );
cairo_rectangle( pCairo.get(), 0, 0, floor( aSize.getX() ), floor( aSize.getY() ) );
cairo_clip( pCairo.get() );
cairo_set_matrix( pCairo.get(), &aOrigMatrix );
if( isContentFullyOpaque() )
cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_set_source_surface( pCairo.get(),
mpBufferSurface->getCairoSurface().get(),
fX, fY );
if( ::rtl::math::approxEqual( fAlpha, 1.0 ) )
cairo_paint( pCairo.get() );
else
cairo_paint_with_alpha( pCairo.get(), fAlpha );
cairo_restore( pCairo.get() );
}
cairo_set_matrix( pCairo.get(), &aMatrix );
}
fX = basegfx::fround( fX );
fY = basegfx::fround( fY );
cairo_matrix_t aOrigMatrix;
cairo_get_matrix( pCairo.get(), &aOrigMatrix );
cairo_translate( pCairo.get(), fX, fY );
if( getClip().is() )
{
const uno::Reference<rendering::XPolyPolygon2D>& rClip( getClip() );
::basegfx::B2DPolyPolygon aClipPoly(
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
rClip ));
doPolyPolygonImplementation( aClipPoly, Clip, pCairo.get(),
nullptr, SurfaceProviderRef(mpSpriteCanvas.get()),
rClip->getFillRule() );
}
SAL_INFO( "canvas.cairo","aSize " << aSize.getX() << " x " << aSize.getY() << " position: " << fX << "," << fY );
cairo_rectangle( pCairo.get(), 0, 0, floor( aSize.getX() ), floor( aSize.getY() ) );
cairo_clip( pCairo.get() );
cairo_set_matrix( pCairo.get(), &aOrigMatrix );
if( isContentFullyOpaque() )
cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_set_source_surface( pCairo.get(),
mpBufferSurface->getCairoSurface().get(),
fX, fY );
if( ::rtl::math::approxEqual( fAlpha, 1.0 ) )
cairo_paint( pCairo.get() );
else
cairo_paint_with_alpha( pCairo.get(), fAlpha );
cairo_restore( pCairo.get() );
#ifdef CAIRO_CANVAS_PERF_TRACE
mxDevice->stopPerfTrace( &aTimer, "sprite redraw" );
#endif

View File

@@ -400,21 +400,21 @@ namespace oglcanvas
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
{
if( mpDevice )
{
mpRecordedActions->push_back( Action() );
Action& rAct=mpRecordedActions->back();
if( !mpDevice )
return;
setupGraphicsState( rAct, viewState, renderState );
mpRecordedActions->push_back( Action() );
Action& rAct=mpRecordedActions->back();
// TODO(F2): subdivide&render whole curve
rAct.maFunction = std::bind(&lcl_drawLine,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5,
geometry::RealPoint2D(
aBezierSegment.Px,
aBezierSegment.Py),
aEndPoint);
}
setupGraphicsState( rAct, viewState, renderState );
// TODO(F2): subdivide&render whole curve
rAct.maFunction = std::bind(&lcl_drawLine,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5,
geometry::RealPoint2D(
aBezierSegment.Px,
aBezierSegment.Py),
aEndPoint);
}
uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawPolyPolygon( const rendering::XCanvas* /*pCanvas*/,

View File

@@ -194,29 +194,29 @@ namespace canvas
{
// check whether bitmap is non-alpha, and whether its
// transformed size covers the whole sprite.
if( !xBitmap->hasAlpha() )
{
const geometry::IntegerSize2D& rInputSize(
xBitmap->getSize() );
const ::basegfx::B2DSize& rOurSize(
rSprite->getSizePixel() );
if( xBitmap->hasAlpha() )
return;
::basegfx::B2DHomMatrix aTransform;
if( tools::isInside(
::basegfx::B2DRectangle( 0.0,0.0,
rOurSize.getX(),
rOurSize.getY() ),
::basegfx::B2DRectangle( 0.0,0.0,
rInputSize.Width,
rInputSize.Height ),
::canvas::tools::mergeViewAndRenderTransform(aTransform,
viewState,
renderState) ) )
{
// bitmap is opaque and will fully cover the sprite,
// set flag appropriately
mbIsContentFullyOpaque = true;
}
const geometry::IntegerSize2D& rInputSize(
xBitmap->getSize() );
const ::basegfx::B2DSize& rOurSize(
rSprite->getSizePixel() );
::basegfx::B2DHomMatrix aTransform;
if( tools::isInside(
::basegfx::B2DRectangle( 0.0,0.0,
rOurSize.getX(),
rOurSize.getY() ),
::basegfx::B2DRectangle( 0.0,0.0,
rInputSize.Width,
rInputSize.Height ),
::canvas::tools::mergeViewAndRenderTransform(aTransform,
viewState,
renderState) ) )
{
// bitmap is opaque and will fully cover the sprite,
// set flag appropriately
mbIsContentFullyOpaque = true;
}
}
@@ -257,23 +257,23 @@ namespace canvas
::basegfx::unotools::b2DPointFromRealPoint2D(aNewPos) );
aPoint *= aTransform;
if( aPoint != maPosition )
if( aPoint == maPosition )
return;
const ::basegfx::B2DRectangle& rBounds
= getUpdateArea( ::basegfx::B2DRectangle( 0.0, 0.0,
maSize.getX(),
maSize.getY() ) );
if( mbActive )
{
const ::basegfx::B2DRectangle& rBounds
= getUpdateArea( ::basegfx::B2DRectangle( 0.0, 0.0,
maSize.getX(),
maSize.getY() ) );
if( mbActive )
{
mpSpriteCanvas->moveSprite( rSprite,
rBounds.getMinimum(),
rBounds.getMinimum() - maPosition + aPoint,
rBounds.getRange() );
}
maPosition = aPoint;
mpSpriteCanvas->moveSprite( rSprite,
rBounds.getMinimum(),
rBounds.getMinimum() - maPosition + aPoint,
rBounds.getRange() );
}
maPosition = aPoint;
}
void CanvasCustomSpriteHelper::transform( const Sprite::Reference& rSprite,
@@ -283,26 +283,26 @@ namespace canvas
::basegfx::unotools::homMatrixFromAffineMatrix(aMatrix,
aTransformation);
if( maTransform != aMatrix )
if( maTransform == aMatrix )
return;
// retrieve bounds before and after transformation change.
const ::basegfx::B2DRectangle& rPrevBounds( getUpdateArea() );
maTransform = aMatrix;
if( !updateClipState( rSprite ) &&
mbActive )
{
// retrieve bounds before and after transformation change.
const ::basegfx::B2DRectangle& rPrevBounds( getUpdateArea() );
maTransform = aMatrix;
if( !updateClipState( rSprite ) &&
mbActive )
{
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
rPrevBounds );
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
mbTransformDirty = true;
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
rPrevBounds );
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
mbTransformDirty = true;
}
void CanvasCustomSpriteHelper::clip( const Sprite::Reference& rSprite,
@@ -351,20 +351,20 @@ namespace canvas
if( !mpSpriteCanvas.get() )
return; // we're disposed
if( !mbActive )
if( mbActive )
return;
mpSpriteCanvas->showSprite( rSprite );
mbActive = true;
// TODO(P1): if clip is the NULL clip (nothing visible),
// also save us the update call.
if( mfAlpha != 0.0 )
{
mpSpriteCanvas->showSprite( rSprite );
mbActive = true;
// TODO(P1): if clip is the NULL clip (nothing visible),
// also save us the update call.
if( mfAlpha != 0.0 )
{
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
}
@@ -373,20 +373,20 @@ namespace canvas
if( !mpSpriteCanvas.get() )
return; // we're disposed
if( mbActive )
if( !mbActive )
return;
mpSpriteCanvas->hideSprite( rSprite );
mbActive = false;
// TODO(P1): if clip is the NULL clip (nothing visible),
// also save us the update call.
if( mfAlpha != 0.0 )
{
mpSpriteCanvas->hideSprite( rSprite );
mbActive = false;
// TODO(P1): if clip is the NULL clip (nothing visible),
// also save us the update call.
if( mfAlpha != 0.0 )
{
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
mpSpriteCanvas->updateSprite( rSprite,
maPosition,
getUpdateArea() );
}
}

View File

@@ -56,41 +56,41 @@ namespace canvas
{
// only deal with change events from the currently
// affected sprite
if( rSpriteRecord.mpAffectedSprite == mpAffectedSprite )
if( rSpriteRecord.mpAffectedSprite != mpAffectedSprite )
return;
switch( rSpriteRecord.meChangeType )
{
switch( rSpriteRecord.meChangeType )
{
case SpriteRedrawManager::SpriteChangeRecord::ChangeType::move:
if( !mbIsMove )
{
// no move yet - this must be the first one
maMoveStartArea = ::basegfx::B2DRectangle(
rSpriteRecord.maOldPos,
rSpriteRecord.maOldPos + rSpriteRecord.maUpdateArea.getRange() );
mbIsMove = true;
}
case SpriteRedrawManager::SpriteChangeRecord::ChangeType::move:
if( !mbIsMove )
{
// no move yet - this must be the first one
maMoveStartArea = ::basegfx::B2DRectangle(
rSpriteRecord.maOldPos,
rSpriteRecord.maOldPos + rSpriteRecord.maUpdateArea.getRange() );
mbIsMove = true;
}
maMoveEndArea = rSpriteRecord.maUpdateArea;
break;
maMoveEndArea = rSpriteRecord.maUpdateArea;
break;
case SpriteRedrawManager::SpriteChangeRecord::ChangeType::update:
// update end update area of the
// sprite. Thus, every update() action
// _after_ the last move will correctly
// update the final repaint area. And this
// does not interfere with subsequent
// moves, because moves always perform a
// hard set of maMoveEndArea to their
// stored value
maMoveEndArea.expand( rSpriteRecord.maUpdateArea );
mbIsGenericUpdate = true;
break;
case SpriteRedrawManager::SpriteChangeRecord::ChangeType::update:
// update end update area of the
// sprite. Thus, every update() action
// _after_ the last move will correctly
// update the final repaint area. And this
// does not interfere with subsequent
// moves, because moves always perform a
// hard set of maMoveEndArea to their
// stored value
maMoveEndArea.expand( rSpriteRecord.maUpdateArea );
mbIsGenericUpdate = true;
break;
default:
ENSURE_OR_THROW( false,
"Unexpected case in SpriteUpdater::operator()" );
break;
}
default:
ENSURE_OR_THROW( false,
"Unexpected case in SpriteUpdater::operator()" );
break;
}
}

View File

@@ -295,20 +295,20 @@ namespace canvas::tools
#endif
}
if( renderState.CompositeOperation < rendering::CompositeOperation::CLEAR ||
renderState.CompositeOperation > rendering::CompositeOperation::SATURATE )
{
if( !(renderState.CompositeOperation < rendering::CompositeOperation::CLEAR ||
renderState.CompositeOperation > rendering::CompositeOperation::SATURATE) )
return;
#if OSL_DEBUG_LEVEL > 0
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): render state's CompositeOperation value out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(renderState.CompositeOperation)) +
" not known)",
xIf, nArgPos );
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): render state's CompositeOperation value out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(renderState.CompositeOperation)) +
" not known)",
xIf, nArgPos );
#else
throw lang::IllegalArgumentException();
throw lang::IllegalArgumentException();
#endif
}
}
void verifyInput( const rendering::Texture& texture,
@@ -361,20 +361,20 @@ namespace canvas::tools
#endif
}
if( texture.RepeatModeY < rendering::TexturingMode::NONE ||
texture.RepeatModeY > rendering::TexturingMode::REPEAT )
{
if( !(texture.RepeatModeY < rendering::TexturingMode::NONE ||
texture.RepeatModeY > rendering::TexturingMode::REPEAT) )
return;
#if OSL_DEBUG_LEVEL > 0
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): textures' RepeatModeY value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(texture.RepeatModeY)) +
" not known)",
xIf, nArgPos );
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): textures' RepeatModeY value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(texture.RepeatModeY)) +
" not known)",
xIf, nArgPos );
#else
throw lang::IllegalArgumentException();
throw lang::IllegalArgumentException();
#endif
}
}
namespace
@@ -483,20 +483,20 @@ namespace canvas::tools
#endif
}
if( strokeAttributes.JoinType < rendering::PathJoinType::NONE ||
strokeAttributes.JoinType > rendering::PathJoinType::BEVEL )
{
if( !(strokeAttributes.JoinType < rendering::PathJoinType::NONE ||
strokeAttributes.JoinType > rendering::PathJoinType::BEVEL) )
return;
#if OSL_DEBUG_LEVEL > 0
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): stroke attributes' JoinType value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(strokeAttributes.JoinType)) +
" not known)",
xIf, nArgPos );
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): stroke attributes' JoinType value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(strokeAttributes.JoinType)) +
" not known)",
xIf, nArgPos );
#else
throw lang::IllegalArgumentException();
throw lang::IllegalArgumentException();
#endif
}
}
void verifyInput( const rendering::IntegerBitmapLayout& bitmapLayout,
@@ -552,20 +552,20 @@ namespace canvas::tools
#endif
}
if( bitmapLayout.ColorSpace->getEndianness() < util::Endianness::LITTLE ||
bitmapLayout.ColorSpace->getEndianness() > util::Endianness::BIG )
{
if( !(bitmapLayout.ColorSpace->getEndianness() < util::Endianness::LITTLE ||
bitmapLayout.ColorSpace->getEndianness() > util::Endianness::BIG) )
return;
#if OSL_DEBUG_LEVEL > 0
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): bitmap layout's ColorSpace getEndianness() value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(bitmapLayout.ColorSpace->getEndianness())) +
" not known)",
xIf, nArgPos );
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyInput(): bitmap layout's ColorSpace getEndianness() value is out of range (" +
OUString::number(sal::static_int_cast<sal_Int32>(bitmapLayout.ColorSpace->getEndianness())) +
" not known)",
xIf, nArgPos );
#else
throw lang::IllegalArgumentException();
throw lang::IllegalArgumentException();
#endif
}
}
void verifyInput( const rendering::FontRequest& fontRequest,
@@ -660,19 +660,19 @@ namespace canvas::tools
#endif
}
if( size.Height <= 0 )
{
if( size.Height > 0 )
return;
#if OSL_DEBUG_LEVEL > 0
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyBitmapSize(): size has 0 or negative height (value: " +
OUString::number(size.Height) +
")",
xIf, 0 );
throw lang::IllegalArgumentException(
OUString::createFromAscii(pStr) +
": verifyBitmapSize(): size has 0 or negative height (value: " +
OUString::number(size.Height) +
")",
xIf, 0 );
#else
throw lang::IllegalArgumentException();
throw lang::IllegalArgumentException();
#endif
}
}
void verifySpriteSize( const geometry::RealSize2D& size,

View File

@@ -31,19 +31,19 @@ namespace vclcanvas
maVDev( VclPtr<VirtualDevice>::Create( rRefDevice,
bMonochromeBuffer ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT ) )
{
if( !bMonochromeBuffer )
{
// #i95645#
if( bMonochromeBuffer )
return;
// #i95645#
#if defined( MACOSX )
// use AA on VCLCanvas for Mac
maVDev->SetAntialiasing( AntialiasingFlags::EnableB2dDraw | maVDev->GetAntialiasing() );
// use AA on VCLCanvas for Mac
maVDev->SetAntialiasing( AntialiasingFlags::EnableB2dDraw | maVDev->GetAntialiasing() );
#else
// switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
// is not required to do AA. It would need to be adapted to use it correctly
// (especially gradient painting). This will need extra work.
maVDev->SetAntialiasing( maVDev->GetAntialiasing() & ~AntialiasingFlags::EnableB2dDraw);
// switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
// is not required to do AA. It would need to be adapted to use it correctly
// (especially gradient painting). This will need extra work.
maVDev->SetAntialiasing( maVDev->GetAntialiasing() & ~AntialiasingFlags::EnableB2dDraw);
#endif
}
}
BackBuffer::~BackBuffer()

View File

@@ -106,30 +106,30 @@ namespace vclcanvas
void BitmapBackBuffer::createVDev() const
{
if( !mpVDev )
{
// VDev not yet created, do it now. Create an alpha-VDev,
// if bitmap has transparency.
mpVDev = maBitmap->IsTransparent() ?
VclPtr<VirtualDevice>::Create( mrRefDevice, DeviceFormat::DEFAULT, DeviceFormat::DEFAULT ) :
VclPtr<VirtualDevice>::Create( mrRefDevice );
if( mpVDev )
return;
OSL_ENSURE( mpVDev,
"BitmapBackBuffer::createVDev(): Unable to create VirtualDevice" );
// VDev not yet created, do it now. Create an alpha-VDev,
// if bitmap has transparency.
mpVDev = maBitmap->IsTransparent() ?
VclPtr<VirtualDevice>::Create( mrRefDevice, DeviceFormat::DEFAULT, DeviceFormat::DEFAULT ) :
VclPtr<VirtualDevice>::Create( mrRefDevice );
mpVDev->SetOutputSizePixel( maBitmap->GetSizePixel() );
OSL_ENSURE( mpVDev,
"BitmapBackBuffer::createVDev(): Unable to create VirtualDevice" );
// #i95645#
mpVDev->SetOutputSizePixel( maBitmap->GetSizePixel() );
// #i95645#
#if defined( MACOSX )
// use AA on VCLCanvas for Mac
mpVDev->SetAntialiasing( AntialiasingFlags::EnableB2dDraw | mpVDev->GetAntialiasing() );
// use AA on VCLCanvas for Mac
mpVDev->SetAntialiasing( AntialiasingFlags::EnableB2dDraw | mpVDev->GetAntialiasing() );
#else
// switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
// is not required to do AA. It would need to be adapted to use it correctly
// (especially gradient painting). This will need extra work.
mpVDev->SetAntialiasing(mpVDev->GetAntialiasing() & ~AntialiasingFlags::EnableB2dDraw);
// switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
// is not required to do AA. It would need to be adapted to use it correctly
// (especially gradient painting). This will need extra work.
mpVDev->SetAntialiasing(mpVDev->GetAntialiasing() & ~AntialiasingFlags::EnableB2dDraw);
#endif
}
}
void BitmapBackBuffer::updateVDev() const

View File

@@ -154,35 +154,35 @@ namespace vclcanvas
void CanvasHelper::clear()
{
// are we disposed?
if( mpOutDevProvider )
{
OutputDevice& rOutDev( mpOutDevProvider->getOutDev() );
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
if( !mpOutDevProvider )
return;
rOutDev.EnableMapMode( false );
rOutDev.SetAntialiasing( AntialiasingFlags::EnableB2dDraw );
rOutDev.SetLineColor( COL_WHITE );
rOutDev.SetFillColor( COL_WHITE );
rOutDev.SetClipRegion();
rOutDev.DrawRect( ::tools::Rectangle( Point(),
rOutDev.GetOutputSizePixel()) );
OutputDevice& rOutDev( mpOutDevProvider->getOutDev() );
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
if( mp2ndOutDevProvider )
{
OutputDevice& rOutDev2( mp2ndOutDevProvider->getOutDev() );
rOutDev.EnableMapMode( false );
rOutDev.SetAntialiasing( AntialiasingFlags::EnableB2dDraw );
rOutDev.SetLineColor( COL_WHITE );
rOutDev.SetFillColor( COL_WHITE );
rOutDev.SetClipRegion();
rOutDev.DrawRect( ::tools::Rectangle( Point(),
rOutDev.GetOutputSizePixel()) );
rOutDev2.SetDrawMode( DrawModeFlags::Default );
rOutDev2.EnableMapMode( false );
rOutDev2.SetAntialiasing( AntialiasingFlags::EnableB2dDraw );
rOutDev2.SetLineColor( COL_WHITE );
rOutDev2.SetFillColor( COL_WHITE );
rOutDev2.SetClipRegion();
rOutDev2.DrawRect( ::tools::Rectangle( Point(),
rOutDev2.GetOutputSizePixel()) );
rOutDev2.SetDrawMode( DrawModeFlags::BlackLine | DrawModeFlags::BlackFill | DrawModeFlags::BlackText |
DrawModeFlags::BlackGradient | DrawModeFlags::BlackBitmap );
}
}
if( !mp2ndOutDevProvider )
return;
OutputDevice& rOutDev2( mp2ndOutDevProvider->getOutDev() );
rOutDev2.SetDrawMode( DrawModeFlags::Default );
rOutDev2.EnableMapMode( false );
rOutDev2.SetAntialiasing( AntialiasingFlags::EnableB2dDraw );
rOutDev2.SetLineColor( COL_WHITE );
rOutDev2.SetFillColor( COL_WHITE );
rOutDev2.SetClipRegion();
rOutDev2.DrawRect( ::tools::Rectangle( Point(),
rOutDev2.GetOutputSizePixel()) );
rOutDev2.SetDrawMode( DrawModeFlags::BlackLine | DrawModeFlags::BlackFill | DrawModeFlags::BlackText |
DrawModeFlags::BlackGradient | DrawModeFlags::BlackBitmap );
}
void CanvasHelper::drawLine( const rendering::XCanvas* ,
@@ -192,22 +192,22 @@ namespace vclcanvas
const rendering::RenderState& renderState )
{
// are we disposed?
if( mpOutDevProvider )
{
// nope, render
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
setupOutDevState( viewState, renderState, LINE_COLOR );
if( !mpOutDevProvider )
return;
const Point aStartPoint( tools::mapRealPoint2D( aStartRealPoint2D,
viewState, renderState ) );
const Point aEndPoint( tools::mapRealPoint2D( aEndRealPoint2D,
viewState, renderState ) );
// TODO(F2): alpha
mpOutDevProvider->getOutDev().DrawLine( aStartPoint, aEndPoint );
// nope, render
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
setupOutDevState( viewState, renderState, LINE_COLOR );
if( mp2ndOutDevProvider )
mp2ndOutDevProvider->getOutDev().DrawLine( aStartPoint, aEndPoint );
}
const Point aStartPoint( tools::mapRealPoint2D( aStartRealPoint2D,
viewState, renderState ) );
const Point aEndPoint( tools::mapRealPoint2D( aEndRealPoint2D,
viewState, renderState ) );
// TODO(F2): alpha
mpOutDevProvider->getOutDev().DrawLine( aStartPoint, aEndPoint );
if( mp2ndOutDevProvider )
mp2ndOutDevProvider->getOutDev().DrawLine( aStartPoint, aEndPoint );
}
void CanvasHelper::drawBezier( const rendering::XCanvas* ,
@@ -216,38 +216,38 @@ namespace vclcanvas
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
{
if( mpOutDevProvider )
{
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
setupOutDevState( viewState, renderState, LINE_COLOR );
if( !mpOutDevProvider )
return;
const Point& rStartPoint( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.Px,
aBezierSegment.Py),
viewState, renderState ) );
const Point& rCtrlPoint1( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C1x,
aBezierSegment.C1y),
viewState, renderState ) );
const Point& rCtrlPoint2( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C2x,
aBezierSegment.C2y),
viewState, renderState ) );
const Point& rEndPoint( tools::mapRealPoint2D( _aEndPoint,
viewState, renderState ) );
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider );
setupOutDevState( viewState, renderState, LINE_COLOR );
::tools::Polygon aPoly(4);
aPoly.SetPoint( rStartPoint, 0 );
aPoly.SetFlags( 0, PolyFlags::Normal );
aPoly.SetPoint( rCtrlPoint1, 1 );
aPoly.SetFlags( 1, PolyFlags::Control );
aPoly.SetPoint( rCtrlPoint2, 2 );
aPoly.SetFlags( 2, PolyFlags::Control );
aPoly.SetPoint( rEndPoint, 3 );
aPoly.SetFlags( 3, PolyFlags::Normal );
const Point& rStartPoint( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.Px,
aBezierSegment.Py),
viewState, renderState ) );
const Point& rCtrlPoint1( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C1x,
aBezierSegment.C1y),
viewState, renderState ) );
const Point& rCtrlPoint2( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C2x,
aBezierSegment.C2y),
viewState, renderState ) );
const Point& rEndPoint( tools::mapRealPoint2D( _aEndPoint,
viewState, renderState ) );
// TODO(F2): alpha
mpOutDevProvider->getOutDev().DrawPolygon( aPoly );
if( mp2ndOutDevProvider )
mp2ndOutDevProvider->getOutDev().DrawPolygon( aPoly );
}
::tools::Polygon aPoly(4);
aPoly.SetPoint( rStartPoint, 0 );
aPoly.SetFlags( 0, PolyFlags::Normal );
aPoly.SetPoint( rCtrlPoint1, 1 );
aPoly.SetFlags( 1, PolyFlags::Control );
aPoly.SetPoint( rCtrlPoint2, 2 );
aPoly.SetFlags( 2, PolyFlags::Control );
aPoly.SetPoint( rEndPoint, 3 );
aPoly.SetFlags( 3, PolyFlags::Normal );
// TODO(F2): alpha
mpOutDevProvider->getOutDev().DrawPolygon( aPoly );
if( mp2ndOutDevProvider )
mp2ndOutDevProvider->getOutDev().DrawPolygon( aPoly );
}
uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawPolyPolygon( const rendering::XCanvas* ,

View File

@@ -196,21 +196,21 @@ namespace vclcanvas
{
static sal_Int32 nFilePostfixCount(0);
if( mpOutDev )
{
OUString aFilename = "dbg_frontbuffer" + OUString::number(nFilePostfixCount) + ".bmp";
if( !mpOutDev )
return;
SvFileStream aStream( aFilename, StreamMode::STD_READWRITE );
OUString aFilename = "dbg_frontbuffer" + OUString::number(nFilePostfixCount) + ".bmp";
const ::Point aEmptyPoint;
OutputDevice& rOutDev = mpOutDev->getOutDev();
bool bOldMap( rOutDev.IsMapModeEnabled() );
rOutDev.EnableMapMode( false );
WriteDIB(rOutDev.GetBitmapEx(aEmptyPoint, rOutDev.GetOutputSizePixel()), aStream, false);
rOutDev.EnableMapMode( bOldMap );
SvFileStream aStream( aFilename, StreamMode::STD_READWRITE );
++nFilePostfixCount;
}
const ::Point aEmptyPoint;
OutputDevice& rOutDev = mpOutDev->getOutDev();
bool bOldMap( rOutDev.IsMapModeEnabled() );
rOutDev.EnableMapMode( false );
WriteDIB(rOutDev.GetBitmapEx(aEmptyPoint, rOutDev.GetOutputSizePixel()), aStream, false);
rOutDev.EnableMapMode( bOldMap );
++nFilePostfixCount;
}
}

View File

@@ -597,64 +597,64 @@ namespace vclcanvas
void SpriteCanvasHelper::renderSpriteCount( OutputDevice& rOutDev )
{
if( mpRedrawManager )
{
sal_Int32 nCount(0);
if( !mpRedrawManager )
return;
mpRedrawManager->forEachSprite( makeAdder(nCount,sal_Int32(1)) );
OUString text( OUString::number(nCount) );
sal_Int32 nCount(0);
// pad with leading space
while( text.getLength() < 3 )
text = " " + text;
mpRedrawManager->forEachSprite( makeAdder(nCount,sal_Int32(1)) );
OUString text( OUString::number(nCount) );
text = "Sprites: " + text;
// pad with leading space
while( text.getLength() < 3 )
text = " " + text;
renderInfoText( rOutDev,
text,
Point(0, 30) );
}
text = "Sprites: " + text;
renderInfoText( rOutDev,
text,
Point(0, 30) );
}
void SpriteCanvasHelper::renderMemUsage( OutputDevice& rOutDev )
{
BackBufferSharedPtr pBackBuffer( mpOwningSpriteCanvas->getBackBuffer() );
if( mpRedrawManager &&
pBackBuffer )
{
double nPixel(0.0);
if( !(mpRedrawManager &&
pBackBuffer) )
return;
// accumulate pixel count for each sprite into fCount
mpRedrawManager->forEachSprite(
[&nPixel]( const ::canvas::Sprite::Reference& rSprite )
{ makeAdder( nPixel, 1.0 )( calcNumPixel(rSprite) ); }
);
double nPixel(0.0);
static const int NUM_VIRDEV(2);
static const int BYTES_PER_PIXEL(3);
// accumulate pixel count for each sprite into fCount
mpRedrawManager->forEachSprite(
[&nPixel]( const ::canvas::Sprite::Reference& rSprite )
{ makeAdder( nPixel, 1.0 )( calcNumPixel(rSprite) ); }
);
const Size& rVDevSize( maVDev->GetOutputSizePixel() );
const Size& rBackBufferSize( pBackBuffer->getOutDev().GetOutputSizePixel() );
static const int NUM_VIRDEV(2);
static const int BYTES_PER_PIXEL(3);
const double nMemUsage( nPixel * NUM_VIRDEV * BYTES_PER_PIXEL +
rVDevSize.Width()*rVDevSize.Height() * BYTES_PER_PIXEL +
rBackBufferSize.Width()*rBackBufferSize.Height() * BYTES_PER_PIXEL );
const Size& rVDevSize( maVDev->GetOutputSizePixel() );
const Size& rBackBufferSize( pBackBuffer->getOutDev().GetOutputSizePixel() );
OUString text( ::rtl::math::doubleToUString( nMemUsage / 1048576.0,
rtl_math_StringFormat_F,
2,'.',nullptr,' ') );
const double nMemUsage( nPixel * NUM_VIRDEV * BYTES_PER_PIXEL +
rVDevSize.Width()*rVDevSize.Height() * BYTES_PER_PIXEL +
rBackBufferSize.Width()*rBackBufferSize.Height() * BYTES_PER_PIXEL );
// pad with leading space
while( text.getLength() < 4 )
text = " " + text;
OUString text( ::rtl::math::doubleToUString( nMemUsage / 1048576.0,
rtl_math_StringFormat_F,
2,'.',nullptr,' ') );
text = "Mem: " + text + "MB";
// pad with leading space
while( text.getLength() < 4 )
text = " " + text;
renderInfoText( rOutDev,
text,
Point(0, 60) );
}
text = "Mem: " + text + "MB";
renderInfoText( rOutDev,
text,
Point(0, 60) );
}
}

View File

@@ -98,248 +98,248 @@ namespace vclcanvas
const double fAlpha( getAlpha() );
if( isActive() &&
!::basegfx::fTools::equalZero( fAlpha ) )
if( !(isActive() &&
!::basegfx::fTools::equalZero( fAlpha )) )
return;
const Point aEmptyPoint;
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;
const ::basegfx::B2DVector& rOrigOutputSize( getSizePixel() );
BitmapEx aBmp( mpBackBuffer->getOutDev().GetBitmapEx( aEmptyPoint,
aOutputSize ) );
// 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 )
if( isContentFullyOpaque() )
{
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 ) );
// bitmasks are much faster than alphamasks on some platforms
// so convert to bitmask if useful
bool convertTo1Bpp = aMask.GetBitCount() != 1;
#ifdef MACOSX
convertTo1Bpp = false;
#endif
if( SkiaHelper::isVCLSkiaEnabled())
convertTo1Bpp = false;
if( convertTo1Bpp )
{
OSL_FAIL("CanvasCustomSprite::redraw(): Mask bitmap is not "
"monochrome (performance!)");
BitmapEx aMaskEx(aMask);
BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255));
aMask = aMaskEx.GetBitmap();
}
// Note: since we retrieved aBmp and aMask
// directly from an OutDev, it's already a
// 'display bitmap' on windows.
if( aMask.GetBitCount() == 1 )
maContent = BitmapEx( aBmp.GetBitmap(), aMask.GetBitmap() );
else
maContent = BitmapEx( aBmp.GetBitmap(), AlphaMask( aMask.GetBitmap()) );
}
// 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;
}
::basegfx::B2DHomMatrix aTransform( getTransformation() );
// check whether matrix is "easy" to handle - pure
// translations or scales are handled by OutputDevice
// alone
const bool bIdentityTransform( aTransform.isIdentity() );
// make transformation absolute (put sprite to final
// output position). Need to happen here, as we also have
// to translate the clip polygon
aTransform.translate( aOutPos.X(),
aOutPos.Y() );
if( !bIdentityTransform )
else
{
// Avoid the trick with the negative width in the OpenGL case,
// OutputDevice::DrawDeviceAlphaBitmap() doesn't like it.
if (!::basegfx::fTools::equalZero( aTransform.get(0,1) ) ||
!::basegfx::fTools::equalZero( aTransform.get(1,0) )
#if HAVE_FEATURE_UI
|| OpenGLHelper::isVCLOpenGLEnabled()
// sprite content might contain alpha, create
// BmpEx, then.
BitmapEx aMask( mpBackBufferMask->getOutDev().GetBitmapEx( aEmptyPoint,
aOutputSize ) );
// bitmasks are much faster than alphamasks on some platforms
// so convert to bitmask if useful
bool convertTo1Bpp = aMask.GetBitCount() != 1;
#ifdef MACOSX
convertTo1Bpp = false;
#endif
|| SkiaHelper::isVCLSkiaEnabled()
)
if( SkiaHelper::isVCLSkiaEnabled())
convertTo1Bpp = false;
if( convertTo1Bpp )
{
// "complex" transformation, employ affine
// transformator
OSL_FAIL("CanvasCustomSprite::redraw(): Mask bitmap is not "
"monochrome (performance!)");
BitmapEx aMaskEx(aMask);
BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255));
aMask = aMaskEx.GetBitmap();
}
// modify output position, to account for the fact
// that transformBitmap() always normalizes its output
// bitmap into the smallest enclosing box.
::basegfx::B2DRectangle aDestRect;
::canvas::tools::calcTransformedRectBounds( aDestRect,
::basegfx::B2DRectangle(0,
0,
rOrigOutputSize.getX(),
rOrigOutputSize.getY()),
aTransform );
// Note: since we retrieved aBmp and aMask
// directly from an OutDev, it's already a
// 'display bitmap' on windows.
if( aMask.GetBitCount() == 1 )
maContent = BitmapEx( aBmp.GetBitmap(), aMask.GetBitmap() );
else
maContent = BitmapEx( aBmp.GetBitmap(), AlphaMask( aMask.GetBitmap()) );
}
}
aOutPos.setX( ::basegfx::fround( aDestRect.getMinX() ) );
aOutPos.setY( ::basegfx::fround( aDestRect.getMinY() ) );
::basegfx::B2DHomMatrix aTransform( getTransformation() );
// TODO(P3): Use optimized bitmap transformation here.
// check whether matrix is "easy" to handle - pure
// translations or scales are handled by OutputDevice
// alone
const bool bIdentityTransform( aTransform.isIdentity() );
// actually re-create the bitmap ONLY if necessary
if( bNeedBitmapUpdate )
maContent = tools::transformBitmap( *maContent,
// make transformation absolute (put sprite to final
// output position). Need to happen here, as we also have
// to translate the clip polygon
aTransform.translate( aOutPos.X(),
aOutPos.Y() );
if( !bIdentityTransform )
{
// Avoid the trick with the negative width in the OpenGL case,
// OutputDevice::DrawDeviceAlphaBitmap() doesn't like it.
if (!::basegfx::fTools::equalZero( aTransform.get(0,1) ) ||
!::basegfx::fTools::equalZero( aTransform.get(1,0) )
#if HAVE_FEATURE_UI
|| OpenGLHelper::isVCLOpenGLEnabled()
#endif
|| SkiaHelper::isVCLSkiaEnabled()
)
{
// "complex" transformation, employ affine
// transformator
// modify output position, to account for the fact
// that transformBitmap() always normalizes its output
// bitmap into the smallest enclosing box.
::basegfx::B2DRectangle aDestRect;
::canvas::tools::calcTransformedRectBounds( aDestRect,
::basegfx::B2DRectangle(0,
0,
rOrigOutputSize.getX(),
rOrigOutputSize.getY()),
aTransform );
aOutputSize = maContent->GetSizePixel();
}
else
{
// relatively 'simplistic' transformation -
// retrieve scale and translational offset
aOutputSize.setWidth (
::basegfx::fround( rOrigOutputSize.getX() * aTransform.get(0,0) ) );
aOutputSize.setHeight(
::basegfx::fround( rOrigOutputSize.getY() * aTransform.get(1,1) ) );
aOutPos.setX( ::basegfx::fround( aDestRect.getMinX() ) );
aOutPos.setY( ::basegfx::fround( aDestRect.getMinY() ) );
aOutPos.setX( ::basegfx::fround( aTransform.get(0,2) ) );
aOutPos.setY( ::basegfx::fround( aTransform.get(1,2) ) );
}
// TODO(P3): Use optimized bitmap transformation here.
// actually re-create the bitmap ONLY if necessary
if( bNeedBitmapUpdate )
maContent = tools::transformBitmap( *maContent,
aTransform );
aOutputSize = maContent->GetSizePixel();
}
// transformBitmap() might return empty bitmaps, for tiny
// scales.
if( !!(*maContent) )
else
{
rTargetSurface.Push( PushFlags::CLIPREGION );
// relatively 'simplistic' transformation -
// retrieve scale and translational offset
aOutputSize.setWidth (
::basegfx::fround( rOrigOutputSize.getX() * aTransform.get(0,0) ) );
aOutputSize.setHeight(
::basegfx::fround( rOrigOutputSize.getY() * aTransform.get(1,1) ) );
// apply clip (if any)
if( getClip().is() )
{
::basegfx::B2DPolyPolygon aClipPoly(
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
getClip() ));
aOutPos.setX( ::basegfx::fround( aTransform.get(0,2) ) );
aOutPos.setY( ::basegfx::fround( aTransform.get(1,2) ) );
}
}
if( aClipPoly.count() )
{
// aTransform already contains the
// translational component, moving the clip to
// the final sprite output position.
aClipPoly.transform( aTransform );
// transformBitmap() might return empty bitmaps, for tiny
// scales.
if( !(*maContent) )
return;
if( mbShowSpriteBounds )
{
// Paint green sprite clip area
rTargetSurface.SetLineColor( Color( 0,255,0 ) );
rTargetSurface.SetFillColor();
rTargetSurface.Push( PushFlags::CLIPREGION );
rTargetSurface.DrawPolyPolygon(::tools::PolyPolygon(aClipPoly)); // #i76339#
}
// apply clip (if any)
if( getClip().is() )
{
::basegfx::B2DPolyPolygon aClipPoly(
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
getClip() ));
vcl::Region aClipRegion( aClipPoly );
rTargetSurface.SetClipRegion( aClipRegion );
}
}
if( ::rtl::math::approxEqual(fAlpha, 1.0) )
{
// no alpha modulation -> just copy to output
if( maContent->IsTransparent() )
rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize, *maContent );
else
rTargetSurface.DrawBitmap( aOutPos, aOutputSize, maContent->GetBitmap() );
}
else
{
// TODO(P3): Switch to OutputDevice::DrawTransparent()
// here
// draw semi-transparent
sal_uInt8 nColor( static_cast<sal_uInt8>( ::basegfx::fround( 255.0*(1.0 - fAlpha) + .5) ) );
AlphaMask aAlpha( maContent->GetSizePixel(),
&nColor );
// mask out fully transparent areas
if( maContent->IsTransparent() )
aAlpha.Replace( maContent->GetMask(), 255 );
// alpha-blend to output
rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize,
BitmapEx( maContent->GetBitmap(),
aAlpha ) );
}
rTargetSurface.Pop();
if( aClipPoly.count() )
{
// aTransform already contains the
// translational component, moving the clip to
// the final sprite output position.
aClipPoly.transform( aTransform );
if( mbShowSpriteBounds )
{
::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 );
// Paint green sprite clip area
rTargetSurface.SetLineColor( Color( 0,255,0 ) );
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(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());
rTargetSurface.DrawPolyPolygon(::tools::PolyPolygon(aClipPoly)); // #i76339#
}
vcl::Region aClipRegion( aClipPoly );
rTargetSurface.SetClipRegion( aClipRegion );
}
}
if( ::rtl::math::approxEqual(fAlpha, 1.0) )
{
// no alpha modulation -> just copy to output
if( maContent->IsTransparent() )
rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize, *maContent );
else
rTargetSurface.DrawBitmap( aOutPos, aOutputSize, maContent->GetBitmap() );
}
else
{
// TODO(P3): Switch to OutputDevice::DrawTransparent()
// here
// draw semi-transparent
sal_uInt8 nColor( static_cast<sal_uInt8>( ::basegfx::fround( 255.0*(1.0 - fAlpha) + .5) ) );
AlphaMask aAlpha( maContent->GetSizePixel(),
&nColor );
// mask out fully transparent areas
if( maContent->IsTransparent() )
aAlpha.Replace( maContent->GetMask(), 255 );
// alpha-blend to output
rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize,
BitmapEx( maContent->GetBitmap(),
aAlpha ) );
}
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(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