示例#1
0
        static DrillGCode ParseGCode(GerberLineReader lineReader, GerberImage image)
        {
            DrillFileStats stats  = image.DrillStats;
            DrillGCode     result = DrillGCode.Unknown;
            int            length = 0;

            int value = lineReader.GetIntegerValue(ref length);

            if (length == 2)
            {
                switch (value)
                {
                case 0:
                    stats.G00++;
                    result = DrillGCode.Rout;
                    break;

                case 1:
                    stats.G01++;
                    result = DrillGCode.LinearMove;
                    break;

                case 2:
                    stats.G02++;
                    result = DrillGCode.ClockwiseMove;
                    break;

                case 3:
                    stats.G03++;
                    result = DrillGCode.CounterClockwiseMove;
                    break;

                case 5:
                    image.DrillStats.G05++;
                    result = DrillGCode.Drill;
                    break;

                case 90:
                    stats.G90++;
                    result = DrillGCode.Absolute;
                    break;

                case 91:
                    stats.G91++;
                    result = DrillGCode.Incrementle;
                    break;

                case 93:
                    stats.G93++;
                    result = DrillGCode.ZeroSet;
                    break;

                default:
                    stats.GUnknown++;
                    break;
                }
            }

            return(result);
        }
示例#2
0
        public GerberNet(GerberImage gerberImage, GerberNet currentNet, GerberLevel level, GerberNetState netState)
        {
            if (level != null)
            {
                Level = level;
            }

            else
            {
                Level = currentNet.Level;
            }

            if (netState != null)
            {
                NetState = netState;
            }

            else
            {
                NetState = currentNet.NetState;
            }

            Label = String.Empty;
            //IsSelected = false;
            gerberImage.GerberNetList.Add(this);
        }
示例#3
0
        }                                                   // Scale factor in the B axis (usually this is the Y axis)

        /// <summary>
        /// Creates a new gerber net state and intialize with defaults.
        /// </summary>
        public GerberNetState(GerberImage gerberImage)
        {
            Unit   = GerberUnit.Inch;
            ScaleA = 1.0;
            ScaleB = 1.0;
            gerberImage.NetStateList.Add(this);
        }
示例#4
0
        private static void AddFileToProject(GerberProject project, GerberImage parsedImage, string fullPathName, bool reloading)
        {
            int fileIndex           = project.FileInfo.Count - 1;
            int colorIndex          = 0;
            GerberVerifyError error = GerberVerifyError.ImageOK;

            //Debug.WriteLine("Integrity check on image....\n");
            error = parsedImage.GerberImageVerify();
            if (error != GerberVerifyError.ImageOK)
            {
                project.FileInfo.RemoveAt(fileIndex);   // Image has errors, remove it from the file list.
                if ((error & GerberVerifyError.MissingNetList) > 0)
                {
                    throw new GerberImageException("Missing image net list.");
                }

                if ((error & GerberVerifyError.MissingFormat) > 0)
                {
                    throw new GerberImageException("Missing format information in file.");
                }

                if ((error & GerberVerifyError.MissingApertures) > 0)
                {
                    throw new GerberImageException("Missing apertures/drill sizes.");
                }

                if ((error & GerberVerifyError.MissingImageInfo) > 0)
                {
                    throw new GerberImageException("Missing image information.");
                }
            }

            project.FileInfo[fileIndex].Image = parsedImage;
            if (reloading) // If reload, just exchange the image and return.
            {
                return;
            }

            project.FileInfo[fileIndex].FullPathName = fullPathName;
            project.FileInfo[fileIndex].FileName     = Path.GetFileName(fullPathName);
            colorIndex = defaultColorIndex % NumberOfDefaultColors;
            project.FileInfo[fileIndex].Color     = Color.FromArgb(defaultColors[colorIndex, 1], defaultColors[colorIndex, 2], defaultColors[colorIndex, 3]);
            project.FileInfo[fileIndex].Alpha     = defaultColors[colorIndex, 0];
            project.FileInfo[fileIndex].IsVisible = true;
            defaultColorIndex++;
        }
示例#5
0
        private static bool OpenImage(GerberProject project, string fullPathName, bool reloading, int index)
        {
            GerberImage parsedImage     = null;
            string      displayFileName = String.Empty;
            bool        success         = false;

            int numberOfAttributes = 0;
            List <GerberHIDAttribute> attributesList = null;

            if (Gerber.IsGerberRS427X(fullPathName))
            {
                parsedImage = Gerber.ParseGerber(fullPathName);
            }

            else if (Drill.IsDrillFile(fullPathName))
            {
                parsedImage = Drill.ParseDrillFile(fullPathName, attributesList, numberOfAttributes, reloading);
            }

            else
            {
                throw new GerberFileException("Unknown file format " + fullPathName);
            }

            if (parsedImage != null)
            {
                if (!reloading)
                {
                    project.FileInfo.Add(new GerberFileInformation());
                    AddFileToProject(project, parsedImage, fullPathName, reloading);
                }

                else
                {
                    AddFileToProject(project, parsedImage, fullPathName, reloading);
                }
            }

            return(success);
        }
示例#6
0
        }                                                        // The level name (NULL for none).

        /// <summary>
        /// Create a new Gerber Level.
        /// </summary>
        public GerberLevel(GerberImage gerberImage)
        {
            Knockout      = new GerberKnockout();
            StepAndRepeat = new GerberStepAndRepeat();
            Rotation      = 0.0;
            Polarity      = GerberPolarity.Dark;
            LevelName     = String.Empty;

            // If not the first then copy the previous level values into the new one.
            if (gerberImage.LevelList.Count > 0)
            {
                int previous = gerberImage.LevelList.Count - 1;
                this.LevelName     = gerberImage.LevelList[previous].LevelName;
                this.StepAndRepeat = gerberImage.LevelList[previous].StepAndRepeat;
                this.Polarity      = gerberImage.LevelList[previous].Polarity;
                this.Knockout      = gerberImage.LevelList[previous].Knockout;
                // Clear this boolean so we only draw the knockout once.
                this.Knockout.FirstInstance = false;
            }

            gerberImage.LevelList.Add(this);
        }
