Beispiel #1
0
 // Is this OCAD coordinate starting a hole?
 static bool IsOcadCoordHoleStart(OcadCoord coord)
 {
     if ((coord.y & 2) != 0)
         return true;
     else
         return false;
 }
Beispiel #2
0
 // Is this OCAD coordinate a bezier control point?
 static bool IsOcadCoordBezierControl(OcadCoord coord)
 {
     if ((coord.x & 3) != 0)
         return true;
     else
         return false;
 }
Beispiel #3
0
 // Is this OCAD coordinate a area boundary cutout?
 static bool IsOcadCoordBoundaryCutOut(OcadCoord coord)
 {
     if ((coord.x & 8) != 0)
         return true;
     else
         return false;
 }
Beispiel #4
0
        internal static OcadCoord[] FixOcadCoords(OcadCoord[] coords, bool allowHoles, out int numHoles, out bool anyCutouts)
        {
            bool foundProblem = false;
            int numBezierControls = 0;      // tracks the current number of bezier controls found.

            numHoles = 0;
            anyCutouts = false;

            if (coords.Length == 0)
                return coords;

            if (IsOcadCoordBezierControl(coords[0]))
                foundProblem = true;

            for (int i = 0; i < coords.Length; ++i) {
                OcadCoord coord = coords[i];

                if (IsOcadCoordAnyCutOut(coord))
                    anyCutouts = true;

                if (i >= 1 && IsOcadCoordHoleStart(coord)) {
                    if (IsOcadCoordBezierControl(coord))
                        foundProblem = true;
                    if (numBezierControls != 0)
                        foundProblem = true;
                    if (!allowHoles)
                        foundProblem = true;
                    else
                        ++numHoles;
                }

                if (IsOcadCoordBezierControl(coord))
                    ++numBezierControls;
                else {
                    if (numBezierControls != 0 && numBezierControls != 2)
                        foundProblem = true;
                    numBezierControls = 0;
                }
            }

            if (numBezierControls != 0)
                foundProblem = true;       // should not end with bezier controls.

            // If there were no problems, just return the argument and done (fast, common case).
            if (!foundProblem)
                return coords;
            else
                return PatchUpOcadCoords(coords, allowHoles);
        }
Beispiel #5
0
 // Is this COAD coord any cutout?
 static bool IsOcadCoordAnyCutOut(OcadCoord coord)
 {
     if (((coord.x & 0xC) != 0) || ((coord.y & 4) != 0))
         return true;
     else
         return false;
 }
Beispiel #6
0
        // Scan the OCAD coordinates and fix the following problems:
        // 1. not exactly two bezier control points in a row
        // 2. start or end with bezier control points
        // 3. holes when none are allowed.
        // If holes are allowed, counts how many there are.
        static OcadCoord[] PatchUpOcadCoords(OcadCoord[] coords, bool allowHoles)
        {
            int numBezierControls = 0;                                      // number of consecutive bezier control points found.
            bool atStart = true;                                                 // are we at the start or the start of a hole?
            List<OcadCoord> list = new List<OcadCoord>();    // the list of coordinates we are building up.

            for (int i = 0; i < coords.Length; ++i) {
                OcadCoord coord = coords[i];

                if (IsOcadCoordHoleStart(coord)) {
                    if (numBezierControls != 0) {
                        // remove trailing bezier control points.
                        list.RemoveRange(list.Count - numBezierControls, numBezierControls);
                        numBezierControls = 0;
                    }

                    atStart = true;

                    if (!allowHoles)
                        break;
                }

                if (IsOcadCoordBezierControl(coord)) {
                    // At the start ignore bezier control points.
                    if (!atStart) {
                        ++numBezierControls;
                        list.Add(coord);
                    }
                }
                else {
                    if (numBezierControls != 0 && numBezierControls != 2)
                        list.RemoveRange(list.Count - numBezierControls, numBezierControls);
                    numBezierControls = 0;
                    if (atStart && list.Count != 0)
                        coord.y |= 2;             // we need to start a hole here, since the bezier that started the hole might have been nuked.
                    list.Add(coord);
                    atStart = false;
                }
            }

            // Remove trailing bezier control points.
            if (numBezierControls != 0)
                list.RemoveRange(list.Count - numBezierControls, numBezierControls);

            return list.ToArray();
        }
