The code shall be taken "as is", no support in any way, I don't need bug reports or ideas right now, not all commands are supported yet, it always shows the whole board (no zooming or moving), drop the gerber file on the canvas, some primitives are not generated yet, the gerber data is not verified yet, I'm programming on Windows (no idea whether the other OSes work), not threadsafe, didn't test with scaling...
Code: Select all
DeclareModule Gerber
Enumeration Fill
#Gerber_FillMode_Outline ;Draw outlines
#Gerber_FillMode_Fill ;Fill polygons
EndEnumeration
Structure Pos
X.d
Y.d
EndStructure
Structure Vertex
X.f
Y.f
EndStructure
Structure Primitive
Type.a
Exposure.a
Diameter.f
CenterX.f
CenterY.f
Rotation.f
Width.f
Height.f
StartX.f
StartY.f
EndX.f
EndY.f
OuterDiameter.f
InnerDiameter.f
Gap.f
VertexCount.w
RingThickness.f
CrosshairThickness.f
CrosshairLength.f
List Vertices.Vertex()
EndStructure
Structure AM
List Primitives.Primitive()
EndStructure
Structure Aperture
Type.a
ApertureMacro.s
Diameter.d
Vertex.a
Rotation.d
X.d
Y.d
InnerX.d
InnerY.d
EndStructure
Structure Gerber
OmittedZeros.a
CoordinateMode.a
SequenceNumber.a
PreparatoryFunctionCode.a
X.f
Y.f
Z.f
DraftCode.a
MiscCode.a
Unit.a
ExposureMode.a
LeadPolarity.a
MirrorA.a
MirrorB.a
ScaleFactorA.f
ScaleFactorB.f
Digits.a
Map ApertureMacro.AM()
Map Apertures.Aperture()
List Names.s()
List RawData.s()
List Path.s()
Map Attributes.s()
Min.Pos
Max.Pos
Scaling.d
BackgroundColor.l
ForegroundColor.l
OutlineColor.l
FiducialColor.l
FillMode.a
BoardSize.Pos;in mm
LastDuration.l
EndStructure
Declare PlotGerberToCanvas(Gadget.i,*Gerber.Gerber)
Declare CreateGerberDataFromString(Gerber$)
Declare CreateGerberDataFromFile(File$)
EndDeclareModule
Module Gerber
EnableExplicit
Enumeration RegEx
#Gerber_RegEx_Input
#Gerber_RegEx_Header
#Gerber_RegEx_ExposureMode
#Gerber_RegEx_Macro
#Gerber_RegEx_Apertures
#Gerber_RegEx_Names
#Gerber_RegEx_Scaling
#Gerber_RegEx_LeadPolarity
#Gerber_RegEx_Mirror
#Gerber_RegEx_ScaleFactor
#Gerber_RegEx_Attributes
#Gerber_RegEx_Omitter
#Gerber_Command_Preprocess
#Gerber_Command_PreprocessX
#Gerber_Command_PreprocessY
#Gerber_Command_SelectAperture
#Gerber_Command_D01
#Gerber_Command_D02
#Gerber_Command_D03
#Gerber_Command_G01
#Gerber_Command_G02
#Gerber_Command_G03
#Gerber_Command_Generic
#Gerber_Command_JustMove
EndEnumeration
Enumeration OmittedZeros
#Gerber_OZ_No
#Gerber_OZ_Trailing
#Gerber_OZ_Leading
EndEnumeration
Enumeration CoordinateMode
#Gerber_Coord_Absolute
#Gerber_Coord_Incremental
EndEnumeration
Enumeration Unit
#Gerber_Unit_Inch
#Gerber_Unit_MM
EndEnumeration
Enumeration ExposureMode
#Gerber_EM_Positiv
#Gerber_EM_Negativ
EndEnumeration
;{ MacroTypes
#Gerber_MT_Comment = 0
#Gerber_MT_Circle = 1
#Gerber_MT_LineVector = 2;=#Gerber_MT_VectorLine
#Gerber_MT_VectorLine = 20
#Gerber_MT_CenterLine = 21
#Gerber_MT_LowerLeftLine = 22
#Gerber_MT_Outline = 4
#Gerber_MT_Polygon = 5
#Gerber_MT_Moire = 6
#Gerber_MT_Thermal = 7
;}
Enumeration Exposure
#Gerber_Exp_Off
#Gerber_Exp_On
EndEnumeration
Enumeration ApertureType
#Gerber_AT_Circle
#Gerber_AT_Rectangle
#Gerber_AT_Obround
#Gerber_AT_Polygon
#Gerber_AT_ApertureMacro
EndEnumeration
Enumeration LeadPolarity
#Gerber_LeadPolarity_Dark
#Gerber_LeadPolarity_Clear
EndEnumeration
Enumeration GMode
#Gerber_GMode_Undefined
#Gerber_GMode_G01
#Gerber_GMode_G02
#Gerber_GMode_G03
EndEnumeration
;{ Create RegEx
CreateRegularExpression(#Gerber_RegEx_Header,"^FS([L|T|D])([A|I])(\d?)(\d?)X(\d{2})Y(\d{2})(Z(\d{2}))?(D(\d+))?(M(\d+))?\*$")
CreateRegularExpression(#Gerber_RegEx_Names,"^LN([^\*]+)\*$")
CreateRegularExpression(#Gerber_RegEx_Scaling,"^MO(MM|IN)\*$")
CreateRegularExpression(#Gerber_RegEx_ExposureMode,"^IP(POS|NEG)\*$")
CreateRegularExpression(#Gerber_RegEx_Macro,"^AM([^\*]+)\*([^\%]+)$")
CreateRegularExpression(#Gerber_RegEx_Apertures,"^ADD(\d+)([^\,\%]+)\,?(.*)\*$")
CreateRegularExpression(#Gerber_RegEx_LeadPolarity,"^LP([CD])\*$")
CreateRegularExpression(#Gerber_RegEx_Mirror,"^MI([AB][01])([AB][01])?\*$")
CreateRegularExpression(#Gerber_RegEx_ScaleFactor,"^SF([AB][\d\.]+)([AB][\d\.]+)?\*$")
CreateRegularExpression(#Gerber_RegEx_Attributes,"^TF\.(\w+)\,(.+)\*$")
CreateRegularExpression(#Gerber_RegEx_Attributes,"^TF\.(\w+)\,(.+)\*$")
CreateRegularExpression(#Gerber_RegEx_Omitter,"[XYIJ][-\d]+")
CreateRegularExpression(#Gerber_Command_Preprocess,"((X)([\d\.\-]+))((Y)([\d\.\-]+))|((X)([\d\.\-]+))|((Y)([\d\.\-]+))")
CreateRegularExpression(#Gerber_Command_PreprocessX,"X([\d\.\-]+)")
CreateRegularExpression(#Gerber_Command_PreprocessY,"Y([\d\.\-]+)")
CreateRegularExpression(#Gerber_Command_SelectAperture,"^((G54D|D)(\d+))$")
CreateRegularExpression(#Gerber_Command_Generic,"^([XYIJD])([\d-]+)(([XYIJD])([\d-]+))?(([XYIJD])([\d-]+))?(([XYIJD])([\d-]+))?(([XYIJD])([\d-]+))?(([XYIJD])([\d-]+))?$")
CreateRegularExpression(#Gerber_Command_D01,"^([XY])([-\d]+)(([XY])([-\d]+))?D01$")
CreateRegularExpression(#Gerber_Command_D02,"^([XY])([-\d]+)(([XY])([-\d]+))?D02$")
CreateRegularExpression(#Gerber_Command_D03,"^([XY])([-\d]+)(([XY])([-\d]+))?D03$")
CreateRegularExpression(#Gerber_Command_G01,"^G01([XY])([-\d]+)(([XY])([-\d]+))?D(\d+)$")
CreateRegularExpression(#Gerber_Command_G02,"^G02([XYIJ][\d-]+)([XYIJ][\d-]+)?([XYIJ][\d-]+)?([XYIJ][\d-]+)?D01$")
CreateRegularExpression(#Gerber_Command_G03,"^G03([XYIJ][\d-]+)([XYIJ][\d-]+)?([XYIJ][\d-]+)?([XYIJ][\d-]+)?D01$")
CreateRegularExpression(#Gerber_Command_JustMove,"^([XY])([-\d]+)(([XY])([-\d]+))?$")
;}
Macro Movement(UsedCommand)
OldPosition\X=Position\X
OldPosition\Y=Position\Y
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
NewPosition\X=Position\X
NewPosition\Y=Position\Y
Else
NewPosition\X=0
NewPosition\Y=0
EndIf
Select CountRegularExpressionGroups(UsedCommand)
Case 2,3;X/Y
Select RegularExpressionGroup(UsedCommand,1)
Case "X"
NewPosition\X=Val(RegularExpressionGroup(UsedCommand,2))
Case "Y"
NewPosition\Y=Val(RegularExpressionGroup(UsedCommand,2))
EndSelect
Case 5,6;X und Y
Select RegularExpressionGroup(UsedCommand,1)
Case "X"
NewPosition\X=Val(RegularExpressionGroup(UsedCommand,2))
Case "Y"
NewPosition\Y=Val(RegularExpressionGroup(UsedCommand,2))
EndSelect
Select RegularExpressionGroup(UsedCommand,4)
Case "X"
NewPosition\X=Val(RegularExpressionGroup(UsedCommand,5))
Case "Y"
NewPosition\Y=Val(RegularExpressionGroup(UsedCommand,5))
EndSelect
EndSelect
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
Position\X=NewPosition\X
Position\Y=NewPosition\Y
Else
Position\X+NewPosition\X
Position\Y+NewPosition\Y
EndIf
If SizeMode
If Position\X>*Gerber\Max\X:*Gerber\Max\X=Position\X:EndIf
If Position\X<*Gerber\Min\X:*Gerber\Min\X=Position\X:EndIf
If Position\Y>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y:EndIf
If Position\Y<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y:EndIf
EndIf
EndMacro
Macro DrawGerber(MyPosition)
If G75
VectorSourceColor($FF000000|*Gerber\OutlineColor)
Else
VectorSourceColor($FF000000|*Gerber\ForegroundColor)
EndIf
Select *Gerber\FillMode
Case #Gerber_FillMode_Outline
StrokePath(1,#PB_Path_Default)
Case #Gerber_FillMode_Fill
If G75
StrokePath(1,#PB_Path_Default)
Else
If GMode=1
If *Gerber\Apertures(Aperture)\Type=#Gerber_AT_Circle
StrokePath(*Gerber\Apertures(Aperture)\Diameter,#PB_Path_Default)
Else
StrokePath(*Gerber\Apertures(Aperture)\X,#PB_Path_Default)
EndIf
Else
FillPath(#PB_Path_Default|#PB_Path_Winding)
EndIf
EndIf
EndSelect
MovePathCursor(MyPosition\X,MyPosition\Y)
EndMacro
Procedure DrawPrimitives(*AMacro.AM,*Position.Pos,SizeMode.a,*Gerber.Gerber)
Protected Orig.Pos,Rot.d,Count.w,Len.d,NX.d,NY.d,G75.a=0,GMode.a=0,Aperture.s=""
ForEach *AMacro\Primitives()
MovePathCursor(*Position\X,*Position\Y,#PB_Path_Default)
Select *AMacro\Primitives()\Type
Case #Gerber_MT_Comment;0
Debug "Primitive: Comment"
Case #Gerber_MT_Circle ;1
If SizeMode
Len=Pow(Pow(*AMacro\Primitives()\CenterX,2)+Pow(*AMacro\Primitives()\CenterY,2),0.5)
Rot=*AMacro\Primitives()\Diameter/2
NX=*Position\X+Len*Cos(Radian(*AMacro\Primitives()\Rotation))
NY=*Position\Y+Len*Sin(Radian(*AMacro\Primitives()\Rotation))
AddPathCircle(NX,NY,Rot,0,360,#PB_Path_Default)
If NX-Rot<*Gerber\Min\X:*Gerber\Min\X=NX-Rot:EndIf
If NX+Rot>*Gerber\Max\X:*Gerber\Max\X=NX+Rot:EndIf
If NY-Rot<*Gerber\Min\Y:*Gerber\Min\Y=NY-Rot:EndIf
If NY+Rot>*Gerber\Max\Y:*Gerber\Max\Y=NY+Rot:EndIf
Else
Len=Pow(Pow(*AMacro\Primitives()\CenterX,2)+Pow(*AMacro\Primitives()\CenterY,2),0.5)
AddPathCircle(*Position\X+Len*Cos(Radian(*AMacro\Primitives()\Rotation)),*Position\Y+Len*Sin(Radian(*AMacro\Primitives()\Rotation)),*AMacro\Primitives()\Diameter/2,0,360,#PB_Path_Default)
EndIf
Case #Gerber_MT_LineVector,#Gerber_MT_VectorLine;2,20
Select #Gerber_FillMode_Fill
Case #Gerber_FillMode_Outline
StrokePath(1,#PB_Path_Default)
Case #Gerber_FillMode_Fill
FillPath(#PB_Path_Winding)
EndSelect
If SizeMode
Len=Pow(Pow(*AMacro\Primitives()\StartX,2)+Pow(*AMacro\Primitives()\StartY,2),0.5)
Rot=ATan2(*AMacro\Primitives()\StartX,*AMacro\Primitives()\StartY)+Radian(*AMacro\Primitives()\Rotation)
NX=*Position\X+Len*Cos(Rot)
NY=*Position\Y+Len*Sin(Rot)
MovePathCursor(NX,NY,#PB_Path_Default)
If NX<*Gerber\Min\X:*Gerber\Min\X=NX:EndIf
If NX>*Gerber\Max\X:*Gerber\Max\X=NX:EndIf
If NY<*Gerber\Min\Y:*Gerber\Min\Y=NY:EndIf
If NY>*Gerber\Max\Y:*Gerber\Max\Y=NY:EndIf
Len=Pow(Pow(*AMacro\Primitives()\EndX,2)+Pow(*AMacro\Primitives()\EndY,2),0.5)
Rot=ATan2(*AMacro\Primitives()\EndX,*AMacro\Primitives()\EndY)+Radian(*AMacro\Primitives()\Rotation)
NX=*Position\X+Len*Cos(Rot)
NY=*Position\Y+Len*Sin(Rot)
AddPathLine(NX,NY,#PB_Path_Default)
If NX<*Gerber\Min\X:*Gerber\Min\X=NX:EndIf
If NX>*Gerber\Max\X:*Gerber\Max\X=NX:EndIf
If NY<*Gerber\Min\Y:*Gerber\Min\Y=NY:EndIf
If NY>*Gerber\Max\Y:*Gerber\Max\Y=NY:EndIf
Else
Len=Pow(Pow(*AMacro\Primitives()\StartX,2)+Pow(*AMacro\Primitives()\StartY,2),0.5)
Rot=ATan2(*AMacro\Primitives()\StartX,*AMacro\Primitives()\StartY)+Radian(*AMacro\Primitives()\Rotation)
MovePathCursor(*Position\X+Len*Cos(Rot),*Position\Y+Len*Sin(Rot),#PB_Path_Default)
Len=Pow(Pow(*AMacro\Primitives()\EndX,2)+Pow(*AMacro\Primitives()\EndY,2),0.5)
Rot=ATan2(*AMacro\Primitives()\EndX,*AMacro\Primitives()\EndY)+Radian(*AMacro\Primitives()\Rotation)
AddPathLine(*Position\X+Len*Cos(Rot),*Position\Y+Len*Sin(Rot),#PB_Path_Default)
EndIf
StrokePath(*AMacro\Primitives()\Width)
Case #Gerber_MT_Outline ;4
Len=Pow(Pow(*AMacro\Primitives()\StartX,2)+Pow(*AMacro\Primitives()\StartY,2),0.5)
Rot=ATan2(*AMacro\Primitives()\StartX,*AMacro\Primitives()\StartY)+Radian(*AMacro\Primitives()\Rotation)
MovePathCursor(*Position\X+Len*Cos(Rot),*Position\Y+Len*Sin(Rot),#PB_Path_Default)
ResetList(*AMacro\Primitives()\Vertices())
For Count=1 To *AMacro\Primitives()\VertexCount
NextElement(*AMacro\Primitives()\Vertices())
Len=Pow(Pow(*AMacro\Primitives()\Vertices()\X,2)+Pow(*AMacro\Primitives()\Vertices()\Y,2),0.5)
Rot=ATan2(*AMacro\Primitives()\Vertices()\X,*AMacro\Primitives()\Vertices()\Y)+Radian(*AMacro\Primitives()\Rotation)
AddPathLine(*Position\X+Len*Cos(Rot),*Position\Y+Len*Sin(Rot),#PB_Path_Default)
Next
Case #Gerber_MT_Polygon;5
Debug "Primitive ignored: Polygon"
Case #Gerber_MT_Moire ;6
Debug "Primitive ignored: Moire"
Case #Gerber_MT_Thermal;7
Debug "Primitive ignored: Thermal"
Case #Gerber_MT_CenterLine;21
Debug "Primitive ignored: CenterLine"
Case #Gerber_MT_LowerLeftLine;22
Debug "Primitive ignored: LowerLeftLine"
Default
Debug "Unbekanntes Primitive: "+Str(*AMacro\Primitives()\Type)
EndSelect
If *Gerber\FillMode=#Gerber_FillMode_Fill
DrawGerber(*Position)
EndIf
Next
EndProcedure
Procedure DrawAperture(*Aperture.Aperture,*Position.Pos,SizeMode.a,*Gerber.Gerber,*AMacro.AM=0)
Protected Counter.a,Part.d,Rad.d
MovePathCursor(*Position\X,*Position\Y,#PB_Path_Default)
Select *Aperture\Type
Case #Gerber_AT_Circle
Rad=*Aperture\Diameter/2
AddPathCircle(*Position\X,*Position\Y,Rad,0,360,#PB_Path_Default)
If *Aperture\InnerX>0
AddPathCircle(*Position\X,*Position\Y,Rad,0,360,#PB_Path_Default)
EndIf
If SizeMode
If *Position\X-Rad<*Gerber\Min\X:*Gerber\Min\X=*Position\X-Rad:EndIf
If *Position\X+Rad>*Gerber\Max\X:*Gerber\Max\X=*Position\X+Rad:EndIf
If *Position\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=*Position\Y-Rad:EndIf
If *Position\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=*Position\Y+Rad:EndIf
EndIf
Case #Gerber_AT_Rectangle
AddPathBox(-*Aperture\X/2,-*Aperture\Y/2,*Aperture\X,*Aperture\Y,#PB_Path_Relative)
Case #Gerber_AT_Obround
If *Aperture\X>*Aperture\Y
AddPathCircle(-(*Aperture\X-*Aperture\Y)/2,0,*Aperture\Y/2,90,270,#PB_Path_Relative)
AddPathLine(*Aperture\X-*Aperture\Y,0,#PB_Path_Relative)
AddPathCircle(0,*Aperture\Y/2,*Aperture\Y/2,270,90,#PB_Path_Relative)
AddPathLine(*Aperture\Y-*Aperture\X,0,#PB_Path_Relative)
Else
AddPathCircle(0,-(*Aperture\Y-*Aperture\X)/2,*Aperture\X/2,180,0,#PB_Path_Relative)
AddPathLine(0,*Aperture\Y-*Aperture\X,#PB_Path_Relative)
AddPathCircle(-*Aperture\X/2,0,*Aperture\X/2,0,180,#PB_Path_Relative)
AddPathLine(0,*Aperture\X-*Aperture\Y,#PB_Path_Relative)
EndIf
MovePathCursor(*Position\X,*Position\Y,#PB_Path_Default)
If *Aperture\InnerX
MovePathCursor(*Position\X,*Position\Y,#PB_Path_Default)
AddPathCircle(*Position\X,*Position\Y,*Aperture\InnerX,0,360,#PB_Path_Default)
EndIf
Case #Gerber_AT_Polygon
MovePathCursor(*Aperture\Diameter/2*Cos(Radian(-1**Aperture\Rotation)),*Aperture\Diameter/2*Sin(Radian(-1**Aperture\Rotation)),#PB_Path_Relative)
Part=360/*Aperture\Vertex
For Counter=0 To *Aperture\Vertex
*Position\X+*Aperture\Diameter/2*Cos(Radian(-1**Aperture\Rotation+Part*Counter))
*Position\Y+*Aperture\Diameter/2*Sin(Radian(-1**Aperture\Rotation+Part*Counter))
AddPathLine(*Position\X,*Position\Y)
Next
If *Aperture\InnerX>0
AddPathCircle(*Position\X,*Position\Y,*Aperture\InnerX,0,360,#PB_Path_Default)
EndIf
Case #Gerber_AT_ApertureMacro
DrawPrimitives(*AMacro,*Position,SizeMode,*Gerber)
Default
Debug "Aperture-Fehler (Type): "+Str(*Aperture\Type)
EndSelect
MovePathCursor(*Position\X,*Position\Y,#PB_Path_Default)
EndProcedure
Procedure PlotGerber(*Gerber.Gerber,SizeMode.a=#False)
Protected PlotMode.a,Counter.a,Temp$,Position.Pos,Aperture.s,NewPosition.Pos,Center.Pos,G75.a,GMode.a,Rad.d,OldPosition.Pos,G36.a
MovePathCursor(0,0)
Position\X=0:Position\Y=0
NewPosition\X=0:NewPosition\Y=0
ForEach *Gerber\Path()
If MatchRegularExpression(#Gerber_Command_SelectAperture,*Gerber\Path())
;{ Apertur einstellen
If ExamineRegularExpression(#Gerber_Command_SelectAperture,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_SelectAperture)
Aperture=RegularExpressionGroup(#Gerber_Command_SelectAperture,3)
GMode=#Gerber_GMode_Undefined
Else
PrintN("G54-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_D01,*Gerber\Path())
;{ Kommando D01, LINE
If ExamineRegularExpression(#Gerber_Command_D01,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_D01)
Movement(#Gerber_Command_D01)
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
DrawGerber(Position)
If SizeMode
If Position\X>*Gerber\Max\X:*Gerber\Max\X=Position\X:EndIf
If Position\X<*Gerber\Min\X:*Gerber\Min\X=Position\X:EndIf
If Position\Y>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y:EndIf
If Position\Y<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y:EndIf
EndIf
Else
PrintN("D01-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_D02,*Gerber\Path())
;{ Kommando D02, MOVE
If ExamineRegularExpression(#Gerber_Command_D02,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_D02)
Movement(#Gerber_Command_D02)
MovePathCursor(Position\X,Position\Y,#PB_Path_Default)
If SizeMode
If Position\X>*Gerber\Max\X:*Gerber\Max\X=Position\X:EndIf
If Position\X<*Gerber\Min\X:*Gerber\Min\X=Position\X:EndIf
If Position\Y>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y:EndIf
If Position\Y<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y:EndIf
EndIf
Else
PrintN("D02-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_D03,*Gerber\Path())
;{ Kommando D03, FLASH
If ExamineRegularExpression(#Gerber_Command_D03,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_D03)
Movement(#Gerber_Command_D03)
MovePathCursor(Position\X,Position\Y,#PB_Path_Default)
;AddPathLine(Position\X,Position\Y,#PB_Path_Default)
If *Gerber\Apertures(Aperture)\Type=#Gerber_AT_ApertureMacro
DrawAperture(*Gerber\Apertures(Aperture),Position,SizeMode,*Gerber,*Gerber\ApertureMacro(*Gerber\Apertures(Aperture)\ApertureMacro))
Else
DrawAperture(*Gerber\Apertures(Aperture),Position,SizeMode,*Gerber)
EndIf
Else
PrintN("D03-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_G01,*Gerber\Path())
;{ G01: Linear-Plot-Modus
If ExamineRegularExpression(#Gerber_Command_G01,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_G01)
If *Gerber\FillMode=#Gerber_FillMode_Fill
DrawGerber(Position)
EndIf
Movement(#Gerber_Command_G01)
Select RegularExpressionGroup(#Gerber_Command_G01,CountRegularExpressionGroups(#Gerber_Command_G01))
Case "01"
If *Gerber\FillMode=#Gerber_FillMode_Outline
Select *Gerber\Apertures(Aperture)\Type
Case #Gerber_AT_Circle
Rad=*Gerber\Apertures(Aperture)\Diameter/2
AddPathCircle(OldPosition\X,OldPosition\Y,Rad,0,360,#PB_Path_Default)
AddPathCircle(Position\X,Position\Y,Rad,0,360,#PB_Path_Default)
If SizeMode
If OldPosition\X-Rad<*Gerber\Min\X:*Gerber\Min\X=OldPosition\X-Rad:EndIf
If OldPosition\X+Rad>*Gerber\Max\X:*Gerber\Max\X=OldPosition\X+Rad:EndIf
If OldPosition\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=OldPosition\Y-Rad:EndIf
If OldPosition\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=OldPosition\Y+Rad:EndIf
If Position\X-Rad<*Gerber\Min\X:*Gerber\Min\X=Position\X-Rad:EndIf
If Position\X+Rad>*Gerber\Max\X:*Gerber\Max\X=Position\X+Rad:EndIf
If Position\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y-Rad:EndIf
If Position\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y+Rad:EndIf
EndIf
Case #Gerber_AT_Rectangle
AddPathBox(OldPosition\X-*Gerber\Apertures(Aperture)\X/2,OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2,*Gerber\Apertures(Aperture)\X,*Gerber\Apertures(Aperture)\Y,#PB_Path_Default)
AddPathBox(Position\X-*Gerber\Apertures(Aperture)\X/2,Position\Y-*Gerber\Apertures(Aperture)\Y/2,*Gerber\Apertures(Aperture)\X,*Gerber\Apertures(Aperture)\Y,#PB_Path_Default)
If SizeMode
If OldPosition\X-*Gerber\Apertures(Aperture)\X/2<*Gerber\Min\X:*Gerber\Min\X=OldPosition\X-*Gerber\Apertures(Aperture)\X/2:EndIf
If OldPosition\X+*Gerber\Apertures(Aperture)\X/2>*Gerber\Max\X:*Gerber\Max\X=OldPosition\X+*Gerber\Apertures(Aperture)\X/2:EndIf
If OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2<*Gerber\Min\Y:*Gerber\Min\Y=OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2:EndIf
If OldPosition\Y+*Gerber\Apertures(Aperture)\Y/2>*Gerber\Max\Y:*Gerber\Max\Y=OldPosition\Y+*Gerber\Apertures(Aperture)\Y/2:EndIf
If Position\X-*Gerber\Apertures(Aperture)\X/2<*Gerber\Min\X:*Gerber\Min\X=Position\X-*Gerber\Apertures(Aperture)\X/2:EndIf
If Position\X+*Gerber\Apertures(Aperture)\X/2>*Gerber\Max\X:*Gerber\Max\X=Position\X+*Gerber\Apertures(Aperture)\X/2:EndIf
If Position\Y-*Gerber\Apertures(Aperture)\Y/2<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y-*Gerber\Apertures(Aperture)\Y/2:EndIf
If Position\Y+*Gerber\Apertures(Aperture)\Y/2>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y+*Gerber\Apertures(Aperture)\Y/2:EndIf
EndIf
EndSelect
MovePathCursor(OldPosition\X,OldPosition\Y,#PB_Path_Default)
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
Else
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
If Not G36
Select *Gerber\Apertures(Aperture)\Type
Case #Gerber_AT_Circle,#Gerber_AT_Polygon
StrokePath(*Gerber\Apertures(Aperture)\Diameter,#PB_Path_Default|#PB_Path_RoundEnd)
Case #Gerber_AT_Rectangle
StrokePath(*Gerber\Apertures(Aperture)\X,#PB_Path_Default|#PB_Path_SquareEnd)
EndSelect
EndIf
EndIf
Case "02"
MovePathCursor(Position\X,Position\Y,#PB_Path_Default)
Default
Debug "G01-Error: "+*Gerber\Path()
EndSelect
GMode=#Gerber_GMode_G01
Else
PrintN("G01-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_G02,*Gerber\Path())
;{ G02: Kreismodus (im Uhrzeigersinn)
If ExamineRegularExpression(#Gerber_Command_G02,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_G02)
DrawGerber(Position)
NewPosition\X=Position\X
NewPosition\Y=Position\Y
Center\X=Position\X
Center\Y=Position\Y
For Counter=1 To CountRegularExpressionGroups(#Gerber_Command_G02)
Temp$=RegularExpressionGroup(#Gerber_Command_G02,Counter)
Select Left(Temp$,1)
Case "X"
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
NewPosition\X=ValD(Right(Temp$,Len(Temp$)-1))
Else
NewPosition\X=Position\X+ValD(Right(Temp$,Len(Temp$)-1))
EndIf
Case "Y"
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
NewPosition\Y=ValD(Right(Temp$,Len(Temp$)-1))
Else
NewPosition\Y=Position\Y+ValD(Right(Temp$,Len(Temp$)-1))
EndIf
Case "I"
Center\X=Position\X+ValD(Right(Temp$,Len(Temp$)-1))
Case "J"
Center\Y=Position\Y+ValD(Right(Temp$,Len(Temp$)-1))
EndSelect
Next
Rad=Pow(Pow(Center\X-Position\X,2)+Pow(Center\Y-Position\Y,2),0.5)
AddPathCircle(Center\X,Center\Y,Rad,Degree(ATan2(NewPosition\X-Center\X,NewPosition\Y-Center\Y)),Degree(ATan2(Position\X-Center\X,Position\Y-Center\Y)),#PB_Path_Default)
If SizeMode
If Center\X-Rad<*Gerber\Min\X:*Gerber\Min\X=Center\X-Rad:EndIf
If Center\X+Rad>*Gerber\Max\X:*Gerber\Max\X=Center\X+Rad:EndIf
If Center\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=Center\Y-Rad:EndIf
If Center\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=Center\Y+Rad:EndIf
EndIf
Position\X=NewPosition\X
Position\Y=NewPosition\Y
GMode=#Gerber_GMode_G02
If *Gerber\FillMode=#Gerber_FillMode_Fill
StrokePath(*Gerber\Apertures(Aperture)\Diameter,#PB_Path_RoundEnd)
Else
StrokePath(1,#PB_Path_RoundEnd)
EndIf
Else
PrintN("G02-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_Command_G03,*Gerber\Path())
;{ G03: Kreismodus (gegen den Uhrzeigersinn)
If ExamineRegularExpression(#Gerber_Command_G03,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_G03)
DrawGerber(Position)
NewPosition\X=Position\X
NewPosition\Y=Position\Y
Center\X=Position\X
Center\Y=Position\Y
For Counter=1 To CountRegularExpressionGroups(#Gerber_Command_G03)
Temp$=RegularExpressionGroup(#Gerber_Command_G03,Counter)
Select Left(Temp$,1)
Case "X"
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
NewPosition\X=ValD(Right(Temp$,Len(Temp$)-1))
Else
NewPosition\X=Position\X+ValD(Right(Temp$,Len(Temp$)-1))
EndIf
Case "Y"
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
NewPosition\Y=ValD(Right(Temp$,Len(Temp$)-1))
Else
NewPosition\Y=Position\Y+ValD(Right(Temp$,Len(Temp$)-1))
EndIf
Case "I"
Center\X=Position\X+ValD(Right(Temp$,Len(Temp$)-1))
Case "J"
Center\Y=Position\Y+ValD(Right(Temp$,Len(Temp$)-1))
EndSelect
Next
Rad=Pow(Pow(Center\X-Position\X,2)+Pow(Center\Y-Position\Y,2),0.5)
AddPathCircle(Center\X,Center\Y,Rad,Degree(ATan2(Position\X-Center\X,Position\Y-Center\Y)),Degree(ATan2(NewPosition\X-Center\X,NewPosition\Y-Center\Y)),#PB_Path_Default)
If SizeMode
If Center\X-Rad<*Gerber\Min\X:*Gerber\Min\X=Center\X-Rad:EndIf
If Center\X+Rad>*Gerber\Max\X:*Gerber\Max\X=Center\X+Rad:EndIf
If Center\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=Center\Y-Rad:EndIf
If Center\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=Center\Y+Rad:EndIf
EndIf
Position\X=NewPosition\X
Position\Y=NewPosition\Y
GMode=#Gerber_GMode_G03
If *Gerber\FillMode=#Gerber_FillMode_Fill
StrokePath(*Gerber\Apertures(Aperture)\Diameter,#PB_Path_RoundEnd)
Else
StrokePath(1,#PB_Path_RoundEnd)
EndIf
Else
PrintN("G03-Fehler: "+*Gerber\Path())
EndIf
;}
ElseIf *Gerber\Path()="G36"
;{ Begin Contour
DrawGerber(Position)
G36=#True
;}
ElseIf *Gerber\Path()="G37"
;{ End Contour
DrawGerber(Position)
G36=#False
;}
ElseIf MatchRegularExpression(#Gerber_Command_JustMove,*Gerber\Path())
;{ Nur bewegen (ggf. mit aktuellem GMode zeichnen)
If ExamineRegularExpression(#Gerber_Command_JustMove,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_JustMove)
Movement(#Gerber_Command_JustMove)
If G36
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
Else
Select GMode
Case #Gerber_GMode_G01
Select *Gerber\FillMode
Case #Gerber_FillMode_Outline
Select *Gerber\Apertures(Aperture)\Type
Case #Gerber_AT_Circle
Rad=*Gerber\Apertures(Aperture)\Diameter/2
AddPathCircle(OldPosition\X,OldPosition\Y,Rad,0,360,#PB_Path_Default)
AddPathCircle(Position\X,Position\Y,Rad,0,360,#PB_Path_Default)
If SizeMode
If OldPosition\X-Rad<*Gerber\Min\X:*Gerber\Min\X=OldPosition\X-Rad:EndIf
If OldPosition\X+Rad>*Gerber\Max\X:*Gerber\Max\X=OldPosition\X+Rad:EndIf
If OldPosition\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=OldPosition\Y-Rad:EndIf
If OldPosition\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=OldPosition\Y+Rad:EndIf
If Position\X-Rad<*Gerber\Min\X:*Gerber\Min\X=Position\X-Rad:EndIf
If Position\X+Rad>*Gerber\Max\X:*Gerber\Max\X=Position\X+Rad:EndIf
If Position\Y-Rad<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y-Rad:EndIf
If Position\Y+Rad>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y+Rad:EndIf
EndIf
Case #Gerber_AT_Rectangle
AddPathBox(OldPosition\X-*Gerber\Apertures(Aperture)\X/2,OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2,*Gerber\Apertures(Aperture)\X,*Gerber\Apertures(Aperture)\Y,#PB_Path_Default)
AddPathBox(Position\X-*Gerber\Apertures(Aperture)\X/2,Position\Y-*Gerber\Apertures(Aperture)\Y/2,*Gerber\Apertures(Aperture)\X,*Gerber\Apertures(Aperture)\Y,#PB_Path_Default)
If SizeMode
If OldPosition\X-*Gerber\Apertures(Aperture)\X/2<*Gerber\Min\X:*Gerber\Min\X=OldPosition\X-*Gerber\Apertures(Aperture)\X/2:EndIf
If OldPosition\X+*Gerber\Apertures(Aperture)\X/2>*Gerber\Max\X:*Gerber\Max\X=OldPosition\X+*Gerber\Apertures(Aperture)\X/2:EndIf
If OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2<*Gerber\Min\Y:*Gerber\Min\Y=OldPosition\Y-*Gerber\Apertures(Aperture)\Y/2:EndIf
If OldPosition\Y+*Gerber\Apertures(Aperture)\Y/2>*Gerber\Max\Y:*Gerber\Max\Y=OldPosition\Y+*Gerber\Apertures(Aperture)\Y/2:EndIf
If Position\X-*Gerber\Apertures(Aperture)\X/2<*Gerber\Min\X:*Gerber\Min\X=Position\X-*Gerber\Apertures(Aperture)\X/2:EndIf
If Position\X+*Gerber\Apertures(Aperture)\X/2>*Gerber\Max\X:*Gerber\Max\X=Position\X+*Gerber\Apertures(Aperture)\X/2:EndIf
If Position\Y-*Gerber\Apertures(Aperture)\Y/2<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y-*Gerber\Apertures(Aperture)\Y/2:EndIf
If Position\Y+*Gerber\Apertures(Aperture)\Y/2>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y+*Gerber\Apertures(Aperture)\Y/2:EndIf
EndIf
EndSelect
MovePathCursor(OldPosition\X,OldPosition\Y,#PB_Path_Default)
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
Case #Gerber_FillMode_Fill
DrawGerber(OldPosition)
AddPathLine(Position\X,Position\Y,#PB_Path_Default)
Select *Gerber\Apertures(Aperture)\Type
Case #Gerber_AT_Circle
StrokePath(*Gerber\Apertures(Aperture)\Diameter,#PB_Path_Default|#PB_Path_RoundEnd)
Case #Gerber_AT_Rectangle
StrokePath(*Gerber\Apertures(Aperture)\X,#PB_Path_Default|#PB_Path_SquareEnd)
EndSelect
EndSelect
Case #Gerber_GMode_G02
Debug "JustMove G02 ignoriert"
Case #Gerber_GMode_G03
Debug "JustMove G03 ignoriert"
Default
MovePathCursor(Position\X,Position\Y,#PB_Path_Default)
EndSelect
EndIf
EndIf
;}
ElseIf *Gerber\Path()="G75" Or *Gerber\Path()="G74"
;{ Umschaltung auf Umrissmodus (74 ist Single-Quadrant-Mode; eventuell anpassen, aber eigentlich obsolet)
VectorSourceColor($FF000000|*Gerber\ForegroundColor)
Select *Gerber\FillMode
Case #Gerber_FillMode_Outline
StrokePath(1,#PB_Path_Default)
Case #Gerber_FillMode_Fill
If G75
StrokePath(1,#PB_Path_Default)
Else
FillPath(#PB_Path_Winding)
EndIf
EndSelect
G75=#True
GMode=#Gerber_GMode_Undefined
;}
Else
Debug "Nicht verarbeitetes Kommando: "+*Gerber\Path()
EndIf
Next
DrawGerber(Position)
EndProcedure
Procedure PlotGerberToCanvas(Gadget.i,*Gerber.Gerber)
Protected Tick.q=ElapsedMilliseconds(),Size.Pos,NewPosition.Pos,Image.i
Image=CreateImage(#PB_Any,GadgetWidth(Gadget),GadgetHeight(Gadget),24,*Gerber\BackgroundColor)
StartVectorDrawing(ImageVectorOutput(Image))
Size\X=ImageWidth(Image)/(*Gerber\Max\X-*Gerber\Min\X)
Size\Y=ImageHeight(Image)/(*Gerber\Max\Y-*Gerber\Min\Y)
If Size\X>Size\Y:Size\X=Size\Y:EndIf
ScaleCoordinates(Size\X*0.98,Size\X*0.98,#PB_Coordinate_User)
TranslateCoordinates(-*Gerber\Min\X,*Gerber\Min\Y,#PB_Coordinate_User)
TranslateCoordinates(0.01*(*Gerber\Max\X-*Gerber\Min\X),0.01*(*Gerber\Max\Y-*Gerber\Min\Y),#PB_Coordinate_User)
FlipCoordinatesY((*Gerber\Max\Y-*Gerber\Min\Y)/2,#PB_Coordinate_User)
PlotGerber(*Gerber,#False)
StopDrawing()
StartDrawing(CanvasOutput(Gadget))
Box(0,0,GadgetWidth(Gadget),GadgetHeight(Gadget),*Gerber\BackgroundColor)
DrawImage(ImageID(Image),0,0)
StopDrawing()
FreeImage(Image)
*Gerber\LastDuration=ElapsedMilliseconds()-Tick
EndProcedure
Procedure CreateGerberDataFromString(Gerber$)
Protected Tick.q=ElapsedMilliseconds(),MacroName$,Temp$,PCount.l,PCounter.l,Counter.l,TCount.l,TCounter.l,ACount.l,ATemp$,ACounter.l,*Gerber.Gerber,Position.Pos,Image.i,Dim Out$(0),sum.a,count
Gerber$=ReplaceString(ReplaceString(ReplaceString(ReplaceString(Gerber$,#CR$,""),#LF$,""),#TAB$,"")," ","")
PCount=CountString(Gerber$,"%")+1
*Gerber=AllocateStructure(Gerber)
*Gerber\Min\X=Pow(10,9):*Gerber\Min\Y=Pow(10,9)
*Gerber\Max\X=-Pow(10,9):*Gerber\Max\Y=-Pow(10,9)
For PCounter=1 To PCount
Temp$=Trim(StringField(Gerber$,PCounter,"%"))
If Temp$<>""
AddElement(*Gerber\RawData())
*Gerber\RawData()=Temp$
EndIf
Next
ForEach *Gerber\RawData()
If MatchRegularExpression(#Gerber_RegEx_Header,*Gerber\RawData())
;{ Header einlesen
If ExamineRegularExpression(#Gerber_RegEx_Header,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Header)
Select RegularExpressionGroup(#Gerber_RegEx_Header,1);Ommited Zeros
Case "L"
*Gerber\OmittedZeros=#Gerber_OZ_Leading
Case "T"
*Gerber\OmittedZeros=#Gerber_OZ_Trailing
Case "D"
*Gerber\OmittedZeros=#Gerber_OZ_No
EndSelect
Select RegularExpressionGroup(#Gerber_RegEx_Header,2);Coordinate Mode
Case "A"
*Gerber\CoordinateMode=#Gerber_Coord_Absolute
Case "I"
*Gerber\CoordinateMode=#Gerber_Coord_Incremental
EndSelect
*Gerber\SequenceNumber=Val(RegularExpressionGroup(#Gerber_RegEx_Header,3))
*Gerber\PreparatoryFunctionCode=Val(RegularExpressionGroup(#Gerber_RegEx_Header,4))
*Gerber\X=Val(Left(RegularExpressionGroup(#Gerber_RegEx_Header,5),1))
*Gerber\Digits=Val(Right(RegularExpressionGroup(#Gerber_RegEx_Header,5),1))
*Gerber\Y=Val(Left(RegularExpressionGroup(#Gerber_RegEx_Header,6),1))
*Gerber\Z=Val(Left(RegularExpressionGroup(#Gerber_RegEx_Header,7),1))
*Gerber\DraftCode=Val(RegularExpressionGroup(#Gerber_RegEx_Header,8))
*Gerber\MiscCode=Val(RegularExpressionGroup(#Gerber_RegEx_Header,9))
*Gerber\Scaling=Pow(10,*Gerber\Digits)
Else
PrintN("Header fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Names,*Gerber\RawData())
;{ Names einlesen
If ExamineRegularExpression(#Gerber_RegEx_Names,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Names)
AddElement(*Gerber\Names())
*Gerber\Names()=RegularExpressionGroup(#Gerber_RegEx_Names,1)
Else
PrintN("Namenszeile fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Scaling,*Gerber\RawData())
;{ Scaling einlesen (mm oder Zoll)
If ExamineRegularExpression(#Gerber_RegEx_Scaling,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Scaling)
Select RegularExpressionGroup(#Gerber_RegEx_Scaling,1)
Case "IN"
*Gerber\Unit=#Gerber_Unit_Inch
Case "MM"
*Gerber\Unit=#Gerber_Unit_MM
EndSelect
Else
PrintN("Header Scalingzeile fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_ExposureMode,*Gerber\RawData())
;{ Exposuremode einlesen (positiv oder negativ)
If ExamineRegularExpression(#Gerber_RegEx_ExposureMode,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_ExposureMode)
Select RegularExpressionGroup(#Gerber_RegEx_ExposureMode,1)
Case "POS"
*Gerber\ExposureMode=#Gerber_EM_Positiv
Case "NEG"
*Gerber\ExposureMode=#Gerber_EM_Negativ
EndSelect
Else
PrintN("Exposuremode Zeile fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Macro,*Gerber\RawData())
;{ Apertur-Makros erstellen
If ExamineRegularExpression(#Gerber_RegEx_Macro,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Macro)
MacroName$=RegularExpressionGroup(#Gerber_RegEx_Macro,1)
ATemp$=Trim(RegularExpressionGroup(#Gerber_RegEx_Macro,2),"*")
ACount=CountString(ATemp$,"*")+1
For ACounter=1 To ACount
Temp$=StringField(ATemp$,ACounter,"*")
TCount=CountString(Temp$,",")+1
If Val(StringField(Temp$,1,","))<>0;Kommentare aussortieren
AddElement(*Gerber\ApertureMacro(MacroName$)\Primitives())
*Gerber\ApertureMacro(MacroName$)\Primitives()\Type=Val(StringField(Temp$,1,","))
Select *Gerber\ApertureMacro(MacroName$)\Primitives()\Type
Case #Gerber_MT_Circle
*Gerber\ApertureMacro(MacroName$)\Primitives()\Exposure=Val(StringField(Temp$,2,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\Diameter=ValD(StringField(Temp$,3,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterX=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterY=ValD(StringField(Temp$,5,","))**Gerber\Scaling
If TCount>5
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,6,","))**Gerber\Scaling
EndIf
Case #Gerber_MT_Outline
*Gerber\ApertureMacro(MacroName$)\Primitives()\Exposure=Val(StringField(Temp$,2,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\StartX=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\StartY=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\VertexCount=Val(StringField(Temp$,3,","))
For TCounter=1 To *Gerber\ApertureMacro(MacroName$)\Primitives()\VertexCount
AddElement(*Gerber\ApertureMacro(MacroName$)\Primitives()\Vertices())
*Gerber\ApertureMacro(MacroName$)\Primitives()\Vertices()\X=ValD(StringField(Temp$,4+2*TCounter,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Vertices()\Y=ValD(StringField(Temp$,5+2*TCounter,","))**Gerber\Scaling
Next
If TCount>5+2**Gerber\ApertureMacro(MacroName$)\Primitives()\VertexCount
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,6+2*ListSize(*Gerber\ApertureMacro(MacroName$)\Primitives()\Vertices()),","))**Gerber\Scaling
EndIf
Case #Gerber_MT_Polygon
*Gerber\ApertureMacro(MacroName$)\Primitives()\Exposure=Val(StringField(Temp$,2,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\VertexCount=Val(StringField(Temp$,3,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterX=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterY=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Diameter=ValD(StringField(Temp$,6,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,7,","))**Gerber\Scaling
Case #Gerber_MT_Thermal
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterX=ValD(StringField(Temp$,2,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterY=ValD(StringField(Temp$,3,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\OuterDiameter=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\InnerDiameter=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Gap=ValD(StringField(Temp$,6,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,7,","))**Gerber\Scaling
Case #Gerber_MT_VectorLine,#Gerber_MT_LineVector
*Gerber\ApertureMacro(MacroName$)\Primitives()\Exposure=Val(StringField(Temp$,2,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\Width=ValD(StringField(Temp$,3,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\StartX=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\StartY=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\EndX=ValD(StringField(Temp$,6,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\EndY=ValD(StringField(Temp$,7,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,8,","))**Gerber\Scaling
Case #Gerber_MT_CenterLine,#Gerber_MT_LowerLeftLine
*Gerber\ApertureMacro(MacroName$)\Primitives()\Exposure=Val(StringField(Temp$,2,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\Width=ValD(StringField(Temp$,3,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Height=ValD(StringField(Temp$,4,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterX=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterY=ValD(StringField(Temp$,6,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,7,","))**Gerber\Scaling
Case #Gerber_MT_Moire
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterX=ValD(StringField(Temp$,2,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CenterY=ValD(StringField(Temp$,3,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Diameter=Val(StringField(Temp$,4,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\RingThickness=ValD(StringField(Temp$,5,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Gap=ValD(StringField(Temp$,6,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\VertexCount=Val(StringField(Temp$,7,","))
*Gerber\ApertureMacro(MacroName$)\Primitives()\CrosshairThickness=ValD(StringField(Temp$,8,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\CrosshairLength=ValD(StringField(Temp$,9,","))**Gerber\Scaling
*Gerber\ApertureMacro(MacroName$)\Primitives()\Rotation=ValD(StringField(Temp$,10,","))**Gerber\Scaling
EndSelect
EndIf
Next
Else
PrintN("Apertur-Makro fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Apertures,*Gerber\RawData())
;{ Aperturen erstellen
If ExamineRegularExpression(#Gerber_RegEx_Apertures,*Gerber\RawData())
While NextRegularExpressionMatch(#Gerber_RegEx_Apertures)
ATemp$=RegularExpressionGroup(#Gerber_RegEx_Apertures,1)
Select RegularExpressionGroup(#Gerber_RegEx_Apertures,2)
Case "C"
*Gerber\Apertures(ATemp$)\Type=#Gerber_AT_Circle
Temp$=RegularExpressionGroup(#Gerber_RegEx_Apertures,3)
*Gerber\Apertures(ATemp$)\Diameter=ValD(StringField(Temp$,1,"X"))**Gerber\Scaling
Select CountString(Temp$,"X")
Case 1
*Gerber\Apertures(ATemp$)\InnerX=ValD(StringField(Temp$,2,"X"))**Gerber\Scaling
Case 2
*Gerber\Apertures(ATemp$)\InnerX=ValD(StringField(Temp$,2,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\InnerY=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
EndSelect
Case "R"
*Gerber\Apertures(ATemp$)\Type=#Gerber_AT_Rectangle
Temp$=RegularExpressionGroup(#Gerber_RegEx_Apertures,3)
*Gerber\Apertures(ATemp$)\X=ValD(StringField(Temp$,1,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\Y=ValD(StringField(Temp$,2,"X"))**Gerber\Scaling
Select CountString(Temp$,"X")
Case 2
*Gerber\Apertures(ATemp$)\Diameter=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
Case 3
*Gerber\Apertures(ATemp$)\InnerX=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\InnerY=ValD(StringField(Temp$,4,"X"))**Gerber\Scaling
EndSelect
Case "O"
*Gerber\Apertures(ATemp$)\Type=#Gerber_AT_Obround
Temp$=RegularExpressionGroup(#Gerber_RegEx_Apertures,3)
*Gerber\Apertures(ATemp$)\X=ValD(StringField(Temp$,1,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\Y=ValD(StringField(Temp$,2,"X"))**Gerber\Scaling
If CountString(Temp$,"X")=2
*Gerber\Apertures(Temp$)\InnerX=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
EndIf
Case "P"
*Gerber\Apertures(ATemp$)\Type=#Gerber_AT_Polygon
Temp$=RegularExpressionGroup(#Gerber_RegEx_Apertures,3)
*Gerber\Apertures(ATemp$)\X=ValD(StringField(Temp$,1,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\Vertex=Val(StringField(Temp$,2,"X"))
Select CountString(Temp$,"X")
Case 2
*Gerber\Apertures(ATemp$)\Rotation=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
Case 3
*Gerber\Apertures(ATemp$)\Rotation=ValD(StringField(Temp$,3,"X"))**Gerber\Scaling
*Gerber\Apertures(ATemp$)\InnerX=ValD(StringField(Temp$,4,"X"))**Gerber\Scaling
EndSelect
Default
*Gerber\Apertures(ATemp$)\Type=#Gerber_AT_ApertureMacro
*Gerber\Apertures(ATemp$)\ApertureMacro=RegularExpressionGroup(#Gerber_RegEx_Apertures,2)
If Not FindMapElement(*Gerber\ApertureMacro(),*Gerber\Apertures(ATemp$)\ApertureMacro)
Debug "Fehlendes Apertur-Makro: "+*Gerber\Apertures(ATemp$)\ApertureMacro
EndIf
EndSelect
Wend
Else
PrintN("Apertur fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_LeadPolarity,*Gerber\RawData())
;{ Lead Polarity (Dark/Clear)
If ExamineRegularExpression(#Gerber_RegEx_LeadPolarity,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_LeadPolarity)
Select RegularExpressionGroup(#Gerber_RegEx_LeadPolarity,1)
Case "D"
*Gerber\LeadPolarity=#Gerber_LeadPolarity_Dark
Case "C"
*Gerber\LeadPolarity=#Gerber_LeadPolarity_Clear
EndSelect
Else
PrintN("Header LeadPolarity fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Mirror,*Gerber\RawData())
;{ Mirror Image
If ExamineRegularExpression(#Gerber_RegEx_Mirror,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Mirror)
For ACount=1 To CountRegularExpressionGroups(#Gerber_RegEx_Mirror)
Temp$=RegularExpressionGroup(#Gerber_RegEx_Mirror,ACount)
Select Left(Temp$,1)
Case "A"
*Gerber\MirrorA=Val(Right(Temp$,1))
Case "B"
*Gerber\MirrorB=Val(Right(Temp$,1))
EndSelect
Next
Else
PrintN("Mirroring fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_ScaleFactor,*Gerber\RawData())
;{ ScaleFactor
If ExamineRegularExpression(#Gerber_RegEx_ScaleFactor,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_ScaleFactor)
For ACount=1 To CountRegularExpressionGroups(#Gerber_RegEx_ScaleFactor)
Temp$=RegularExpressionGroup(#Gerber_RegEx_ScaleFactor,ACount)
Select Left(Temp$,1)
Case "A"
*Gerber\ScaleFactorA=Val(Right(Temp$,Len(Temp$)-1))
Case "B"
*Gerber\ScaleFactorB=Val(Right(Temp$,Len(Temp$)-1))
EndSelect
Next
Else
PrintN("ScaleFactor fehlerhaft!")
EndIf
;}
ElseIf MatchRegularExpression(#Gerber_RegEx_Attributes,*Gerber\RawData())
;{ Attribute einlesen
If ExamineRegularExpression(#Gerber_RegEx_Attributes,*Gerber\RawData()) And NextRegularExpressionMatch(#Gerber_RegEx_Attributes)
*Gerber\Attributes(RegularExpressionGroup(#Gerber_RegEx_Attributes,1))=RegularExpressionGroup(#Gerber_RegEx_Attributes,2)
Else
PrintN("Attribut fehlerhaft!")
EndIf
;}
Else
;{ Renderpfad generieren
Select Left(*Gerber\RawData(),1)
Case "X","Y","G","D"
Temp$=Trim(*Gerber\RawData(),"*")
ACount=CountString(Temp$,"*")
If StringField(Temp$,ACount+1,"*")="M02"
For ACounter=1 To ACount
AddElement(*Gerber\Path())
If *Gerber\OmittedZeros=#Gerber_OZ_Trailing
ATemp$=StringField(Temp$,ACounter,"*")
sum=ExtractRegularExpression(#Gerber_RegEx_Omitter,ATemp$,Out$())
If sum>0
For count=0 To ArraySize(Out$())
If FindString(Out$(count),"-")
ATemp$=ReplaceString(ATemp$,Out$(count),LSet(Out$(count),2+*Gerber\X+*Gerber\Digits,"0"))
Else
ATemp$=ReplaceString(ATemp$,Out$(count),LSet(Out$(count),1+*Gerber\X+*Gerber\Digits,"0"))
EndIf
Next
EndIf
*Gerber\Path()=ATemp$
Else
*Gerber\Path()=StringField(Temp$,ACounter,"*")
EndIf
If ExamineRegularExpression(#Gerber_Command_PreprocessX,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_PreprocessX)
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
Position\X=ValD(RegularExpressionGroup(#Gerber_Command_PreprocessX,1))
Else
Position\X+ValD(RegularExpressionGroup(#Gerber_Command_PreprocessX,1))
EndIf
If Position\X>*Gerber\Max\X:*Gerber\Max\X=Position\X:EndIf
If Position\X<*Gerber\Min\X:*Gerber\Min\X=Position\X:EndIf
EndIf
If ExamineRegularExpression(#Gerber_Command_PreprocessY,*Gerber\Path()) And NextRegularExpressionMatch(#Gerber_Command_PreprocessY)
If *Gerber\CoordinateMode=#Gerber_Coord_Absolute
Position\Y=ValD(RegularExpressionGroup(#Gerber_Command_PreprocessY,1))
Else
Position\Y+ValD(RegularExpressionGroup(#Gerber_Command_PreprocessY,1))
EndIf
If Position\Y>*Gerber\Max\Y:*Gerber\Max\Y=Position\Y:EndIf
If Position\Y<*Gerber\Min\Y:*Gerber\Min\Y=Position\Y:EndIf
EndIf
Next
Else
PrintN("Plottersequenz ohne Ende gefunden!")
EndIf
Default
ConsoleColor(4,0)
PrintN("Unbekannt: "+Left(*Gerber\RawData(),25)+"...")
ConsoleColor(7,0)
EndSelect
;}
EndIf
Next
Image=CreateImage(#PB_Any,1,1)
StartVectorDrawing(ImageVectorOutput(Image))
PlotGerber(*Gerber,#True)
StopDrawing()
FreeImage(Image)
*Gerber\BoardSize\X=(*Gerber\Max\X-*Gerber\Min\X)/*Gerber\Scaling
*Gerber\BoardSize\Y=(*Gerber\Max\Y-*Gerber\Min\Y)/*Gerber\Scaling
If *Gerber\Unit=#Gerber_Unit_Inch
*Gerber\BoardSize\X=*Gerber\BoardSize\X*25.4
*Gerber\BoardSize\Y=*Gerber\BoardSize\Y*25.4
EndIf
*Gerber\LastDuration=ElapsedMilliseconds()-Tick
ProcedureReturn *Gerber
EndProcedure
Procedure CreateGerberDataFromFile(File$)
Protected File,Input$
File=ReadFile(#PB_Any,File$,#PB_Ascii|#PB_File_SharedRead)
If File
Input$=ReadString(file,#PB_File_IgnoreEOL)
CloseFile(File)
EndIf
If Input$<>""
ProcedureReturn CreateGerberDataFromString(Input$)
EndIf
EndProcedure
EndModule