示例#7
0
        static GerberNet AddDrillHole(GerberImage image, DrillState drillState, GerberNet currentNet)
        {
            image.DrillStats.IncrementDrillCounter(drillState.CurrentTool);
            GerberNet newDrillNet = new GerberNet(image, currentNet, null, null);

            newDrillNet.BoundingBox = new BoundingBox();
            newDrillNet.StartX      = drillState.CurrentX;
            newDrillNet.StartY      = drillState.CurrentY;
            if (drillState.Unit == GerberUnit.Millimeter)
            {
                newDrillNet.StartX       /= 25.4;
                newDrillNet.StartY       /= 25.4;
                newDrillNet.NetState.Unit = GerberUnit.Inch;
            }

            newDrillNet.StopX         = newDrillNet.StartX - drillState.OriginX;
            newDrillNet.StopY         = newDrillNet.StartY - drillState.OriginY;
            newDrillNet.Aperture      = drillState.CurrentTool;
            newDrillNet.ApertureState = GerberApertureState.Flash;

            // Check if the aperture is set.
            if (image.ApertureArray[drillState.CurrentTool] == null)
            {
                return(newDrillNet);
            }

            newDrillNet.BoundingBox.Left   = newDrillNet.StartX - image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2;
            newDrillNet.BoundingBox.Right  = newDrillNet.StartX + image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2;
            newDrillNet.BoundingBox.Bottom = newDrillNet.StartY - image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2;
            newDrillNet.BoundingBox.Top    = newDrillNet.StartY + image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2;

            image.ImageInfo.MinX = Math.Min(image.ImageInfo.MinX, (newDrillNet.StartX - image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2));
            image.ImageInfo.MinY = Math.Min(image.ImageInfo.MinY, (newDrillNet.StartY - image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2));
            image.ImageInfo.MaxX = Math.Max(image.ImageInfo.MaxX, (newDrillNet.StartX + image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2));
            image.ImageInfo.MaxY = Math.Max(image.ImageInfo.MaxY, (newDrillNet.StartY + image.ApertureArray[drillState.CurrentTool].Parameters[0] / 2));

            return(newDrillNet);
        }
示例#8
0
        static void ParseCoordinate(GerberLineReader lineReader, char firstCharacter, GerberImage image, DrillState drillState)
        {
            if (drillState.CoordinateMode == DrillCoordinateMode.Absolute)
            {
                if (firstCharacter == 'X')
                {
                    drillState.CurrentX = GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                    if (lineReader.Read() == 'Y')
                    {
                        drillState.CurrentY = GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                    }

                    else
                    {
                        lineReader.Position--;
                    }
                }

                else
                {
                    drillState.CurrentY = GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                }
            }

            else
            {
                if (firstCharacter == 'X')
                {
                    drillState.CurrentX += GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                    if (lineReader.Read() == 'Y')
                    {
                        drillState.CurrentY += GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                    }
                }

                else
                {
                    drillState.CurrentY += GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                }
            }
        }
示例#9
0
        static int ParseTCode(GerberLineReader lineReader, string drillFileName, DrillState drillState, GerberImage image)
        {
            int            drillNumber;
            double         drillSize = 0.0;
            int            length    = 0;
            char           nextCharacter;
            bool           done         = false;
            DrillFileStats stats        = image.DrillStats;
            string         line         = String.Empty;
            string         errorMessage = String.Empty;

            nextCharacter = lineReader.Read();
            if (!Char.IsDigit(nextCharacter))
            {
                if (nextCharacter == 'C')
                {
                    lineReader.Position -= 2;
                    line = lineReader.ReadLineToEnd();
                    if (line == "TCST")
                    {
                        errorMessage = "Tool change stop switch found.";
                        stats.AddNewError(-1, errorMessage, GerberErrorType.GerberNote, lineReader.LineNumber, drillFileName);
                    }

                    return(-1);
                }
            }

            lineReader.Position--;
            drillNumber = lineReader.GetIntegerValue(ref length);
            // T00 is a tool unload command.
            if (drillNumber == 0)
            {
                return(drillNumber);
            }

            if (drillNumber < ToolMin && drillNumber >= ToolMax)
            {
                errorMessage = String.Format(CultureInfo.CurrentCulture, "Drill number out of bounds:{0}.\n", drillNumber);
                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberError, lineReader.LineNumber, drillFileName);
            }

            drillState.CurrentTool = drillNumber;

            // Tool definition following tool number.
            if (lineReader.Position > 0)
            {
                while (!done)
                {
                    nextCharacter = lineReader.Read();
                    switch (nextCharacter)
                    {
                    case 'C':
                        drillSize = GetDoubleValue(lineReader, drillState.HeaderNumberFormat, GerberOmitZero.OmitZerosTrailing, drillState.DecimalPlaces);
                        if (drillState.Unit == GerberUnit.Millimeter)
                        {
                            drillSize /= 25.4;
                        }

                        else if (drillSize >= 4.0)
                        {
                            drillSize /= 1000.0;
                        }

                        if (drillSize <= 0 || drillSize >= 10000)
                        {
                            errorMessage = "Unreasonable drill size found.";
                            stats.AddNewError(-1, errorMessage, GerberErrorType.GerberError, lineReader.LineNumber, drillFileName);
                        }

                        else
                        {
                            // Allow a redefinition of a tool only if all parameters are the same.
                            if (image.ApertureArray[drillNumber] != null)
                            {
                                if (image.ApertureArray[drillNumber].Parameters[0] != drillSize ||
                                    image.ApertureArray[drillNumber].ApertureType != GerberApertureType.Circle ||
                                    image.ApertureArray[drillNumber].ParameterCount != 1 ||
                                    image.ApertureArray[drillNumber].Unit != GerberUnit.Inch)
                                {
                                    errorMessage = String.Format(CultureInfo.CurrentCulture, "Found redefinition if drill {0}.\n", drillNumber);
                                    stats.AddNewError(-1, errorMessage, GerberErrorType.GerberError);
                                }
                            }

                            else
                            {
                                image.ApertureArray[drillNumber] = new ApertureDefinition();
                                image.ApertureArray[drillNumber].Parameters[0]  = drillSize;
                                image.ApertureArray[drillNumber].ApertureType   = GerberApertureType.Circle;
                                image.ApertureArray[drillNumber].ParameterCount = 1;
                                image.ApertureArray[drillNumber].Unit           = GerberUnit.Inch;
                            }
                        }

                        string drillUnit = (drillState.Unit == GerberUnit.Millimeter) ? "MM" : "INCH";
                        stats.AddToDrillList(drillNumber, (drillState.Unit == GerberUnit.Millimeter) ? drillSize * 25.4 : drillSize, drillUnit);
                        break;

                    case 'F':
                    case 'S':
                        lineReader.GetIntegerValue(ref length);
                        break;

                    default:
                        lineReader.Position--;
                        done = true;
                        break;
                    }
                }
            }

            return(drillNumber);
        }