Beispiel #7
0
		public static void WriteCoords(BinaryWriter writer, OcadCoord[] coords) {
			foreach (OcadCoord coord in coords)
				coord.Write(writer);
		}
Beispiel #8
0
 //PointF[] lineBuilder = new PointF[1]; // used to build lines in CreateSymPath.
 PointF PointFromOcadCoord(OcadCoord coord)
 {
     return new PointF(ToWorldDimensions(coord.x >> 8), ToWorldDimensions(coord.y >> 8));
 }
Beispiel #9
0
 PointKind PointKindFromOcadCoord(OcadCoord coord)
 {
     if ((coord.x & 3) != 0)
         return PointKind.BezierControl;
     else if ((coord.y & 1) != 0)
         return PointKind.Corner;
     else if ((coord.y & 8) != 0)
         return PointKind.Dash;
     else
         return PointKind.Normal;
 }
Beispiel #10
0
        OcadCoord[] GetTextObjectCoords(TextSymbol sym)
        {
            TextSymDef symdef = ((TextSymDef) sym.Definition);
            PointF location = sym.Location;
            SizeF size = sym.TextSize;
            float angle = sym.Rotation;
            float width = sym.Width;

            PointF[] points;

            if (width > 0) {
                // Formatted text
                points = new PointF[4];
                float topAdjust = symdef.FontEmHeight - (symdef.FontAscent + symdef.FontDescent);
                float height = size.Height + symdef.FontEmHeight - symdef.FontAscent;
                location.Y -= (float) (topAdjust * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (topAdjust * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[3] = location;
                location.Y -= (float) (width * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X += (float) (width * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[2] = location;
                location.Y -= (float) (height * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (height * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[1] = location;
                location.Y += (float) (width * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (width * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[0] = location;
            }
            else {
                // Unformatted text
                float topAdjust = symdef.FontAscent;
                float height = symdef.FontEmHeight;
                float descent = symdef.FontDescent;
                points = new PointF[5];

                location.Y -= (float) (topAdjust * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (topAdjust * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[0] = location;
                location.Y -= (float) (descent * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (descent * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                if (symdef.FontAlignment == TextSymDefAlignment.Right) {
                    location.Y += (float) (size.Width * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                    location.X -= (float) (size.Width * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                }
                else if (symdef.FontAlignment == TextSymDefAlignment.Center) {
                    location.Y += (float) ((size.Width/2) * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                    location.X -= (float) ((size.Width/2) * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                }
                points[1] = location;
                location.Y -= (float) (size.Width * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X += (float) (size.Width * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[2] = location;
                location.Y += (float) ((descent+height) * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X += (float) ((descent+height) * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[3] = location;
                location.Y += (float) (size.Width * Math.Cos((angle + 90.0) / 360.0 * 2 * Math.PI));
                location.X -= (float) (size.Width * Math.Sin((angle + 90.0) / 360.0 * 2 * Math.PI));
                points[4] = location;
            }

            OcadCoord[] coords = new OcadCoord[points.Length];
            for (int i = 0; i < coords.Length; ++i)
                coords[i] = OcadCoordFromPoint(points[i]);

            return coords;
        }
Beispiel #11
0
        SymPath CreateSymPath(OcadCoord[] coords)
        {
            int dummy;
            bool anyCutouts;
            coords = FixOcadCoords(coords, false, out dummy, out anyCutouts);

            PointF[] points = new PointF[coords.Length];
            PointKind[] kinds = new PointKind[coords.Length];
            byte[] startStopFlags = null;

            if (anyCutouts)
                startStopFlags = new byte[coords.Length - 1];

            for (int i = 0; i < coords.Length; ++i) {
                points[i] = PointFromOcadCoord(coords[i]);
                kinds[i] = PointKindFromOcadCoord(coords[i]);
                if (anyCutouts && i < coords.Length - 1)
                    startStopFlags[i] = StartStopFlagsFromCoord(coords[i]);
            }

            return new SymPath(points, kinds, startStopFlags, false);
        }
Beispiel #12
0
        OcadCoord[] CoordsFromSymPathWithHoles(SymPathWithHoles path)
        {
            OcadCoord[] firstCoords = CoordsFromSymPath(path.MainPath);

            SymPath[] holes = path.Holes;

            if (holes == null)
                return firstCoords;

            int totalLength = firstCoords.Length;

            OcadCoord[][] holeCoords = new OcadCoord[holes.Length][];
            for (int i = 0; i < holes.Length; ++i) {
                holeCoords[i] = CoordsFromSymPath(holes[i]);
                totalLength += holeCoords[i].Length;
            }

            OcadCoord[] fullCoords = new OcadCoord[totalLength];
            Array.Copy(firstCoords, 0, fullCoords, 0, firstCoords.Length);
            totalLength = firstCoords.Length;
            for (int i = 0; i < holes.Length; ++i) {
                Array.Copy(holeCoords[i], 0, fullCoords, totalLength, holeCoords[i].Length);
                fullCoords[totalLength].y |= 2; // mark beginning of hole.
                totalLength += holeCoords[i].Length;
            }

            return fullCoords;
        }
Beispiel #13
0
        OcadCoord[] CoordsFromSymPath(SymPath path)
        {
            PointF[] points = path.Points;
            PointKind[] kinds = path.PointKinds;
            byte[] startStopFlags = path.StartStopFlags;
            int length = points.Length;
            if (path.LastPointSynthesized)
                length -= 1;

            OcadCoord[] coords = new OcadCoord[length];

            for (int i = 0; i < length; ++i) {
                coords[i] = OcadCoordFromPoint(points[i]);

                switch (kinds[i]) {
                case PointKind.Normal:
                    break;
                case PointKind.Dash:
                    if (version >= 7) coords[i].y |= 8;
                    break;
                case PointKind.Corner:
                    coords[i].y |= 1; break;
                case PointKind.BezierControl:
                    if (i > 0 && kinds[i-1] == PointKind.BezierControl)
                        coords[i].x |= 2;
                    else
                        coords[i].x |= 1;
                    break;
                }

                if (startStopFlags != null && i < startStopFlags.Length) {
                    if ((startStopFlags[i] & SymPath.DOUBLE_LEFT_STARTSTOPFLAG) != 0)
                        coords[i].x |= 4;
                    if ((startStopFlags[i] & SymPath.DOUBLE_RIGHT_STARTSTOPFLAG) != 0)
                        coords[i].y |= 4;
                    if ((startStopFlags[i] & SymPath.AREA_BOUNDARY_STARTSTOPFLAG) != 0)
                        coords[i].x |= 8;
                }
            }

            return coords;
        }
Beispiel #14
0
		public void Read(BinaryReader reader, int version) {
			LowerLeft = new OcadCoord();
			LowerLeft.Read(reader);
			UpperRight = new OcadCoord();
			UpperRight.Read(reader);
            if (version <= 8) {
                Pos = reader.ReadInt32();
                Len = reader.ReadInt16();
                Sym = reader.ReadInt16();
            }
            else {
                Pos = reader.ReadInt32();
                Len = reader.ReadInt32();
                Sym = reader.ReadInt32();
                ObjType = reader.ReadByte();
                Rex = reader.ReadByte();
                Status = reader.ReadByte();
                ViewType = reader.ReadByte();
                Color = reader.ReadInt16();
                reader.ReadInt16();
                ImpLayer = reader.ReadInt16();
                reader.ReadInt16();
            }
		}
Beispiel #15
0
 // Is this OCAD coordinate a left-double-ine cutout?
 static bool IsOcadCoordLeftCutOut(OcadCoord coord)
 {
     if ((coord.x & 4) != 0)
         return true;
     else
         return false;
 }
Beispiel #16
0
 PointF[] PointsFromOcadCoord(OcadCoord[] coords)
 {
     PointF[] pts = new PointF[coords.Length];
     for (int i = 0; i < coords.Length; ++i)
         pts[i] = PointFromOcadCoord(coords[i]);
     return pts;
 }
Beispiel #17
0
 // Is this OCAD coordinate a right-double-ine cutout?
 static bool IsOcadCoordRightCutOut(OcadCoord coord)
 {
     if ((coord.y & 4) != 0)
         return true;
     else
         return false;
 }
Beispiel #18
0
        // Convert flags in the OCAD coord to the sympath start/stop flags.
        byte StartStopFlagsFromCoord(OcadCoord coord)
        {
            byte b = 0;
            if (IsOcadCoordLeftCutOut(coord))
                b |= SymPath.DOUBLE_LEFT_STARTSTOPFLAG;
            if (IsOcadCoordRightCutOut(coord))
                b |= SymPath.DOUBLE_RIGHT_STARTSTOPFLAG;
            if (IsOcadCoordBoundaryCutOut(coord))
                b |= SymPath.AREA_BOUNDARY_STARTSTOPFLAG;

            return b;
        }
Beispiel #19
0
        // Creates holes, and also closes the path (and holes)
        SymPathWithHoles CreateAreaSymPath(OcadCoord[] coords)
        {
            int numHoles;
            bool anyCutouts;

            coords = FixOcadCoords(coords, true, out numHoles, out anyCutouts);

            SymPath[] holes;
            if (numHoles > 0)
                holes = new SymPath[numHoles];
            else
                holes = null;

            SymPath path = null;

            // Pass 2: allocate the correct sizes of arrays and fill them in
            int startIndex = 0;
            int holeNumber = -1;
            for (int i = 1; i <= coords.Length; ++i) {
                if (i == coords.Length || IsOcadCoordHoleStart(coords[i])) {
                    // Found the end of the main path or hole.

                    int size = i - startIndex;
                    int arraySize = size;

                    // Make a closed path by duplicating first coord?
                    bool closed = (size <= 1 || PointFromOcadCoord(coords[i-1]) != PointFromOcadCoord(coords[startIndex]));
                    if (closed) {
                        ++arraySize;
                    }

                    PointF[] points = new PointF[arraySize];
                    PointKind[] kinds = new PointKind[arraySize];
                    byte[] startStopFlags = null;
                    if (anyCutouts)
                        startStopFlags = new byte[arraySize - 1];

                    for (int pointIndex = 0; pointIndex < size; ++pointIndex) {
                        points[pointIndex] = PointFromOcadCoord(coords[pointIndex + startIndex]);
                        kinds[pointIndex] = PointKindFromOcadCoord(coords[pointIndex + startIndex]);
                        if (startStopFlags != null && pointIndex < startStopFlags.Length)
                            startStopFlags[pointIndex] = StartStopFlagsFromCoord(coords[pointIndex + startIndex]);
                    }
                    if (closed) {
                        points[arraySize - 1] = PointFromOcadCoord(coords[startIndex]);
                        kinds[arraySize - 1] = PointKindFromOcadCoord(coords[startIndex]);
                    }

                    SymPath p = new SymPath(points, kinds, startStopFlags, closed);
                    if (holeNumber == -1)
                        path = p;
                    else
                        holes[holeNumber] = p;

                    ++holeNumber;
                    startIndex = i;
                }
            }

            return new SymPathWithHoles(path, holes);
        }
Beispiel #20
0
		public static OcadCoord[] ReadCoords(BinaryReader reader, int nCoord) {
			OcadCoord[] coords = new OcadCoord[nCoord];
			for (int i = 0; i < nCoord; ++i) {
				coords[i].Read(reader);
			}
			return coords;
		}