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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions