Esempio n. 1
0
        public void Paint(Graphics graphics, IDrawingSurface layer, ITile iTile, bool isPrint)
        {
            if (!m_enabled)
            {
                return;
            }

            //LibSys.StatusBar.Trace("Track::Paint()  - " + m_trackpoints.Count + " : " + Name);

            int prevX = 0;
            int prevY = 0;

            int   arrowWingsTrk        = Math.Max(15, (int)(7.0f * TrackPalette.penTrackThickness));
            int   arrowWingsRte        = Math.Max(18, (int)(9.0f * TrackPalette.penRouteThickness));
            float trackThicknessFactor = TrackPalette.penTrackThickness / 2.0f;

            Pen penHighlight  = new Pen(Color.Red, 3.0f * trackThicknessFactor);
            Pen penHighlight2 = new Pen(Color.Yellow, 3.0f * trackThicknessFactor);

            int diam = (int)Math.Ceiling(4.0f * trackThicknessFactor);
            int rad  = diam / 2;

            Waypoint _lastHighlightedWaypoint = null;

            int step = getStep(this, layer.getCameraElevation());

            bool doDrawPoints   = Project.drawTrackpoints && (layer.getCameraElevation() < DRAW_POINT_TRESHOLD);
            int  pointCount     = 0;
            int  lastArrowCount = 0;
//			Point tailPoint = Point.Empty;
            Point lastArrowPoint = Point.Empty;

            // prepare default brushes/pens, with either random or preset color:
            Brush trkBrush = getBrush();                        // filled circles, arrow heads
            Pen   trkPen   = getTrackPen();                     // lines
            Pen   rtePen   = getRoutePen();                     // lines
            Pen   rteTrkPen;

            // square (flat) Cap is a pain in neck; this kind of works:
            GraphicsPath objPath = new GraphicsPath();
//			objPath.AddRectangle(new Rectangle(0, -1, 0, 0));
            CustomLineCap squareCap = new System.Drawing.Drawing2D.CustomLineCap(objPath, null, LineCap.Flat);

            squareCap.WidthScale = 0.0f;

            bool skipOne;

            for (int i = 0; i < m_trackpoints.Count; i += step)
            {
                skipOne = false;
                try
                {
                    Waypoint wp1             = (Waypoint)m_trackpoints.GetByIndex(i);
                    bool     doDrawThisPoint = doDrawPoints;

                    if (wp1.ThumbImage != null)
                    {
                        skipOne = true;                                 // draw and move to next trackpoint; keep in sync with the stepping logic
                    }

                    pointCount++;
                    Waypoint wp2 = null;
                    if (i != m_trackpoints.Count - 1 && (i + step) < m_trackpoints.Count)                       // last point
                    {
                        wp2 = (Waypoint)m_trackpoints.GetByIndex(i + step);
                    }

                    if (!layer.insideScreenRectangle(wp1.Location) && wp2 != null && !layer.insideScreenRectangle(wp2.Location))
                    {
                        goto nextLoop;
                    }

                    Point p1 = isPrint ? layer.toPixelLocationPrint(wp1.Location, iTile) : layer.toPixelLocation(wp1.Location, iTile);
//					if(tailPoint.IsEmpty)
//					{
//						tailPoint = p1;
//					}

                    int    dd          = diam;
                    bool   staying     = false;
                    bool   doHighlight = false;
                    bool   hasContent  = wp1.hasContent;
                    bool   hasUrl      = wp1.Url != null && wp1.Url.Length > 0;
                    string stayLbl     = "";
                    if (TimeFilter.Enabled)
                    {
                        doHighlight = TimeFilter.passes(wp1.DateTime);
                        if (!doHighlight && TimeFilter.beforeFrom(wp1.DateTime))
                        {
                            // in case it doesn't pass directly, but we are in the middle of the track
                            // and the time filter boundaries are between this point and next point,
                            // we highlight both points because we are sitting there at this time.
                            if (i > 0 && wp2 != null)                                   // mid-track
                            {
                                if (TimeFilter.afterTo(wp2.DateTime))
                                {
                                    doHighlight = true;
                                    dd         *= 3;
                                    staying     = true;
                                    DateTime wp2LocalTime = Project.zuluToLocal(wp2.DateTime);
                                    stayLbl = "staying till " + wp2LocalTime.TimeOfDay;
                                }
                            }
                        }
                    }

                    if (SelectFilter.Enabled)
                    {
                        doHighlight = SelectFilter.passes(wp1);
                        dd          = 2;
                    }

                    if (doHighlight)
                    {
                        if (_lastHighlightedWaypoint == null)
                        {
                            _lastHighlightedWaypoint = wp1;
                        }
                        graphics.DrawEllipse(penHighlight, p1.X - dd, p1.Y - dd, dd * 2, dd * 2);
                        if (staying)
                        {
                            int  x    = p1.X + 10;
                            int  y    = p1.Y - dd * 2;
                            Font font = Project.getLabelFont(Project.FONT_SIZE_REGULAR + 2);
                            if (Project.waypointUseShadow)
                            {
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x, y);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x + 2, y);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x, y - 2);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x + 2, y - 2);
                            }
                            graphics.DrawString(stayLbl, font, Project.whiteBrush, x + 1, y - 1);
                        }
                    }

                    if (hasUrl)
                    {
                        graphics.DrawEllipse(penHighlight2, p1.X - 4, p1.Y - 4, 8, 8);
                    }

                    if (hasContent)
                    {
                        if (!hasUrl)
                        {
                            graphics.DrawEllipse(Pens.Cyan, p1.X - 4, p1.Y - 4, 8, 8);
                        }
                        graphics.DrawEllipse(penHighlight, p1.X - 2, p1.Y - 2, 4, 4);
                    }

                    if (hasUrl || hasContent || (wp2 == null && (i == 0 || !Project.makeRouteMode)))                    // last point
                    {
                        int offsetX = 0;
                        int offsetY = 0;
                        if (isPrint)
                        {
                            Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null);
                            Point pixelPosDispl = wp1.PixelLocation;
                            offsetX = pixelPosPrint.X - pixelPosDispl.X;
                            offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                        }
                        wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                    }

                    if (wp2 != null)                                    // not the last point
                    {
                        Point p2 = isPrint ? layer.toPixelLocationPrint(wp2.Location, iTile) : layer.toPixelLocation(wp2.Location, iTile);

                        bool thickPen = false;
                        if (m_isRoute)
                        {
                            rteTrkPen = rtePen;
                        }
                        else
                        {
                            if (Project.trackElevColor)
                            {
                                double elevRange = ElevMax - ElevMin;
                                if (elevRange > 1.0d && elevRange < 20000.0d)
                                {
                                    double elevFactor = elevRange / 256.0d;
                                    double elev       = wp2.Location.Elev;
                                    int    r          = (int)((elev - ElevMin) / elevFactor);
                                    if (r > 255)
                                    {
                                        r = 255;
                                    }
                                    int b = 255 - r;
                                    int g = (255 - (r > b ? r : b)) * 2;                                                // will be high where R and B are close to equal, amounts to cyan

                                    Color legColor = Color.FromArgb(r, g, b);
                                    trkBrush = new SolidBrush(legColor);
                                    trkPen   = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor);
                                    thickPen = true;
                                }
                            }
                            else if (Project.trackSpeedColor)
                            {
                                double speedRange = SpeedMax - SpeedMin;
                                if (speedRange > 1000.0d && speedRange < 1000000000.0d)
                                {
                                    double speedFactor = speedRange / 256.0d;
                                    double speed       = wp2.Speed;
                                    int    r           = (int)((speed - SpeedMin) / speedFactor);
                                    if (r > 255)
                                    {
                                        r = 255;
                                    }
                                    int b = 255 - r;
                                    int g = (255 - (r > b ? r : b)) * 2;                                                // will be high where R and B are close to equal, amounts to cyan

                                    Color legColor = Color.FromArgb(r, g, b);
                                    trkBrush = new SolidBrush(legColor);
                                    trkPen   = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor);
                                    thickPen = true;
                                }
                            }
                            rteTrkPen = doHighlight ? penHighlight : trkPen;
                        }

                        int    dltaX  = p2.X - p1.X;
                        int    dltaY  = p2.Y - p1.Y;
                        double lenSq  = dltaX * dltaX + dltaY * dltaY;
                        int    dlta2X = p2.X - lastArrowPoint.X;
                        int    dlta2Y = p2.Y - lastArrowPoint.Y;
                        double lenSq2 = dlta2X * dlta2X + dlta2Y * dlta2Y;

                        if (lenSq2 > 10000.0d || lenSq > 900.0d)                        // big enough to hold arrow?
                        {
                            float arrowWidth  = thickPen ? 4 : 3;
                            float arrowHeight = 6;
                            bool  arrowFill   = true;

                            rteTrkPen.CustomEndCap = new AdjustableArrowCap(arrowWidth, arrowHeight, arrowFill);

                            lastArrowCount = pointCount;
                            lastArrowPoint = p2;
//							tailPoint = p2;
                            //doDrawThisPoint = false;
                        }
                        else
                        {
                            // no cap - null doesn't work here
                            rteTrkPen.CustomEndCap = squareCap;
                        }

                        graphics.DrawLine(rteTrkPen, p1, p2);

                        if (doDrawThisPoint && diam > 2)
                        {
                            graphics.FillEllipse(trkBrush, p2.X - rad, p2.Y - rad, diam, diam);
                        }

                        if (i == 0)
                        {
                            int offsetX = 0;
                            int offsetY = 0;
                            if (isPrint)
                            {
                                Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null);
                                Point pixelPosDispl = wp1.PixelLocation;
                                offsetX = pixelPosPrint.X - pixelPosDispl.X;
                                offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                            }
                            wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                            prevX = p1.X;
                            prevY = p1.Y;
                        }
                        else if ((p1.X - prevX) * (p1.X - prevX) + (p1.Y - prevY) * (p1.Y - prevY) > 900)
                        {
                            if (Project.showTrackpointNumbers)
                            {
                                // call simplified PaintLabel, not regular one:
                                PaintLabel(graphics, wp1.Name, p1.X, p1.Y, isPrint);
                            }
                            prevX = p1.X;
                            prevY = p1.Y;
                        }
                    }
                    else if (doDrawThisPoint)
                    {
                        graphics.FillEllipse(trkBrush, p1.X - rad, p1.Y - rad, diam, diam);
                    }
                }
                catch (Exception e)
                {
                    LibSys.StatusBar.Error("Track::Paint()  - " + e.Message);
                }

