Ejemplo n.º 1
0
        /// <summary>
        /// Reads a double value and applies number formating if no decimal places.
        /// </summary>
        /// <param name="lineReader"></param>
        /// <param name="numberFormat"></param>
        /// <param name="omitZeros"></param>
        /// <param name="decimals"></param>
        /// <returns></returns>
        static double GetDoubleValue(GerberLineReader lineReader, DrillNumberFormat numberFormat, GerberOmitZero omitZeros, int decimals)
        {
            int  length          = 0;
            bool hasDecimalPoint = false;

            if (lineReader.CurrentLine.Contains('.'))
            {
                hasDecimalPoint = true;
            }

            double value = lineReader.GetDoubleValue(ref length);

            if (hasDecimalPoint)    // No formatting required.
            {
                return(value);
            }

            if (omitZeros == GerberOmitZero.OmitZerosTrailing)
            {
                // Append the number of zeros as needed.
                switch (numberFormat)
                {
                case DrillNumberFormat.Format_00_0000:
                    value *= Math.Pow(10.0, (decimals + 2) - length);
                    break;

                case DrillNumberFormat.Format_000_000:
                    value *= Math.Pow(10.0, (decimals + 3) - length);
                    break;

                case DrillNumberFormat.Format_0000_00:
                    value *= Math.Pow(10.0, (decimals + 4) - length);
                    break;

                case DrillNumberFormat.Format_000_00:
                    value *= Math.Pow(10.0, (decimals + 3) - length);
                    break;
                }
            }

            switch (numberFormat)
            {
            case DrillNumberFormat.Format_00_0000:
                value /= 10000;
                break;

            case DrillNumberFormat.Format_000_000:
                value /= 1000;
                break;

            case DrillNumberFormat.Format_0000_00:
                value /= 100;
                break;

            case DrillNumberFormat.Format_000_00:
                value /= 100;
                break;

            case DrillNumberFormat.UserDefined:
                value /= Math.Pow(10.0, -1.0 * decimals);
                break;
            }

            return(value);
        }
