private void RenderPadPrimitive(Graphics g, PcbPad pad) { var holeCenter = ScreenFromWorld(pad.Location.X, pad.Location.Y); g.TranslateTransform(holeCenter.X, holeCenter.Y); g.RotateTransform(-(float)pad.Rotation); DrawPad(g, pad, PcbPadPart.BottomSolder); DrawPad(g, pad, PcbPadPart.TopSolder); DrawPad(g, pad, PcbPadPart.BottomLayer); DrawPad(g, pad, PcbPadPart.TopLayer); if (pad.HasHole) { g.RotateTransform(-(float)pad.HoleRotation); using (var brush = new SolidBrush(Layer.GetLayerColor("PadHoleLayer"))) { var rect = ScaleRect(pad.CalculatePartRect(PcbPadPart.Hole, false)); switch (pad.HoleShape) { case PcbPadHoleShape.Round: g.FillEllipse(brush, rect); break; case PcbPadHoleShape.Square: DrawingUtils.FillRectangle(g, brush, rect); break; case PcbPadHoleShape.Slot: DrawingUtils.FillRoundedRect(g, brush, rect, 100); break; default: return; } } } g.ResetTransform(); const float MIN_FONT_DESCRIPTOR = 7; var fontSize = Math.Min(29f, ScaleCoord(pad.HasHole ? pad.HoleSize : pad.SizeTop.Y) * 0.5f); if (fontSize > MIN_FONT_DESCRIPTOR) { var fontColor = pad.HasHole ? Color.FromArgb(255, 227, 143) : Color.FromArgb(255, 181, 181); using (var brush = new SolidBrush(fontColor)) // TODO: add constant using (var font = new Font("Arial", fontSize)) { DrawingUtils.DrawString(g, pad.Designator, font, brush, holeCenter.X, holeCenter.Y, StringAlignmentKind.Tight, StringAlignment.Center, StringAlignment.Center); } } }
private void WriteFootprintPad(BinaryWriter writer, PcbPad pad) { WriteStringBlock(writer, pad.Designator); WriteBlock(writer, new byte[] { 0 }); // TODO: Unknown WriteStringBlock(writer, "|&|0"); WriteBlock(writer, new byte[] { 0 }); // TODO: Unknown WriteBlock(writer, w => { WriteFootprintCommon(w, pad, pad.Location); WriteCoordPoint(w, pad.SizeTop); WriteCoordPoint(w, pad.SizeMiddle); WriteCoordPoint(w, pad.SizeBottom); w.Write(pad.HoleSize.ToInt32()); w.Write((byte)(pad.ShapeTop == PcbPadShape.RoundedRectangle ? PcbPadShape.Round : pad.ShapeTop)); // 72 w.Write((byte)(pad.ShapeMiddle == PcbPadShape.RoundedRectangle ? PcbPadShape.Round : pad.ShapeMiddle)); w.Write((byte)(pad.ShapeBottom == PcbPadShape.RoundedRectangle ? PcbPadShape.Round : pad.ShapeBottom)); w.Write((double)pad.Rotation); w.Write(pad.IsPlated); w.Write((byte)0); // 91 constant value? w.Write((byte)pad.StackMode); w.Write((byte)0); // TODO: Unknown 0 w.Write(0); // TODO: Unknown 0 w.Write(Coord.FromMils(10)); // TODO: Unknown 10mil? w.Write((short)4); // 102 constant value? w.Write(Coord.FromMils(10)); // TODO: Unknown 10mil? w.Write(Coord.FromMils(20)); // TODO: Unknown 20mil? w.Write(Coord.FromMils(20)); // TODO: Unknown 20mil? w.Write(pad.PasteMaskExpansion.ToInt32()); w.Write(pad.SolderMaskExpansion.ToInt32()); w.Write((byte)0); // TODO: Unknown 0 w.Write((byte)0); // TODO: Unknown 0 w.Write((byte)0); // TODO: Unknown 0 w.Write((byte)0); // TODO: Unknown 0/1 w.Write((byte)0); // TODO: Unknown 0/1 w.Write((byte)0); // TODO: Unknown 0/1 w.Write((byte)0); // TODO: Unknown 0/1 w.Write((byte)(pad.PasteMaskExpansionManual ? 2 : 0)); w.Write((byte)(pad.SolderMaskExpansionManual ? 2 : 1)); w.Write((byte)0); // TODO: Unknown 0/1 w.Write((byte)0); // TODO: Unknown 0 w.Write((byte)0); // TODO: Unknown 0 w.Write(0); // TODO: Unknown w.Write((short)pad.JumperId); w.Write((short)0); }); // Write size and shape and parts of hole information if (pad.NeedsFullStackData) { WriteBlock(writer, w => { // 29 items foreach (var padSize in pad.SizeMiddleLayers) { w.Write(padSize.X.ToInt32()); } foreach (var padSize in pad.SizeMiddleLayers) { w.Write(padSize.Y.ToInt32()); } foreach (var padShape in pad.ShapeMiddleLayers) { w.Write((byte)padShape); } w.Write((byte)0); // TODO: Unknown w.Write((byte)pad.HoleShape); w.Write(pad.HoleSlotLength); w.Write((double)pad.HoleRotation); // 32 items foreach (var offset in pad.OffsetsFromHoleCenter) { w.Write(offset.X.ToInt32()); } foreach (var offset in pad.OffsetsFromHoleCenter) { w.Write(offset.Y.ToInt32()); } w.Write(pad.HasRoundedRectangles); if (pad.HasRoundedRectangles) { foreach (var padShape in pad.ShapeLayers) { w.Write((byte)padShape); } } else { foreach (var padShape in pad.ShapeLayers) { w.Write((byte)PcbPadShape.Round); // write dummy value } } // 32 items foreach (var crp in pad.CornerRadiusPercentage) { w.Write((byte)crp); } }); } else { WriteBlock(writer, Array.Empty <byte>()); } }
private void DrawPad(Graphics g, PcbPad pad, PcbPadPart padPart) { PcbPadShape shape; int cornerRadiusPercent; Color color; // setup parameters according to the current padPart switch (padPart) { case PcbPadPart.TopLayer: shape = pad.ShapeTop; cornerRadiusPercent = pad.CornerRadiusTop; color = LayerMetadata.GetColor(pad.Layer); break; case PcbPadPart.BottomLayer: shape = pad.ShapeBottom; cornerRadiusPercent = pad.CornerRadiusBot; color = LayerMetadata.GetColor(pad.Layer); break; case PcbPadPart.TopSolder: shape = pad.ShapeTop; cornerRadiusPercent = pad.CornerRadiusTop; color = LayerMetadata.GetColor("TopSolder"); break; case PcbPadPart.BottomSolder: shape = pad.ShapeBottom; cornerRadiusPercent = pad.CornerRadiusBot; color = LayerMetadata.GetColor("BottomSolder"); break; default: return; } var rect = ScaleRect(pad.CalculatePartRect(padPart, false)); using (var brush = new SolidBrush(color)) { switch (shape) { case PcbPadShape.Round: DrawingUtils.FillRoundedRect(g, brush, rect, 100); break; case PcbPadShape.Rectangular: DrawingUtils.FillRectangle(g, brush, rect); break; case PcbPadShape.Octogonal: DrawingUtils.FillOctagon(g, brush, rect); break; case PcbPadShape.RoundedRectangle: cornerRadiusPercent = cornerRadiusPercent > 0 ? cornerRadiusPercent : 100; DrawingUtils.FillRoundedRect(g, brush, rect, cornerRadiusPercent); break; default: return; } } }
private PcbPad ReadFootprintPad(BinaryReader reader) { var pad = new PcbPad(); pad.Designator = ReadStringBlock(reader); ReadBlock(reader); // TODO: Unknown ReadStringBlock(reader); // constant: |&|0 ReadBlock(reader); // TODO: Unknown ReadBlock(reader, blockSize => { ReadFootprintCommon(reader, pad); pad.Location = ReadCoordPoint(reader); pad.SizeTop = ReadCoordPoint(reader); pad.SizeMiddle = ReadCoordPoint(reader); pad.SizeBottom = ReadCoordPoint(reader); pad.HoleSize = reader.ReadInt32(); pad.ShapeTop = (PcbPadShape)reader.ReadByte(); //72 pad.ShapeMiddle = (PcbPadShape)reader.ReadByte(); pad.ShapeBottom = (PcbPadShape)reader.ReadByte(); pad.Rotation = reader.ReadDouble(); pad.IsPlated = reader.ReadBoolean(); CheckValue("#91", reader.ReadByte(), 0); pad.StackMode = (PcbStackMode)reader.ReadByte(); reader.ReadByte(); // TODO: Unknown 0 reader.ReadInt32(); // TODO: Unknown 0 reader.ReadInt32(); // TODO: Unknown 10mil? CheckValue("#102", reader.ReadInt16(), 4); reader.ReadUInt32(); // TODO: Unknown 10mil? reader.ReadUInt32(); // TODO: Unknown 20mil? reader.ReadUInt32(); // TODO: Unknown 20mil? pad.PasteMaskExpansion = Coord.FromInt32(reader.ReadInt32()); pad.SolderMaskExpansion = Coord.FromInt32(reader.ReadInt32()); reader.ReadByte(); // TODO: Unknown 0 reader.ReadByte(); // TODO: Unknown 0 reader.ReadByte(); // TODO: Unknown 0 reader.ReadByte(); // TODO: Unknown 0/1 reader.ReadByte(); // TODO: Unknown 0/1 reader.ReadByte(); // TODO: Unknown 0/1 reader.ReadByte(); // TODO: Unknown 0/1 pad.PasteMaskExpansionManual = reader.ReadByte() == 2; pad.SolderMaskExpansionManual = reader.ReadByte() == 2; reader.ReadByte(); // TODO: Unknown 0/1 reader.ReadByte(); // TODO: Unknown 0 reader.ReadByte(); // TODO: Unknown 0 reader.ReadUInt32(); // TODO: Unknown pad.JumperId = reader.ReadInt16(); reader.ReadInt16(); /* * if (blockSize > 114) * { * reader.ReadUInt32(); // TODO: Unknown * pad.Layer = reader.ReadByte(); // Layer again? * reader.ReadByte(); // TODO: Unknown * reader.ReadByte(); // TODO: Unknown * pad.FromLayer = reader.ReadByte(); * reader.ReadByte(); // TODO: Unknown * reader.ReadByte(); // TODO: Unknown * } */ }); // Read size and shape and parts of hole information ReadBlock(reader, blockSize => { CheckValue(nameof(blockSize), blockSize, 596, 628); var padXSizes = new Coord[29]; var padYSizes = new Coord[29]; for (int i = 0; i < 29; ++i) { padXSizes[i] = reader.ReadInt32(); } for (int i = 0; i < 29; ++i) { padYSizes[i] = reader.ReadInt32(); } for (int i = 0; i < 29; ++i) { pad.SizeMiddleLayers[i] = new CoordPoint(padXSizes[i], padYSizes[i]); } for (int i = 1; i < 30; ++i) { pad.ShapeLayers[i] = (PcbPadShape)reader.ReadByte(); } reader.ReadByte(); // TODO: Unknown pad.HoleShape = (PcbPadHoleShape)reader.ReadByte(); pad.HoleSlotLength = reader.ReadInt32(); pad.HoleRotation = reader.ReadDouble(); var offsetXFromHoleCenter = new int[32]; var offsetYFromHoleCenter = new int[32]; for (int i = 0; i < 32; ++i) { offsetXFromHoleCenter[i] = reader.ReadInt32(); } for (int i = 0; i < 32; ++i) { offsetYFromHoleCenter[i] = reader.ReadInt32(); } for (int i = 0; i < 32; ++i) { pad.OffsetsFromHoleCenter[i] = new CoordPoint(offsetXFromHoleCenter[i], offsetYFromHoleCenter[i]); } var hasRoundedRect = reader.ReadBoolean(); if (hasRoundedRect) { for (int i = 0; i < 32; ++i) { pad.ShapeLayers[i] = (PcbPadShape)reader.ReadByte(); } } else { for (int i = 0; i < 32; ++i) { reader.ReadByte(); // ignore values } } for (int i = 0; i < 32; ++i) { pad.CornerRadiusPercentage[i] = reader.ReadByte(); } }); return(pad); }