nextLoop:
                if (skipOne)
                {
                    i -= (step - 1);                                    // move to the next trackpoint
                    continue;
                }
                int pointsLeft = m_trackpoints.Count - i;
                if (pointsLeft > 1 && pointsLeft < step)
                {
                    step = pointsLeft - 2;
                    if (step < 1)
                    {
                        step = 1;
                    }
                }
            }

            if (Project.thumbDoDisplay)
            {
                SortedList ppts = Project.mainCommand.getWaypointsWithThumbs(m_id);
                for (int i = 0; i < ppts.Count; i++)
                {
                    Waypoint wpt            = (Waypoint)ppts.GetByIndex(i);
                    Pen      thumbBorderPen = Pens.Blue;
                    Pen      thumbCornerPen = new Pen(Color.Blue, 3.0f);
                    int      width          = wpt.ThumbImage.Width;
                    int      height         = wpt.ThumbImage.Height;
                    Point    p1             = isPrint ? layer.toPixelLocationPrint(wpt.Location, iTile) : layer.toPixelLocation(wpt.Location, iTile);
                    switch (wpt.ThumbPosition)
                    {
                    case 0:                                     // top right
                        graphics.DrawImage(wpt.ThumbImage, p1.X, p1.Y - height, width, height);
                        graphics.DrawRectangle(thumbBorderPen, p1.X, p1.Y - height, width - 1, height - 1);
                        graphics.DrawLine(thumbCornerPen, p1.X + 2, p1.Y, p1.X + 2, p1.Y - 10);
                        graphics.DrawLine(thumbCornerPen, p1.X, p1.Y - 2, p1.X + 10, p1.Y - 2);
                        break;

                    case 1:                                     // center
                    default:
                        graphics.DrawImage(wpt.ThumbImage, p1.X - width / 2, p1.Y - height / 2, width, height);
                        graphics.DrawRectangle(thumbBorderPen, p1.X - width / 2, p1.Y - height / 2, width - 1, height - 1);
                        break;
                    }
                    int offsetX = 0;
                    int offsetY = 0;
                    if (isPrint)
                    {
                        Point pixelPosPrint = layer.toPixelLocationPrint(wpt.Location, null);
                        Point pixelPosDispl = wpt.PixelLocation;
                        offsetX = pixelPosPrint.X - pixelPosDispl.X;
                        offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                    }
                    wpt.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                }
            }

            if (_lastHighlightedWaypoint != null)
            {
                lastHighlightedWaypoint = _lastHighlightedWaypoint;
            }
        }
