core.git: drawinglayer/source

2024-10-03 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |  157 ++
 1 file changed, 68 insertions(+), 89 deletions(-)

New commits:
commit c92846d670ba5c7f3a7abbced8e88fd214c87ca2
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Oct 3 11:51:13 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Oct 3 14:26:53 2024 +0200

tdf#163234: CairoSDPR: PixelSnap corrections

PixelSnap has to also snap control points, also
simplified some stuff in line geometry conversion
to cairo, plus more precise detection of when to
apply piyel snap

Change-Id: I41d27d8d513a62609a727dfd80f073356c901c49
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174418
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index db25c150e822..06e1459d1b4c 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -82,81 +82,55 @@ void impl_cairo_set_hairline(cairo_t* pRT,
 
 void addB2DPolygonToPathGeometry(cairo_t* pRT, const basegfx::B2DPolygon& 
rPolygon)
 {
-// short circuit if there is nothing to do
 const sal_uInt32 nPointCount(rPolygon.count());
 
-const bool bHasCurves(rPolygon.areControlPointsUsed());
-const bool bClosePath(rPolygon.isClosed());
-const basegfx::B2DPoint* pLast(nullptr);
+if (0 == nPointCount)
+// no points, done
+return;
 
-for (sal_uInt32 nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++)
-{
-int nClosedIdx = nPointIdx;
-if (nPointIdx >= nPointCount)
-{
-// prepare to close last curve segment if needed
-if (bClosePath && (nPointIdx == nPointCount))
-{
-nClosedIdx = 0;
-}
-else
-{
-break;
-}
-}
+// get basic infos
+const bool bClosed(rPolygon.isClosed());
+const sal_uInt32 nEdgeCount(bClosed ? nPointCount : nPointCount - 1);
 
-const basegfx::B2DPoint& rPoint(rPolygon.getB2DPoint(nClosedIdx));
+// get 1st point and move to it
+basegfx::B2DPoint aCurrent(rPolygon.getB2DPoint(0));
+cairo_move_to(pRT, aCurrent.getX(), aCurrent.getY());
 
-if (!nPointIdx)
-{
-// first point => just move there
-cairo_move_to(pRT, rPoint.getX(), rPoint.getY());
-pLast = &rPoint;
-continue;
-}
+for (sal_uInt32 nIndex(0); nIndex < nEdgeCount; nIndex++)
+{
+// get index for and next point
+const sal_uInt32 nNextIndex((nIndex + 1) % nPointCount);
+const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
 
-bool bPendingCurve(false);
+// get and check curve stuff
+basegfx::B2DPoint aCP1(rPolygon.getNextControlPoint(nIndex));
+basegfx::B2DPoint aCP2(rPolygon.getPrevControlPoint(nNextIndex));
+const bool bCP1Equal(aCP1.equal(aCurrent));
+const bool bCP2Equal(aCP2.equal(aNext));
 
-if (bHasCurves)
+if (!bCP1Equal || !bCP2Equal)
 {
-bPendingCurve = rPolygon.isNextControlPointUsed(nPrevIdx);
-bPendingCurve |= rPolygon.isPrevControlPointUsed(nClosedIdx);
-}
+// tdf#99165, see other similar changes for more info
+if (bCP1Equal)
+aCP1 = aCurrent + ((aCP2 - aCurrent) * 0.0005);
 
-if (!bPendingCurve) // line segment
-{
-cairo_line_to(pRT, rPoint.getX(), rPoint.getY());
+if (bCP2Equal)
+aCP2 = aNext + ((aCP1 - aNext) * 0.0005);
+
+cairo_curve_to(pRT, aCP1.getX(), aCP1.getY(), aCP2.getX(), 
aCP2.getY(), aNext.getX(),
+   aNext.getY());
 }
-else // cubic bezier segment
+else
 {
-basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint(nPrevIdx);
-basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint(nClosedIdx);
-
-// tdf#99165 if the control points are 'empty', create the 
mathematical
-// correct replacement ones to avoid problems with the graphical 
sub-system
-// tdf#101026 The 1st attempt to create a mathematically correct 
replacement control
-// vector was wrong. Best alternative is one as close as possible 
which means short.
-if (aCP1.equal(*pLast))
-{
-aCP1 = *pLast + ((aCP2 - *pLast) * 0.0005);
-}
-
-if (aCP2.equal(rPoint))
-{
-aCP2 = rPoint + ((aCP1 - rPoint) * 0.0005);
-}
-
-cairo_curve_to(pRT, aCP1.getX(), aCP1.getY(), aCP2.getX(), 
aCP2.getY(), rPoint.getX(),
-   rPoint.getY());
+cairo_line_to(pRT, aNext.getX(), aNext.getY());
 }
 
-pLa

core.git: drawinglayer/source include/drawinglayer

2024-09-27 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   64 +++--
 drawinglayer/source/processor2d/processor2dtools.cxx   |   56 ++-
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   20 +++-
 3 files changed, 106 insertions(+), 34 deletions(-)

New commits:
commit 59fc2b5ca9678855feb30345761dad739b546edc
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Sep 26 21:00:50 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Sep 27 13:38:35 2024 +0200

tdf#163125: CairoSDPR: Take virtual OutDevs into account

Unfortunaletly we have 'virtual' OutDevs, that means their
PixelSize is bigger as they claim and they use an internal
offset. This is used to not have to create too many Windows
inside Windows (AFAIR initial reason was that Windows has
a fix number of Windows per process that can be incarnated).

The offset was/is already supported by SDPRs using
ViewInformation2D and adding ot to the ViewTransformation,
but the evtl. existing PixelSize has to be clipped against.
The fallback VclPixelProcessor2D supports that indirectly
by doing that in the OutDev commands that get called, so
it does not need to be done by that renderer.

I have now added code to support that for the
CairoPixelProcessor2D, see code and comments. It uses an
existing method of cairo to do that elegantly inside the
system-dependent code of the SDPR.

Note that the Windows SDPR D2DPixelProcessor2D will
have the same problem that will have to be solved there,
too. Since it's currently in experimental state I made
myself a note about that.

Change-Id: I68915985102bb4a63c84299f8d022ab013633510
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173998
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 1bf2b7dd9324..a1b57ed7940a 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -866,9 +866,12 @@ basegfx::B2DRange getDiscreteViewRange(cairo_t* pRT)
 namespace drawinglayer::processor2d
 {
 CairoPixelProcessor2D::CairoPixelProcessor2D(const 
geometry::ViewInformation2D& rViewInformation,
- cairo_surface_t* pTarget)
+ cairo_surface_t* pTarget, 
tools::Long nOffsetPixelX,
+ tools::Long nOffsetPixelY, 
tools::Long nWidthPixel,
+ tools::Long nHeightPixel)
 : BaseProcessor2D(rViewInformation)
 , maBColorModifierStack()
+, mpCreateForRectangle(nullptr)
 , mpRT(nullptr)
 , mbRenderSimpleTextDirect(
   
officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get())
@@ -878,19 +881,64 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const 
geometry::ViewInformation2D&
 {
 if (pTarget)
 {
-cairo_t* pRT = cairo_create(pTarget);
-cairo_set_antialias(pRT, rViewInformation.getUseAntiAliasing() ? 
CAIRO_ANTIALIAS_DEFAULT
-   : 
CAIRO_ANTIALIAS_NONE);
-cairo_set_fill_rule(pRT, CAIRO_FILL_RULE_EVEN_ODD);
-cairo_set_operator(pRT, CAIRO_OPERATOR_OVER);
-setRenderTarget(pRT);
+bool bClipNeeded(false);
+
+if (0 != nOffsetPixelX || 0 != nOffsetPixelY || 0 != nWidthPixel || 0 
!= nHeightPixel)
+{
+if (0 != nOffsetPixelX || 0 != nOffsetPixelY)
+{
+// if offset is used we need initial clip
+bClipNeeded = true;
+}
+else
+{
+// no offset used, compare to real pixel size
+const tools::Long 
nRealPixelWidth(cairo_image_surface_get_width(pTarget));
+const tools::Long 
nRealPixelHeight(cairo_image_surface_get_height(pTarget));
+
+if (nRealPixelWidth != nWidthPixel || nRealPixelHeight != 
nHeightPixel)
+{
+// if size differs we need initial clip
+bClipNeeded = true;
+}
+}
+}
+
+if (bClipNeeded)
+{
+// optional: if the possibility to add an initial clip relative
+// to the real pixel dimensions of the target surface is used,
+// aplly it here using that nice existing method of cairo
+mpCreateForRectangle = cairo_surface_create_for_rectangle(
+pTarget, nOffsetPixelX, nOffsetPixelY, nWidthPixel, 
nHeightPixel);
+
+if (nullptr != mpCreateForRectangle)
+mpRT = cairo_create(mpCreateForRectangle);
+}
+else
+{
+// create RenderTarget for full target
+mpRT = cairo_c

core.git: drawinglayer/source

2024-09-25 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

New commits:
commit dad5b34d011da41d536eb0db9635ac84e51bfcd5
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Sep 24 18:01:11 2024 +0200
Commit: Armin Le Grand 
CommitDate: Wed Sep 25 10:56:34 2024 +0200

tdf#163131 CairoSDPR:

Added BColorModifierStack to SVG linear and radial
gradient direct support, was missing.

Change-Id: I1405ea0653180fa695b40082bf8b8520441d0620
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173871
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 2951b7d33ca1..1bf2b7dd9324 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -3366,9 +3366,9 @@ void 
CairoPixelProcessor2D::processSvgLinearGradientPrimitive2D(
 
 for (const auto& entry : rGradientEntries)
 {
-const basegfx::BColor& rColor(entry.getColor());
-cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), 
rColor.getRed(),
-  rColor.getGreen(), rColor.getBlue(), 
entry.getOpacity());
+const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(entry.getColor()));
+cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), 
aColor.getRed(),
+  aColor.getGreen(), aColor.getBlue(), 
entry.getOpacity());
 }
 
 // set SpreadMethod. Note that we have no SpreadMethod::None because the
@@ -3462,9 +3462,9 @@ void 
CairoPixelProcessor2D::processSvgRadialGradientPrimitive2D(
 
 for (const auto& entry : rGradientEntries)
 {
-const basegfx::BColor& rColor(entry.getColor());
-cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), 
rColor.getRed(),
-  rColor.getGreen(), rColor.getBlue(), 
entry.getOpacity());
+const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(entry.getColor()));
+cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), 
aColor.getRed(),
+  aColor.getGreen(), aColor.getBlue(), 
entry.getOpacity());
 }
 
 // set SpreadMethod


core.git: drawinglayer/qa drawinglayer/source include/drawinglayer sd/qa sw/qa

2024-09-23 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/qa/unit/border.cxx|   16 -
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |  164 ++---
 drawinglayer/source/processor2d/processor2dtools.cxx   |   13 -
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   10 
 sd/qa/unit/PNGExportTests.cxx  |2 
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx |6 
 6 files changed, 126 insertions(+), 85 deletions(-)

New commits:
commit 1acd37a671b9d3633a7d31a0b60478815fbc685f
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Sep 13 11:42:27 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Sep 23 14:12:04 2024 +0200

CairoSDPR: Activate globally to check builds/tests

This is to check all builds/tests with activated
CairoSDPR to evtl. make needed additional changes
as preparation to activate this in the future.

adapted for testTdf139000():
Use no AA offset (0.5) for applying mask.

Adapted for testDoublePixelProcessing:
The trick (hack) to create a PixelProcessor and then
attact a metafile to start recording to it does no
longer work/make sense since the VclPixelProcessor2D
is no longer the only PiyelProcessor you might get.
If it is a SDPR one (e.g. CairoSDPR) it *cannot*
record metafiles - and is not intended to do so.
Since this test was already adapted 6 years ago to
the modernized decompose of a double line to just
two lines anyways it is OK to now change to use
a VclMetafileProcessor2D now initially.

Adapted for CppunitTest_svgio:
In SvgFeBlendNode::apply execute the calls for
convertToBitmapEx without AntiAliasing to get better
edges. Input data is SVGToken::FeFlood, so a
rectangular area, so no AA needed.
Taking this back: The reason must be in the renderer,
nothing else changed. Debugged in detail through
both, problem is that VclPixelProcessor2D ends up in
CairoCommon::drawPolyPolygon and draws the polygon
AntiAliased, but just the fill and thus *not* with
the AA-offset of 0.5, that is only done for fill.
I have to re-consider the AA offset decision for filled
polygons. Checked CairoCommon again, indeed AA offset
is ony done for lines, not for fill - that corresponds
with my thoghts from the weekend. Somehow this must
have come in with copy/paste (?). Same is already
in D2DPixelProcessor2D, have to remove there, too.

