调整附注内容

This commit is contained in:
sladro 2026-01-07 15:19:56 +08:00
parent 041940be17
commit 5cfad1923a
2 changed files with 208 additions and 59 deletions

View File

@ -982,7 +982,7 @@ namespace CadParamPluging.Cad
var searchRegionMinX = f.MaxPoint.X - 200.0; // Assume title block width < 200
var searchRegionMinY = f.MinPoint.Y;
var searchRegionMaxY = f.MinPoint.Y + 150.0; // Assume title block height < 150
var searchRegionMaxY = f.MinPoint.Y + 80.0; // Reduce to avoid picking up drawing lines (Title block usually < 80mm)
double tableTopY = f.MinPoint.Y + 60.0; // Default fallback (e.g. 60mm from bottom)
@ -1032,22 +1032,58 @@ namespace CadParamPluging.Cad
var insertY = tableTopY + 2.0;
var insertPoint = new Point3d(insertX, insertY, 0);
var textHeight = 3.2; // 9号字 (interpreted as 9pt approx 3.2mm)
var mt = new MText();
mt.Contents = ToMTextContents(textToShow);
// Set font to SimSun (宋体)
mt.Contents = @"{\fSimSun|b0|i0|c134|p2;" + ToMTextContents(textToShow) + "}";
mt.Location = insertPoint;
mt.TextHeight = 5.0;
mt.Attachment = AttachmentPoint.BottomRight; // Anchor at bottom-right, grows up and left
mt.TextHeight = textHeight;
mt.Attachment = AttachmentPoint.BottomRight; // Anchor at bottom-right
mt.Width = 0; // No wrap width, auto
mt.ColorIndex = 7;
mt.ColorIndex = 7; // White
// Create White Border
// Estimate dimensions: Chinese char width approx equals height
// Adding padding to visually center the text in the box
double charWidthFactor = 1.0;
double estimatedTextWidth = textToShow.Length * textHeight * charWidthFactor;
double paddingH = 1.5; // Horizontal padding
double paddingV = 1.5; // Vertical padding
// Since Attachment is BottomRight:
// Text occupies roughly: [X - Width, X] x [Y, Y + Height]
// We draw box around this area with padding
var boxMinX = insertX - estimatedTextWidth - paddingH;
var boxMaxX = insertX + paddingH;
var boxMinY = insertY - paddingV;
var boxMaxY = insertY + textHeight + paddingV;
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(boxMinX, boxMinY), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(boxMaxX, boxMinY), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(boxMaxX, boxMaxY), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(boxMinX, boxMaxY), 0, 0, 0);
poly.Closed = true;
poly.ColorIndex = 7; // White (Index 7 is White/Black depending on bg, usually White for plot)
try
{
var layerTbl = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
if (layerTbl.Has("TEXT")) mt.Layer = "TEXT";
else if (layerTbl.Has("文字")) mt.Layer = "文字";
else mt.Layer = "0";
string targetLayer = "0";
if (layerTbl.Has("TEXT")) targetLayer = "TEXT";
else if (layerTbl.Has("文字")) targetLayer = "文字";
// Assign layer to both MText and Box
mt.Layer = targetLayer;
poly.Layer = targetLayer;
}
catch { mt.Layer = "0"; }
catch { }
space.AppendEntity(poly);
tr.AddNewlyCreatedDBObject(poly, true);
space.AppendEntity(mt);
tr.AddNewlyCreatedDBObject(mt, true);

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace CadParamPluging.Common
{
@ -182,78 +183,190 @@ namespace CadParamPluging.Common
{
templateText = templateText ?? string.Empty;
// Normalize newlines to \n
var s = NormalizeNewLines(templateText);
// Split into lines to process removal logic
var lines = s.Split(new[] { '\n' }, StringSplitOptions.None);
// Build map
var map = new Dictionary<int, string>();
foreach (var b in bindings ?? Enumerable.Empty<NotePlaceholderBinding>())
{
if (b == null)
if (b != null && b.Index > 0 && !string.IsNullOrWhiteSpace(b.ParamKey))
{
continue;
}
if (b.Index <= 0)
{
continue;
}
var key = (b.ParamKey ?? string.Empty).Trim();
if (key.Length == 0)
{
continue;
}
var key = b.ParamKey.Trim();
if (!map.ContainsKey(b.Index))
{
map[b.Index] = key;
}
}
}
var sb = new StringBuilder(s.Length + 64);
var resultLines = new List<string>();
var placeholderIndex = 0;
for (var i = 0; i < s.Length;)
foreach (var line in lines)
{
if (s[i] != '*')
// 1. Scan line to determine if it should be skipped (if any param value is "空")
bool shouldSkip = false;
int localPlaceholderCount = 0;
// We must traverse the line to find placeholders correctly to sync index
for (int i = 0; i < line.Length; )
{
if (line[i] != '*')
{
sb.Append(s[i]);
i++;
continue;
}
var j = i;
while (j < s.Length && s[j] == '*')
// Check for escape ****
int j = i;
while (j < line.Length && line[j] == '*') j++;
if (j - i == 4)
{
j++;
// **** counts as text, not placeholder
i = j;
continue;
}
var runLen = j - i;
if (runLen == 4)
// Run of * (length != 4)
int runLen = j - i;
for (int k = 0; k < runLen; k++)
{
localPlaceholderCount++;
int currentIdx = placeholderIndex + localPlaceholderCount;
if (map.TryGetValue(currentIdx, out var key) && getValue != null)
{
var val = getValue(key);
// Check for strict "空"
if (string.Equals(val, "空", StringComparison.OrdinalIgnoreCase))
{
// Exception: MarkingContent (标刻内容) should NOT cause line skip
if (!string.Equals(key, "MarkingContent", StringComparison.OrdinalIgnoreCase))
{
shouldSkip = true;
}
}
}
}
i = j;
}
// 2. If line is skipped, just update global index and continue
if (shouldSkip)
{
placeholderIndex += localPlaceholderCount;
continue;
}
// 3. If line matches, render it
// We re-scan to apply values.
// Using a temp index starting from where we were
var sb = new StringBuilder(line.Length + 64);
int tempIdx = placeholderIndex;
for (int i = 0; i < line.Length; )
{
if (line[i] != '*')
{
sb.Append(line[i]);
i++;
continue;
}
int j = i;
while (j < line.Length && line[j] == '*') j++;
if (j - i == 4)
{
sb.Append("****");
i = j;
continue;
}
for (var k = 0; k < runLen; k++)
int runLen = j - i;
for (int k = 0; k < runLen; k++)
{
placeholderIndex++;
if (map.TryGetValue(placeholderIndex, out var key) && getValue != null)
tempIdx++;
if (map.TryGetValue(tempIdx, out var key) && getValue != null)
{
var v = getValue(key);
if (!string.IsNullOrWhiteSpace(v))
{
// Handle "空" value
if (string.Equals(v, "空", StringComparison.OrdinalIgnoreCase))
{
if (string.Equals(key, "MarkingContent", StringComparison.OrdinalIgnoreCase))
{
// MarkingContent -> render empty string
// (Separators will be cleaned up later)
}
else
{
// Other keys -> render empty (should imply hidden line,
// but if we are here, it means some OTHER key prevented hiding?
// Or this case shouldn't happen if mixed?
// Assuming if line is not skipped, we treat "空" as empty string.)
}
}
else
{
sb.Append(v);
continue;
}
}
else
{
// Keep * if value is missing/empty (but not "空" which was handled)
sb.Append('*');
}
}
else
{
sb.Append('*');
}
}
i = j;
}
return sb.ToString();
var renderedLine = sb.ToString();
// 3.1 Clean up redundant separators for MarkingContent removal
// Replace "、、" with "、"
renderedLine = Regex.Replace(renderedLine, @"、\s*、", "、");
// Replace ":、" with "" (start of list)
renderedLine = Regex.Replace(renderedLine, @"([:])\s*、", "$1");
// Replace "、。" with "。" (end of list)
renderedLine = Regex.Replace(renderedLine, @"、\s*([。.;])", "$1");
// Trim trailing "、" if it exists (no period)
renderedLine = Regex.Replace(renderedLine, @"、\s*$", "");
resultLines.Add(renderedLine);
placeholderIndex += localPlaceholderCount;
}
// 4. Renumbering Logic
var renumberRegex = new Regex(@"^(\s*)(\d+)([、\.])");
int counter = 1;
for (int i = 0; i < resultLines.Count; i++)
{
var match = renumberRegex.Match(resultLines[i]);
if (match.Success)
{
var prefix = match.Groups[1].Value;
var suffix = match.Groups[3].Value;
var newLine = prefix + counter + suffix + resultLines[i].Substring(match.Length);
resultLines[i] = newLine;
counter++;
}
}
return string.Join("\n", resultLines);
}
/// <summary>