Esempio n. 2
0
        public void Paint(Graphics graphics, IDrawingSurface layer, ITile iTile, bool isPrint)
        {
            if(!m_enabled)
            {
                return;
            }

            //LibSys.StatusBar.Trace("Track::Paint()  - " + m_trackpoints.Count + " : " + Name);

            int prevX = 0;
            int prevY = 0;

            int arrowWingsTrk = Math.Max(15, (int)(7.0f * TrackPalette.penTrackThickness));
            int arrowWingsRte = Math.Max(18, (int)(9.0f * TrackPalette.penRouteThickness));
            float trackThicknessFactor = TrackPalette.penTrackThickness / 2.0f;

            Pen	penHighlight = new Pen(Color.Red, 3.0f * trackThicknessFactor);
            Pen	penHighlight2 = new Pen(Color.Yellow, 3.0f * trackThicknessFactor);

            int diam = (int)Math.Ceiling(4.0f * trackThicknessFactor);
            int rad = diam/2;

            Waypoint _lastHighlightedWaypoint = null;

            int step = getStep(this, layer.getCameraElevation());

            bool doDrawPoints = Project.drawTrackpoints && (layer.getCameraElevation() < DRAW_POINT_TRESHOLD);
            int pointCount = 0;
            int lastArrowCount = 0;
            //			Point tailPoint = Point.Empty;
            Point lastArrowPoint = Point.Empty;

            // prepare default brushes/pens, with either random or preset color:
            Brush trkBrush = getBrush();		// filled circles, arrow heads
            Pen trkPen = getTrackPen();			// lines
            Pen rtePen = getRoutePen();			// lines
            Pen rteTrkPen;

            // square (flat) Cap is a pain in neck; this kind of works:
            GraphicsPath objPath = new GraphicsPath();
            //			objPath.AddRectangle(new Rectangle(0, -1, 0, 0));
            CustomLineCap squareCap = new System.Drawing.Drawing2D.CustomLineCap(objPath, null, LineCap.Flat);
            squareCap.WidthScale = 0.0f;

            bool skipOne;

            for(int i=0; i < m_trackpoints.Count ;i+=step)
            {
                skipOne = false;
                try
                {
                    Waypoint wp1 = (Waypoint)m_trackpoints.GetByIndex(i);
                    bool doDrawThisPoint = doDrawPoints;

                    if(wp1.ThumbImage != null)
                    {
                        skipOne = true;		// draw and move to next trackpoint; keep in sync with the stepping logic
                    }

                    pointCount++;
                    Waypoint wp2 = null;
                    if(i != m_trackpoints.Count-1 && (i + step) < m_trackpoints.Count)	// last point
                    {
                        wp2 = (Waypoint)m_trackpoints.GetByIndex(i+step);
                    }

                    if(!layer.insideScreenRectangle(wp1.Location) && wp2 != null && !layer.insideScreenRectangle(wp2.Location))
                    {
                        goto nextLoop;
                    }

                    Point p1 = isPrint ? layer.toPixelLocationPrint(wp1.Location, iTile) : layer.toPixelLocation(wp1.Location, iTile);
            //					if(tailPoint.IsEmpty)
            //					{
            //						tailPoint = p1;
            //					}

                    int dd = diam;
                    bool staying = false;
                    bool doHighlight = false;
                    bool hasContent = wp1.hasContent;
                    bool hasUrl = wp1.Url != null && wp1.Url.Length > 0;
                    string stayLbl = "";
                    if(TimeFilter.Enabled)
                    {
                        doHighlight = TimeFilter.passes(wp1.DateTime);
                        if(!doHighlight && TimeFilter.beforeFrom(wp1.DateTime))
                        {
                            // in case it doesn't pass directly, but we are in the middle of the track
                            // and the time filter boundaries are between this point and next point,
                            // we highlight both points because we are sitting there at this time.
                            if(i > 0 && wp2 != null)	// mid-track
                            {
                                if(TimeFilter.afterTo(wp2.DateTime))
                                {
                                    doHighlight = true;
                                    dd *= 3;
                                    staying = true;
                                    DateTime wp2LocalTime = Project.zuluToLocal(wp2.DateTime);
                                    stayLbl = "staying till " + wp2LocalTime.TimeOfDay;
                                }
                            }
                        }
                    }

                    if(SelectFilter.Enabled)
                    {
                        doHighlight = SelectFilter.passes(wp1);
                        dd = 2;
                    }

                    if(doHighlight)
                    {
                        if(_lastHighlightedWaypoint == null)
                        {
                            _lastHighlightedWaypoint = wp1;
                        }
                        graphics.DrawEllipse(penHighlight, p1.X-dd, p1.Y-dd, dd*2, dd*2);
                        if(staying)
                        {
                            int x = p1.X + 10;
                            int y = p1.Y - dd*2;
                            Font font = Project.getLabelFont(Project.FONT_SIZE_REGULAR + 2);
                            if(Project.waypointUseShadow)
                            {
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x,   y);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x+2, y);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x,   y-2);
                                graphics.DrawString(stayLbl, font, Project.blackBrush, x+2, y-2);
                            }
                            graphics.DrawString(stayLbl, font, Project.whiteBrush, x+1,   y-1);
                        }
                    }

                    if(hasUrl)
                    {
                        graphics.DrawEllipse(penHighlight2, p1.X-4, p1.Y-4, 8, 8);
                    }

                    if(hasContent)
                    {
                        if(!hasUrl)
                        {
                            graphics.DrawEllipse(Pens.Cyan, p1.X-4, p1.Y-4, 8, 8);
                        }
                        graphics.DrawEllipse(penHighlight, p1.X-2, p1.Y-2, 4, 4);
                    }

                    if(hasUrl || hasContent || (wp2 == null && (i==0 || !Project.makeRouteMode)))	// last point
                    {
                        int offsetX = 0;
                        int offsetY = 0;
                        if(isPrint)
                        {
                            Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null);
                            Point pixelPosDispl = wp1.PixelLocation;
                            offsetX = pixelPosPrint.X - pixelPosDispl.X;
                            offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                        }
                        wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                    }

                    if(wp2 != null)			// not the last point
                    {
                        Point p2 = isPrint ? layer.toPixelLocationPrint(wp2.Location, iTile) : layer.toPixelLocation(wp2.Location, iTile);

                        bool thickPen = false;
                        if(m_isRoute)
                        {
                            rteTrkPen = rtePen;
                        }
                        else
                        {
                            if(Project.trackElevColor)
                            {
                                double elevRange = ElevMax - ElevMin;
                                if(elevRange > 1.0d && elevRange < 20000.0d)
                                {
                                    double elevFactor = elevRange / 256.0d;
                                    double elev = wp2.Location.Elev;
                                    int r = (int)((elev - ElevMin) / elevFactor);
                                    if(r > 255)
                                    {
                                        r = 255;
                                    }
                                    int b = 255 - r;
                                    int g = (255 - (r > b ? r : b)) * 2;		// will be high where R and B are close to equal, amounts to cyan

                                    Color legColor = Color.FromArgb(r, g, b);
                                    trkBrush = new SolidBrush(legColor);
                                    trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor);
                                    thickPen = true;
                                }
                            }
                            else if(Project.trackSpeedColor)
                            {
                                double speedRange = SpeedMax - SpeedMin;
                                if(speedRange > 1000.0d && speedRange < 1000000000.0d)
                                {
                                    double speedFactor = speedRange / 256.0d;
                                    double speed = wp2.Speed;
                                    int r = (int)((speed - SpeedMin) / speedFactor);
                                    if(r > 255)
                                    {
                                        r = 255;
                                    }
                                    int b = 255 - r;
                                    int g = (255 - (r > b ? r : b)) * 2;		// will be high where R and B are close to equal, amounts to cyan

                                    Color legColor = Color.FromArgb(r, g, b);
                                    trkBrush = new SolidBrush(legColor);
                                    trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor);
                                    thickPen = true;
                                }
                            }
                            rteTrkPen = doHighlight ? penHighlight : trkPen;
                        }

                        int dltaX = p2.X - p1.X;
                        int dltaY = p2.Y - p1.Y;
                        double lenSq = dltaX * dltaX + dltaY * dltaY;
                        int dlta2X = p2.X - lastArrowPoint.X;
                        int dlta2Y = p2.Y - lastArrowPoint.Y;
                        double lenSq2 = dlta2X * dlta2X + dlta2Y * dlta2Y;

                        if(lenSq2 > 10000.0d || lenSq > 900.0d)	// big enough to hold arrow?
                        {
                            float arrowWidth = thickPen ? 4 : 3;
                            float arrowHeight = 6;
                            bool arrowFill = true;

                            rteTrkPen.CustomEndCap = new AdjustableArrowCap(arrowWidth, arrowHeight, arrowFill);

                            lastArrowCount = pointCount;
                            lastArrowPoint = p2;
            //							tailPoint = p2;
                            //doDrawThisPoint = false;
                        }
                        else
                        {
                            // no cap - null doesn't work here
                            rteTrkPen.CustomEndCap = squareCap;
                        }

                        graphics.DrawLine(rteTrkPen, p1, p2);

                        if(doDrawThisPoint && diam > 2)
                        {
                            graphics.FillEllipse(trkBrush, p2.X-rad, p2.Y-rad, diam, diam);
                        }

                        if(i == 0)
                        {
                            int offsetX = 0;
                            int offsetY = 0;
                            if(isPrint)
                            {
                                Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null);
                                Point pixelPosDispl = wp1.PixelLocation;
                                offsetX = pixelPosPrint.X - pixelPosDispl.X;
                                offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                            }
                            wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                            prevX = p1.X;
                            prevY = p1.Y;
                        }
                        else if((p1.X - prevX)*(p1.X - prevX) + (p1.Y - prevY)*(p1.Y - prevY) > 900)
                        {
                            if(Project.showTrackpointNumbers)
                            {
                                // call simplified PaintLabel, not regular one:
                                PaintLabel(graphics, wp1.Name, p1.X,   p1.Y, isPrint);
                            }
                            prevX = p1.X;
                            prevY = p1.Y;
                        }
                    }
                    else if(doDrawThisPoint)
                    {
                        graphics.FillEllipse(trkBrush, p1.X-rad, p1.Y-rad, diam, diam);
                    }

                }
                catch (Exception e)
                {
                    LibSys.StatusBar.Error("Track::Paint()  - " + e.Message);
                }

            nextLoop:
                if(skipOne)
                {
                    i -= (step - 1);		// move to the next trackpoint
                    continue;
                }
                int pointsLeft = m_trackpoints.Count - i;
                if(pointsLeft > 1 && pointsLeft < step)
                {
                    step = pointsLeft - 2;
                    if(step < 1)
                    {
                        step = 1;
                    }
                }
            }

            if(Project.thumbDoDisplay)
            {
                SortedList ppts = Project.mainCommand.getWaypointsWithThumbs(m_id);
                for (int i=0; i < ppts.Count ;i++)
                {
                    Waypoint wpt = (Waypoint)ppts.GetByIndex(i);
                    Pen thumbBorderPen = Pens.Blue;
                    Pen thumbCornerPen = new Pen(Color.Blue, 3.0f);
                    int width = wpt.ThumbImage.Width;
                    int height = wpt.ThumbImage.Height;
                    Point p1 = isPrint ? layer.toPixelLocationPrint(wpt.Location, iTile) : layer.toPixelLocation(wpt.Location, iTile);
                    switch(wpt.ThumbPosition)
                    {
                        case 0:		// top right
                            graphics.DrawImage(wpt.ThumbImage, p1.X, p1.Y-height, width, height);
                            graphics.DrawRectangle(thumbBorderPen, p1.X, p1.Y-height, width-1, height-1);
                            graphics.DrawLine(thumbCornerPen, p1.X+2, p1.Y, p1.X+2, p1.Y-10);
                            graphics.DrawLine(thumbCornerPen, p1.X, p1.Y-2, p1.X+10, p1.Y-2);
                            break;
                        case 1:		// center
                        default:
                            graphics.DrawImage(wpt.ThumbImage, p1.X-width/2, p1.Y-height/2, width, height);
                            graphics.DrawRectangle(thumbBorderPen, p1.X-width/2, p1.Y-height/2, width-1, height-1);
                            break;
                    }
                    int offsetX = 0;
                    int offsetY = 0;
                    if(isPrint)
                    {
                        Point pixelPosPrint = layer.toPixelLocationPrint(wpt.Location, null);
                        Point pixelPosDispl = wpt.PixelLocation;
                        offsetX = pixelPosPrint.X - pixelPosDispl.X;
                        offsetY = pixelPosPrint.Y - pixelPosDispl.Y;
                    }
                    wpt.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY);
                }
            }

            if(_lastHighlightedWaypoint != null)
            {
                lastHighlightedWaypoint = _lastHighlightedWaypoint;
            }
        }