core.git: drawinglayer/source
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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