Ejemplo n.º 2
0
        public static ApertureMacro ProcessApertureMacro(GerberLineReader reader)
        {
            const int         MathOperationStackSize = 2;
            ApertureMacro     apertureMacro          = new ApertureMacro();
            GerberInstruction instruction;

            GerberOpcodes[] mathOperations = new GerberOpcodes[MathOperationStackSize];
            char            characterRead;
            int             primitive          = 0;
            int             mathOperationIndex = 0;
            int             equate             = 0;
            bool            continueLoop       = true;
            bool            comma          = false; // Just read an operator (one of '*+X/)
            bool            isNegative     = false; // Negative numbers succeeding ','
            bool            foundPrimitive = false;
            int             length         = 0;

            // Get macro name
            apertureMacro.Name = reader.GetStringValue('*');
            characterRead      = reader.Read(); // skip '*'

            // The first instruction in all programs will be NOP.
            instruction        = new GerberInstruction();
            instruction.Opcode = GerberOpcodes.NOP;
            apertureMacro.InstructionList.Add(instruction);

            while (continueLoop && !reader.EndOfFile)
            {
                length        = 0;
                characterRead = reader.Read();
                switch (characterRead)
                {
                case '$':
                    if (foundPrimitive)
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = GerberOpcodes.PushParameter;
                        apertureMacro.InstructionList.Add(instruction);
                        apertureMacro.NufPushes++;
                        instruction.Data.IntValue = reader.GetIntegerValue(ref length);
                        comma = false;
                    }

                    else
                    {
                        equate = reader.GetIntegerValue(ref length);
                    }

                    break;

                case '*':
                    while (mathOperationIndex != 0)
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    // Check is due to some gerber files has spurious empty lines (eg EagleCad)
                    if (foundPrimitive)
                    {
                        instruction = new GerberInstruction();
                        if (equate > 0)
                        {
                            instruction.Opcode        = GerberOpcodes.PopParameter;
                            instruction.Data.IntValue = equate;
                        }

                        else
                        {
                            instruction.Opcode        = GerberOpcodes.Primative;
                            instruction.Data.IntValue = primitive;
                        }

                        apertureMacro.InstructionList.Add(instruction);

                        equate         = 0;
                        primitive      = 0;
                        foundPrimitive = false;
                    }
                    break;

                case '=':
                    if (equate > 0)
                    {
                        foundPrimitive = true;
                    }

                    break;

                case ',':
                    if (!foundPrimitive)
                    {
                        foundPrimitive = true;
                        break;
                    }

                    while (mathOperationIndex != 0)
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    comma = true;
                    break;

                case '+':
                    while ((mathOperationIndex != 0) &&
                           OperatorPrecedence((mathOperationIndex > 0) ? mathOperations[mathOperationIndex - 1] : GerberOpcodes.NOP) >=
                           (OperatorPrecedence(GerberOpcodes.Add)))
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    mathOperations[mathOperationIndex++] = GerberOpcodes.Add;
                    comma = true;
                    break;

                case '-':
                    if (comma)
                    {
                        isNegative = true;
                        comma      = false;
                        break;
                    }

                    while ((mathOperationIndex != 0) &&
                           OperatorPrecedence((mathOperationIndex > 0) ? mathOperations[mathOperationIndex - 1] : GerberOpcodes.NOP) >=
                           (OperatorPrecedence(GerberOpcodes.Subtract)))
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    mathOperations[mathOperationIndex++] = GerberOpcodes.Subtract;
                    break;

                case '/':
                    while ((mathOperationIndex != 0) &&
                           OperatorPrecedence((mathOperationIndex > 0) ? mathOperations[mathOperationIndex - 1] : GerberOpcodes.NOP) >=
                           (OperatorPrecedence(GerberOpcodes.Divide)))
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    mathOperations[mathOperationIndex++] = GerberOpcodes.Divide;
                    comma = true;
                    break;

                case 'X':
                case 'x':
                    while ((mathOperationIndex != 0) &&
                           OperatorPrecedence((mathOperationIndex > 0) ? mathOperations[mathOperationIndex - 1] : GerberOpcodes.NOP) >=
                           (OperatorPrecedence(GerberOpcodes.Multiple)))
                    {
                        instruction        = new GerberInstruction();
                        instruction.Opcode = mathOperations[--mathOperationIndex];
                        apertureMacro.InstructionList.Add(instruction);
                    }

                    mathOperations[mathOperationIndex++] = GerberOpcodes.Multiple;
                    comma = true;
                    break;

                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '.':
                    // Comments in aperture macros are a definition starting with zero and ends with a '*'
                    if ((characterRead == '0') && (!foundPrimitive) && (primitive == 0))
                    {
                        // Comment continues until next '*', just throw it away.
                        reader.GetStringValue('*');
                        characterRead = reader.Read();     // Read the '*'.
                        break;
                    }

                    // First number in an aperture macro describes the primitive as a numerical value
                    if (!foundPrimitive)
                    {
                        primitive = (primitive * 10) + (characterRead - '0');
                        break;
                    }

                    reader.Position--;
                    instruction        = new GerberInstruction();
                    instruction.Opcode = GerberOpcodes.Push;
                    apertureMacro.InstructionList.Add(instruction);
                    apertureMacro.NufPushes++;
                    instruction.Data.DoubleValue = reader.GetDoubleValue();
                    if (isNegative)
                    {
                        instruction.Data.DoubleValue = -(instruction.Data.DoubleValue);
                    }

                    isNegative = false;
                    comma      = false;
                    break;

                case '%':
                    reader.Position--;          // Must return with % first in string since the main parser needs it.
                    continueLoop = false;       // Reached the end of the macro.
                    break;

                default:
                    // Whitespace.
                    break;
                }
            }

            if (reader.EndOfFile)
            {
                return(null);
            }

            return(apertureMacro);
        }