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-16 07:38:10 +03:00
|
|
|
#include <numeric>
|
|
|
|
|
2017-11-23 23:03:52 +01:00
|
|
|
#include <vcl/gdimtf.hxx>
|
|
|
|
#include <vcl/lineinfo.hxx>
|
|
|
|
#include <vcl/metaact.hxx>
|
2014-04-14 21:54:43 +10:00
|
|
|
#include <vcl/outdev.hxx>
|
2015-05-23 18:52:00 +02:00
|
|
|
#include <vcl/virdev.hxx>
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
#include <salgdi.hxx>
|
|
|
|
|
|
|
|
#include <basegfx/matrix/b2dhommatrix.hxx>
|
|
|
|
#include <basegfx/polygon/b2dpolygontools.hxx>
|
|
|
|
#include <basegfx/polygon/b2dpolypolygontools.hxx>
|
|
|
|
#include <basegfx/polygon/b2dlinegeometry.hxx>
|
|
|
|
|
|
|
|
void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
|
|
|
|
const LineInfo& rLineInfo )
|
|
|
|
{
|
2015-06-18 10:37:01 +03:00
|
|
|
assert(!is_double_buffered_window());
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( rLineInfo.IsDefault() )
|
|
|
|
{
|
|
|
|
DrawLine( rStartPt, rEndPt );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( mpMetaFile )
|
|
|
|
mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
|
|
|
|
|
2016-09-02 08:36:23 +02:00
|
|
|
if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LineStyle::NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
|
2014-04-14 21:54:43 +10:00
|
|
|
return;
|
|
|
|
|
2018-11-01 13:14:09 +02:00
|
|
|
if( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
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;
|
|
|
|
|
|
|
|
const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
|
|
|
|
const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
|
|
|
|
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);
|
|
|
|
|
|
|
|
if ( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if(bDashUsed || bLineWidthUsed)
|
|
|
|
{
|
|
|
|
basegfx::B2DPolygon aLinePolygon;
|
|
|
|
aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
|
|
|
|
aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
|
|
|
|
|
2014-11-05 22:30:49 +11:00
|
|
|
drawLine( basegfx::B2DPolyPolygon(aLinePolygon), aInfo );
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
|
|
|
|
{
|
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 MetaLineAction( rStartPt, rEndPt ) );
|
|
|
|
|
|
|
|
if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
|
|
|
|
return;
|
|
|
|
|
2018-11-01 13:14:09 +02:00
|
|
|
if ( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-22 00:40:20 +10: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
|
|
|
|
|
|
|
// #i101598# support AA and snap for lines, too
|
2015-05-19 12:16:31 +02:00
|
|
|
if((mnAntialiasing & AntialiasingFlags::EnableB2dDraw)
|
2016-09-01 14:18:39 +02:00
|
|
|
&& mpGraphics->supportsOperation(OutDevSupportType::B2DDraw)
|
2016-09-01 15:48:15 +02:00
|
|
|
&& RasterOp::OverPaint == GetRasterOp()
|
2014-04-14 21:54:43 +10:00
|
|
|
&& IsLineColor())
|
|
|
|
{
|
|
|
|
// at least transform with double precision to device coordinates; this will
|
|
|
|
// avoid pixel snap of single, appended lines
|
|
|
|
const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
|
|
|
|
const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
|
|
|
|
basegfx::B2DPolygon aB2DPolyLine;
|
|
|
|
|
|
|
|
aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
|
|
|
|
aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
|
|
|
|
aB2DPolyLine.transform( aTransform );
|
|
|
|
|
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 bool bPixelSnapHairline(mnAntialiasing & AntialiasingFlags::PixelSnapHairline);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
2016-04-09 23:15:09 +02:00
|
|
|
if( 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
|
|
|
basegfx::B2DHomMatrix(),
|
2016-04-09 23:15:09 +02:00
|
|
|
aB2DPolyLine,
|
|
|
|
0.0,
|
|
|
|
aB2DLineWidth,
|
|
|
|
basegfx::B2DLineJoin::NONE,
|
|
|
|
css::drawing::LineCap_BUTT,
|
2018-08-04 10:37:17 +03:00
|
|
|
basegfx::deg2rad(15.0), // not used with B2DLineJoin::NONE, but the correct default
|
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
|
|
|
bPixelSnapHairline,
|
2016-04-09 23:15:09 +02:00
|
|
|
this))
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
|
|
|
|
const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
|
|
|
|
|
|
|
|
mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawLine( rStartPt, rEndPt );
|
|
|
|
}
|
|
|
|
|
2014-11-05 22:30:49 +11:00
|
|
|
void OutputDevice::drawLine( basegfx::B2DPolyPolygon aLinePolyPolygon, const LineInfo& rInfo )
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2015-05-19 12:16:31 +02:00
|
|
|
const bool bTryAA((mnAntialiasing & AntialiasingFlags::EnableB2dDraw)
|
2016-09-01 14:18:39 +02:00
|
|
|
&& mpGraphics->supportsOperation(OutDevSupportType::B2DDraw)
|
2016-09-01 15:48:15 +02:00
|
|
|
&& RasterOp::OverPaint == GetRasterOp()
|
2014-04-14 21:54:43 +10:00
|
|
|
&& IsLineColor());
|
|
|
|
basegfx::B2DPolyPolygon aFillPolyPolygon;
|
2016-09-02 08:36:23 +02:00
|
|
|
const bool bDashUsed(LineStyle::Dash == rInfo.GetStyle());
|
2014-04-14 21:54:43 +10:00
|
|
|
const bool bLineWidthUsed(rInfo.GetWidth() > 1);
|
|
|
|
|
|
|
|
if(bDashUsed && aLinePolyPolygon.count())
|
|
|
|
{
|
|
|
|
::std::vector< double > fDotDashArray;
|
|
|
|
const double fDashLen(rInfo.GetDashLen());
|
|
|
|
const double fDotLen(rInfo.GetDotLen());
|
|
|
|
const double fDistance(rInfo.GetDistance());
|
|
|
|
|
|
|
|
for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
|
|
|
|
{
|
|
|
|
fDotDashArray.push_back(fDashLen);
|
|
|
|
fDotDashArray.push_back(fDistance);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
|
|
|
|
{
|
|
|
|
fDotDashArray.push_back(fDotLen);
|
|
|
|
fDotDashArray.push_back(fDistance);
|
|
|
|
}
|
|
|
|
|
|
|
|
const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
|
|
|
|
|
|
|
|
if(fAccumulated > 0.0)
|
|
|
|
{
|
|
|
|
basegfx::B2DPolyPolygon aResult;
|
|
|
|
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rPolygon : aLinePolyPolygon)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2014-11-02 15:55:33 +11:00
|
|
|
basegfx::B2DPolyPolygon aLineTarget;
|
2017-09-22 14:12:07 +03:00
|
|
|
basegfx::utils::applyLineDashing(
|
2018-10-12 20:06:18 +02:00
|
|
|
rPolygon,
|
2014-04-14 21:54:43 +10:00
|
|
|
fDotDashArray,
|
2014-11-02 15:55:33 +11:00
|
|
|
&aLineTarget);
|
|
|
|
aResult.append(aLineTarget);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
aLinePolyPolygon = aResult;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bLineWidthUsed && aLinePolyPolygon.count())
|
|
|
|
{
|
|
|
|
const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
|
|
|
|
|
|
|
|
if(aLinePolyPolygon.areControlPointsUsed())
|
|
|
|
{
|
|
|
|
// #i110768# When area geometry has to be created, do not
|
|
|
|
// use the fallback bezier decomposition inside createAreaGeometry,
|
|
|
|
// but one that is at least as good as ImplSubdivideBezier was.
|
|
|
|
// There, Polygon::AdaptiveSubdivide was used with default parameter
|
|
|
|
// 1.0 as quality index.
|
2017-09-22 14:12:07 +03:00
|
|
|
aLinePolyPolygon = basegfx::utils::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rPolygon : aLinePolyPolygon)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2017-09-22 14:12:07 +03:00
|
|
|
aFillPolyPolygon.append(basegfx::utils::createAreaGeometry(
|
2018-10-12 20:06:18 +02:00
|
|
|
rPolygon,
|
2014-04-14 21:54:43 +10:00
|
|
|
fHalfLineWidth,
|
|
|
|
rInfo.GetLineJoin(),
|
|
|
|
rInfo.GetLineCap()));
|
|
|
|
}
|
|
|
|
|
|
|
|
aLinePolyPolygon.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
GDIMetaFile* pOldMetaFile = mpMetaFile;
|
2015-11-10 10:28:29 +01:00
|
|
|
mpMetaFile = nullptr;
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if(aLinePolyPolygon.count())
|
|
|
|
{
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rB2DPolygon : aLinePolyPolygon)
|
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 bool bPixelSnapHairline(mnAntialiasing & AntialiasingFlags::PixelSnapHairline);
|
2014-04-14 21:54:43 +10:00
|
|
|
bool bDone(false);
|
|
|
|
|
|
|
|
if(bTryAA)
|
|
|
|
{
|
2016-04-09 23:15:09 +02:00
|
|
|
bDone = 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
|
|
|
basegfx::B2DHomMatrix(),
|
2018-10-12 20:06:18 +02:00
|
|
|
rB2DPolygon,
|
2016-04-09 23:15:09 +02:00
|
|
|
0.0,
|
|
|
|
basegfx::B2DVector(1.0,1.0),
|
|
|
|
basegfx::B2DLineJoin::NONE,
|
|
|
|
css::drawing::LineCap_BUTT,
|
2018-08-04 10:37:17 +03:00
|
|
|
basegfx::deg2rad(15.0), // not used with B2DLineJoin::NONE, but the correct default
|
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
|
|
|
bPixelSnapHairline,
|
2016-04-09 23:15:09 +02:00
|
|
|
this);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!bDone)
|
|
|
|
{
|
2018-10-12 20:06:18 +02:00
|
|
|
tools::Polygon aPolygon(rB2DPolygon);
|
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
|
|
|
mpGraphics->DrawPolyLine(
|
|
|
|
aPolygon.GetSize(),
|
|
|
|
reinterpret_cast<SalPoint*>(aPolygon.GetPointAry()),
|
|
|
|
this);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(aFillPolyPolygon.count())
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
bool bDone(false);
|
|
|
|
|
|
|
|
if(bTryAA)
|
|
|
|
{
|
2018-09-06 18:15:02 +02:00
|
|
|
bDone = mpGraphics->DrawPolyPolygon(
|
|
|
|
basegfx::B2DHomMatrix(),
|
|
|
|
aFillPolyPolygon,
|
|
|
|
0.0,
|
|
|
|
this);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!bDone)
|
|
|
|
{
|
2018-10-12 20:06:18 +02:00
|
|
|
for(auto const& rB2DPolygon : aFillPolyPolygon)
|
2014-04-14 21:54:43 +10:00
|
|
|
{
|
2018-10-12 20:06:18 +02:00
|
|
|
tools::Polygon aPolygon(rB2DPolygon);
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
// need to subdivide, mpGraphics->DrawPolygon ignores curves
|
|
|
|
aPolygon.AdaptiveSubdivide(aPolygon);
|
2015-01-19 15:10:10 +01:00
|
|
|
mpGraphics->DrawPolygon(aPolygon.GetSize(), reinterpret_cast<const SalPoint*>(aPolygon.GetConstPointAry()), this);
|
2014-04-14 21:54:43 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFillColor( aOldFillColor );
|
|
|
|
SetLineColor( aOldLineColor );
|
|
|
|
}
|
|
|
|
|
|
|
|
mpMetaFile = pOldMetaFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|