示例#10
0
        static DrillMCode ParseMCode(GerberLineReader lineReader, DrillState drillState, GerberImage image)
        {
            DrillFileStats stats  = image.DrillStats;
            DrillMCode     result = DrillMCode.Unknown;
            int            length = 0;
            string         line   = String.Empty;

            int value = lineReader.GetIntegerValue(ref length);

            switch (value)
            {
            case 0:
                stats.M00++;
                result = DrillMCode.End;
                break;

            case 1:
                stats.M01++;
                result = DrillMCode.EndPattern;
                break;

            case 18:
                stats.M18++;
                result = DrillMCode.TipCheck;
                break;

            case 25:
                stats.M25++;
                result = DrillMCode.BeginPattern;
                break;

            case 30:
                stats.M30++;
                result = DrillMCode.EndRewind;
                break;

            case 31:
                stats.M31++;
                result = DrillMCode.BeginPattern;
                break;

            case 45:
                stats.M45++;
                result = DrillMCode.LongMessage;
                break;

            case 47:
                stats.M47++;
                result = DrillMCode.Message;
                break;

            case 48:
                stats.M48++;
                result = DrillMCode.Header;
                break;

            case 71:
                stats.M71++;
                result = DrillMCode.Metric;
                break;

            case 72:
                stats.M72++;
                result = DrillMCode.Imperial;
                break;

            case 95:
                stats.M95++;
                result = DrillMCode.EndHeader;
                break;

            case 97:
                stats.M97++;
                result = DrillMCode.CannedText;
                break;

            case 98:
                stats.M98++;
                result = DrillMCode.CannedText;
                break;

            default:
                stats.MUnknown++;
                break;
            }

            return(result);
        }
示例#11
0
        private static List <GerberHIDAttribute> drillAttributeList = new List <GerberHIDAttribute>(); /* <---- NOT SURE IF WE NEED THIS.*/

        public static GerberImage ParseDrillFile(string drillFileName, List <GerberHIDAttribute> attributeList, int numberOfAttributes, bool reload)
        {
            bool        foundEOF     = false;
            string      errorMessage = String.Empty;
            DrillState  drillState   = new DrillState();
            GerberImage image        = new GerberImage("Excellon Drill File");

            CreateDefaultAttributeList();
            if (reload & attributeList != null)
            {
                image.ImageInfo.NumberOfAttribute = numberOfAttributes;
                image.ImageInfo.AttributeList     = new List <GerberHIDAttribute>();
                for (int i = 0; i < numberOfAttributes; i++)
                {
                    GerberHIDAttribute attribute = new GerberHIDAttribute(attributeList[i]);
                    image.ImageInfo.AttributeList.Add(attribute);
                }
            }

            else
            {
                // Load default attributes.
                image.ImageInfo.NumberOfAttribute = drillAttributeList.Count;
                image.ImageInfo.AttributeList     = new List <GerberHIDAttribute>();
                for (int i = 0; i < image.ImageInfo.NumberOfAttribute; i++)
                {
                    GerberHIDAttribute attribute = new GerberHIDAttribute(drillAttributeList[i]);
                    image.ImageInfo.AttributeList.Add(attribute);
                }
            }

            DrillAttributeMerge(image.ImageInfo.AttributeList, image.ImageInfo.NumberOfAttribute, attributeList, numberOfAttributes);
            image.FileType         = GerberFileType.Drill;
            image.DrillStats       = new DrillFileStats();
            image.Format           = new GerberFormat();
            image.Format.OmitZeros = GerberOmitZero.OmitZerosUnspecified;

            if (image.ImageInfo.AttributeList[(int)HA.AutoDetect].DefaultValue.IntValue > 0)
            {
                drillState.AutoDetect       = false;
                drillState.DataNumberFormat = DrillNumberFormat.UserDefined;
                drillState.DecimalPlaces    = image.ImageInfo.AttributeList[(int)HA.Digits].DefaultValue.IntValue;
                if (image.ImageInfo.AttributeList[(int)HA.ZeroSuppression].DefaultValue.IntValue == (int)Units.Millimeters)
                {
                    drillState.Unit = GerberUnit.Millimeter;
                }

                switch (image.ImageInfo.AttributeList[(int)HA.ZeroSuppression].DefaultValue.IntValue)
                {
                case (int)ZeroSuppression.Leading:
                    image.Format.OmitZeros = GerberOmitZero.OmitZerosLeading;
                    break;

                case (int)ZeroSuppression.Trailing:
                    image.Format.OmitZeros = GerberOmitZero.OmitZerosTrailing;
                    break;

                default:
                    image.Format.OmitZeros = GerberOmitZero.OmitZerosExplicit;
                    break;
                }
            }

            //Debug.WriteLine(String.Format("Starting to parse drill file {0}", drillFileName));

            using (StreamReader drillFileStream = new StreamReader(drillFileName, Encoding.ASCII))
            {
                GerberLineReader lineReader = new GerberLineReader(drillFileStream);
                foundEOF = ParseDrillSegment(drillFileName, lineReader, image, drillState);
            }

            if (!foundEOF)
            {
                errorMessage = String.Format(CultureInfo.CurrentCulture, "File {0} is missing Excellon Drill EOF code./n", drillFileName);
                image.DrillStats.AddNewError(-1, errorMessage, GerberErrorType.GerberError);
            }

            //Debug.WriteLine("... done parsing Excellon Drill file.");
            return(image);
        }
