? src/map_draw_cairo.c_1 Index: src/map.c =================================================================== RCS file: /cvs/cairo/roadster/src/map.c,v retrieving revision 1.27 diff -u -p -r1.27 map.c --- src/map.c 14 Mar 2005 02:04:30 -0000 1.27 +++ src/map.c 14 Mar 2005 05:12:43 -0000 @@ -199,8 +199,8 @@ void map_draw(map_t* pMap, gint nDrawFla gint nRenderMode = RENDERMODE_FAST; // XXX test -// GdkRectangle rect = {200,200,100,100}; -// scenemanager_claim_rectangle(pMap->m_pSceneManager, &rect); + GdkRectangle rect = {200,200,100,100}; + scenemanager_claim_rectangle(pMap->m_pSceneManager, &rect); if(nRenderMode == RENDERMODE_FAST) { if(nDrawFlags & DRAWFLAG_GEOMETRY) { @@ -215,8 +215,8 @@ void map_draw(map_t* pMap, gint nDrawFla } // XXX test -// gdk_draw_rectangle(pMap->m_pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], -// FALSE, 200,200, 100, 100); + gdk_draw_rectangle(pMap->m_pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], + FALSE, 200,200, 100, 100); gtk_widget_queue_draw(pMap->m_pTargetWidget); } Index: src/map_draw_cairo.c =================================================================== RCS file: /cvs/cairo/roadster/src/map_draw_cairo.c,v retrieving revision 1.11 diff -u -p -r1.11 map_draw_cairo.c --- src/map_draw_cairo.c 13 Mar 2005 23:31:21 -0000 1.11 +++ src/map_draw_cairo.c 14 Mar 2005 05:12:43 -0000 @@ -145,10 +145,12 @@ static void map_draw_cairo_background(ma } #define ROAD_MAX_SEGMENTS 100 +#define LABEL_MAX_SEGMENTS 10 #define DRAW_LABEL_BUFFER_LEN (200) typedef struct labelposition { guint m_nSegments; + guint m_iIndex; gdouble m_fLength; gdouble m_fRunTotal; gdouble m_fMeanSlope; @@ -156,6 +158,14 @@ typedef struct labelposition { gdouble m_fScore; } labelposition_t; +typedef struct labelsegment { + gchar m_azLabelSegment[DRAW_LABEL_BUFFER_LEN]; + GdkPoint m_aBoundingPolygon[4]; + gdouble m_fDrawX; + gdouble m_fDrawY; + gdouble m_fAngleInRadians; +} labelsegment_t; + static void map_draw_cairo_line_label_one_segment(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, gdouble fLineWidth, const gchar* pszLabel) { // gdouble fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1]; @@ -291,6 +301,15 @@ static void map_draw_cairo_line_label_on cairo_restore(pCairo); } +static gint map_draw_cairo_line_label_position_sort(gconstpointer pA, gconstpointer pB) +{ + labelposition_t *pPosA = *(labelposition_t **)pA; + labelposition_t *pPosB = *(labelposition_t **)pB; + + if(pPosA->m_fScore > pPosB->m_fScore) return -1; + return 1; +} + static void map_draw_cairo_line_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, gdouble fLineWidth, const gchar* pszLabel) { if(pPointString->m_pPointsArray->len < 2) return; @@ -301,17 +320,11 @@ static void map_draw_cairo_line_label(ma return; } - // XXX - return; - if(pPointString->m_pPointsArray->len > ROAD_MAX_SEGMENTS) { g_warning("not drawing label for road '%s' with > %d segments.\n", pszLabel, ROAD_MAX_SEGMENTS); return; } -// gdouble fFontSize = pLabelStyle->m_afFontSizeAtZoomLevel[pRenderMetrics->m_nZoomLevel-1]; -// if(fFontSize == 0) return; - if(!scenemanager_can_draw_label_at(pMap->m_pSceneManager, pszLabel, NULL)) { //g_print("dup label: %s\n", pszLabel); return; @@ -320,10 +333,6 @@ static void map_draw_cairo_line_label(ma gchar* pszFontFamily = ROAD_FONT; cairo_save(pCairo); -// cairo_select_font(pCairo, pszFontFamily, CAIRO_FONT_SLANT_NORMAL, -// pLabelStyle->m_abBoldAtZoomLevel[pRenderMetrics->m_nZoomLevel-1] ? -// CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); -// cairo_scale_font(pCairo, fFontSize); // get total width of string cairo_text_extents_t extents; @@ -369,6 +378,7 @@ static void map_draw_cairo_line_label(ma aSlopes[iPoint] = fSlope; aPositions[iPoint].m_nSegments = 0; + aPositions[iPoint].m_iIndex = iPoint; aPositions[iPoint].m_fLength = 0.0; aPositions[iPoint].m_fRunTotal = 0.0; aPositions[iPoint].m_fMeanSlope = 0.0; @@ -393,7 +403,8 @@ static void map_draw_cairo_line_label(ma return; } - gdouble fMaxScore = 0.0; + GPtrArray *pPositionsPtrArray = g_ptr_array_new(); + //gdouble fMaxScore = 0; gint iBestPosition; for(iPosition = 1 ; iPosition < nPositions ; iPosition++) { @@ -414,14 +425,17 @@ static void map_draw_cairo_line_label(ma // calculate a score between 0 (worst) and 1 (best), we want to minimize both the mean and std dev of slope aPositions[iPosition].m_fScore = 1.0/((aPositions[iPosition].m_fMeanAbsSlope+1.0)*(fStdDevSlope+1.0)); - - // find position with highest score + + // find max only + /* if(aPositions[iPosition].m_fScore > fMaxScore) { fMaxScore = aPositions[iPosition].m_fScore; iBestPosition = iPosition; } - // TODO: sort postions by score and test each against scene manager until we get go ahead + */ + // add position to the ptr array + g_ptr_array_add(pPositionsPtrArray, &(aPositions[iPosition])); /* g_print("%s: [%d] segments = %d, slope = %2.2f, stddev = %2.2f, score = %2.2f\n", pszLabel, iPosition, @@ -432,175 +446,233 @@ static void map_draw_cairo_line_label(ma */ } + // sort postions by score + if(nPositions > 1) + g_ptr_array_sort(pPositionsPtrArray, map_draw_cairo_line_label_position_sort); + + /* + for(iPosition = 1 ; iPosition < nPositions ; iPosition++) { + labelposition_t *pPos = g_ptr_array_index(pPositionsPtrArray, iPosition - 1); + + if(pPos->m_nSegments > 1) + g_print("%s: [%d] segments = %d, slope = %2.2f, score = %2.2f\n", pszLabel, iPosition, + pPos->m_nSegments, + pPos->m_fMeanAbsSlope, + pPos->m_fScore); + } + */ cairo_font_extents_t font_extents; cairo_current_font_extents(pCairo, &font_extents); - gdouble fFrontPadding = 0.0; - gdouble fFrontPaddingNext = (aPositions[iBestPosition].m_fLength - extents.width) / 2; - gint iStartPoint; + gint nTotalStringLength = strlen(pszLabel); + + for(iPosition = 1 ; iPosition < nPositions ; iPosition++) { + labelposition_t *pPos = g_ptr_array_index(pPositionsPtrArray, iPosition - 1); + gint iBestPosition = pPos->m_iIndex; + //g_print("trying position %d with score %2.2f\n", iBestPosition, pPos->m_fScore); + + gdouble fFrontPadding = 0.0; + gdouble fFrontPaddingNext = (aPositions[iBestPosition].m_fLength - extents.width) / 2; + gint iStartPoint; - iStartPoint = iBestPosition; - if(aPositions[iBestPosition].m_fRunTotal > 0) { iStartPoint = iBestPosition; - } - else { - // road runs backwards, reverse everything - iStartPoint = nNumPoints - iBestPosition - aPositions[iBestPosition].m_nSegments + 1; - // reverse the array - gint iRead,iWrite; - for(iWrite=0, iRead=nNumPoints-1 ; iRead>= 0 ; iWrite++, iRead--) { - apPoints[iWrite] = g_ptr_array_index(pPointString->m_pPointsArray, iRead); + if(aPositions[iBestPosition].m_fRunTotal > 0) { + iStartPoint = iBestPosition; + } + else { + // road runs backwards, reverse everything + iStartPoint = nNumPoints - iBestPosition - aPositions[iBestPosition].m_nSegments + 1; + // reverse the array + gint iRead,iWrite; + for(iWrite=0, iRead=nNumPoints-1 ; iRead>= 0 ; iWrite++, iRead--) { + apPoints[iWrite] = g_ptr_array_index(pPointString->m_pPointsArray, iRead); + } } - } - gint iEndPoint = iStartPoint + aPositions[iBestPosition].m_nSegments; + gint iEndPoint = iStartPoint + aPositions[iBestPosition].m_nSegments; + gint nStringStartIndex = 0; + gboolean bGoodPosition = TRUE; + labelsegment_t aSegments[LABEL_MAX_SEGMENTS]; + guint nLabelSegments = 0; - gint nTotalStringLength = strlen(pszLabel); - gint nStringStartIndex = 0; + for(iPoint = iStartPoint ; iPoint < iEndPoint ; iPoint++) { + RENDERING_THREAD_YIELD; - for(iPoint = iStartPoint ; iPoint < iEndPoint ; iPoint++) { - RENDERING_THREAD_YIELD; + if(nTotalStringLength == nStringStartIndex) break; // done - if(nTotalStringLength == nStringStartIndex) break; // done + if(nLabelSegments == LABEL_MAX_SEGMENTS) break; + labelsegment_t *pSeg = &(aSegments[nLabelSegments++]); - pMapPoint1 = apPoints[iPoint-1]; - pMapPoint2 = apPoints[iPoint]; + pMapPoint1 = apPoints[iPoint-1]; + pMapPoint2 = apPoints[iPoint]; - gdouble fX1 = SCALE_X(pRenderMetrics, pMapPoint1->m_fLongitude); - gdouble fY1 = SCALE_Y(pRenderMetrics, pMapPoint1->m_fLatitude); - gdouble fX2 = SCALE_X(pRenderMetrics, pMapPoint2->m_fLongitude); - gdouble fY2 = SCALE_Y(pRenderMetrics, pMapPoint2->m_fLatitude); + gdouble fX1 = SCALE_X(pRenderMetrics, pMapPoint1->m_fLongitude); + gdouble fY1 = SCALE_Y(pRenderMetrics, pMapPoint1->m_fLatitude); + gdouble fX2 = SCALE_X(pRenderMetrics, pMapPoint2->m_fLongitude); + gdouble fY2 = SCALE_Y(pRenderMetrics, pMapPoint2->m_fLatitude); - // determine slope of the line - gdouble fRise = fY2 - fY1; - gdouble fRun = fX2 - fX1; + // determine slope of the line + gdouble fRise = fY2 - fY1; + gdouble fRun = fX2 - fX1; - gdouble fLineLength = sqrt((fRun*fRun) + (fRise*fRise)); + gdouble fLineLength = sqrt((fRun*fRun) + (fRise*fRise)); - fFrontPadding = fFrontPaddingNext; - fFrontPaddingNext = 0.0; + fFrontPadding = fFrontPaddingNext; + fFrontPaddingNext = 0.0; - // this is probably not needed now that we only loop over line segments that will contain some label - if(fFrontPadding > fLineLength) { - fFrontPaddingNext = fFrontPadding - fLineLength; - continue; - } + pSeg->m_fAngleInRadians = atan(fRise / fRun); + if(fRun < 0.0) pSeg->m_fAngleInRadians += M_PI; - // do this after the padding calculation to possibly save some CPU cycles - gdouble fAngleInRadians = atan(fRise / fRun); - if(fRun < 0.0) fAngleInRadians += M_PI; - - //g_print("(fRise(%f) / fRun(%f)) = %f, atan(fRise / fRun) = %f: ", fRise, fRun, fRise / fRun, fAngleInRadians); - //g_print("=== NEW SEGMENT, pixel (deltaY=%f, deltaX=%f), line len=%f, (%f,%f)->(%f,%f)\n",fRise, fRun, fLineLength, pMapPoint1->m_fLatitude,pMapPoint1->m_fLongitude,pMapPoint2->m_fLatitude,pMapPoint2->m_fLongitude); - //g_print(" has screen coords (%f,%f)->(%f,%f)\n", fX1,fY1,fX2,fY2); - - gchar azLabelSegment[DRAW_LABEL_BUFFER_LEN]; - - // Figure out how much of the string we can put in this line segment - gboolean bFoundWorkableStringLength = FALSE; - gint nWorkableStringLength; - if(iPoint == (nNumPoints-1)) { - // last segment, use all of string - nWorkableStringLength = (nTotalStringLength - nStringStartIndex); - - // copy it in to the temp buffer - memcpy(azLabelSegment, &pszLabel[nStringStartIndex], nWorkableStringLength); - azLabelSegment[nWorkableStringLength] = '\0'; - } - else { - g_assert((nTotalStringLength - nStringStartIndex) > 0); + //g_print("(fRise(%f) / fRun(%f)) = %f, atan(fRise / fRun) = %f: ", fRise, fRun, fRise / fRun, fAngleInRadians); + //g_print("=== NEW SEGMENT, pixel (deltaY=%f, deltaX=%f), line len=%f, (%f,%f)->(%f,%f)\n",fRise, fRun, fLineLength, pMapPoint1->m_fLatitude,pMapPoint1->m_fLongitude,pMapPoint2->m_fLatitude,pMapPoint2->m_fLongitude); + //g_print(" has screen coords (%f,%f)->(%f,%f)\n", fX1,fY1,fX2,fY2); - for(nWorkableStringLength = (nTotalStringLength - nStringStartIndex) ; nWorkableStringLength >= 1 ; nWorkableStringLength--) { - //g_print("trying nWorkableStringLength = %d\n", nWorkableStringLength); - if(nWorkableStringLength >= DRAW_LABEL_BUFFER_LEN) break; + // Figure out how much of the string we can put in this line segment + gboolean bFoundWorkableStringLength = FALSE; + gint nWorkableStringLength; + if(iPoint == (nNumPoints-1)) { + // last segment, use all of string + nWorkableStringLength = (nTotalStringLength - nStringStartIndex); // copy it in to the temp buffer - memcpy(azLabelSegment, &pszLabel[nStringStartIndex], nWorkableStringLength); - azLabelSegment[nWorkableStringLength] = '\0'; + memcpy(pSeg->m_azLabelSegment, &pszLabel[nStringStartIndex], nWorkableStringLength); + pSeg->m_azLabelSegment[nWorkableStringLength] = '\0'; + } + else { + g_assert((nTotalStringLength - nStringStartIndex) > 0); + + for(nWorkableStringLength = (nTotalStringLength - nStringStartIndex) ; nWorkableStringLength >= 1 ; nWorkableStringLength--) { + //g_print("trying nWorkableStringLength = %d\n", nWorkableStringLength); + + if(nWorkableStringLength >= DRAW_LABEL_BUFFER_LEN) break; + + // copy it in to the temp buffer + memcpy(pSeg->m_azLabelSegment, &pszLabel[nStringStartIndex], nWorkableStringLength); + pSeg->m_azLabelSegment[nWorkableStringLength] = '\0'; - //g_print("azLabelSegment = %s\n", azLabelSegment); + //g_print("azLabelSegment = %s\n", pSeg->m_azLabelSegment); - // measure the label - cairo_text_extents(pCairo, azLabelSegment, &extents); + // measure the label + cairo_text_extents(pCairo, pSeg->m_azLabelSegment, &extents); + + // if we're skipping ahead some (frontpadding), effective line length is smaller, so subtract padding + if(extents.width <= (fLineLength - fFrontPadding)) { + //g_print("found length %d for %s\n", nWorkableStringLength, pSeg->m_azLabelSegment); + bFoundWorkableStringLength = TRUE; + + // if we have 3 pixels, and we use 2, this should be NEGATIVE 1 + // TODO: we should only really do this if the next segment doesn't take a huge bend + fFrontPaddingNext = extents.width - (fLineLength - fFrontPadding); + fFrontPaddingNext /= 2; // no good explanation for this + break; + } + } - // if we're skipping ahead some (frontpadding), effective line length is smaller, so subtract padding - if(extents.width <= (fLineLength - fFrontPadding)) { - //g_print("found length %d for %s\n", nWorkableStringLength, azLabelSegment); - bFoundWorkableStringLength = TRUE; + if(!bFoundWorkableStringLength) { + // write one character and set some frontpadding for the next piece + g_assert(nWorkableStringLength == 0); + nWorkableStringLength = 1; - // if we have 3 pixels, and we use 2, this should be NEGATIVE 1 - // TODO: we should only really do this if the next segment doesn't take a huge bend + // give the next segment some padding if we went over on this segment fFrontPaddingNext = extents.width - (fLineLength - fFrontPadding); - fFrontPaddingNext /= 2; // no good explanation for this - break; + //g_print("forcing a character (%s) on small segment, giving next segment front-padding: %f\n", pSeg->m_azLabelSegment, fFrontPaddingNext); } } - if(!bFoundWorkableStringLength) { - // write one character and set some frontpadding for the next piece - g_assert(nWorkableStringLength == 0); - nWorkableStringLength = 1; - - // give the next segment some padding if we went over on this segment - fFrontPaddingNext = extents.width - (fLineLength - fFrontPadding); - //g_print("forcing a character (%s) on small segment, giving next segment front-padding: %f\n", azLabelSegment, fFrontPaddingNext); - } - } + // move the current index up + nStringStartIndex += nWorkableStringLength; - // move the current index up - nStringStartIndex += nWorkableStringLength; - - // Normalize (make length = 1.0) by dividing by line length - // This makes a line with length 1 from the origin (0,0) - gdouble fNormalizedX = fRun / fLineLength; - gdouble fNormalizedY = fRise / fLineLength; - - // CENTER IT on the line ? - // (buffer space) |-text-| (buffer space) - // ====================================== - //gdouble fHalfBufferSpace = ((fLineLength - extents.width)/2); - gdouble fDrawX = fX1 + (fNormalizedX * fFrontPadding); - gdouble fDrawY = fY1 + (fNormalizedY * fFrontPadding); + // Normalize (make length = 1.0) by dividing by line length + // This makes a line with length 1 from the origin (0,0) + gdouble fNormalizedX = fRun / fLineLength; + gdouble fNormalizedY = fRise / fLineLength; + + // CENTER IT on the line ? + // (buffer space) |-text-| (buffer space) + // ====================================== + //gdouble fHalfBufferSpace = ((fLineLength - extents.width)/2); + pSeg->m_fDrawX = fX1 + (fNormalizedX * fFrontPadding); + pSeg->m_fDrawY = fY1 + (fNormalizedY * fFrontPadding); + + // NOTE: ***Swap the X and Y*** and normalize (make length = 1.0) by dividing by line length + // This makes a perpendicular line with length 1 from the origin (0,0) + gdouble fPerpendicularNormalizedX = fRise / fLineLength; + gdouble fPerpendicularNormalizedY = -(fRun / fLineLength); + + // we want the normal pointing towards the top of the screen. that's the negative Y direction. + //if(fPerpendicularNormalizedY > 0) fPerpendicularNormalizedY = -fPerpendicularNormalizedY; + + pSeg->m_fDrawX -= (fPerpendicularNormalizedX * font_extents.ascent/2); + pSeg->m_fDrawY -= (fPerpendicularNormalizedY * font_extents.ascent/2); + + // 0 is bottom left point + pSeg->m_aBoundingPolygon[0].x = pSeg->m_fDrawX; + pSeg->m_aBoundingPolygon[0].y = pSeg->m_fDrawY; + // 1 is upper left point + pSeg->m_aBoundingPolygon[1].x = pSeg->m_fDrawX + (fPerpendicularNormalizedX * font_extents.ascent); + pSeg->m_aBoundingPolygon[1].y = pSeg->m_fDrawY + (fPerpendicularNormalizedY * font_extents.ascent); + // 2 is upper right point + pSeg->m_aBoundingPolygon[2].x = pSeg->m_aBoundingPolygon[1].x + (fNormalizedX * extents.width); + pSeg->m_aBoundingPolygon[2].y = pSeg->m_aBoundingPolygon[1].y + (fNormalizedY * extents.width); + // 2 is lower right point + pSeg->m_aBoundingPolygon[3].x = pSeg->m_fDrawX + (fNormalizedX * extents.width); + pSeg->m_aBoundingPolygon[3].y = pSeg->m_fDrawY + (fNormalizedY * extents.width); + + if(FALSE == scenemanager_can_draw_polygon(pMap->m_pSceneManager, pSeg->m_aBoundingPolygon, 4)) { + bGoodPosition = FALSE; + break; + } - // NOTE: ***Swap the X and Y*** and normalize (make length = 1.0) by dividing by line length - // This makes a perpendicular line with length 1 from the origin (0,0) - gdouble fPerpendicularNormalizedX = fRise / fLineLength; - gdouble fPerpendicularNormalizedY = -(fRun / fLineLength); + } - // we want the normal pointing towards the top of the screen. that's the negative Y direction. - //if(fPerpendicularNormalizedY > 0) fPerpendicularNormalizedY = -fPerpendicularNormalizedY; + // try next position + if(bGoodPosition == FALSE) + continue; - fDrawX -= (fPerpendicularNormalizedX * font_extents.ascent/2); - fDrawY -= (fPerpendicularNormalizedY * font_extents.ascent/2); + // draw it + guint iLabelSegment; + for(iLabelSegment = 0 ; iLabelSegment < nLabelSegments ; iLabelSegment++) { + RENDERING_THREAD_YIELD; - cairo_save(pCairo); - cairo_move_to(pCairo, fDrawX, fDrawY); - cairo_set_rgb_color(pCairo, 0.0,0.0,0.0); - cairo_set_alpha(pCairo, 1.0); - cairo_rotate(pCairo, fAngleInRadians); + labelsegment_t *pSeg = &(aSegments[iLabelSegment]); - gdouble fHaloSize = pLabelStyle->m_afHaloAtZoomLevel[pRenderMetrics->m_nZoomLevel-1]; - if(fHaloSize >= 0) { cairo_save(pCairo); - cairo_text_path(pCairo, azLabelSegment); - cairo_set_line_width(pCairo, fHaloSize); - cairo_set_rgb_color(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_move_to(pCairo, pSeg->m_fDrawX, pSeg->m_fDrawY); + cairo_set_rgb_color(pCairo, 0.0,0.0,0.0); + cairo_set_alpha(pCairo, 1.0); + cairo_rotate(pCairo, pSeg->m_fAngleInRadians); + + gdouble fHaloSize = pLabelStyle->m_afHaloAtZoomLevel[pRenderMetrics->m_nZoomLevel-1]; + if(fHaloSize >= 0) { + cairo_save(pCairo); + cairo_text_path(pCairo, pSeg->m_azLabelSegment); + cairo_set_line_width(pCairo, fHaloSize); + cairo_set_rgb_color(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); + } + cairo_show_text(pCairo, pSeg->m_azLabelSegment); + //cairo_fill(pCairo); cairo_restore(pCairo); + + // claim the space this took up + scenemanager_claim_polygon(pMap->m_pSceneManager, pSeg->m_aBoundingPolygon, 4); } - cairo_show_text(pCairo, azLabelSegment); - //cairo_fill(pCairo); + cairo_restore(pCairo); - // scenemanager_claim_polygon(pMap->m_pSceneManager, GdkPoint *pPoints, gint nNumPoints); + // claim the label (so it won't be drawn twice) + scenemanager_claim_label(pMap->m_pSceneManager, pszLabel); + + // success + break; } - cairo_restore(pCairo); - scenemanager_claim_label(pMap->m_pSceneManager, pszLabel); + g_ptr_array_free(pPositionsPtrArray, FALSE); } void map_draw_cairo_polygon_label(map_t* pMap, cairo_t *pCairo, textlabelstyle_t* pLabelStyle, rendermetrics_t* pRenderMetrics, pointstring_t* pPointString, const gchar* pszLabel) Index: src/welcomewindow.c =================================================================== RCS file: /cvs/cairo/roadster/src/welcomewindow.c,v retrieving revision 1.4 diff -u -p -r1.4 welcomewindow.c --- src/welcomewindow.c 4 Mar 2005 09:27:26 -0000 1.4 +++ src/welcomewindow.c 14 Mar 2005 05:12:43 -0000 @@ -31,7 +31,7 @@ #include "mainwindow.h" #include "welcomewindow.h" -#define URL_CENSUS_GOV_TIGER_DATA_WEBSITE ("http://www.census.gov/geo/www/tiger/tiger2003/tgr2003.html") +#define URL_CENSUS_GOV_TIGER_DATA_WEBSITE ("http://www.census.gov/geo/www/tiger/tiger2004fe/tgr2004fe.html") struct { GtkWindow* m_pWindow;