2014-04-14 21:54:43 +10:00
|
|
|
/* -*- 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 .
|
|
|
|
*/
|
2015-06-18 10:37:01 +03:00
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
2014-04-27 05:07:47 -05:00
|
|
|
#include <sal/types.h>
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
#include <basegfx/matrix/b2dhommatrix.hxx>
|
|
|
|
#include <basegfx/polygon/b2dlinegeometry.hxx>
|
2017-11-23 23:03:52 +01:00
|
|
|
#include <vcl/gdimtf.hxx>
|
|
|
|
#include <vcl/metaact.hxx>
|
2014-04-27 05:07:47 -05:00
|
|
|
#include <vcl/outdev.hxx>
|
2015-05-23 18:52:00 +02:00
|
|
|
#include <vcl/virdev.hxx>
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2017-10-23 22:28:18 +02:00
|
|
|
#include <salgdi.hxx>
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2015-08-16 16:45:12 -05:00
|
|
|
void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly )
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2015-06-18 10:37:01 +03:00
|
|
|
assert(!is_double_buffered_window());
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if( mpMetaFile )
|
|
|
|
mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
|
|
|
|
|
|
|
|
sal_uInt16 nPoints = rPoly.GetSize();
|
|
|
|
|
|
|
|
if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// we need a graphics
|
2014-04-27 05:07:47 -05:00
|
|
|
if ( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
2021-03-21 15:27:09 +00:00
|
|
|
assert(mpGraphics);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if ( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
// use b2dpolygon drawing if possible
|
2020-09-24 19:43:58 +02:00
|
|
|
if(DrawPolyLineDirectInternal(
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
basegfx::B2DHomMatrix(),
|
|
|
|
rPoly.getB2DPolygon()))
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-04-14 21:54:43 +10:00
|
|
|
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
const basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
|
|
|
|
const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
|
|
|
|
const bool bPixelSnapHairline(mnAntialiasing & AntialiasingFlags::PixelSnapHairline);
|
|
|
|
|
2020-11-10 16:08:17 +01:00
|
|
|
bool bDrawn = mpGraphics->DrawPolyLine(
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
aTransform,
|
|
|
|
aB2DPolyLine,
|
|
|
|
0.0,
|
2020-04-30 12:23:28 +02:00
|
|
|
0.0, // tdf#124848 hairline
|
2020-02-06 18:53:12 +01:00
|
|
|
nullptr, // MM01
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
basegfx::B2DLineJoin::NONE,
|
|
|
|
css::drawing::LineCap_BUTT,
|
|
|
|
basegfx::deg2rad(15.0) /*default fMiterMinimumAngle, not used*/,
|
|
|
|
bPixelSnapHairline,
|
2020-11-30 12:10:47 +00:00
|
|
|
*this);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2020-11-10 16:08:17 +01:00
|
|
|
if(!bDrawn)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2020-11-10 16:08:17 +01:00
|
|
|
tools::Polygon aPoly = ImplLogicToDevicePixel( rPoly );
|
2020-11-12 12:29:08 +02:00
|
|
|
Point* pPtAry = aPoly.GetPointAry();
|
2020-11-10 16:08:17 +01:00
|
|
|
|
|
|
|
// #100127# Forward beziers to sal, if any
|
|
|
|
if( aPoly.HasFlags() )
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2020-11-10 16:08:17 +01:00
|
|
|
const PolyFlags* pFlgAry = aPoly.GetConstFlagAry();
|
2020-11-27 12:47:27 +00:00
|
|
|
if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, *this ) )
|
2020-11-10 16:08:17 +01:00
|
|
|
{
|
|
|
|
aPoly = tools::Polygon::SubdivideBezier(aPoly);
|
2020-11-12 12:29:08 +02:00
|
|
|
pPtAry = aPoly.GetPointAry();
|
2020-11-27 12:47:27 +00:00
|
|
|
mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, *this );
|
2020-11-10 16:08:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-27 12:47:27 +00:00
|
|
|
mpGraphics->DrawPolyLine( nPoints, pPtAry, *this );
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawPolyLine( rPoly );
|
|
|
|
}
|
|
|
|
|
2015-08-16 16:45:12 -05:00
|
|
|
void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly, const LineInfo& rLineInfo )
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2015-06-18 10:37:01 +03:00
|
|
|
assert(!is_double_buffered_window());
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( rLineInfo.IsDefault() )
|
|
|
|
{
|
|
|
|
DrawPolyLine( rPoly );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// #i101491#
|
|
|
|
// Try direct Fallback to B2D-Version of DrawPolyLine
|
2020-09-25 13:30:11 +02:00
|
|
|
if(LineStyle::Solid == rLineInfo.GetStyle())
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2016-04-09 23:15:09 +02:00
|
|
|
DrawPolyLine(
|
|
|
|
rPoly.getB2DPolygon(),
|
2021-04-27 11:44:48 +02:00
|
|
|
rLineInfo.GetWidth(),
|
2016-04-09 23:15:09 +02:00
|
|
|
rLineInfo.GetLineJoin(),
|
|
|
|
rLineInfo.GetLineCap(),
|
2018-08-04 10:37:17 +03:00
|
|
|
basegfx::deg2rad(15.0) /* default fMiterMinimumAngle, value not available in LineInfo */);
|
2014-04-14 21:54:43 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( mpMetaFile )
|
|
|
|
mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
|
|
|
|
|
2014-11-02 12:38:16 +11:00
|
|
|
drawPolyLine(rPoly, rLineInfo);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
2014-04-27 05:07:47 -05:00
|
|
|
void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon,
|
|
|
|
double fLineWidth,
|
|
|
|
basegfx::B2DLineJoin eLineJoin,
|
2016-04-09 23:15:09 +02:00
|
|
|
css::drawing::LineCap eLineCap,
|
|
|
|
double fMiterMinimumAngle)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2015-06-18 10:37:01 +03:00
|
|
|
assert(!is_double_buffered_window());
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if( mpMetaFile )
|
|
|
|
{
|
|
|
|
LineInfo aLineInfo;
|
|
|
|
if( fLineWidth != 0.0 )
|
2021-04-27 11:44:48 +02:00
|
|
|
aLineInfo.SetWidth( fLineWidth );
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2021-10-02 11:11:32 +10:00
|
|
|
aLineInfo.SetLineJoin(eLineJoin);
|
|
|
|
aLineInfo.SetLineCap(eLineCap);
|
|
|
|
|
2015-08-16 16:45:12 -05:00
|
|
|
const tools::Polygon aToolsPolygon( rB2DPolygon );
|
2014-04-14 21:54:43 +10:00
|
|
|
mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not paint empty PolyPolygons
|
|
|
|
if(!rB2DPolygon.count() || !IsDeviceOutputNecessary())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// we need a graphics
|
2014-04-27 05:07:47 -05:00
|
|
|
if( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
2021-03-21 15:27:09 +00:00
|
|
|
assert(mpGraphics);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
// use b2dpolygon drawing if possible
|
2020-09-24 19:43:58 +02:00
|
|
|
if(DrawPolyLineDirectInternal(
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
basegfx::B2DHomMatrix(),
|
|
|
|
rB2DPolygon,
|
|
|
|
fLineWidth,
|
|
|
|
0.0,
|
2020-02-06 18:53:12 +01:00
|
|
|
nullptr, // MM01
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
eLineJoin,
|
|
|
|
eLineCap,
|
|
|
|
fMiterMinimumAngle))
|
|
|
|
{
|
2014-11-02 13:10:13 +11:00
|
|
|
return;
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
}
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
// #i101491#
|
|
|
|
// no output yet; fallback to geometry decomposition and use filled polygon paint
|
|
|
|
// when line is fat and not too complex. ImplDrawPolyPolygonWithB2DPolyPolygon
|
|
|
|
// will do internal needed AA checks etc.
|
2014-04-27 05:07:47 -05:00
|
|
|
if(fLineWidth >= 2.5 &&
|
|
|
|
rB2DPolygon.count() &&
|
|
|
|
rB2DPolygon.count() <= 1000)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
|
|
|
const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
|
|
|
|
const basegfx::B2DPolyPolygon aAreaPolyPolygon(
|
2017-09-22 14:12:07 +03:00
|
|
|
basegfx::utils::createAreaGeometry( rB2DPolygon,
|
2014-04-27 05:07:47 -05:00
|
|
|
fHalfLineWidth,
|
|
|
|
eLineJoin,
|
2016-04-09 23:15:09 +02:00
|
|
|
eLineCap,
|
|
|
|
fMiterMinimumAngle));
|
2014-04-14 21:54:43 +10:00
|
|
|
const Color aOldLineColor(maLineColor);
|
|
|
|
const Color aOldFillColor(maFillColor);
|
|
|
|
|
|
|
|
SetLineColor();
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
SetFillColor(aOldLineColor);
|
2014-04-27 19:38:55 +10:00
|
|
|
InitFillColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2015-07-02 18:25:58 +02:00
|
|
|
// draw using a loop; else the topology will paint a PolyPolygon
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rPolygon : aAreaPolyPolygon)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
|
|
|
ImplDrawPolyPolygonWithB2DPolyPolygon(
|
2018-10-12 20:06:18 +02:00
|
|
|
basegfx::B2DPolyPolygon(rPolygon));
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
SetLineColor(aOldLineColor);
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
SetFillColor(aOldFillColor);
|
2014-04-27 19:38:55 +10:00
|
|
|
InitFillColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2014-11-02 13:42:34 +11:00
|
|
|
// when AA it is necessary to also paint the filled polygon's outline
|
|
|
|
// to avoid optical gaps
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rPolygon : aAreaPolyPolygon)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2020-09-24 19:43:58 +02:00
|
|
|
(void)DrawPolyLineDirectInternal(
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
basegfx::B2DHomMatrix(),
|
2020-09-25 13:30:11 +02:00
|
|
|
rPolygon);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// fallback to old polygon drawing if needed
|
2015-08-16 16:45:12 -05:00
|
|
|
const tools::Polygon aToolsPolygon( rB2DPolygon );
|
2014-04-14 21:54:43 +10:00
|
|
|
LineInfo aLineInfo;
|
|
|
|
if( fLineWidth != 0.0 )
|
2021-04-27 11:44:48 +02:00
|
|
|
aLineInfo.SetWidth( fLineWidth );
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-11-02 12:38:16 +11:00
|
|
|
drawPolyLine( aToolsPolygon, aLineInfo );
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-16 16:45:12 -05:00
|
|
|
void OutputDevice::drawPolyLine(const tools::Polygon& rPoly, const LineInfo& rLineInfo)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
|
|
|
sal_uInt16 nPoints(rPoly.GetSize());
|
|
|
|
|
2016-09-02 08:36:23 +02:00
|
|
|
if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LineStyle::NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
|
2014-04-14 21:54:43 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
// we need a graphics
|
2014-04-23 07:22:08 +10:00
|
|
|
if ( !mpGraphics && !AcquireGraphics() )
|
2014-04-14 21:54:43 +10:00
|
|
|
return;
|
2021-03-21 15:27:09 +00:00
|
|
|
assert(mpGraphics);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
|
2016-09-02 08:36:23 +02:00
|
|
|
const bool bDashUsed(LineStyle::Dash == aInfo.GetStyle());
|
2014-04-14 21:54:43 +10:00
|
|
|
const bool bLineWidthUsed(aInfo.GetWidth() > 1);
|
|
|
|
|
crashtesting: assert making thumbnail on reexport of tdf127770-1.ods to ods
convert to B2DPolygon earlier and do scaling on B2DPolygon's doubles
#18 0x00007f534e1093bc in ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long) (n=<optimized out>, nDPI=<optimized out>, nMapNum=<optimized out>, nMapDenom=<optimized out>) at vcl/source/outdev/map.cxx:268
__PRETTY_FUNCTION__ = "tools::Long ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long)"
n64 = <optimized out>
#19 0x00007f534e10a4ff in OutputDevice::ImplLogicToDevicePixel(tools::Polygon const&) const (this=this@entry=0x55c3ebbb9f60, rLogicPoly=...) at include/tools/gen.hxx:80
rPt = Point = {x = -794275722273860480, y = 0}
i = 0
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x55c3e9fdc250}}
pPointAry = 0x55c3e9c9b970
#20 0x00007f534e0ff4d4 in OutputDevice::drawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:251
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x7f534e0bfde8 <__gnu_debug::_Safe_sequence<std::__debug::vector<OutDevState, std::allocator<OutDevState> > >::_M_invalidate_if<__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > > >(__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > >)+208>}}
__PRETTY_FUNCTION__ = "void OutputDevice::drawPolyLine(const tools::Polygon&, const LineInfo&)"
aInfo = {mpImplLineInfo = {m_pimpl = 0x55c3eaa4ca68}}
bDashUsed = <optimized out>
bLineWidthUsed = <optimized out>
#21 0x00007f534e0ff3d8 in OutputDevice::DrawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:135
__PRETTY_FUNCTION__ = "void OutputDevice::DrawPolyLine(const tools::Polygon&, const LineInfo&)"
#22 0x00007f534e1f1d56 in MetaPolyLineAction::Execute(OutputDevice*) (this=0x55c3e998e300, pOut=0x55c3ebbb9f60) at vcl/source/gdi/metaact.cxx:481
#23 0x00007f534e1be27a in GDIMetaFile::Play(OutputDevice&, unsigned long) (this=this@entry=0x55c3e9e4c700, rOut=..., nPos=86, nPos@entry=4294967295) at vcl/source/gdi/gdimtf.cxx:371
nCurPos = 48
i = 48
pAction = 0x55c3e998e300
nObjCount = <optimized out>
nSyncCount = 4294967295
#24 0x00007f534e1be4e1 in GDIMetaFile::Play(OutputDevice&, Point const&, Size const&) (this=this@entry=0x55c3e9e4c700, rOut=..., rPos=Point = {...}, rSize=Size = {...}) at vcl/source/gdi/gdimtf.cxx:512
aDrawMap = {mpImplMapMode = {m_pimpl = 0x55c3e9f338d0}}
aDestSize = Size = {width = 756, height = 1020}
pMtf = 0x0
aScaleX = {mnNumerator = 756, mnDenominator = 341, mbValid = true}
aScaleY = {mnNumerator = 1020, mnDenominator = 461, mbValid = true}
rOldOffset = Size = {width = 0, height = 0}
aEmptySize = Size = {width = 0, height = 0}
bIsRecord = false
#25 0x00007f534e1be9c5 in GDIMetaFile::CreateThumbnail(BitmapEx&, BmpConversion, BmpScaleFlag) const (this=this@entry=0x55c3e9e4c700, rBitmapEx=..., eColorConversion=eColorConversion@entry=BmpConversion::N8BitColors, nScaleFlag=nScaleFlag@entry=BmpScaleFlag::Default) at include/rtl/ref.hxx:206
aAntialias = Size = {width = 756, height = 1020}
aBitmap = {maBitmap = <incomplete type>, maAlphaMask = <incomplete type>, maBitmapSize = Size = {width = 94299930324064, height = 139995769668141}}
aVDev = {<ScopedVclPtr<VirtualDevice>> = {<VclPtr<VirtualDevice>> = {m_rInnerRef = rtl::Reference to 0x55c3ebbb9f60}, <No data fields>}, <No data fields>}
aNullPt = Point = {x = 0, y = 0}
aDrawSize = Size = {width = 189, height = 255}
aSizePix = <optimized out>
nMaximumExtent = 256
aAntialiasSize = Size = {width = 760, height = 1024}
Change-Id: I4284a7da0684845d7c0af136b25c5210d522c79b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121863
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2021-09-09 20:02:55 +01:00
|
|
|
if (bDashUsed || bLineWidthUsed)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
crashtesting: assert making thumbnail on reexport of tdf127770-1.ods to ods
convert to B2DPolygon earlier and do scaling on B2DPolygon's doubles
#18 0x00007f534e1093bc in ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long) (n=<optimized out>, nDPI=<optimized out>, nMapNum=<optimized out>, nMapDenom=<optimized out>) at vcl/source/outdev/map.cxx:268
__PRETTY_FUNCTION__ = "tools::Long ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long)"
n64 = <optimized out>
#19 0x00007f534e10a4ff in OutputDevice::ImplLogicToDevicePixel(tools::Polygon const&) const (this=this@entry=0x55c3ebbb9f60, rLogicPoly=...) at include/tools/gen.hxx:80
rPt = Point = {x = -794275722273860480, y = 0}
i = 0
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x55c3e9fdc250}}
pPointAry = 0x55c3e9c9b970
#20 0x00007f534e0ff4d4 in OutputDevice::drawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:251
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x7f534e0bfde8 <__gnu_debug::_Safe_sequence<std::__debug::vector<OutDevState, std::allocator<OutDevState> > >::_M_invalidate_if<__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > > >(__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > >)+208>}}
__PRETTY_FUNCTION__ = "void OutputDevice::drawPolyLine(const tools::Polygon&, const LineInfo&)"
aInfo = {mpImplLineInfo = {m_pimpl = 0x55c3eaa4ca68}}
bDashUsed = <optimized out>
bLineWidthUsed = <optimized out>
#21 0x00007f534e0ff3d8 in OutputDevice::DrawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:135
__PRETTY_FUNCTION__ = "void OutputDevice::DrawPolyLine(const tools::Polygon&, const LineInfo&)"
#22 0x00007f534e1f1d56 in MetaPolyLineAction::Execute(OutputDevice*) (this=0x55c3e998e300, pOut=0x55c3ebbb9f60) at vcl/source/gdi/metaact.cxx:481
#23 0x00007f534e1be27a in GDIMetaFile::Play(OutputDevice&, unsigned long) (this=this@entry=0x55c3e9e4c700, rOut=..., nPos=86, nPos@entry=4294967295) at vcl/source/gdi/gdimtf.cxx:371
nCurPos = 48
i = 48
pAction = 0x55c3e998e300
nObjCount = <optimized out>
nSyncCount = 4294967295
#24 0x00007f534e1be4e1 in GDIMetaFile::Play(OutputDevice&, Point const&, Size const&) (this=this@entry=0x55c3e9e4c700, rOut=..., rPos=Point = {...}, rSize=Size = {...}) at vcl/source/gdi/gdimtf.cxx:512
aDrawMap = {mpImplMapMode = {m_pimpl = 0x55c3e9f338d0}}
aDestSize = Size = {width = 756, height = 1020}
pMtf = 0x0
aScaleX = {mnNumerator = 756, mnDenominator = 341, mbValid = true}
aScaleY = {mnNumerator = 1020, mnDenominator = 461, mbValid = true}
rOldOffset = Size = {width = 0, height = 0}
aEmptySize = Size = {width = 0, height = 0}
bIsRecord = false
#25 0x00007f534e1be9c5 in GDIMetaFile::CreateThumbnail(BitmapEx&, BmpConversion, BmpScaleFlag) const (this=this@entry=0x55c3e9e4c700, rBitmapEx=..., eColorConversion=eColorConversion@entry=BmpConversion::N8BitColors, nScaleFlag=nScaleFlag@entry=BmpScaleFlag::Default) at include/rtl/ref.hxx:206
aAntialias = Size = {width = 756, height = 1020}
aBitmap = {maBitmap = <incomplete type>, maAlphaMask = <incomplete type>, maBitmapSize = Size = {width = 94299930324064, height = 139995769668141}}
aVDev = {<ScopedVclPtr<VirtualDevice>> = {<VclPtr<VirtualDevice>> = {m_rInnerRef = rtl::Reference to 0x55c3ebbb9f60}, <No data fields>}, <No data fields>}
aNullPt = Point = {x = 0, y = 0}
aDrawSize = Size = {width = 189, height = 255}
aSizePix = <optimized out>
nMaximumExtent = 256
aAntialiasSize = Size = {width = 760, height = 1024}
Change-Id: I4284a7da0684845d7c0af136b25c5210d522c79b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121863
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2021-09-09 20:02:55 +01:00
|
|
|
basegfx::B2DPolygon aPoly = ImplLogicToDevicePixel(rPoly.getB2DPolygon());
|
|
|
|
drawLine(basegfx::B2DPolyPolygon(aPoly), aInfo);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
crashtesting: assert making thumbnail on reexport of tdf127770-1.ods to ods
convert to B2DPolygon earlier and do scaling on B2DPolygon's doubles
#18 0x00007f534e1093bc in ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long) (n=<optimized out>, nDPI=<optimized out>, nMapNum=<optimized out>, nMapDenom=<optimized out>) at vcl/source/outdev/map.cxx:268
__PRETTY_FUNCTION__ = "tools::Long ImplLogicToPixel(tools::Long, tools::Long, tools::Long, tools::Long)"
n64 = <optimized out>
#19 0x00007f534e10a4ff in OutputDevice::ImplLogicToDevicePixel(tools::Polygon const&) const (this=this@entry=0x55c3ebbb9f60, rLogicPoly=...) at include/tools/gen.hxx:80
rPt = Point = {x = -794275722273860480, y = 0}
i = 0
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x55c3e9fdc250}}
pPointAry = 0x55c3e9c9b970
#20 0x00007f534e0ff4d4 in OutputDevice::drawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:251
nPoints = 2
aPoly = {mpImplPolygon = {m_pimpl = 0x7f534e0bfde8 <__gnu_debug::_Safe_sequence<std::__debug::vector<OutDevState, std::allocator<OutDevState> > >::_M_invalidate_if<__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > > >(__gnu_debug::_Equal_to<__gnu_cxx::__normal_iterator<OutDevState const*, std::__cxx1998::vector<OutDevState, std::allocator<OutDevState> > > >)+208>}}
__PRETTY_FUNCTION__ = "void OutputDevice::drawPolyLine(const tools::Polygon&, const LineInfo&)"
aInfo = {mpImplLineInfo = {m_pimpl = 0x55c3eaa4ca68}}
bDashUsed = <optimized out>
bLineWidthUsed = <optimized out>
#21 0x00007f534e0ff3d8 in OutputDevice::DrawPolyLine(tools::Polygon const&, LineInfo const&) (this=this@entry=0x55c3ebbb9f60, rPoly=..., rLineInfo=...) at vcl/source/outdev/polyline.cxx:135
__PRETTY_FUNCTION__ = "void OutputDevice::DrawPolyLine(const tools::Polygon&, const LineInfo&)"
#22 0x00007f534e1f1d56 in MetaPolyLineAction::Execute(OutputDevice*) (this=0x55c3e998e300, pOut=0x55c3ebbb9f60) at vcl/source/gdi/metaact.cxx:481
#23 0x00007f534e1be27a in GDIMetaFile::Play(OutputDevice&, unsigned long) (this=this@entry=0x55c3e9e4c700, rOut=..., nPos=86, nPos@entry=4294967295) at vcl/source/gdi/gdimtf.cxx:371
nCurPos = 48
i = 48
pAction = 0x55c3e998e300
nObjCount = <optimized out>
nSyncCount = 4294967295
#24 0x00007f534e1be4e1 in GDIMetaFile::Play(OutputDevice&, Point const&, Size const&) (this=this@entry=0x55c3e9e4c700, rOut=..., rPos=Point = {...}, rSize=Size = {...}) at vcl/source/gdi/gdimtf.cxx:512
aDrawMap = {mpImplMapMode = {m_pimpl = 0x55c3e9f338d0}}
aDestSize = Size = {width = 756, height = 1020}
pMtf = 0x0
aScaleX = {mnNumerator = 756, mnDenominator = 341, mbValid = true}
aScaleY = {mnNumerator = 1020, mnDenominator = 461, mbValid = true}
rOldOffset = Size = {width = 0, height = 0}
aEmptySize = Size = {width = 0, height = 0}
bIsRecord = false
#25 0x00007f534e1be9c5 in GDIMetaFile::CreateThumbnail(BitmapEx&, BmpConversion, BmpScaleFlag) const (this=this@entry=0x55c3e9e4c700, rBitmapEx=..., eColorConversion=eColorConversion@entry=BmpConversion::N8BitColors, nScaleFlag=nScaleFlag@entry=BmpScaleFlag::Default) at include/rtl/ref.hxx:206
aAntialias = Size = {width = 756, height = 1020}
aBitmap = {maBitmap = <incomplete type>, maAlphaMask = <incomplete type>, maBitmapSize = Size = {width = 94299930324064, height = 139995769668141}}
aVDev = {<ScopedVclPtr<VirtualDevice>> = {<VclPtr<VirtualDevice>> = {m_rInnerRef = rtl::Reference to 0x55c3ebbb9f60}, <No data fields>}, <No data fields>}
aNullPt = Point = {x = 0, y = 0}
aDrawSize = Size = {width = 189, height = 255}
aSizePix = <optimized out>
nMaximumExtent = 256
aAntialiasSize = Size = {width = 760, height = 1024}
Change-Id: I4284a7da0684845d7c0af136b25c5210d522c79b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121863
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2021-09-09 20:02:55 +01:00
|
|
|
tools::Polygon aPoly = ImplLogicToDevicePixel(rPoly);
|
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
// #100127# the subdivision HAS to be done here since only a pointer
|
|
|
|
// to an array of points is given to the DrawPolyLine method, there is
|
|
|
|
// NO way to find out there that it's a curve.
|
|
|
|
if( aPoly.HasFlags() )
|
|
|
|
{
|
2015-08-16 16:45:12 -05:00
|
|
|
aPoly = tools::Polygon::SubdivideBezier( aPoly );
|
2014-04-14 21:54:43 +10:00
|
|
|
nPoints = aPoly.GetSize();
|
|
|
|
}
|
|
|
|
|
2020-11-27 12:47:27 +00:00
|
|
|
mpGraphics->DrawPolyLine(nPoints, aPoly.GetPointAry(), *this);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
|
|
|
|
}
|
|
|
|
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
bool OutputDevice::DrawPolyLineDirect(
|
|
|
|
const basegfx::B2DHomMatrix& rObjectTransform,
|
|
|
|
const basegfx::B2DPolygon& rB2DPolygon,
|
|
|
|
double fLineWidth,
|
|
|
|
double fTransparency,
|
2020-02-06 18:53:12 +01:00
|
|
|
const std::vector< double >* pStroke, // MM01
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
basegfx::B2DLineJoin eLineJoin,
|
|
|
|
css::drawing::LineCap eLineCap,
|
2020-09-25 13:30:11 +02:00
|
|
|
double fMiterMinimumAngle)
|
2020-09-24 19:43:58 +02:00
|
|
|
{
|
|
|
|
if(DrawPolyLineDirectInternal(rObjectTransform, rB2DPolygon, fLineWidth, fTransparency,
|
2020-09-25 13:30:11 +02:00
|
|
|
pStroke, eLineJoin, eLineCap, fMiterMinimumAngle))
|
2020-09-24 19:43:58 +02:00
|
|
|
{
|
|
|
|
// Worked, add metafile action (if recorded). This is done only here,
|
|
|
|
// because this function is public, other OutDev functions already add metafile
|
|
|
|
// actions, so they call the internal function directly.
|
|
|
|
if( mpMetaFile )
|
|
|
|
{
|
|
|
|
LineInfo aLineInfo;
|
|
|
|
if( fLineWidth != 0.0 )
|
2021-04-27 11:44:48 +02:00
|
|
|
aLineInfo.SetWidth( fLineWidth );
|
2020-09-24 19:43:58 +02:00
|
|
|
// Transport known information, might be needed
|
|
|
|
aLineInfo.SetLineJoin(eLineJoin);
|
|
|
|
aLineInfo.SetLineCap(eLineCap);
|
|
|
|
// MiterMinimumAngle does not exist yet in LineInfo
|
|
|
|
const tools::Polygon aToolsPolygon( rB2DPolygon );
|
|
|
|
mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OutputDevice::DrawPolyLineDirectInternal(
|
|
|
|
const basegfx::B2DHomMatrix& rObjectTransform,
|
|
|
|
const basegfx::B2DPolygon& rB2DPolygon,
|
|
|
|
double fLineWidth,
|
|
|
|
double fTransparency,
|
|
|
|
const std::vector< double >* pStroke, // MM01
|
|
|
|
basegfx::B2DLineJoin eLineJoin,
|
|
|
|
css::drawing::LineCap eLineCap,
|
2020-09-25 13:30:11 +02:00
|
|
|
double fMiterMinimumAngle)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2015-06-18 10:37:01 +03:00
|
|
|
assert(!is_double_buffered_window());
|
2015-05-23 18:52:00 +02:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
// AW: Do NOT paint empty PolyPolygons
|
|
|
|
if(!rB2DPolygon.count())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// we need a graphics
|
2014-04-27 05:07:47 -05:00
|
|
|
if( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return false;
|
2021-03-21 15:27:09 +00:00
|
|
|
assert(mpGraphics);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if( mbOutputClipped )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2020-09-25 13:30:11 +02:00
|
|
|
const bool bTryB2d(mpGraphics->supportsOperation(OutDevSupportType::B2DDraw) &&
|
2016-09-01 15:48:15 +02:00
|
|
|
RasterOp::OverPaint == GetRasterOp() &&
|
2020-09-25 13:30:11 +02:00
|
|
|
IsLineColor());
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2020-09-25 13:30:11 +02:00
|
|
|
if(bTryB2d)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
// combine rObjectTransform with WorldToDevice
|
|
|
|
const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation() * rObjectTransform);
|
|
|
|
const bool bPixelSnapHairline((mnAntialiasing & AntialiasingFlags::PixelSnapHairline) && rB2DPolygon.count() < 1000);
|
2014-11-02 13:42:34 +11:00
|
|
|
|
2020-05-14 14:42:24 +03:00
|
|
|
const double fAdjustedTransparency = mpAlphaVDev ? 0 : fTransparency;
|
2014-11-02 13:42:34 +11:00
|
|
|
// draw the polyline
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
bool bDrawSuccess = mpGraphics->DrawPolyLine(
|
|
|
|
aTransform,
|
|
|
|
rB2DPolygon,
|
2020-05-14 14:42:24 +03:00
|
|
|
fAdjustedTransparency,
|
2020-04-30 12:23:28 +02:00
|
|
|
fLineWidth, // tdf#124848 use LineWidth direct, do not try to solve for zero-case (aka hairline)
|
2020-02-06 18:53:12 +01:00
|
|
|
pStroke, // MM01
|
Support buffering SystemDependent GraphicData
This is a first step to allow buffering of system
dependent data, especially (but not only) for the
system-dependent implementations of graphic output.
For example, for B2DPolygon and Win output, it allows
buffering the Gdiplus::GraphicsPath instead of re-
creating it all the time.
To support that, the change includes forwarding the
current transformation to the renderers in SalGraphics.
The current state in VCL is to transform all and
everything to device coordinates at every single
paint.
I have currently started to do this for ::drawPolyLine
implementations. The fallbacks for all systems will
at the start of that method just transform the data
to device coordinates, so all works as before.
This may also be done for FilledPolygon paint in a later
step, but most urgent is FatLine painting.
An arrangement of shared_ptr/weak_ptr is used so that
either the instance buffering (in the example B2DPolygon)
or the instance managing it can delete it. The instance
managing it currently uses a 1s Timer and a cycle-lifetime
management, but that can be extended in the future
to e.g. include size hints, too.
The mechanism it designed to support multiple Data per
buffering element, e.g. for B2DPolygon at the same time
system-dependent instances of Gdiplus and Cairo can be
buffered, but also PDF-data.
This is achieved semi-automatic by using
typeid(class).hash_code() as key for organization.
The mechanism will be used for now at B2DPolygon, but
is not limited to. There is already a similar but less
general buffer (see GdiPlusBuffer) that can and will
be converted to use this new mechanism.
Added vcl/headless Cairo renderer to support given
ObjectToDevice transformation (not to transform given
B2DPolygon)
Added support for CairoPath buffered at B2DPolygon,
seems to work well. Need to do more tests
Moved usage to templates suggested by Noel Grandin
(Noel Grandin <noelgrandin@gmail.com>), thanks for
these suggestions. Adapted Win usage to that, too.
Converted Win-specific GdiPlus BitmapBuffer to new
mechanism, works well. Checked, the manager holds
now a mix of bitmap and path data under Win
Added a cleanup mechanism to flush all buffered data
at DeInitVCL() using flushAll() at
SystemDependentDataBuffer
Adapted Linux-versions of ::drawPolyLine to support
PixelSnapHairline, for now in a simplified version
that still allows buffering. This will also be used
(and use buffering) for the Cairo-fallback in
X11SalGraphics
Change-Id: I88d7e438a20b96ddab7707050893bdd590c098c7
Reviewed-on: https://gerrit.libreoffice.org/59555
Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-08-24 13:01:08 +02:00
|
|
|
eLineJoin,
|
|
|
|
eLineCap,
|
|
|
|
fMiterMinimumAngle,
|
|
|
|
bPixelSnapHairline,
|
2020-11-30 12:10:47 +00:00
|
|
|
*this);
|
2014-11-02 13:42:34 +11:00
|
|
|
|
|
|
|
if( bDrawSuccess )
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2020-05-14 14:42:24 +03:00
|
|
|
if (mpAlphaVDev)
|
|
|
|
mpAlphaVDev->DrawPolyLineDirect(rObjectTransform, rB2DPolygon, fLineWidth,
|
|
|
|
fTransparency, pStroke, eLineJoin, eLineCap,
|
2020-09-25 13:30:11 +02:00
|
|
|
fMiterMinimumAngle);
|
2020-05-14 14:42:24 +03:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|