示例#12
0
        static bool ParseDrillSegment(string drillFileName, GerberLineReader lineReader, GerberImage image, DrillState drillState)
        {
            bool           foundEOF   = false;
            DrillFileStats stats      = image.DrillStats;
            GerberNet      currentNet = image.GerberNetList[0];

            currentNet.Level    = image.LevelList[0];
            currentNet.NetState = image.NetStateList[0];

            bool   done = false;
            string line;

            string[] command;
            string   errorMessage;
            char     nextCharacter;

            while (!lineReader.EndOfFile && !foundEOF)
            {
                nextCharacter = lineReader.Read();
                switch (nextCharacter)
                {
                case ';':       // Comment.
                    line = lineReader.ReadLineToEnd();
                    break;

                case 'D':
                    lineReader.Position--;
                    line = lineReader.ReadLineToEnd();
                    if (line.Substring(0, 6) == "DETECT")
                    {
                        stats.Detect = line.Substring(6, (line.Length - 7));
                    }

                    else
                    {
                        errorMessage = String.Format(CultureInfo.CurrentCulture, "Undefined header line: {0}.\n", line);
                        stats.AddNewError(-1, errorMessage, GerberErrorType.GerberNote, lineReader.LineNumber, drillFileName);
                    }
                    break;

                case 'F':
                    lineReader.Position--;
                    line = lineReader.ReadLineToEnd();
                    if (line != "FMAT,2")
                    {
                        errorMessage = String.Format(CultureInfo.CurrentCulture, "Undefined header line: {0}.\n", line);
                        stats.AddNewError(-1, errorMessage, GerberErrorType.GerberNote, lineReader.LineNumber, drillFileName);
                    }
                    break;

                case 'G':
                    DrillGCode gCode = ParseGCode(lineReader, image);
                    switch (gCode)
                    {
                    case DrillGCode.Rout:
                        errorMessage = "Rout Mode not supported.\n";
                        stats.AddNewError(-1, errorMessage, GerberErrorType.GerberNote, lineReader.LineNumber, drillFileName);
                        break;

                    case DrillGCode.Drill:
                        break;

                    case DrillGCode.Slot:
                        nextCharacter = lineReader.Read();
                        ParseCoordinate(lineReader, nextCharacter, image, drillState);
                        currentNet.StopX = drillState.CurrentX;
                        currentNet.StopY = drillState.CurrentY;
                        if (drillState.Unit == GerberUnit.Millimeter)
                        {
                            currentNet.StopX /= 25.4;
                            currentNet.StopY /= 25.4;
                        }

                        currentNet.ApertureState = GerberApertureState.On;
                        break;

                    case DrillGCode.Absolute:
                        drillState.CoordinateMode = DrillCoordinateMode.Absolute;
                        break;

                    case DrillGCode.Incrementle:
                        drillState.CoordinateMode = DrillCoordinateMode.Incremental;
                        break;

                    case DrillGCode.ZeroSet:
                        nextCharacter = lineReader.Read();
                        ParseCoordinate(lineReader, nextCharacter, image, drillState);
                        drillState.OriginX = drillState.CurrentX;
                        drillState.OriginY = drillState.CurrentY;
                        break;

                    default:
                        line = lineReader.ReadLineToEnd();
                        break;
                    }

                    break;

                case 'I':       // Inch header.
                    if (drillState.CurrentSection != DrillFileSection.Header)
                    {
                        break;
                    }

                    nextCharacter = lineReader.Read();
                    switch (nextCharacter)
                    {
                    // Inch
                    case 'N':
                        lineReader.Position -= 2;
                        line    = lineReader.ReadLineToEnd();
                        command = line.Split(',');
                        if (command[0] == "INCH")
                        {
                            drillState.Unit = GerberUnit.Inch;
                        }

                        if (command.Length == 2)
                        {
                            if (command[1] == "TZ")
                            {
                                if (drillState.AutoDetect)
                                {
                                    image.Format.OmitZeros        = GerberOmitZero.OmitZerosLeading;
                                    drillState.HeaderNumberFormat = DrillNumberFormat.Format_00_0000;
                                    drillState.DecimalPlaces      = 4;
                                }
                            }

                            else if (command[1] == "LZ")
                            {
                                image.Format.OmitZeros        = GerberOmitZero.OmitZerosTrailing;
                                drillState.HeaderNumberFormat = DrillNumberFormat.Format_00_0000;
                                drillState.DecimalPlaces      = 4;
                            }

                            else
                            {
                                errorMessage = "Invalid zero suppression found after INCH.\n";
                                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning, lineReader.LineNumber, drillFileName);
                            }
                        }

                        else
                        {
                            // No TZ/LZ specified, use defaults.
                            if (drillState.AutoDetect)
                            {
                                image.Format.OmitZeros        = GerberOmitZero.OmitZerosLeading;
                                drillState.HeaderNumberFormat = DrillNumberFormat.Format_00_0000;
                                drillState.DecimalPlaces      = 4;
                            }
                        }

                        break;

                    case 'C':
                        lineReader.Position -= 2;
                        line    = lineReader.ReadLineToEnd();
                        command = line.Split(',');
                        if (command.Length == 2)
                        {
                            if (command[1] == "ON")
                            {
                                drillState.CoordinateMode = DrillCoordinateMode.Incremental;
                            }

                            else if (command[1] == "OFF")
                            {
                                drillState.CoordinateMode = DrillCoordinateMode.Absolute;
                            }

                            else
                            {
                                errorMessage = "Invalid coordinate data found.\n";
                                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning, lineReader.LineNumber, drillFileName);
                            }
                        }

                        else
                        {
                            errorMessage = "Invalid data found.\n";
                            stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning, lineReader.LineNumber, drillFileName);
                        }

                        break;
                    }

                    break;

                case 'M':                             // M code or Metric
                    nextCharacter = lineReader.Read();
                    if (!Char.IsDigit(nextCharacter)) // Not a M## command.
                    {
                        // Should be a metric command in header.
                        // METRIC is only acceptable within the header section.
                        // The syntax is METRIC[,{TZ|LZ}][,{000.000|000.00|0000.00}] ??????
                        if (drillState.CurrentSection != DrillFileSection.Header)
                        {
                            break;
                        }

                        done = true;
                        lineReader.Position -= 2;       // Point back to the start on the line.
                        line    = lineReader.ReadLineToEnd();
                        command = line.Split(',');
                        if (command[0] == "METRIC")
                        {
                            drillState.Unit = GerberUnit.Millimeter;
                        }

                        if (command.Length > 1)
                        {
                            if (command[1] == "TZ")
                            {
                                if (drillState.AutoDetect)
                                {
                                    image.Format.OmitZeros = GerberOmitZero.OmitZerosLeading;
                                }

                                done = false;
                            }

                            else if (command[1] == "LZ")
                            {
                                if (drillState.AutoDetect)
                                {
                                    image.Format.OmitZeros = GerberOmitZero.OmitZerosTrailing;
                                }

                                done = false;
                            }

                            else
                            {
                                errorMessage = "Invalid zero suppression found after METRIC.\n";
                                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning, lineReader.LineNumber, drillFileName);
                                done = true;
                            }

                            // Number format may or may not be specified.
                            if (!done && command.Length == 3)
                            {
                                if (drillState.AutoDetect)
                                {
                                    drillState.HeaderNumberFormat = drillState.DataNumberFormat = DrillNumberFormat.Format_000_000;
                                    drillState.DecimalPlaces      = 3;
                                }

                                if (command[2] == "0000.00")
                                {
                                    drillState.DataNumberFormat = DrillNumberFormat.Format_0000_00;
                                    drillState.DecimalPlaces    = 2;
                                }

                                else if (command[2] == "000.000")
                                {
                                    drillState.DataNumberFormat = DrillNumberFormat.Format_000_000;
                                    drillState.DecimalPlaces    = 3;
                                }

                                else if (command[2] == "000.00")
                                {
                                    drillState.DataNumberFormat = DrillNumberFormat.Format_000_00;
                                    drillState.DecimalPlaces    = 2;
                                }

                                else
                                {
                                    errorMessage = "Invalid number format found after TZ/LZ.\n";
                                    stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning, lineReader.LineNumber, drillFileName);
                                }
                            }
                        }

                        else
                        {
                            // No TZ/LZ or number format specified, use defaults.
                            if (drillState.AutoDetect)
                            {
                                image.Format.OmitZeros        = GerberOmitZero.OmitZerosLeading;
                                drillState.HeaderNumberFormat = DrillNumberFormat.Format_000_000;
                                drillState.DecimalPlaces      = 3;
                            }
                        }
                    }

                    else if (Char.IsDigit(nextCharacter))
                    {
                        // Must be an M## code.
                        lineReader.Position--;
                        DrillMCode mCode = ParseMCode(lineReader, drillState, image);
                        switch (mCode)
                        {
                        case DrillMCode.Header:
                            drillState.CurrentSection = DrillFileSection.Header;
                            break;

                        case DrillMCode.EndHeader:
                            drillState.CurrentSection = DrillFileSection.Data;
                            break;

                        case DrillMCode.Metric:
                            if (drillState.Unit == GerberUnit.Unspecified && drillState.CurrentSection != DrillFileSection.Header)
                            {
                                errorMessage = "M71 code found with no METRIC specification in header.\n";
                                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberError, lineReader.LineNumber, drillFileName);

                                errorMessage = "Assuming all tool sizes are in millimeters.\n";
                                stats.AddNewError(-1, errorMessage, GerberErrorType.GerberWarning);


                                for (int toolNumber = ToolMin; toolNumber < ToolMax; toolNumber++)
                                {
                                    if (image.ApertureArray[toolNumber] != null)
                                    {
                                        double toolSize = image.ApertureArray[toolNumber].Parameters[0];
                                        stats.ModifyDrillList(toolNumber, toolSize, "MM");
                                        image.ApertureArray[toolNumber].Parameters[0] /= 25.4;
                                    }
                                }
                            }

                            if (drillState.AutoDetect)
                            {
                                drillState.DataNumberFormat = drillState.BackupNumberFormat;
                                drillState.Unit             = GerberUnit.Millimeter;
                            }

                            break;

                        case DrillMCode.Imperial:
                            if (drillState.AutoDetect)
                            {
                                if (drillState.DataNumberFormat != DrillNumberFormat.Format_00_0000)
                                {
                                    drillState.BackupNumberFormat = drillState.DataNumberFormat;            // Save format definition for later.
                                }
                                drillState.DataNumberFormat = DrillNumberFormat.Format_00_0000;
                                drillState.DecimalPlaces    = 4;
                                drillState.Unit             = GerberUnit.Inch;
                            }
                            break;

                        case DrillMCode.LongMessage:
                        case DrillMCode.Message:
                        case DrillMCode.CannedText:
                            line = lineReader.ReadLineToEnd();
                            // message here.
                            break;

                        case DrillMCode.NotImplemented:
                        case DrillMCode.EndPattern:
                        case DrillMCode.TipCheck:
                            break;

                        case DrillMCode.End:
                            line = lineReader.ReadLineToEnd();
                            break;

                        case DrillMCode.EndRewind:          // EOF.
                            //done = true;
                            foundEOF = true;
                            break;

                        default:
                            stats.AddNewError(-1, "Undefined M code.", GerberErrorType.GerberError, lineReader.LineNumber, drillFileName);
                            break;
                        }
                    }
                    break;

                case 'R':
                    if (drillState.CurrentSection == DrillFileSection.Header)
                    {
                        stats.AddNewError(-1, "R code not allowed in the header.", GerberErrorType.GerberError, lineReader.LineNumber, drillFileName);
                    }

                    else
                    {
                        double stepX = 0.0, stepY = 0.0;
                        int    length = 0;

                        image.DrillStats.R++;
                        double startX      = drillState.CurrentX;
                        double startY      = drillState.CurrentY;
                        int    repeatcount = lineReader.GetIntegerValue(ref length);
                        nextCharacter = lineReader.Read();
                        if (nextCharacter == 'X')
                        {
                            stepX         = GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                            nextCharacter = lineReader.Read();
                        }

                        if (nextCharacter == 'Y')
                        {
                            stepY = GetDoubleValue(lineReader, drillState.DataNumberFormat, image.Format.OmitZeros, drillState.DecimalPlaces);
                        }

                        else
                        {
                            lineReader.Position--;
                        }

                        for (int i = 1; i < repeatcount; i++)
                        {
                            drillState.CurrentX = startX + i * stepX;
                            drillState.CurrentY = startY + i * stepY;
                            currentNet          = AddDrillHole(image, drillState, currentNet);
                        }
                    }
                    break;

                case 'S':
                    // Ignore spindle speed.
                    lineReader.ReadLineToEnd();
                    break;

                case 'T':
                    int tool = ParseTCode(lineReader, drillFileName, drillState, image);
                    break;

                case 'X':
                case 'Y':
                    // Hole coordinate found. Do some parsing.
                    ParseCoordinate(lineReader, nextCharacter, image, drillState);

                    // Add the new drill hole.
                    currentNet = AddDrillHole(image, drillState, currentNet);
                    break;

                case '%':
                    drillState.CurrentSection = DrillFileSection.Data;
                    break;

                // Ignore white space or null characters.
                case '\n':
                case '\r':
                case ' ':
                case '\t':
                case '\0':
                    break;
                }
            }

            return(foundEOF);
        }
