制作印章來說,主要是如何讓字均勻的顯示在弧線段上,那麼一般的印章要麼以圓或者橢圓為底圖,不過這兩者的算法大致相同,為了方便說明,如下就用相對簡單的圓來舉例說明,如果需要做橢圓的話,可以在我的基礎上進行擴展,因為核心算法是一樣的,相對於圓來說,橢圓求弧長以及各個字符的位置,這兩點相對麻煩些,但是這兩者都可找到相應的數學公式。
這裡首先提一點,我這篇文章部分借鑒了codeproject的一個例子,原文可以參看如下地址。
http://www.codeproject.com/vb/net/Text_on_Path_with_VBNET.asp
(說實話,這篇文章寫得有些亂,而且對於buffer的操作近乎於瘋狂)
由於印章的實現相對於這篇文章來說,相對簡單多了,而且規律性很強,因此我自己考慮重新組織算法進行實現。
那麼實現一個印章,大致步驟如下。
1.計算字符串總長度,以及各個字符的長度;
2.計算出字符串的起始角度;
3.求出每個字符的所在的點,以及相對於中心的角度;
4.繪制每個字符。
計算字符串總長度,以及各個字符的長度
這裡需要用到“Graphics.MeasureString”和“Graphics.MeasureCharacterRanges”這兩個方法,由於前者算出來的總長度有問題,所以需要後面進行重新計算(此外,這裡我還考慮了字符最後顯示方向)。
這部分的代碼如下:
Code
[copy to clipboard]
CODE:
/// <summary>
/// Compute string total length and every char length
/// </summary>
/// <param name="sText"></param>
/// <param name="g"></param>
/// <param name="fCharWidth"></param>
/// <param name="fIntervalWidth"></param>
/// <returns></returns>
private float ComputeStringLength( string sText, Graphics g, float[] fCharWidth,
float fIntervalWidth,
Char_Direction Direction )
{
// Init string format
StringFormat sf = new StringFormat();
sf.Trimming = StringTrimming.None;
sf.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
// Measure whole string length
SizeF size = g.MeasureString( sText, _font, (int)_font.Style );
RectangleF rect = new RectangleF( 0f,0f, size.Width, size.Height );
// Measure every character size
CharacterRange[] crs = new CharacterRange[sText.Length];
for( int i = 0; i < sText.Length; i++ )
crs = new CharacterRange( i, 1 );
// Reset string format
sf.FormatFlags = StringFormatFlags.NoClip;
sf.SetMeasurableCharacterRanges( crs );
sf.Alignment = StringAlignment.Near;
// Get every character size
Region[] regs = g.MeasureCharacterRanges( sText,_font, rect, sf );
// Re-compute whole string length with space interval width
float fTotalWidth = 0f;
for( int i = 0; i < regs.Length; i++ )
{
if( Direction == Char_Direction.Center || Direction == Char_Direction.OutSide )
fCharWidth = regs.GetBounds( g ).Width;
else
fCharWidth = regs.GetBounds( g ).Height;
fTotalWidth += fCharWidth + fIntervalWidth;
}
fTotalWidth -= fIntervalWidth;//Remove the last interval width
return fTotalWidth;
}