Example #1
0
        public override void DrawArc(double x1, double y1, double x2, double y2, double bulge)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawArc(x1, y1, x2, y2, bulge);
                return;
            }

            stipplebit = 0x8000;

            int clipres = Clipper.ClipArc(x1, y1, x2, y2, bulge, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            for (int idx = 0; idx < clipres; idx += 5)
            {
                int cx = GFXUtil.FloatToInt(clipbuffer[idx]), cy = GFXUtil.FloatToInt(clipbuffer[idx + 1]), nx, ny;
                GeomUtil.FlattenArc(clipbuffer[idx], clipbuffer[idx + 1], clipbuffer[idx + 2], clipbuffer[idx + 3], clipbuffer[idx + 4], false, flattentol, (x, y, moveto) =>
                {
                    nx = GFXUtil.FloatToInt(x);
                    ny = GFXUtil.FloatToInt(y);
                    Line_Internal(cx, cy, nx, ny, x2 == x && y2 == y); //set last point if last segment
                    cx = nx;
                    cy = ny;
                });
            }
        }
Example #2
0
        public override void DrawLine(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawLine(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;
            Line_Internal(GFXUtil.FloatToInt(x1), GFXUtil.FloatToInt(y1), GFXUtil.FloatToInt(x2), GFXUtil.FloatToInt(y2), true);
        }
Example #3
0
        public override void DrawEllipticArc(double cx, double cy, double aradius, double bradius, double tilt, double startangle, double sweepangle)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle);
                return;
            }

            /* stipplebit = 0x8000;
             *
             * int px=0,py=0,nx,ny;
             * bool first = true;
             *
             * GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, flattentol, true, (x, y,moveto) =>
             * {
             *   nx = GFXUtil.RealToInt(x);
             *   ny = GFXUtil.RealToInt(y);
             *   if (!first)
             *       Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment?
             *   else
             *       first = false;
             *
             *
             *   px = nx;
             *   py = ny;
             * });*/


            int px = 0, py = 0, nx, ny;

            int num = Clipper.ClipEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            for (int l = 0; l < num; l += 2)
            {
                stipplebit = 0x8000;

                GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, clipbuffer[l], clipbuffer[l + 1] - clipbuffer[l], flattentol, true, (x, y, moveto) =>
                {
                    nx = GFXUtil.FloatToInt(x);
                    ny = GFXUtil.FloatToInt(y);
                    if (!moveto)
                    {
                        Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment?
                    }
                    px = nx;
                    py = ny;
                });
            }
        }
Example #4
0
        public override void DrawRectangleT(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawRectangleT(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;

            //convert to four points as poly to be able to transform
            double x3 = x2;
            double y3 = y2;

            y2 = y1;
            double x4 = x1;
            double y4 = y3;

            Transform.Apply(x1, y1, out x1, out y1, true);
            Transform.Apply(x2, y2, out x2, out y2, true);
            Transform.Apply(x3, y3, out x3, out y3, true);
            Transform.Apply(x4, y4, out x4, out y4, true);

            int ix1 = GFXUtil.FloatToInt(x1);
            int iy1 = GFXUtil.FloatToInt(y1);
            int ix2 = GFXUtil.FloatToInt(x2);
            int iy2 = GFXUtil.FloatToInt(y2);
            int ix3 = GFXUtil.FloatToInt(x3);
            int iy3 = GFXUtil.FloatToInt(y3);
            int ix4 = GFXUtil.FloatToInt(x4);
            int iy4 = GFXUtil.FloatToInt(y4);

            //check for pixel sized rectangle
            if (ix1 == ix2 && ix2 == ix3 && ix3 == ix4 && iy1 == iy2 && iy2 == iy3 && iy3 == iy4)
            {
                SetPixel(ix1, iy1, color);
                return;
            }

            Line_Internal(ix1, iy1, ix2, iy2, false);
            Line_Internal(ix2, iy2, ix3, iy3, false);
            Line_Internal(ix3, iy3, ix4, iy4, false);
            Line_Internal(ix4, iy4, ix1, iy1, false);
        }
Example #5
0
        public override void DrawPolyLine(bool close, params double[] xy)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawPolyLine(close, xy);
                return;
            }

            stipplebit = 0x8000;

            int n = xy.Length;

            if (xy.Length < 2)
            {
                return;
            }

            int prevx  = GFXUtil.FloatToInt(xy[0]);
            int prevy  = GFXUtil.FloatToInt(xy[1]);
            int firstx = prevx;
            int firsty = prevy;

            int lastidx = n - 2;

            for (int l = 0; l < n;)
            {
                bool lastpixel = l == lastidx;

                int nextx = GFXUtil.FloatToInt(xy[l++]);
                int nexty = GFXUtil.FloatToInt(xy[l++]);

                Line_Internal(prevx, prevy, nextx, nexty, lastpixel);
                prevx = nextx;
                prevy = nexty;
            }

            if (close)
            {
                Line_Internal(prevx, prevy, firstx, firsty, false);
            }
        }
Example #6
0
        private void InternalDrawBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
        {
            int n = Clipper.ClipBezier(x1, y1, x2, y2, x3, y3, x4, y4, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);
            int penx = 0, peny = 0;

            for (int l = 0; l < n; l += 2)
            {
                GeomUtil.FlattenBezier(x1, y1, x2, y2, x3, y3, x4, y4, true, flattentol, (x, y, moveto) =>
                {
                    int nextx = GFXUtil.FloatToInt(x);
                    int nexty = GFXUtil.FloatToInt(y);

                    if (!moveto)
                    {
                        Line_Internal(penx, peny, nextx, nexty, false);
                    }

                    penx = nextx;
                    peny = nexty;
                }, clipbuffer[l], clipbuffer[l + 1]);
            }
        }
