Exemplo n.º 1
0
        public void Paint(Graphics g, Rectangle bounds)
        {
            // Lock the sheet and strokes
            using (Synchronizer.Lock(this.m_Sheet.SyncRoot)) {
                using (Synchronizer.Lock(this.m_Sheet.Ink.Strokes.SyncRoot)) {
                    if (this.m_Sheet.Ink.Strokes.Count <= 0)
                    {
                        return;
                    }

                    // Make a copy of the set of all strokes to be painted.
                    // The selected strokes will be removed from this and painted separately.
                    Strokes strokes   = this.m_Sheet.Ink.Strokes;
                    Strokes selection = this.m_Sheet.Selection;

                    if (selection != null)
                    {
                        strokes.Remove(selection);
                    }

                    // Create an image using temporary graphics and graphics buffer object
                    Bitmap imageForPrinting = new Bitmap(bounds.Width, bounds.Height);
                    using (Graphics graphicsImage = Graphics.FromImage(imageForPrinting))
                        using (DibGraphicsBuffer dib = new DibGraphicsBuffer()) {
                            // Create temporary screen Graphics
                            System.Windows.Forms.Form tempForm = new System.Windows.Forms.Form();
                            Graphics screenGraphics            = tempForm.CreateGraphics();
                            // Create temporary Graphics from the Device Independent Bitmap
                            using (Graphics graphicsTemp = dib.RequestBuffer(screenGraphics, bounds.Width, bounds.Height)) {
                                graphicsTemp.Clear(System.Drawing.Color.Transparent);

                                // Draw the unselected ink!
                                // (Ink is not a published property of the InkSheetModel, so no need to obtain a lock.)
                                this.m_Renderer.Draw(graphicsTemp, strokes);

                                if (selection != null)
                                {
                                    // Draw each stroke individually, adjusting its DrawingAttributes.
                                    // TODO: This is very inefficient compared to drawing them all as a group (make a selection of several hundred strokes to see -- a big slow-down).
                                    foreach (Stroke stroke in selection)
                                    {
                                        // It's possible to erase ink while it's selected,
                                        // either with the inverted end of the stylus or via the Undo service.
                                        // But even though the deleted ink won't be part of the main Ink.Strokes collection,
                                        // it won't have been removed from the selection Strokes collection.
                                        // TODO: Being able to delete strokes while they are selected might break more than this.
                                        //   Evaluate what needs to change in the eraser and undo service to make this less hacky.
                                        if (stroke.Deleted)
                                        {
                                            continue;
                                        }

                                        // First draw a highlighted background for all the strokes.
                                        DrawingAttributes atts = stroke.DrawingAttributes.Clone();
                                        float             width = atts.Width, height = atts.Height;
                                        atts.RasterOperation = RasterOperation.CopyPen;
                                        atts.Color           = SystemColors.Highlight;
                                        atts.Width          += SELECTED_BORDER_WIDTH__HIMETRIC;
                                        atts.Height         += SELECTED_BORDER_WIDTH__HIMETRIC;
                                        this.m_Renderer.Draw(graphicsTemp, stroke, atts);
                                    }

                                    foreach (Stroke stroke in selection)
                                    {
                                        if (stroke.Deleted)
                                        {
                                            continue;
                                        }

                                        // Second, draw the stroke itself, but with a contrastive color.
                                        DrawingAttributes atts = stroke.DrawingAttributes.Clone();
                                        atts.RasterOperation = RasterOperation.CopyPen;
                                        atts.Color           = SystemColors.HighlightText;
                                        this.m_Renderer.Draw(graphicsTemp, stroke, atts);
                                    }
                                }

                                // Use the buffer to paint onto the final image
                                dib.PaintBuffer(graphicsImage, 0, 0);

                                // Draw this image onto the printer graphics,
                                // adjusting for printer margins
                                g.DrawImage(imageForPrinting, bounds.Top, bounds.Left);
                            }
                        }
                }
            }
        }