diff options
author | Stefan Wildemann <gta04@metalstrolche.de> | 2019-07-28 22:31:34 +0200 |
---|---|---|
committer | Stefan Wildemann <gta04@metalstrolche.de> | 2019-07-28 22:31:34 +0200 |
commit | 864d83c33a998c52a5afff3eb543a0665c98ce02 (patch) | |
tree | e24478466e0e9cdc701606ff4f7113c9080e7679 | |
parent | f682af2c26869d8f1a5501a021f55dedb4c49e05 (diff) | |
download | navit-864d83c33a998c52a5afff3eb543a0665c98ce02.tar.gz |
implement drawing of polygons with holes for qt5
-rw-r--r-- | navit/graphics.c | 48 | ||||
-rw-r--r-- | navit/graphics.h | 2 | ||||
-rw-r--r-- | navit/graphics/qt5/graphics_qt5.cpp | 41 |
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 */ |