void Route::DrawSegment( ocpnDC& dc, wxPoint *rp1, wxPoint *rp2, ViewPort &vp, bool bdraw_arrow ) { if( m_bRtIsSelected ) dc.SetPen( *g_pRouteMan->GetSelectedRoutePen() ); else if( m_bRtIsActive ) dc.SetPen( *g_pRouteMan->GetActiveRoutePen() ); else dc.SetPen( *g_pRouteMan->GetRoutePen() ); RenderSegment( dc, rp1->x, rp1->y, rp2->x, rp2->y, vp, bdraw_arrow ); }
void ConfigurationBatchDialog::Render(ocpnDC &dc, PlugIn_ViewPort &vp) { if(!IsShown() || m_notebookConfigurations->GetCurrentPage() != m_pRoutes) return; wxFont mfont( 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ); dc.SetFont( mfont ); dc.SetTextForeground(*wxRED); // dc.SetTextBackground(*wxTRANSPARENT); // dc.SetTextBackground(wxColour(0, 0, 0, wxALPHA_TRANSPARENT)); dc.SetPen(wxPen(*wxRED, 3)); for(std::vector<BatchSource*>::iterator it = sources.begin(); it != sources.end(); it++) { wxPoint p1, p2; double lat, lon; RouteMap::PositionLatLon((*it)->Name, lat, lon); GetCanvasPixLL(&vp, &p1, lat, lon); dc.DrawText((*it)->Name, p1.x, p1.y); dc.DrawCircle(p1.x, p1.y, 5); for(std::list<BatchSource*>::iterator it2 = (*it)->destinations.begin(); it2 != (*it)->destinations.end(); it2++) { RouteMap::PositionLatLon((*it2)->Name, lat, lon); GetCanvasPixLL(&vp, &p2, lat, lon); dc.DrawLine(p1.x, p1.y, p2.x, p2.y); wxPoint p3((2*p1.x+3*p2.x)/5, (2*p1.y+3*p2.y)/5); wxPoint p4((p1.x+p2.x)/2, (p1.y+p2.y)/2); wxPoint p5((p2.y-p1.y)/8, (p1.x-p2.x)/8); dc.DrawLine(p3.x, p3.y, p4.x+p5.x, p4.y+p5.y); dc.DrawLine(p3.x, p3.y, p4.x-p5.x, p4.y-p5.y); } } }
void RoutePoint::Draw( ocpnDC& dc, wxPoint *rpn ) { wxPoint r; wxRect hilitebox; cc1->GetCanvasPointPix( m_lat, m_lon, &r ); // return the home point in this dc to allow "connect the dots" if( NULL != rpn ) *rpn = r; if( !m_bIsVisible ) // pjotrc 2010.02.13, 2011.02.24 return; // Optimization, especially apparent on tracks in normal cases if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return; wxPen *pen; if( m_bBlink ) pen = g_pRouteMan->GetActiveRoutePointPen(); else pen = g_pRouteMan->GetRoutePointPen(); // Substitue icon? wxBitmap *pbm; if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) ) pbm = pWayPointMan->GetIconBitmap( _T ( "activepoint" ) ); else pbm = m_pbmIcon; wxBitmap *pbms = NULL; if( g_ChartScaleFactorExp > 1.0){ if(m_IconScaleFactor != g_ChartScaleFactorExp){ wxImage scaled_image = pbm->ConvertToImage(); int new_width = pbm->GetWidth() * g_ChartScaleFactorExp; int new_height = pbm->GetHeight() * g_ChartScaleFactorExp; m_ScaledBMP = wxBitmap(scaled_image.Scale(new_width, new_height, wxIMAGE_QUALITY_HIGH)); m_IconScaleFactor = g_ChartScaleFactorExp; } if( m_ScaledBMP.IsOk() ) pbm = &m_ScaledBMP; } int sx2 = pbm->GetWidth() / 2; int sy2 = pbm->GetHeight() / 2; // Calculate the mark drawing extents wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 ); // the bitmap extents if( m_bShowName ) { if( 0 == m_pMarkFont ) { m_pMarkFont = FontMgr::Get().GetFont( _( "Marks" ) ); m_FontColor = FontMgr::Get().GetFontColor( _( "Marks" ) ); CalculateNameExtents(); } if( m_pMarkFont ) { wxRect r2( r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY, m_NameExtents.x, m_NameExtents.y ); r1.Union( r2 ); } } hilitebox = r1; hilitebox.x -= r.x; hilitebox.y -= r.y; float radius; if( g_btouch ){ hilitebox.Inflate( 20 ); radius = 20.0f; } else{ hilitebox.Inflate( 4 ); radius = 4.0f; } wxColour hi_colour = pen->GetColour(); unsigned char transparency = 100; if( m_bIsBeingEdited ){ hi_colour = GetGlobalColor( _T ( "YELO1" ) ); transparency = 150; } // Highlite any selected point if( m_bPtIsSelected || m_bIsBeingEdited) { AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius, hi_colour, transparency ); } bool bDrawHL = false; if( m_bBlink && ( gFrame->nBlinkerTick & 1 ) ) bDrawHL = true; if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) { dc.DrawBitmap( *pbm, r.x - sx2, r.y - sy2, true ); // on MSW, the dc Bounding box is not updated on DrawBitmap() method. // Do it explicitely here for all platforms. dc.CalcBoundingBox( r.x - sx2, r.y - sy2 ); dc.CalcBoundingBox( r.x + sx2, r.y + sy2 ); } if( m_bShowName ) { if( m_pMarkFont ) { dc.SetFont( *m_pMarkFont ); dc.SetTextForeground( m_FontColor ); dc.DrawText( m_MarkName, r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY ); } } // Draw waypoint radar rings if activated if( m_iWaypointRangeRingsNumber && m_bShowWaypointRangeRings ) { double factor = 1.00; if( m_iWaypointRangeRingsStepUnits == 1 ) // nautical miles factor = 1 / 1.852; factor *= m_fWaypointRangeRingsStep; double tlat, tlon; wxPoint r1; ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon ); cc1->GetCanvasPointPix( tlat, tlon, &r1 ); double lpp = sqrt( pow( (double) (r.x - r1.x), 2) + pow( (double) (r.y - r1.y), 2 ) ); int pix_radius = (int) lpp; wxPen ppPen1( m_wxcWaypointRangeRingsColour, 2 ); wxBrush saveBrush = dc.GetBrush(); wxPen savePen = dc.GetPen(); dc.SetPen( ppPen1 ); dc.SetBrush( wxBrush( m_wxcWaypointRangeRingsColour, wxBRUSHSTYLE_TRANSPARENT ) ); for( int i = 1; i <= m_iWaypointRangeRingsNumber; i++ ) dc.StrokeCircle( r.x, r.y, i * pix_radius ); dc.SetPen( savePen ); dc.SetBrush( saveBrush ); } // Save the current draw rectangle in the current DC // This will be useful for fast icon redraws CurrentRect_in_DC.x = r.x + hilitebox.x; CurrentRect_in_DC.y = r.y + hilitebox.y; CurrentRect_in_DC.width = hilitebox.width; CurrentRect_in_DC.height = hilitebox.height; if( m_bBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker delete pbms; // the potentially scaled bitmap }
void Route::RenderSegment( ocpnDC& dc, int xa, int ya, int xb, int yb, ViewPort &VP, bool bdraw_arrow, int hilite_width ) { // Get the dc boundary int sx, sy; dc.GetSize( &sx, &sy ); // Try to exit early if the segment is nowhere near the screen wxRect r( 0, 0, sx, sy ); wxRect s( xa, ya, 1, 1 ); wxRect t( xb, yb, 1, 1 ); s.Union( t ); if( !r.Intersects( s ) ) return; // Clip the line segment to the dc boundary int x0 = xa; int y0 = ya; int x1 = xb; int y1 = yb; // If hilite is desired, use a Native Graphics context to render alpha colours // That is, if wxGraphicsContext is available..... if( hilite_width ) { if( Visible == cohen_sutherland_line_clip_i( &x0, &y0, &x1, &y1, 0, sx, 0, sy ) ) { wxPen psave = dc.GetPen(); wxColour y = GetGlobalColor( _T ( "YELO1" ) ); wxColour hilt( y.Red(), y.Green(), y.Blue(), 128 ); wxPen HiPen( hilt, hilite_width, wxSOLID ); dc.SetPen( HiPen ); dc.StrokeLine( x0, y0, x1, y1 ); dc.SetPen( psave ); dc.StrokeLine( x0, y0, x1, y1 ); } } else { if( Visible == cohen_sutherland_line_clip_i( &x0, &y0, &x1, &y1, 0, sx, 0, sy ) ) dc.StrokeLine( x0, y0, x1, y1 ); } if( bdraw_arrow ) { // Draw a direction arrow double theta = atan2( (double) ( yb - ya ), (double) ( xb - xa ) ); theta -= PI / 2; wxPoint icon[10]; double icon_scale_factor = 100 * VP.view_scale_ppm; icon_scale_factor = fmin ( icon_scale_factor, 1.5 ); // Sets the max size icon_scale_factor = fmax ( icon_scale_factor, .10 ); // Get the absolute line length // and constrain the arrow to be no more than xx% of the line length double nom_arrow_size = 20.; double max_arrow_to_leg = .20; double lpp = sqrt( pow( (double) ( xa - xb ), 2 ) + pow( (double) ( ya - yb ), 2 ) ); double icon_size = icon_scale_factor * nom_arrow_size; if( icon_size > ( lpp * max_arrow_to_leg ) ) icon_scale_factor = ( lpp * max_arrow_to_leg ) / nom_arrow_size; for( int i = 0; i < 7; i++ ) { int j = i * 2; double pxa = (double) ( s_arrow_icon[j] ); double pya = (double) ( s_arrow_icon[j + 1] ); pya *= icon_scale_factor; pxa *= icon_scale_factor; double px = ( pxa * sin( theta ) ) + ( pya * cos( theta ) ); double py = ( pya * sin( theta ) ) - ( pxa * cos( theta ) ); icon[i].x = (int) ( px ) + xb; icon[i].y = (int) ( py ) + yb; } wxPen savePen = dc.GetPen(); dc.SetPen( *wxTRANSPARENT_PEN ); dc.StrokePolygon( 6, &icon[0], 0, 0 ); dc.SetPen( savePen ); } }
void Route::Draw( ocpnDC& dc, ViewPort &VP ) { if( m_nPoints == 0 ) return; if( m_bVisible && m_bRtIsSelected ) { dc.SetPen( *g_pRouteMan->GetSelectedRoutePen() ); dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() ); } else if ( m_bVisible ) { int style = wxSOLID; int width = g_route_line_width; wxColour col; if( m_style != STYLE_UNDEFINED ) style = m_style; if( m_width != STYLE_UNDEFINED ) width = m_width; if( m_Colour == wxEmptyString ) { col = g_pRouteMan->GetRoutePen()->GetColour(); } else { for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) { if( m_Colour == ::GpxxColorNames[i] ) { col = ::GpxxColors[i]; break; } } } dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxSOLID ) ); } if( m_bVisible && m_bRtIsActive ) { dc.SetPen( *g_pRouteMan->GetActiveRoutePen() ); dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() ); } wxPoint rpt1, rpt2; if ( m_bVisible ) DrawPointWhich( dc, 1, &rpt1 ); wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp1 = node->GetData(); node = node->GetNext(); if ( !m_bVisible && prp1->m_bKeepXRoute ) prp1->Draw( dc ); while( node ) { RoutePoint *prp2 = node->GetData(); if ( !m_bVisible && prp2->m_bKeepXRoute ) prp2->Draw( dc ); else if (m_bVisible) prp2->Draw( dc, &rpt2 ); if ( m_bVisible ) { // Handle offscreen points bool b_2_on = VP.GetBBox().PointInBox( prp2->m_lon, prp2->m_lat, 0 ); bool b_1_on = VP.GetBBox().PointInBox( prp1->m_lon, prp1->m_lat, 0 ); //TODO This logic could be simpliifed //Simple case if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, VP, true ); // with arrows // In the cases where one point is on, and one off // we must decide which way to go in longitude // Arbitrarily, we will go the shortest way double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * VP.view_scale_ppm; double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); double dtest; int adder; if( b_1_on && !b_2_on ) { if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, VP, true ); } else if( !b_1_on && b_2_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true ); } //Both off, need to check shortest distance else if( !b_1_on && !b_2_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true ); } } rpt1 = rpt2; prp1 = prp2; node = node->GetNext(); } }
void Route::Draw( ocpnDC& dc, ViewPort &vp, const LLBBox &box ) { if( pRoutePointList->empty() ) return; LLBBox test_box = GetBBox(); if( box.IntersectOut( test_box ) ) // Route is wholly outside window return; int width = g_route_line_width; if( m_width != WIDTH_UNDEFINED ) width = m_width; if( m_bVisible && m_bRtIsSelected ) { wxPen spen = *g_pRouteMan->GetSelectedRoutePen(); spen.SetWidth( width ); dc.SetPen( spen ); dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() ); } else if ( m_bVisible ) { wxPenStyle style = wxPENSTYLE_SOLID; wxColour col; if( m_style != wxPENSTYLE_INVALID ) style = m_style; if( m_Colour == wxEmptyString ) { col = g_pRouteMan->GetRoutePen()->GetColour(); } else { for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) { if( m_Colour == ::GpxxColorNames[i] ) { col = ::GpxxColors[i]; break; } } } dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) ); } if( m_bVisible && m_bRtIsActive ) { wxPen spen = *g_pRouteMan->GetActiveRoutePen(); spen.SetWidth( width ); dc.SetPen( spen ); dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() ); } wxPoint rpt1, rpt2; if ( m_bVisible ) DrawPointWhich( dc, 1, &rpt1 ); wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp1 = node->GetData(); node = node->GetNext(); if ( !m_bVisible && prp1->m_bKeepXRoute ) prp1->Draw( dc ); while( node ) { RoutePoint *prp2 = node->GetData(); if ( !m_bVisible && prp2->m_bKeepXRoute ) prp2->Draw( dc ); else if (m_bVisible) prp2->Draw( dc, &rpt2 ); if ( m_bVisible ) { // Handle offscreen points bool b_2_on = vp.GetBBox().Contains( prp2->m_lat, prp2->m_lon ); bool b_1_on = vp.GetBBox().Contains( prp1->m_lat, prp1->m_lon ); //Simple case if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); // with arrows // In the cases where one point is on, and one off // we must decide which way to go in longitude // Arbitrarily, we will go the shortest way double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * vp.view_scale_ppm; double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); double dtest; int adder; if( b_1_on && !b_2_on ) { if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, vp, true, m_hiliteWidth ); } else if( !b_1_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; float rxd = rpt2.x - ( rpt1.x + adder ); float ryd = rpt1.y - rpt2.y; dtest = rxd*rxd + ryd*ryd; if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); } } rpt1 = rpt2; prp1 = prp2; node = node->GetNext(); } }
void Piano::Paint( int y, ocpnDC& dc, wxDC *shapeDC ) { if(shapeDC) { shapeDC->SetBackground( *wxBLACK_BRUSH); shapeDC->SetBrush( *wxWHITE_BRUSH); shapeDC->SetPen( *wxWHITE_PEN); shapeDC->Clear(); } ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle(); if(!style->chartStatusWindowTransparent) { dc.SetPen( *wxTRANSPARENT_PEN ); dc.SetBrush( m_backBrush ); dc.DrawRectangle( 0, y, cc1->GetClientSize().x, GetHeight() ); } // Create the Piano Keys int nKeys = m_key_array.GetCount(); wxPen ppPen( GetGlobalColor( _T("CHBLK") ), 1, wxPENSTYLE_SOLID ); dc.SetPen( ppPen ); for( int i = 0; i < nKeys; i++ ) { int key_db_index = m_key_array.Item( i ); if( -1 == key_db_index ) continue; bool selected = InArray(m_active_index_array, key_db_index); if( ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93 || ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93COMP ) { if(selected) dc.SetBrush( m_scBrush ); else dc.SetBrush( m_cBrush ); } else if( ChartData->GetDBChartFamily( key_db_index ) == CHART_FAMILY_VECTOR ) { if(selected) dc.SetBrush( m_svBrush ); else dc.SetBrush( m_vBrush ); } else { // Raster Chart if(selected) dc.SetBrush( m_slBrush ); else dc.SetBrush( m_tBrush ); } #if 0 // Check to see if this box appears in the sub_light array // If so, add a crosshatch pattern to the brush if(InArray(m_eclipsed_index_array, key_db_index)) { wxBrush ebrush( dc.GetBrush().GetColour(), wxCROSSDIAG_HATCH ); dc.SetBrush(ebrush); } #endif if(m_bBusy) dc.SetBrush( m_uvBrush ); wxRect box = KeyRect.Item( i ); box.y += y; if( m_brounded ) { dc.DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 ); if(shapeDC) shapeDC->DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 ); } else { dc.DrawRectangle( box.x, box.y, box.width, box.height ); if(shapeDC) shapeDC->DrawRectangle( box ); } if(InArray(m_eclipsed_index_array, key_db_index)) { dc.SetBrush( m_backBrush ); int w = 3; dc.DrawRoundedRectangle( box.x + w, box.y + w, box.width - ( 2 * w ), box.height - ( 2 * w ), 3 ); } // Look in the current noshow array for this index if(InArray(m_noshow_index_array, key_db_index) && m_pInVizIconBmp && m_pInVizIconBmp->IsOk() ) dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pInVizIconBmp ), box.x + 4, box.y + 3, false ); // Look in the current skew array for this index if(InArray(m_skew_index_array, key_db_index) && m_pSkewIconBmp && m_pSkewIconBmp->IsOk()) dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pSkewIconBmp ), box.x + box.width - m_pSkewIconBmp->GetWidth() - 4, box.y + 2, false ); // Look in the current tmerc array for this index if(InArray(m_tmerc_index_array, key_db_index) && m_pTmercIconBmp && m_pTmercIconBmp->IsOk() ) dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pTmercIconBmp ), box.x + box.width - m_pTmercIconBmp->GetWidth() - 4, box.y + 2, false ); // Look in the current poly array for this index if(InArray(m_poly_index_array, key_db_index) && m_pPolyIconBmp && m_pPolyIconBmp->IsOk() ) dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pPolyIconBmp ), box.x + box.width - m_pPolyIconBmp->GetWidth() - 4, box.y + 2, false ); } }
void Track::Draw( ocpnDC& dc, ViewPort &VP, const LLBBox &box ) { std::list< std::list<wxPoint> > pointlists; GetPointLists(pointlists, VP, box); if(!pointlists.size()) return; unsigned short int FromSegNo = 1; // Establish basic colour wxColour basic_colour; if( IsRunning() ) basic_colour = GetGlobalColor( _T ( "URED" ) ); else basic_colour = GetDimColor(g_colourTrackLineColour); wxPenStyle style = wxPENSTYLE_SOLID; int width = g_pRouteMan->GetTrackPen()->GetWidth(); wxColour col; if( m_style != wxPENSTYLE_INVALID ) style = m_style; if( m_width != WIDTH_UNDEFINED ) width = m_width; if( m_Colour == wxEmptyString ) { col = basic_colour; } else { for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) { if( m_Colour == ::GpxxColorNames[i] ) { col = ::GpxxColors[i]; break; } } } double radius = 0.; if( g_bHighliteTracks ) { double radius_meters = 20; //Current_Ch->GetNativeScale() * .0015; // 1.5 mm at original scale radius = radius_meters * VP.view_scale_ppm; if(radius < 1.0) radius = 0; } if( dc.GetDC() || radius ) { dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) ); for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin(); lines != pointlists.end(); lines++) { // convert from linked list to array wxPoint *points = new wxPoint[lines->size()]; int i = 0; for(std::list<wxPoint>::iterator line = lines->begin(); line != lines->end(); line++) { points[i] = *line; i++; } int hilite_width = radius; if( hilite_width ) { wxPen psave = dc.GetPen(); dc.StrokeLines( i, points ); wxColor trackLine_dim_colour = GetDimColor(g_colourTrackLineColour); wxColour hilt( trackLine_dim_colour.Red(), trackLine_dim_colour.Green(), trackLine_dim_colour.Blue(), 128 ); wxPen HiPen( hilt, hilite_width, wxPENSTYLE_SOLID ); dc.SetPen( HiPen ); dc.StrokeLines( i, points ); dc.SetPen( psave ); } else dc.StrokeLines( i, points ); delete [] points; } } #ifdef ocpnUSE_GL else { // opengl version glColor3ub(col.Red(), col.Green(), col.Blue()); glLineWidth( wxMax( g_GLMinSymbolLineWidth, width ) ); if( g_GLOptions.m_GLLineSmoothing ) glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); int size = 0; // convert from linked list to array, allocate array just once for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin(); lines != pointlists.end(); lines++) size = wxMax(size, lines->size()); int *points = new int[2*size]; glVertexPointer(2, GL_INT, 0, points); glEnableClientState(GL_VERTEX_ARRAY); for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin(); lines != pointlists.end(); lines++) { // convert from linked list to array int i = 0; for(std::list<wxPoint>::iterator line = lines->begin(); line != lines->end(); line++) { points[i+0] = line->x; points[i+1] = line->y; i+=2; } glDrawArrays(GL_LINE_STRIP, 0, i >> 1); } glDisableClientState(GL_VERTEX_ARRAY); delete [] points; glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); } #endif if(m_HighlightedTrackPoint >= 0) TrackPoints[m_HighlightedTrackPoint]->Draw(dc); }