gpt4 book ai didi

c# - 确定指定字体的确切字形高度

转载 作者:可可西里 更新时间:2023-11-01 08:44:26 25 4
gpt4 key购买 nike

我已经搜索了很多,尝试了很多,但我找不到合适的解决方案。

我想知道是否有任何方法可以确定指定字体中的精确 字形高度

我的意思是,当我想确定 DOT 字形的高度时,我应该收到较小的高度,而不是带填充的高度或字体大小。

我找到了确定精确 字形宽度的解决方案 here (我使用了第二种方法)但它不适用于高度。

更新:我需要 .NET 1.1 的解决方案

最佳答案

获取字符指标并不难。 GDI 包含一个函数 GetGlyphOutline您可以使用 GGO_METRICS 常量调用,以获取呈现时包含字形所需的最小 封闭矩形的高度和宽度。即,Arial 字体中点的 10 点字形将给出 1x1 像素的矩形,如果字体大小为 100 点,则字母 I 为 95x.14。

这些是 P/Invoke 调用的声明:

// the declarations
public struct FIXED
{
public short fract;
public short value;
}

public struct MAT2
{
[MarshalAs(UnmanagedType.Struct)] public FIXED eM11;
[MarshalAs(UnmanagedType.Struct)] public FIXED eM12;
[MarshalAs(UnmanagedType.Struct)] public FIXED eM21;
[MarshalAs(UnmanagedType.Struct)] public FIXED eM22;
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}

[StructLayout(LayoutKind.Sequential)]
public struct POINTFX
{
[MarshalAs(UnmanagedType.Struct)] public FIXED x;
[MarshalAs(UnmanagedType.Struct)] public FIXED y;
}

[StructLayout(LayoutKind.Sequential)]
public struct GLYPHMETRICS
{

public int gmBlackBoxX;
public int gmBlackBoxY;
[MarshalAs(UnmanagedType.Struct)] public POINT gmptGlyphOrigin;
[MarshalAs(UnmanagedType.Struct)] public POINTFX gmptfxGlyphOrigin;
public short gmCellIncX;
public short gmCellIncY;

}

private const int GGO_METRICS = 0;
private const uint GDI_ERROR = 0xFFFFFFFF;

[DllImport("gdi32.dll")]
static extern uint GetGlyphOutline(IntPtr hdc, uint uChar, uint uFormat,
out GLYPHMETRICS lpgm, uint cbBuffer, IntPtr lpvBuffer, ref MAT2 lpmat2);

[DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

如果您不考虑 P/Invoke 冗余,实际代码相当简单。我测试了代码,它有效(您也可以调整以从 GLYPHMETRICS 获取宽度)。

注意:这是临时代码,在现实世界中,您应该使用 ReleaseHandleDeleteObject 清理 HDC 和对象。感谢 user2173353 指出这一点的评论。

// if you want exact metrics, use a high font size and divide the result
// otherwise, the resulting rectangle is rounded to nearest int
private int GetGlyphHeight(char letter, string fontName, float fontPointSize)
{
// init the font. Probably better to do this outside this function for performance
Font font = new Font(new FontFamily(fontName), fontPointSize);
GLYPHMETRICS metrics;

// identity matrix, required
MAT2 matrix = new MAT2
{
eM11 = {value = 1},
eM12 = {value = 0},
eM21 = {value = 0},
eM22 = {value = 1}
};

// HDC needed, we use a bitmap
using(Bitmap b = new Bitmap(1,1))
using (Graphics g = Graphics.FromImage(b))
{
IntPtr hdc = g.GetHdc();
IntPtr prev = SelectObject(hdc, font.ToHfont());
uint retVal = GetGlyphOutline(
/* handle to DC */ hdc,
/* the char/glyph */ letter,
/* format param */ GGO_METRICS,
/* glyph-metrics */ out metrics,
/* buffer, ignore */ 0,
/* buffer, ignore */ IntPtr.Zero,
/* trans-matrix */ ref matrix);

if(retVal == GDI_ERROR)
{
// something went wrong. Raise your own error here,
// or just silently ignore
return 0;
}


// return the height of the smallest rectangle containing the glyph
return metrics.gmBlackBoxY;
}
}

关于c# - 确定指定字体的确切字形高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9924066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com