summaryrefslogtreecommitdiff
path: root/src/map_draw_gdk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map_draw_gdk.c')
-rw-r--r--src/map_draw_gdk.c146
1 files changed, 100 insertions, 46 deletions
diff --git a/src/map_draw_gdk.c b/src/map_draw_gdk.c
index 4a538e8..c972531 100644
--- a/src/map_draw_gdk.c
+++ b/src/map_draw_gdk.c
@@ -38,6 +38,7 @@
#include "db.h"
#include "road.h"
#include "map_style.h"
+#include "map_math.h"
#include "locationset.h"
#include "location.h"
#include "scenemanager.h"
@@ -51,6 +52,13 @@ static void map_draw_gdk_layer_fill(map_t* pMap, GdkPixmap* pPixmap, rendermetri
static void map_draw_gdk_locations(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics);
static void map_draw_gdk_locationset(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, locationset_t* pLocationSet, GPtrArray* pLocationsArray);
+typedef struct {
+ GdkPixmap* pPixmap;
+ GdkGC* pGC;
+ maplayerstyle_t* pLayerStyle;
+ rendermetrics_t* pRenderMetrics;
+} gdk_draw_context_t;
+
//static void map_draw_gdk_tracks(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics);
void map_draw_gdk_set_color(GdkGC* pGC, color_t* pColor)
@@ -147,6 +155,53 @@ void map_draw_gdk(map_t* pMap, GPtrArray* pTiles, rendermetrics_t* pRenderMetric
TIMER_END(maptimer, "END RENDER MAP (gdk)");
}
+// useful for filling the screen with a color. not much else.
+static void map_draw_gdk_layer_fill(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, maplayerstyle_t* pLayerStyle)
+{
+ GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
+
+ GdkGCValues gcValues;
+ if(pLayerStyle->pGlyphFill != NULL) {
+ // Instead of filling with a color, fill with a tiled image
+ gdk_gc_get_values(pGC, &gcValues);
+ gdk_gc_set_fill(pGC, GDK_TILED);
+ gdk_gc_set_tile(pGC, glyph_get_pixmap(pLayerStyle->pGlyphFill, pMap->pTargetWidget));
+
+ // This makes the fill image scroll with the map, instead of staying still
+ gdk_gc_set_ts_origin(pGC, SCALE_X(pRenderMetrics, pRenderMetrics->fScreenLongitude), SCALE_Y(pRenderMetrics, pRenderMetrics->fScreenLatitude));
+ }
+ else {
+ // Simple color fill
+ map_draw_gdk_set_color(pGC, &(pLayerStyle->clrPrimary));
+ }
+
+ gdk_draw_rectangle(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
+ TRUE, 0,0, pMap->MapDimensions.uWidth, pMap->MapDimensions.uHeight);
+
+ if(pLayerStyle->pGlyphFill != NULL) {
+ // Restore fill style
+ gdk_gc_set_values(pGC, &gcValues, GDK_GC_FILL);
+ }
+}
+
+//
+static void map_draw_gdk_polygons(const GArray* pMapPointsArray, const gdk_draw_context_t* pContext)
+{
+ // Copy all points into this array. Yuuup this is slow. :)
+ GdkPoint aPoints[MAX_GDK_LINE_SEGMENTS];
+ mappoint_t* pPoint;
+
+ gint iPoint;
+ for(iPoint=0 ; iPoint<pMapPointsArray->len ; iPoint++) {
+ pPoint = &g_array_index(pMapPointsArray, mappoint_t, iPoint);
+
+ aPoints[iPoint].x = pContext->pLayerStyle->nPixelOffsetX + (gint)SCALE_X(pContext->pRenderMetrics, pPoint->fLongitude);
+ aPoints[iPoint].y = pContext->pLayerStyle->nPixelOffsetY + (gint)SCALE_Y(pContext->pRenderMetrics, pPoint->fLatitude);
+ }
+
+ gdk_draw_polygon(pContext->pPixmap, pContext->pGC, TRUE, aPoints, pMapPointsArray->len);
+}
+
static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
{
mappoint_t* pPoint;
@@ -174,13 +229,21 @@ static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, renderm
map_draw_gdk_set_color(pGC, &(pLayerStyle->clrPrimary));
}
+ gdk_draw_context_t context;
+ context.pPixmap = pPixmap;
+ context.pGC = pGC;
+ context.pLayerStyle = pLayerStyle;
+ context.pRenderMetrics = pRenderMetrics;
+
for(iString=0 ; iString<pRoadsArray->len ; iString++) {
pRoad = g_ptr_array_index(pRoadsArray, iString);
- if(!map_rects_overlap(&(pRoad->rWorldBoundingBox), &(pRenderMetrics->rWorldBoundingBox))) {
+ EOverlapType eOverlapType = map_rect_a_overlap_type_with_rect_b(&(pRoad->rWorldBoundingBox), &(pRenderMetrics->rWorldBoundingBox));
+ if(eOverlapType == OVERLAP_NONE) {
continue;
}
+ // XXX: should we remove this?
if(pRoad->pMapPointsArray->len < 3) {
//g_warning("not drawing polygon with < 3 points\n");
continue;
@@ -191,17 +254,15 @@ static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, renderm
continue;
}
- GdkPoint aPoints[MAX_GDK_LINE_SEGMENTS];
-
- for(iPoint=0 ; iPoint<pRoad->pMapPointsArray->len ; iPoint++) {
- pPoint = &g_array_index(pRoad->pMapPointsArray, mappoint_t, iPoint);
-
- aPoints[iPoint].x = pLayerStyle->nPixelOffsetX + (gint)SCALE_X(pRenderMetrics, pPoint->fLongitude);
- aPoints[iPoint].y = pLayerStyle->nPixelOffsetY + (gint)SCALE_Y(pRenderMetrics, pPoint->fLatitude);
+ if(eOverlapType == OVERLAP_PARTIAL) {
+ // draw clipped
+ // XXX: Currently no clipping, just draw normally
+ map_draw_gdk_polygons(pRoad->pMapPointsArray, &context);
+ }
+ else {
+ // draw normally
+ map_draw_gdk_polygons(pRoad->pMapPointsArray, &context);
}
-
- gdk_draw_polygon(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
- TRUE, aPoints, pRoad->pMapPointsArray->len);
}
if(pLayerStyle->pGlyphFill != NULL) {
// Restore fill style
@@ -209,45 +270,34 @@ static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, renderm
}
}
-// useful for filling the screen with a color. not much else.
-static void map_draw_gdk_layer_fill(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, maplayerstyle_t* pLayerStyle)
+static void map_draw_gdk_lines(const GArray* pMapPointsArray, const gdk_draw_context_t* pContext)
{
- GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
-
- GdkGCValues gcValues;
- if(pLayerStyle->pGlyphFill != NULL) {
- // Instead of filling with a color, fill with a tiled image
- gdk_gc_get_values(pGC, &gcValues);
- gdk_gc_set_fill(pGC, GDK_TILED);
- gdk_gc_set_tile(pGC, glyph_get_pixmap(pLayerStyle->pGlyphFill, pMap->pTargetWidget));
-
- // This makes the fill image scroll with the map, instead of staying still
- gdk_gc_set_ts_origin(pGC, SCALE_X(pRenderMetrics, pRenderMetrics->fScreenLongitude), SCALE_Y(pRenderMetrics, pRenderMetrics->fScreenLatitude));
- }
- else {
- // Simple color fill
- map_draw_gdk_set_color(pGC, &(pLayerStyle->clrPrimary));
- }
+ // Copy all points into this array. Yuuup this is slow. :)
+ GdkPoint aPoints[MAX_GDK_LINE_SEGMENTS];
+ mappoint_t* pPoint;
- gdk_draw_rectangle(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
- TRUE, 0,0, pMap->MapDimensions.uWidth, pMap->MapDimensions.uHeight);
+ gint iPoint;
+ for(iPoint=0 ; iPoint<pMapPointsArray->len ; iPoint++) {
+ pPoint = &g_array_index(pMapPointsArray, mappoint_t, iPoint);
- if(pLayerStyle->pGlyphFill != NULL) {
- // Restore fill style
- gdk_gc_set_values(pGC, &gcValues, GDK_GC_FILL);
+ aPoints[iPoint].x = pContext->pLayerStyle->nPixelOffsetX + (gint)SCALE_X(pContext->pRenderMetrics, pPoint->fLongitude);
+ aPoints[iPoint].y = pContext->pLayerStyle->nPixelOffsetY + (gint)SCALE_Y(pContext->pRenderMetrics, pPoint->fLatitude);
}
+
+ gdk_draw_lines(pContext->pPixmap, pContext->pGC, aPoints, pMapPointsArray->len);
}
static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
{
road_t* pRoad;
- mappoint_t* pPoint;
gint iString;
gint iPoint;
if(pLayerStyle->fLineWidth <= 0.0) return; // Don't draw invisible lines
if(pLayerStyle->clrPrimary.fAlpha == 0.0) return; // invisible? (not that we respect it in gdk drawing anyway)
+ GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
+
// Translate generic cap style into GDK constant
gint nCapStyle;
if(pLayerStyle->nCapStyle == MAP_CAP_STYLE_ROUND) {
@@ -278,10 +328,17 @@ static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetr
map_draw_gdk_set_color(pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)], &(pLayerStyle->clrPrimary));
+ gdk_draw_context_t context;
+ context.pPixmap = pPixmap;
+ context.pGC = pGC;
+ context.pLayerStyle = pLayerStyle;
+ context.pRenderMetrics = pRenderMetrics;
+
for(iString=0 ; iString<pRoadsArray->len ; iString++) {
pRoad = g_ptr_array_index(pRoadsArray, iString);
- if(!map_rects_overlap(&(pRoad->rWorldBoundingBox), &(pRenderMetrics->rWorldBoundingBox))) {
+ EOverlapType eOverlapType = map_rect_a_overlap_type_with_rect_b(&(pRoad->rWorldBoundingBox), &(pRenderMetrics->rWorldBoundingBox));
+ if(eOverlapType == OVERLAP_NONE) {
continue;
}
@@ -295,17 +352,14 @@ static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetr
continue;
}
- // Copy all points into this array. Yuuup this is slow. :)
- GdkPoint aPoints[MAX_GDK_LINE_SEGMENTS];
-
- for(iPoint=0 ; iPoint<pRoad->pMapPointsArray->len ; iPoint++) {
- pPoint = &g_array_index(pRoad->pMapPointsArray, mappoint_t, iPoint);
-
- aPoints[iPoint].x = pLayerStyle->nPixelOffsetX + (gint)SCALE_X(pRenderMetrics, pPoint->fLongitude);
- aPoints[iPoint].y = pLayerStyle->nPixelOffsetY + (gint)SCALE_Y(pRenderMetrics, pPoint->fLatitude);
+ if(eOverlapType == OVERLAP_PARTIAL) {
+ // draw clipped
+ map_draw_gdk_lines(pRoad->pMapPointsArray, &context);
+ }
+ else {
+ // draw directly
+ map_draw_gdk_lines(pRoad->pMapPointsArray, &context);
}
-
- gdk_draw_lines(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)], aPoints, pRoad->pMapPointsArray->len);
}
}