2011-10-20 23 views
3

System.Drawing.Fontを使用すると、文字サイズを変更できるように、文字間隔を変更する方法はありますか?System.Drawing.Font - 文字間隔を変更しますか?

特定の幅に合わせて文字間隔を広げようとしています。

これができない場合は、希望する効果を得るための選択肢がありますか?例えば、私の特定の幅に適合する複数のグラフィックを持つ簡単な方法はありますか?

+0

このフォントはどこで使用していますか?それを使っているのは何ですか? – musefan

+0

GDI +イメージで 'Graphics.DrawString() 'と使用されています – Curt

+0

' System.Drawing'に文字間隔を調整してテキストを描画する組み込みのメカニズムはありません。そのために独自のコードをロールバックする必要があります。まず、MeasureCharacterRangesを見てみましょう。 –

答えて

4

私はDrawStringで文字間の間隔のような詳細を指定することはできませんが、希望の幅に基づいて間隔を計算し、それぞれの文字を描画するヘルパー関数を作成すると思います。

あなたはおそらく文字あたりMeasureStringに一つだけの呼び出しを行うために、これを最適化することができ

public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth) 
    { 
     //Calculate spacing 
     float widthNeeded = 0; 
     foreach (char c in text) 
     { 
      widthNeeded += g.MeasureString(c.ToString(), font).Width; 
     } 
     float spacing = (desiredWidth - widthNeeded)/(text.Length - 1); 

     //draw text 
     float indent = 0; 
     foreach (char c in text) 
     { 
      g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y)); 
      indent += g.MeasureString(c.ToString(), font).Width + spacing; 
     } 
    } 

...これを試してみて、あなたが取得する方法を参照してください。あるいは編集(私はとにかく、より正確であると信じて)配列

を取得するためにMeasureCharacterRangesを使用します。ここでは代わりにMeasureCharacterRangesを使用した例です...

public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth) 
    { 
     //Calculate spacing 
     float widthNeeded = 0; 
     Region[] regions = g.MeasureCharacterRanges(text, font, new RectangleF(point, new SizeF(desiredWidth, font.Height + 10)), StringFormat.GenericDefault); 
     float[] widths = new float[regions.Length]; 
     for(int i = 0; i < widths.Length; i++) 
     { 
      widths[i] = regions[i].GetBounds(g).Width; 
      widthNeeded += widths[i]; 
     } 
     float spacing = (desiredWidth - widthNeeded)/(text.Length - 1); 

     //draw text 
     float indent = 0; 
     int index = 0; 
     foreach (char c in text) 
     { 
      g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y)); 
      indent += widths[index] + spacing; 
      index++; 
     } 
    } 
+2

+1これは良い方法です。しかし、一定のスペーシングスクック[text kerning](http://ja.wikipedia.org/wiki/Kerning)を正しく実行することは困難です。言い換えれば、ウィキペディアを引用するために、結果は適切なカーニングと同じように視覚的に満足できるものではありません。 – Groo

+0

これは、1文字===グリフであると仮定すると、やや素朴なアプローチです。二重、結紮などはありません。 ASCIIテーブルの下半分。 – olegz

0

このコードは、新しい行をサポートしていますテキストを返し、Imageオブジェクトを返します。

public static Image ConvertTextToImage(String text, Font font, Color textColor, int spacing = 0) 
{ 
    var textParts = SplitOnBreakLines(text); 
    // dummy image, just create drawing 
    var img = new Bitmap(1, 1); 
    var drawing = Graphics.FromImage(img); 
    // calculate width, height 
    var width = 0.0F; 
    foreach (char c in text) 
    { 
     width += drawing.MeasureString(c.ToString(), font).Width; 
    }   
    width = (width + spacing * (ClearBreakLines(text).Length - 1))/textParts.Length; 
    if (width <= 0) 
     width = 1; 
    var height = font.Height * textParts.Length; 
    // clear and create new objects 
    img.Dispose(); 
    drawing.Dispose(); 

    img = new Bitmap((int)width, (int)height); 
    drawing = Graphics.FromImage(img); 

    //Adjust for high quality 
    drawing.CompositingQuality = CompositingQuality.HighQuality; 
    drawing.InterpolationMode = InterpolationMode.HighQualityBilinear; 
    drawing.PixelOffsetMode = PixelOffsetMode.HighQuality; 
    drawing.SmoothingMode = SmoothingMode.HighQuality; 
    drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; 

    //paint the background 
    drawing.Clear(Color.Transparent); 

    //create a brush for the text 
    var textBrush = new SolidBrush(textColor); 
    //write text 
    var indent = 0.0F; 
    var point = new Point();    
    foreach (var textPart in textParts) 
    { 
     foreach (char c in textPart) 
     { 
      drawing.DrawString(c.ToString(), font, textBrush, new PointF(point.X + indent, point.Y)); 
      indent += drawing.MeasureString(c.ToString(), font).Width + spacing; 
     } 
     indent = 0.0F; 
     point.Y += font.Height; 
    } 
    drawing.Save(); 
    textBrush.Dispose(); 
    drawing.Dispose(); 
    return img;   
} 

public static string ClearBreakLines(string s) 
{ 
    return Regex.Replace(s, @"\r\n?|\n", string.Empty); 
} 

public static string[] SplitOnBreakLines(string s) 
{ 
    return Regex.Split(s, @"\r\n?|\n");   
} 
関連する問題