印章製作的關鍵在於:**如何將字符沿圓弧或橢圓弧均勻分佈**。本文以圓形印章為例,橢圓僅需在弧長計算與座標映射上擴展,核心邏輯一致。
Graphics.TranslateTransform + RotateTransform 將每字符繪製至對應切線方向。private float ComputeStringLength(string text, Graphics g,
float[] charWidths, float intervalWidth, CharDirection direction)
{
// 1. 量測整體尺寸(取得初略矩形)
var sf = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap | StringFormatFlags.LineLimit);
SizeF size = g.MeasureString(text, _font, int.MaxValue, sf);
RectangleF layoutRect = new RectangleF(0, 0, size.Width, size.Height);
// 2. 精確量測每個字符獨立區域
var ranges = new CharacterRange[text.Length];
for (int i = 0; i < text.Length; i++)
ranges[i] = new CharacterRange(i, 1);
sf.FormatFlags = StringFormatFlags.NoClip;
sf.SetMeasurableCharacterRanges(ranges);
sf.Alignment = StringAlignment.Near;
Region[] regions = g.MeasureCharacterRanges(text, _font, layoutRect, sf);
// 3. 累加實際字符寬度 + 間距
float total = 0f;
for (int i = 0; i < regions.Length; i++)
{
float w = (direction == CharDirection.Center || direction == CharDirection.Outside)
? regions[i].GetBounds(g).Width
: regions[i].GetBounds(g).Height;
charWidths[i] = w;
total += w + intervalWidth;
}
return total - intervalWidth; // 扣除末尾多餘間距
}
private void DrawTextOnArc(Graphics g, string text, float radius, float startAngle,
float[] charWidths, float interval, CharDirection dir)
{
float currentAngle = startAngle;
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
float charW = charWidths[i];
// 1. 計算字符中心對應的極座標角度(弧度制)
float halfCharAngle = (charW / 2f) / radius; // 弧長 = 半徑 × 角度
float charCenterAngle = currentAngle + halfCharAngle;
// 2. 計算字符中心點笛卡爾座標
float cx = centerX + radius * (float)Math.Cos(charCenterAngle);
float cy = centerY + radius * (float)Math.Sin(charCenterAngle);
// 3. 設定繪圖變換:平移到字符中心 → 旋轉到切線方向 → 繪製
g.TranslateTransform(cx, cy);
g.RotateTransform((float)(charCenterAngle * 180 / Math.PI) + 90); // 切線方向 = 半徑方向 + 90°
// 4. 繪製單字符(原點在基線左下角,需微調)
g.DrawString(c.ToString(), _font, _brush, -charW/2, -_font.Height/2);
g.ResetTransform(); // 重置變換供下一字符
// 5. 更新下一字符起始角度
currentAngle += (charW + interval) / radius;
}
}
enum CharDirection { Center, Outside, Inside }
// Center: 字符基線在圓周上
// Outside: 字符向外輻射(印章外圈文字常用)
// Inside: 字符向內輻射(印章內圈文字常用)
橢圓擴展重點:將半徑 `radius` 替換為橢圓參數方程,弧長計算需用橢圓積分或拉馬努金近似公式,座標映射改為 `x = a*cos(t), y = b*sin(t)`,切線角度同理推導。
掌握 MeasureCharacterRanges 精確度量、弧長-角度換算、GDI+ 座標變換三大核心,即可實現高質量印章文字排版。完整專案可封裝為 SealGenerator 元件,支援雙圈文字、五角星、圖片水印等豐富功能。