示例#13
0
        /// <summary>
        /// Adds a gerber object to the selection buffer if it lies within the selection region.
        /// </summary>
        /// <param name="selectionInfo">current selection info</param>
        /// <param name="image">gerber image containing the net</param>
        /// <param name="net">net to add to the selection info</param>
        public void ObjectInSelectedRegion(SelectionInformation selectionInfo, ref int i, Graphics graphics)
        {
            bool        inSelect = false;
            GerberImage image    = selectionInfo.SelectionImage;
            GerberNet   net      = image.GerberNetList[i];
            float       x1       = (float)selectionInfo.LowerLeftX;
            float       y1       = (float)selectionInfo.LowerLeftY;
            float       x2       = (float)selectionInfo.UpperRightX;
            float       y2       = (float)selectionInfo.UpperRightY;

            if (selectionInfo.SelectionType == GerberSelection.PointClick)
            {
                if (net.BoundingBox != null)
                {
                    if (!net.BoundingBox.Contains(new PointD(x1, y1)))
                    {
                        return;
                    }

                    if (net.ApertureState == GerberApertureState.Flash)
                    {
                        inSelect = net.BoundingBox.Contains(new PointD(x1, y1));
                    }

                    else if (net.ApertureState == GerberApertureState.On)
                    {
                        switch (net.Interpolation)
                        {
                        case GerberInterpolation.PolygonAreaStart:
                            inSelect = net.BoundingBox.Contains(new PointD(x1, y1));
                            break;

                        case GerberInterpolation.LinearX10:
                        case GerberInterpolation.LinearX1:
                        case GerberInterpolation.LinearX01:
                        case GerberInterpolation.LinearX001:
                            using (GraphicsPath gp = new GraphicsPath())
                                using (Pen pen = new Pen(Color.Transparent))
                                {
                                    pen.Width    = (float)image.ApertureArray[net.Aperture].Parameters[0];
                                    pen.StartCap = pen.EndCap = LineCap.Round;
                                    PointF start = new PointF((float)(net.StartX), (float)(net.StartY));
                                    PointF end   = new PointF((float)(net.StopX), (float)(net.StopY));
                                    gp.AddLine(start, end);
                                    if (gp.IsOutlineVisible(new PointF(x1, y1), pen, graphics))
                                    {
                                        inSelect = true;
                                    }

                                    break;
                                }

                        case GerberInterpolation.ClockwiseCircular:
                        case GerberInterpolation.CounterClockwiseCircular:
                            using (GraphicsPath gp = new GraphicsPath())
                                using (Pen pen = new Pen(Color.Transparent))
                                {
                                    float centerX    = (float)net.CircleSegment.CenterX;
                                    float centerY    = (float)net.CircleSegment.CenterY;
                                    float width      = (float)net.CircleSegment.Width;
                                    float height     = (float)net.CircleSegment.Height;
                                    float startAngle = (float)net.CircleSegment.StartAngle;
                                    float sweepAngle = (float)net.CircleSegment.SweepAngle;
                                    if (image.ApertureArray[net.Aperture].ApertureType == GerberApertureType.Rectangle)
                                    {
                                        pen.StartCap = pen.EndCap = LineCap.Square;
                                    }

                                    else
                                    {
                                        pen.StartCap = pen.EndCap = LineCap.Round;
                                    }

                                    RectangleF arcRectangle = new RectangleF(centerX - (width / 2), centerY - (height / 2), width, height);
                                    pen.Width = width;

                                    gp.AddArc(arcRectangle, startAngle, sweepAngle);
                                    if (gp.IsOutlineVisible(new PointF(x1, y1), pen, graphics))
                                    {
                                        inSelect = true;
                                    }
                                }
                            break;
                        }
                    }
                }
            }

            else if (selectionInfo.SelectionType == GerberSelection.DragBox)
            {
                if (net.BoundingBox != null)
                {
                    double left   = Math.Min(selectionInfo.LowerLeftX, selectionInfo.UpperRightX);
                    double right  = Math.Max(selectionInfo.LowerLeftX, selectionInfo.UpperRightX);
                    double top    = Math.Min(selectionInfo.LowerLeftY, selectionInfo.UpperRightY);
                    double bottom = Math.Max(selectionInfo.LowerLeftY, selectionInfo.UpperRightY);

                    BoundingBox box = new BoundingBox(left, bottom, right, top);
                    if (!box.Contains(net.BoundingBox))
                    {
                        return;
                    }

                    if (net.ApertureState == GerberApertureState.Flash)
                    {
                        inSelect = box.Contains(net.BoundingBox);
                    }

                    else if (net.ApertureState == GerberApertureState.On)
                    {
                        inSelect = box.Contains(net.BoundingBox);
                    }
                }
            }

            if (inSelect)
            {
                selectionInfo.SelectedNetList.Add(net);
                selectionInfo.SelectionCount++;
                if (net.Interpolation == GerberInterpolation.PolygonAreaStart)  // Add all the poly points.
                {
                    do
                    {
                        i++;
                        net = image.GerberNetList[i];
                        selectionInfo.SelectedNetList.Add(net);
                    } while (net.Interpolation != GerberInterpolation.PolygonAreaEnd);
                }
            }
        }
