Skip to content

Problem with generated SDF bitmap #1

@BreyerW

Description

@BreyerW

Im trying to integrate your lib into my app and overall it works but SDF for certain characters is reeeeaaaly iffy. I tested several fonts: Arial, times, tahoma all of em have a bit of broken characters in resulting bitmap. Some characters looks like noise, some skewed, rest are ok

wrong results:

skewed n character

n_times

character d looks like noise

d_times

good results just to show that sometimes it works as expected

A character (a little strange it selected a small though)

A_times

S character

s_times

iffines in files proves there is a problem with generating SDF itself rather than rendering since bytes are saved to disk basically as-is

this is how i generate SDF: (c is of type char and passed as-is)

var index=StbTrueType.stbtt_FindGlyphIndex(face, c);
var bytes=StbTrueType.stbtt_GetGlyphSDF(face,StbTrueType.stbtt_ScaleForPixelHeight(face,24),index,1,180,180,&width,&height,&xoff,&yoff);
					StbTrueType.stbtt_GetCodepointHMetrics(face,c,&advance,&bearingX);
					var bitmap = new Span<byte>(bytes, width * height).ToArray();
					var invalidchars = Path.GetInvalidFileNameChars();
					bool allowed = true;
					foreach(var invalid in invalidchars)
					{
						allowed = invalid != c;
					}
					if (c!=':' && allowed)
						using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))
						{

							var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
							System.Runtime.InteropServices.Marshal.Copy(bitmap, 0, bmpdata.Scan0, bitmap.Length);
							bmp.UnlockBits(bmpdata);
							bmp.Save(@"B:\Sharp.Engine3\Sharp.Core\bin\Debug\netcoreapp3.1\" + c+"_"+fontName + ".png");
						}

I tried several parameters ones you see there and ones that can be seen in stb_truetype original work, some of my own invention none of them produces fully correct bitmaps

Since i mentioned that character 'A' turned into 'a' in picture does it mean i must preprocess standard .NET char c into codepoint understandable for stb_truetype?

Other than that im completely lost. Any ideas what might be wrong?

EDIT

normalizing string and/or converting to codepoints like this didnt work:

public static int[] ToCodePoints(string str)
{
    if (str == null)
        throw new ArgumentNullException("str");

    var codePoints = new List<int>(str.Length);
    for (int i = 0; i < str.Length; i++)
    {
        codePoints.Add(Char.ConvertToUtf32(str, i));
        if (Char.IsHighSurrogate(str[i]))
            i += 1;
    }

    return codePoints.ToArray();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions