예제 #1
0
        private void PaintElement(GraphicsProxy g, Elem e)
        {
            Node node = e.GetNode();
            Point placement = e.Location;
            bool isSelected = m_selected.Contains(e);

            if (e.Parent != null)
                g.DrawLine(StandardLinePen(), placement.X + e.Dimensions.Width / 2, placement.Y,
                    e.Parent.Location.X + e.Parent.Dimensions.Width / 2, e.Parent.Location.Y +
                    e.Parent.Dimensions.Height);

            if (node.IsBlank())
            {
                if (isSelected)
                    g.FillRectangle(HighlightBackBrush(), placement.X, placement.Y, e.Dimensions.Width - 1,
                        e.Dimensions.Height - 1);
                /*the minus 1 in the above line prevent a weird screen artefact when drawing
                 the selected variant of the red X when antialiasing is on. It looks like
                 the antialiasing actually draws pixels outside the box specified? One solution
                 would be to push antialias state, turn it off, draw the box, and pop antialias state,
                 but this is faster and adequate*/
                DrawBigX(g, placement.X + (e.Dimensions.Width / 2), placement.Y + (e.Dimensions.Height / 2));
            }
            else
            {
                Graphics realGraphics = g.Graphics;
                if (realGraphics == null)
                    RenderNode(g, e, e.Rect, isSelected, false);
                else
                {
                    if (e.cache == null)
                    {
                        Bitmap bm = new Bitmap(e.Dimensions.Width, e.Dimensions.Height);
                        using (Graphics bmGraphics = Graphics.FromImage(bm))
                        {
                            GraphicsPassThrough gp = new GraphicsPassThrough(bmGraphics);
                            SetupAntiAliasing(gp);
                            RenderNodePositionInfo rnpi =
                                RenderNode(gp, e, new Rectangle(Point.Empty, e.Dimensions), false, true);
                            e.labelRect = rnpi.labelRect;
                            e.lexRect = rnpi.lexRect;
                        }
                        e.cache = bm;
                        bm = new Bitmap(e.Dimensions.Width, e.Dimensions.Height);
                        using (Graphics bmGraphics = Graphics.FromImage(bm))
                        {
                            GraphicsPassThrough gp = new GraphicsPassThrough(bmGraphics);
                            SetupAntiAliasing(gp);
                            RenderNode(gp, e, new Rectangle(Point.Empty, e.Dimensions), true, false);
                        }
                        e.cacheSelected = bm;
                    }
                    realGraphics.DrawImageUnscaled(isSelected ? e.cacheSelected : e.cache, e.Location);

                    /*
                     * I would like to draw the image with transparency, but this
                     * produces problems since the text image includes gradients
                     * resulting from text antialiasing
                    System.Drawing.Imaging.ImageAttributes attrs=
                        new System.Drawing.Imaging.ImageAttributes();
                    attrs.SetColorKey(Color.White, Color.White);
                    realGraphics.DrawImage(isSelected ? e.cacheSelected : e.cache,
                        e.Rect, 0, 0, e.Rect.Width, e.Rect.Height, GraphicsUnit.Pixel,
                        attrs);
                     */
                }

                if (node.GetDisplayType() == NodeDisplayType.Triangle)
                {
                    int paddingvertical = PaddingVertical();
                    Rectangle lexRect = e.lexRect;
                    Rectangle labelRect = e.labelRect;
                    lexRect.Offset(e.Location);
                    labelRect.Offset(e.Location);
                    g.DrawPolygon(StandardLinePen(), new Point[] {
                    new Point(lexRect.Left,lexRect.Top-paddingvertical),
                    new Point(lexRect.Right,lexRect.Top-paddingvertical),
                    new Point(labelRect.Left+labelRect.Width/2,labelRect.Bottom+paddingvertical)
                });
                }
            }

            Decoration decoration = node.Decoration;
            if (decoration.mode != DecorationMode.None)
            {
                int pv = PaddingVertical() / 2 + (int)node.Decoration.penstyle.width;
                int ph = PaddingHorizontal() / 2 + (int)node.Decoration.penstyle.width;
                int pd = node.Decoration.padding;
                Rectangle decorationRect;
                if (decoration.mode == DecorationMode.Node)
                    decorationRect = new Rectangle(e.Rect.Left + ph, e.Rect.Top + pv, e.Rect.Width - ph * 2, e.Rect.Height - pv * 2);
                else
                { // subtree mode
                    decorationRect = OptGetSubTreeRectangle(e);
                    decorationRect.Inflate(pd, pd);
                }
                switch (decoration.shape)
                {
                    case DecorationShape.Ellipse:
                        using (Pen pen = decoration.penstyle.GetPen(GetZoomFactor()))
                            g.DrawEllipse(pen, decorationRect.Left, decorationRect.Top, decorationRect.Width, decorationRect.Height);
                        break;
                    case DecorationShape.Cross:
                        using (Pen pen = decoration.penstyle.GetPen(GetZoomFactor()))
                        {
                            g.DrawLine(pen, decorationRect.Left, decorationRect.Top, decorationRect.Left + decorationRect.Width, decorationRect.Height + decorationRect.Top);
                            g.DrawLine(pen, decorationRect.Left, decorationRect.Top + decorationRect.Height, decorationRect.Left + decorationRect.Width, decorationRect.Top);
                        }
                        break;
                    case DecorationShape.Rectangle:
                        using (Pen pen = decoration.penstyle.GetPen(GetZoomFactor()))
                            g.DrawRectangle(pen, decorationRect.Left, decorationRect.Top, decorationRect.Width, decorationRect.Height);
                        break;
                    default:
                        throw new Exception("unknown shape");
                }
            }

            /*in determining how to vertically space traces,
             we should perhaps use a fancier algorithm, so that their
             height is offset only if they would actually cross. An reasonable
             approximation of such a fancy algorithm might keep track of
             traceCount on a per-level basis, rather than a per-common-ancestor
             basis

             * This block, which draws the traces, shouldn't be here,
             * as traces shouldn't be members of elements
             */
            int traceCount = 0;
            foreach (ElemTrace elemtrace in e.Traces())
            {
                traceCount++;
                using (Pen pen = elemtrace.trace.penstyle.GetPen(GetZoomFactor()))
                {

                    Point[] points = elemtrace.GetPoints(e, TraceSpacingHorizontal(),
                        TraceSpacingVertical(), traceCount);
                    switch (elemtrace.trace.tracestyle)
                    {
                        case TraceStyle.Line:
                            g.DrawLines(pen, points);
                            break;
                        case TraceStyle.Curve:
                            g.DrawBezier(pen, points[0], points[1], points[points.Length - 2], points[points.Length - 1]);
                            break;
                        default:
                            throw new TreeException("Unknown trace style");
                    }
                }
            }
        }
예제 #2
0
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //Console.WriteLine(e.ClipRectangle);
            using (Graphics g = e.Graphics)
            {
                GraphicsPassThrough gpt = new GraphicsPassThrough(g);
                StdCalcTree(ClientSize);

                Point offset = new Point(Math.Max(0, -m_maximumExtents.Left), Math.Max(0, -m_maximumExtents.Top));

                if (offset.X > 0 || offset.Y > 0)
                {
                    Rectangle size = new Rectangle(Point.Empty, m_maximumExtents.Size);
                    StdCalcTree(ClientSize, offset);
                }
                AutoScrollMinSize = m_maximumExtents.Size;

                Point pt = AutoScrollPosition;
                gpt.TranslateTransform(pt.X, pt.Y);

                DoPaint(gpt);
                /*
                 * Alternatively, draw to back buffer:
                 * using (Bitmap bm = GetBitmap())
                 *   g.DrawImageUnscaled(bm, 0, 0);
                 */
            }
        }