调整附注内容
This commit is contained in:
parent
041940be17
commit
5cfad1923a
@ -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);
|
||||
|
||||
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CadParamPluging.Common
|
||||
{
|
||||
@ -181,79 +182,191 @@ namespace CadParamPluging.Common
|
||||
public static string Render(string templateText, IEnumerable<NotePlaceholderBinding> bindings, Func<string, string> getValue)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!map.ContainsKey(b.Index))
|
||||
{
|
||||
map[b.Index] = key;
|
||||
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; )
|
||||
{
|
||||
sb.Append(s[i]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (line[i] != '*')
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var j = i;
|
||||
while (j < s.Length && s[j] == '*')
|
||||
{
|
||||
j++;
|
||||
}
|
||||
// Check for escape ****
|
||||
int j = i;
|
||||
while (j < line.Length && line[j] == '*') j++;
|
||||
|
||||
if (j - i == 4)
|
||||
{
|
||||
// **** counts as text, not placeholder
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
|
||||
var runLen = j - i;
|
||||
if (runLen == 4)
|
||||
{
|
||||
sb.Append("****");
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var k = 0; k < runLen; k++)
|
||||
{
|
||||
placeholderIndex++;
|
||||
if (map.TryGetValue(placeholderIndex, out var key) && getValue != null)
|
||||
// Run of * (length != 4)
|
||||
int runLen = j - i;
|
||||
for (int k = 0; k < runLen; k++)
|
||||
{
|
||||
var v = getValue(key);
|
||||
if (!string.IsNullOrWhiteSpace(v))
|
||||
localPlaceholderCount++;
|
||||
int currentIdx = placeholderIndex + localPlaceholderCount;
|
||||
|
||||
if (map.TryGetValue(currentIdx, out var key) && getValue != null)
|
||||
{
|
||||
sb.Append(v);
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.Append('*');
|
||||
i = j;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int runLen = j - i;
|
||||
for (int k = 0; k < runLen; k++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep * if value is missing/empty (but not "空" which was handled)
|
||||
sb.Append('*');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append('*');
|
||||
}
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
// 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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user