LineTextSymbol CreateLineTextSymbol(OcadObject obj, TextSymDef symdef) { if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); if (obj.coords == null || obj.coords.Length < 2) return null; SymPath path = CreateSymPath(obj.coords); string text = obj.text; CheckFont(symdef.FontName); return new LineTextSymbol(symdef, path, text); }
// Create an image graphics object ---- an line object created from an image import ImageLineSymbol CreateLineImageObject(OcadObject obj, ImageSymDef symdef) { if (obj.coords == null || obj.coords.Length < 2) return null; SymPath path = CreateSymPath(obj.coords); LineStyle lineStyle = ImportLineStyle(obj.DiamFlags); return new ImageLineSymbol(symdef, path, ColorFromCompressedCMYK(obj.Col), ToWorldDimensions(obj.LineWidth), lineStyle); }
LineSymbol CreateLineSymbol(OcadObject obj, LineSymDef symdef) { if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); if (obj.coords == null || obj.coords.Length < 2) return null; SymPath path = CreateSymPath(obj.coords); return new LineSymbol(symdef, path); }
// Create a iamge object -- an object created from an image import operations void CreateImageObject(OcadObject obj) { ImageSymDef def = GetImageSymDef(); // Get the symdef. Symbol sym = null; if (obj.Otp == 3) { sym = CreateAreaImageObject(obj, def); } else if (obj.Otp == 2) { sym = CreateLineImageObject(obj, def); } if (sym != null) { map.AddSymbol(sym); CheckSymbolRenderable(sym); } }
// Create an line graphics object ---- an line object created from an object broken apart with the To Graphics command. GraphicsLineSymbol CreateLineGraphicsObject(OcadObject obj, GraphicsSymDef symdef) { if (obj.coords == null || obj.coords.Length < 2) return null; SymPath path = CreateSymPath(obj.coords); LineStyle lineStyle = ImportLineStyle(obj.DiamFlags); return new GraphicsLineSymbol(symdef, path, GetColor((int) obj.Col), ToWorldDimensions(obj.LineWidth), lineStyle); }
// Create an area iamge object ---- an area object created from an image import ImageAreaSymbol CreateAreaImageObject(OcadObject obj, ImageSymDef symdef) { SymPathWithHoles path = CreateAreaSymPath(obj.coords); return new ImageAreaSymbol(symdef, path, ColorFromCompressedCMYK(obj.Col)); }
AreaSymbol CreateAreaSymbol(OcadObject obj, AreaSymDef symdef) { if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); SymPathWithHoles path = CreateAreaSymPath(obj.coords); return new AreaSymbol(symdef, path, AngleToDegrees(obj.Ang)); }
void ReadAndCreateObjects(OcadIndexBlocks b) { for (int i = 0; i < b.indexes.Length; ++i) { if (b.indexes[i].Sym != 0 && (version <= 8 || b.indexes[i].Status == 1)) { OcadObject obj = new OcadObject(); reader.BaseStream.Seek(b.indexes[i].Pos, SeekOrigin.Begin); obj.Read(reader, version); CreateObject(obj); } } }
// Create an area graphics object ---- an area object created from an object broken apart with the To Graphics command. GraphicsAreaSymbol CreateAreaGraphicsObject(OcadObject obj, GraphicsSymDef symdef) { SymPathWithHoles path = CreateAreaSymPath(obj.coords); return new GraphicsAreaSymbol(symdef, path, GetColor((int) obj.Col)); }
TextSymbol CreateTextSymbol(OcadObject obj, TextSymDef symdef, bool formatted) { if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); string text = obj.text; PointF location; float width, topAdjust; float angle = AngleToDegrees(obj.Ang); if (formatted) { location = PointFromOcadCoord(obj.coords[3]); width = Util.DistanceF(location, PointFromOcadCoord(obj.coords[2])); // OCAD adds an extra internal leading (incorrectly). topAdjust = symdef.FontEmHeight - (symdef.FontAscent + symdef.FontDescent); } else { location = PointFromOcadCoord(obj.coords[0]); width = 0; // OCAD positions by baseline of text, we position at top of ascent of text. topAdjust = 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)); string[] lines = Util.SplitLines(text); CheckFont(symdef.FontName); return new TextSymbol(symdef, lines, location, angle, width); }
// Rectangle symbols may be translated into multiple symbols (if there is a grid). Symbol[] CreateRectangleSymbol(OcadObject obj, LineSymDef symdef, RectangleInfo rectinfo) { List<Symbol> symlist = new List<Symbol>(); // list of symbols we're creating. if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); if (obj.coords == null || obj.coords.Length < 2) return null; // Create the main rectangle symbol. // Determine size of the rectangle, and matrix needed to transform points to their correct location. PointF[] pts = {PointFromOcadCoord(obj.coords[0]), PointFromOcadCoord(obj.coords[1]), PointFromOcadCoord(obj.coords[2]), PointFromOcadCoord(obj.coords[3])}; SizeF size = new SizeF(Util.DistanceF(pts[0], pts[1]), Util.DistanceF(pts[0], pts[3])); float angle = Util.Angle(pts[0], pts[1]); Matrix matrix = new Matrix(); matrix.Translate(pts[0].X, pts[0].Y); matrix.Rotate(angle); SymPath path; PointKind[] kinds; PointF[] pathpts; if (rectinfo.cornerRadius == 0) { kinds = new PointKind[] {PointKind.Corner, PointKind.Corner, PointKind.Corner, PointKind.Corner, PointKind.Corner}; pathpts = new PointF[] { new PointF(0,0), new PointF(0, size.Height), new PointF(size.Width, size.Height), new PointF(size.Width, 0), new PointF(0,0)}; } else { kinds = new PointKind[] {PointKind.Normal, PointKind.Normal, PointKind.BezierControl, PointKind.BezierControl, PointKind.Normal, PointKind.Normal, PointKind.BezierControl, PointKind.BezierControl, PointKind.Normal, PointKind.Normal, PointKind.BezierControl, PointKind.BezierControl, PointKind.Normal, PointKind.Normal, PointKind.BezierControl, PointKind.BezierControl, PointKind.Normal}; pathpts = new PointF[] { new PointF(rectinfo.cornerRadius, 0), new PointF(size.Width - rectinfo.cornerRadius, 0), new PointF(size.Width - (1-Util.kappa) * rectinfo.cornerRadius, 0), new PointF(size.Width, (1-Util.kappa) * rectinfo.cornerRadius), new PointF(size.Width, rectinfo.cornerRadius), new PointF(size.Width, size.Height - rectinfo.cornerRadius), new PointF(size.Width, size.Height - (1-Util.kappa) * rectinfo.cornerRadius), new PointF(size.Width - (1-Util.kappa) * rectinfo.cornerRadius, size.Height), new PointF(size.Width - rectinfo.cornerRadius, size.Height), new PointF(rectinfo.cornerRadius, size.Height), new PointF((1-Util.kappa) * rectinfo.cornerRadius, size.Height), new PointF(0, size.Height - (1-Util.kappa) * rectinfo.cornerRadius), new PointF(0, size.Height - rectinfo.cornerRadius), new PointF(0, rectinfo.cornerRadius), new PointF(0, (1-Util.kappa) * rectinfo.cornerRadius), new PointF((1-Util.kappa) * rectinfo.cornerRadius, 0), new PointF(rectinfo.cornerRadius, 0)}; } pathpts = GraphicsUtil.TransformPoints(pathpts, matrix); for (int i = 0; i < pathpts.Length; ++i) pathpts[i] = new PointF((float) Math.Round(pathpts[i].X, 2), (float) Math.Round(pathpts[i].Y, 2)); // round to 2 decimals, so round trip to OCAD without change. path = new SymPath(pathpts, kinds); symlist.Add(new LineSymbol(symdef, path)); if (rectinfo.grid) { if (size.Width > 0 && size.Height > 0) { int cxCells = (int) Math.Round(size.Width / rectinfo.cellWidth); if (cxCells < 1) cxCells = 1; int cyCells = (int) Math.Round(size.Height / rectinfo.cellHeight); if (cyCells < 1) cyCells = 1; float width = size.Width / cxCells; float height = size.Height / cyCells; CreateGridLines(size, matrix, cxCells, cyCells, width, height, rectinfo.gridLines, symlist); CreateGridText(size, matrix, angle, cxCells, cyCells, width, height, rectinfo, symlist); } } return symlist.ToArray(); }
PointSymbol CreatePointSymbol(OcadObject obj, PointSymDef symdef) { if (symdef == null) throw new OcadFileFormatException("Object has unknown or inconsistent symbol type {0}", obj.Sym); PointF location = PointFromOcadCoord(obj.coords[0]); // Determine if there are any circle gaps. float[] gaps = null; if (obj.coords.Length > 1) { // The additional coordinates give circle gaps. They are expressed in pairs of OCAD angles, where the X is the start and // the Y is the end. gaps = new float[(obj.coords.Length - 1) * 2]; for (int i = 0; i < obj.coords.Length - 1; ++i) { OcadCoord ocadGap = obj.coords[i + 1]; gaps[i * 2] = AngleToDegrees(ocadGap.x); gaps[i * 2 + 1] = AngleToDegrees(ocadGap.y); } } return new PointSymbol(symdef, location, AngleToDegrees(obj.Ang), gaps); }
void CreateObject(OcadObject obj) { int symid; if (version >= 9) { if (obj.Sym == -1) { return; // imported object } else if (obj.Sym == -2) { // Graphics object -- from broken apart symbol. CreateGraphicsObject(obj); return; } else if (obj.Sym == -3) { // Image object -- from imported AI/WMF CreateImageObject(obj); return; } symid = obj.Sym; } else { symid = (obj.Sym / 10) * 1000 + (obj.Sym % 10); } if (! symdefids.ContainsKey(symid)) { // Unknown symbol definition. // CONSIDER: produce warning that at unsymbols object is being ignored? return; } SymDef symdef = symdefids[symid] as SymDef; Symbol sym = null; switch (obj.Otp) { default: throw new OcadFileFormatException("Invalid Otp value {0} in object", obj.Otp); case 1: sym = CreatePointSymbol(obj, symdef as PointSymDef); break; case 2: // Line or line text symbols. if (symdef is LineSymDef) sym = CreateLineSymbol(obj, symdef as LineSymDef); else sym = CreateLineTextSymbol(obj, symdef as TextSymDef); break; case 3: // Area symbols. sym = CreateAreaSymbol(obj, symdef as AreaSymDef); break; case 4: // Text symbols sym = CreateTextSymbol(obj, symdef as TextSymDef, false); break; case 6: // Line text symbol. sym = CreateLineTextSymbol(obj, symdef as TextSymDef); break; case 5: case 7: // formatted text or rectangle symbol if (symdef is TextSymDef) sym = CreateTextSymbol(obj, symdef as TextSymDef, true); else { RectangleInfo rectinfo = (RectangleInfo) rectangleInfos[symid]; Symbol[] syms = CreateRectangleSymbol(obj, symdef as LineSymDef, rectinfo); if (syms != null) { foreach (Symbol s in syms) { map.AddSymbol(s); } } } break; } if (sym != null) { map.AddSymbol(sym); CheckSymbolRenderable(sym); } }
// Write a symbol, return nItem + nText. int WriteSymbol(Symbol sym, out OcadObject obj) { obj = new OcadObject(); obj.Sym = ConvertSymdefId(sym.Definition.OcadID); if (sym is PointSymbol) { PointSymbol psym = sym as PointSymbol; obj.Otp = 1; obj.Ang = AngleToOcad(psym.Rotation); OcadCoord pointCoord = OcadCoordFromPoint(psym.Location); if (psym.Gaps == null) { obj.coords = new OcadCoord[1] { pointCoord }; } else { // object has circle gaps in it. obj.coords = new OcadCoord[1 + psym.Gaps.Length / 2]; obj.coords[0] = pointCoord; for (int i = 0; i < psym.Gaps.Length; i += 2) { obj.coords[i / 2 + 1].x = AngleToOcad(psym.Gaps[i]); obj.coords[i / 2 + 1].y = AngleToOcad(psym.Gaps[i + 1]); } } } else if (sym is LineSymbol) { LineSymbol lsym = sym as LineSymbol; obj.Otp = 2; obj.coords = CoordsFromSymPath(lsym.Path); } else if (sym is GraphicsLineSymbol) { GraphicsLineSymbol glsym = sym as GraphicsLineSymbol; obj.Sym = -2; obj.Otp = 2; obj.coords = CoordsFromSymPath(glsym.Path); obj.Col = (uint) NumberOfColor(glsym.LineColor); obj.LineWidth = (short) ToOcadDimensions(glsym.Thickness); obj.DiamFlags = OcadLineStyle(glsym.LineStyle); } else if (sym is ImageLineSymbol) { ImageLineSymbol ilsym = sym as ImageLineSymbol; obj.Sym = -3; obj.Otp = 2; obj.coords = CoordsFromSymPath(ilsym.Path); obj.Col = CompressedCMYKFromColor(ilsym.LineColor); obj.LineWidth = (short) ToOcadDimensions(ilsym.Thickness); obj.DiamFlags = OcadLineStyle(ilsym.LineStyle); } else if (sym is AreaSymbol) { AreaSymbol asym = sym as AreaSymbol; obj.Otp = 3; obj.coords = CoordsFromSymPathWithHoles(asym.Path); obj.Ang = AngleToOcad(asym.Angle); // UNDONE: if this symbol has a border and version <=8, need to create additional objects for the border. } else if (sym is GraphicsAreaSymbol) { GraphicsAreaSymbol gasym = sym as GraphicsAreaSymbol; obj.Sym = -2; obj.Otp = 3; obj.coords = CoordsFromSymPathWithHoles(gasym.Path); obj.Col = (uint) NumberOfColor(gasym.FillColor); } else if (sym is ImageAreaSymbol) { ImageAreaSymbol iasym = sym as ImageAreaSymbol; obj.Sym = -3; obj.Otp = 3; obj.coords = CoordsFromSymPathWithHoles(iasym.Path); obj.Col = CompressedCMYKFromColor(iasym.FillColor); } else if (sym is TextSymbol) { TextSymbol tsym = sym as TextSymbol; obj.Otp = (byte) (tsym.Width > 0 ? 5 : 4); obj.text = string.Join("\r\n", tsym.Text); obj.Ang = AngleToOcad(tsym.Rotation); obj.coords = GetTextObjectCoords(tsym); } else if (sym is LineTextSymbol) { LineTextSymbol ltsym = sym as LineTextSymbol; obj.Otp = (byte) ((version <= 8) ? 2 : 6); obj.text = ltsym.Text; obj.Ang = 0; obj.coords = CoordsFromSymPath(ltsym.Path); } else { Debug.Fail("Unexpected symbol type"); } // UNDONE: deal with overflow of a short below. if (obj.coords != null) obj.nItem = (short) (obj.coords.Length); if (obj.text != null) { if (version >= 9 || obj.Unicode != 0) obj.nText = (short) ((obj.text.Length / 4) + 1); else obj.nText = (short) ((obj.text.Length / 8) + 1); } obj.Write(writer, version); return obj.nItem + obj.nText; }