示例#14
0
        // Renders a gerber image to the specified graphics target.
        private static void RenderToTarget(Graphics graphics, GerberImage gerberImage, Collection <GerberNet> gerberNetList, GerberUserTransform userTransform,
                                           Color foreGroundColor, Color backGroundColor, bool invert)
        {
            float dx, dy;
            float startX, startY, stopX, stopY;
            float p1, p2, p3, p4, p5;
            int   repeatX = 1, repeatY = 1;
            float repeatDistanceX = 0.0f, repeatDistanceY = 0.0f;

            Collection <SimplifiedApertureMacro> simplifiedMacroList;
            PointF     startPoint, endPoint;
            RectangleF apertureRectangle;

            int            netListIndex     = 0;
            GerberNet      currentNet       = null;
            GerberLevel    oldLevel         = null;
            GerberNetState oldState         = null;
            bool           useClearOperator = false;
            bool           invertPolarity   = false;

            SolidBrush brush = new SolidBrush(foreGroundColor);
            Pen        pen   = new Pen(foreGroundColor);

            // Apply user supplied transforations.
            double scaleX = userTransform.ScaleX;
            double scaleY = userTransform.ScaleY;

            if (userTransform.MirrorAroundX)
            {
                scaleY *= -1;
            }

            if (userTransform.MirrorAroundY)
            {
                scaleX *= -1;
            }

            graphics.TranslateTransform((float)userTransform.TranslateX, (float)userTransform.TranslateY);
            graphics.ScaleTransform((float)scaleX, (float)scaleY);
            graphics.RotateTransform((float)userTransform.Rotation);

            // Apply initial image transformations.
            graphics.TranslateTransform((float)gerberImage.ImageInfo.ImageJustifyOffsetActualA, (float)gerberImage.ImageInfo.ImageJustifyOffsetActualB);
            graphics.TranslateTransform((float)gerberImage.ImageInfo.OffsetA, (float)gerberImage.ImageInfo.OffsetB);
            graphics.RotateTransform((float)gerberImage.ImageInfo.ImageRotation);

            invertPolarity = invert;
            if (gerberImage.ImageInfo.Polarity == GerberPolarity.Negative)
            {
                invertPolarity = !invertPolarity;
            }

            if (invertPolarity)
            {
                graphics.Clear(foreGroundColor);
            }

            else
            {
                pen.Color = brush.Color = foreGroundColor;
            }

            for (netListIndex = 0; netListIndex < gerberNetList.Count; GetNextRenderObject(gerberNetList, ref netListIndex))
            {
                currentNet = gerberNetList[netListIndex];
                if (currentNet.Level != oldLevel)
                {
                    // Set the current net transformation and polarity.
                    graphics.RotateTransform((float)currentNet.Level.Rotation);
                    if (currentNet.Level.Polarity == GerberPolarity.Clear ^ invertPolarity)
                    {
                        pen.Color = brush.Color = backGroundColor;
                    }

                    else
                    {
                        pen.Color = brush.Color = foreGroundColor;
                    }

                    // Check for changes to step and repeat.
                    repeatX         = currentNet.Level.StepAndRepeat.X;
                    repeatY         = currentNet.Level.StepAndRepeat.Y;
                    repeatDistanceX = (float)currentNet.Level.StepAndRepeat.DistanceX;
                    repeatDistanceY = (float)currentNet.Level.StepAndRepeat.DistanceY;

                    // Draw any knockout areas.
                    if (currentNet.Level.Knockout.FirstInstance == true)
                    {
                        Color oldColor = foreGroundColor;
                        if (currentNet.Level.Knockout.Polarity == GerberPolarity.Clear)
                        {
                            pen.Color = brush.Color = backGroundColor;
                        }

                        else
                        {
                            pen.Color = brush.Color = foreGroundColor;
                        }

                        GraphicsPath knockoutPath = new GraphicsPath();
                        PointF       pf1          = new PointF((float)(currentNet.Level.Knockout.LowerLeftX - currentNet.Level.Knockout.Border),
                                                               (float)(currentNet.Level.Knockout.LowerLeftY - currentNet.Level.Knockout.Border));
                        PointF pf2 = new PointF(pf1.X + (float)(currentNet.Level.Knockout.Width + (currentNet.Level.Knockout.Border * 2)), pf1.Y);
                        PointF pf3 = new PointF(pf2.X, pf1.Y + (float)(currentNet.Level.Knockout.Height + (currentNet.Level.Knockout.Border * 2)));
                        PointF pf4 = new PointF(pf1.X, pf3.Y);

                        PointF[] points = new PointF[] { pf1, pf2, pf3, pf4 };
                        knockoutPath.AddLines(points);
                        knockoutPath.CloseFigure();
                        graphics.FillPath(brush, knockoutPath);

                        // Restore the polarity.
                        pen.Color = brush.Color = oldColor;
                    }

                    ApplyNetStateTransformation(graphics, currentNet.NetState);
                    oldLevel = currentNet.Level;
                }

                // Check if this is a new netstate.
                if (currentNet.NetState != oldState)
                {
                    // A new state, so recalculate the new transformation matrix.
                    ApplyNetStateTransformation(graphics, currentNet.NetState);
                    oldState = currentNet.NetState;
                }

                for (int rx = 0; rx < repeatX; rx++)
                {
                    for (int ry = 0; ry < repeatY; ry++)
                    {
                        float stepAndRepeatX = rx * repeatDistanceX;
                        float stepAndRepeatY = ry * repeatDistanceY;

                        startX = (float)currentNet.StartX + stepAndRepeatX;
                        startY = (float)currentNet.StartY + stepAndRepeatY;
                        stopX  = (float)currentNet.StopX + stepAndRepeatX;
                        stopY  = (float)currentNet.StopY + stepAndRepeatY;

                        switch (gerberNetList[netListIndex].Interpolation)
                        {
                        case GerberInterpolation.PolygonAreaStart:
                            FillPolygonArea(graphics, brush, gerberNetList, netListIndex, stepAndRepeatX, stepAndRepeatY);
                            continue;

                        case GerberInterpolation.Deleted:
                            continue;
                        }

                        switch (currentNet.ApertureState)
                        {
                        case GerberApertureState.On:
                            switch (currentNet.Interpolation)
                            {
                            case GerberInterpolation.LinearX10:
                            case GerberInterpolation.LinearX01:
                            case GerberInterpolation.LinearX001:
                            case GerberInterpolation.LinearX1:
                                pen.SetLineCap(LineCap.Round, LineCap.Round, DashCap.Round);
                                switch (gerberImage.ApertureArray[currentNet.Aperture].ApertureType)
                                {
                                case GerberApertureType.Circle:
                                    pen.Width  = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[0];
                                    startPoint = new PointF(startX, startY);
                                    endPoint   = new PointF(stopX, stopY);
                                    graphics.DrawLine(pen, startPoint, endPoint);
                                    break;

                                case GerberApertureType.Rectangle:
                                    dx = (float)(gerberImage.ApertureArray[currentNet.Aperture].Parameters[0] / 2);
                                    dy = (float)(gerberImage.ApertureArray[currentNet.Aperture].Parameters[1] / 2);
                                    if (startX > stopX)
                                    {
                                        dx = -dx;
                                    }

                                    if (startY > stopY)
                                    {
                                        dy = -dy;
                                    }

                                    using (GraphicsPath path = new GraphicsPath())
                                    {
                                        path.AddLine(startX - dx, startY - dy, startX - dx, startY + dy);
                                        path.AddLine(startX - dx, startY + dy, stopX - dx, stopY + dy);
                                        path.AddLine(stopX - dx, stopY + dy, stopX + dx, stopY + dy);
                                        path.AddLine(stopX + dx, stopY + dy, stopX + dx, stopY - dy);
                                        path.AddLine(stopX + dx, stopY - dy, startX + dx, startY - dy);
                                        graphics.FillPath(brush, path);
                                    }
                                    break;

                                // For now, just render ovals or polygons like a circle.
                                case GerberApertureType.Oval:
                                case GerberApertureType.Polygon:
                                    pen.Width  = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[0];
                                    startPoint = new PointF(startX, startY);
                                    endPoint   = new PointF(stopX, stopY);
                                    graphics.DrawLine(pen, startPoint, endPoint);
                                    break;

                                // Macros can only be flashed, so ignore any that might be here.
                                default:
                                    break;
                                }
                                break;

                            case GerberInterpolation.ClockwiseCircular:
                            case GerberInterpolation.CounterClockwiseCircular:
                                float centerX    = (float)currentNet.CircleSegment.CenterX;
                                float centerY    = (float)currentNet.CircleSegment.CenterY;
                                float width      = (float)currentNet.CircleSegment.Width;
                                float height     = (float)currentNet.CircleSegment.Height;
                                float startAngle = (float)currentNet.CircleSegment.StartAngle;
                                float sweepAngle = (float)currentNet.CircleSegment.SweepAngle;
                                if (gerberImage.ApertureArray[currentNet.Aperture].ApertureType == GerberApertureType.Rectangle)
                                {
                                    pen.SetLineCap(LineCap.Square, LineCap.Square, DashCap.Flat);
                                }

                                else
                                {
                                    pen.SetLineCap(LineCap.Round, LineCap.Round, DashCap.Round);
                                }

                                RectangleF arcRectangle = new RectangleF(centerX - (width / 2), centerY - (height / 2), width, height);
                                pen.Width = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[0];
                                if (arcRectangle != RectangleF.Empty)
                                {
                                    graphics.DrawArc(pen, arcRectangle, startAngle, sweepAngle);
                                }

                                break;

                            default:
                                break;
                            }
                            break;

                        case GerberApertureState.Flash:
                            p1 = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[0];
                            p2 = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[1];
                            p3 = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[2];
                            p4 = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[3];
                            p5 = (float)gerberImage.ApertureArray[currentNet.Aperture].Parameters[4];

                            GraphicsState state = graphics.Save();
                            graphics.TranslateTransform(stopX, stopY);
                            using (GraphicsPath path = new GraphicsPath())
                            {
                                switch (gerberImage.ApertureArray[currentNet.Aperture].ApertureType)
                                {
                                case GerberApertureType.Circle:
                                    apertureRectangle = new RectangleF(-(p1 / 2), -(p1 / 2), p1, p1);
                                    path.AddEllipse(apertureRectangle);
                                    DrawAperatureHole(path, p2, p3);
                                    break;

                                case GerberApertureType.Rectangle:
                                    apertureRectangle = new RectangleF(-(p1 / 2), -(p2 / 2), p1, p2);
                                    path.AddRectangle(apertureRectangle);
                                    DrawAperatureHole(path, p3, p4);
                                    break;

                                case GerberApertureType.Oval:
                                    apertureRectangle = new RectangleF(-(p1 / 2), -(p2 / 2), p1, p2);
                                    CreateOblongPath(path, p1, p2);
                                    DrawAperatureHole(path, p3, p4);
                                    break;

                                case GerberApertureType.Polygon:
                                    CreatePolygon(graphics, path, p1, p2, p3);
                                    DrawAperatureHole(path, p4, p5);
                                    break;

                                case GerberApertureType.Macro:
                                    simplifiedMacroList = gerberImage.ApertureArray[currentNet.Aperture].SimplifiedMacroList;
                                    useClearOperator    = gerberImage.ApertureArray[currentNet.Aperture].Parameters[0] == 1.0 ? true : false;
                                    DrawApertureMacro(graphics, simplifiedMacroList, brush.Color, backGroundColor, useClearOperator);
                                    break;

                                default:
                                    break;
                                }

                                graphics.FillPath(brush, path);     // Fill the path.
                                graphics.Restore(state);
                            }

                            break;

                        default:
                            break;
                        }
                    }
                }
            }

            pen.Dispose();
            brush.Dispose();
        }