From 20faf4f04698e9352c537dda0c2a35e72cb9de28 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 10:12:17 +0000 Subject: [PATCH 1/2] Write and read the DXF text height as the height of the capital letters (#506) The height of a DXF TEXT or MTEXT (group 40) is the height of the capital letters, which AutoCAD and other viewers scale the font to, while Text.TextSize is the em height of the font. Since the move to ACadSharp the exporter wrote TextSize unchanged, so every other program showed exported texts 1.4 (Arial) to 1.6 (Consolas) times larger than CADability drew them and than their bounding cube. The netDxf exporter of 1.0.x had scaled the height by the font metrics. The export now multiplies TextSize by the cap height of the font, measured at the outline of "H" (FontCache.GetCapHeight, Text.CapHeightFactor), and the import divides by the same factor, so a round trip keeps TextSize and the extent unchanged. Imported DXF and DWG texts are therefore drawn larger than before, as large as AutoCAD shows them. The MTEXT line spacing is converted with the same factor. The export also writes the width factor (group 41) from the length of the line direction, which it dropped before, while the import already read it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01F53kFpUYJXo4cE8wSe2jHi --- CADability/ExportDxf.cs | 19 ++- CADability/ImportDxf.cs | 8 +- CADability/Text.cs | 51 +++++++ .../DxfTextHeightTest.cs | 143 ++++++++++++++++++ 4 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 tests/CADability.ImportTests/DxfTextHeightTest.cs diff --git a/CADability/ExportDxf.cs b/CADability/ExportDxf.cs index 217f4da2..fa635d79 100644 --- a/CADability/ExportDxf.cs +++ b/CADability/ExportDxf.cs @@ -697,9 +697,11 @@ private Entity ExportText(GeoObject.Text text) if (text.Bold) fs |= System.Drawing.FontStyle.Bold; if (text.Italic) fs |= System.Drawing.FontStyle.Italic; - // TextSize is the raw DXF cap-height (group 40) stored unchanged during import. - // Do not apply any font-metric scaling here — it would corrupt the value. - double height = text.TextSize; + // TextSize is the em height of the font, while the DXF height (group 40) is the + // height of the capital letters, which AutoCAD and other viewers scale the font to. + // Writing TextSize unchanged makes the text 1.4 (Arial) to 1.6 (Consolas) times too + // large in every other program (issue #506). The import divides by the same factor. + double height = text.TextSize * text.CapHeightFactor; string fontName = text.Font ?? "Standard"; if (!createdTextStyles.TryGetValue(fontName, out ACadSharp.Tables.TextStyle textStyle)) @@ -765,6 +767,10 @@ private Entity ExportText(GeoObject.Text text) Normal = ToXYZ(normal), Rotation = rotation, }; + // Group 41: CADability stretches or compresses a text by the length of its line + // direction relative to its glyph direction. + double widthFactor = text.LineDirection.Length / text.GlyphDirection.Length; + if (widthFactor > 0.0 && Math.Abs(widthFactor - 1.0) > 1e-9) res.WidthFactor = widthFactor; // Set group 11 whenever it is meaningful. Leaving it at its (0,0,0) default while // groups 72/73 say it is authoritative would place the text at the origin. if (!defaultAlign) @@ -814,9 +820,10 @@ private ACadSharp.Entities.MText BuildMText(GeoObject.Text text, string textStri if (text.ColumnWidth > 0) res.RectangleWidth = text.ColumnWidth; if (text.LineSpacing > 0) { - // Import stores the DXF spacing factor as 5/3 * factor (AutoCAD's MTEXT - // baseline distance); invert that here and keep it inside the DXF range. - double factor = text.LineSpacing * 3.0 / 5.0; + // AutoCAD spaces MTEXT baselines 5/3 * factor of the DXF height apart, and the + // import converts that into a factor of TextSize; invert that here and keep it + // inside the DXF range. + double factor = text.LineSpacing * 3.0 / 5.0 / text.CapHeightFactor; res.LineSpacing = Math.Max(0.25, Math.Min(4.0, factor)); // Group 73 must name a real spacing style, otherwise the factor in group 44 // is ignored; the default (None/0) is not one the DXF reference allows here. diff --git a/CADability/ImportDxf.cs b/CADability/ImportDxf.cs index 4da4e903..b76877d6 100644 --- a/CADability/ImportDxf.cs +++ b/CADability/ImportDxf.cs @@ -1907,6 +1907,9 @@ private IGeoObject CreateText(ACadSharp.Entities.TextEntity txt, bool pointsInWc text.Location = pointsInWcs ? GeoPoint(anchor) : OcsToWcs(anchor, txt.Normal); text.LineDirection = linedir; text.GlyphDirection = glyphdir; + // The DXF height is the height of the capital letters, TextSize the em height of + // the font (issue #506). The export multiplies by the same factor. + h /= text.CapHeightFactor; text.TextSize = h; linedir.Length = h * txt.WidthFactor; if (!linedir.IsNullVector()) text.LineDirection = linedir; @@ -2559,9 +2562,10 @@ private IGeoObject CreateMText(ACadSharp.Entities.MText mText) // Automatic word wrap at the MTEXT column width (DXF group code 41) if (mText.RectangleWidth > 0) text.ColumnWidth = mText.RectangleWidth; // AutoCAD spaces MTEXT baselines 5/3 of the text height apart, scaled by the - // file's line spacing factor (DXF group code 44, default 1.0) + // file's line spacing factor (DXF group code 44, default 1.0). The text height + // is that of the capital letters, LineSpacing a factor of the em height. double factor = mText.LineSpacing > 0 ? mText.LineSpacing : 1.0; - text.LineSpacing = 5.0 / 3.0 * factor; + text.LineSpacing = 5.0 / 3.0 * factor * text.CapHeightFactor; } return geo; } diff --git a/CADability/Text.cs b/CADability/Text.cs index 0e171b09..dde4de96 100644 --- a/CADability/Text.cs +++ b/CADability/Text.cs @@ -477,6 +477,7 @@ struct FontCharacteristics readonly Dictionary centerLineCache; // Cache für die CenterLines, Größe 1 readonly Dictionary fontCharacteristicsCache; // Cache für die FontCharacteristics readonly Dictionary faces; // the faces of FontProvider.Current, per font name and bold/italic + readonly Dictionary capHeights; // see GetCapHeight public FontCache() { FontPrecision = Settings.GlobalSettings.GetIntValue("Font.Precision", 1); // |grob|mittel|fein @@ -485,6 +486,7 @@ public FontCache() centerLineCache = new Dictionary(); fontCharacteristicsCache = new Dictionary(); faces = new Dictionary(); + capHeights = new Dictionary(); } /// /// Returns the face of for a font name and a font style (the flags of @@ -521,6 +523,39 @@ internal FontFace TryGetFace(string fontName, int fontStyle) return null; } } + /// + /// The height of the capital letters of a font in units of the em height, measured at the outline of "H". A DXF or + /// DWG text height (group 40) is this height, while is the em height (issue #506). + /// Returns 1.0 when there is no font at all or the font has no "H", then both heights are taken to be the same. + /// + internal double GetCapHeight(string fontName, int fontStyle) + { + FontKey key = new FontKey(fontName ?? "", fontStyle & 3); + lock (this) + { + if (capHeights.TryGetValue(key, out double res)) return res; + res = 1.0; + FontFace face = TryGetFace(fontName, fontStyle & 3); + if (face != null && face.EmHeight > 0) + { + try + { // the outline is y downwards with the baseline at CellAscent/EmHeight, see FontFace.GetGlyphPath + face.GetGlyphPath('H', false, false, out PointF[] points, out byte[] _); + if (points.Length > 0) + { + double top = points.Min(p => p.Y); + double height = (double)face.CellAscent / face.EmHeight - top; + if (height > 0.0 && height <= 2.0) res = height; + } + } + catch (Exception ex) when (!(ex is ThreadAbortException)) + { // a glyph that cannot be read leaves the heights the same + } + } + capHeights[key] = res; + return res; + } + } // The caches are shared by all threads that measure or paint text, and Clear may empty them at any time: every access // goes through lock (this). The lock is reentrant, Get and GetCenterLines call GetOutline2D. The faces are locked // separately and always after this, so the two locks are taken in the same order everywhere. @@ -754,6 +789,7 @@ public void Clear() cache.Clear(); centerLineCache.Clear(); fontCharacteristicsCache.Clear(); + capHeights.Clear(); lock (faces) faces.Clear(); } } @@ -2358,6 +2394,21 @@ public double TextSize } } /// + /// The height of the capital letters of the font of this text as a fraction of , which is the + /// em height. DXF and DWG give the height of a text as the height of its capital letters, so import and export + /// convert with this factor (issue #506). + /// + internal double CapHeightFactor + { + get + { + int fs = 0; + if (Bold) fs |= (int)FontStyle.Bold; + if (Italic) fs |= (int)FontStyle.Italic; + return FontCache.GlobalFontCache.GetCapHeight(fontName, fs); + } + } + /// /// Width of the text column for automatic word wrapping (in world units, e.g. from a DXF MTEXT). /// The displayed text is broken into additional lines at word boundaries so that no line gets /// wider than this value. 0.0 (the default) means no automatic wrapping, only explicit line diff --git a/tests/CADability.ImportTests/DxfTextHeightTest.cs b/tests/CADability.ImportTests/DxfTextHeightTest.cs new file mode 100644 index 00000000..bacf8cb8 --- /dev/null +++ b/tests/CADability.ImportTests/DxfTextHeightTest.cs @@ -0,0 +1,143 @@ +using System; +using System.IO; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using CADability; +using CADability.GeoObject; + +namespace CADability.ImportTests +{ + /// + /// Regression for issue #506: the height of a DXF TEXT (group 40) is the height of the capital + /// letters, which AutoCAD and other viewers scale the font to, while + /// is the em height of the font. The exporter wrote TextSize unchanged, so every other program + /// showed the text 1.4 (Arial) to 1.6 (Consolas) times larger than CADability and its bounding + /// box. The font is Liberation Sans, which the tests register (see ). + /// + [TestClass] + public class DxfTextHeightTest + { + public TestContext TestContext { get; set; } + + private const string Font = "Liberation Sans"; + + [TestMethod] + public void export_dxf_text_height_is_the_height_of_the_capital_letters() + { + Text text = MakeText("H", 12.0); + double capitalHeight = OutlineHeight(text); + Assert.IsTrue(capitalHeight > 6.0 && capitalHeight < 10.0, "test setup: an H is about 0.7 em high"); + + ACadSharp.Entities.TextEntity written = ReadSingleText(Export(text)); + Assert.AreEqual(capitalHeight, written.Height, 1e-6, "group 40 is the height of the H CADability draws"); + Assert.AreEqual(1.0, written.WidthFactor, 1e-12, "group 41 of an unstretched text"); + } + + [TestMethod] + public void import_dxf_text_draws_capital_letters_as_high_as_the_text_height() + { + ACadSharp.CadDocument doc = new ACadSharp.CadDocument(); + ACadSharp.Tables.TextStyle style = new ACadSharp.Tables.TextStyle(Font) { Filename = Font + ".ttf" }; + doc.TextStyles.Add(style); + doc.Entities.Add(new ACadSharp.Entities.TextEntity + { + Value = "H", + Height = 10.0, + Style = style, + InsertPoint = new CSMath.XYZ(5, 7, 0), + }); + string file = this.TestContext.TestName + ".dxf"; + using (ACadSharp.IO.DxfWriter writer = new ACadSharp.IO.DxfWriter(file, doc, false)) writer.Write(); + + Text text = ReimportSingle(file); + Assert.AreEqual(Font, text.Font); + Assert.AreEqual(10.0, OutlineHeight(text), 1e-6, "the imported H is as high as group 40"); + } + + [TestMethod] + public void export_dxf_text_round_trip_keeps_size_width_and_extent() + { + Text text = MakeText("only 6 days left", 12.0); + // stretched to twice the width + text.LineDirection = 2.0 * text.LineDirection; + BoundingCube extent = text.GetBoundingCube(); + + string file = Export(text); + Assert.AreEqual(2.0, ReadSingleText(file).WidthFactor, 1e-9, "group 41 carries the stretch"); + + Text back = ReimportSingle(file); + Assert.AreEqual(text.TextSize, back.TextSize, 1e-6, "TextSize"); + Assert.AreEqual(text.LineDirection.Length, back.LineDirection.Length, 1e-6, "length of the line direction"); + BoundingCube backExtent = back.GetBoundingCube(); + Assert.AreEqual(extent.Xmin, backExtent.Xmin, 1e-6); + Assert.AreEqual(extent.Xmax, backExtent.Xmax, 1e-6); + Assert.AreEqual(extent.Ymin, backExtent.Ymin, 1e-6); + Assert.AreEqual(extent.Ymax, backExtent.Ymax, 1e-6); + } + + [TestMethod] + public void export_dxf_mtext_round_trip_keeps_size_and_line_spacing() + { + Text text = MakeText("first line\nsecond line", 12.0); + text.LineSpacing = 1.4; + text.Alignment = Text.AlignMode.Bottom; // MTEXT has no baseline attachment + BoundingCube extent = text.GetBoundingCube(); + + string file = Export(text); + ACadSharp.Entities.MText written = ACadSharp.IO.DxfReader.Read(file).Entities.OfType().Single(); + Assert.AreEqual(OutlineHeight(MakeText("H", 12.0)), written.Height, 1e-6, "group 40 is the height of the capital letters"); + + Text back = ReimportSingle(file); + Assert.AreEqual(text.TextSize, back.TextSize, 1e-6, "TextSize"); + Assert.AreEqual(text.LineSpacing, back.LineSpacing, 1e-6, "LineSpacing"); + BoundingCube backExtent = back.GetBoundingCube(); + Assert.AreEqual(extent.Ymin, backExtent.Ymin, 1e-6); + Assert.AreEqual(extent.Ymax, backExtent.Ymax, 1e-6); + } + + // --- helpers ------------------------------------------------------------------------- + + private static Text MakeText(string value, double size) + { + Text text = Text.Construct(); + text.Font = Font; + text.TextString = value; + text.Location = new GeoPoint(5, 7, 0); + text.LineDirection = GeoVector.XAxis; + text.GlyphDirection = GeoVector.YAxis; + text.TextSize = size; + return text; + } + + /// + /// The height of the glyphs as CADability draws them. + /// + private static double OutlineHeight(Text text) + { + BoundingCube ext = BoundingCube.EmptyBoundingCube; + foreach (IGeoObject go in text.GetOutline()) ext.MinMax(go.GetBoundingCube()); + return ext.Ymax - ext.Ymin; + } + + private string Export(IGeoObject geoObject) + { + Project project = Project.CreateSimpleProject(); + project.GetModel(0).Add(geoObject.Clone()); + string file = this.TestContext.TestName + ".dxf"; + Assert.IsTrue(project.Export(file, "dxf"), "export must succeed"); + return file; + } + + private static ACadSharp.Entities.TextEntity ReadSingleText(string file) + { + return ACadSharp.IO.DxfReader.Read(file).Entities.OfType().Single(); + } + + private static Text ReimportSingle(string file) + { + Project project = Project.ReadFromFile(file, "dxf"); + Assert.IsNotNull(project); + return project.GetActiveModel().AllObjects.OfType().Single(); + } + } +} From f31e7348d161bce4a5b35ef7d85208838bdf3990 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 10:17:48 +0000 Subject: [PATCH 2/2] Write and read DIMTXT as the height of the capital letters (#506) DIMTXT, the text height of a DXF dimension style, is the height of the capital letters like the height of a TEXT, while CADability draws the dimension text with DimensionStyle.TextSize as the em height of the font. The export now multiplies TextSize by the cap height of the style's font and the import divides by it, so imported dimensions show their text as large as AutoCAD does and a round trip keeps TextSize. TextSizeTol follows TextSize, and TextDist is computed from the converted size, which keeps the distance of the text from the dimension line at DIMGAP. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01F53kFpUYJXo4cE8wSe2jHi --- CADability/ExportDxf.cs | 5 +++- CADability/ImportDxf.cs | 13 ++++---- CADability/Text.cs | 18 ++++++----- .../DxfDimensionTest.cs | 30 ++++++++++++++++--- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/CADability/ExportDxf.cs b/CADability/ExportDxf.cs index fa635d79..0335f36b 100644 --- a/CADability/ExportDxf.cs +++ b/CADability/ExportDxf.cs @@ -1128,7 +1128,10 @@ private ACadSharp.Tables.DimensionStyle GetOrCreateDimensionStyle(CADability.Att found = new ACadSharp.Tables.DimensionStyle(candidate); doc.DimensionStyles.Add(found); } - if (style.TextSize > 0.0) found.TextHeight = style.TextSize; + // DIMTXT is the height of the capital letters like the height of a TEXT, while + // CADability draws the dimension text with TextSize as the em height (issue #506). + if (style.TextSize > 0.0) + found.TextHeight = style.TextSize * GeoObject.Text.GetCapHeightFactor(style.TextFont, false, false); found.ArrowSize = Math.Max(0.0, style.SymbolSize); found.ExtensionLineOffset = style.ExtLineOffset; found.ExtensionLineExtension = style.ExtLineExtension; diff --git a/CADability/ImportDxf.cs b/CADability/ImportDxf.cs index b76877d6..a3a6a4ed 100644 --- a/CADability/ImportDxf.cs +++ b/CADability/ImportDxf.cs @@ -2276,8 +2276,6 @@ private void MapDimensionStyle(ACadSharp.Tables.DimensionStyle acad, { double scale = acad.ScaleFactor > 0.0 ? acad.ScaleFactor : 1.0; style.Types = Attribute.DimensionStyle.ETypeFlag.DimAllTypes; - style.TextSize = acad.TextHeight * scale; - style.TextSizeTol = acad.TextHeight * acad.ToleranceScaleFactor * scale; style.SymbolSize = acad.ArrowSize * scale; style.ExtLineOffset = acad.ExtensionLineOffset * scale; style.ExtLineExtension = acad.ExtensionLineExtension * scale; @@ -2302,12 +2300,17 @@ private void MapDimensionStyle(ACadSharp.Tables.DimensionStyle acad, style.TextPrefix = arcSymbol + (acad.Prefix ?? ""); style.TextPostfix = acad.Suffix ?? ""; style.TextFont = FontNameFromStyle(acad.Style); + // DIMTXT is the height of the capital letters like the height of a TEXT, while + // CADability draws the dimension text with TextSize as the em height (issue #506). + double emHeight = acad.TextHeight * scale / GeoObject.Text.GetCapHeightFactor(style.TextFont, false, false); + style.TextSize = emHeight; + style.TextSizeTol = emHeight * acad.ToleranceScaleFactor; // DIMTAD says whether the text sits on the dimension line or above it, DIMGAP how - // far; CADability measures that distance in text heights. + // far; CADability measures that distance in multiples of TextSize. style.TextDist = acad.TextVerticalAlignment == DimensionTextVerticalAlignment.Centered - || acad.TextHeight <= 0.0 + || emHeight <= 0.0 ? 0.0 - : Math.Abs(acad.DimensionLineGap) / acad.TextHeight; + : Math.Abs(acad.DimensionLineGap) * scale / emHeight; style.Symbol = MapArrowSymbol(acad); style.DimNoExtLine1 = acad.SuppressFirstExtensionLine; style.DimNoExtLine2 = acad.SuppressSecondExtensionLine; diff --git a/CADability/Text.cs b/CADability/Text.cs index dde4de96..7c944a7e 100644 --- a/CADability/Text.cs +++ b/CADability/Text.cs @@ -2398,15 +2398,17 @@ public double TextSize /// em height. DXF and DWG give the height of a text as the height of its capital letters, so import and export /// convert with this factor (issue #506). /// - internal double CapHeightFactor + internal double CapHeightFactor => GetCapHeightFactor(fontName, Bold, Italic); + /// + /// The height of the capital letters of the font as a fraction of its em height, see + /// . Dimensions use it for the text size of their style. + /// + internal static double GetCapHeightFactor(string fontName, bool bold, bool italic) { - get - { - int fs = 0; - if (Bold) fs |= (int)FontStyle.Bold; - if (Italic) fs |= (int)FontStyle.Italic; - return FontCache.GlobalFontCache.GetCapHeight(fontName, fs); - } + int fs = 0; + if (bold) fs |= (int)FontStyle.Bold; + if (italic) fs |= (int)FontStyle.Italic; + return FontCache.GlobalFontCache.GetCapHeight(fontName, fs); } /// /// Width of the text column for automatic word wrapping (in world units, e.g. from a DXF MTEXT). diff --git a/tests/CADability.ImportTests/DxfDimensionTest.cs b/tests/CADability.ImportTests/DxfDimensionTest.cs index 4a37aa85..5e31ae14 100644 --- a/tests/CADability.ImportTests/DxfDimensionTest.cs +++ b/tests/CADability.ImportTests/DxfDimensionTest.cs @@ -565,7 +565,9 @@ public void export_dimension_writes_a_dxf_dimension() "the measurement text"); } Assert.AreEqual(project.DimensionStyleList.Current.Name, linear.Style.Name); - Assert.AreEqual(project.DimensionStyleList.Current.TextSize, linear.Style.TextHeight, 1e-12); + CADability.Attribute.DimensionStyle current = project.DimensionStyleList.Current; + Assert.AreEqual(CapitalHeight(current.TextFont, current.TextSize), linear.Style.TextHeight, 1e-8, + "DIMTXT is the height of the capital letters CADability draws (issue #506)"); } /// @@ -981,7 +983,8 @@ public void import_dxf_dimension_translates_the_dimension_style() Assert.IsNotNull(style, "a rebuilt dimension needs a style to draw with"); Assert.AreEqual("LOGICAL", style.Name, "the style should keep the name from the file"); Assert.AreSame(style, project.DimensionStyleList.Find("LOGICAL"), "the style is part of the project"); - Assert.AreEqual(7.0, style.TextSize, 1e-8, "DIMTXT 3.5 times DIMSCALE 2"); + Assert.AreEqual(7.0, CapitalHeight(style.TextFont, style.TextSize), 1e-8, + "capital letters as high as DIMTXT 3.5 times DIMSCALE 2 (issue #506)"); Assert.AreEqual(3.0, style.SymbolSize, 1e-8, "DIMASZ 1.5 times DIMSCALE 2"); Assert.AreEqual(1.0, style.ExtLineOffset, 1e-8, "DIMEXO 0.5 times DIMSCALE 2"); Assert.AreEqual(2.5, style.ExtLineExtension, 1e-8, "DIMEXE 1.25 times DIMSCALE 2"); @@ -1002,7 +1005,8 @@ public void import_dxf_dimension_uses_the_standard_style_of_the_file() Project project = ImportProjectAsDimensions(StyledPrologue + standard + Epilogue); Dimension dim = SingleDimensionObject(project.GetActiveModel()); - Assert.AreEqual(0.18, dim.DimensionStyle.TextSize, 1e-8, "DIMTXT of AutoCAD's Standard style"); + Assert.AreEqual(0.18, CapitalHeight(dim.DimensionStyle.TextFont, dim.DimensionStyle.TextSize), 1e-8, + "capital letters as high as DIMTXT of AutoCAD's Standard style"); Assert.AreEqual(0.18, dim.DimensionStyle.SymbolSize, 1e-8, "DIMASZ of AutoCAD's Standard style"); } @@ -1047,7 +1051,8 @@ public void import_dxf_dimension_style_override_does_not_leak() Dimension[] dims = model.AllObjects.OfType().ToArray(); Assert.AreEqual(2, dims.Length, "both dimensions should be rebuilt"); - double[] sizes = dims.Select(d => d.DimensionStyle.TextSize).OrderBy(t => t).ToArray(); + double[] sizes = dims.Select(d => CapitalHeight(d.DimensionStyle.TextFont, d.DimensionStyle.TextSize)) + .OrderBy(t => t).ToArray(); Assert.AreEqual(7.0, sizes[0], 1e-8, "the plain dimension keeps DIMTXT 3.5 times DIMSCALE 2"); Assert.AreEqual(18.0, sizes[1], 1e-8, "the overridden one gets 9.0 times DIMSCALE 2"); Assert.AreNotSame(dims[0].DimensionStyle, dims[1].DimensionStyle, @@ -1603,6 +1608,23 @@ private Model ExportAndImport(Project project) private static double Distance(CSMath.XYZ p, GeoPoint q) => new GeoPoint(p.X, p.Y, p.Z) | q; + /// + /// The height of an "H" that CADability draws in with the text size + /// , which is the em height. DIMTXT is this height (issue #506). + /// + private static double CapitalHeight(string font, double textSize) + { + Text text = Text.Construct(); + text.Font = font; + text.TextString = "H"; + text.LineDirection = GeoVector.XAxis; + text.GlyphDirection = GeoVector.YAxis; + text.TextSize = textSize; + BoundingCube ext = BoundingCube.EmptyBoundingCube; + foreach (IGeoObject go in text.GetOutline()) ext.MinMax(go.GetBoundingCube()); + return ext.Ymax - ext.Ymin; + } + private static Block SingleDimensionBlock(Model model) { Assert.AreEqual(1, model.Count, "the DIMENSION should import as one object");