Я знаю, что это старый вопрос, но мне было очень трудно использовать CreateFontPackage
API из C # (как упоминалось в ответе @ josh3736), поэтому я решил поделиться своим кодом.
Я используюAPI с glyphIndices, вы можете использовать его непосредственно с символами, удалив флаг TTFCFP_FLAGS_GLYPHLIST
.
Это мой код:
public byte[] CreateSubset(byte[] inputData, IEnumerable<ushort> glyphIndices)
{
AllocProc allocProc = Marshal.AllocHGlobal;
ReallocProc reallocProc = (p, c) =>
p == IntPtr.Zero
? Marshal.AllocHGlobal(c)
: Marshal.ReAllocHGlobal(p, c);
FreeProc freeProc = Marshal.FreeHGlobal;
var resultCode = CreateFontPackage(
inputData, (uint) inputData.Length,
out var bufferPtr,
out _,
out var bytesWritten,
TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST,
0,
TTFMFP_SUBSET,
0,
TTFCFP_MS_PLATFORMID,
TTFCFP_UNICODE_CHAR_SET,
glyphIndices,
(ushort)glyphIndices.Length,
allocProc, reallocProc, freeProc, (IntPtr)0);
if (resultCode != 0 || bufferPtr == IntPtr.Zero)
{
return null;
}
try
{
var buffer = new byte[bytesWritten];
Marshal.Copy(bufferPtr, buffer, 0, buffer.Length);
return buffer;
}
finally
{
freeProc(bufferPtr);
}
}
internal const ushort TTFCFP_FLAGS_SUBSET = 0x0001;
internal const ushort TTFCFP_FLAGS_COMPRESS = 0x0002;
internal const ushort TTFCFP_FLAGS_TTC = 0x0004;
internal const ushort TTFCFP_FLAGS_GLYPHLIST = 0x0008;
internal const ushort TTFMFP_SUBSET = 0x0000;
internal const ushort TTFCFP_UNICODE_PLATFORMID = 0x0000;
internal const ushort TTFCFP_MS_PLATFORMID = 0x0003;
internal const ushort TTFCFP_UNICODE_CHAR_SET = 0x0001;
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private delegate IntPtr AllocProc(Int32 size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private delegate IntPtr ReallocProc(IntPtr memBlock, IntPtr size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private delegate void FreeProc(IntPtr memBlock);
[DllImport("FontSub.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
private static extern uint CreateFontPackage(
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
byte[] puchSrcBuffer,
uint ulSrcBufferSize,
out IntPtr puchFontPackageBufferPtr,
out uint pulFontPackageBufferSize,
out uint pulBytesWritten,
ushort usFlags,
ushort usTtcIndex,
ushort usSubsetFormat,
ushort usSubsetLanguage,
ushort usSubsetPlatform,
ushort usSubsetEncoding,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 12)]
ushort[] pusSubsetKeepList,
ushort usSubsetKeepListCount,
AllocProc lpfnAllocate,
ReallocProc lpfnReAllocate,
FreeProc lpfnFree,
IntPtr lpvReserved
);
Я использовал с кодом только с файлами TTF,для TTC (наборов шрифтов) вы должны изменить несколько вещей, но, тем не менее, это должно работать.