gpt4 book ai didi

asp.net - 有没有办法以编程方式确定字体文件是否具有特定的Unicode字形?

转载 作者:行者123 更新时间:2023-12-03 08:58:48 25 4
gpt4 key购买 nike

我正在开发一个项目,该项目生成的PDF可能包含相当复杂的数学和科学公式。文本以Times New Roman呈现,它具有相当好的Unicode覆盖范围,但并不完整。我们有一个系统可以将更完整的Unicode完整字体替换为TNR中没有字形的代码点(例如大多数“陌生人”数学符号),但是我似乎找不到一种查询方法* .ttf文件,以查看是否存在给定的字形。到目前为止,我只是对存在代码点的查找表进行了硬编码,但是我更喜欢自动解决方案。

我在ASP.net下的Web系统中使用VB.Net,但是任何编程语言/环境下的解决方案都将不胜感激。

编辑:win32解决方案看起来很棒,但是我要解决的特定情况是在ASP.Net Web系统中。是否可以在不将Windows API DLL包含到我的网站中的情况下执行此操作?

最佳答案

这是使用C#和Windows API的传递。

[DllImport("gdi32.dll")]
public static extern uint GetFontUnicodeRanges(IntPtr hdc, IntPtr lpgs);

[DllImport("gdi32.dll")]
public extern static IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

public struct FontRange
{
public UInt16 Low;
public UInt16 High;
}

public List<FontRange> GetUnicodeRangesForFont(Font font)
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr hdc = g.GetHdc();
IntPtr hFont = font.ToHfont();
IntPtr old = SelectObject(hdc, hFont);
uint size = GetFontUnicodeRanges(hdc, IntPtr.Zero);
IntPtr glyphSet = Marshal.AllocHGlobal((int)size);
GetFontUnicodeRanges(hdc, glyphSet);
List<FontRange> fontRanges = new List<FontRange>();
int count = Marshal.ReadInt32(glyphSet, 12);
for (int i = 0; i < count; i++)
{
FontRange range = new FontRange();
range.Low = (UInt16)Marshal.ReadInt16(glyphSet, 16 + i * 4);
range.High = (UInt16)(range.Low + Marshal.ReadInt16(glyphSet, 18 + i * 4) - 1);
fontRanges.Add(range);
}
SelectObject(hdc, old);
Marshal.FreeHGlobal(glyphSet);
g.ReleaseHdc(hdc);
g.Dispose();
return fontRanges;
}

public bool CheckIfCharInFont(char character, Font font)
{
UInt16 intval = Convert.ToUInt16(character);
List<FontRange> ranges = GetUnicodeRangesForFont(font);
bool isCharacterPresent = false;
foreach (FontRange range in ranges)
{
if (intval >= range.Low && intval <= range.High)
{
isCharacterPresent = true;
break;
}
}
return isCharacterPresent;
}

然后,给要检查的字符char和要使用的Font theFont进行测试...
if (!CheckIfCharInFont(toCheck, theFont) {
// not present
}

使用VB.Net的相同代码
<DllImport("gdi32.dll")> _
Public Shared Function GetFontUnicodeRanges(ByVal hds As IntPtr, ByVal lpgs As IntPtr) As UInteger
End Function

<DllImport("gdi32.dll")> _
Public Shared Function SelectObject(ByVal hDc As IntPtr, ByVal hObject As IntPtr) As IntPtr
End Function

Public Structure FontRange
Public Low As UInt16
Public High As UInt16
End Structure

Public Function GetUnicodeRangesForFont(ByVal font As Font) As List(Of FontRange)
Dim g As Graphics
Dim hdc, hFont, old, glyphSet As IntPtr
Dim size As UInteger
Dim fontRanges As List(Of FontRange)
Dim count As Integer

g = Graphics.FromHwnd(IntPtr.Zero)
hdc = g.GetHdc()
hFont = font.ToHfont()
old = SelectObject(hdc, hFont)
size = GetFontUnicodeRanges(hdc, IntPtr.Zero)
glyphSet = Marshal.AllocHGlobal(CInt(size))
GetFontUnicodeRanges(hdc, glyphSet)
fontRanges = New List(Of FontRange)
count = Marshal.ReadInt32(glyphSet, 12)

For i = 0 To count - 1
Dim range As FontRange = New FontRange
range.Low = Marshal.ReadInt16(glyphSet, 16 + (i * 4))
range.High = range.Low + Marshal.ReadInt16(glyphSet, 18 + (i * 4)) - 1
fontRanges.Add(range)
Next

SelectObject(hdc, old)
Marshal.FreeHGlobal(glyphSet)
g.ReleaseHdc(hdc)
g.Dispose()

Return fontRanges
End Function

Public Function CheckIfCharInFont(ByVal character As Char, ByVal font As Font) As Boolean
Dim intval As UInt16 = Convert.ToUInt16(character)
Dim ranges As List(Of FontRange) = GetUnicodeRangesForFont(font)
Dim isCharacterPresent As Boolean = False

For Each range In ranges
If intval >= range.Low And intval <= range.High Then
isCharacterPresent = True
Exit For
End If
Next range
Return isCharacterPresent
End Function

关于asp.net - 有没有办法以编程方式确定字体文件是否具有特定的Unicode字形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/103725/

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