user1946932
user1946932

Reputation: 602

Letter spacing with DrawString?

In an answer to an older post at C# Drawstring Letter Spacing regarding letter spacing, I saw:

[DllImport("gdi32.dll", CharSet=CharSet.Auto)] 
public static extern int SetTextCharacterExtra( 
    IntPtr hdc,    // DC handle
    int nCharExtra // extra-space value 
); 

public void Draw(Graphics g) 
{ 
    IntPtr hdc = g.GetHdc(); 
    SetTextCharacterExtra(hdc, 24); //set spacing between characters 
    g.ReleaseHdc(hdc); 

    e.Graphics.DrawString("str",this.Font,Brushes.Black,0,0); 
}  

I tried it with both positive and negative numbers (converted to VB.NET) but it had no effect at all. Is it a valid code piece or is it incorrect?

  <DllImport("gdi32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function SetTextCharacterExtra(ByVal hdc As IntPtr, ByVal nCharExtra As Integer) As Integer
        ' extra-space value
    End Function

And in a function:

 With gClsGraphics1
            'Drawstring
            .SmoothingMode = SmoothingMode.HighQuality
            .TextRenderingHint = Text.TextRenderingHint.ClearTypeGridFit
            .CompositingQuality = CompositingQuality.HighQuality

            Dim hdc As IntPtr = .GetHdc()
            SetTextCharacterExtra(hdc, 30)
           .ReleaseHdc(hdc)

        End With

Upvotes: 0

Views: 2522

Answers (1)

TaW
TaW

Reputation: 54433

This is not an answer to the question in the body of your post, just a workaround for the question in the title.

So while I don't even try to use any legacy function I simply add spaces in between the normal characters.

Using normal spaces would be rather crude, but there are nice other whitespace characters:

char thin_space = (char)0x2009;
char hair_space = (char)0x200a;
char narrow_nbr_space = (char)0x202f;

Using a simple function like this..:

string spaced(string text, int spacing, char space)
{
    string spaces = "".PadLeft(spacing, space);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < text.Length; i++) sb.Append(text[i] + spaces);
    return sb.ToString().Trim(space);
}

..you can observe interesting differences:

enter image description here

As you can see, for single line text, the hair-space will allow the finest tuning of the pseudo character-spacing; but for multi-line text a non-breaking space is preferrable. It will still allow white space in front of the lines, though.

But as there is no practical, or at least simple workaround for the missing line spacing, the conclusion remains: Typographic support in GDI+ is poor.

Upvotes: 1

Related Questions