// NOTE: Eventually this code should be converted to use SlideRenderer instead of each SheetRenderer. There were some issues with doing // this initially so for the time being we will keep it like this. public static Bitmap DrawSlide(TableOfContentsModel.Entry currentEntry, BackgroundTemplate template, System.Drawing.Color background, SheetDisposition dispositions, int width, int height, float scale ) { // Save the old state System.Drawing.Drawing2D.GraphicsState oldState; using (Synchronizer.Lock(currentEntry.Slide.SyncRoot)) { Rectangle rect; int boundsWidth = currentEntry.Slide.Bounds.Width; int boundsHeight = currentEntry.Slide.Bounds.Height; int exportWidth = width; int exportHeight = height; if (width > 0 && height > 0) { // Do Nothing } else if (width > 0) { exportHeight = (int)Math.Round( ( (float)width / (float)boundsWidth ) * (float)boundsHeight ); } else if (height > 0) { exportWidth = (int)Math.Round( ( (float)height / (float)boundsHeight ) * (float)boundsWidth ); } else { exportWidth = boundsWidth; exportHeight = boundsHeight; } // Scale the size exportWidth = (int)Math.Round( exportWidth * scale ); exportHeight = (int)Math.Round( exportHeight * scale ); rect = new Rectangle(0, 0, exportWidth, exportHeight); //Note: Uses DibGraphicsBuffer from TPC SDK to do antialiasing //See: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dntablet/html/tbconprintingink.asp /// create the bitmap we're exporting to Bitmap toExport = new Bitmap(rect.Width, rect.Height); /// create what we will be drawing on to the export Graphics toSave = Graphics.FromImage(toExport); /// draw the slide data on a temporary graphics object in a temporary form System.Windows.Forms.Form tempForm = new System.Windows.Forms.Form(); Graphics screenGraphics = tempForm.CreateGraphics(); DibGraphicsBuffer dib = new DibGraphicsBuffer(); Graphics tempGraphics = dib.RequestBuffer(screenGraphics, rect.Width, rect.Height); //Add the background color //First see if there is a Slide BG, if not, try the Deck. Otherwise, use transparent. tempGraphics.Clear(background); //Add the background template if (template != null) { using (BackgroundTemplateRenderer bkgRender = new BackgroundTemplateRenderer(template)) { bkgRender.DrawAll(tempGraphics, rect); } } //Get the Slide content and draw it oldState = tempGraphics.Save(); Model.Presentation.SlideModel.SheetCollection sheets = currentEntry.Slide.ContentSheets; for (int i = 0; i < sheets.Count; i++) { Model.Viewer.SlideDisplayModel display = new Model.Viewer.SlideDisplayModel(tempGraphics, null); Rectangle slide = rect; float zoom = 1f; if (currentEntry.Slide != null) { slide = currentEntry.Slide.Bounds; zoom = currentEntry.Slide.Zoom; } System.Drawing.Drawing2D.Matrix pixel, ink; display.FitSlideToBounds(System.Windows.Forms.DockStyle.Fill, rect, zoom, ref slide, out pixel, out ink); using (Synchronizer.Lock(display.SyncRoot)) { display.SheetDisposition = dispositions; display.Bounds = slide; display.PixelTransform = pixel; display.InkTransform = ink; } Viewer.Slides.SheetRenderer r = Viewer.Slides.SheetRenderer.ForStaticSheet(display, sheets[i]); if ((r.Sheet.Disposition & dispositions) != 0) r.Paint(new System.Windows.Forms.PaintEventArgs(tempGraphics, rect)); r.Dispose(); } //Restore the Old State tempGraphics.Restore(oldState); oldState = tempGraphics.Save(); //Get the Annotation content and draw it sheets = currentEntry.Slide.AnnotationSheets; for (int i = 0; i < sheets.Count; i++) { Model.Viewer.SlideDisplayModel display = new Model.Viewer.SlideDisplayModel(tempGraphics, null); Rectangle slide = rect; float zoom = 1f; if (currentEntry.Slide != null) { slide = currentEntry.Slide.Bounds; zoom = currentEntry.Slide.Zoom; } System.Drawing.Drawing2D.Matrix pixel, ink; display.FitSlideToBounds(System.Windows.Forms.DockStyle.Fill, rect, zoom, ref slide, out pixel, out ink); using (Synchronizer.Lock(display.SyncRoot)) { display.SheetDisposition = dispositions; display.Bounds = slide; display.PixelTransform = pixel; display.InkTransform = ink; } Viewer.Slides.SheetRenderer r = Viewer.Slides.SheetRenderer.ForStaticSheet(display, sheets[i]); if ((r.Sheet.Disposition & dispositions) != 0) r.Paint(new System.Windows.Forms.PaintEventArgs(tempGraphics, rect)); r.Dispose(); } //Restore the Old State tempGraphics.Restore(oldState); //Export the image //Merge the graphics dib.PaintBuffer(toSave, 0, 0); //Dispose all the graphics toSave.Dispose(); screenGraphics.Dispose(); tempGraphics.Dispose(); return toExport; } }
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 ); } } } } }
private void DrawSlide2( DeckTraversalModel traversal, int index, System.Drawing.Rectangle displayBounds, System.Drawing.Graphics g ) { float width_scale = g.DpiX / 100f; float height_scale = g.DpiY / 100f; Rectangle bounds = new Rectangle( 0, 0, (int)(displayBounds.Width * 3f), (int)(displayBounds.Height * 3f) ); // 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, imageForPrinting.Width, imageForPrinting.Height ) ) { // Save the old state System.Drawing.Drawing2D.GraphicsState oldState; using( Synchronizer.Lock( traversal.SyncRoot ) ) { using( Synchronizer.Lock( traversal.Deck.SyncRoot ) ) { using( Synchronizer.Lock( traversal.Deck.TableOfContents.SyncRoot ) ) { TableOfContentsModel.Entry entry = traversal.Deck.TableOfContents.Entries[index]; using( Synchronizer.Lock( entry.Slide.SyncRoot ) ) { //Draw the background color //First see if there is a Slide BG, if not, try the Deck. Otherwise, use transparent. if( entry.Slide.BackgroundColor != Color.Empty ) { graphicsTemp.Clear( entry.Slide.BackgroundColor ); } else if( traversal.Deck.DeckBackgroundColor != Color.Empty ) { graphicsTemp.Clear( traversal.Deck.DeckBackgroundColor ); } else { graphicsTemp.Clear( Color.Transparent ); } //Get the Slide content and draw it oldState = graphicsTemp.Save(); Model.Presentation.SlideModel.SheetCollection sheets = entry.Slide.ContentSheets; for( int i = 0; i < sheets.Count; i++ ) { SlideDisplayModel display = new SlideDisplayModel( graphicsTemp, null ); Rectangle rect = new Rectangle( 0, 0, bounds.Width, bounds.Height ); Rectangle slide = new Rectangle( rect.X, rect.Y, rect.Width, rect.Height ); float zoom = 1f; if( entry.Slide != null ) { slide = entry.Slide.Bounds; zoom = entry.Slide.Zoom; } System.Drawing.Drawing2D.Matrix pixel, ink; display.FitSlideToBounds( System.Windows.Forms.DockStyle.Fill, rect, zoom, ref slide, out pixel, out ink ); using( Synchronizer.Lock( display.SyncRoot ) ) { display.Bounds = slide; display.PixelTransform = pixel; display.InkTransform = ink; } Viewer.Slides.SheetRenderer r = Viewer.Slides.SheetRenderer.ForStaticSheet( display, sheets[i] ); r.Paint( new System.Windows.Forms.PaintEventArgs( graphicsTemp, bounds ) ); r.Dispose(); } } } } } //Restore the Old State graphicsTemp.Restore( oldState ); // 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, displayBounds ); //Cleanup graphicsTemp.Dispose(); screenGraphics.Dispose(); tempForm.Dispose(); dib.Dispose(); graphicsImage.Dispose(); imageForPrinting.Dispose(); } } } }