Example #7
0
        public override void DrawRectangle(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawRectangle(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;

            int ix1 = GFXUtil.FloatToInt(x1);
            int iy1 = GFXUtil.FloatToInt(y1);
            int ix2 = GFXUtil.FloatToInt(x2);
            int iy2 = GFXUtil.FloatToInt(y2);

            if (ix1 == ix2)
            {
                if (iy1 == iy2)
                {
                    SetPixel(ix1, iy1, color);
                    return;
                }
                else
                {
                    Line_Internal(ix1, iy1, ix1, iy2, true); //vertical line
                    return;
                }
            }
            else if (iy1 == iy2)
            {
                Line_Internal(ix1, iy1, ix2, iy1, true); //horizontal line
                return;
            }

            Line_Internal(ix1, iy1, ix2, iy1, false);
            Line_Internal(ix2, iy1, ix2, iy2, false);
            Line_Internal(ix2, iy2, ix1, iy2, false);
            Line_Internal(ix1, iy2, ix1, iy1, false);
        }
Example #8
0
        /// <summary>
        /// Create a GDI+ Pen that corresponds to a Painter setup
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Pen CreateLinePenFromPainter(Painter p)
        {
            Color c = PainterGDIPlus.RGBToColor(p.Color);

            if (p.Opacity < 0.999)
            {
                c = Color.FromArgb(GFXUtil.FloatToInt(MathUtil.Clamp(p.Opacity * 255.0, 0.0, 255.0)), c);
            }

            Pen linepen = new Pen(c, (float)Math.Abs(p.LineWidth)); //0 means the thinnest possible on device


            switch (p.LineStyle)
            {
            case LineStyle.Continuous: break;     //done already

            case LineStyle.Custom:
                SetCustomDashes(p.LineStyleDashes, p.LineWidth, linepen);
                linepen.DashStyle = DashStyle.Custom;
                break;

            case LineStyle.Dash:
                linepen.DashPattern = new float[] { 8, 8 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.DashDotDot:
                linepen.DashPattern = new float[] { 7, 2, 2, 1, 2, 2 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.DashDot:
                linepen.DashPattern = new float[] { 8, 3, 2, 3 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.Dot:
                linepen.DashPattern = new float[] { 4, 4 };
                linepen.DashStyle   = DashStyle.Custom;
                break;
            }


            /*  if (p.LineStyle != LineStyle.Continuous)
             * {
             *    //linepen.DashStyle = LineStyleToDashStyle(p.LineStyle);
             *    linepen.DashStyle = DashStyle.Custom;
             *    if (p.LineStyle == LineStyle.Custom)
             *        SetCustomDashes(p.LineStyleDashes, linepen);
             *    else if (p.LineStyle == LineStyle.Dot)
             *        linepen.DashPattern = new float[] { 4, 4 };
             *    else
             *        linepen.DashPattern = new float[] { 10, 4, 4, 4 };
             *
             *
             *
             * }
             */

            LineCap ecap;
            DashCap dcap;

            if (p.EndCaps != EndCap.Flat) //flat is default for pen and thus need no change
            {
                GetEndCap(p.EndCaps, out ecap, out dcap);
                linepen.EndCap   = ecap;
                linepen.StartCap = ecap;
                linepen.DashCap  = dcap;
            }


            if (p.LineJoin != LineJoin.Miter)  //miter is default and thus needs no change
            {
                linepen.LineJoin = GetLineJoin(p.LineJoin);
            }

            return(linepen);
        }
Example #9
0
        public override void DrawCircle(double cx, double cy, double radius)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawCircle(cx, cy, radius);
                return;
            }


            stipplebit = 0x8000;
            int nx = 0, ny = 0, px = 0, py = 0;

            int buffersize = Clipper.ClipCircle(cx, cy, radius, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            if (buffersize <= 0)
            {
                return;
            }

            if (buffersize >= 5) //circle is clipped to arcs
            {                    //the circle is divided into arc(s)
                double bulge, x1, y1, x2, y2;
                for (int l = 0; l < buffersize; l += 5)
                {
                    x1    = clipbuffer[l];
                    y1    = clipbuffer[l + 1];
                    x2    = clipbuffer[l + 2];
                    y2    = clipbuffer[l + 3];
                    bulge = clipbuffer[l + 4];

                    //draw arc here instead of calling DrawArc to avoid arc clipping because we already clipped!
                    GeomUtil.FlattenArc(x1, y1, x2, y2, bulge, true, flattentol, (x, y, moveto) =>
                    {
                        if (moveto)
                        {
                            px = GFXUtil.FloatToInt(x);
                            py = GFXUtil.FloatToInt(y);
                        }
                        else
                        {
                            nx = GFXUtil.FloatToInt(x);
                            ny = GFXUtil.FloatToInt(y);
                            Line_Internal(px, py, nx, ny, false);
                            px = nx;
                            py = ny;
                        }
                    });
                }

                return;
            }


            for (double l = -1; l <= 1.0001; l += 2)
            { //2 arcs gives circle  //TODO: make flatten circle in GeomUtil instead
                GeomUtil.FlattenArc(cx + radius * l, cy, cx - radius * l, cy, 1.0, true, flattentol, (x, y, moveto) =>
                {
                    if (moveto)
                    {
                        px = GFXUtil.FloatToInt(x);
                        py = GFXUtil.FloatToInt(y);
                    }
                    else
                    {
                        nx = GFXUtil.FloatToInt(x);
                        ny = GFXUtil.FloatToInt(y);
                        Line_Internal(px, py, nx, ny, false);
                        px = nx;
                        py = ny;
                    }
                });
            }
        }