|
|
48e38ea |
From f17080780f6240bb813a133f60c43aaad29b2584 Mon Sep 17 00:00:00 2001
|
|
|
6e9d999 |
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
|
|
|
6e9d999 |
Date: Tue, 24 Nov 2015 23:12:49 +0000
|
|
|
6e9d999 |
Subject: [PATCH] gtk3: implement drawPolyLine for svp/gtk3 backend
|
|
|
6e9d999 |
|
|
|
6e9d999 |
by stealing the quartz impl
|
|
|
6e9d999 |
|
|
|
6e9d999 |
(cherry picked from commit 3d22df17b33d6c66c3b7441bd220712ada53e667)
|
|
|
6e9d999 |
|
|
|
6e9d999 |
Change-Id: I548042328144e23c68b83e461a63cdb0d7d8ff2c
|
|
|
6e9d999 |
---
|
|
|
6e9d999 |
vcl/headless/svpgdi.cxx | 199 ++++++++++++++++++++++++++++++++++++++++--------
|
|
|
6e9d999 |
1 file changed, 166 insertions(+), 33 deletions(-)
|
|
|
6e9d999 |
|
|
|
6e9d999 |
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
|
|
|
48e38ea |
index cc4baab..21efd33 100644
|
|
|
6e9d999 |
--- a/vcl/headless/svpgdi.cxx
|
|
|
6e9d999 |
+++ b/vcl/headless/svpgdi.cxx
|
|
|
48e38ea |
@@ -156,6 +156,27 @@ namespace
|
|
|
6e9d999 |
|
|
|
6e9d999 |
return extents;
|
|
|
6e9d999 |
}
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_rectangle_int_t getStrokeDamage(cairo_t* cr)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ cairo_rectangle_int_t extents;
|
|
|
6e9d999 |
+ double x1, y1, x2, y2;
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_clip_extents(cr, &x1, &y1, &x2, &y2;;
|
|
|
6e9d999 |
+ extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1;
|
|
|
6e9d999 |
+#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 10)
|
|
|
6e9d999 |
+ cairo_region_t *region = cairo_region_create_rectangle(&extents);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_stroke_extents(cr, &x1, &y1, &x2, &y2;;
|
|
|
6e9d999 |
+ extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1;
|
|
|
6e9d999 |
+ cairo_region_intersect_rectangle(region, &extents);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_region_get_extents(region, &extents);
|
|
|
6e9d999 |
+ cairo_region_destroy(region);
|
|
|
6e9d999 |
+#endif
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ return extents;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
}
|
|
|
6e9d999 |
#endif
|
|
|
48e38ea |
|
|
|
48e38ea |
@@ -624,39 +645,6 @@ void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
|
|
|
6e9d999 |
dbgOut( m_aDevice );
|
|
|
6e9d999 |
}
|
|
|
6e9d999 |
|
|
|
6e9d999 |
-bool SvpSalGraphics::drawPolyLine(
|
|
|
6e9d999 |
- const ::basegfx::B2DPolygon&,
|
|
|
6e9d999 |
- double /*fTransparency*/,
|
|
|
6e9d999 |
- const ::basegfx::B2DVector& /*rLineWidths*/,
|
|
|
6e9d999 |
- basegfx::B2DLineJoin /*eJoin*/,
|
|
|
6e9d999 |
- com::sun::star::drawing::LineCap /*eLineCap*/)
|
|
|
6e9d999 |
-{
|
|
|
6e9d999 |
- // TODO: implement and advertise OutDevSupport_B2DDraw support
|
|
|
6e9d999 |
- return false;
|
|
|
6e9d999 |
-}
|
|
|
6e9d999 |
-
|
|
|
6e9d999 |
-bool SvpSalGraphics::drawPolyLineBezier( sal_uInt32,
|
|
|
6e9d999 |
- const SalPoint*,
|
|
|
6e9d999 |
- const sal_uInt8* )
|
|
|
6e9d999 |
-{
|
|
|
6e9d999 |
- return false;
|
|
|
6e9d999 |
-}
|
|
|
6e9d999 |
-
|
|
|
6e9d999 |
-bool SvpSalGraphics::drawPolygonBezier( sal_uInt32,
|
|
|
6e9d999 |
- const SalPoint*,
|
|
|
6e9d999 |
- const sal_uInt8* )
|
|
|
6e9d999 |
-{
|
|
|
6e9d999 |
- return false;
|
|
|
6e9d999 |
-}
|
|
|
6e9d999 |
-
|
|
|
6e9d999 |
-bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
|
|
|
6e9d999 |
- const sal_uInt32*,
|
|
|
6e9d999 |
- const SalPoint* const*,
|
|
|
6e9d999 |
- const sal_uInt8* const* )
|
|
|
6e9d999 |
-{
|
|
|
6e9d999 |
- return false;
|
|
|
6e9d999 |
-}
|
|
|
6e9d999 |
-
|
|
|
6e9d999 |
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
|
|
|
6e9d999 |
static void AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon, bool bClosePath)
|
|
|
6e9d999 |
{
|
|
|
48e38ea |
@@ -720,6 +708,151 @@ static void AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon, b
|
|
|
6e9d999 |
}
|
|
|
6e9d999 |
#endif
|
|
|
6e9d999 |
|
|
|
6e9d999 |
+bool SvpSalGraphics::drawPolyLine(
|
|
|
6e9d999 |
+ const ::basegfx::B2DPolygon& rPolyLine,
|
|
|
6e9d999 |
+ double fTransparency,
|
|
|
6e9d999 |
+ const ::basegfx::B2DVector& rLineWidths,
|
|
|
6e9d999 |
+ basegfx::B2DLineJoin eLineJoin,
|
|
|
6e9d999 |
+ css::drawing::LineCap eLineCap)
|
|
|
6e9d999 |
+{
|
|
|
6e9d999 |
+ bool bRet = false;
|
|
|
6e9d999 |
+ (void)rPolyLine; (void)fTransparency; (void)rLineWidths; (void)eLineJoin; (void)eLineCap;
|
|
|
6e9d999 |
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
|
|
|
6e9d999 |
+ // short circuit if there is nothing to do
|
|
|
6e9d999 |
+ const int nPointCount = rPolyLine.count();
|
|
|
6e9d999 |
+ if (nPointCount <= 0)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ return true;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ // reject requests that cannot be handled yet
|
|
|
6e9d999 |
+ if (rLineWidths.getX() != rLineWidths.getY())
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawPolyLine case");
|
|
|
6e9d999 |
+ return false;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ // #i101491# Cairo does not support B2DLineJoin::NONE; return false to use
|
|
|
6e9d999 |
+ // the fallback (own geometry preparation)
|
|
|
6e9d999 |
+ // #i104886# linejoin-mode and thus the above only applies to "fat" lines
|
|
|
6e9d999 |
+ if (basegfx::B2DLINEJOIN_NONE == eLineJoin && rLineWidths.getX() > 1.3)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawPolyLine case");
|
|
|
6e9d999 |
+ return false;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_t* cr = createCairoContext(m_aDevice);
|
|
|
6e9d999 |
+ if (!cr)
|
|
|
6e9d999 |
+ return bRet;
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ if (!m_aDevice->isTopDown())
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ cairo_scale(cr, 1, -1.0);
|
|
|
6e9d999 |
+ cairo_translate(cr, 0.0, -m_aDevice->getSize().getY());
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ clipRegion(cr);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ // setup line attributes
|
|
|
6e9d999 |
+ cairo_line_join_t eCairoLineJoin = CAIRO_LINE_JOIN_MITER;
|
|
|
6e9d999 |
+ switch (eLineJoin)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ case basegfx::B2DLINEJOIN_NONE:
|
|
|
6e9d999 |
+ eCairoLineJoin = /*TODO?*/CAIRO_LINE_JOIN_MITER;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ case basegfx::B2DLINEJOIN_MIDDLE:
|
|
|
6e9d999 |
+ eCairoLineJoin = /*TODO?*/CAIRO_LINE_JOIN_MITER;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ case basegfx::B2DLINEJOIN_BEVEL:
|
|
|
6e9d999 |
+ eCairoLineJoin = CAIRO_LINE_JOIN_BEVEL;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ case basegfx::B2DLINEJOIN_MITER:
|
|
|
6e9d999 |
+ eCairoLineJoin = CAIRO_LINE_JOIN_MITER;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ case basegfx::B2DLINEJOIN_ROUND:
|
|
|
6e9d999 |
+ eCairoLineJoin = CAIRO_LINE_JOIN_ROUND;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ // setup cap attribute
|
|
|
6e9d999 |
+ cairo_line_cap_t eCairoLineCap(CAIRO_LINE_CAP_BUTT);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ switch (eLineCap)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ default: // css::drawing::LineCap_BUTT:
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ eCairoLineCap = CAIRO_LINE_CAP_BUTT;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+ case css::drawing::LineCap_ROUND:
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ eCairoLineCap = CAIRO_LINE_CAP_ROUND;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+ case css::drawing::LineCap_SQUARE:
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ eCairoLineCap = CAIRO_LINE_CAP_SQUARE;
|
|
|
6e9d999 |
+ break;
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ AddPolygonToPath(cr, rPolyLine, rPolyLine.isClosed());
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_rectangle_int_t extents;
|
|
|
6e9d999 |
+ basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker());
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_set_source_rgba(cr, m_aLineColor.getRed()/255.0,
|
|
|
6e9d999 |
+ m_aLineColor.getGreen()/255.0,
|
|
|
6e9d999 |
+ m_aLineColor.getBlue()/255.0,
|
|
|
6e9d999 |
+ 1.0-fTransparency);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_set_line_join(cr, eCairoLineJoin);
|
|
|
6e9d999 |
+ cairo_set_line_cap(cr, eCairoLineCap);
|
|
|
6e9d999 |
+ cairo_set_line_width(cr, rLineWidths.getX());
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ if (xDamageTracker)
|
|
|
6e9d999 |
+ extents = getStrokeDamage(cr);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_stroke(cr);
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ cairo_surface_flush(cairo_get_target(cr));
|
|
|
6e9d999 |
+ cairo_destroy(cr); // unref
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+ if (xDamageTracker)
|
|
|
6e9d999 |
+ {
|
|
|
6e9d999 |
+ xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width,
|
|
|
6e9d999 |
+ extents.y + extents.height));
|
|
|
6e9d999 |
+ }
|
|
|
6e9d999 |
+ bRet = true;
|
|
|
6e9d999 |
+#endif
|
|
|
6e9d999 |
+ return bRet;
|
|
|
6e9d999 |
+}
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+bool SvpSalGraphics::drawPolyLineBezier( sal_uInt32,
|
|
|
6e9d999 |
+ const SalPoint*,
|
|
|
6e9d999 |
+ const sal_uInt8* )
|
|
|
6e9d999 |
+{
|
|
|
6e9d999 |
+ SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawPolyLineBezier case");
|
|
|
6e9d999 |
+ return false;
|
|
|
6e9d999 |
+}
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+bool SvpSalGraphics::drawPolygonBezier( sal_uInt32,
|
|
|
6e9d999 |
+ const SalPoint*,
|
|
|
6e9d999 |
+ const sal_uInt8* )
|
|
|
6e9d999 |
+{
|
|
|
6e9d999 |
+ SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawPolygonBezier case");
|
|
|
6e9d999 |
+ return false;
|
|
|
6e9d999 |
+}
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
+bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
|
|
|
6e9d999 |
+ const sal_uInt32*,
|
|
|
6e9d999 |
+ const SalPoint* const*,
|
|
|
6e9d999 |
+ const sal_uInt8* const* )
|
|
|
6e9d999 |
+{
|
|
|
6e9d999 |
+ SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawPolyPolygonBezier case");
|
|
|
6e9d999 |
+ return false;
|
|
|
6e9d999 |
+}
|
|
|
6e9d999 |
+
|
|
|
6e9d999 |
bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
|
|
|
6e9d999 |
{
|
|
|
6e9d999 |
bool bRet = false;
|
|
|
6e9d999 |
--
|
|
|
6e9d999 |
2.5.0
|
|
|
6e9d999 |
|