Adapted for CppunitTest_sd_png_export_tests:
This was a hard one, debugged all the components used
for ConvertToBitmap/MaskCreation. Cumulated to be
some diff in processTransparencePrimitive2D, but
found no error after checking all tranmsformations.
The orig errof ro the failing test (tdf#158743)
seemed to give a hint, but ObjectTransformation
was just handled well. At the end the diff was
that VclProcessor2D uses the same processor, while
CairoPixelProcessor2D creates local instances
(what is cheap). Thus the content rendering for
TransparencePrimitive2D was *not* using the set
BColorModifierStack. Added as needed to be able
to transfer that to the content rendering
instance.

Adapted for CppunitTest_sd_png_export_tests:
Gerrit says PNGExportTests.cxx:1041 asserts,
but I cannot reproduce. Maybe at the build
system a slightly different font is used.
My only idea is to add the mentioned point
at (12,120) to the rectangles, obviously the
bottom one.
Next one is (13,82), again bottom one,
adapting.

Adapted for CppunitTest_sw_ooxmlexport16:
The test 'testTdf136841' uses a WMF that contains
XOR paint parts. This showed that that part in
CairoSDPR did not work yet as needed. Adapted
that, also the test slightly due to the color
result slightly changed with CairoSDPR.

One last change before activating in master: Add
DISABLE_SYSTEM_DEPENDENT_PRIMITIVE_RENDERER in
case it urgently needs to be switched off or to
be able to simply test if something happening is
related to CairoSDPR

Change-Id: Idb8237a05d7594efe20edfa1707ca0002185645a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173330
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index c69e0e94e7ba..9524ec845afb 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -93,15 +93,23 @@ CPPUNIT_TEST_FIXTURE(DrawinglayerBorderTest, 
testDoubleDecompositionSolid)
 
 CPPUNIT_TEST_FIXTURE(DrawinglayerBorderTest, testDoublePixelProcessing)
 {
-// Create a pixel processor.
+// Creating a pixel-processor and after that attacing a metafile
+// recording is not possible anymore, the pixel-processor may be
+// a SDPR, e.g. a CairoSDPR, and *not* a VclPixelProcessor2D anymore.
+// Since the intention had changed already (see c

core.git: drawinglayer/source include/drawinglayer

2024-09-03 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   42 +++--
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |4 +
 2 files changed, 40 insertions(+), 6 deletions(-)

New commits:
commit c37d18c0a8dbe77ead043a1f3dce86192ca74a79
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Sep 3 13:36:17 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Sep 3 15:58:37 2024 +0200

CairoSDPR: Fixed a problem with cairo_clip (see comments)

Change-Id: I14d477dbeb9a18cc6f9d750b5d1f837117c22eaf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172798
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index ba8d5fb73261..34438eb95f95 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -874,6 +874,7 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const 
geometry::ViewInformation2D&
   
officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get())
 , mbRenderDecoratedTextDirect(
   
officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get())
+, mnClipRecurstionCount(0)
 {
 if (pTarget)
 {
@@ -1448,16 +1449,16 @@ void CairoPixelProcessor2D::processMaskPrimitive2D(
 return;
 }
 
-basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
+const basegfx::B2DPolyPolygon& rMask(rMaskCandidate.getMask());
 
-if (!aMask.count())
+if (!rMask.count())
 {
 // no mask (so nothing inside), done
 return;
 }
 
 // calculate visible range
-basegfx::B2DRange aMaskRange(aMask.getB2DRange());
+basegfx::B2DRange aMaskRange(rMask.getB2DRange());
 
aMaskRange.transform(getViewInformation2D().getObjectToViewTransformation());
 if (!getDiscreteViewRange(mpRT).overlaps(aMaskRange))
 {
@@ -1479,20 +1480,40 @@ void CairoPixelProcessor2D::processMaskPrimitive2D(
 
 // create path geometry and put mask as path
 cairo_new_path(mpRT);
-getOrCreateFillGeometry(mpRT, aMask);
+getOrCreateFillGeometry(mpRT, rMask);
 
-// clip to this mask (also reset path, cairo_clip does not consume it)
+// clip to this mask
 cairo_clip(mpRT);
-cairo_new_path(mpRT);
 
 // reset transformation to not have it set when processing
 // child content below (was only used to set clip path)
 cairo_identity_matrix(mpRT);
 
 // process sub-content (that shall be masked)
+mnClipRecurstionCount++;
 process(rMaskCandidate.getChildren());
+mnClipRecurstionCount--;
 
 cairo_restore(mpRT);
+
+if (0 == mnClipRecurstionCount)
+{
+// for *some* reason Cairo seems to have problems using cairo_clip
+// recursively, in combination with cairo_save/cairo_restore. I think
+// it *should* work as used here, see
+// https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-clip
+// where this combination is explicitely mentioned/explained. It may
+// just be a error in cairo, too (?).
+// The error is that without that for some reason the last clip is not
+// restored but *stays*, so e.g. when having a shape filled with
+// 'tux.svg' and an ellipse overlapping in front, suddenly (but not
+// always?) the ellipse gets 'clipped' against the shape filled with
+// the tux graphic.
+// What helps is to count the clip recursion for each incarnation of
+// CairoPixelProcessor2D/cairo_t used and call/use cairo_reset_clip
+// when last clip is left.
+cairo_reset_clip(mpRT);
+}
 }
 
 void CairoPixelProcessor2D::processModifiedColorPrimitive2D(
@@ -3463,6 +3484,8 @@ void 
CairoPixelProcessor2D::processSvgRadialGradientPrimitive2D(
 
 void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitive2D& rCandidate)
 {
+const cairo_status_t aStart(cairo_status(mpRT));
+
 switch (rCandidate.getPrimitive2DID())
 {
 // geometry that *has* to be processed
@@ -3630,6 +3653,13 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimit
 break;
 }
 }
+
+const cairo_status_t aEnd(cairo_status(mpRT));
+
+if (aStart != aEnd)
+{
+SAL_WARN("drawinglayer", "CairoSDPR: Cairo status problem (!)");
+}
 }
 
 } // end of namespace
diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx 
b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
index 02a49842c512..f654b52c58f0 100644
--- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
@@ -75,6 +75,10 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) 
CairoPixelProcessor2D final : pub
 bool mbRenderSimpleTextDirect;
 bool mbRenderDecoratedTextDirect;
 
+// recu

core.git: drawinglayer/source

2024-08-28 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |   79 +++---
 1 file changed, 67 insertions(+), 12 deletions(-)

New commits:
commit e68715944f26cf3171dde12c4a2dfef64f0e684a
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Aug 27 22:14:09 2024 +0200
Commit: Armin Le Grand 
CommitDate: Wed Aug 28 21:01:30 2024 +0200

CairoSDPR: Use integer & shifting in LuminanceToAlpha conversion

Change-Id: I8a6b6341295487d7590d166d327ea90b7d1315db
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172480
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 5379f751f30f..f8a786fa7870 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -759,13 +759,64 @@ void LuminanceToAlpha(cairo_surface_t* pMask)
 
 unsigned char* mask_surface_data(cairo_image_surface_get_data(pMask));
 
-// include/basegfx/color/bcolormodifier.hxx
-constexpr double nRedMul(0.2125 / 255.0);
-constexpr double nGreenMul(0.7154 / 255.0);
-constexpr double nBlueMul(0.0721 / 255.0);
+// change to unsigned 16bit and shifting. This is not much
+// faster on modern processors due to nowadays good double/
+// float HW, but may also be used on smaller HW (ARM, ...).
+// Since source is sal_uInt8 integer using double (see version
+// before) is not required numerically either.
+// scaling values are now put to a 256 entry lookup for R, G and B
+// thus 768 bytes, so no multiplications have to happen. The values
+// used to create these are (54+183+18 == 255):
+//sal_uInt16 nR(0.2125 * 256.0); // -> 54.4
+//sal_uInt16 nG(0.7154 * 256.0); // -> 183.1424
+//sal_uInt16 nB(0.0721 * 256.0); // -> 18.4576
+// and the short loop (for nR, nG and nB resp.) like:
+//for(unsigned short a(0); a < 256; a++)
+//std::cout << ((a * nR) / 255) << ", ";
+constexpr std::array nRArray
+= { 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3, 
 3,  3,  4,  4,  4,
+4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,  7,  7,  8, 
 8,  8,  8,  8,  9,
+9,  9,  9,  9,  10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 
12, 12, 13, 13, 13, 13,
+13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 
17, 17, 17, 18, 18, 18,
+18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 
22, 22, 22, 22, 22, 23,
+23, 23, 23, 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 
26, 26, 27, 27, 27, 27,
+27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 
31, 31, 31, 31, 32, 32,
+32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 
36, 36, 36, 36, 36, 37,
+37, 37, 37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 
40, 40, 41, 41, 41, 41,
+41, 42, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 
45, 45, 45, 45, 46, 46,
+46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 
49, 50, 50, 50, 50, 51,
+51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 54 };
+constexpr std::array nGArray
+= { 0,   0,   1,   2,   2,   3,   4,   5,   5,   6,   7,   7,   8,   
9,   10,  10,
+11,  12,  12,  13,  14,  15,  15,  16,  17,  17,  18,  19,  20,  
20,  21,  22,
+22,  23,  24,  25,  25,  26,  27,  27,  28,  29,  30,  30,  31,  
32,  33,  33,
+34,  35,  35,  36,  37,  38,  38,  39,  40,  40,  41,  42,  43,  
43,  44,  45,
+45,  46,  47,  48,  48,  49,  50,  50,  51,  52,  53,  53,  54,  
55,  55,  56,
+57,  58,  58,  59,  60,  61,  61,  62,  63,  63,  64,  65,  66,  
66,  67,  68,
+68,  69,  70,  71,  71,  72,  73,  73,  74,  75,  76,  76,  77,  
78,  78,  79,
+80,  81,  81,  82,  83,  83,  84,  85,  86,  86,  87,  88,  88,  
89,  90,  91,
+91,  92,  93,  94,  94,  95,  96,  96,  97,  98,  99,  99,  100, 
101, 101, 102,
+103, 104, 104, 105, 106, 106, 107, 108, 109, 109, 110, 111, 111, 
112, 113, 114,
+114, 115, 116, 116, 117, 118, 119, 119, 120, 121, 122, 122, 123, 
124, 124, 125,
+126, 127, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 
135, 136, 137,
+137, 138, 139, 139, 140, 141, 142, 142, 143, 144, 144, 145, 146, 
147, 147, 148,
+149, 149, 150, 151, 152, 152, 153, 154, 155, 155, 156, 157, 157, 
158, 159, 160,
+160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 167, 168, 169, 
170, 170, 171,
+172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 180, 180, 
181, 182, 183 };
+constexpr std::array nBArray
+= { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1, 
 1,  1,  1,  1,  1,
+1,  1,  1, 

core.git: drawinglayer/source

2024-08-27 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/processor2dtools.cxx |   21 ---
 1 file changed, 18 insertions(+), 3 deletions(-)

New commits:
commit bf3cd8e50f886084500e3a8ff72ff4ffab05ddd7
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Aug 26 14:25:19 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Aug 27 13:05:19 2024 +0200

CairoSDPR: Make using SDPR dependent of ExperimentalMode

Change-Id: Ia25fe2f3c5ff4904530ea8c296d10bbbe2823af5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172394
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/processor2dtools.cxx 
b/drawinglayer/source/processor2d/processor2dtools.cxx
index 585f312c7c60..742115f0b156 100644
--- a/drawinglayer/source/processor2d/processor2dtools.cxx
+++ b/drawinglayer/source/processor2d/processor2dtools.cxx
@@ -27,6 +27,7 @@
 #include 
 #elif USE_HEADLESS_CODE
 #include 
+#include 
 #endif
 
 namespace drawinglayer::processor2d
@@ -35,10 +36,23 @@ std::unique_ptr 
createPixelProcessor2DFromOutputDevice(
 OutputDevice& rTargetOutDev,
 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D)
 {
-static const bool bTestSystemPrimitiveRenderer(nullptr != 
std::getenv("TEST_SYSTEM_PRIMITIVE_RENDERER"));
-if(bTestSystemPrimitiveRenderer)
+static bool bUsePrimitiveRenderer(
+#if defined(_WIN32)
+// Windows: make still dependent on TEST_SYSTEM_PRIMITIVE_RENDERER
+nullptr != std::getenv("TEST_SYSTEM_PRIMITIVE_RENDERER")
+#elif USE_HEADLESS_CODE
+// Linux/Cairo: make dependent on ExperimentalMode now
+officecfg::Office::Common::Misc::ExperimentalMode::get()
+#else
+// all others: do not use, not (yet) supported
+false
+#endif
+);
+
+if(bUsePrimitiveRenderer)
 {
 drawinglayer::geometry::ViewInformation2D 
aViewInformation2D(rViewInformation2D);
+
 // if mnOutOffX/mnOutOffY is set (a 'hack' to get a cheap additional 
offset), apply it additionally
 if(0 != rTargetOutDev.GetOutOffXPixel() || 0 != 
rTargetOutDev.GetOutOffYPixel())
 {
@@ -46,6 +60,7 @@ std::unique_ptr 
createPixelProcessor2DFromOutputDevice(
 aTransform.translate(rTargetOutDev.GetOutOffXPixel(), 
rTargetOutDev.GetOutOffYPixel());
 aViewInformation2D.setViewTransformation(aTransform);
 }
+
 #if defined(_WIN32)
 SystemGraphicsData aData(rTargetOutDev.GetSystemGfxData());
 std::unique_ptr aRetval(
@@ -61,7 +76,7 @@ std::unique_ptr 
createPixelProcessor2DFromOutputDevice(
 #endif
 }
 
-// create Pixel Vcl-Processor
+// default: create Pixel Vcl-Processor
 return std::make_unique(rViewInformation2D, 
rTargetOutDev);
 }
 


core.git: drawinglayer/Library_drawinglayer.mk drawinglayer/source svx/source

2024-08-24 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/Library_drawinglayer.mk |1 
 drawinglayer/source/processor2d/helperwrongspellrenderer.cxx |   78 ---
 drawinglayer/source/processor2d/helperwrongspellrenderer.hxx |   47 --
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx  |   19 --
 drawinglayer/source/processor2d/vclpixelprocessor2d.hxx  |2 
 svx/source/svdraw/svdotextdecomposition.cxx  |6 
 6 files changed, 153 deletions(-)

New commits:
commit 79ab5c3775f8d0685585810583b84c0f4d49a1bf
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Aug 23 20:59:55 2024 +0200
Commit: Armin Le Grand 
CommitDate: Sat Aug 24 15:10:45 2024 +0200

CairoSDPR: Let VclPixelProcessor2D use RedLining decompose

VclPixelProcessor2D used PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D
to render WrongSpellPrimitive2D using processWrongSpellPrimitive2D
and there renderWrongSpellPrimitive2D. That again used
DrawWaveLine at OutputDevice.

This again does some very special things, e.g. it uses the set
Font at the OutputDevice which hopefully is the one the
redlining refers to (info from that has to be added to the
WrongSpellPrimitive2D if needed, in this case the
LogicalFontInstance's GetWavelineUnderlineSize result). It
seems to rely on the Text being redlined being 'painted'
directly before this.
It also renders the WaveLine to a BitmapEx and does pixel-
based operations on it (probably to 'clip' the WaveLine instead
of adding needed partial curve geometry), and adds that
BitmapData to a cache.
It also mentions it 'make sure the waveline does not exceed the
descent to avoid paint problems', probably because when not
handling it as Primitive from a PrimitiveProcessor the
invalidation Range will not fit (it still uses the getB2DRange
of the WrongSpellPrimitive2D to do that part indirectly), so
these regions will probably not always have fit.

Nothing of this is needed, after I made the
WrongSpellPrimitive2D to use view-independent (aka pixel-
oriented scaling, fixed size) to behave like the current paint
the VclPixelProcessor2D can just use the decompose and render
the view-dependent and buffered visualization of the WaveLine.

NOTE: It is not possible to completely get rid of
OutputDevice::DrawWaveLine since it is used in some cases in
Writer directly, also in ImpEditEngine::Paint when the
EditEngine is painting directly (very rare now).

NOTE: Also impCreateTextPortionPrimitive did swap start/end
in preparationm to create a WrongSpellPrimitive2D (look for
tdf#151968), this will no longer be needed.

Change-Id: I31aec8ea9c2e3c574ad471082612a10d95810f3b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172331
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index e8e3dde7c952..6409e379df6b 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -194,7 +194,6 @@ $(eval $(call 
gb_Library_add_exception_objects,drawinglayer,\
 drawinglayer/source/processor2d/processor2dtools \
 drawinglayer/source/processor2d/contourextractor2d \
 drawinglayer/source/processor2d/getdigitlanguage \
-drawinglayer/source/processor2d/helperwrongspellrenderer \
 drawinglayer/source/processor2d/hittestprocessor2d \
 drawinglayer/source/processor2d/linegeometryextractor2d \
 drawinglayer/source/processor2d/objectinfoextractor2d \
diff --git a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx 
b/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx
deleted file mode 100644
index d4f14a13ce6c..
--- a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include "helperwrongspellrenderer.hxx"
-#include 
-#include 
-#include 
-#include 
-#include 
-
-using namespace css;
-
-namespace drawinglayer
-{
-namespace
-{
-constexpr sa

core.git: drawinglayer/source include/basegfx include/drawinglayer

2024-08-23 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx  |  102 +
 include/basegfx/curve/b2dcubicbezier.hxx   |2 
 include/drawinglayer/primitive2d/wrongspellprimitive2d.hxx |4 
 3 files changed, 81 insertions(+), 27 deletions(-)

New commits:
commit 8bdddee0897034976bbbea57eedf4c7611228d5d
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Aug 23 14:39:34 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Aug 23 16:36:59 2024 +0200

CairoSDPR: Adapt WrongSpell Primitive to View-Independent

Change-Id: If739dd9f28f56874978c7b3a76e1234e5f430c9f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172319
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx 
b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx
index 6084814ae71f..b583dd9901a1 100644
--- a/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx
@@ -19,9 +19,10 @@
 
 #include 
 #include 
-#include 
+#include 
+#include 
+#include 
 #include 
-#include 
 #include 
 
 
@@ -29,43 +30,95 @@ namespace drawinglayer::primitive2d
 {
 Primitive2DReference 
WrongSpellPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 
/*rViewInformation*/) const
 {
-// ATM this decompose is view-independent, what the original 
VCL-Display is not. To mimic
-// the old behaviour here if wanted it is necessary to add 
get2DDecomposition and implement
-// it similar to the usage in e.g. HelplinePrimitive2D. 
Remembering the ViewTransformation
-// should be enough then.
-// The view-independent wavelines work well (if You ask me). Maybe 
the old VCL-Behaviour is only
-// in place because it was not possible/too expensive at that time 
to scale the wavelines with the
-// view...
-// With the VCL-PixelRenderer this will not even be used since it 
implements WrongSpellPrimitive2D
-// directly and mimics the old VCL-Display there. If You 
implemented a new renderer without
-// direct WrongSpellPrimitive2D support, You may want to do the 
described change here.
+// This *was* a view-independent primitive before (see before this 
commit),
+// but was never really used, but handled in various processors 
anyways.
+// Since the current VCL primitve renderer and it's functions used 
in
+// VCL do render this always in one discrete pixel size I decided 
to
+// adapt this primitive to do that, too, but - due to being a 
primitive -
+// with the correct invalidate/hit-ranges etc.
+// I use here DiscreteMetricDependentPrimitive2D which already 
implements
+// buffering and providing the discrete size using 
'getDiscreteUnit()' plus
+// the needed updates to buffering, what makes the rest simple.
+// NOTE: If one day the (in my opinion) also good looking 
view-independent
+// version should be needed again, just revert this change
+if (basegfx::fTools::lessOrEqual(getStop(), getStart()))
+{
+// stop smaller or equal to start, done
+return nullptr;
+}
 
 // get the font height (part of scale), so decompose the matrix
 basegfx::B2DVector aScale, aTranslate;
 double fRotate, fShearX;
 getTransformation().decompose(aScale, aTranslate, fRotate, 
fShearX);
 
+constexpr double constMinimumFontHeight(5.0);
+if (aScale.getY() / getDiscreteUnit() < constMinimumFontHeight)
+{
+// font height smaller constMinimumFontHeight pixels -> 
decompose to empty
+return nullptr;
+}
+
 // calculate distances based on a static default (to allow testing 
in debugger)
 static const double fDefaultDistance(0.03);
 const double fFontHeight(aScale.getY());
 const double fUnderlineDistance(fFontHeight * fDefaultDistance);
-const double fWaveWidth(2.0 * fUnderlineDistance);
 
 // the Y-distance needs to be relative to FontHeight since the 
points get
 // transformed with the transformation containing that scale 
already.
 const double 
fRelativeUnderlineDistance(basegfx::fTools::equalZero(aScale.getY()) ? 0.0 : 
fUnderlineDistance / aScale.getY());
-basegfx::B2DPoint aStart(getStart(), fRelativeUnderlineDistance);
-basegfx::B2DPoint aStop(getStop(), fRelativeUnderlineDistance);
-basegfx::B2DPolygon aPolygon;
 
-aPolygon.append(getTransformation() * aStart);
-aPolygon.append(getTransformation() * aStop);
+// get start/stop positions and WaveLength, base all calculations 
for

core.git: drawinglayer/source include/drawinglayer

2024-08-22 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/svggradientprimitive2d.cxx  |  203 +-
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx   |  223 
 include/drawinglayer/primitive2d/svggradientprimitive2d.hxx |   22 -
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx  |   10 
 4 files changed, 351 insertions(+), 107 deletions(-)

New commits:
commit 13366d4951bd4ed92cdeed3c8fdeb1ab0543a3db
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Aug 22 12:13:55 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Aug 22 21:11:00 2024 +0200

CairoSDPR: Add support for SVG Gradient direct rendering

Change-Id: I7fb1c885e46a23e999ea4c98a73d3d526a2923e5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172245
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx 
b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
index 69881695a22b..4b8a5cb4ab86 100644
--- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -104,7 +104,6 @@ namespace drawinglayer::primitive2d
 
 void SvgGradientHelper::checkPreconditions()
 {
-mbPreconditionsChecked = true;
 const SvgGradientEntryVector& rEntries = getGradientEntries();
 
 if(rEntries.empty())
@@ -356,7 +355,6 @@ namespace drawinglayer::primitive2d
 maGradientEntries(std::move(rGradientEntries)),
 maStart(rStart),
 maSpreadMethod(aSpreadMethod),
-mbPreconditionsChecked(false),
 mbCreatesContent(false),
 mbSingleEntry(false),
 mbFullyOpaque(true),
@@ -468,13 +466,56 @@ namespace drawinglayer::primitive2d
 }
 }
 
-Primitive2DReference 
SvgLinearGradientPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
+basegfx::B2DHomMatrix 
SvgLinearGradientPrimitive2D::createUnitGradientToObjectTransformation() const
 {
-if(!getPreconditionsChecked())
+const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+const double fPolyWidth(aPolyRange.getWidth());
+const double fPolyHeight(aPolyRange.getHeight());
+
+// create ObjectTransform based on polygon range
+const basegfx::B2DHomMatrix aObjectTransform(
+basegfx::utils::createScaleTranslateB2DHomMatrix(
+fPolyWidth, fPolyHeight,
+aPolyRange.getMinX(), aPolyRange.getMinY()));
+basegfx::B2DHomMatrix aUnitGradientToObject;
+
+if(getUseUnitCoordinates())
 {
-const_cast< SvgLinearGradientPrimitive2D* 
>(this)->checkPreconditions();
+// interpret in unit coordinate system -> object aspect ratio 
will scale result
+// create unit transform from unit vector [0.0 .. 1.0] along 
the X-Axis to given
+// gradient vector defined by Start,End
+const basegfx::B2DVector aVector(getEnd() - getStart());
+const double fVectorLength(aVector.getLength());
+
+aUnitGradientToObject.scale(fVectorLength, 1.0);
+aUnitGradientToObject.rotate(atan2(aVector.getY(), 
aVector.getX()));
+aUnitGradientToObject.translate(getStart().getX(), 
getStart().getY());
+
+aUnitGradientToObject *= getGradientTransform();
+
+// create full transform from unit gradient coordinates to 
object coordinates
+// including the SvgGradient transformation
+aUnitGradientToObject *= aObjectTransform;
+}
+else
+{
+// interpret in object coordinate system -> object aspect 
ratio will not scale result
+const basegfx::B2DPoint aStart(aObjectTransform * getStart());
+const basegfx::B2DPoint aEnd(aObjectTransform * getEnd());
+const basegfx::B2DVector aVector(aEnd - aStart);
+
+aUnitGradientToObject.scale(aVector.getLength(), 1.0);
+aUnitGradientToObject.rotate(atan2(aVector.getY(), 
aVector.getX()));
+aUnitGradientToObject.translate(aStart.getX(), aStart.getY());
+
+aUnitGradientToObject *= getGradientTransform();
 }
 
+return aUnitGradientToObject;
+}
+
+Primitive2DReference 
SvgLinearGradientPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
+{
 if(getSingleEntry())
 {
 // fill with last existing color
@@ -484,48 +525,7 @@ namespace drawinglayer::primitive2d
 {
 // at least two color stops in range [0.0 .. 1.0], sorted, 
non-null vector, not completely
 // invisib

core.git: drawinglayer/source

2024-08-20 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |   31 +-
 1 file changed, 30 insertions(+), 1 deletion(-)

New commits:
commit b3c7c30ca1e9102be7246d97792147997b5696a2
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Aug 20 14:23:53 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Aug 20 20:58:11 2024 +0200

CairoSDPR: Finetuning some Cairo-Values

Experimented with painting 'problematic' bitmaps
e.g. RGBA 1xN or Nx1 pixels -> Cairo paints out of
bounds (?), so had to clip that. For more info,
see added code comments.

Change-Id: I4dcd488e5e0c692e236136a216ad7b460d681233
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172112
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 5fbc9dfc2749..b5f56007cb77 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -825,6 +825,7 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const 
geometry::ViewInformation2D&
 cairo_set_antialias(pRT, rViewInformation.getUseAntiAliasing() ? 
CAIRO_ANTIALIAS_DEFAULT
: 
CAIRO_ANTIALIAS_NONE);
 cairo_set_fill_rule(pRT, CAIRO_FILL_RULE_EVEN_ODD);
+cairo_set_operator(pRT, CAIRO_OPERATOR_OVER);
 setRenderTarget(pRT);
 }
 }
@@ -955,10 +956,18 @@ void CairoPixelProcessor2D::paintBitmapAlpha(const 
BitmapEx& rBitmapEx,
 // insert a ARGB image, zoom to the borders. Seems to be half
 // a pixel. Very good to demonstrate: 8x1 pixel, some
 // transparent.
+// Also errors with images 1 pixel wide/high, e.g. insert
+// RGBA 8x1, 1x8 to see (and deactivate fix below). It also
+// depends on the used filter, see commnet below at
+// cairo_pattern_set_filter. Found also errors with more
+// than one pixel, so cannot use as criteria.
 // This effect is also visible in the left/right/bottom/top
 // page shadows, these DO use 8x1/1x8 images which led me to
-// that problem. I see two solutions:
+// that problem. I double-checked that these *are* correctly
+// defined, that is not the problem.
+// I see two solutions:
 static bool bRenderMasked(true);
+
 if (bRenderMasked)
 {
 // Consequence is that these need clipping. That again is
@@ -989,6 +998,22 @@ void CairoPixelProcessor2D::paintBitmapAlpha(const 
BitmapEx& rBitmapEx,
 }
 }
 
+// The error/effect described above also is connected to the
+// filter used, so I checked the filter modes available
+// in Cairo:
+//
+// CAIRO_FILTER_FAST: okay, small errors, sometimes stretching some pixels
+// CAIRO_FILTER_GOOD: stretching error
+// CAIRO_FILTER_BEST: okay, small errors
+// CAIRO_FILTER_NEAREST: similar to CAIRO_FILTER_FAST
+// CAIRO_FILTER_BILINEAR: similar to CAIRO_FILTER_GOOD
+// CAIRO_FILTER_GAUSSIAN: same as CAIRO_FILTER_GOOD/CAIRO_FILTER_BILINEAR, 
should
+//   not be used anyways (see docs)
+//
+// CAIRO_FILTER_GOOD seems to be the default anyways, but set it
+// to be on the safe side
+cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_GOOD);
+
 cairo_pattern_set_matrix(sourcepattern, &aMatrix);
 
 // paint bitmap data, evtl. with additional alpha channel
@@ -1970,6 +1995,10 @@ void 
CairoPixelProcessor2D::processFillGraphicPrimitive2D(
 cairo_pattern_set_matrix(sourcepattern, &aMatrix);
 cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT);
 
+// CAIRO_FILTER_GOOD seems to be the default anyways, but set it
+// to be on the safe side
+cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_GOOD);
+
 // paint
 if (rFillGraphicPrimitive2D.hasTransparency())
 cairo_paint_with_alpha(mpRT, 1.0 - 
rFillGraphicPrimitive2D.getTransparency());


core.git: 2 commits - drawinglayer/source vcl/inc vcl/source

2024-08-19 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |8 
 vcl/inc/sallayout.hxx |2 ++
 vcl/source/gdi/sallayout.cxx  |8 
 3 files changed, 14 insertions(+), 4 deletions(-)

New commits:
commit 19cea16244956382f7e985c934c008392e13552f
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Aug 19 17:38:52 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Aug 19 19:51:52 2024 +0200

CairoSDPR: Make PixelSnap better aligned

Change-Id: I64ca3e6bd0690ea14e95f3ed0969c320a45f30d6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172043
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 3f2df4822b23..5fbc9dfc2749 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -329,12 +329,12 @@ void checkAndDoPixelSnap(cairo_t* pRT,
 // transform to discrete pixels
 cairo_user_to_device(pRT, pX, pY);
 
-// round them, also subtract 0.5 which will be as transform in
+// round them, also add 0.5 which will be as transform in
 // the paint method to move to 'inside' pixels when AA used.
 // remember: this is only done when AA is active (see 
bPixelSnap
-// above)
-*pX = basegfx::fround(*pX) - 0.5;
-*pY = basegfx::fround(*pY) - 0.5;
+// above) and moves the hairline to full-pixel position
+*pX = trunc(*pX) + 0.5;
+*pY = trunc(*pY) + 0.5;
 
 // transform back to former transformed state
 cairo_device_to_user(pRT, pX, pY);
commit fe27013495d58beedf982414bbd00f6ea577ff81
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Aug 19 14:57:06 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Aug 19 19:51:42 2024 +0200

CairoSDPR: Text render needs MultiSalLayout support

Change-Id: I418675012392a9707dc515eb1e05a2689ec902aa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172039
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 6b299322441e..ed539f058402 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -90,6 +90,8 @@ public:
 
 SAL_DLLPRIVATE virtual ~MultiSalLayout() override;
 
+virtual void drawSalLayout(void* /*pSurface*/, const basegfx::BColor& 
/*rTextColor*/, bool /*bAntiAliased*/) const override;
+
 private:
 MultiSalLayout( const MultiSalLayout& ) = delete;
 MultiSalLayout& operator=( const MultiSalLayout& ) = 
delete;
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 9e2c0b66b9f9..1a63504ecc88 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -1277,4 +1277,12 @@ SalLayoutGlyphs MultiSalLayout::GetGlyphs() const
 return glyphs;
 }
 
+void MultiSalLayout::drawSalLayout(void* pSurface, const basegfx::BColor& 
rTextColor, bool bAntiAliased) const
+{
+for( int i = mnLevel; --i >= 0; )
+{
+
Application::GetDefaultDevice()->GetGraphics()->DrawSalLayout(*mpLayouts[ i ], 
pSurface, rTextColor, bAntiAliased);
+}
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


core.git: drawinglayer/source include/drawinglayer

2024-08-16 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx  |   70 +-
 drawinglayer/source/primitive2d/textprimitive2d.cxx   |   24 ++
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |  102 +-
 include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx |5 
 include/drawinglayer/primitive2d/textprimitive2d.hxx  |6 
 5 files changed, 143 insertions(+), 64 deletions(-)

New commits:
commit cd6529a0501d49e0cd6344523d509fa7186687c9
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Aug 15 17:30:23 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Aug 16 14:44:11 2024 +0200

CairoSDPR: Add support for Relief for Text Rendering

Change-Id: Idcb33e0f799b2219a4e737d0421bc21d85b5c7aa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171915
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 2f0792fb7aa0..bfa5ebbb7eea 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -120,6 +120,11 @@ namespace drawinglayer::primitive2d
 
 if(bOverlineUsed)
 {
+// for Relief we have to manipulate the OverlineColor
+basegfx::BColor aOverlineColor(getOverlineColor());
+if (hasTextRelief() && COL_BLACK.getBColor() == aOverlineColor)
+aOverlineColor = COL_WHITE.getBColor();
+
 // create primitive geometry for overline
 maBufferedDecorationGeometry.push_back(
 new TextLinePrimitive2D(
@@ -128,11 +133,16 @@ namespace drawinglayer::primitive2d
 aTextLayouter.getOverlineOffset(),
 aTextLayouter.getOverlineHeight(),
 getFontOverline(),
-getOverlineColor()));
+aOverlineColor));
 }
 
 if(bUnderlineUsed)
 {
+// for Relief we have to manipulate the TextlineColor
+basegfx::BColor aTextlineColor(getTextlineColor());
+if (hasTextRelief() && COL_BLACK.getBColor() == aTextlineColor)
+aTextlineColor = COL_WHITE.getBColor();
+
 // create primitive geometry for underline
 maBufferedDecorationGeometry.push_back(
 new TextLinePrimitive2D(
@@ -141,11 +151,16 @@ namespace drawinglayer::primitive2d
 aTextLayouter.getUnderlineOffset(),
 aTextLayouter.getUnderlineHeight(),
 getFontUnderline(),
-getTextlineColor()));
+aTextlineColor));
 }
 
 if(bStrikeoutUsed)
 {
+// for Relief we have to manipulate the FontColor
+basegfx::BColor aFontColor(getFontColor());
+if (hasTextRelief() && COL_BLACK.getBColor() == aFontColor)
+aFontColor = COL_WHITE.getBColor();
+
 // create primitive geometry for strikeout
 if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || 
TEXT_STRIKEOUT_X == getTextStrikeout())
 {
@@ -156,7 +171,7 @@ namespace drawinglayer::primitive2d
 new TextCharacterStrikeoutPrimitive2D(
 rDecTrans.getB2DHomMatrix(),
 fTextWidth,
-getFontColor(),
+aFontColor,
 aStrikeoutChar,
 getFontAttribute(),
 getLocale()));
@@ -168,7 +183,7 @@ namespace drawinglayer::primitive2d
 new TextGeometryStrikeoutPrimitive2D(
 rDecTrans.getB2DHomMatrix(),
 fTextWidth,
-getFontColor(),
+aFontColor,
 aTextLayouter.getUnderlineHeight(),
 aTextLayouter.getStrikeoutOffset(),
 getTextStrikeout()));
@@ -182,6 +197,11 @@ namespace drawinglayer::primitive2d
 
 if (pSalLayout)
 {
+// for Relief we have to manipulate the FontColor
+basegfx::BColor aFontColor(getFontColor());
+if (hasTextRelief() && COL_BLACK.getBColor() == aFontColor)
+aFontColor = COL_WHITE.getBColor();
+
 // placeholders for repeated content, only created once
 Primitive2DReference aShape;
 Primitive2DReference aRect1;
@@ -198,7 +218,7 @@ namespace drawinglayer::primitive2d
 
 // the callback from Outpu

core.git: drawinglayer/source include/drawinglayer

2024-08-15 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx |   10 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx|  149 +++
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx   |   12 
 3 files changed, 117 insertions(+), 54 deletions(-)

New commits:
commit 6ab0c616d72f224c5de87b8afd2b228c223bb056
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Aug 15 11:29:28 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Aug 15 16:05:41 2024 +0200

CairoSDPR: Add outline to direct text rendering

Change-Id: I8c8820066a402653bf0f49bd78a98be692530e42
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171892
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx
index 41f7299c4486..497f8c2dbe40 100644
--- a/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx
@@ -211,11 +211,11 @@ namespace drawinglayer::primitive2d
 aTransform.rotate(fRotate);
 aTransform.translate(aTranslate.getX(), aTranslate.getY());
 
-// add transform primitive
-xRetval =
-new TransformPrimitive2D(
-aTransform,
-Primitive2DContainer{xRetval});
+// add original and transform primitive to a GroupPrimitive2D
+xRetval = new GroupPrimitive2D({
+xRetval, new TransformPrimitive2D(
+aTransform,
+Primitive2DContainer{xRetval}) });
 }
 
 return xRetval;
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index dfbce4af0c70..942a07290ece 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -2932,7 +2932,7 @@ void CairoPixelProcessor2D::renderTextBackground(
 void CairoPixelProcessor2D::renderSalLayout(const std::unique_ptr& 
rSalLayout,
 const basegfx::BColor& rTextColor,
 const basegfx::B2DHomMatrix& 
rTransform,
-bool bAntiAliase)
+bool bAntiAliase) const
 {
 cairo_save(mpRT);
 cairo_matrix_t aMatrix;
@@ -2943,34 +2943,13 @@ void CairoPixelProcessor2D::renderSalLayout(const 
std::unique_ptr& rS
 cairo_restore(mpRT);
 }
 
-void CairoPixelProcessor2D::renderShadowTextDecoration(
-const basegfx::BColor& rShadowColor, const basegfx::B2DHomMatrix& 
rShadowObjectTransform,
+void CairoPixelProcessor2D::renderTextDecorationWithOptionalTransformAndColor(
 const primitive2d::TextDecoratedPortionPrimitive2D& rDecoratedCandidate,
-const basegfx::utils::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans)
+const basegfx::utils::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans,
+const basegfx::B2DHomMatrix* pOptionalObjectTransform, const 
basegfx::BColor* pReplacementColor)
 {
-// modify ColorStack as needed
-
maBColorModifierStack.push(std::make_shared(rShadowColor));
-
-// modify transformation as needed
-const geometry::ViewInformation2D 
aLastViewInformation2D(getViewInformation2D());
-geometry::ViewInformation2D aViewInformation2D(getViewInformation2D());
-aViewInformation2D.setObjectTransformation(rShadowObjectTransform);
-updateViewInformation(aViewInformation2D);
-
-// render same primitives as for non-shadow, but with mods set above
-renderTextDecoration(rDecoratedCandidate, rDecTrans);
-
-// restore mods
-updateViewInformation(aLastViewInformation2D);
-maBColorModifierStack.pop();
-}
-
-void CairoPixelProcessor2D::renderTextDecoration(
-const primitive2d::TextDecoratedPortionPrimitive2D& rDecoratedCandidate,
-const basegfx::utils::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans)
-{
-// get decorations from Primitive, guaranteed the same as
-// a decomposition would create
+// get decorations from Primitive (using original TextTransform),
+// guaranteed the same visualization as a decomposition would create
 const primitive2d::Primitive2DContainer& rDecorationGeometryContent(
 rDecoratedCandidate.getOrCreateDecorationGeometryContent(
 rDecTrans, rDecoratedCandidate.getText(), 
rDecoratedCandidate.getTextPosition(),
@@ -2982,7 +2961,28 @@ void CairoPixelProcessor2D::renderTextDecoration(
 return;
 }
 
+// modify ColorStack as needed - if needed
+if (nullptr != pReplacementColor)
+maBColorModifierStack.push(
+
std::make_shared(*pReplacementColor));
+
+// modify transformation as needed - if needed
+const geometry::Vie

core.git: drawinglayer/source include/drawinglayer include/vcl vcl/Library_vcl.mk vcl/source

2024-08-14 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/Tools.cxx  |2 
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx   |  117 
--
 drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx   |   12 +
 drawinglayer/source/primitive2d/textlayoutdevice.cxx   |   45 +++
 drawinglayer/source/primitive2d/textprimitive2d.cxx|   51 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   81 
++
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |7 
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx |1 
 include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx  |   10 
 include/drawinglayer/primitive2d/textlayoutdevice.hxx  |   13 +
 include/drawinglayer/primitive2d/textprimitive2d.hxx   |   14 +
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |2 
 include/vcl/outdev.hxx |7 
 vcl/Library_vcl.mk |1 
 vcl/source/outdev/EmphasisMarks.cxx|  100 

 15 files changed, 388 insertions(+), 75 deletions(-)

New commits:
commit 4a0cd8990467466a04bafd7bb1a780247535ab83
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Aug 13 14:50:24 2024 +0200
Commit: Armin Le Grand 
CommitDate: Wed Aug 14 10:48:51 2024 +0200

CairoSDPR: Handle EmphasisMarks

Handling EmphasisMarks for direct text rendering
was a hard task - the EmphasisMark stuff is deeply
buried in vcl (would have needed to move quite some
includes from vcl to public) and thus hard to use.
It is also quite old (tools Polygon, Rectangle).

It was missing in the decomposition of the
TextDecoratedPortionPrimitive2D (for good reason),
but is needed now.

I found a way using a callback lambda function to
create the needed geometry in vcl and hand back the
needed data to the caller, in this case to the
decomposition. Adding it to the decomposition of
TextDecoratedPortionPrimitive2D also guarantees
that other renderers/usages will do the correct
thing and all will look identical.

Interestingly EmphasisMarks were never added to
Metafiles (see OutputDevice::ImplDrawEmphasisMarks)
so they were not 'missing' in Metafile-based
exports. But for SDPRs they have to work. I added
another encapsulating TextHierarchyPrimitive to
encapsulate primitives that do represent
EmphasisMarks and added to ignore these in the
VclMetafileProcessor2D (as needed).

Change-Id: I5b5c1528d86a123df2beb57d8366f05aa71e77cf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171826
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/Tools.cxx 
b/drawinglayer/source/primitive2d/Tools.cxx
index 52545212b8cc..e1c3dfe96e80 100644
--- a/drawinglayer/source/primitive2d/Tools.cxx
+++ b/drawinglayer/source/primitive2d/Tools.cxx
@@ -241,6 +241,8 @@ OUString idToString(sal_uInt32 nId)
 return u"BITMAPALPHAPRIMITIVE2D"_ustr;
 case PRIMITIVE2D_ID_POLYPOLYGONALPHAGRADIENTPRIMITIVE2D:
 return u"POLYPOLYGONALPHAGRADIENTPRIMITIVE2D"_ustr;
+case PRIMITIVE2D_ID_TEXTHIERARCHYEMPHASISMARKPRIMITIVE2D:
+return u"TEXTHIERARCHYEMPHASISMARKPRIMITIVE2D"_ustr;
 default:
 return OUString::number((nId >> 16) & 0xFF) + "|" + 
OUString::number(nId & 0xFF);
 }
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 41a09c5968ea..d500e4476785 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -22,10 +22,14 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-
+#include 
 
 namespace drawinglayer::primitive2d
 {
@@ -75,8 +79,10 @@ namespace drawinglayer::primitive2d
 const bool bOverlineUsed(TEXT_LINE_NONE != getFontOverline());
 const bool bUnderlineUsed(TEXT_LINE_NONE != getFontUnderline());
 const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != 
getTextStrikeout());
+const bool bEmphasisMarkUsed(TEXT_FONT_EMPHASIS_MARK_NONE != 
getTextEmphasisMark()
+&& (getEmphasisMarkAbove() || getEmphasisMarkBelow()));
 
-if(!(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed))
+if(!(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed || 
bEmphasisMarkUsed))
 {
 // not used, return empty Primitive2DContainer
 return maBufferedDecorationGeometry;
@@ -88,16 +94,9 @@ namespace drawinglayer::primitive2d
 return maBufferedDecorationGeometry;
 }
 
-// common preparations
-  

core.git: drawinglayer/source include/drawinglayer svx/source

2024-08-09 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx  |  137 +++--
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |  251 +++---
 include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx |   13 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx|   29 +
 svx/source/sdr/properties/textproperties.cxx  |   16 
 svx/source/svdraw/svdotextdecomposition.cxx   |   34 -
 6 files changed, 341 insertions(+), 139 deletions(-)

New commits:
commit 4c1aa38025d79400e0aa539fba2ba8c3f51316f5
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Aug 9 12:53:47 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Aug 9 21:18:42 2024 +0200

CairoSDPR: Support TextDecoration

Change-Id: I923069582bb7c5022cfbff7e869c1d577a9123ce
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171691
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 125b1e735cc8..41a09c5968ea 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -52,13 +52,19 @@ namespace drawinglayer::primitive2d
 getLocale(),
 getFontColor()));
 
-CreateDecorationGeometryContent(rTarget, rDecTrans, rText,
-nTextPosition, nTextLength,
-rDXArray);
+// create and add decoration
+const Primitive2DContainer& rDecorationGeometryContent(
+getOrCreateDecorationGeometryContent(
+rDecTrans,
+rText,
+nTextPosition,
+nTextLength,
+rDXArray));
+
+rTarget.insert(rTarget.end(), rDecorationGeometryContent.begin(), 
rDecorationGeometryContent.end());
 }
 
-void TextDecoratedPortionPrimitive2D::CreateDecorationGeometryContent(
-Primitive2DContainer& rTarget,
+const Primitive2DContainer& 
TextDecoratedPortionPrimitive2D::getOrCreateDecorationGeometryContent(
 basegfx::utils::B2DHomMatrixBufferedOnDemandDecompose const & 
rDecTrans,
 const OUString& rText,
 sal_Int32 nTextPosition,
@@ -71,7 +77,16 @@ namespace drawinglayer::primitive2d
 const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != 
getTextStrikeout());
 
 if(!(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed))
-return;
+{
+// not used, return empty Primitive2DContainer
+return maBufferedDecorationGeometry;
+}
+
+if (!maBufferedDecorationGeometry.empty())
+{
+// if not empty it is used -> append and return 
Primitive2DContainer
+return maBufferedDecorationGeometry;
+}
 
 // common preparations
 TextLayouterDevice aTextLayouter;
@@ -107,7 +122,7 @@ namespace drawinglayer::primitive2d
 if(bOverlineUsed)
 {
 // create primitive geometry for overline
-rTarget.push_back(
+maBufferedDecorationGeometry.push_back(
 new TextLinePrimitive2D(
 rDecTrans.getB2DHomMatrix(),
 fTextWidth,
@@ -120,7 +135,7 @@ namespace drawinglayer::primitive2d
 if(bUnderlineUsed)
 {
 // create primitive geometry for underline
-rTarget.push_back(
+maBufferedDecorationGeometry.push_back(
 new TextLinePrimitive2D(
 rDecTrans.getB2DHomMatrix(),
 fTextWidth,
@@ -130,60 +145,73 @@ namespace drawinglayer::primitive2d
 getTextlineColor()));
 }
 
-if(!bStrikeoutUsed)
-return;
-
-// create primitive geometry for strikeout
-if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || TEXT_STRIKEOUT_X 
== getTextStrikeout())
+if(bStrikeoutUsed)
 {
-// strikeout with character
-const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == 
getTextStrikeout() ? '/' : 'X');
+// create primitive geometry for strikeout
+if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || 
TEXT_STRIKEOUT_X == getTextStrikeout())
+{
+// strikeout with character
+const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == 
getTextStrikeout() ? '/' : 'X');
+
+maBufferedDecorationGeometry.push_back(
+new TextCharacterStrikeoutPrimitive2D(
+rDecTrans.getB2DHomMatrix(),
+ 

core.git: drawinglayer/Library_drawinglayer.mk drawinglayer/source include/drawinglayer svx/source

2024-08-08 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/Library_drawinglayer.mk |
1 
 drawinglayer/source/primitive2d/PolyPolygonAlphaGradientPrimitive2D.cxx  |  
106 ++
 drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D.cxx   |
6 
 drawinglayer/source/primitive2d/Tools.cxx|
2 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx|   
81 +++
 drawinglayer/source/tools/primitive2dxmldump.cxx |   
13 +
 include/drawinglayer/primitive2d/PolyPolygonAlphaGradientPrimitive2D.hxx |   
87 
 include/drawinglayer/primitive2d/PolyPolygonRGBAPrimitive2D.hxx  |
4 
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx   |
1 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx   |
4 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx |   
32 ++-
 11 files changed, 322 insertions(+), 15 deletions(-)

New commits:
commit ebe1543250b9729a6560545e58f50ea68e62be11
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Aug 8 14:08:22 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Aug 8 18:27:16 2024 +0200

CairoSDPR: Support ColorPolygon with AlphaGradient

Cairo can render RGBA gradients directly and the
CairoSDPR supports that. If we have a PolyPolygon
filled with single color combined with a gradient
alpha the renderer could map RGB to that color
and combine with the real alpha gradient steps.

To support that I added another Primitive called
PolyPolygonAlphaGradientPrimitive2D. It decomposes
as needed (TransparencePrimitive2D if needed), so
no other renderers have to be touched.

The Cairo renderer supports it directly, though,
what makes it much faster.

Change-Id: Ie90c8bd84d6458d12443db815ced55bdea93c15c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171628
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index 7529c34a43b7..e8e3dde7c952 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -144,6 +144,7 @@ $(eval $(call 
gb_Library_add_exception_objects,drawinglayer,\
 drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonColorPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D \
+drawinglayer/source/primitive2d/PolyPolygonAlphaGradientPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D \
diff --git 
a/drawinglayer/source/primitive2d/PolyPolygonAlphaGradientPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonAlphaGradientPrimitive2D.cxx
new file mode 100644
index ..c65785e78bb8
--- /dev/null
+++ b/drawinglayer/source/primitive2d/PolyPolygonAlphaGradientPrimitive2D.cxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace com::sun::star;
+
+namespace drawinglayer::primitive2d
+{
+Primitive2DReference 
PolyPolygonAlphaGradientPrimitive2D::create2DDecomposition(
+const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+if (0 == getB2DPolyPolygon().count())
+{
+// no geometry, done
+return nullptr;
+}
+
+if (getAlphaGradient().isDefault())
+{
+// default is a single ColorStop at 0.0 with black (0, 0, 0). The
+// luminance is then 0.0, too -> not transparent at all
+return new PolyPolygonColorPrimitive2D(getB2DPolyPolygon(), 
getBColor());
+}
+
+basegfx::BColor aSingleColor;
+if (getAlphaGradient().getColorStops().isSingleColor(aSingleColor))
+{
+// no real taransparence gradient, only unified alpha,
+// we can use PolyPolygonRGBAPrimitive2D
+return 

core.git: drawinglayer/source

2024-08-06 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |   21 --
 1 file changed, 13 insertions(+), 8 deletions(-)

New commits:
commit bece17ca694093f9cd19ec99e45f5e603ecd2851
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Aug 5 14:37:25 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Aug 6 16:52:22 2024 +0200

CairoSDPR: Support TextBackgroundFill

Change-Id: Ifa00a230ad88d49ccda7c7f47b3d87870d4dfc3c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171489
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index f6869a97aa1c..62e009e62bc9 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -2859,14 +2859,6 @@ void 
CairoPixelProcessor2D::renderTextSimpleOrDecoratedPortionPrimitive2D(
 return;
 }
 
-// set FillColor Attribute at Font
-Color aFillColor(
-
maBColorModifierStack.getModifiedColor(rTextCandidate.getTextFillColor().getBColor()));
-aFont.SetTransparent(rTextCandidate.getTextFillColor().IsTransparent());
-if (rTextCandidate.getTextFillColor().IsTransparent())
-aFillColor.SetAlpha(rTextCandidate.getTextFillColor().GetAlpha());
-aFont.SetFillColor(aFillColor);
-
 // create integer DXArray. As mentioned above we can act in the
 // Text's local coordinate system without transformation at all
 const ::std::vector& rDXArray(rTextCandidate.getDXArray());
@@ -2933,6 +2925,19 @@ void 
CairoPixelProcessor2D::renderTextSimpleOrDecoratedPortionPrimitive2D(
   aFullTextTransform.c(), aFullTextTransform.d(), 
aFullTextTransform.e(),
   aFullTextTransform.f());
 cairo_set_matrix(mpRT, &aMatrix);
+
+if (!rTextCandidate.getTextFillColor().IsTransparent())
+{
+// TextFillColor is set -> text background is filled, paint it
+const basegfx::BColor aFillColor(
+
maBColorModifierStack.getModifiedColor(rTextCandidate.getTextFillColor().getBColor()));
+cairo_set_source_rgb(mpRT, aFillColor.getRed(), aFillColor.getGreen(),
+ aFillColor.getBlue());
+cairo_rectangle(mpRT, 0.0, -aTextLayouter.getFontAscent(), 
pSalLayout->GetTextWidth(),
+aTextLayouter.getTextHeight());
+cairo_fill(mpRT);
+}
+
 pSalLayout->drawSalLayout(mpRT, aRGBFontColor, 
getViewInformation2D().getUseAntiAliasing());
 cairo_restore(mpRT);
 }


core.git: drawinglayer/source include/drawinglayer include/vcl vcl/headless vcl/inc vcl/source vcl/unx

2024-08-05 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/textlayoutdevice.cxx   |   32 ++
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |  158 -
 include/drawinglayer/primitive2d/textlayoutdevice.hxx  |   19 +
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   11 
 include/vcl/vcllayout.hxx  |3 
 vcl/headless/svptext.cxx   |   10 
 vcl/inc/headless/svpgdi.hxx|1 
 vcl/inc/salgdi.hxx |1 
 vcl/inc/sallayout.hxx  |2 
 vcl/inc/unx/cairotextrender.hxx|7 
 vcl/source/gdi/CommonSalLayout.cxx |5 
 vcl/unx/generic/gdi/cairotextrender.cxx|   37 +--
 12 files changed, 265 insertions(+), 21 deletions(-)

New commits:
commit bf9e8d5ffd3f29fa027f0009a70f27d3456b648b
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Aug 2 15:56:52 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Aug 5 12:29:02 2024 +0200

CairoSDPR: direct text rendering using Cairo

I have added basic support for the text primitives
(TextSimplePortionPrimitive2D) to the SDPR Cairo
renderer. It can now basically render Text using
a fallback to the already existing CairoTextRender.

NOTE: This is not yet complete, but for discussion.
Change-Id: I9b0c7b6bb4892905576593ef4e2b4071c7663c63
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171429
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 3daecb4bec62..3a6667d0461f 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -38,6 +38,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 namespace drawinglayer::primitive2d
 {
@@ -192,6 +194,21 @@ void TextLayouterDevice::setFontAttribute(const 
attribute::FontAttribute& rFontA
 }
 }
 
+void TextLayouterDevice::setLayoutMode(vcl::text::ComplexTextLayoutFlags 
nTextLayoutMode)
+{
+mrDevice.SetLayoutMode(nTextLayoutMode);
+}
+
+vcl::text::ComplexTextLayoutFlags TextLayouterDevice::getLayoutMode() const
+{
+return mrDevice.GetLayoutMode();
+}
+
+void TextLayouterDevice::setTextColor(const basegfx::BColor& rColor)
+{
+mrDevice.SetTextColor(Color(rColor));
+}
+
 double TextLayouterDevice::getOverlineOffset() const
 {
 const ::FontMetric& rMetric = mrDevice.GetFontMetric();
@@ -348,6 +365,21 @@ std::vector TextLayouterDevice::getTextArray(const 
OUString& rText, sal_
 return aRetval;
 }
 
+std::unique_ptr TextLayouterDevice::getSalLayout(const OUString& 
rText,
+sal_uInt32 nIndex, 
sal_uInt32 nLength,
+const 
basegfx::B2DPoint& rStartPoint,
+const KernArray& 
rDXArray,
+std::span pKashidaAry)
+{
+const SalLayoutGlyphs* pGlyphs(
+SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&mrDevice, rText, 
nIndex, nLength));
+const Point aStartPoint(basegfx::fround(rStartPoint.getX()),
+basegfx::fround(rStartPoint.getY()));
+KernArraySpan aKernArraySpan(rDXArray);
+return mrDevice.ImplLayout(rText, nIndex, nLength, aStartPoint, 0, 
aKernArraySpan, pKashidaAry,
+   SalLayoutFlags::NONE, nullptr, pGlyphs);
+}
+
 // helper methods for vcl font handling
 
 vcl::Font getVclFontFromFontAttribute(const attribute::FontAttribute& 
rFontAttribute,
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index f6483e4a795e..baea016068c1 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -39,12 +39,17 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -285,7 +290,7 @@ void checkAndDoPixelSnap(cairo_t* pRT,
 
 // with the comments above at CairoPathHelper we cannot do PixelSnap
 // at path construction time, so it needs to be done *after* the path
-// data is added to the cairo context. ADvantage is that all general
+// data is added to the cairo context. Advantage is that all general
 // path data can be buffered, though, but needs view-dependent manipulation
 // here after being added.
 // For now, just snap all points - no real need to identify hor/ver lines
@@ -807,6 +812,10 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const 
geometry::ViewInformation2D&
 : BaseProcessor2D(rVi

core.git: drawinglayer/source editeng/inc editeng/source include/drawinglayer include/editeng svx/source

2024-08-01 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx |   12 ++
 drawinglayer/source/primitive2d/textprimitive2d.cxx  |8 -
 drawinglayer/source/processor2d/vclprocessor2d.cxx   |   45 ++-
 editeng/inc/outleeng.hxx |8 -
 editeng/source/editeng/editeng.cxx   |8 -
 editeng/source/editeng/impedit3.cxx  |   23 +++--
 editeng/source/outliner/outleeng.cxx |9 --
 editeng/source/outliner/outliner.cxx |   16 ---
 include/drawinglayer/primitive2d/textprimitive2d.hxx |   11 --
 include/editeng/editeng.hxx  |6 -
 include/editeng/outliner.hxx |   14 ---
 svx/source/svdraw/svdotextdecomposition.cxx  |5 -
 12 files changed, 43 insertions(+), 122 deletions(-)

New commits:
commit af014d1b5dea3419560b1df7933e3ac61db2c76b
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Aug 1 17:05:25 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Aug 1 20:28:36 2024 +0200

CairoSDPR: Simplify EditEngine text decomposition

The EditEngine decomposes it's content mainly to
Prmitives (there is still a direct paint mode used
in rare remaining cases which we not yet got rid
of). For TABs the special case for 'extended' TABs
(see format/paragraph/Tabs, FillCharacter) was
handed through all layers using method DrawingTab,
put into a DrawPortionInfo and held at the text
primitive (TextSimplePortionPrimitive2D). While
for direct paint the expansion was already done in
ImpEditEngine::Paint anyways (and always painted,
independent from bStripOnly what was unneccessary
and I corrected that, too) it had to be done for
text paint in VclProcessor2D for each repaint.
This is not needed, so now the extended text
created in EditEngine decompose gets used.

This makes a lot of stuff simpler, including
EditEngine/Outliner and some involved classes.
If it somehow should show that it might be
necessary to do that for each paint it should
be done in the obvious way then - using an own
primitive that creates the expansin in the
decomposition (and buffers it).

Change-Id: Ieb02219142af8f6bee01dcd658e08b185a4212cb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171380
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 07181bbf2a17..125b1e735cc8 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -338,7 +338,17 @@ namespace drawinglayer::primitive2d
 bool bEmphasisMarkBelow,
 TextRelief eTextRelief,
 bool bShadow)
-:   TextSimplePortionPrimitive2D(rNewTransform, rText, nTextPosition, 
nTextLength, std::move(rDXArray), std::move(rKashidaArray), rFontAttribute, 
rLocale, rFontColor, false, 0, rFillColor),
+:   TextSimplePortionPrimitive2D(
+rNewTransform,
+rText,
+nTextPosition,
+nTextLength,
+std::move(rDXArray),
+std::move(rKashidaArray),
+rFontAttribute,
+rLocale,
+rFontColor,
+rFillColor),
 maOverlineColor(rOverlineColor),
 maTextlineColor(rTextlineColor),
 meFontOverline(eFontOverline),
diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textprimitive2d.cxx
index 2d91785c5287..820b3d39f804 100644
--- a/drawinglayer/source/primitive2d/textprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -203,8 +203,7 @@ TextSimplePortionPrimitive2D::TextSimplePortionPrimitive2D(
 basegfx::B2DHomMatrix rNewTransform, OUString rText, sal_Int32 
nTextPosition,
 sal_Int32 nTextLength, std::vector&& rDXArray, 
std::vector&& rKashidaArray,
 attribute::FontAttribute aFontAttribute, css::lang::Locale aLocale,
-const basegfx::BColor& rFontColor, bool bFilled, tools::Long nWidthToFill,
-const Color& rTextFillColor)
+const basegfx::BColor& rFontColor, const Color& rTextFillColor)
 : maTextTransform(std::move(rNewTransform))
 , maText(std::move(rText))
 , mnTextPosition(nTextPosition)
@@ -214,8 +213,6 @@ TextSimplePortionPrimitive2D::TextSimplePortionPrimitive2D(
 , maFontAttribute(std::move(aFontAttribute))
 , maLocale(std::move(aLocale))
 , maFontColor(rFontColor)
-, mbFilled(bFilled)
-, mnWidthToFill(nWidthToFill)
 , maTextFillColor(rTextFillColor)
 {
 #if OSL_DEBUG_LEVEL > 0
@@ -245,8 +242,7 @@ bool TextSimplePortionPrimitive2D::operator==(const 
BasePrimitive2D& rPrimitive)

core.git: include/svl include/svx svl/source svx/source

2024-07-28 Thread Armin Le Grand (Collabora) (via logerrit)
 include/svl/itempool.hxx|   13 +++
 include/svl/poolitem.hxx|6 +++
 include/svx/xit.hxx |5 +-
 svl/source/items/itempool.cxx   |   44 
 svl/source/items/itemset.cxx|   17 +++--
 svl/source/items/poolitem.cxx   |1 
 svx/source/xoutdev/xattr.cxx|   71 +---
 svx/source/xoutdev/xattrbmp.cxx |8 ++--
 8 files changed, 122 insertions(+), 43 deletions(-)

New commits:
commit be5fad6d0755e3d1e7ab5c9d4bfda8248b4e51d2
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Jul 26 20:15:56 2024 +0200
Commit: Noel Grandin 
CommitDate: Mon Jul 29 08:01:06 2024 +0200

tdf#161875 buffer NameOrIndex Items for fast Surrogates

Problem is that collecting the Items using the ItemSets and
PoolItemHolders is too expensive when used too often. For
read-only access it is okay to have the Items directly
registerd (for write access we *need* the ItemSets and
PoolItemHolders, see iterateItemSurrogates).
This is limited to Items which need to support surrogates,
but can further be limited to the here critical ones - the
ones derived from NameOrIndex.
This is done here by checking if the Item is a NameOrIndex
based one by adding a bool to the item that gets set in the
NameOrIndex constructor. If needed this can be changed,
e.g. by using besides the SFX_ITEMINFOFLAG_SUPPORT_SURROGATE
another flag signaling this.
Since only Items that are currently held by an ItemSet or a
PoolItemHolder get registered it is not necessary to change
the Item's RefCount in any way, doing that may lead (again,
we had that with directly set Items at the Pool in the past)
to long-living Items that only get cleaned-up when the pool/
document gets destructed.
This buffering is now SfxItemType-based, no longer using the
WhichID, so the result needs to be checked for WhichID
additionally - if needed (?).
All in all it's anyways a compromize, every usage of the
surrogate mechanism is a 'hack' in the sense that for lazy
reasons not the model data is traversed directly, but assumed
that all Items set at a pool/model *are* model/document data
(what is not always true).

CheckNamedItem does not need to be static, changed that.
Also all accesses to maRegisteredNameOrIndex *have* to
work on the MasterPool instance, same as buffered ItemSets
or PoolItemHolders, corrected that, too.

Number of instances in the buffer need to be counted, else
an instance will be removed too early: The same instance
of an Item can be referenced by multiple sets/holders,
so the first remove from the buffer would already remove
even when the Item is referenced multiple times. Added
that.

Added more asserts & made sure that all constructors/
destructors of SfxItemSet do take care of registering
Items for the surrogate mechanism as needed.

Change-Id: Ib33e7f0bd4abd32a3bb68278f33b0abb9a4754c3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171084
Reviewed-by: Noel Grandin 
Tested-by: Jenkins

diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx
index 7c3868ca9996..030a09d0f688 100644
--- a/include/svl/itempool.hxx
+++ b/include/svl/itempool.hxx
@@ -136,6 +136,8 @@ typedef std::unordered_set 
registeredSfxPoolItemHolders;
 typedef std::vector ItemSurrogates;
 typedef std::unordered_map userItemInfos;
 typedef std::vector itemInfoVector;
+typedef std::unordered_map NameOrIndexContent;
+typedef std::unordered_map 
registeredNameOrIndex;
 
 /** Base class for providers of defaults of SfxPoolItems.
  *
@@ -165,6 +167,11 @@ class SVL_DLLPUBLIC SfxItemPool : public 
salhelper::SimpleReferenceObject
 
 registeredSfxItemSets maRegisteredSfxItemSets;
 registeredSfxPoolItemHolders maRegisteredSfxPoolItemHolders;
+
+// place to register all NameOrIndex Items that are either set in an
+// SfxItemSet or SfxPolItemHolder for this Model/Pool
+registeredNameOrIndex maRegisteredNameOrIndex;
+
 bool mbShutdownHintSent;
 
 itemInfoVector maItemInfos;
@@ -204,6 +211,9 @@ private:
 void registerPoolItemHolder(SfxPoolItemHolder& rHolder);
 void unregisterPoolItemHolder(SfxPoolItemHolder& rHolder);
 
+void registerNameOrIndex(const SfxPoolItem& rItem);
+void unregisterNameOrIndex(const SfxPoolItem& rItem);
+
 public:
 // for default SfxItemSet::CTOR, set default WhichRanges
 const WhichRangesContainer& GetMergedIdRanges() const;
@@ -311,6 +321,9 @@ public:
 // Read commit text for more information
 void GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 nWhich) const;
 
+// special version for read-oly itemSurrogates for NameOrIndex Items
+void GetItemSurrogatesForItem(ItemSurrogates& rTarget, const SfxPoolItem& 
rItem) const;
+
 sal_uInt16 GetFirstWhich() const { return mnStart; }
 sal_uInt16 GetLastWhi

core.git: drawinglayer/source include/drawinglayer svx/source

2024-07-26 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx  |9 +
 drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx |   48 
++
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx   |   33 
+-
 drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx |2 
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx  |   40 
+++-
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |2 
 include/drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx |   11 +-
 include/drawinglayer/primitive2d/fillgradientprimitive2d.hxx|9 +
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx|   35 
---
 9 files changed, 143 insertions(+), 46 deletions(-)

New commits:
commit 4461173a4d0dff82e6223bdc1376230a9cd6b1cc
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Jul 25 20:25:31 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Jul 26 10:56:33 2024 +0200

CairoSDPR: Support direct transparency for gradients

FillGradientPrimitive2D/ and PolyPolygonGradientPrimitive2D
now support both alphas, a gradientAlpha and a unified one.
This allows a processor to directly handle a gradient with
a unifiedAlpha if he wants. Adapted other places accordingly.

NOTE: In VclMetafileProcessor2D handling of the primitive
PolyPolygonGradientPrimitive2D has to do a local compromize,
see comment there.

Change-Id: I536f4935dafde0369f768dbd281d547b7bb08eb4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171052
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
index de114e2fdf53..d37e3d71225b 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
@@ -40,7 +40,7 @@ Primitive2DReference 
PolyPolygonGradientPrimitive2D::create2DDecomposition(
 const basegfx::B2DRange 
aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
 rtl::Reference pNewGradient = new 
FillGradientPrimitive2D(
 aPolyPolygonRange, getDefinitionRange(), getFillGradient(),
-hasAlphaGradient() ? &getAlphaGradient() : nullptr);
+hasAlphaGradient() ? &getAlphaGradient() : nullptr, 
getTransparency());
 Primitive2DContainer aSubSequence{ pNewGradient };
 
 // create mask primitive
@@ -56,17 +56,19 @@ 
PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
 , maDefinitionRange(rPolyPolygon.getB2DRange())
 , maFillGradient(rFillGradient)
 , maAlphaGradient()
+, mfTransparency(0.0)
 {
 }
 
 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
 basegfx::B2DPolyPolygon aPolyPolygon, const basegfx::B2DRange& 
rDefinitionRange,
 const attribute::FillGradientAttribute& rFillGradient,
-const attribute::FillGradientAttribute* pAlphaGradient)
+const attribute::FillGradientAttribute* pAlphaGradient, double 
fTransparency)
 : maPolyPolygon(std::move(aPolyPolygon))
 , maDefinitionRange(rDefinitionRange)
 , maFillGradient(rFillGradient)
 , maAlphaGradient()
+, mfTransparency(fTransparency)
 {
 // copy alpha gradient if we got one
 if (nullptr != pAlphaGradient)
@@ -93,6 +95,9 @@ bool PolyPolygonGradientPrimitive2D::operator==(const 
BasePrimitive2D& rPrimitiv
 if (maAlphaGradient != rCompare.maAlphaGradient)
 return false;
 
+if (!basegfx::fTools::equal(getTransparency(), rCompare.getTransparency()))
+return false;
+
 return true;
 }
 
diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx 
b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
index 19dfe8482430..8c2e339f8fbb 100644
--- a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -264,22 +265,33 @@ namespace drawinglayer::primitive2d
 // SDPR: support alpha directly now. If a primitive processor
 // cannot deal with it, use it's decomposition. For that purpose
 // this decomposition has two stages now: This 1st one will
-// separate content and alpha into a TransparencePrimitive2D,
+// (if needed) separate content and alpha into a 
TransparencePrimitive2D
+// and (if needed) embed that to a UnifiedTransparencePrimitive2D,
 // so all processors can work as before
-if (hasAlphaGradient())
+if (hasAlphaGradient() || hasTransparency())
 {
-Primitive2DContainer aContent{ new FillGradientPrimitive2D(
-getOutputRange(),
-getDefinitionRange(),
-   

core.git: drawinglayer/source

2024-07-25 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

New commits:
commit 125752096bf00069b329217ec61464ec8224c9b3
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Jul 25 13:36:40 2024 +0200
Commit: Armin Le Grand 
CommitDate: Thu Jul 25 16:52:08 2024 +0200

CairoSDPR: Added more care to TransparencyGradient

In VclMetafileProcessor2D for handling the
PolyPolygonGradientPrimitive2D the case that is may have
now a alphaGradient has to be handled with more care for
adding a gradient itself and also for added SVG information,
see BGRAD_SEQ_BEGIN stuff

Change-Id: Ifab5ec9581a5e400549189a5a41190a91c0cb4cd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171009
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 3ec3c4922260..aa54a63366ae 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1986,6 +1986,13 @@ void 
VclMetafileProcessor2D::processPolyPolygonGradientPrimitive2D(
 {
 bool useDecompose(false);
 
+// SDPR: Caution: metafile export cannot handle added TransparencyGradient
+if (rGradientCandidate.hasAlphaGradient())
+{
+// SDPR: metafile cannot handle this, use decompose
+useDecompose = true;
+}
+
 if (!useDecompose)
 {
 basegfx::B2DVector aScale, aTranslate;
@@ -2049,7 +2056,8 @@ void 
VclMetafileProcessor2D::processPolyPolygonGradientPrimitive2D(
 GDIMetaFile* pMetaFile(mpOutputDevice->GetConnectMetaFile());
 
 // tdf#155479 only add 'BGRAD_SEQ_BEGIN' if SVG export
-if (nullptr != pMetaFile && pMetaFile->getSVG())
+// SDPR: Caution: metafile export cannot handle added 
TransparencyGradient
+if (nullptr != pMetaFile && pMetaFile->getSVG() && 
!rGradientCandidate.hasAlphaGradient())
 {
 // write the color stops to a memory stream
 SvMemoryStream aMemStm;


core.git: drawinglayer/source include/drawinglayer svx/source

2024-07-24 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/attribute/fillgraphicattribute.cxx|5 
 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx |   27 +---
 drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx  |   64 
+-
 include/drawinglayer/attribute/fillgraphicattribute.hxx   |1 
 include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx |   14 ++
 svx/source/sdr/contact/viewobjectcontact.cxx  |   27 
 6 files changed, 94 insertions(+), 44 deletions(-)

New commits:
commit 1b74b95bba6b84225248e5b7badf1de7ae401a79
Author: Armin Le Grand (Collabora) 
AuthorDate: Wed Jul 24 13:45:58 2024 +0200
Commit: Armin Le Grand 
CommitDate: Wed Jul 24 17:00:56 2024 +0200

CairoSDPR: Improve animated tiled fills

Up to now these needed to be decomposed to be
rendered and did not support animation. I already
added animation, but that was a compromize.
Done that now in the correct way, so that animation
is possible and can be directly rendered using
a FillGraphicPrimitive2D if wanted, including one
extra layer of alpha, too.
This will also enhance other primitive processors,
but of course most those that do handle that now
directly, so CairoPixelProcessor2D does that.
Note that it does not need to support animation
in any way (that is part of the primitive stack),
but just direct tiled rendering.

Change-Id: I8860098dfb3f2369e361579cf1deea7c67b662b9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170937
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/attribute/fillgraphicattribute.cxx 
b/drawinglayer/source/attribute/fillgraphicattribute.cxx
index 300d6f6123f1..3da913eee8d0 100644
--- a/drawinglayer/source/attribute/fillgraphicattribute.cxx
+++ b/drawinglayer/source/attribute/fillgraphicattribute.cxx
@@ -94,6 +94,11 @@ namespace drawinglayer::attribute
 }
 }
 
+FillGraphicAttribute::FillGraphicAttribute()
+:   mpFillGraphicAttribute(theGlobalDefault())
+{
+}
+
 FillGraphicAttribute::FillGraphicAttribute(
 const Graphic& rGraphic,
 const basegfx::B2DRange& rGraphicRange,
diff --git a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
index 7853709b9541..fee818e23d65 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -46,7 +47,7 @@ Primitive2DReference 
PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 return nullptr;
 }
 
-const Graphic& rGraphic = getFillGraphic().getGraphic();
+const Graphic& rGraphic(getFillGraphic().getGraphic());
 const GraphicType aType(rGraphic.GetType());
 
 // is there a bitmap or a metafile (do we have content)?
@@ -67,10 +68,9 @@ Primitive2DReference 
PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 
 // create SubSequence with FillGraphicPrimitive2D based on polygon range
 const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange());
-const basegfx::B2DHomMatrix aNewObjectTransform(
-basegfx::utils::createScaleTranslateB2DHomMatrix(aOutRange.getRange(),
- 
aOutRange.getMinimum()));
-Primitive2DReference xSubRef;
+const basegfx::B2DHomMatrix 
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(
+aOutRange.getRange(), aOutRange.getMinimum()));
+drawinglayer::attribute::FillGraphicAttribute 
aFillGraphicAttribute(getFillGraphic());
 
 if (aOutRange != getDefinitionRange())
 {
@@ -96,21 +96,18 @@ Primitive2DReference 
PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 
 aAdaptedRange.transform(aFromGlobalToOutRange);
 
-const drawinglayer::attribute::FillGraphicAttribute 
aAdaptedFillGraphicAttribute(
+aFillGraphicAttribute = drawinglayer::attribute::FillGraphicAttribute(
 getFillGraphic().getGraphic(), aAdaptedRange, 
getFillGraphic().getTiling(),
 getFillGraphic().getOffsetX(), getFillGraphic().getOffsetY());
-
-xSubRef = new FillGraphicPrimitive2D(aNewObjectTransform, 
aAdaptedFillGraphicAttribute,
- getTransparency());
-}
-else
-{
-xSubRef
-= new FillGraphicPrimitive2D(aNewObjectTransform, 
getFillGraphic(), getTransparency());
 }
 
+// use tooling due to evtl. animation info needs to be created if
+// the Graphic is animated somehow
+Primitive2DReference aContent(
+createFillGraphicPrimitive2D(aTransform, aFillGraphicAttribute, 
getTransparency()));
+
 // embed to mask primitive
-return new MaskPrimitive2D(getB2DPolyPolygon(), Primitiv

core.git: drawinglayer/source include/drawinglayer svx/source

2024-07-23 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx  |   27 ++
 drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx |   20 +-
 drawinglayer/source/primitive2d/graphicprimitive2d.cxx |   19 -
 drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx   |   94 
++---
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   34 ++-
 drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx|   14 +
 drawinglayer/source/processor2d/hittestprocessor2d.cxx |  100 
++
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |9 
 drawinglayer/source/processor2d/vclprocessor2d.cxx |   17 +
 include/drawinglayer/primitive2d/PolyPolygonGraphicPrimitive2D.hxx |   12 +
 include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx|   14 +
 include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx  |7 
 include/drawinglayer/processor2d/hittestprocessor2d.hxx|2 
 svx/source/sdr/contact/viewobjectcontact.cxx   |6 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx   |   11 +
 15 files changed, 280 insertions(+), 106 deletions(-)

New commits:
commit 462d85709ead9c7cec33ce58fc608997263cb6aa
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Jul 23 13:26:34 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Jul 23 18:35:26 2024 +0200

CairoSDPR: Support alpha for BitmapPrimitives

To more directly support an additional alpha channel
for BitmapPrimitive data I have done some deeper
changes to the primitive stack, in a compatible
way. Quite some more graphic types and primitives
now support an additional direct alpha value. All
that is decomposed/created/broken down in a way
that needs no changes for existing renderers, in
already described ways.
The CairoPixelProcessor2D already uses this in the
processFillGraphicPrimitive2D implementation and
thus in the FillGraphicPrimitive2D. This works since
primitive productions now all try to create that
FillGraphicPrimitive2D type including an additional
alpha value - if possible and necessary.

Change-Id: Ib1b16491a2b3aee16f14cc8196e28af30a7cf9be
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170900
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
index 31a7acb03d7c..7853709b9541 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
@@ -34,21 +34,36 @@ namespace drawinglayer::primitive2d
 Primitive2DReference PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
+if (basegfx::fTools::equal(getTransparency(), 1.0))
+{
+// completely transparent, done
+return nullptr;
+}
+
 if (getFillGraphic().isDefault())
+{
+// no geometry data, done
 return nullptr;
+}
 
 const Graphic& rGraphic = getFillGraphic().getGraphic();
 const GraphicType aType(rGraphic.GetType());
 
 // is there a bitmap or a metafile (do we have content)?
 if (GraphicType::Bitmap != aType && GraphicType::GdiMetafile != aType)
+{
+// no geometry data, done
 return nullptr;
+}
 
 const Size aPrefSize(rGraphic.GetPrefSize());
 
 // does content have a size?
 if (!(aPrefSize.Width() && aPrefSize.Height()))
+{
+// no geometry data with size, done
 return nullptr;
+}
 
 // create SubSequence with FillGraphicPrimitive2D based on polygon range
 const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange());
@@ -85,11 +100,13 @@ Primitive2DReference 
PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 getFillGraphic().getGraphic(), aAdaptedRange, 
getFillGraphic().getTiling(),
 getFillGraphic().getOffsetX(), getFillGraphic().getOffsetY());
 
-xSubRef = new FillGraphicPrimitive2D(aNewObjectTransform, 
aAdaptedFillGraphicAttribute);
+xSubRef = new FillGraphicPrimitive2D(aNewObjectTransform, 
aAdaptedFillGraphicAttribute,
+ getTransparency());
 }
 else
 {
-xSubRef = new FillGraphicPrimitive2D(aNewObjectTransform, 
getFillGraphic());
+xSubRef
+= new FillGraphicPrimitive2D(aNewObjectTransform, 
getFillGraphic(), getTransparency());
 }
 
 // embed to mask primitive
@@ -98,10 +115,11 @@ Primitive2DReference 
PolyPolygonGraphicPrimitive2D::create2DDecomposition(
 
 PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
 basegfx::B2DPolyPolygon aPolyPolygon, const basegfx::B2DRange& 
rDefinitionRange,
-const attribute::FillGraphicAttribute& rFill

core.git: drawinglayer/Library_drawinglayer.mk drawinglayer/source include/drawinglayer

2024-07-22 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/Library_drawinglayer.mk   |1 
 drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx |  105 
++
 drawinglayer/source/primitive2d/Tools.cxx  |2 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   47 
 include/drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx|   82 
+++
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx |1 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |7 
 7 files changed, 241 insertions(+), 4 deletions(-)

New commits:
commit 3dcee7e08008588181e69f13e223d3ed4d667dda
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Jul 22 14:39:01 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Jul 22 20:06:20 2024 +0200

CairoSDPR: Prepare BitmapAlphaPrimitive2D

This provides a BitmapPrimitive2D extended by a unified
transparency component. It will decompose to a
UnifiedTransparencePrimitive2D containing a
BitmapPrimitive2D and the transparence, so no primitive
processor has to support this primitive directly - but
can if feasible. I plan to use that ASAP

Change-Id: I83ec84eaadc8ba2b21f0ba0cb1fdcf43bdc455db
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170852
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index 18578664cf67..7529c34a43b7 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -106,6 +106,7 @@ $(eval $(call 
gb_Library_add_exception_objects,drawinglayer,\
 drawinglayer/source/primitive2d/animatedprimitive2d \
 drawinglayer/source/primitive2d/backgroundcolorprimitive2d \
 drawinglayer/source/primitive2d/bitmapprimitive2d \
+drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D \
 drawinglayer/source/primitive2d/borderlineprimitive2d \
 drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D \
 drawinglayer/source/primitive2d/controlprimitive2d \
diff --git a/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx
new file mode 100644
index ..8aaca2e5fd15
--- /dev/null
+++ b/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace com::sun::star;
+
+namespace drawinglayer::primitive2d
+{
+Primitive2DReference BitmapAlphaPrimitive2D::create2DDecomposition(
+const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+if (basegfx::fTools::equal(getTransparency(), 1.0))
+{
+// completely transparent, done
+return nullptr;
+}
+
+if (getBitmap().IsEmpty())
+{
+// no geometry, done
+return nullptr;
+}
+
+if (basegfx::fTools::equalZero(getTransparency()))
+{
+// no transparency, use simple BitmapPrimitive2D
+return Primitive2DReference{ new BitmapPrimitive2D(getBitmap(), 
getTransform()) };
+}
+
+// default: embed to UnifiedTransparencePrimitive2D
+Primitive2DContainer aContent{ new BitmapPrimitive2D(getBitmap(), 
getTransform()) };
+return Primitive2DReference{ new 
UnifiedTransparencePrimitive2D(std::move(aContent),
+
getTransparency()) };
+}
+
+BitmapAlphaPrimitive2D::BitmapAlphaPrimitive2D(BitmapEx xXBitmap, 
basegfx::B2DHomMatrix aTransform,
+   double fTransparency)
+: maBitmap(std::move(xXBitmap))
+, maTransform(std::move(aTransform))
+, mfTransparency(std::max(0.0, std::min(1.0, fTransparency)))
+{
+}
+
+bool BitmapAlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) 
const
+{
+if (BasePrimitive2D::operator==(rPrimitive))
+{
+const BitmapAlphaPrimitive2D& rCompare
+= static_cast(rPrimitive);
+
+return (getBitmap() == rC

core.git: drawinglayer/source

2024-07-22 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx |  151 +-
 1 file changed, 98 insertions(+), 53 deletions(-)

New commits:
commit a3081afb197dfd55055657eb89c6305a24e9e530
Author: Armin Le Grand (Collabora) 
AuthorDate: Sat Jul 20 19:33:01 2024 +0200
Commit: Armin Le Grand 
CommitDate: Mon Jul 22 12:16:02 2024 +0200

CairoSDPR: Better support for XOR

Change-Id: Ib6a8489e655640e7a12eaec943977867e94d2793
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170799
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 492f50446f61..24695b0b0a8a 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -1212,74 +1212,119 @@ void CairoPixelProcessor2D::processInvertPrimitive2D(
 aContent.process(rInvertCandidate.getChildren());
 cairo_surface_flush(pContent);
 
-// get read access to target - XOR unfortunately needs that
-cairo_surface_t* pRenderTarget(pTarget);
+// decide if to use builtin or create XOR yourself
+// NOTE: not using and doing self is closer to what the
+//   current default does, so keep it
+static bool bUseBuiltinXOR(false);
 
-if (CAIRO_SURFACE_TYPE_IMAGE != cairo_surface_get_type(pRenderTarget))
+if (!bUseBuiltinXOR)
 {
-pRenderTarget = cairo_surface_map_to_image(pRenderTarget, nullptr);
-}
+// get read access to target - XOR unfortunately needs that
+cairo_surface_t* pRenderTarget(pTarget);
 
-// iterate over pre-rendered pContent, call Dst due to being changed
-const sal_uInt32 nDstWidth(cairo_image_surface_get_width(pContent));
-const sal_uInt32 nDstHeight(cairo_image_surface_get_height(pContent));
-const sal_uInt32 nDstStride(cairo_image_surface_get_stride(pContent));
-unsigned char* pDstDataRoot(cairo_image_surface_get_data(pContent));
+if (CAIRO_SURFACE_TYPE_IMAGE != cairo_surface_get_type(pRenderTarget))
+{
+pRenderTarget = cairo_surface_map_to_image(pRenderTarget, nullptr);
+}
 
-// in parallel, iterate over Src data
-const sal_uInt32 nSrcOffX(floor(aVisibleRange.getMinX()));
-const sal_uInt32 nSrcOffY(floor(aVisibleRange.getMinY()));
-const sal_uInt32 nSrcStride(cairo_image_surface_get_stride(pRenderTarget));
-unsigned char* pSrcDataRoot(cairo_image_surface_get_data(pRenderTarget));
+// iterate over pre-rendered pContent (call it Front)
+const sal_uInt32 nFrontWidth(cairo_image_surface_get_width(pContent));
+const sal_uInt32 
nFrontHeight(cairo_image_surface_get_height(pContent));
+const sal_uInt32 
nFrontStride(cairo_image_surface_get_stride(pContent));
+unsigned char* pFrontDataRoot(cairo_image_surface_get_data(pContent));
 
-if (nullptr != pDstDataRoot && nullptr != pSrcDataRoot)
-{
-for (sal_uInt32 y(0); y < nDstHeight; ++y)
-{
-// get mem locations
-unsigned char* pDstData(pDstDataRoot + (nDstStride * y));
-unsigned char* pSrcData(pSrcDataRoot + (nSrcStride * (y + 
nSrcOffY)) + (nSrcOffX * 4));
+// in parallel, iterate over original data (call it Back)
+const sal_uInt32 nBackOffX(floor(aVisibleRange.getMinX()));
+const sal_uInt32 nBackOffY(floor(aVisibleRange.getMinY()));
+const sal_uInt32 
nBackStride(cairo_image_surface_get_stride(pRenderTarget));
+unsigned char* 
pBackDataRoot(cairo_image_surface_get_data(pRenderTarget));
 
-for (sal_uInt32 x(0); x < nDstWidth; ++x)
+if (nullptr != pFrontDataRoot && nullptr != pBackDataRoot)
+{
+for (sal_uInt32 y(0); y < nFrontHeight; ++y)
 {
-// do not forget pre-multiply -> need to get both alphas
-sal_uInt8 nSrcAlpha(pSrcData[SVP_CAIRO_ALPHA]);
-sal_uInt8 nDstAlpha(pDstData[SVP_CAIRO_ALPHA]);
-
-// create XOR r,g,b
-const sal_uInt8 b(
-vcl::bitmap::unpremultiply(nDstAlpha, 
pDstData[SVP_CAIRO_BLUE])
-^ vcl::bitmap::unpremultiply(nSrcAlpha, 
pSrcData[SVP_CAIRO_BLUE]));
-const sal_uInt8 g(
-vcl::bitmap::unpremultiply(nDstAlpha, 
pDstData[SVP_CAIRO_GREEN])
-^ vcl::bitmap::unpremultiply(nSrcAlpha, 
pSrcData[SVP_CAIRO_GREEN]));
-const sal_uInt8 r(vcl::bitmap::unpremultiply(nDstAlpha, 
pDstData[SVP_CAIRO_RED])
-  ^ vcl::bitmap::unpremultiply(nSrcAlpha, 
pSrcData[SVP_CAIRO_RED]));
-
-// write back
-pDstData[SVP_CAIRO_BLUE] = vcl::bitmap::premultiply(nDstAlpha, 
b);
-pDstData[SVP_CAIRO_GREEN] = 
vcl::bitmap::premultiply(nDstAlpha, g);
-pDstData[SVP_CAIRO_RED] = vcl

core.git: drawinglayer/source svgio/qa svgio/source svx/source

2024-07-20 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx |   21 ++--
 drawinglayer/source/primitive2d/svggradientprimitive2d.cxx |   52 
+-
 drawinglayer/source/tools/emfphelperdata.cxx   |   12 --
 svgio/qa/cppunit/SvgImportTest.cxx |   24 ++--
 svgio/source/svgreader/svgfefloodnode.cxx  |   31 +++--
 svgio/source/svgreader/svgstyleattributes.cxx  |   24 +++-
 svx/source/sdr/overlay/overlaytools.cxx|   20 ++-
 7 files changed, 103 insertions(+), 81 deletions(-)

New commits:
commit 45c45e97e1b3a54689557644edd2ea6c3e6af149
Author: Armin Le Grand (Collabora) 
AuthorDate: Sat Jul 20 15:01:37 2024 +0200
Commit: Armin Le Grand 
CommitDate: Sat Jul 20 19:31:36 2024 +0200

CairoSDPR: make use of RGBA PolyPolygon in more cases

Change-Id: I7cd93e5452bce96eef295c766f4cb391ddd67250
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170792
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx 
b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
index ea1b2a56942a..1377ff28ebf3 100644
--- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -43,19 +43,20 @@ namespace drawinglayer::primitive2d
 
 // create decompose geometry
 const basegfx::B2DPolygon 
aOutline(basegfx::utils::createPolygonFromRect(rViewInformation.getViewport()));
-Primitive2DReference aDecompose(new 
PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), getBColor()));
 
-if(getTransparency() != 0.0)
+if (basegfx::fTools::lessOrEqual(getTransparency(), 0.0))
 {
-// if used, embed decompose geometry to unified transparency
-Primitive2DContainer aContent { aDecompose };
-aDecompose =
-new UnifiedTransparencePrimitive2D(
-std::move(aContent),
-getTransparency());
+// no transparency
+return Primitive2DReference {
+new 
PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), getBColor()) };
 }
 
-return aDecompose;
+// if transparent, use PolyPolygonRGBAPrimitive2D
+return Primitive2DReference {
+new PolyPolygonRGBAPrimitive2D(
+basegfx::B2DPolyPolygon(aOutline),
+getBColor(),
+getTransparency()) };
 }
 
 BackgroundColorPrimitive2D::BackgroundColorPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx 
b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
index 24f979ce2c9d..3c6e7ab6b494 100644
--- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -65,39 +66,40 @@ namespace drawinglayer::primitive2d
 {
 Primitive2DReference 
SvgGradientHelper::createSingleGradientEntryFill() const
 {
-const SvgGradientEntryVector& rEntries = getGradientEntries();
+const SvgGradientEntryVector& rEntries(getGradientEntries());
 const sal_uInt32 nCount(rEntries.size());
 
-if(nCount)
+if(0 == nCount)
 {
-const SvgGradientEntry& rSingleEntry = rEntries[nCount - 1];
-const double fOpacity(rSingleEntry.getOpacity());
-
-if(fOpacity > 0.0)
-{
-Primitive2DReference xRef(
-new PolyPolygonColorPrimitive2D(
-getPolyPolygon(),
-rSingleEntry.getColor()));
-
-if(fOpacity < 1.0)
-{
-Primitive2DContainer aContent { xRef };
+// no entries, done
+OSL_ENSURE(false, "Single gradient entry construction without 
entry (!)");
+return nullptr;
+}
 
-xRef =
-new UnifiedTransparencePrimitive2D(
-std::move(aContent),
-1.0 - fOpacity);
-}
+const SvgGradientEntry& rSingleEntry(rEntries[nCount - 1]);
+const double fOpacity(rSingleEntry.getOpacity());
 
-return xRef;
-}
+if (basegfx::fTools::lessOrEqual(fOpacity, 0.0))
+{
+// completely opaque, done
+return nullptr;
  

core.git: drawinglayer/Library_drawinglayer.mk drawinglayer/source include/drawinglayer svx/qa svx/source

2024-07-20 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/Library_drawinglayer.mk   |1 
 drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D.cxx |   99 
++
 drawinglayer/source/primitive2d/Tools.cxx  |2 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |   50 -
 drawinglayer/source/tools/primitive2dxmldump.cxx   |   15 +
 include/drawinglayer/primitive2d/PolyPolygonRGBAPrimitive2D.hxx|   86 

 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx |1 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   10 +
 svx/qa/unit/table.cxx  |4 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx   |9 
 10 files changed, 271 insertions(+), 6 deletions(-)

New commits:
commit 7297b0788f8f20ba6ab0973f944a4d522d666108
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Jul 19 14:35:39 2024 +0200
Commit: Armin Le Grand 
CommitDate: Sat Jul 20 14:19:35 2024 +0200

CairoSDPR: Support direct RGBA paint of PolyPolygons

Change-Id: Id1480297126bcc422945df7cd47993cc7fe5c22a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170768
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index beef19918f7c..18578664cf67 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -142,6 +142,7 @@ $(eval $(call 
gb_Library_add_exception_objects,drawinglayer,\
 drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonColorPrimitive2D \
+drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D \
 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D \
diff --git a/drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D.cxx
new file mode 100644
index ..eb453116c97c
--- /dev/null
+++ b/drawinglayer/source/primitive2d/PolyPolygonRGBAPrimitive2D.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace com::sun::star;
+
+namespace drawinglayer::primitive2d
+{
+Primitive2DReference PolyPolygonRGBAPrimitive2D::create2DDecomposition(
+const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+if (basegfx::fTools::equal(getTransparency(), 1.0))
+{
+// completely transparent, done
+return nullptr;
+}
+
+if (0 == getB2DPolyPolygon().count())
+{
+// no geometry, done
+return nullptr;
+}
+
+if (basegfx::fTools::equalZero(getTransparency()))
+{
+// no transparency, use simple PolyPolygonColorPrimitive2D
+return Primitive2DReference{ new 
PolyPolygonColorPrimitive2D(getB2DPolyPolygon(),
+ 
getBColor()) };
+}
+
+// default: embed to UnifiedTransparencePrimitive2D
+Primitive2DContainer aContent{ new 
PolyPolygonColorPrimitive2D(getB2DPolyPolygon(),
+   
getBColor()) };
+return Primitive2DReference{ new 
UnifiedTransparencePrimitive2D(std::move(aContent),
+
getTransparency()) };
+}
+
+PolyPolygonRGBAPrimitive2D::PolyPolygonRGBAPrimitive2D(basegfx::B2DPolyPolygon 
aPolyPolygon,
+   const basegfx::BColor& 
rBColor,
+   double fTransparency)
+: maPolyPolygon(std::move(aPolyPolygon))
+, maBColor(rBColor)
+, mfTransparency(std::max(0.0, std::min(1.0, fTransparency)))
+{
+}
+
+bool PolyPolygon

core.git: drawinglayer/source include/drawinglayer svx/source

2024-07-19 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx  |   87 +---
 drawinglayer/source/primitive2d/Tools.cxx   |2 
 drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx |   70 ++-
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx   |  205 
--
 drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx |8 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |8 
 include/drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx |   51 --
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx  |3 
 include/drawinglayer/primitive2d/fillgradientprimitive2d.hxx|   16 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx  |   22 -
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx|   40 -
 11 files changed, 226 insertions(+), 286 deletions(-)

New commits:
commit aac4974f2a50ebd34137d0384a5e21567c6ae646
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Jul 18 14:08:48 2024 +0200
Commit: Armin Le Grand 
CommitDate: Fri Jul 19 10:46:34 2024 +0200

CairoSDPR: Direct support for RGBA Gradients (III)

I thought about this functionality again and decided
to change doing it in a way that will support more
alpha more directly in existing primitives - that will
be better for also supporting e.g. PolyPolys with alpha,
etc. Will need checking of existing usages of e.g.
FillGradientPrimitive2D, but it's worth it.
Note that when your primitive processor (usually a
renderer) does *not* support alpha in gradients
directly it is now requuired to continue using the
decomposition (what renderers do automatically when
calling 'BaseProcessor2D::process' in the default
case. Checked that for existing processors.

Change-Id: I840c9feb8c98549b790ef16285a309b42c4b1b53
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170687
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
index 2e6b83ab526f..de114e2fdf53 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
@@ -39,7 +39,8 @@ Primitive2DReference 
PolyPolygonGradientPrimitive2D::create2DDecomposition(
 // create SubSequence with FillGradientPrimitive2D
 const basegfx::B2DRange 
aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
 rtl::Reference pNewGradient = new 
FillGradientPrimitive2D(
-aPolyPolygonRange, getDefinitionRange(), getFillGradient());
+aPolyPolygonRange, getDefinitionRange(), getFillGradient(),
+hasAlphaGradient() ? &getAlphaGradient() : nullptr);
 Primitive2DContainer aSubSequence{ pNewGradient };
 
 // create mask primitive
@@ -49,87 +50,57 @@ Primitive2DReference 
PolyPolygonGradientPrimitive2D::create2DDecomposition(
 }
 
 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
-const basegfx::B2DPolyPolygon& rPolyPolygon, 
attribute::FillGradientAttribute aFillGradient)
+const basegfx::B2DPolyPolygon& rPolyPolygon,
+const attribute::FillGradientAttribute& rFillGradient)
 : maPolyPolygon(rPolyPolygon)
 , maDefinitionRange(rPolyPolygon.getB2DRange())
-, maFillGradient(std::move(aFillGradient))
+, maFillGradient(rFillGradient)
+, maAlphaGradient()
 {
 }
 
 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
 basegfx::B2DPolyPolygon aPolyPolygon, const basegfx::B2DRange& 
rDefinitionRange,
-attribute::FillGradientAttribute aFillGradient)
+const attribute::FillGradientAttribute& rFillGradient,
+const attribute::FillGradientAttribute* pAlphaGradient)
 : maPolyPolygon(std::move(aPolyPolygon))
 , maDefinitionRange(rDefinitionRange)
-, maFillGradient(std::move(aFillGradient))
+, maFillGradient(rFillGradient)
+, maAlphaGradient()
 {
+// copy alpha gradient if we got one
+if (nullptr != pAlphaGradient)
+maAlphaGradient = *pAlphaGradient;
 }
 
 bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& 
rPrimitive) const
 {
-if (BufferedDecompositionPrimitive2D::operator==(rPrimitive))
-{
-const PolyPolygonGradientPrimitive2D& rCompare
-= static_cast(rPrimitive);
+if (!(BufferedDecompositionPrimitive2D::operator==(rPrimitive)))
+return false;
 
-return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
-&& getDefinitionRange() == rCompare.getDefinitionRange()
-&& getFillGradient() == rCompare.getFillGradient());
-}
+const PolyPolygonGradientPrimitive2D& rCompare(
+static_cast(rPrimitive));
 
-return false;
-}
+if (getB2DPolyPolygon() != rCompare.getB2DPolyPolygon())
+retu

core.git: drawinglayer/source include/drawinglayer

2024-07-16 Thread Armin Le Grand (Collabora) (via logerrit)
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |  175 +++--
 drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx|6 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   23 +
 include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx   |2 
 4 files changed, 178 insertions(+), 28 deletions(-)

New commits:
commit d1c6eeba13c2551e270e8ff0ba919fc9bac101c9
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Jul 16 14:34:58 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Jul 16 21:15:02 2024 +0200

CairoSDPR: Direct support for RGBA Gradients (II)

This step wil now use the new primitive
PolyPolygonRGBAGradientPrimitive2D inside the
CairoSDPR/CairoPixelProcessor2D to directly
render gradients as RGBA, without painting
RGB (content) and A (alpha) separate and mixing
the results.
Note that this is only possible for gradients
which use the same graphical definition, see the
method 'sameDefinitionThanAlpha' and it's usages
in the code.

Change-Id: I6c46a211ea26d3e4b7bb39c7f2aaff09ec38dec5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170584
Reviewed-by: Armin Le Grand 
Tested-by: Jenkins

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 1de46473d790..5761d8f4bdb1 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1263,8 +1264,10 @@ void CairoPixelProcessor2D::processInvertPrimitive2D(
 cairo_restore(mpRT);
 }
 
-void CairoPixelProcessor2D::processMaskPrimitive2DPixel(
-const primitive2d::MaskPrimitive2D& rMaskCandidate)
+void CairoPixelProcessor2D::processMaskPrimitive2D(
+const primitive2d::MaskPrimitive2D& rMaskCandidate,
+const primitive2d::FillGradientPrimitive2D* pFillGradientPrimitive2D,
+const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
 if (rMaskCandidate.getChildren().empty())
 {
@@ -1314,8 +1317,20 @@ void CairoPixelProcessor2D::processMaskPrimitive2DPixel(
 cairo_clip(mpRT);
 cairo_new_path(mpRT);
 
-// process sub-content (that shall be masked)
-process(rMaskCandidate.getChildren());
+if (nullptr != pFillGradientPrimitive2D && nullptr != pFillGradientAlpha)
+{
+// special case: render given FillGradientPrimitive2D using
+// FillGradientAlpha as RGBA gradient directly
+// note that calling this method with nullptr != pFillGradientAlpha
+// is only allowed internal from
+// CairoPixelProcessor2D::processPolyPolygonRGBAGradientPrimitive2D
+processFillGradientPrimitive2D(*pFillGradientPrimitive2D, 
pFillGradientAlpha);
+}
+else
+{
+// process sub-content (that shall be masked)
+process(rMaskCandidate.getChildren());
+}
 
 cairo_restore(mpRT);
 }
@@ -1922,7 +1937,8 @@ bool 
CairoPixelProcessor2D::processFillGradientPrimitive2D_isCompletelyBordered(
 }
 
 void CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
-const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D)
+const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
 assert(
 (css::awt::GradientStyle_LINEAR == 
rFillGradientPrimitive2D.getFillGradient().getStyle()
@@ -1964,6 +1980,10 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
 
 // get color stops (make copy, might have to be changed)
 basegfx::BColorStops aBColorStops(rFillGradient.getColorStops());
+basegfx::BColorStops aBColorStopsAlpha;
+const bool bHasAlpha(nullptr != pFillGradientAlpha);
+if (bHasAlpha)
+aBColorStopsAlpha = pFillGradientAlpha->getColorStops();
 const bool bAxial(css::awt::GradientStyle_AXIAL == 
rFillGradient.getStyle());
 
 // get and apply border - create soace at start in gradient
@@ -1971,30 +1991,58 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
 if (!basegfx::fTools::equalZero(fBorder))
 {
 if (bAxial)
+{
 aBColorStops.reverseColorStops();
+if (bHasAlpha)
+aBColorStopsAlpha.reverseColorStops();
+}
+
 aBColorStops.createSpaceAtStart(fBorder);
+if (bHasAlpha)
+aBColorStopsAlpha.createSpaceAtStart(fBorder);
+
 if (bAxial)
+{
 aBColorStops.reverseColorStops();
+if (bHasAlpha)
+aBColorStopsAlpha.reverseColorStops();
+}
 }
 
 if (bAxial)
 {
 // expand with mirrored ColorStops to create axial
 aBColorStops.doApplyAxial();
+if (bHasAlpha)
+aBColorStopsAlpha.doApplyAxial();
 }
 
 // Apply steps if

core.git: basegfx/source drawinglayer/source include/basegfx include/drawinglayer svx/inc svx/source

2024-07-16 Thread Armin Le Grand (Collabora) (via logerrit)
 basegfx/source/tools/bgradient.cxx  |   19 
 drawinglayer/source/attribute/fillgradientattribute.cxx |   33 
+++
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx  |   46 
++
 drawinglayer/source/primitive2d/Tools.cxx   |2 
 include/basegfx/utils/bgradient.hxx |4 
 include/drawinglayer/attribute/fillgradientattribute.hxx|4 
 include/drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx |   41 

 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx  |2 
 svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx   |4 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx|   40 
++--
 10 files changed, 183 insertions(+), 12 deletions(-)

New commits:
commit a073b6133960734b809c1bc93e39a76fdf1e7c15
Author: Armin Le Grand (Collabora) 
AuthorDate: Mon Jul 15 18:55:56 2024 +0200
Commit: Armin Le Grand 
CommitDate: Tue Jul 16 13:10:10 2024 +0200

CairoSDPR: Direct support for RGBA Gradients (I)

Detect where created when a RGBA gradient could be
used directly and create a primitive representing
that, a PolyPolygonRGBAGradientPrimitive2D.
That primitive decomposes to what was created before,
so no primitive renderer has to be touched, all will
work as before.
NOTE: That helper primitive just holds references to
what would be created anyways, so one depth step
added but not really any additional data.
This is the 1st step for direct support, the 2nd is
to then detect and use that primitive in SDPR
implementations directly.

Change-Id: I4f247636ce58a8a1fd1e0df32dabed0d6cc10d0e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170527
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/basegfx/source/tools/bgradient.cxx 
b/basegfx/source/tools/bgradient.cxx
index e27ab160463b..bac738ad3221 100644
--- a/basegfx/source/tools/bgradient.cxx
+++ b/basegfx/source/tools/bgradient.cxx
@@ -746,6 +746,25 @@ void BColorStops::tryToApplyBColorModifierStack(const 
BColorModifierStack& rBCol
 }
 }
 
+bool BColorStops::sameSizeAndDistances(const BColorStops& rComp) const
+{
+if (size() != rComp.size())
+{
+return false;
+}
+
+BColorStops::const_iterator EntryA(begin());
+BColorStops::const_iterator EntryB(rComp.begin());
+
+while (EntryA != end() && fTools::equal(EntryA->getStopOffset(), 
EntryB->getStopOffset()))
+{
+EntryA++;
+EntryB++;
+}
+
+return EntryA == end();
+}
+
 std::string BGradient::GradientStyleToString(css::awt::GradientStyle eStyle)
 {
 switch (eStyle)
diff --git a/drawinglayer/source/attribute/fillgradientattribute.cxx 
b/drawinglayer/source/attribute/fillgradientattribute.cxx
index e02fdd4a5dad..54f455f647ef 100644
--- a/drawinglayer/source/attribute/fillgradientattribute.cxx
+++ b/drawinglayer/source/attribute/fillgradientattribute.cxx
@@ -223,6 +223,39 @@ namespace drawinglayer::attribute
 return mpFillGradientAttribute->getSteps();
 }
 
+bool FillGradientAttribute::sameDefinitionThanAlpha(const 
FillGradientAttribute& rAlpha) const
+{
+// entries that are used by all gradient styles
+if (getStyle() != rAlpha.getStyle()
+|| getBorder() != rAlpha.getBorder()
+|| getSteps() != rAlpha.getSteps())
+{
+return false;
+}
+
+// check for offsets if not ignored
+const bool bIgnoreOffset(css::awt::GradientStyle_LINEAR == 
getStyle() || css::awt::GradientStyle_AXIAL == getStyle());
+if (!bIgnoreOffset && (getOffsetX() != rAlpha.getOffsetX() || 
getOffsetY() != rAlpha.getOffsetY()))
+{
+return false;
+}
+
+// check for angle if not ignored
+const bool bIgnoreAngle(css::awt::GradientStyle_RADIAL == 
getStyle());
+if (!bIgnoreAngle && getAngle() != rAlpha.getAngle())
+{
+return false;
+}
+
+// check for same count & offsets in the gradients (all except 
'colors')
+if (!getColorStops().sameSizeAndDistances(rAlpha.getColorStops()))
+{
+return false;
+}
+
+return true;
+}
+
 } // end of namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
index 4fe3321e62f8..2e6b83ab526f 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
@@ -22,6 +22,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -84,6 +86,

[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - basegfx/source include/basegfx

2020-05-14 Thread Armin Le Grand (Collabora) (via logerrit)
 basegfx/source/polygon/b2dpolygontools.cxx  |  419 
 include/basegfx/polygon/b2dpolygontools.hxx |   24 +
 2 files changed, 263 insertions(+), 180 deletions(-)

New commits:
commit d892e03f7dcbb7b8a6cc6a78dd758bab95ddded1
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Feb 14 12:32:42 2020 +0100
Commit: Miklos Vajna 
CommitDate: Thu May 14 09:06:32 2020 +0200

tdf#130655 added callback interface to ::applyLineDashing

This version of the tooling method allows to avoid collecting line
snippets in a return value PolyPolygon. Instead, offer lambda
functions to get callbacks for created snippets. The original
method using a B2DPolyPolygon return value is adapted to already
use this, so serves as example of usage and ensures that only
one identical algorithm is used.

(cherry picked from commit 0dc4fddb9c76a3f4682eca4059b42a079e74e735)

[ Fixes the cui/ build. ]

Change-Id: Ie306968a895ad280fc2425fb40b3244769216ba0

diff --git a/basegfx/source/polygon/b2dpolygontools.cxx 
b/basegfx/source/polygon/b2dpolygontools.cxx
index cbc18ee74203..245ed957fac3 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -1113,7 +1113,102 @@ namespace basegfx
 return false;
 }
 
-void applyLineDashing(const B2DPolygon& rCandidate, const 
std::vector& rDotDashArray, B2DPolyPolygon* pLineTarget, 
B2DPolyPolygon* pGapTarget, double fDotDashLength)
+void applyLineDashing(
+const B2DPolygon& rCandidate,
+const std::vector& rDotDashArray,
+B2DPolyPolygon* pLineTarget,
+B2DPolyPolygon* pGapTarget,
+double fDotDashLength)
+{
+// clear targets in any case
+if(pLineTarget)
+{
+pLineTarget->clear();
+}
+
+if(pGapTarget)
+{
+pGapTarget->clear();
+}
+
+// provide callbacks as lambdas
+auto aLineCallback(
+nullptr == pLineTarget
+? std::function()
+: [&pLineTarget](const basegfx::B2DPolygon& rSnippet){ 
pLineTarget->append(rSnippet); });
+auto aGapCallback(
+nullptr == pGapTarget
+? std::function()
+: [&pGapTarget](const basegfx::B2DPolygon& rSnippet){ 
pGapTarget->append(rSnippet); });
+
+// call version that uses callbacks
+applyLineDashing(
+rCandidate,
+rDotDashArray,
+aLineCallback,
+aGapCallback,
+fDotDashLength);
+}
+
+static void implHandleSnippet(
+const B2DPolygon& rSnippet,
+std::function& 
rTargetCallback,
+B2DPolygon& rFirst,
+B2DPolygon& rLast)
+{
+if(rSnippet.isClosed())
+{
+if(!rFirst.count())
+{
+rFirst = rSnippet;
+}
+else
+{
+if(rLast.count())
+{
+rTargetCallback(rLast);
+}
+
+rLast = rSnippet;
+}
+}
+else
+{
+rTargetCallback(rSnippet);
+}
+}
+
+static void implHandleFirstLast(
+std::function& 
rTargetCallback,
+B2DPolygon& rFirst,
+B2DPolygon& rLast)
+{
+if(rFirst.count() && rLast.count()
+&& rFirst.getB2DPoint(0).equal(rLast.getB2DPoint(rLast.count() 
- 1)))
+{
+// start of first and end of last are the same -> merge them
+rLast.append(rFirst);
+rLast.removeDoublePoints();
+rFirst.clear();
+}
+
+if(rLast.count())
+{
+rTargetCallback(rLast);
+}
+
+if(rFirst.count())
+{
+rTargetCallback(rFirst);
+}
+}
+
+void applyLineDashing(
+const B2DPolygon& rCandidate,
+const std::vector& rDotDashArray,
+std::function 
aLineTargetCallback,
+std::function 
aGapTargetCallback,
+double fDotDashLength)
 {
 const sal_uInt32 nPointCount(rCandidate.count());
 const sal_uInt32 nDotDashCount(rDotDashArray.size());
@@ -1123,244 +1218,210 @@ namespace basegfx
 fDotDashLength = std::accumulate(rDotDashArray.begin(), 
rDotDashArray.end(), 0.0);
 }
 
-if(fTools::more(fDotDashLength, 0.0) && (pLineTarget || 
pGapTarget) && nPointCount)
+if(fTools::lessOrEqual(fDotDashLength, 0.0) || 
(!aLineTargetCallback && !aGapTargetCallback) || !nPointCount)
   

[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - cui/source

2020-04-29 Thread Armin Le Grand (Collabora) (via logerrit)
 cui/source/tabpages/grfpage.cxx |   58 
 1 file changed, 47 insertions(+), 11 deletions(-)

New commits:
commit 56b207065ce0b4c86178131ae43fbbc31165727e
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Apr 28 15:48:50 2020 +0530
Commit: Andras Timar 
CommitDate: Wed Apr 29 09:06:45 2020 +0200

tdf#132381: Avoid XOR paint in Crop dialog

Change-Id: I9d3709f9d2a09de1eaace916dc6033de13dbff86
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93048
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Andras Timar 

diff --git a/cui/source/tabpages/grfpage.cxx b/cui/source/tabpages/grfpage.cxx
index d42f42a7f045..083f362c1acf 100644
--- a/cui/source/tabpages/grfpage.cxx
+++ b/cui/source/tabpages/grfpage.cxx
@@ -35,6 +35,11 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 #define CM_1_TO_TWIP567
 #define TWIP_TO_INCH1440
@@ -698,27 +703,58 @@ void SvxCropExample::SetDrawingArea(weld::DrawingArea* 
pDrawingArea)
 
 void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const 
::tools::Rectangle&)
 {
-rRenderContext.Push(PushFlags::MAPMODE | PushFlags::RASTEROP);
+rRenderContext.Push(PushFlags::MAPMODE);
 rRenderContext.SetMapMode(m_aMapMode);
 
-Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+// Win BG
+const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
 rRenderContext.SetLineColor();
 
rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
 rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
 
-rRenderContext.SetLineColor(COL_WHITE);
-::tools::Rectangle aRect(Point((aWinSize.Width() - m_aFrameSize.Width())/2,
-  (aWinSize.Height() - m_aFrameSize.Height())/2),
-  m_aFrameSize);
+// use AA, the Graphic may be a metafile/svg and would then look ugly
+rRenderContext.SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+
+// draw Graphic
+::tools::Rectangle aRect(
+Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() 
- m_aFrameSize.Height())/2),
+m_aFrameSize);
 m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize());
 
-rRenderContext.SetFillColor(COL_TRANSPARENT);
-rRenderContext.SetRasterOp(RasterOp::Invert);
-aRect.AdjustLeft(m_aTopLeft.Y() );
-aRect.AdjustTop(m_aTopLeft.X() );
+// Remove one more case that uses XOR paint (RasterOp::Invert).
+// Get colors and logic DashLength from settings, use equal to
+// PolygonMarkerPrimitive2D, may be changed to that primitive later.
+// Use this to guarantee good visibility - that was the purpose of
+// the former used XOR paint.
+const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+const Color aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
+const Color aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
+const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
+const basegfx::B2DVector 
aDashVector(rRenderContext.GetInverseViewTransformation() * 
basegfx::B2DVector(fStripeLength, 0.0));
+const double fLogicDashLength(aDashVector.getX());
+
+// apply current crop settings
+aRect.AdjustLeft(m_aTopLeft.Y());
+aRect.AdjustTop(m_aTopLeft.X());
 aRect.AdjustRight(-m_aBottomRight.Y());
 aRect.AdjustBottom(-m_aBottomRight.X());
-rRenderContext.DrawRect(aRect);
+
+// apply dash with direct paint callbacks
+basegfx::utils::applyLineDashing(
+basegfx::utils::createPolygonFromRect(
+basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), 
aRect.Bottom())),
+std::vector< double >(2, fLogicDashLength),
+[&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+{
+rRenderContext.SetLineColor(aColA);
+rRenderContext.DrawPolyLine(rSnippet);
+},
+[&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+{
+rRenderContext.SetLineColor(aColB);
+rRenderContext.DrawPolyLine(rSnippet);
+},
+2.0 * fLogicDashLength);
 
 rRenderContext.Pop();
 }
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - vcl/source

2020-02-24 Thread Armin Le Grand (Collabora) (via logerrit)
 vcl/source/outdev/bitmap.cxx |   15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

New commits:
commit 1c62465ff27a5721fac7f60798e8d674fefdd2aa
Author: Armin Le Grand (Collabora) 
AuthorDate: Sat Feb 22 16:38:50 2020 +0100
Commit: Miklos Vajna 
CommitDate: Mon Feb 24 14:39:38 2020 +0100

tdf#130768 need to use mnOutOffX/mnOutOffY

in OutputDevice local stuff when want to get
to pixel coordiantes. These are not often used
local members of OutputDevice specially used
in fake-Windows as internal windows offset.
Thus there is the protected internal replacement
ImplGetDeviceTransformation() for the usually
used GetViewTransformation().
A very problematic thing - we should in principle
add this to GetViewTransformation() but I am sure
that this will lead to other problems - argh!

Change-Id: Ibedc3a7d6eb3f17c266082729872b81f607836a5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89259
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 
(cherry picked from commit f1d6788fe1767f97e3ca2c67c7415f8c18c3d618)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89340
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Miklos Vajna 

diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 7fe75ec21a14..4aba910cf599 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -1230,7 +1230,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 
 if(bAllowPreferDirectPaint && bTryDirectPaint)
 {
-const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned 
at
+// ImplGetDeviceTransformation declaration
+const basegfx::B2DHomMatrix 
aFullTransform(ImplGetDeviceTransformation() * rTransformation);
 
 if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx))
 {
@@ -1277,7 +1280,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 // to specify order of executions, so give bTryDirectPaint a call
 if(bTryDirectPaint)
 {
-const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned 
at
+// ImplGetDeviceTransformation declaration
+const basegfx::B2DHomMatrix 
aFullTransform(ImplGetDeviceTransformation() * rTransformation);
 
 if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx))
 {
@@ -1316,7 +1322,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 const double fOrigArea(rOriginalSizePixel.Width() * 
rOriginalSizePixel.Height() * 0.5);
 const double fOrigAreaScaled(fOrigArea * 1.44);
 double fMaximumArea(std::min(450.0, std::max(100.0, 
fOrigAreaScaled)));
-basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned at
+// ImplGetDeviceTransformation declaration
+basegfx::B2DHomMatrix aFullTransform(ImplGetDeviceTransformation() * 
rTransformation);
 
 if(!bMetafile)
 {
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - sw/source vcl/headless vcl/inc vcl/source

2020-02-24 Thread Armin Le Grand (Collabora) (via logerrit)
 sw/source/core/doc/notxtfrm.cxx |  198 ++--
 sw/source/core/inc/frmtool.hxx  |6 
 sw/source/core/inc/notxtfrm.hxx |6 
 vcl/headless/svpbmp.cxx |7 +
 vcl/headless/svpgdi.cxx |  219 ---
 vcl/inc/headless/svpbmp.hxx |   26 
 vcl/source/outdev/bitmap.cxx|  247 
 7 files changed, 602 insertions(+), 107 deletions(-)

New commits:
commit ef6f94e93bbe55a26b67b55b2aecda67d406ab85
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Feb 21 16:58:17 2020 +0100
Commit: Miklos Vajna 
CommitDate: Mon Feb 24 13:10:29 2020 +0100

tdf#130768 speedup huge pixel graphics Cairo

For more information/documentation please
refer to the bugzilla task

Fixed a crash in CppunitTest_desktop_lib which
led to a missing test of mpGraphics in
OutputDevice::DrawTransformedBitmapEx. Other
public methods test that and one of the goals
of the cange was to use that method more often,
so this may have never been detected before

Change-Id: I10e57bd05db0c8cf868ff98d63f5af3d116a3015
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89230
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89252
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Miklos Vajna 

diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 04e556277738..f2b148361994 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -82,6 +82,14 @@
 #include 
 #include 
 
+// MM02 needed for VOC mechanism and getting the OC - may be moved to an own 
file
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
 using namespace com::sun::star;
 
 static bool GetRealURL( const SwGrfNode& rNd, OUString& rText )
@@ -148,7 +156,9 @@ static void lcl_PaintReplacement( const SwRect &rRect, 
const OUString &rText,
 SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib )
 :   SwContentFrame( pNode, pSib ),
 // RotateFlyFrame3
-mpTransformableSwFrame()
+mpTransformableSwFrame(),
+// MM02
+mpViewContact()
 {
 mnFrameType = SwFrameType::NoTxt;
 }
@@ -925,6 +935,7 @@ static bool paintUsingPrimitivesHelper(
 return false;
 }
 
+// MM02 original using falölback to VOC and primitive-based version
 void paintGraphicUsingPrimitivesHelper(
 vcl::RenderContext & rOutputDevice,
 GraphicObject const& rGrfObj,
@@ -936,12 +947,24 @@ void paintGraphicUsingPrimitivesHelper(
 // -> the primitive renderer will create the needed pdf export data
 // -> if bitmap content, it will be cached system-dependent
 drawinglayer::primitive2d::Primitive2DContainer aContent(1);
-
 aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
 rGraphicTransform,
 rGrfObj,
 rGraphicAttr);
 
+// MM02 use primitive-based version for visualization
+paintGraphicUsingPrimitivesHelper(
+rOutputDevice,
+aContent,
+rGraphicTransform);
+}
+
+// MM02 new VOC and primitive-based version
+void paintGraphicUsingPrimitivesHelper(
+vcl::RenderContext & rOutputDevice,
+drawinglayer::primitive2d::Primitive2DContainer& rContent,
+const basegfx::B2DHomMatrix& rGraphicTransform)
+{
 // RotateFlyFrame3: If ClipRegion is set at OutputDevice, we
 // need to use that. Usually the renderer would be a VCL-based
 // PrimitiveRenderer, but there are system-specific shortcuts that
@@ -1008,9 +1031,12 @@ void paintGraphicUsingPrimitivesHelper(
 aTarget.append(aClip);
 }
 
-aContent[0] = new drawinglayer::primitive2d::MaskPrimitive2D(
-aTarget,
-aContent);
+drawinglayer::primitive2d::MaskPrimitive2D* pNew(
+new drawinglayer::primitive2d::MaskPrimitive2D(
+aTarget,
+rContent));
+rContent.resize(1);
+rContent[0] = pNew;
 }
 }
 
@@ -1019,11 +1045,111 @@ void paintGraphicUsingPrimitivesHelper(
 
 paintUsingPrimitivesHelper(
 rOutputDevice,
-aContent,
+rContent,
 aTargetRange,
 aTargetRange);
 }
 
+// DrawContact section
+namespace { // anonymous namespace
+class ViewObjectContactOfSwNoTextFrame : public sdr::contact::ViewObjectContact
+{
+protected:
+virtual drawinglayer::primitive2d::Primitive2DContainer 
createPrimitive2DSequence(
+const sdr::contact::DisplayInfo& rDisplayInfo) const override;
+
+public:
+ViewObjectContactOfSwNoTextFrame(
+sdr::contact::ObjectContact& rObjectContact,
+sdr::contact::ViewContact& rViewContact);
+};
+
+class ViewContactOfSwNoTextFrame : public sdr::contact::ViewContact
+{
+private:
+// owner
+const SwNoTextFrame&mrSwNoTextFrame;
+
+protected:
+// Create an Object-Specific Vi

[Libreoffice-commits] core.git: vcl/source

2020-02-22 Thread Armin Le Grand (Collabora) (via logerrit)
 vcl/source/outdev/bitmap.cxx |   15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

New commits:
commit f1d6788fe1767f97e3ca2c67c7415f8c18c3d618
Author: Armin Le Grand (Collabora) 
AuthorDate: Sat Feb 22 16:38:50 2020 +0100
Commit: Armin Le Grand 
CommitDate: Sat Feb 22 17:43:44 2020 +0100

tdf#130768 need to use mnOutOffX/mnOutOffY

in OutputDevice local stuff when want to get
to pixel coordiantes. These are not often used
local members of OutputDevice specially used
in fake-Windows as internal windows offset.
Thus there is the protected internal replacement
ImplGetDeviceTransformation() for the usually
used GetViewTransformation().
A very problematic thing - we should in principle
add this to GetViewTransformation() but I am sure
that this will lead to other problems - argh!

Change-Id: Ibedc3a7d6eb3f17c266082729872b81f607836a5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89259
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 9821fa0aade5..719c9e6e0b2a 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -1222,7 +1222,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 
 if(bAllowPreferDirectPaint && bTryDirectPaint)
 {
-const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned 
at
+// ImplGetDeviceTransformation declaration
+const basegfx::B2DHomMatrix 
aFullTransform(ImplGetDeviceTransformation() * rTransformation);
 
 if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx))
 {
@@ -1269,7 +1272,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 // to specify order of executions, so give bTryDirectPaint a call
 if(bTryDirectPaint)
 {
-const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned 
at
+// ImplGetDeviceTransformation declaration
+const basegfx::B2DHomMatrix 
aFullTransform(ImplGetDeviceTransformation() * rTransformation);
 
 if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx))
 {
@@ -1308,7 +1314,10 @@ void OutputDevice::DrawTransformedBitmapEx(
 const double fOrigArea(rOriginalSizePixel.Width() * 
rOriginalSizePixel.Height() * 0.5);
 const double fOrigAreaScaled(fOrigArea * 1.44);
 double fMaximumArea(std::min(450.0, std::max(100.0, 
fOrigAreaScaled)));
-basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * 
rTransformation);
+// tdf#130768 CAUTION(!) using GetViewTransformation() is *not* enough 
here, it may
+// be that mnOutOffX/mnOutOffY is used - see AOO bug 75163, mentioned at
+// ImplGetDeviceTransformation declaration
+basegfx::B2DHomMatrix aFullTransform(ImplGetDeviceTransformation() * 
rTransformation);
 
 if(!bMetafile)
 {
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: sw/source vcl/headless vcl/inc vcl/source

2020-02-21 Thread Armin Le Grand (Collabora) (via logerrit)
 sw/source/core/doc/notxtfrm.cxx |  228 +---
 sw/source/core/inc/frmtool.hxx  |9 +
 sw/source/core/inc/notxtfrm.hxx |6 
 vcl/headless/svpbmp.cxx |7 
 vcl/headless/svpgdi.cxx |  219 +++---
 vcl/inc/headless/svpbmp.hxx |   26 +++
 vcl/source/outdev/bitmap.cxx|  285 
 7 files changed, 625 insertions(+), 155 deletions(-)

New commits:
commit 828504974d70111e4a35b31d579cf42fe660a660
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Feb 21 16:58:17 2020 +0100
Commit: Armin Le Grand 
CommitDate: Fri Feb 21 20:16:59 2020 +0100

tdf#130768 speedup huge pixel graphics Cairo

For more information/documentation please
refer to the bugzilla task

Fixed a crash in CppunitTest_desktop_lib which
led to a missing test of mpGraphics in
OutputDevice::DrawTransformedBitmapEx. Other
public methods test that and one of the goals
of the cange was to use that method more often,
so this may have never been detected before

Change-Id: I10e57bd05db0c8cf868ff98d63f5af3d116a3015
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89230
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 9858cc3eebfa..86a74dc66fc2 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -74,6 +74,14 @@
 #include 
 #include 
 
+// MM02 needed for VOC mechanism and getting the OC - may be moved to an own 
file
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
 using namespace com::sun::star;
 
 static bool GetRealURL( const SwGrfNode& rNd, OUString& rText )
@@ -140,7 +148,9 @@ static void lcl_PaintReplacement( const SwRect &rRect, 
const OUString &rText,
 SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib )
 :   SwContentFrame( pNode, pSib ),
 // RotateFlyFrame3
-mpTransformableSwFrame()
+mpTransformableSwFrame(),
+// MM02
+mpViewContact()
 {
 mnFrameType = SwFrameType::NoTxt;
 }
@@ -917,6 +927,7 @@ static bool paintUsingPrimitivesHelper(
 return false;
 }
 
+// MM02 original using falölback to VOC and primitive-based version
 void paintGraphicUsingPrimitivesHelper(
 vcl::RenderContext & rOutputDevice,
 GraphicObject const& rGrfObj,
@@ -931,12 +942,30 @@ void paintGraphicUsingPrimitivesHelper(
 // -> the primitive renderer will create the needed pdf export data
 // -> if bitmap content, it will be cached system-dependent
 drawinglayer::primitive2d::Primitive2DContainer aContent(1);
-
 aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
 rGraphicTransform,
 rGrfObj,
 rGraphicAttr);
 
+// MM02 use primitive-based version for visualization
+paintGraphicUsingPrimitivesHelper(
+rOutputDevice,
+aContent,
+rGraphicTransform,
+rName,
+rTitle,
+rDescription);
+}
+
+// MM02 new VOC and primitive-based version
+void paintGraphicUsingPrimitivesHelper(
+vcl::RenderContext & rOutputDevice,
+drawinglayer::primitive2d::Primitive2DContainer& rContent,
+const basegfx::B2DHomMatrix& rGraphicTransform,
+const OUString& rName,
+const OUString& rTitle,
+const OUString& rDescription)
+{
 // RotateFlyFrame3: If ClipRegion is set at OutputDevice, we
 // need to use that. Usually the renderer would be a VCL-based
 // PrimitiveRenderer, but there are system-specific shortcuts that
@@ -1003,9 +1032,12 @@ void paintGraphicUsingPrimitivesHelper(
 aTarget.append(aClip);
 }
 
-aContent[0] = new drawinglayer::primitive2d::MaskPrimitive2D(
-aTarget,
-aContent);
+drawinglayer::primitive2d::MaskPrimitive2D* pNew(
+new drawinglayer::primitive2d::MaskPrimitive2D(
+aTarget,
+rContent));
+rContent.resize(1);
+rContent[0] = pNew;
 }
 }
 
@@ -1013,11 +1045,14 @@ void paintGraphicUsingPrimitivesHelper(
 {
 // Embed to ObjectInfoPrimitive2D when we have Name/Title/Description
 // information available
-aContent[0] = new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
-aContent,
-rName,
-rTitle,
-rDescription);
+drawinglayer::primitive2d::ObjectInfoPrimitive2D* pNew(
+new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
+rContent,
+rName,
+rTitle,
+rDescription));
+rContent.resize(1);
+rContent[0] = pNew;
 }
 
 basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0);
@@ -1025,11 +1060,111 @@ void paintGraphicUsingPrimitivesHelper(
 
 paintUsingPrimitivesHelper(
 rOutputDevice,
-aContent,
+rContent

[Libreoffice-commits] core.git: basegfx/source include/basegfx

2020-02-14 Thread Armin Le Grand (Collabora) (via logerrit)
 basegfx/source/polygon/b2dpolygontools.cxx  |  419 
 include/basegfx/polygon/b2dpolygontools.hxx |   24 +
 2 files changed, 263 insertions(+), 180 deletions(-)

New commits:
commit 0dc4fddb9c76a3f4682eca4059b42a079e74e735
Author: Armin Le Grand (Collabora) 
AuthorDate: Fri Feb 14 12:32:42 2020 +0100
Commit: Armin Le Grand 
CommitDate: Fri Feb 14 16:44:26 2020 +0100

tdf#130655 added callback interface to ::applyLineDashing

This version of the tooling method allows to avoid collecting line
snippets in a return value PolyPolygon. Instead, offer lambda
functions to get callbacks for created snippets. The original
method using a B2DPolyPolygon return value is adapted to already
use this, so serves as example of usage and ensures that only
one identical algorithm is used.

Change-Id: Ie306968a895ad280fc2425fb40b3244769216ba0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88684
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/basegfx/source/polygon/b2dpolygontools.cxx 
b/basegfx/source/polygon/b2dpolygontools.cxx
index cf2de34859cd..68d1120bc2cb 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -1110,7 +1110,102 @@ namespace basegfx::utils
 return false;
 }
 
-void applyLineDashing(const B2DPolygon& rCandidate, const 
std::vector& rDotDashArray, B2DPolyPolygon* pLineTarget, 
B2DPolyPolygon* pGapTarget, double fDotDashLength)
+void applyLineDashing(
+const B2DPolygon& rCandidate,
+const std::vector& rDotDashArray,
+B2DPolyPolygon* pLineTarget,
+B2DPolyPolygon* pGapTarget,
+double fDotDashLength)
+{
+// clear targets in any case
+if(pLineTarget)
+{
+pLineTarget->clear();
+}
+
+if(pGapTarget)
+{
+pGapTarget->clear();
+}
+
+// provide callbacks as lambdas
+auto aLineCallback(
+nullptr == pLineTarget
+? std::function()
+: [&pLineTarget](const basegfx::B2DPolygon& rSnippet){ 
pLineTarget->append(rSnippet); });
+auto aGapCallback(
+nullptr == pGapTarget
+? std::function()
+: [&pGapTarget](const basegfx::B2DPolygon& rSnippet){ 
pGapTarget->append(rSnippet); });
+
+// call version that uses callbacks
+applyLineDashing(
+rCandidate,
+rDotDashArray,
+aLineCallback,
+aGapCallback,
+fDotDashLength);
+}
+
+static void implHandleSnippet(
+const B2DPolygon& rSnippet,
+std::function& 
rTargetCallback,
+B2DPolygon& rFirst,
+B2DPolygon& rLast)
+{
+if(rSnippet.isClosed())
+{
+if(!rFirst.count())
+{
+rFirst = rSnippet;
+}
+else
+{
+if(rLast.count())
+{
+rTargetCallback(rLast);
+}
+
+rLast = rSnippet;
+}
+}
+else
+{
+rTargetCallback(rSnippet);
+}
+}
+
+static void implHandleFirstLast(
+std::function& 
rTargetCallback,
+B2DPolygon& rFirst,
+B2DPolygon& rLast)
+{
+if(rFirst.count() && rLast.count()
+&& rFirst.getB2DPoint(0).equal(rLast.getB2DPoint(rLast.count() 
- 1)))
+{
+// start of first and end of last are the same -> merge them
+rLast.append(rFirst);
+rLast.removeDoublePoints();
+rFirst.clear();
+}
+
+if(rLast.count())
+{
+rTargetCallback(rLast);
+}
+
+if(rFirst.count())
+{
+rTargetCallback(rFirst);
+}
+}
+
+void applyLineDashing(
+const B2DPolygon& rCandidate,
+const std::vector& rDotDashArray,
+std::function 
aLineTargetCallback,
+std::function 
aGapTargetCallback,
+double fDotDashLength)
 {
 const sal_uInt32 nPointCount(rCandidate.count());
 const sal_uInt32 nDotDashCount(rDotDashArray.size());
@@ -1120,244 +1215,210 @@ namespace basegfx::utils
 fDotDashLength = std::accumulate(rDotDashArray.begin(), 
rDotDashArray.end(), 0.0);
 }
 
-if(fTools::more(fDotDashLength, 0.0) && (pLineTarget || 
pGapTarget) && nPointCount)
+if(fTools::lessOrEqual(fDotDashLength, 0.0) || 
(!aLineTargetCallback && !aGapTargetCallback) ||

[Libreoffice-commits] core.git: cui/source

2020-02-13 Thread Armin Le Grand (Collabora) (via logerrit)
 cui/source/tabpages/align.cxx |   44 +-
 1 file changed, 18 insertions(+), 26 deletions(-)

New commits:
commit cfb9e6d9976fd7e87fc9605ca79264df041744ee
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Feb 13 15:40:34 2020 +0100
Commit: Armin Le Grand 
CommitDate: Thu Feb 13 22:43:44 2020 +0100

Revert "Related tdf#130428: let's add some asserts"

This reverts commit 9811796aba7360fc5b7230a8b314a56fbf6ab27a.

Revert "tdf#130428 SfxItemState::UNKNOWN replacements"

This reverts commit cf4e87469baf13fb2766d0f2593fcc2b9b33bc9b.

Change-Id: I976ade5e25db09e18297e46a5c92f8bc578399e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88610
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/cui/source/tabpages/align.cxx b/cui/source/tabpages/align.cxx
index 0488870a775e..30965cf9cb7f 100644
--- a/cui/source/tabpages/align.cxx
+++ b/cui/source/tabpages/align.cxx
@@ -393,14 +393,9 @@ namespace
 SfxItemState eState = pSet->GetItemState(nWhich);
 switch (eState)
 {
-default:
-// tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is (see below):
-// SID_ATTR_ALIGN_STACKED
-// SID_ATTR_ALIGN_ASIANVERTICAL
-// SID_ATTR_ALIGN_LINEBREAK
-// SID_ATTR_ALIGN_HYPHENATION
-// SID_ATTR_ALIGN_SHRINKTOFIT
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+rBtn.hide();
+rTriState.bTriStateEnabled = false;
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -438,9 +433,8 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 SfxItemState eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_ALIGN_HOR_JUSTIFY:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xLbHorAlign->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -482,9 +476,9 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_ALIGN_INDENT:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xEdIndent->hide();
+m_xFtIndent->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -506,9 +500,9 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_ALIGN_VER_JUSTIFY:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xLbVerAlign->hide();
+m_xFtVerAlign->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -547,9 +541,9 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_ALIGN_DEGREES:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xNfRotate->hide();
+m_xCtrlDialWin->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -572,9 +566,8 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_ALIGN_LOCKPOS:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xVsRefEdge->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READONLY:
@@ -612,9 +605,8 @@ void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
 eState = pCoreAttrs->GetItemState(nWhich);
 switch (eState)
 {
-default:
-//tdf#130428 SfxItemState::UNKNOWN cannot happen here, see 
s_pRanges. Input is SID_ATTR_FRAMEDIRECTION:
-assert(false && "UNKNOWN cannot happen here");
+case SfxItemState::UNKNOWN:
+m_xLbFrameDir->hide();
 break;
 case SfxItemState::DISABLED:
 case SfxItemState::READON

[Libreoffice-commits] core.git: vcl/win

2020-02-11 Thread Armin Le Grand (Collabora) (via logerrit)
 vcl/win/gdi/gdiimpl.cxx |   61 +---
 1 file changed, 58 insertions(+), 3 deletions(-)

New commits:
commit c3e098483f4db12e9502c6cbc056e3d7498b7b6c
Author: Armin Le Grand (Collabora) 
AuthorDate: Tue Feb 11 16:33:28 2020 +0100
Commit: Armin Le Grand 
CommitDate: Tue Feb 11 21:09:33 2020 +0100

tdf#130478 add direct dash paint in GDIPlus (win)

Not as easy as hoped, see more info in the adapted
file vcl\win\gdi\gdiimpl.cxx itself.

Change-Id: I265888c65658d5e8a2a04b6f064d2baf3e1d9bad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88463
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index f15f13a94370..a26d85d1e378 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -2309,7 +2309,62 @@ bool WinSalGraphicsImpl::drawPolyLine(
 const bool bStrokeUsed(0.0 != fDotDashLength);
 assert(!bStrokeUsed || (bStrokeUsed && pStroke));
 
-if(pSystemDependentData_GraphicsPath)
+// MM01 decide if to stroke directly
+static bool bDoDirectGDIPlusStroke(true);
+
+// activate to stroke directly
+if(bDoDirectGDIPlusStroke && bStrokeUsed)
+{
+// tdf#130478
+// Unfortunately GDIPlus wants to have the dash pattern relative to 
line width
+// which gets problematic due to the good old office's hairline 
definition. This
+// means that we do not *have* the real line width here, but 0.0 - or 
in the case
+// of GDIPlus (here) 1.0.
+// This is 'corrected' in several locations, e.g. 
OutputDevice::DrawPolyLineDirect
+// to 1.0 and 
VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect to 0.0.
+// This would need some cleanup what will be highly problematic due to 
the usage
+// of hairlines with line width of 0.0 being a pixel always and 
leading to different
+// visualizations. More bad - the potential of having pretty 
'invisible' lines
+// in unexpected places when zooming far out. Another problematic 
aspect of that hairline
+// definition is that this makes hairlines per definition 
view-transformation dependent
+// regarding their 'core' line width and the area they cover - handled 
in Primitives,
+// but not easy to do.
+// The way out here is to calculate back a single pixel from device to 
logic
+// (Object coordinates) to have the 'logic', view-dependent line width 
and use it.
+// That works for the cost of a matrix inversion - sigh.
+std::vector aDashArray(pStroke->size());
+double fFactor(1.0);
+
+if(rLineWidths.getX() <= 1.0)
+{
+// no 'real' line width, need to calculate back the logic line 
width
+// for a one pixel hairline
+basegfx::B2DHomMatrix aObjectToDeviceInv(rObjectToDevice);
+aObjectToDeviceInv.invert();
+const basegfx::B2DVector aOnePixel(aObjectToDeviceInv * 
basegfx::B2DVector(1.0, 1.0));
+
+if(aOnePixel.getX() > 0.0)
+{
+fFactor = 1.0 / aOnePixel.getX();
+}
+}
+else
+{
+// use logic line width
+fFactor = 1.0 / rLineWidths.getX();
+}
+
+for(size_t a(0); a < pStroke->size(); a++)
+{
+aDashArray[a] = Gdiplus::REAL((*pStroke)[a] * fFactor);
+}
+
+aPen.SetDashCap(Gdiplus::DashCapFlat);
+aPen.SetDashOffset(Gdiplus::REAL(0.0));
+aPen.SetDashPattern(aDashArray.data(), aDashArray.size());
+}
+
+if(!bDoDirectGDIPlusStroke && pSystemDependentData_GraphicsPath)
 {
 // MM01 - check on stroke change. Used against not used, or if oth 
used,
 // equal or different? Triangulation geometry creation depends heavily
@@ -2345,7 +2400,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
 // fill data of buffered data
 pGraphicsPath = std::make_shared();
 
-if(bStrokeUsed)
+if(!bDoDirectGDIPlusStroke && bStrokeUsed)
 {
 // MM01 need to do line dashing as fallback stuff here now
 basegfx::B2DPolyPolygon aPolyPolygonLine;
@@ -2373,7 +2428,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
 }
 else
 {
-// no line dashing, just copy
+// no line dashing or direct stroke, just copy
 impAddB2DPolygonToGDIPlusGraphicsPathReal(
 *pGraphicsPath,
 rPolygon,
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - cui/source drawinglayer/source include/vcl vcl/headless vcl/inc vcl/opengl vcl/qt5 vcl/quartz vcl/source vcl/unx vcl/win

2020-02-10 Thread Armin Le Grand (Collabora) (via logerrit)
 cui/source/dialogs/screenshotannotationdlg.cxx  |1 
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx  |2 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |   92 ++--
 include/vcl/outdev.hxx  |1 
 vcl/headless/svpgdi.cxx |  172 ++--
 vcl/inc/headless/svpgdi.hxx |2 
 vcl/inc/openglgdiimpl.hxx   |1 
 vcl/inc/qt5/Qt5Graphics.hxx |7 
 vcl/inc/quartz/salgdi.h |1 
 vcl/inc/salgdi.hxx  |2 
 vcl/inc/salgdiimpl.hxx  |1 
 vcl/inc/unx/genpspgraphics.h|1 
 vcl/inc/unx/salgdi.h|1 
 vcl/inc/win/salgdi.h|1 
 vcl/opengl/gdiimpl.cxx  |   70 --
 vcl/qt5/Qt5Graphics_GDI.cxx |   50 +++-
 vcl/quartz/salgdicommon.cxx |   66 --
 vcl/source/gdi/FileDefinitionWidgetDraw.cxx |4 
 vcl/source/gdi/salgdilayout.cxx |4 
 vcl/source/outdev/line.cxx  |2 
 vcl/source/outdev/polygon.cxx   |3 
 vcl/source/outdev/polyline.cxx  |5 
 vcl/source/outdev/transparent.cxx   |2 
 vcl/unx/generic/gdi/gdiimpl.cxx |   84 ++-
 vcl/unx/generic/gdi/gdiimpl.hxx |1 
 vcl/unx/generic/gdi/salgdi.cxx  |3 
 vcl/unx/generic/print/genpspgraphics.cxx|1 
 vcl/win/gdi/gdiimpl.cxx |  103 +++--
 vcl/win/gdi/gdiimpl.hxx |1 
 vcl/win/gdi/salgdi_gdiplus.cxx  |2 
 30 files changed, 487 insertions(+), 199 deletions(-)

New commits:
commit c069861bf9a32c826cbc86a086a774eba49c4e6f
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Feb 6 18:53:12 2020 +0100
Commit: Tor Lillqvist 
CommitDate: Tue Feb 11 07:19:01 2020 +0100

tdf#130478 Enhance Dashed line drawing on all systems

For more info and explanation including state of process
information and discussion(s) see task please.

Adding corrections for gerrit build

Cherry-picked 5f61c9fe99ac93087b898adddbb4d4733f1fcd07:
Adaptions made and checked that Caio fat line draw
works as expected. Surprisingly some new files were
created which I removed here again.
Also needs to be cherry-picked is:
9c9f76dd5b6fb115e521ac6568673c7a10879192
which will enable direct dash paint for Cairo.
Not done here due to not sure if I can do two
cherry-picks in one run and it's lust a view lines,
so -compared to this one- should be not difficult.

Change-Id: Ie10fb8093a86459dee80db5ab4355b47e46c1f8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88130
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88284
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Tor Lillqvist 

diff --git a/cui/source/dialogs/screenshotannotationdlg.cxx 
b/cui/source/dialogs/screenshotannotationdlg.cxx
index 8c3f6cfc528f..89ff425a5714 100644
--- a/cui/source/dialogs/screenshotannotationdlg.cxx
+++ b/cui/source/dialogs/screenshotannotationdlg.cxx
@@ -460,6 +460,7 @@ void ScreenshotAnnotationDlg_Impl::PaintControlDataEntry(
 aPolygon,
 fLineWidth,
 fTransparency,
+nullptr, // MM01
 basegfx::B2DLineJoin::Round))
 {
 // no transparency, draw without
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx 
b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
index ea2e9c9aede6..9861f6f09722 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -293,6 +293,7 @@ namespace drawinglayer
 maLineAttribute(rLineAttribute),
 maStrokeAttribute(rStrokeAttribute)
 {
+// MM01: keep these - these are no curve-decompposers but just 
checks
 // simplify curve segments: moved here to not need to use it
 // at VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect
 maPolygon = basegfx::utils::simplifyCurveSegments(maPolygon);
@@ -306,6 +307,7 @@ namespace drawinglayer
 maLineAttribute(rLineAttribute),
 maStrokeAttribute()
 {
+// MM01: keep these - these are no curve-decompposers but just 
checks
 // simplify curve segments: moved here to not need to use it
 // at VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect
 maPo

[Libreoffice-commits] core.git: basegfx/source cui/source drawinglayer/source include/basegfx include/vcl vcl/headless vcl/inc vcl/opengl vcl/qt5 vcl/quartz vcl/skia vcl/source vcl/unx vcl/win

2020-02-07 Thread Armin Le Grand (Collabora) (via logerrit)
 basegfx/source/polygon/b2dlinegeometry.cxx  |   23 +-
 cui/source/dialogs/screenshotannotationdlg.cxx  |1 
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx  |2 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |   92 +++---
 include/basegfx/polygon/b2dlinegeometry.hxx |   10 +
 include/vcl/outdev.hxx  |1 
 vcl/headless/svpgdi.cxx |  139 +++-
 vcl/inc/headless/svpgdi.hxx |2 
 vcl/inc/opengl/gdiimpl.hxx  |1 
 vcl/inc/qt5/Qt5Graphics.hxx |7 
 vcl/inc/quartz/salgdi.h |1 
 vcl/inc/salgdi.hxx  |2 
 vcl/inc/salgdiimpl.hxx  |1 
 vcl/inc/skia/gdiimpl.hxx|7 
 vcl/inc/unx/genpspgraphics.h|1 
 vcl/inc/unx/salgdi.h|1 
 vcl/inc/win/salgdi.h|1 
 vcl/opengl/gdiimpl.cxx  |   70 ++--
 vcl/qt5/Qt5Graphics_GDI.cxx |   50 -
 vcl/quartz/salgdicommon.cxx |   67 +--
 vcl/skia/gdiimpl.cxx|   58 +-
 vcl/source/gdi/FileDefinitionWidgetDraw.cxx |4 
 vcl/source/gdi/salgdilayout.cxx |4 
 vcl/source/outdev/line.cxx  |2 
 vcl/source/outdev/polygon.cxx   |3 
 vcl/source/outdev/polyline.cxx  |5 
 vcl/source/outdev/textline.cxx  |   13 +
 vcl/source/outdev/transparent.cxx   |2 
 vcl/unx/generic/gdi/gdiimpl.cxx |   88 +-
 vcl/unx/generic/gdi/gdiimpl.hxx |1 
 vcl/unx/generic/gdi/salgdi.cxx  |3 
 vcl/unx/generic/print/genpspgraphics.cxx|1 
 vcl/win/gdi/gdiimpl.cxx |   99 +--
 vcl/win/gdi/gdiimpl.hxx |1 
 vcl/win/gdi/salgdi_gdiplus.cxx  |2 
 35 files changed, 564 insertions(+), 201 deletions(-)

New commits:
commit 5f61c9fe99ac93087b898adddbb4d4733f1fcd07
Author: Armin Le Grand (Collabora) 
AuthorDate: Thu Feb 6 18:53:12 2020 +0100
Commit: Armin Le Grand 
CommitDate: Fri Feb 7 18:49:18 2020 +0100

tdf#130478 Enhance Dashed line drawing on all systems

For more info and explanation including state of process
information and discussion(s) see task please.

Adding corrections for gerrit build

Change-Id: Ie10fb8093a86459dee80db5ab4355b47e46c1f8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88130
Tested-by: Jenkins
Reviewed-by: Armin Le Grand 

diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx 
b/basegfx/source/polygon/b2dlinegeometry.cxx
index 0f602eb6241e..72c25f0c0593 100644
--- a/basegfx/source/polygon/b2dlinegeometry.cxx
+++ b/basegfx/source/polygon/b2dlinegeometry.cxx
@@ -848,7 +848,8 @@ namespace basegfx
 css::drawing::LineCap eCap,
 double fMaxAllowedAngle,
 double fMaxPartOfEdge,
-double fMiterMinimumAngle)
+double fMiterMinimumAngle,
+basegfx::triangulator::B2DTriangleVector* pTriangles)
 {
 if(fMaxAllowedAngle > F_PI2)
 {
@@ -958,7 +959,7 @@ namespace basegfx
 fHalfLineWidth,
 eJoin,
 fMiterMinimumAngle,
-nullptr));
+pTriangles));
 }
 else if(aOrientation == 
B2VectorOrientation::Negative)
 {
@@ -975,7 +976,7 @@ namespace basegfx
 fHalfLineWidth,
 eJoin,
 fMiterMinimumAngle,
-nullptr));
+pTriangles));
 }
 }
 
@@ -994,7 +995,7 @@ namespace basegfx
 bLast && eCap == 
css::drawing::LineCap_ROUND,
 bFirst && eCap == 
css::drawing::LineCap_SQUARE,
 bLast && eCap == 
css::drawing::LineCap_SQUARE,
-nullptr));
+pTriangles));
 }
 else
 {
@@ -1006,7 +1007,7 @@ namespace basegfx