public override void OnPaintWorkflow(PaintEventArgs e, ViewPortData viewPortData) { Graphics graphics = e.Graphics; Debug.Assert(graphics != null); Bitmap memoryBitmap = viewPortData.MemoryBitmap; Debug.Assert(memoryBitmap != null); //Get the drawing canvas AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; //We set the highest quality interpolation so that we do not loose the image quality GraphicsContainer graphicsState = graphics.BeginContainer(); //Fill the background using the workspace color so that we communicate the paging concept Rectangle workspaceRectangle = new Rectangle(Point.Empty, memoryBitmap.Size); graphics.FillRectangle(AmbientTheme.WorkspaceBackgroundBrush, workspaceRectangle); using (Font headerFooterFont = new Font(ambientTheme.Font.FontFamily, ambientTheme.Font.Size / this.scaling, ambientTheme.Font.Style)) { int currentPage = 0; Matrix emptyMatrix = new Matrix(); //Create the transformation matrix and calculate the physical viewport without translation and scaling //We need to get the physical view port due to the fact that there can be circustances when zoom percentage //is very high, logical view port can be empty in such cases Matrix coOrdTxMatrix = new Matrix(); coOrdTxMatrix.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); coOrdTxMatrix.Invert(); Point[] points = new Point[] { viewPortData.Translation, new Point(viewPortData.ViewPortSize) }; coOrdTxMatrix.TransformPoints(points); coOrdTxMatrix.Invert(); Rectangle physicalViewPort = new Rectangle(points[0], new Size(points[1])); //Create the data for rendering header/footer WorkflowPrintDocument.HeaderFooterData headerFooterData = new WorkflowPrintDocument.HeaderFooterData(); headerFooterData.HeaderFooterMargins = this.headerFooterMargins; headerFooterData.PrintTime = this.previewTime; headerFooterData.TotalPages = this.pageLayoutInfo.Count; headerFooterData.Scaling = this.scaling; headerFooterData.Font = headerFooterFont; WorkflowDesignerLoader serviceDesignerLoader = this.serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; headerFooterData.FileName = (serviceDesignerLoader != null) ? serviceDesignerLoader.FileName : String.Empty; //Create the viewport transformation matrix Matrix viewPortMatrix = new Matrix(); viewPortMatrix.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); viewPortMatrix.Translate(-viewPortData.Translation.X, -viewPortData.Translation.Y, MatrixOrder.Append); //We now have the viewport properly drawn, now we need to draw it on the actual graphics object //Now that we have the designer bitmap we start splicing it based on the pages //Note that this is quite expensive operation and hence one should try to use //The memory bitmap we have got is scaled appropriately foreach (PageLayoutData pageLayoutData in this.pageLayoutInfo) { currentPage += 1; //We do not draw the non intersecting pages, get the intersected viewport //We purposely use the physical viewport here because, there are cases in which the viewport //will not contain any logical bitmap areas in which case we atleast need to draw the pages properly if (!pageLayoutData.PageBounds.IntersectsWith(physicalViewPort) || pageLayoutData.PageBounds.Width <= 0 || pageLayoutData.PageBounds.Height <= 0) continue; //******START PAGE DRAWING, FIRST DRAW THE OUTLINE //Scale and translate so that we can draw the pages graphics.Transform = viewPortMatrix; graphics.FillRectangle(Brushes.White, pageLayoutData.PageBounds); ActivityDesignerPaint.DrawDropShadow(graphics, pageLayoutData.PageBounds, Color.Black, AmbientTheme.DropShadowWidth, LightSourcePosition.Left | LightSourcePosition.Top, 0.2f, false); //***START BITMAP SPLICING //Draw spliced bitmap for the page if we have any displayable area Rectangle intersectedViewPort = pageLayoutData.LogicalPageBounds; intersectedViewPort.Intersect(viewPortData.LogicalViewPort); if (!intersectedViewPort.IsEmpty) { //Make sure that we now clear the translation factor graphics.Transform = emptyMatrix; //Paint bitmap on the pages //Now that the page rectangle is actually drawn, we will scale down the Location of page rectangle //so that we can draw the viewport bitmap part on it Point bitmapDrawingPoint = Point.Empty; bitmapDrawingPoint.X = pageLayoutData.ViewablePageBounds.X + Math.Abs(pageLayoutData.LogicalPageBounds.X - intersectedViewPort.X); bitmapDrawingPoint.Y = pageLayoutData.ViewablePageBounds.Y + Math.Abs(pageLayoutData.LogicalPageBounds.Y - intersectedViewPort.Y); points = new Point[] { bitmapDrawingPoint }; coOrdTxMatrix.TransformPoints(points); bitmapDrawingPoint = new Point(points[0].X - viewPortData.Translation.X, points[0].Y - viewPortData.Translation.Y); //This is the area of the viewport bitmap we need to copy on the page Rectangle viewPortBitmapArea = Rectangle.Empty; viewPortBitmapArea.X = intersectedViewPort.X - viewPortData.LogicalViewPort.X; viewPortBitmapArea.Y = intersectedViewPort.Y - viewPortData.LogicalViewPort.Y; viewPortBitmapArea.Width = intersectedViewPort.Width; viewPortBitmapArea.Height = intersectedViewPort.Height; //This rectangle is in translated logical units, we need to scale it down points = new Point[] { viewPortBitmapArea.Location, new Point(viewPortBitmapArea.Size) }; coOrdTxMatrix.TransformPoints(points); viewPortBitmapArea.Location = points[0]; viewPortBitmapArea.Size = new Size(points[1]); ActivityDesignerPaint.DrawImage(graphics, memoryBitmap, new Rectangle(bitmapDrawingPoint, viewPortBitmapArea.Size), viewPortBitmapArea, DesignerContentAlignment.Fill, 1.0f, WorkflowTheme.CurrentTheme.AmbientTheme.DrawGrayscale); } //***END BITMAP SPLICING //Draw the page outline graphics.Transform = viewPortMatrix; graphics.DrawRectangle(Pens.Black, pageLayoutData.PageBounds); //Draw the printable page outline graphics.DrawRectangle(ambientTheme.ForegroundPen, pageLayoutData.ViewablePageBounds.Left - 3, pageLayoutData.ViewablePageBounds.Top - 3, pageLayoutData.ViewablePageBounds.Width + 6, pageLayoutData.ViewablePageBounds.Height + 6); //Draw the header and footer after we draw the actual page headerFooterData.PageBounds = pageLayoutData.PageBounds; headerFooterData.PageBoundsWithoutMargin = pageLayoutData.ViewablePageBounds; headerFooterData.CurrentPage = currentPage; //Draw the header if (this.printDocument.PageSetupData.HeaderTemplate.Length > 0) this.printDocument.PrintHeaderFooter(graphics, true, headerFooterData); //Draw footer if (this.printDocument.PageSetupData.FooterTemplate.Length > 0) this.printDocument.PrintHeaderFooter(graphics, false, headerFooterData); //***END DRAWING HEADER FOOTER } graphics.EndContainer(graphicsState); } }
public override void OnPaintWorkflow(PaintEventArgs e, ViewPortData viewPortData) { Graphics graphics = e.Graphics; Bitmap memoryBitmap = viewPortData.MemoryBitmap; AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; GraphicsContainer container = graphics.BeginContainer(); Rectangle rect = new Rectangle(Point.Empty, memoryBitmap.Size); graphics.FillRectangle(AmbientTheme.WorkspaceBackgroundBrush, rect); using (Font font = new Font(ambientTheme.Font.FontFamily, ambientTheme.Font.Size / this.scaling, ambientTheme.Font.Style)) { int num = 0; Matrix matrix = new Matrix(); Matrix matrix2 = new Matrix(); matrix2.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); matrix2.Invert(); Point[] pts = new Point[] { viewPortData.Translation, new Point(viewPortData.ViewPortSize) }; matrix2.TransformPoints(pts); matrix2.Invert(); Rectangle rectangle2 = new Rectangle(pts[0], new Size(pts[1])); WorkflowPrintDocument.HeaderFooterData headerFooterPrintData = new WorkflowPrintDocument.HeaderFooterData { HeaderFooterMargins = this.headerFooterMargins, PrintTime = this.previewTime, TotalPages = this.pageLayoutInfo.Count, Scaling = this.scaling, Font = font }; WorkflowDesignerLoader service = base.serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; headerFooterPrintData.FileName = (service != null) ? service.FileName : string.Empty; Matrix matrix3 = new Matrix(); matrix3.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); matrix3.Translate((float) -viewPortData.Translation.X, (float) -viewPortData.Translation.Y, MatrixOrder.Append); foreach (PageLayoutData data2 in this.pageLayoutInfo) { num++; if ((data2.PageBounds.IntersectsWith(rectangle2) && (data2.PageBounds.Width > 0)) && (data2.PageBounds.Height > 0)) { graphics.Transform = matrix3; graphics.FillRectangle(Brushes.White, data2.PageBounds); ActivityDesignerPaint.DrawDropShadow(graphics, data2.PageBounds, Color.Black, 4, LightSourcePosition.Top | LightSourcePosition.Left, 0.2f, false); Rectangle logicalPageBounds = data2.LogicalPageBounds; logicalPageBounds.Intersect(viewPortData.LogicalViewPort); if (!logicalPageBounds.IsEmpty) { graphics.Transform = matrix; Point empty = Point.Empty; empty.X = data2.ViewablePageBounds.X + Math.Abs((int) (data2.LogicalPageBounds.X - logicalPageBounds.X)); empty.Y = data2.ViewablePageBounds.Y + Math.Abs((int) (data2.LogicalPageBounds.Y - logicalPageBounds.Y)); pts = new Point[] { empty }; matrix2.TransformPoints(pts); empty = new Point(pts[0].X - viewPortData.Translation.X, pts[0].Y - viewPortData.Translation.Y); Rectangle source = Rectangle.Empty; source.X = logicalPageBounds.X - viewPortData.LogicalViewPort.X; source.Y = logicalPageBounds.Y - viewPortData.LogicalViewPort.Y; source.Width = logicalPageBounds.Width; source.Height = logicalPageBounds.Height; pts = new Point[] { source.Location, new Point(source.Size) }; matrix2.TransformPoints(pts); source.Location = pts[0]; source.Size = new Size(pts[1]); ActivityDesignerPaint.DrawImage(graphics, memoryBitmap, new Rectangle(empty, source.Size), source, DesignerContentAlignment.Fill, 1f, WorkflowTheme.CurrentTheme.AmbientTheme.DrawGrayscale); } graphics.Transform = matrix3; graphics.DrawRectangle(Pens.Black, data2.PageBounds); graphics.DrawRectangle(ambientTheme.ForegroundPen, (int) (data2.ViewablePageBounds.Left - 3), (int) (data2.ViewablePageBounds.Top - 3), (int) (data2.ViewablePageBounds.Width + 6), (int) (data2.ViewablePageBounds.Height + 6)); headerFooterPrintData.PageBounds = data2.PageBounds; headerFooterPrintData.PageBoundsWithoutMargin = data2.ViewablePageBounds; headerFooterPrintData.CurrentPage = num; if (this.printDocument.PageSetupData.HeaderTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, true, headerFooterPrintData); } if (this.printDocument.PageSetupData.FooterTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, false, headerFooterPrintData); } } } graphics.EndContainer(container); } }
public override void OnPaintWorkflow(PaintEventArgs e, ViewPortData viewPortData) { Graphics graphics = e.Graphics; Debug.Assert(graphics != null); Bitmap memoryBitmap = viewPortData.MemoryBitmap; Debug.Assert(memoryBitmap != null); //Get the drawing canvas AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; //We set the highest quality interpolation so that we do not loose the image quality GraphicsContainer graphicsState = graphics.BeginContainer(); //Fill the background using the workspace color so that we communicate the paging concept Rectangle workspaceRectangle = new Rectangle(Point.Empty, memoryBitmap.Size); graphics.FillRectangle(AmbientTheme.WorkspaceBackgroundBrush, workspaceRectangle); using (Font headerFooterFont = new Font(ambientTheme.Font.FontFamily, ambientTheme.Font.Size / this.scaling, ambientTheme.Font.Style)) { int currentPage = 0; Matrix emptyMatrix = new Matrix(); //Create the transformation matrix and calculate the physical viewport without translation and scaling //We need to get the physical view port due to the fact that there can be circustances when zoom percentage //is very high, logical view port can be empty in such cases Matrix coOrdTxMatrix = new Matrix(); coOrdTxMatrix.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); coOrdTxMatrix.Invert(); Point[] points = new Point[] { viewPortData.Translation, new Point(viewPortData.ViewPortSize) }; coOrdTxMatrix.TransformPoints(points); coOrdTxMatrix.Invert(); Rectangle physicalViewPort = new Rectangle(points[0], new Size(points[1])); //Create the data for rendering header/footer WorkflowPrintDocument.HeaderFooterData headerFooterData = new WorkflowPrintDocument.HeaderFooterData(); headerFooterData.HeaderFooterMargins = this.headerFooterMargins; headerFooterData.PrintTime = this.previewTime; headerFooterData.TotalPages = this.pageLayoutInfo.Count; headerFooterData.Scaling = this.scaling; headerFooterData.Font = headerFooterFont; WorkflowDesignerLoader serviceDesignerLoader = this.serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; headerFooterData.FileName = (serviceDesignerLoader != null) ? serviceDesignerLoader.FileName : String.Empty; //Create the viewport transformation matrix Matrix viewPortMatrix = new Matrix(); viewPortMatrix.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); viewPortMatrix.Translate(-viewPortData.Translation.X, -viewPortData.Translation.Y, MatrixOrder.Append); //We now have the viewport properly drawn, now we need to draw it on the actual graphics object //Now that we have the designer bitmap we start splicing it based on the pages //Note that this is quite expensive operation and hence one should try to use //The memory bitmap we have got is scaled appropriately foreach (PageLayoutData pageLayoutData in this.pageLayoutInfo) { currentPage += 1; //We do not draw the non intersecting pages, get the intersected viewport //We purposely use the physical viewport here because, there are cases in which the viewport //will not contain any logical bitmap areas in which case we atleast need to draw the pages properly if (!pageLayoutData.PageBounds.IntersectsWith(physicalViewPort) || pageLayoutData.PageBounds.Width <= 0 || pageLayoutData.PageBounds.Height <= 0) { continue; } //******START PAGE DRAWING, FIRST DRAW THE OUTLINE //Scale and translate so that we can draw the pages graphics.Transform = viewPortMatrix; graphics.FillRectangle(Brushes.White, pageLayoutData.PageBounds); ActivityDesignerPaint.DrawDropShadow(graphics, pageLayoutData.PageBounds, Color.Black, AmbientTheme.DropShadowWidth, LightSourcePosition.Left | LightSourcePosition.Top, 0.2f, false); //***START BITMAP SPLICING //Draw spliced bitmap for the page if we have any displayable area Rectangle intersectedViewPort = pageLayoutData.LogicalPageBounds; intersectedViewPort.Intersect(viewPortData.LogicalViewPort); if (!intersectedViewPort.IsEmpty) { //Make sure that we now clear the translation factor graphics.Transform = emptyMatrix; //Paint bitmap on the pages //Now that the page rectangle is actually drawn, we will scale down the Location of page rectangle //so that we can draw the viewport bitmap part on it Point bitmapDrawingPoint = Point.Empty; bitmapDrawingPoint.X = pageLayoutData.ViewablePageBounds.X + Math.Abs(pageLayoutData.LogicalPageBounds.X - intersectedViewPort.X); bitmapDrawingPoint.Y = pageLayoutData.ViewablePageBounds.Y + Math.Abs(pageLayoutData.LogicalPageBounds.Y - intersectedViewPort.Y); points = new Point[] { bitmapDrawingPoint }; coOrdTxMatrix.TransformPoints(points); bitmapDrawingPoint = new Point(points[0].X - viewPortData.Translation.X, points[0].Y - viewPortData.Translation.Y); //This is the area of the viewport bitmap we need to copy on the page Rectangle viewPortBitmapArea = Rectangle.Empty; viewPortBitmapArea.X = intersectedViewPort.X - viewPortData.LogicalViewPort.X; viewPortBitmapArea.Y = intersectedViewPort.Y - viewPortData.LogicalViewPort.Y; viewPortBitmapArea.Width = intersectedViewPort.Width; viewPortBitmapArea.Height = intersectedViewPort.Height; //This rectangle is in translated logical units, we need to scale it down points = new Point[] { viewPortBitmapArea.Location, new Point(viewPortBitmapArea.Size) }; coOrdTxMatrix.TransformPoints(points); viewPortBitmapArea.Location = points[0]; viewPortBitmapArea.Size = new Size(points[1]); ActivityDesignerPaint.DrawImage(graphics, memoryBitmap, new Rectangle(bitmapDrawingPoint, viewPortBitmapArea.Size), viewPortBitmapArea, DesignerContentAlignment.Fill, 1.0f, WorkflowTheme.CurrentTheme.AmbientTheme.DrawGrayscale); } //***END BITMAP SPLICING //Draw the page outline graphics.Transform = viewPortMatrix; graphics.DrawRectangle(Pens.Black, pageLayoutData.PageBounds); //Draw the printable page outline graphics.DrawRectangle(ambientTheme.ForegroundPen, pageLayoutData.ViewablePageBounds.Left - 3, pageLayoutData.ViewablePageBounds.Top - 3, pageLayoutData.ViewablePageBounds.Width + 6, pageLayoutData.ViewablePageBounds.Height + 6); //Draw the header and footer after we draw the actual page headerFooterData.PageBounds = pageLayoutData.PageBounds; headerFooterData.PageBoundsWithoutMargin = pageLayoutData.ViewablePageBounds; headerFooterData.CurrentPage = currentPage; //Draw the header if (this.printDocument.PageSetupData.HeaderTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, true, headerFooterData); } //Draw footer if (this.printDocument.PageSetupData.FooterTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, false, headerFooterData); } //***END DRAWING HEADER FOOTER } graphics.EndContainer(graphicsState); } }
public override void OnPaintWorkflow(PaintEventArgs e, ViewPortData viewPortData) { Graphics graphics = e.Graphics; Bitmap memoryBitmap = viewPortData.MemoryBitmap; AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; GraphicsContainer container = graphics.BeginContainer(); Rectangle rect = new Rectangle(Point.Empty, memoryBitmap.Size); graphics.FillRectangle(AmbientTheme.WorkspaceBackgroundBrush, rect); using (Font font = new Font(ambientTheme.Font.FontFamily, ambientTheme.Font.Size / this.scaling, ambientTheme.Font.Style)) { int num = 0; Matrix matrix = new Matrix(); Matrix matrix2 = new Matrix(); matrix2.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); matrix2.Invert(); Point[] pts = new Point[] { viewPortData.Translation, new Point(viewPortData.ViewPortSize) }; matrix2.TransformPoints(pts); matrix2.Invert(); Rectangle rectangle2 = new Rectangle(pts[0], new Size(pts[1])); WorkflowPrintDocument.HeaderFooterData headerFooterPrintData = new WorkflowPrintDocument.HeaderFooterData { HeaderFooterMargins = this.headerFooterMargins, PrintTime = this.previewTime, TotalPages = this.pageLayoutInfo.Count, Scaling = this.scaling, Font = font }; WorkflowDesignerLoader service = base.serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; headerFooterPrintData.FileName = (service != null) ? service.FileName : string.Empty; Matrix matrix3 = new Matrix(); matrix3.Scale(viewPortData.Scaling.Width, viewPortData.Scaling.Height, MatrixOrder.Prepend); matrix3.Translate((float)-viewPortData.Translation.X, (float)-viewPortData.Translation.Y, MatrixOrder.Append); foreach (PageLayoutData data2 in this.pageLayoutInfo) { num++; if ((data2.PageBounds.IntersectsWith(rectangle2) && (data2.PageBounds.Width > 0)) && (data2.PageBounds.Height > 0)) { graphics.Transform = matrix3; graphics.FillRectangle(Brushes.White, data2.PageBounds); ActivityDesignerPaint.DrawDropShadow(graphics, data2.PageBounds, Color.Black, 4, LightSourcePosition.Top | LightSourcePosition.Left, 0.2f, false); Rectangle logicalPageBounds = data2.LogicalPageBounds; logicalPageBounds.Intersect(viewPortData.LogicalViewPort); if (!logicalPageBounds.IsEmpty) { graphics.Transform = matrix; Point empty = Point.Empty; empty.X = data2.ViewablePageBounds.X + Math.Abs((int)(data2.LogicalPageBounds.X - logicalPageBounds.X)); empty.Y = data2.ViewablePageBounds.Y + Math.Abs((int)(data2.LogicalPageBounds.Y - logicalPageBounds.Y)); pts = new Point[] { empty }; matrix2.TransformPoints(pts); empty = new Point(pts[0].X - viewPortData.Translation.X, pts[0].Y - viewPortData.Translation.Y); Rectangle source = Rectangle.Empty; source.X = logicalPageBounds.X - viewPortData.LogicalViewPort.X; source.Y = logicalPageBounds.Y - viewPortData.LogicalViewPort.Y; source.Width = logicalPageBounds.Width; source.Height = logicalPageBounds.Height; pts = new Point[] { source.Location, new Point(source.Size) }; matrix2.TransformPoints(pts); source.Location = pts[0]; source.Size = new Size(pts[1]); ActivityDesignerPaint.DrawImage(graphics, memoryBitmap, new Rectangle(empty, source.Size), source, DesignerContentAlignment.Fill, 1f, WorkflowTheme.CurrentTheme.AmbientTheme.DrawGrayscale); } graphics.Transform = matrix3; graphics.DrawRectangle(Pens.Black, data2.PageBounds); graphics.DrawRectangle(ambientTheme.ForegroundPen, (int)(data2.ViewablePageBounds.Left - 3), (int)(data2.ViewablePageBounds.Top - 3), (int)(data2.ViewablePageBounds.Width + 6), (int)(data2.ViewablePageBounds.Height + 6)); headerFooterPrintData.PageBounds = data2.PageBounds; headerFooterPrintData.PageBoundsWithoutMargin = data2.ViewablePageBounds; headerFooterPrintData.CurrentPage = num; if (this.printDocument.PageSetupData.HeaderTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, true, headerFooterPrintData); } if (this.printDocument.PageSetupData.FooterTemplate.Length > 0) { this.printDocument.PrintHeaderFooter(graphics, false, headerFooterPrintData); } } } graphics.EndContainer(container); } }