summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wildemann <gta04@metalstrolche.de>2019-07-28 22:31:34 +0200
committerStefan Wildemann <gta04@metalstrolche.de>2019-07-28 22:31:34 +0200
commit864d83c33a998c52a5afff3eb543a0665c98ce02 (patch)
treee24478466e0e9cdc701606ff4f7113c9080e7679
parentf682af2c26869d8f1a5501a021f55dedb4c49e05 (diff)
downloadnavit-864d83c33a998c52a5afff3eb543a0665c98ce02.tar.gz
implement drawing of polygons with holes for qt5
-rw-r--r--navit/graphics.c48
-rw-r--r--navit/graphics.h2
-rw-r--r--navit/graphics/qt5/graphics_qt5.cpp41
3 files changed, 89 insertions, 2 deletions
diff --git a/navit/graphics.c b/navit/graphics.c
index ef0390b92..ec7ea1afd 100644
--- a/navit/graphics.c
+++ b/navit/graphics.c
@@ -1099,6 +1099,47 @@ static void graphics_draw_polygon(struct graphics *gra, struct graphics_gc *gc,
}
}
+/**
+ * @brief Draw a plain polygon with holes on the display
+ *
+ * @param gra The graphics instance on which to draw
+ * @param gc The graphics context
+ * @param[in] pin An array of points forming the polygon
+ * @param count_in The number of elements inside @p pin
+ * @param hole_count The number of hole polygons to cut out
+ * @param pcount array of [hole_count] integers giving the number of
+ * points per hole
+ * @param holes array of point arrays for the hole polygons
+ */
+static void graphics_draw_polygon_with_holes(struct graphics *gra, struct graphics_gc *gc, struct point *pin,
+ int count_in, int hole_count, int* ccount, struct point **holes) {
+ if (! gra->meth.draw_polygon_with_holes) {
+ /* TODO: add attr to configure if polygons with holes should be drawn without
+ * the holes if no graphics support for this is present.
+ */
+ graphics_draw_polygon(gra, gc, pin, count_in);
+ return;
+ } else {
+ struct point * pin_scaled = g_alloca(sizeof (struct point)*count_in);
+ struct point ** holes_scaled = g_alloca(sizeof (struct point *)*hole_count);
+ int a;
+ int b;
+ /* scale the outline */
+ for(a=0; a < count_in; a ++)
+ pin_scaled[a] = graphics_dpi_scale_point(gra,&(pin[a]));
+ /*scale the holes */
+ for(b=0; b < hole_count; b ++) {
+ holes_scaled[b] = g_malloc(sizeof(*(holes_scaled[b])) * ccount[b]);
+ for(a=0; a < ccount[b]; a ++)
+ holes_scaled[b][a] = graphics_dpi_scale_point(gra,&(holes[b][a]));
+ }
+ gra->meth.draw_polygon_with_holes(gra->priv, gc->priv, pin_scaled, count_in, hole_count, ccount, holes_scaled);
+ /* free the hole arrays */
+ for(b=0; b < hole_count; b ++)
+ g_free(holes_scaled[b]);
+ }
+}
+
void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc *gc, struct point *plu, int w, int h,
int r, int fill) {
struct point *p=g_alloca(sizeof(struct point)*(r*4+32));
@@ -2353,6 +2394,7 @@ static void displayitem_draw(struct displayitem *di, void *dummy, struct display
while (di) {
int i,count=di->count,mindist=dc->mindist;
struct displayitem_poly_holes t_holes;
+ t_holes.count=0;
di->z_order=++(gra->current_z_order);
@@ -2377,7 +2419,11 @@ static void displayitem_draw(struct displayitem *di, void *dummy, struct display
count=transform(dc->trans, dc->pro, di->c, pa, count, mindist, 0, NULL);
switch (e->type) {
case element_polygon:
- graphics_draw_polygon_clipped(gra, gc, pa, count);
+ /*TODO: implement a "clipped" version of graphics_draw_polygon_with_holes*/
+ if(t_holes.count > 0)
+ graphics_draw_polygon_with_holes(gra, gc, pa, count, t_holes.count, t_holes.ccount, (struct point **)t_holes.coords);
+ else
+ graphics_draw_polygon_clipped(gra, gc, pa, count);
break;
case element_polyline: {
graphics_gc_set_linewidth(gc, 1);
diff --git a/navit/graphics.h b/navit/graphics.h
index eec44ae14..3ea10e271 100644
--- a/navit/graphics.h
+++ b/navit/graphics.h
@@ -160,6 +160,8 @@ struct graphics_methods {
int (*show_native_keyboard)(struct graphics_keyboard *kbd);
void (*hide_native_keyboard)(struct graphics_keyboard *kbd);
navit_float (*get_dpi)(struct graphics_priv * gr);
+ void (*draw_polygon_with_holes) (struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count,
+ int hole_count, int* ccount, struct point **holes);
};
diff --git a/navit/graphics/qt5/graphics_qt5.cpp b/navit/graphics/qt5/graphics_qt5.cpp
index 535b370dc..10784d6b3 100644
--- a/navit/graphics/qt5/graphics_qt5.cpp
+++ b/navit/graphics/qt5/graphics_qt5.cpp
@@ -418,6 +418,44 @@ static void draw_polygon(struct graphics_priv* gr, struct graphics_gc_priv* gc,
gr->painter->drawPolygon(polygon);
}
+static void draw_polygon_with_holes (struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count,
+ int hole_count, int* ccount, struct point **holes) {
+ int i;
+ int j;
+ QPainterPath path;
+ QPainterPath inner;
+ QPolygon polygon;
+ //dbg(lvl_error,"enter gr=%p, gc=%p, (%d, %d) holes %d", gr, gc, p->x, p->y, hole_count);
+ if (gr->painter == NULL)
+ return;
+ gr->painter->setPen(*gc->pen);
+ gr->painter->setBrush(*gc->brush);
+ /* construct outer polygon */
+ for (i = 0; i < count; i++)
+ polygon.putPoints(i, 1, p[i].x, p[i].y);
+ /* add it to outer path */
+ path.addPolygon(polygon);
+ /* construct the polygons for the holes and add them to inner */
+ for(j=0; j<hole_count; j ++) {
+ QPolygon hole;
+ for (i = 0; i < ccount[j]; i++)
+ hole.putPoints(i, 1, holes[j][i].x, holes[j][i].y);
+ inner.addPolygon(hole);
+ }
+ /* intersect */
+ if(hole_count > 0)
+ path = path.subtracted(inner);
+
+ /* if the polygon is transparent, we need to clear it first */
+ if (!gc->brush->isOpaque()) {
+ QPainter::CompositionMode mode = gr->painter->compositionMode();
+ gr->painter->setCompositionMode(QPainter::CompositionMode_Clear);
+ gr->painter->drawPath(path);
+ gr->painter->setCompositionMode(mode);
+ }
+ gr->painter->drawPath(path);
+}
+
static void draw_rectangle(struct graphics_priv* gr, struct graphics_gc_priv* gc, struct point* p, int w, int h) {
// dbg(lvl_debug,"gr=%p gc=%p %d,%d,%d,%d", gr, gc, p->x, p->y, w, h);
if (gr->painter == NULL)
@@ -851,7 +889,8 @@ static struct graphics_methods graphics_methods = {
NULL, //set_attr
NULL, //show_native_keyboard
NULL, //hide_native_keyboard
- get_dpi
+ get_dpi,
+ draw_polygon_with_holes
};
/* create new graphics context on given context */