Sé que es una vieja pregunta, pero me ha parecido muy difícil utilizar la API de CreateFontPackage
C# (como se ha mencionado por la respuesta de @ josh3736) así que pensé compartir mi código.
Estoy usando la API con los glyphIndices, puede usarla directamente con los caracteres eliminando el indicador TTFCFP_FLAGS_GLYPHLIST
.
Este es mi código:
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
);
que se utiliza con código sólo con los archivos TTF, TTC (para colecciones de fuentes) que tiene que cambiar algunas cosas pero debería funcionar, no obstante.
Me preguntaba para qué sirve la declaración de gt? No se usa después de haber sido declarado ... –
@BrianTHOMAS, sí, lo siento, fue un artefacto de más código. no se usa en este ejemplo. siéntase libre de editar el código. –