[cairo-commit] roadster/src db.c, 1.23, 1.24 import_tiger.c, 1.17,
1.18 layers.h, 1.6, 1.7 map.c, 1.41, 1.42 map.h, 1.18,
1.19 map_draw_cairo.c, 1.19, 1.20 map_draw_gdk.c, 1.15,
1.16 scenemanager.c, 1.11, 1.12 scenemanager.h, 1.5,
1.6 util.c, 1.7, 1.8
Ian McIntosh
commit at pdx.freedesktop.org
Wed Aug 31 01:37:55 PDT 2005
Committed by: ian
Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv11436/src
Modified Files:
db.c import_tiger.c layers.h map.c map.h map_draw_cairo.c
map_draw_gdk.c scenemanager.c scenemanager.h util.c
Log Message:
* src/db.c: Remove incorrect 'UNIQUE' attribute on Name index in RoadName table.
* src/scenemanager.c: Add 'on screen' as additional (optional) criteria for allowing drawing.
* src/map_draw_cairo.c: Update to new scenemanager API. Add new dual-line smart area labeler.
* src/util.c: Function util_split_words_onto_two_lines() is now used.
* data/layers.xml: Various style tweaks. It's fun.
* src/map.c: Style tweaks.
Index: db.c
===================================================================
RCS file: /cvs/cairo/roadster/src/db.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- db.c 28 Aug 2005 22:23:14 -0000 1.23
+++ db.c 31 Aug 2005 08:37:53 -0000 1.24
@@ -585,7 +585,7 @@
" Name VARCHAR(30) NOT NULL,"
" SuffixID INT1 UNSIGNED NOT NULL,"
" PRIMARY KEY (ID)," // for joining RoadName to Road
- " UNIQUE KEY (Name(7)));", NULL); // for searching by RoadName. 7 is enough for decent uniqueness(?)
+ " INDEX (Name(7)));", NULL); // for searching by RoadName. 7 is enough for decent uniqueness(?)
// City
db_query("CREATE TABLE IF NOT EXISTS City("
Index: import_tiger.c
===================================================================
RCS file: /cvs/cairo/roadster/src/import_tiger.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- import_tiger.c 28 Aug 2005 22:23:14 -0000 1.17
+++ import_tiger.c 31 Aug 2005 08:37:53 -0000 1.18
@@ -488,6 +488,8 @@
// columns 6 to 15 is the TLID -
import_tiger_read_int(&pLine[6-1], TIGER_TLID_LENGTH, &pRecord->m_nTLID);
+
+ // columns 20 to ? is the name
import_tiger_read_string(&pLine[20-1], TIGER_CHAIN_NAME_LEN, &pRecord->m_achName[0]);
// columns 141-145 and 146-150 are FIPS55 codes which link this road to a city
@@ -503,7 +505,6 @@
if(achType[0] != '\0' && pRecord->m_nRoadNameSuffixID == ROAD_SUFFIX_NONE) {
g_print("type '%s' couldn't be looked up\n", achType);
}
-
import_tiger_read_int(&pLine[135-1], 3, &pRecord->m_nCountyIDLeft);
import_tiger_read_int(&pLine[138-1], 3, &pRecord->m_nCountyIDRight);
Index: layers.h
===================================================================
RCS file: /cvs/cairo/roadster/src/layers.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- layers.h 13 Mar 2005 23:31:21 -0000 1.6
+++ layers.h 31 Aug 2005 08:37:53 -0000 1.7
@@ -29,21 +29,24 @@
G_BEGIN_DECLS
-#define LAYER_NONE (0)
+#define LAYER_NONE (0)
#define LAYER_MINORSTREET (1)
#define LAYER_MAJORSTREET (2)
+
#define LAYER_MINORHIGHWAY (3)
-#define LAYER_MINORHIGHWAY_RAMP (4)
+#define LAYER_MINORHIGHWAY_RAMP (4)
+
#define LAYER_MAJORHIGHWAY (5) // used?
-#define LAYER_MAJORHIGHWAY_RAMP (6) // used?
+#define LAYER_MAJORHIGHWAY_RAMP (6) // used?
+
#define LAYER_RAILROAD (7)
-#define LAYER_PARK (8)
-#define LAYER_RIVER (9)
-#define LAYER_LAKE (10)
+#define LAYER_PARK (8)
+#define LAYER_RIVER (9)
+#define LAYER_LAKE (10)
#define LAYER_MISC_AREA (11)
-#define NUM_LAYERS (11)
+#define NUM_LAYERS (11)
#define LAYER_FIRST (1)
#define LAYER_LAST (11)
Index: map.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- map.c 28 Aug 2005 22:23:14 -0000 1.41
+++ map.c 31 Aug 2005 08:37:53 -0000 1.42
@@ -39,6 +39,11 @@
#include "location.h"
#include "scenemanager.h"
+
+#define ENABLE_RIVER_TO_LAKE_LOADTIME_HACK // change circular rivers to lakes when loading from disk
+//#define ENABLE_SCENEMANAGER_DEBUG_TEST
+
+
#ifdef THREADED_RENDERING
#define RENDERING_THREAD_YIELD g_thread_yield()
#else
@@ -63,9 +68,6 @@
#define MIN_ZOOMLEVEL_FOR_LOCATIONS (6)
-#define ENABLE_RIVER_TO_LAKE_LOADTIME_HACK // change circular rivers to lakes when loading from disk
-//#define ENABLE_SCENEMANAGER_DEBUG_TEST
-
/* Prototypes */
// data loading
@@ -92,6 +94,7 @@
{ 1600000, ""}, // 1
{ 800000, ""}, // 2
{ 400000, ""}, // 3
+
{ 200000, ""}, // 4
{ 100000, ""}, // 5
@@ -106,11 +109,11 @@
{LAYER_MISC_AREA, 0, SUBLAYER_RENDERTYPE_POLYGONS}, //map_draw_layer_polygons},
- {LAYER_PARK, 0, SUBLAYER_RENDERTYPE_LINES}, //map_draw_layer_lines},
+// {LAYER_PARK, 0, SUBLAYER_RENDERTYPE_LINES}, //map_draw_layer_lines},
{LAYER_PARK, 1, SUBLAYER_RENDERTYPE_POLYGONS}, //map_draw_layer_polygons},
- {LAYER_LAKE, 0, SUBLAYER_RENDERTYPE_LINES}, // NOTE: drawing lines BELOW polygons (and ~double width) lets us avoid drawing seams on top of multi-polygon lakes
- {LAYER_RIVER, 0, SUBLAYER_RENDERTYPE_LINES}, //map_draw_layer_lines}, // single-line rivers
+// {LAYER_LAKE, 0, SUBLAYER_RENDERTYPE_LINES}, // NOTE: drawing lines BELOW polygons (and ~double width) lets us avoid drawing seams on top of multi-polygon lakes
+// {LAYER_RIVER, 0, SUBLAYER_RENDERTYPE_LINES}, //map_draw_layer_lines}, // single-line rivers
{LAYER_LAKE, 1, SUBLAYER_RENDERTYPE_POLYGONS},
{LAYER_RIVER, 1, SUBLAYER_RENDERTYPE_LINES}, //map_draw_layer_lines}, // single-line rivers
@@ -240,18 +243,15 @@
{
g_assert(pMap != NULL);
- scenemanager_clear(pMap->m_pSceneManager);
-
- // Get render metrics
+ // Get area of world to draw and screen dimensions to draw to, etc.
rendermetrics_t renderMetrics = {0};
map_get_render_metrics(pMap, &renderMetrics);
rendermetrics_t* pRenderMetrics = &renderMetrics;
- //g_print("drawing at %f,%f\n", pMap->m_MapCenter.m_fLatitude, pMap->m_MapCenter.m_fLongitude);
+ scenemanager_clear(pMap->m_pSceneManager);
+ scenemanager_set_screen_dimensions(pMap->m_pSceneManager, pRenderMetrics->m_nWindowWidth, pRenderMetrics->m_nWindowHeight);
- //
// Load geometry
- //
TIMER_BEGIN(loadtimer, "--- BEGIN ALL DB LOAD");
map_data_clear(pMap);
map_data_load_tiles(pMap, &(pRenderMetrics->m_rWorldBoundingBox));
Index: map.h
===================================================================
RCS file: /cvs/cairo/roadster/src/map.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- map.h 28 Aug 2005 22:23:14 -0000 1.18
+++ map.h 31 Aug 2005 08:37:53 -0000 1.19
@@ -252,7 +252,7 @@
#define DRAWFLAG_ALL (1|2)
-#define NUM_SUBLAYER_TO_DRAW (24)
+#define NUM_SUBLAYER_TO_DRAW (21) //(24)
extern draworder_t layerdraworder[NUM_SUBLAYER_TO_DRAW]; //
void map_init(void);
Index: map_draw_cairo.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_cairo.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- map_draw_cairo.c 28 Aug 2005 22:23:14 -0000 1.19
+++ map_draw_cairo.c 31 Aug 2005 08:37:53 -0000 1.20
@@ -28,10 +28,13 @@
#define ENABLE_LABEL_LIMIT_TO_ROAD // don't draw labels if they would be longer than the road
#define ENABLE_HACK_AROUND_CAIRO_LINE_CAP_BUG // enable to ensure roads have rounded caps if the style dictates
-#define ACCEPTABLE_LINE_LABEL_OVERDRAW_IN_PIXELS_SQUARED (38*38)
+#define ACCEPTABLE_LINE_LABEL_OVERDRAW_IN_PIXELS_SQUARED (24*24) // XXX: make this a run-time variable
-#define ROAD_FONT "Bitstream Vera Sans"
-#define AREA_FONT "Bitstream Vera Sans"
+#define ROAD_FONT "Free Sans" //Bitstream Vera Sans"
+#define AREA_FONT "Free Sans" // "Bitstream Vera Sans"
+
+#define MIN_AREA_LABEL_LINE_LENGTH (4)
+#define MAX_AREA_LABEL_LINE_LENGTH (8)
#include <gdk/gdkx.h>
#include <cairo.h>
@@ -62,7 +65,7 @@
// Draw a single line/polygon/point
static void map_draw_cairo_background(map_t* pMap, cairo_t *pCairo);
static void map_draw_cairo_layer_points(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationsArray);
-//static void map_draw_cairo_locationset(map_t* pMap, cairo_t *pCairo, rendermetrics_t* pRenderMetrics, locationset_t* pLocationSet, GPtrArray* pLocationsArray);
+static void map_draw_cairo_locationset(map_t* pMap, cairo_t *pCairo, rendermetrics_t* pRenderMetrics, locationset_t* pLocationSet, GPtrArray* pLocationsArray);
static void map_draw_cairo_locationselection(map_t* pMap, cairo_t *pCairo, rendermetrics_t* pRenderMetrics, GPtrArray* pLocationSelectionArray);
// Draw a single line/polygon label
@@ -103,11 +106,7 @@
drawable = gdk_x11_drawable_get_xid(pPixmap);
gdk_drawable_get_size (pPixmap, &width, &height);
- cairo_surface_t *pSurface = cairo_xlib_surface_create (dpy,
- drawable,
- visual,
- width,
- height);
+ cairo_surface_t *pSurface = cairo_xlib_surface_create (dpy, drawable, visual, width, height);
cairo_t* pCairo = cairo_create (pSurface);
// 2. Rendering
@@ -167,7 +166,7 @@
}
}
-// map_draw_cairo_locations(pMap, pCairo, pRenderMetrics);
+ //map_draw_cairo_locations(pMap, pCairo, pRenderMetrics); done with GDK
map_draw_cairo_locationselection(pMap, pCairo, pRenderMetrics, pMap->m_pLocationSelectionArray);
// 4. Cleanup
@@ -410,44 +409,6 @@
*/
}
-<<<<<<< map_draw_cairo.c
-#define ROAD_MAX_SEGMENTS (100)
-=======
-//void map_draw_cairo_locations(map_t* pMap, cairo_t* pCairo, rendermetrics_t* pRenderMetrics)
-//{
-/*
- location_t loc;
- location_t* pLoc = &loc;
-
- // XXX: debug
- pLoc->m_pszName = "2020 Massachusetts Ave., Cambridge, MA, 02140";
- pLoc->m_Coordinates.m_fLongitude = 0;
- pLoc->m_Coordinates.m_fLatitude = 0;
-
- //
- // Draw
- //
- cairo_save(pCairo);
-
- gdouble fX = (gdouble)(gint)SCALE_X(pRenderMetrics, pLoc->m_Coordinates.m_fLongitude);
- gdouble fY = (gdouble)(gint)SCALE_Y(pRenderMetrics, pLoc->m_Coordinates.m_fLatitude);
-
-#define BIP (3)
-#define BAP (1.5)
-
- cairo_set_source_rgb(pCairo, 20/255.0, 20/255.0, 20/255.0);
- cairo_set_line_width(pCairo, 2.5);
- cairo_set_alpha(pCairo, 1.0);
-
- cairo_rectangle(pCairo, fX - BIP, fY - BIP, BIP*2, BIP*2);
- cairo_stroke(pCairo);
-
- cairo_rectangle(pCairo, fX - BAP, fY - BAP, BAP*2, BAP*2);
- cairo_fill(pCairo);
- cairo_restore(pCairo);
-*/
-//}
-
#define ROAD_MAX_SEGMENTS 100
#define DRAW_LABEL_BUFFER_LEN (200)
@@ -467,7 +428,7 @@
static void map_draw_cairo_road_label_one_segment(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, GPtrArray* pPointsArray, gdouble fLineWidth, const gchar* pszLabel)
{
// get permission to draw this label
- if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
+ if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
return;
}
@@ -575,7 +536,7 @@
aBoundingPolygon[3].y = fDrawY + (fNormalizedY * (fLabelWidth+B)) - (fPerpendicularNormalizedY * B);
// Ask whether we can draw here
- if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4)) {
+ if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
continue;
}
@@ -657,7 +618,7 @@
// Request permission to draw this label. This prevents multiple labels too close together.
// NOTE: Currently no location is used, only allows one of each text string per draw
- if(!scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
+ if(!scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
return;
}
@@ -959,7 +920,7 @@
aBoundingPolygon[3].x = fDrawX + (fNormalizedX * extents.width);
aBoundingPolygon[3].y = fDrawY + (fNormalizedY * extents.width);
- if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4)) {
+ if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
bGood = FALSE;
break;
}
@@ -1142,7 +1103,7 @@
g_ptr_array_free(pPositionsPtrArray, FALSE);
*/
}
-/*
+
//
// Draw a single polygon label
//
@@ -1150,34 +1111,24 @@
{
if(pPointsArray->len < 3) return;
- if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
+ if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
return;
}
- //gdouble fTotalX = 0.0;
- //gdouble fTotalY = 0.0;
-
gdouble fMaxLat = MIN_LATITUDE; // init to the worst possible value so first point will override
gdouble fMinLat = MAX_LATITUDE;
gdouble fMaxLon = MIN_LONGITUDE;
gdouble fMinLon = MAX_LONGITUDE;
- mappoint_t* pMapPoint;
- gdouble fX;
- gdouble fY;
gint i;
for(i=0 ; i<pPointsArray->len ; i++) {
- pMapPoint = g_ptr_array_index(pPointsArray, i);
+ mappoint_t* pMapPoint = g_ptr_array_index(pPointsArray, i);
// find polygon bounding box for visibility test below
fMaxLat = max(pMapPoint->m_fLatitude,fMaxLat);
fMinLat = min(pMapPoint->m_fLatitude,fMinLat);
fMaxLon = max(pMapPoint->m_fLongitude,fMaxLon);
fMinLon = min(pMapPoint->m_fLongitude,fMinLon);
-
- // sum up Xs and Ys (we'll take an average later)
- //fTotalX += SCALE_X(pRenderMetrics, pMapPoint->m_fLongitude);
- //fTotalY += SCALE_Y(pRenderMetrics, pMapPoint->m_fLatitude);
}
// rectangle overlap test
@@ -1189,74 +1140,119 @@
return; // not visible
}
- gdouble fDrawX = SCALE_X(pRenderMetrics, (fMinLon + fMaxLon) / 2); //fMinX + fPolygonWidth/2; //fTotalX / pPointString->m_pPointsArray->len;
- gdouble fDrawY = SCALE_Y(pRenderMetrics, (fMinLat + fMaxLat) / 2); //fMinY + fPolygonHeight/2; //fTotalY / pPointString->m_pPointsArray->len;
+ gdouble fAreaOriginX = SCALE_X(pRenderMetrics, fMinLon);
+ gdouble fAreaOriginY = SCALE_Y(pRenderMetrics, fMaxLat);
+//g_print("Area origin (%f,%f)\n", fAreaOriginX, fAreaOriginY);
-#define MIN_AREA_LABEL_LINE_LENGTH (4)
-#define MAX_AREA_LABEL_LINE_LENGTH (10)
+ gdouble fAreaWidth = SCALE_X(pRenderMetrics, fMaxLon) - SCALE_X(pRenderMetrics, fMinLon);
+ gdouble fAreaHeight = SCALE_Y(pRenderMetrics, fMinLat) - SCALE_Y(pRenderMetrics, fMaxLat);
+//g_print("Area size (%f,%f)\n", fAreaWidth, fAreaHeight);
gchar** aLines = util_split_words_onto_two_lines(pszLabel, MIN_AREA_LABEL_LINE_LENGTH, MAX_AREA_LABEL_LINE_LENGTH);
+ gint nLineCount = g_strv_length(aLines); // could be one or two, unless we change above function
+ gint* anWidths = g_new0(gint, nLineCount);
- cairo_save(pCairo);
+ gdouble fLabelBoxWidth = 0.0;
+ gdouble fLabelBoxHeight = 0.0;
- // Get total width of string
cairo_text_extents_t extents;
- cairo_text_extents(pCairo, aLines[0], &extents);
- gint nWidth = extents.width;
- gint nHeight = extents.height;
-
- // add second line if present
- if(aLines[1]) {
- cairo_text_extents(pCairo, aLines[1], &extents);
- nWidth = max(nWidth, extents.width);
- nHeight += extents.height;
+ for(i=0 ; i<nLineCount ; i++) {
+ cairo_text_extents(pCairo, aLines[i], &extents);
+ anWidths[i] = extents.width;
+ fLabelBoxWidth = max(fLabelBoxWidth, (gdouble)extents.width); // as wide as the widest line
+ fLabelBoxHeight += (gdouble)extents.height; // total height of all lines
}
- fDrawX -= (extents.width / 2);
- fDrawY += (extents.height / 2);
+ gdouble fOneLineHeight = fLabelBoxHeight / nLineCount;
- // check permission with scenemanager
- GdkRectangle rcLabelOutline;
- rcLabelOutline.x = (gint)fDrawX;
- rcLabelOutline.width = nWidth;
- rcLabelOutline.y = ((gint)fDrawY) - nHeight;
- rcLabelOutline.height = nHeight;
- if(FALSE == scenemanager_can_draw_rectangle(pMap->m_pSceneManager, &rcLabelOutline)) {
- cairo_restore(pCairo);
- g_strfreev(aLines);
- return;
- }
- // claim it! Now no one else will draw text here.
- scenemanager_claim_rectangle(pMap->m_pSceneManager, &rcLabelOutline);
+ gdouble fHorizontalPadding = (fAreaWidth - fLabelBoxWidth);
+ gdouble fVerticalPadding = (fAreaHeight - fLabelBoxHeight);
+//g_print("padding (%f,%f)\n", fHorizontalPadding, fVerticalPadding);
+
+ // various places to try...
+ struct { gdouble fX,fY; } afPercentagesOfPadding[] = {
+ {0.50, 0.50},
+
+ // first the close-to-center positions (.25 and .75)
+ {0.50, 0.25}, {0.50, 0.75}, // dodge up/down
+ {0.25, 0.50}, {0.75, 0.50}, // dodge left/right middle
+ {0.25, 0.25}, {0.75, 0.25}, // upper left/right
+ {0.25, 0.75}, {0.75, 0.75}, // lower left/right
+
+ // now the close-to-center positions (0.0 and 1.0)
+ {0.50, 0.00}, {0.50, 1.00}, // dodge up/down
+ {0.00, 0.50}, {1.00, 0.50}, // dodge left/right middle
+// {0.00, 0.00}, {1.00, 0.00}, // upper left/right
+// {0.00, 1.00}, {1.00, 1.00}, // lower left/right
+ };
+
+ gboolean bSuccess = FALSE;
+ gint iSlot;
+ for(iSlot=0 ; iSlot<NUM_ELEMS(afPercentagesOfPadding) ; iSlot++) {
+ gdouble fDrawBoxCornerX = fAreaOriginX + (fHorizontalPadding * afPercentagesOfPadding[iSlot].fX);
+ gdouble fDrawBoxCornerY = fAreaOriginY + (fVerticalPadding * afPercentagesOfPadding[iSlot].fY);
+
+ GdkRectangle rcLabelOutline;
+ rcLabelOutline.x = (gint)(fDrawBoxCornerX);
+ rcLabelOutline.width = (gint)(fLabelBoxWidth);
+ rcLabelOutline.y = (gint)(fDrawBoxCornerY);
+ rcLabelOutline.height = (gint)(fLabelBoxHeight);
+ if(FALSE == scenemanager_can_draw_rectangle(pMap->m_pSceneManager, &rcLabelOutline, SCENEMANAGER_FLAG_FULLY_ON_SCREEN)) {
+ continue;
+ }
+
+ // passed test! claim this label and rectangle area
+ scenemanager_claim_label(pMap->m_pSceneManager, pszLabel);
+ scenemanager_claim_rectangle(pMap->m_pSceneManager, &rcLabelOutline);
+
+ //
+ // Draw Halo for all lines, if style dictates.
+ //
+ gdouble fHaloSize = pLabelStyle->m_afHaloAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
+ if(fHaloSize >= 0) {
+ cairo_save(pCairo);
- gdouble fHaloSize = pLabelStyle->m_afHaloAtZoomLevel[pRenderMetrics->m_nZoomLevel-1];
- if(fHaloSize >= 0) {
- cairo_save(pCairo);
- cairo_move_to(pCairo, fDrawX, fDrawY);
- cairo_text_path(pCairo, pszLabel);
cairo_set_line_width(pCairo, fHaloSize);
cairo_set_source_rgb (pCairo, 1.0,1.0,1.0);
cairo_set_line_join(pCairo, CAIRO_LINE_JOIN_BEVEL);
-// cairo_set_miter_limit(pCairo, 0.1);
- cairo_stroke(pCairo);
- cairo_restore(pCairo);
+ for(i=0 ; i<nLineCount ; i++) {
+ // Get total width of string
+ cairo_move_to(pCairo,
+ fDrawBoxCornerX + ((fLabelBoxWidth - anWidths[i])/2),
+ fDrawBoxCornerY + ((i+1) * fOneLineHeight));
+ cairo_text_path(pCairo, aLines[i]);
+ cairo_stroke(pCairo);
+ }
+ cairo_restore(pCairo);
+ }
+
+ //
+ // Draw text for all lines.
+ //
+ for(i=0 ; i<nLineCount ; i++) {
+ // Get total width of string
+ cairo_move_to(pCairo,
+ fDrawBoxCornerX + ((fLabelBoxWidth - anWidths[i])/2),
+ fDrawBoxCornerY + ((i+1) * fOneLineHeight));
+ cairo_show_text(pCairo, aLines[i]);
+ }
+ break;
}
- cairo_move_to(pCairo, fDrawX, fDrawY);
- cairo_show_text(pCairo, pszLabel);
- cairo_restore(pCairo);
- // Tell scenemanager that we've drawn this label
- scenemanager_claim_label(pMap->m_pSceneManager, pszLabel);
-
+ // draw it
+// cairo_save(pCairo);
+
+// cairo_restore(pCairo);
g_strfreev(aLines);
+ g_free(anWidths);
}
-*/
+/*
void map_draw_cairo_polygon_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, GPtrArray* pPointsArray, const gchar* pszLabel)
{
if(pPointsArray->len < 3) return;
- if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) {
+ if(FALSE == scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
return;
}
@@ -1319,7 +1315,7 @@
rcLabelOutline.width = extents.width;
rcLabelOutline.y = ((gint)fDrawY) - extents.height;
rcLabelOutline.height = extents.height;
- if(FALSE == scenemanager_can_draw_rectangle(pMap->m_pSceneManager, &rcLabelOutline)) {
+ if(FALSE == scenemanager_can_draw_rectangle(pMap->m_pSceneManager, &rcLabelOutline, SCENEMANAGER_FLAG_PARTLY_ON_SCREEN)) {
cairo_restore(pCairo);
return;
}
@@ -1345,6 +1341,7 @@
// Tell scenemanager that we've drawn this label
scenemanager_claim_label(pMap->m_pSceneManager, pszLabel);
}
+*/
/*
static void map_draw_cairo_locations(map_t* pMap, cairo_t *pCairo, rendermetrics_t* pRenderMetrics)
Index: map_draw_gdk.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_gdk.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- map_draw_gdk.c 28 Aug 2005 22:23:14 -0000 1.15
+++ map_draw_gdk.c 31 Aug 2005 08:37:53 -0000 1.16
@@ -205,9 +205,9 @@
// XXX: Don't use round at low zoom levels
// gint nCapStyle = pSubLayerStyle->m_nCapStyle;
gint nCapStyle = GDK_CAP_ROUND;
- if(fLineWidth < 8) {
- nCapStyle = GDK_CAP_PROJECTING;
- }
+ //if(fLineWidth < 8) {
+ // nCapStyle = GDK_CAP_PROJECTING;
+ //}
gint nLineWidth = (gint)fLineWidth;
@@ -250,7 +250,9 @@
aPoints[iPoint].y = (gint)SCALE_Y(pRenderMetrics, pPoint->m_fLatitude);
}
- // rectangle overlap test
+ // basic rectangle overlap test
+ // XXX: not quite right. the points that make up a road may be offscreen,
+ // but a thick road should still be visible
if(fMaxLat < pRenderMetrics->m_rWorldBoundingBox.m_A.m_fLatitude
|| fMaxLon < pRenderMetrics->m_rWorldBoundingBox.m_A.m_fLongitude
|| fMinLat > pRenderMetrics->m_rWorldBoundingBox.m_B.m_fLatitude
Index: scenemanager.c
===================================================================
RCS file: /cvs/cairo/roadster/src/scenemanager.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- scenemanager.c 28 Aug 2005 22:23:14 -0000 1.11
+++ scenemanager.c 31 Aug 2005 08:37:53 -0000 1.12
@@ -34,6 +34,7 @@
void scenemanager_init(void)
{
+
}
void scenemanager_new(scenemanager_t** ppReturn)
@@ -45,22 +46,63 @@
*ppReturn = pNew;
}
-gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* __unused_pScreenLocation)
+// NOTE: must be called before any scenemanager_can_draw_* calls
+void scenemanager_set_screen_dimensions(scenemanager_t* pSceneManager, gint nWindowWidth, gint nWindowHeight)
+{
+ pSceneManager->m_nWindowWidth = nWindowWidth;
+ pSceneManager->m_nWindowHeight = nWindowHeight;
+}
+
+gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* __unused_pScreenLocation, gint nFlags)
{
g_assert(pSceneManager != NULL);
g_assert(pszLabel != NULL);
-
+
// g_assert(pScreenLocation != NULL);
// NOTE: ignore pScreenLocation for now
-
gpointer pKey, pValue;
// Can draw if it doesn't exist in table
return (FALSE == g_hash_table_lookup_extended(pSceneManager->m_pLabelHash, pszLabel, &pKey, &pValue));
}
-gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints)
+gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints, gint nFlags)
{
+ //
+ // 1) Enforce on-screen rules
+ //
+ if(nFlags & SCENEMANAGER_FLAG_FULLY_ON_SCREEN) {
+ // all points must be within screen box
+ gint i;
+ for(i=0 ; i<nNumPoints ; i++) {
+ GdkPoint* pPoint = &pPoints[i];
+ if(pPoint->x < 0 || pPoint->x > pSceneManager->m_nWindowWidth) return FALSE;
+ if(pPoint->y < 0 || pPoint->y > pSceneManager->m_nWindowHeight) return FALSE;
+ }
+ // else go on to test below
+ }
+ else if(nFlags & SCENEMANAGER_FLAG_PARTLY_ON_SCREEN) {
+ // one point must be withing screen box
+ gint i;
+ gboolean bFound = FALSE;
+ for(i=0 ; i<nNumPoints ; i++) {
+ GdkPoint* pPoint = &pPoints[i];
+ if(pPoint->x > 0 && pPoint->x < pSceneManager->m_nWindowWidth) {
+ bFound = TRUE;
+ break;
+ }
+ if(pPoint->y > 0 && pPoint->y < pSceneManager->m_nWindowHeight) {
+ bFound = TRUE;
+ break;
+ }
+ }
+ if(!bFound) return FALSE;
+ // else go on to test below
+ }
+
+ //
+ // 2) Enforce overlap rules
+ //
GdkRegion* pNewRegion = gdk_region_polygon(pPoints, nNumPoints, GDK_WINDING_RULE);
gdk_region_intersect(pNewRegion, pSceneManager->m_pTakenRegion); // sets pNewRegion to the intersection of itself and the 'taken region'
@@ -70,8 +112,29 @@
return bOK;
}
-gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect)
+gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect, gint nFlags)
{
+ //
+ // 1) Enforce on-screen rules
+ //
+ if(nFlags & SCENEMANAGER_FLAG_FULLY_ON_SCREEN) {
+ // basic rect1 contains rect2 test
+ if((pRect->x) <= 0) return FALSE;
+ if((pRect->y) <= 0) return FALSE;
+ if((pRect->x + pRect->width) > pSceneManager->m_nWindowWidth) return FALSE;
+ if((pRect->y + pRect->height) > pSceneManager->m_nWindowHeight) return FALSE;
+ }
+ else if(nFlags & SCENEMANAGER_FLAG_PARTLY_ON_SCREEN) {
+ // basic rect intersect test
+ if((pRect->x + pRect->width) <= 0) return FALSE;
+ if((pRect->y + pRect->height) <= 0) return FALSE;
+ if((pRect->x) > pSceneManager->m_nWindowWidth) return FALSE;
+ if((pRect->y) > pSceneManager->m_nWindowHeight) return FALSE;
+ }
+
+ //
+ // 2) Enforce overlap rules
+ //
GdkRegion* pNewRegion = gdk_region_rectangle(pRect);
gdk_region_intersect(pNewRegion, pSceneManager->m_pTakenRegion); // sets pNewRegion to the intersection of itself and the 'taken region'
Index: scenemanager.h
===================================================================
RCS file: /cvs/cairo/roadster/src/scenemanager.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- scenemanager.h 10 Mar 2005 06:12:03 -0000 1.5
+++ scenemanager.h 31 Aug 2005 08:37:53 -0000 1.6
@@ -24,18 +24,28 @@
#ifndef _SCENEMANAGER_H_
#define _SCENEMANAGER_H_
+// Flags
+#define SCENEMANAGER_FLAG_NONE (0)
+#define SCENEMANAGER_FLAG_FULLY_ON_SCREEN (1)
+#define SCENEMANAGER_FLAG_PARTLY_ON_SCREEN (2)
+
typedef struct scenemanager {
GdkRegion* m_pTakenRegion;
+ gint m_nWindowWidth;
+ gint m_nWindowHeight;
+
GHashTable* m_pLabelHash;
} scenemanager_t;
void scenemanager_init(void);
void scenemanager_new(scenemanager_t** ppReturn);
+void scenemanager_set_screen_dimensions(scenemanager_t* pSceneManager, gint nWindowWidth, gint nWindowHeight);
+
+gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* pScreenLocation, gint nFlags);
+gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints, gint nFlags);
+gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect, gint nFlags);
-gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* pScreenLocation);
-gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints);
-gboolean scenemanager_can_draw_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect);
void scenemanager_claim_label(scenemanager_t* pSceneManager, const gchar* pszLabel);
void scenemanager_claim_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints);
void scenemanager_claim_rectangle(scenemanager_t* pSceneManager, GdkRectangle* pRect);
Index: util.c
===================================================================
RCS file: /cvs/cairo/roadster/src/util.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- util.c 28 Aug 2005 22:23:14 -0000 1.7
+++ util.c 31 Aug 2005 08:37:53 -0000 1.8
@@ -78,10 +78,7 @@
gchar** util_split_words_onto_two_lines(const gchar* pszText, gint nMinLineLength, gint nMaxLineLength)
{
- g_assert_not_reached(); // untested
-
#define MAX_WORDS_WE_CAN_HANDLE (6)
-
// NOTE: 'nMinLineLength' and 'nMaxLineLength' are loosely enforced
//
More information about the cairo-commit
mailing list