public void Execute(IPCBIWindow parent) { IStep step = parent.GetCurrentStep(); IFilter filter = new IFilter(parent); IODBLayer layerPolygons = filter.CreateEmptyODBLayer("polygons_n", step.Name); bool polyStart = true; List <IODBObject> listOfSelection = step.GetSelectedElements(); PCBI.MathUtils.IPolyClass poly = new PCBI.MathUtils.IPolyClass(); foreach (IODBObject obj in listOfSelection) { IObjectSpecificsD os = obj.GetSpecificsD(); if (os.GetType() == typeof(IArcSpecificsD)) { IArcSpecificsD aEdge = (IArcSpecificsD)os; if (polyStart) { polyStart = false; } poly.AddEdge(aEdge.Start, aEdge.End, aEdge.Center, aEdge.ClockWise); } else if (os.GetType() == typeof(ILineSpecificsD)) { ILineSpecificsD aEdge = (ILineSpecificsD)os; if (polyStart) { polyStart = false; } poly.AddEdge(aEdge.Start, aEdge.End); } } if (poly.GetSubPolygons().Count > 0) { foreach (PCBI.MathUtils.IPolyClass polyC in poly.GetSubPolygons()) { if (polyC.GetBounds().Width > 0.001 && polyC.GetBounds().Height > 0.001) { IODBObject surfaceFromPoly = polyC.GetSurfaceFromPolygon(layerPolygons); } } layerPolygons.EnableLayer(true); } else { IODBObject suf = poly.GetSurfaceFromPolygon(layerPolygons); layerPolygons.EnableLayer(true); } parent.UpdateView(); IMatrix matrix = parent.GetMatrix(); matrix.UpdateDataAndList(); }
private static void MakeDrillCutOutOnCopperLayers(IPCBIWindow Parent, IMatrix matrix, IStep step) { IFilter filter = new IFilter(Parent); int counterDielectirc = 1; foreach (string layerName in matrix.GetAllDrillLayerNames()) { ILayer drill_layer = step.GetLayer(layerName); bool lastWasSignal = false; foreach (string sigLayer in matrix.GetAllLayerWithThisDrills(layerName)) { var type = matrix.GetMatrixLayerType(sigLayer); if (type != MatrixLayerType.Dielectric && !matrix.IsSignalLayer(sigLayer)) //only dielectric und signals { continue; } if ((type == MatrixLayerType.Power_ground || type == MatrixLayerType.Signal)) { if (lastWasSignal) { //if last and current one are signals -> we need a dielectric between both IODBLayer dielectric = filter.CreateEmptyODBLayer("dielectric_" + counterDielectirc, step.Name); counterDielectirc++; if (dielectric != null) { AddDrillObjects(filter, drill_layer, MatrixLayerType.Dielectric, dielectric); matrix.SetMatrixLayerIndex(dielectric.GetLayerName(), matrix.GetRawIndexByName(sigLayer)); matrix.SetMatrixLayerParameter(dielectric.GetLayerName(), MatrixLayerContext.Board, MatrixLayerPolarity.Negative, MatrixLayerType.Dielectric, -1, -1); matrix.SetLayerHeight(dielectric.GetLayerName(), 5); //value in mils matrix.UpdateDataAndList(); //update list for correct order } else { Debug.WriteLine("error, can't create dielectric..."); } } lastWasSignal = true; } else { lastWasSignal = false; } IODBLayer odb_sig_layer = (IODBLayer)step.GetLayer(sigLayer); if (drill_layer.GetType() == typeof(IODBLayer)) { AddDrillObjects(filter, drill_layer, type, odb_sig_layer); drill_layer.EnableLayer(false); odb_sig_layer.EnableLayer(true); } } } matrix.UpdateDataAndList(); Parent.UpdateControlsAndResetView(); }
public void Execute(IPCBIWindow parent) { IStep step = parent.GetCurrentStep(); IMatrix matrix = parent.GetMatrix(); if (matrix == null || step == null) { return; //if there is no data loaded -> return } IODBLayer topLayer = step.GetOutsideODBLayer(true); if (topLayer != null) { MarkAllSMDPadsOnLayer(topLayer, matrix.GetAllDrillLayersForThisLayer(topLayer.LayerName), step); topLayer.EnableLayer(true); //to see the result for top side immidiatly, it will be enabled } IODBLayer botLayer = step.GetOutsideODBLayer(false); if (botLayer != null) { MarkAllSMDPadsOnLayer(botLayer, matrix.GetAllDrillLayersForThisLayer(botLayer.LayerName), step); } parent.UpdateView(); //redraw to show marked smd pads }
private void ResultDLG_ItemSelectionChanged1(ListView.SelectedListViewItemCollection Selection) { IStep step = parent.GetCurrentStep(); if (step != null) { foreach (ListViewItem lvi in Selection) { if (step != null) { step.ClearSelection(); ((ICMPObject)lvi.Tag).Select(true); step.TurnOffAllLayer(); IODBLayer layer = step.GetOutsideODBLayer(((ICMPObject)lvi.Tag).PlacedTop); if (layer != null) { layer.EnableLayer(true); } parent.UpdateSelection(); PCBI.MathUtils.RectangleD zoomRect = ((ICMPObject)lvi.Tag).GetBoundsD(); if (zoomRect == PCBI.MathUtils.RectangleD.Empty) { parent.ZoomToSelection(); } else { zoomRect.Inflate(zoomRect.Width * 0.5, zoomRect.Height * 0.5); parent.ZoomRect(zoomRect); } } else { ((ICMPObject)lvi.Tag).Select(true); parent.UpdateSelection(); parent.UpdateView(); } } } }
public void Execute(IPCBIWindow parent) { IFilter filter = new IFilter(parent); IStep curStep = parent.GetCurrentStep(); if (curStep == null) { MessageBox.Show("No Job loaded, please load a job before start this script!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } IODBLayer newLayer = filter.CreateEmptyODBLayer("help_layer", curStep.Name); newLayer.EnableLayer(true); IMatrix matrix = parent.GetMatrix(); matrix.UpdateDataAndList(); parent.UpdateView(); }
private void CreateNewLayer(IPCBIWindow parent, string newlayername) { IFilter filter = new IFilter(parent); IStep curStep = parent.GetCurrentStep(); if (curStep == null) { MessageBox.Show("No Job loaded, please load a job before start this script!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } IODBLayer newLayer = filter.CreateEmptyODBLayer(newlayername, curStep.Name); newLayer.EnableLayer(true); IMatrix matrix = parent.GetMatrix(); matrix.SetMatrixLayerContext(newlayername, MatrixLayerContext.Board); matrix.SetMatrixLayerType(newlayername, MatrixLayerType.Signal); matrix.UpdateDataAndList(); parent.UpdateView(); }
private void CalculateCopperFinish() { IFilter filter = new IFilter(Parent); IStep curStep = Parent.GetCurrentStep(); if (curStep == null) { MessageBox.Show("No Job loaded, please load a job before start this script!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } IODBLayer fiducialLayer = filter.CreateEmptyODBLayer("copper", curStep.Name); if (fiducialLayer == null) { MessageBox.Show("Can't create new layer!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } IMatrix matrix = Parent.GetMatrix(); string topLayerName = matrix.GetTopSignalLayer(); string topMaskName = matrix.GetNameByRowIndex(matrix.GetRawIndexByName(topLayerName) - 1); string botLayerName = matrix.GetBotSignalLayer(); string botMaskName = matrix.GetNameByRowIndex(matrix.GetRawIndexByName(botLayerName) + 1); IODBLayer topLayer = (IODBLayer)curStep.GetLayer(topLayerName); IODBLayer topMaskLayer = (IODBLayer)curStep.GetLayer(topMaskName); IODBLayer botLayer = (IODBLayer)curStep.GetLayer(botLayerName); IODBLayer botMaskLayer = (IODBLayer)curStep.GetLayer(botMaskName); //topLayer.PolygonizeLayer(); //botLayer.PolygonizeLayer(); matrix.MakeLayerPositive(topMaskName); matrix.MakeLayerPositive(botMaskName); Parent.UpdateControlsAndResetView(); MakeObjectsNegative(topMaskLayer); MakeObjectsNegative(botMaskLayer); Parent.UIAction.Execute(ID_ActionItem.ID_CLEAR_SELECTION); SelectAllObjectsOnLayer(topMaskLayer); Parent.UIAction.Execute(ID_ActionItem.ID_COPY_SELECTED_ODBOBJECTS); topLayer.EnableLayer(true); Parent.UIAction.Execute(ID_ActionItem.ID_PASTE_COPIED_ITEMS); Parent.UIAction.Execute(ID_ActionItem.ID_CLEAR_SELECTION); SelectAllObjectsOnLayer(botMaskLayer); Parent.UIAction.Execute(ID_ActionItem.ID_COPY_SELECTED_ODBOBJECTS); botLayer.EnableLayer(true); Parent.UIAction.Execute(ID_ActionItem.ID_PASTE_COPIED_ITEMS); Parent.UIAction.Execute(ID_ActionItem.ID_CLEAR_SELECTION); Parent.UIAction.Execute(ID_ActionItem.ID_ALL_LAYER_OFF); topLayer.PolygonizeLayer(); botLayer.PolygonizeLayer(); Parent.UpdateControlsAndResetView(); Parent.UIAction.Execute(ID_ActionItem.ID_CALCULATE_AREA); }
private void CreateNewDrillODBLayer(PCBI.Automation.IFilter filter, string newLayerName, IPCBIWindow parent, List <IODBObject> currIODBObjectList, bool activateLayer) { if (currIODBObjectList.Count == 0) { return; } IODBLayer layer = filter.CreateEmptyODBLayer(newLayerName, parent.GetCurrentStep().Name); Dictionary <string, int> shapeList = new Dictionary <string, int>(); foreach (IODBObject obj in currIODBObjectList) { if (obj.Type == IObjectType.Pad) { IPadSpecificsD specPad = (IPadSpecificsD)obj.GetSpecificsD(); if (!shapeList.ContainsKey(specPad.ODBSymbol_String)) { int newShapeIndex = IFilter.AddToolFromODBString(layer, specPad.ODBSymbol_String, shapeList.Count); shapeList.Add(specPad.ODBSymbol_String, newShapeIndex); } IODBObject pad = filter.CreatePad(layer); IPadSpecificsD padInfosD = (IPadSpecificsD)obj.GetSpecificsD(); padInfosD.ShapeIndex = shapeList[specPad.ODBSymbol_String]; pad.SetSpecifics(padInfosD, shapeList[specPad.ODBSymbol_String]); } else if (obj.Type == IObjectType.Line) { ILineSpecificsD specLine = (ILineSpecificsD)obj.GetSpecificsD(); if (!shapeList.ContainsKey(specLine.ODBSymbol_String)) { int newShapeIndex = IFilter.AddToolFromODBString(layer, specLine.ODBSymbol_String, shapeList.Count); shapeList.Add(specLine.ODBSymbol_String, newShapeIndex); } IODBObject line = filter.CreateLine(layer); ILineSpecificsD lineSpecificsD = (ILineSpecificsD)obj.GetSpecificsD(); lineSpecificsD.ShapeIndex = shapeList[specLine.ODBSymbol_String]; line.SetSpecifics(lineSpecificsD); } else if (obj.Type == IObjectType.Arc) { IArcSpecificsD specArc = (IArcSpecificsD)obj.GetSpecificsD(); if (!shapeList.ContainsKey(specArc.ODBSymbol_String)) { int newShapeIndex = IFilter.AddToolFromODBString(layer, specArc.ODBSymbol_String, shapeList.Count); shapeList.Add(specArc.ODBSymbol_String, newShapeIndex); } IODBObject arc = filter.CreateArc(layer); IArcSpecificsD specificsArcD = (IArcSpecificsD)obj.GetSpecificsD(); specificsArcD.ShapeIndex = shapeList[specArc.ODBSymbol_String]; arc.SetSpecifics(specificsArcD); } else if (obj.Type == IObjectType.Surface) { IODBObject surface = filter.CreatePolygon(layer); ISurfaceSpecificsD surfaceSpecificsD = (ISurfaceSpecificsD)obj.GetSpecificsD(); surface.SetSpecifics(surfaceSpecificsD); } else if (obj.Type == IObjectType.Text) { IODBObject text = filter.CreateText(layer); ITextSpecificsD textSpecificsD = (ITextSpecificsD)obj.GetSpecificsD(); text.SetSpecifics(textSpecificsD); } } if (activateLayer) { layer.EnableLayer(true); } IMatrix matrix = parent.GetMatrix(); matrix.SetMatrixLayerType(layer.LayerName, MatrixLayerType.Drill); matrix.SetMatrixLayerContext(layer.LayerName, MatrixLayerContext.Board); }
public void Execute(IPCBIWindow parent) { if (parent.GetCurrentStep() == null) { return; } bool clearLayer = false; IStep step = parent.GetCurrentStep(); IFilter filter = new IFilter(parent); if (parent.GetCurrentStep() == null) { return; } IODBLayer layerTopPins = null; IODBLayer layerbotPins = null; if (layerTopPins == null) { layerTopPins = filter.CreateEmptyODBLayer("component_top_shapes", step.Name); if (clearLayer) { foreach (IODBObject o in layerTopPins.GetAllLayerObjects()) { layerTopPins.RemoveObject(o); } } } if (layerbotPins == null) { layerbotPins = filter.CreateEmptyODBLayer("component_bot_shapes", step.Name); if (clearLayer) { foreach (IODBObject o in layerbotPins.GetAllLayerObjects()) { layerbotPins.RemoveObject(o); } } } foreach (ICMPObject cmp in step.GetAllCMPObjects()) { PCBI.MathUtils.IPolyClass CMP_Poly = cmp.GetPolygonOutline(false); IODBObject outlinePolygon; if (cmp.PlacedTop) { outlinePolygon = filter.CreatePolygon(layerTopPins); } else { outlinePolygon = filter.CreatePolygon(layerbotPins); } ISurfaceSpecifics CMP_Body_Polygon = (ISurfaceSpecifics)outlinePolygon.GetSpecifics(); bool polyStart = true; foreach (IEdge edge in CMP_Poly.GetEdges()) { if (polyStart) { polyStart = false; CMP_Body_Polygon.StartPolygon(false, new PointF((float)edge.Begin.X, (float)edge.Begin.Y)); } else if (edge is IArcEdge) { IArcEdge aEdge = (IArcEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); PointF center = new PointF((float)aEdge.Center.X, (float)aEdge.Center.Y); CMP_Body_Polygon.AddArc(start, end, center, aEdge.ClockWise); } else if (edge is ILineEdge) { ILineEdge aEdge = (ILineEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); CMP_Body_Polygon.AddLine(start, end); } } CMP_Body_Polygon.EndPolygon(); //close the new contour outlinePolygon.SetSpecifics(CMP_Body_Polygon); } layerbotPins.EnableLayer(true); layerTopPins.EnableLayer(true); parent.UpdateView(); parent.UpdateControlsAndResetView(); }
public void Execute(IPCBIWindow parent) { if (parent.GetCurrentStep() == null) { return; } bool clearLayer = false; IStep step = parent.GetCurrentStep(); IODBLayer layerTopPins = null; IODBLayer layerbotPins = null; IFilter filter = new IFilter(parent); if (layerTopPins == null) { layerTopPins = filter.CreateEmptyODBLayer("component_top_shapes", step.Name); if (clearLayer) { foreach (IODBObject o in layerTopPins.GetAllLayerObjects()) { layerTopPins.RemoveObject(o); } } } if (layerbotPins == null) { layerbotPins = filter.CreateEmptyODBLayer("component_bot_shapes", step.Name); if (clearLayer) { foreach (IODBObject o in layerbotPins.GetAllLayerObjects()) { layerbotPins.RemoveObject(o); } } } // Pins foreach (ICMPObject cmp in step.GetAllCMPObjects()) { foreach (IPin pin in cmp.GetPinList()) { IODBObject outlinePolygon = null; if (cmp.PlacedTop) { outlinePolygon = filter.CreatePolygon(layerTopPins); } else { outlinePolygon = filter.CreatePolygon(layerbotPins); } ISurfaceSpecifics specOutline = (ISurfaceSpecifics)outlinePolygon.GetSpecifics(); bool polyStart = true; PointF StartPoint = new PointF(0, 0); PointF EndPoint = new PointF(0, 0); foreach (IEdge edge in pin.GetPolygonOutline(cmp).GetEdges()) { if (polyStart) { polyStart = false; StartPoint = new PointF((float)edge.Begin.X, (float)edge.Begin.Y); specOutline.StartPolygon(false, StartPoint); if (edge is IArcEdge) { IArcEdge aEdge = (IArcEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); PointF center = new PointF((float)aEdge.Center.X, (float)aEdge.Center.Y); specOutline.AddArc(start, end, center, aEdge.ClockWise); if (aEdge.ClockWise) { EndPoint = end; } else { EndPoint = start; } } else if (edge is ILineEdge) { ILineEdge aEdge = (ILineEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); specOutline.AddLine(start, end); EndPoint = end; } } else if (edge is IArcEdge) { IArcEdge aEdge = (IArcEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); PointF center = new PointF((float)aEdge.Center.X, (float)aEdge.Center.Y); specOutline.AddArc(start, end, center, aEdge.ClockWise); if (aEdge.ClockWise) { EndPoint = end; } else { EndPoint = start; } } else if (edge is ILineEdge) { ILineEdge aEdge = (ILineEdge)edge; PointF start = new PointF((float)aEdge.Begin.X, (float)aEdge.Begin.Y); PointF end = new PointF((float)aEdge.End.X, (float)aEdge.End.Y); specOutline.AddLine(start, end); EndPoint = end; } } specOutline.EndPolygon(); //close the new contour outlinePolygon.SetSpecifics(specOutline); outlinePolygon.ObjectColor = Color.Blue; } } layerbotPins.EnableLayer(true); layerTopPins.EnableLayer(true); parent.UpdateView(); parent.UpdateControlsAndResetView(); }
public void Execute(IPCBIWindow parent) { //set all signal layers in one image string Rows = Microsoft.VisualBasic.Interaction.InputBox("How many rows do you wish?", "Setup", "2"); int rows = 2; try { rows = int.Parse(Rows); } catch (Exception re) { MessageBox.Show("Please provide a number\n" + re.ToString()); } string pathForImage = System.IO.Path.GetTempPath() + "imageComplete.png"; //output somewhere stopImaging = false; //internal bool to use cancel button float DPI = 1000; //in pixel foreach layer int maxWidtBMP = 40000; //image class is dangerous for big RAM usage! int countImagesEachLine = rows; //maximum of image in one line bool AddDrillsToImage = true; //see where are the connections to other layers bool AddCompToImageAsSeperateLayer = true; //see where are the connections to other layers IStep step = parent.GetCurrentStep(); IMatrix matrix = parent.GetMatrix(); if (step == null || matrix == null) { return; } PCB_Investigator.PCBIWindows.PCBIWorkingDialog working = null; try { working = new PCB_Investigator.PCBIWindows.PCBIWorkingDialog(); //show waiting dialog, because for some projects it is very slow working.CanCancel(true); working.CancelPressed += working_CancelPressed; working.SetAnimationStatus(false); working.ShowWorkingDlgAsThread(); int curValPercentage = 0; working.SetStatusPercent(curValPercentage); List <string> allSignalLayerNames = matrix.GetAllSignalLayerNames(); if (!AddCompToImageAsSeperateLayer) { allSignalLayerNames.Insert(0, matrix.GetTopComponentLayer()); allSignalLayerNames.Add(matrix.GetBotComponentLayer()); } List <ILayer> activeLayerList = step.GetActiveLayerList(); //remember active layer list to set them later back step.TurnOffAllLayer(); int maxHeight = 0; int maxWidth = 0; int completeWidth = 0; int lines = 1; bool setBackHatch = parent.IColorsetting.UseHatchMode; Color setBackColor = parent.IColorsetting.SelectionColor; parent.IColorsetting.SelectionColor = Color.White; //highlight selection better with plane color parent.IColorsetting.UseHatchMode = false; RectangleF boundsStep = step.GetBounds(); boundsStep.Inflate(20, 20); int height = (int)(boundsStep.Height * DPI / 1000); int width = (int)(boundsStep.Width * DPI / 1000); //set the step bounds with DPI if (height > maxHeight) { maxHeight = height; } curValPercentage = 10; working.SetStatusPercent(curValPercentage); Dictionary <string, System.Drawing.Bitmap> allLayerImages = new Dictionary <string, System.Drawing.Bitmap>(); int counterLayers = 0; foreach (string layername in allSignalLayerNames) { if (stopImaging) { break; } counterLayers++; working.SetStatusText("working on " + layername); curValPercentage += 80 / allSignalLayerNames.Count; //we want only the part in the middle of the progress bar... working.SetStatusPercent(curValPercentage); Bitmap resultImage; if (step.GetLayer(layername) is IODBLayer) { IODBLayer signalLayer = (IODBLayer)step.GetLayer(layername); signalLayer.EnableLayer(true); if (AddDrillsToImage) { List <ILayer> drawList = new List <ILayer>(); foreach (string layerDrillName in matrix.GetAllDrillLayersForThisLayer(layername)) { drawList.Add(step.GetLayer(layerDrillName)); } drawList.Add(signalLayer); if (AddCompToImageAsSeperateLayer) { if (matrix.GetTopSignalLayer() == layername) { ILayer layer = step.GetLayer(matrix.GetTopComponentLayer()); if (layer != null) { drawList.Add(layer); } } if (matrix.GetBotSignalLayer() == layername) { ILayer layer = step.GetLayer(matrix.GetBotComponentLayer()); if (layer != null) { drawList.Add(layer); } } } resultImage = step.GetBitmap(drawList, boundsStep, width, height, true, false, false, false); // public Bitmap GetBitmap( List<ILayer> Layers,RectangleF DetailRectangle, int Width, int Height, bool DrawPCBOutline, bool FillBoardOutline, bool ShowComponentDetails, bool IgnoreSelection, bool DrawOnlySelection, out RectangleF DrawnRectangle Bitmap copyBitmap = new Bitmap(resultImage); //do copy the image before the old one will be disposed resultImage = copyBitmap; } else { resultImage = step.GetBitmap(new List <ILayer>() { signalLayer }, boundsStep, width, height, true, false, false, false); } if (resultImage != null) { allLayerImages.Add(layername, resultImage); //remember the layer image later } signalLayer.DisableLayer(); } else if (!AddCompToImageAsSeperateLayer && step.GetLayer(layername) is ICMPLayer) { ICMPLayer cmpLayer = (ICMPLayer)step.GetLayer(layername); resultImage = step.GetBitmap(new List <ILayer>() { cmpLayer }, boundsStep, width, height, true, false, true, false); allLayerImages.Add(layername, resultImage); //remember the layer image later } if (completeWidth + width > maxWidtBMP || counterLayers > countImagesEachLine) //max image size { lines++; completeWidth = width; counterLayers = 1; } else { completeWidth += width; } if (completeWidth > maxWidth) { maxWidth = completeWidth; } } working.SetStatusText("built new image..."); working.SetStatusPercent(85); Bitmap bitComplete = null; bool needDownScale = false; try { bitComplete = new Bitmap(maxWidth, lines * (maxHeight + 100) + 60); //depending on your design this constructor sometimes throw an exception } catch { bitComplete = new Bitmap(maxWidth / 10, lines * (maxHeight + 1000) / 10 + 60); needDownScale = true; //depending on your machine settings and RAM it can make problems by creating big images. } parent.IColorsetting.UseHatchMode = setBackHatch; parent.IColorsetting.SelectionColor = setBackColor; Graphics g = Graphics.FromImage(bitComplete); g.Clear(Color.Transparent); int Xoff = 0; int Yoff = 0; working.SetStatusText("set images in one... "); Font f = new Font("Arial", needDownScale ? 20 : 40); //we need a font to write layernames int counterImagesInLine = 0; foreach (string layer in allLayerImages.Keys) { counterImagesInLine++; if (needDownScale && (Xoff + allLayerImages[layer].Width / 10 > bitComplete.Width || counterImagesInLine > countImagesEachLine)) { Yoff += maxHeight / 10 + 100; //space for text Xoff = 0; counterImagesInLine = 1; } else if (Xoff + allLayerImages[layer].Width > maxWidtBMP || counterImagesInLine > countImagesEachLine) { Yoff += maxHeight + 100; //space for text Xoff = 0; counterImagesInLine = 1; } if (needDownScale) { g.DrawImage(allLayerImages[layer], new RectangleF(Xoff, Yoff + 100, width / 10, height / 10), new RectangleF(0, 0, allLayerImages[layer].Width, allLayerImages[layer].Height), GraphicsUnit.Pixel); } else { g.DrawImage(allLayerImages[layer], new Point(Xoff, Yoff + 100)); } g.DrawString(layer, f, Brushes.Red, new PointF(Xoff + 50, Yoff + 30)); //name of layer if (needDownScale) { Xoff += allLayerImages[layer].Width / 10; } else { Xoff += allLayerImages[layer].Width; } } string textForFooter = parent.GetJobName() + " - creation date: " + DateTime.Now.ToString() + " www.PCB-Investigator.com"; SizeF size = g.MeasureString(textForFooter, f); g.DrawString(textForFooter, f, Brushes.White, new PointF((bitComplete.Width - size.Width) / 2, bitComplete.Height - 60)); //name of layer working.SetStatusPercent(91); foreach (ILayer layerActive in activeLayerList) { layerActive.EnableLayer(true); } working.SetStatusPercent(95); try { working.SetStatusText("saving result..."); bitComplete.Save(pathForImage, ImageFormat.Png); //open image with standard viewer System.Diagnostics.Process.Start(pathForImage); } catch { } working.DoClose(); } catch (Exception ex) { if (working != null) { working.DoClose(); } MessageBox.Show("Can't create image, because " + Environment.NewLine + ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } }