Using CreateFontPackage in FontSub.dll
-
Thursday, December 30, 2010 2:42 AM
Hi,
I found samples of how to use CreateFontPackage in the C# forums however after my poor attempt at converting the C# code over to VB code (using VS 2010) I'm ending up with a PInvoke unbalanced stack error when the function is called. I've searched for hours looking for VB code to call this function and it just looks like it has not been done under VB.NET or for some reason the API cannot be called in VB.NET.
Would like to be able to get this working is it will help to reduce the output file size of the XPS files I am creating.
This is the code I ended up with...
Imports System Imports System.IO Imports System.Runtime.InteropServices Public Class SubsetFont <UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _ Public Delegate Function ALLOCPROC(ByVal Sze As Int32) As IntPtr <UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _ Public Delegate Function REALLOCPROC(ByVal MemBlock As IntPtr, ByVal Sze As IntPtr) As IntPtr <UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _ Public Delegate Sub FREEPROC(ByVal MemBlock As IntPtr) Declare Auto Function CreateFontPackage Lib "FontSub.DLL" Alias "CreateFontPackage" (ByVal puchSrcBuffer() As Byte, _ ByVal ulSrcBufferSize As UInteger, _ ByRef puchFontPackageBuffer() As Byte, _ ByRef pulFontPackageBufferSize As UInteger, _ ByRef pulBytesWritten As UInteger, _ ByVal usFlags As UShort, _ ByVal usTTCIndex As UShort, _ ByVal usSubsetFormat As UShort, _ ByVal usSubsetLanguage As UShort, _ ByVal usSubsetPlatform As UShort, _ ByVal usSubsetEncoding As UShort, _ ByVal pusSubsetKeepList() As UShort, _ ByVal usSubsetKeepListCount As UShort, _ ByVal lpfnAllocate As ALLOCPROC, _ ByVal lpfnReAllocate As REALLOCPROC, _ ByVal lpfnFree As FREEPROC, _ ByVal lpvReserved As IntPtr) As UInteger Public Shared Function CreateSubsetFont(ByVal FontFile As String, ByVal characters() As UShort) As Byte() Dim result() As Byte = File.ReadAllBytes(FontFile) Dim allocproc As ALLOCPROC = New ALLOCPROC(AddressOf Marshal.AllocHGlobal) Dim reallocproc As REALLOCPROC = New REALLOCPROC(AddressOf Marshal.ReAllocHGlobal) Dim freeproc As FREEPROC = New FREEPROC(AddressOf Marshal.FreeHGlobal) Dim subset() As UShort = characters Dim buffer() As Byte Dim buffer_size, bytes_written As UInteger Dim rc As UInteger = CreateFontPackage(result, CUInt(result.Length), buffer, buffer_size, bytes_written, 0, 0, 0, 0, 0, 1, subset, CUShort(subset.Length), allocproc, reallocproc, freeproc, Nothing) Return buffer End Function End Class
Thanks!
- Moved by Bob_BaoMVP, Moderator Friday, January 07, 2011 11:35 AM (From:Visual Basic Language)
All Replies
-
Friday, December 31, 2010 1:52 PMNo replies yet, huh? Why didn't you post the link to the C# code so someone could translate it for you? This is what Tergiver came up with.
Imports System.Runtime.InteropServices
Imports System.IO
Module Module1
<UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _
Friend Delegate Function ALLOCPROC(ByVal Size As Integer) As IntPtr
<UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _
Friend Delegate Sub FREEPROC(ByVal MemBlock As IntPtr)
<UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _
Friend Delegate Function REALLOCPROC(ByVal MemBlock As IntPtr, ByVal Size As IntPtr) As IntPtr
Sub Main()
Test_CreateFontPackage()
Console.ReadLine()
End Sub
Friend Sub Test_CreateFontPackage()
Dim buffer As Byte()
Dim buffer_size As UInt32
Dim bytes_written As UInt32
Dim result As Byte() = File.ReadAllBytes("C:\Windows\Fonts\Arial.ttf")
Dim allocproc As ALLOCPROC = New ALLOCPROC(AddressOf Marshal.AllocHGlobal)
Dim reallocproc As REALLOCPROC = New REALLOCPROC(AddressOf Marshal.ReAllocHGlobal)
Dim freeproc As FREEPROC = New FREEPROC(AddressOf Marshal.FreeHGlobal)
Dim subset As UInt16() = New UInt16(0 - 1) {}
Dim rc As UInt32 = CreateFontPackage( _
result, _
CUInt(result.Length), _
buffer, _
buffer_size, _
bytes_written, _
0, 0, 0, 0, 0, 1, _
subset, _
CUShort(subset.Length), _
allocproc, _
reallocproc, _
freeproc, _
IntPtr.Zero)
If (rc <> 0) Then
Console.WriteLine("Failed with code {0}", rc)
Else
Console.WriteLine("Success.")
End If
End Sub
<DllImport("FontSub.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)> _
Friend Function CreateFontPackage( _
<[In](), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _
ByVal puchSrcBuffer As Byte(), _
ByVal ulSrcBufferSize As UInt32, _
<Out(), MarshalAs(UnmanagedType.LPArray)> _
ByRef puchFontPackageBuffer As Byte(), _
<Out()> ByRef pulFontPackageBufferSize As UInt32, _
<Out()> ByRef pulBytesWritten As UInt32, _
ByVal usFlags As UInt16, _
ByVal usTTCIndex As UInt16, _
ByVal usSubsetFormat As UInt16, _
ByVal usSubsetLanguage As UInt16, _
ByVal usSubsetPlatform As UInt16, _
ByVal usSubsetEncoding As UInt16, _
<[In](), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=11)> _
ByVal pusSubsetKeepList As UInt16(), _
ByVal usSubsetKeepListCount As UInt16, _
ByVal lpfnAllocate As ALLOCPROC, _
ByVal lpfnReAllocate As REALLOCPROC, _
ByVal lpfnFree As FREEPROC, _
ByVal lpvReserved As IntPtr) As UInt32
End Function
End Module
' web links
'
' http://social.msdn.microsoft.com/Forums/en-IE/csharplanguage/thread/1652a9fb-87ab-4725-8a73-7f1015519a71
' http://msdn.microsoft.com/en-us/magazine/cc163606.aspx#S1
' http://msdn.microsoft.com/en-us/library/dd183502.aspx
Hope this helps.
Rudy =8^D
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 12:22 AM
Thanks for the copy of Tergiver's code.
I just tried this code as is and I am still getting -
"A call to PInvoke function 'XPSPrint!XPSPrint.Module1::CreateFontPackage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."
Will have a look at the web links you supplied to see if this has come up when using VB/VS 2010/Windows7x64. Possibly the dll function has been modified slightly in Win7?
Thanks,
John
-
Monday, January 03, 2011 12:28 AM
What did you do? I tested the code before I postd it and got the "Success" message running 64-bit Windows 7. What changes did you make?
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 12:37 AM
Do you know what that message means? Stack Imbalance?
The link describes it, but I will summarize it here. When a method call is made, some parameters may be placed onto the stack by the caller. It is the callee's responsibility to clean up the stack prior to exiting. The callee must leave the stack size unchanged. Leave it the same size prior to the method call.
A Stack Imbalance means the stack was not left the same size after the method call. The most common cause of these imbalances is the caller and the callee are not on the same page with their data types. This can easily occur between 16-bit code and 32-bit code when passing default integers.
For example, your 32-bit code passes a default integer, which is four bytes. The callee is 16-bit code. When it reads a default integer in it only pulls 2 bytes off the stack, leaving 2 behind. When the method finishes, the two extra bytes are still on the stack. The stack size has changed, leaving it "Imbalanced".
Rudy =8^D
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 12:45 AM
Sub Main Dim result As UInt32 = CreateSubsetFont("C:\windows\fonts\arial.ttf", "C:\test\arialss.ttf") End Sub Function CreateSubsetFont(ByVal originalTTF, ByVal subsetTTF) As UInt32 Dim buffer As Byte() Dim buffer_size As UInt32 Dim bytes_written As UInt32 Dim result As Byte() = File.ReadAllBytes(originalTTF) Dim allocproc As ALLOCPROC = New ALLOCPROC(AddressOf Marshal.AllocHGlobal) Dim reallocproc As REALLOCPROC = New REALLOCPROC(AddressOf Marshal.ReAllocHGlobal) Dim freeproc As FREEPROC = New FREEPROC(AddressOf Marshal.FreeHGlobal) Dim subset As UInt16() = New UInt16(5) {50, 51, 52, 53, 54, 55} Dim rc As UInt32 = CreateFontPackage( _ result, _ CUInt(result.Length), _ buffer, _ buffer_size, _ bytes_written, _ 0, 0, 0, 0, 0, 1, _ subset, _ CUShort(subset.Length), _ allocproc, _ reallocproc, _ freeproc, _ IntPtr.Zero) Return rc End FunctionThe rest of the code is identical to what you posted. In this case I set the subset to 5 specific character index's. I did try with the same subset setting you posted (no sub setcharacters) however this also had the stack imbalance error as well. Also, I have noticed that it warns about buffer not being assigned a value before being referenced.
If I go into Debug - Exceptions and turn off the PInvokeStackImbalance the code runs with a returned RC of 0 so it appears to work, however buffer, buffer_size and bytes_written all come up empty. Do you actually see a byte array returned with the TTF file bytes in buffer?
-
Monday, January 03, 2011 12:59 AM
I did not check the contents of the buffer, but I can. I get the same warning about the buffer. I ignored it for the time being. The size is being passed as parameter, so the Interop has the info it needs to intialize it dynamically. Size is not known until runtime. C# allows you to turn off warnings for sections of code that you designate with compiler directives.
http://msdn.microsoft.com/en-us/library/ed8yd1ha(VS.71).aspx note the one labeled #warning
VB does not permit that yet. http://msdn.microsoft.com/en-us/library/7ah135z7.aspx
But, did the test program give you the "success" message? The imbalance message says that you are not calling it with the proper data types. I did not get that message with the test program.
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 1:05 AM
OK, I created a new console app and placed your code as is and I no longer get the stack imbalance. However I still do not get any bytes returned in the buffer, regardless of the subset being set to your initial value or if I set it as - Dim subset As UInt16() = New UInt16(5) {50, 51, 52, 53, 54, 55} what puzzles me is that you set the dll function as -
CreateFontPackage(<[In](), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _
ByVal puchSrcBuffer As Byte(), _
ByVal ulSrcBufferSize As UInt32, ...
but when you call the function you use -
Dim rc As UInt32 = CreateFontPackage( _
result, _
CUInt(result.Length), _
buffer,...
What is <[In](), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> and how would this match "result" which is a byte array?
How would puchSrcBuffer as byte array match with CUInt(result.Length).
Finding it tricky to see how the definition of the parameters all align with the call you make? Either way something is not right as I am not getting back anything in buffer.
Regards, John
-
Monday, January 03, 2011 1:24 AM
Take a look at the C signature.
unsigned long CreateFontPackage(
__in const unsigned char *puchSrcBuffer,
__in const unsigned long ulSrcBufferSize,
__out unsigned char **puchFontPackageBuffer,
__out const unsigned long *pulFontPackageBufferSize,
__out unsigned long *pulBytesWritten,
__in const unsigned short usFlags,
__in const unsigned short usTTCIndex,
__in const unsigned short usSubsetFormat,
__in const unsigned short usSubsetLanguage,
__in const unsigned short usSubsetPlatform,
__in const unsigned short usSubsetEncoding,
__in const unsigned short *pusSubsetKeepList,
__in const unsigned short usSubsetKeepListCount,
__in CFP_ALLOCPROC lpfnAllocate,
__in CFP_REALLOCPROC lpfnReAllocate,
__in CFP_FREEPROC lpfnFree,
__in LPVOID lpvReserved
);
Notice the asterisks associated with some parameters. Those parameters are being not being passed by value. They are being passed by reference. The asterisks designates the variable as a pointer. Pointers are of fixed size. The attribute helps the marshaller provide the correct pointer to unmanaged code. The double asterisks indicate pointers to a pointer, which I called "indirect pointers" when I first learned about them.
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 1:24 AM
Also, the new console app with your code which does execute the function is using .net 2.0 whereas the project I am working on is .net 4.0. Would .net 4.0 cause the stack imbalance? If I change the new console app over to use .net 4.0 then the pInvoke error is back. Bit of an issue as my main project is based on .net 4.0.
Still would like to nut out why the buffer of bytes which is supposed to make up the subset TTF file bytes is coming back empty. If I can get that working and work out what the .net 4.0 issue is then we are onto a winner.
-
Monday, January 03, 2011 1:31 AM
I am running VS2010 Ultimate. No stack imbalance error for me. The only change that I am aware of is that the warning has been turned on by default in 2010, whereas in previous versions it was off by default.
One of my links describe the MDAs, Managed Debugging Assistants, available to Visual Studio. The article is about VS2005 and suggests that anyone doing P/Invoke should turn it on. Well, it is now on by default since most developers were not aware of it.
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 1:39 AM
Can you confirm the following on your end -
VS 2010 VB x86 console app using .NET 2.0 (default for new console apps) - code executes without error?
buffer bytes comes back with nothing?
Same app changed to use .NET 4.0 - code executes with PInvoke Stack Imbalance error?
-
Monday, January 03, 2011 1:42 AM
I take that back. I translated and tested that on my older 32 bit machine. My Win7x64 machine throws the stack imbalance error. The pointer sizes are different for 32 and 64 bit machines, but I have my build platform set for x86 and still get the error.
Rudy =8^D
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, January 03, 2011 1:50 AMBased on your finding I then changed the .NET 4.0 console app to anyCPU rather than x86 and the function does execute without error. I assume anyCPU exe's can run on either x64 or x86 platforms so this may be the workaround. I do still need you to confirm that the buffer is returned empty on your end as this is the whole reason I need this function. Bit pointless using the function if it is not going to give me the bytes of the subset TTF file.
-
Monday, January 03, 2011 2:25 AMI am not familiar with that method. I would assume that the parameters being passed as zeroes may have something to do with it. Also, the font must be a true type font.
Mark the best replies as answers. "Fooling computers since 1971." -
Tuesday, January 04, 2011 1:17 AM
Try asking that question here. Providing a link to this thread would be a good thing.
http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/threads
Mark the best replies as answers. "Fooling computers since 1971." -
Monday, February 21, 2011 6:55 PMI am also trying to figure this out. The code itself seems to work fine, but as soon as I set the "usFlags" to 1 (as stated in the fontSub.h) I get an out of memory error. when I run the exact same code in C++ it seems to work fine. I rember reading something about arrays and unmanaged code in the MSDN, saying that it wasnt possible and would cause this error. you guys figured anything out?
-
Monday, February 21, 2011 8:29 PM
The stack imbalance error probably means that your data types don't match. The stack size is supposed to remain unchanged after a method call.
If you place a C# "int" on the stack for a C++ DLL looking for a C++ "int", then your code will seem to run properly most of the time. But, the DLL is only removing the first 2 bytes of the 4 bytes passed to it. When the method returns, these extra bytes are left on the stack. This is known as Stack Imbalance.
Mark the best replies as answers. "Fooling computers since 1971." -
Tuesday, February 22, 2011 10:28 AM
hmmm... unfortuantely I am not exactly a wiz when it gomes to transfering data types, which is why I used the exact same codethat you had posted on december 31 with the exception of one single flag:
without the usFlag = 1 the function returns 0, but the buffer, buffer_size and bytes_written are all nothing/0. This is the same for the c++ version, if the usFlags = 0 the buffer is also nothing and both buffer_size and bytes_written are 0.Dim rc As UInt32 = CreateFontPackage( _ result, _ CUInt(result.Length), _ buffer, _ buffer_size, _ bytes_written, _ 1, 0, 0, 0, 0, 1, _ subset, _ CUShort(subset.Length), _ allocproc, _ reallocproc, _ freeproc, _ IntPtr.Zero)
-
Wednesday, February 23, 2011 11:42 PM
Based on your finding I then changed the .NET 4.0 console app to anyCPU rather than x86 and the function does execute without error. I assume anyCPU exe's can run on either x64 or x86 platforms so this may be the workaround. .
Mark the best replies as answers. "Fooling computers since 1971." -
Thursday, February 24, 2011 11:36 AM
Unfortunately I have to use the .NET framework 2.0 for this program. and regardless if the app is set to x86 or AnyCPU I still recieve an OutOfMemoryException, "Insufficient memory to continue the execution of the program.":
" at System.Runtime.InteropServices.Marshal.ReAllocHGlobal(IntPtr pv, IntPtr cb) at FontSub_VB_console.Module1.CreateFontPackage(Byte[] puchSrcBuffer, UInt32 ulSrcBufferSize, Byte[]& puchFontPackageBuffer, UInt32& pulFontPackageBufferSize, UInt32& pulBytesWritten, UInt16 usFlags, UInt16 usTTCIndex, UInt16 usSubsetFormat, UInt16 usSubsetLanguage, UInt16 usSubsetPlatform, UInt16 usSubsetEncoding, UInt16[] pusSubsetKeepList, UInt16 usSubsetKeepListCount, ALLOCPROC lpfnAllocate, REALLOCPROC lpfnReAllocate, FREEPROC lpfnFree, IntPtr lpvReserved) at FontSub_VB_console.Module1.Test_CreateFontPackage() in C:\Users\MG.CAXPERTS01\Documents\Visual Studio 2008\Projects\FontSub_VB_console\FontSub_VB_console\Module1.vb:line 25 at FontSub_VB_console.Module1.Main() in C:\Users\MG.CAXPERTS01\Documents\Visual Studio 2008\Projects\FontSub_VB_console\FontSub_VB_console\Module1.vb:line 72 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()"
-
Thursday, March 03, 2011 4:19 PMHi - The above code worked without error. but the buffer is null and the buffer size is zero. The buffer should contain the new subset font which could be written to a ttf file.
-
Friday, March 04, 2011 1:59 PM
yes, which is why I changed one line of the above code to:
1, 0, 0, 0, 0, 1, _
since the C++ code works with the usFlags = 0x0001
but as I stated above this causes the error
-
Friday, March 04, 2011 11:09 PM
Ok, since starting this thread it seems we are able to get the function to call without error however it still seems that we cannot get the TTF subset bytes back.
Only just today I was looking into .NET 4 WPF and the GlyphTypeface. Seems that it actually does what we are after -
GlyphTypeface.ComputeSubset Method
Returns the binary image of the font subset based on a specified collection of glyphs.
Namespace: System.Windows.Media
Assembly: PresentationCore (in PresentationCore.dll)
VB Syntax
<CLSCompliantAttribute(False)> Public Function ComputeSubset (glyphs As ICollection(Of UShort)) As Byte()
Parameters
glyphs
Type: System.Collections.Generic.ICollection(Of UInt16)
The collection of glyph indices to be included in the subset.Return Value
Type: System.Byte()
A Byte array that represents the binary image of the font subset.I'm assuming at this early stage that the bytes returned are the actual TTF subset font.
Here's hoping this is the way forward.
-
Friday, March 04, 2011 11:32 PM
Ok, this works with VB 2010 .NET 4.0
Dim glyphTypeface as Media.GlyphTypeface = New Media.GlyphTypeface(New Uri("C:\Windows\Fonts\Arial.TTF")) 'can be any font installed or not
Dim Gindex As System.Collections.Generic.ICollection(Of UShort)
Gindex = New Generic.List(Of UShort)
Dim myBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(SourceText)
Dim myChars As Char() = System.Text.Encoding.Unicode.GetChars(myBytes)
For Charpos = 0 to Ubound(myChars)
Dim CharVal As Integer = AscW(myChars(Charpos))
Dim glyphIndex As Integer = glyphTypeface.CharacterToGlyphMap(CharVal)
Gindex.Add(glyphIndex)
Next
Dim filebytes() As Byte = glyphTypeface.ComputeSubset(Gindex)
Dim oFileStream As System.IO.FileStream
oFileStream = New System.IO.FileStream("D:\NewFonts\ArialSS.TTF", System.IO.FileMode.Create)
oFileStream.Write(filebytes, 0, filebytes.Length)
oFileStream.Close()
-
Friday, March 04, 2011 11:44 PM
Unfortunately this sucks as a solution to anyone not in a position where they can use .NET 4.
Looking at the other new calls available in .NET 4 I'm really starting to warm to it. Just have to convince your customers that the extra .NET 4 Client Profile installer is worth the effort. If only it wasn't 42MB!
-
Monday, March 07, 2011 11:41 AMAs even we have not switched to VS 2010 (even though it will be done soon), our costermers are still using windows XP so this really is not an option.
-
Monday, March 07, 2011 9:07 PM
As even we have not switched to VS 2010 (even though it will be done soon), our costermers are still using windows XP so this really is not an option.
Tested my app under XP SP3 x86 and it works fine. Only additional installs were .NET 4 and XPS Essentials Pack (to be able to view XPS files). .NET 4 is not bound specifically to Vista/Win7/2008/R2. Minimum is XP SP3. Also tested under 2003 server and it also works fine.
The jump from VS 2008 to 2010 was a no-brainer. Even VS 2005 projects / solutions converted across seamlessly. My old VB6 code was a bit tricker however massive chunks of code was eventually replaced by functions that were introduced in .NET 3 and up. They even re-introduced the good old Sring(char,length) function which went missing for a while there (among others). Even C# is friendly enough to learn from a VB programmer's perspective (reading through C++ code still does my head in).
-
Tuesday, March 08, 2011 1:47 PM
Sorry, I've been busy with a couple of deadlines on some projects of late. I have been tinkering with this trying to see why this function seems to work in C++ , but not in managed code. VB/C#. I found some curious behavior using the VB code I posted earlier, the code that comes back "Success". But yet the 'buffer' variable is returned not just empty, it is completely corrupted and has a value of Nothing/null.
Oh yeah, while I am thinking about it and forget to post it again. Here's the link to Tergiver's thread .
Okay. The VB code that I had posted above was a translation of what Tergiver had posted in C#. He noted that he was uncertain as to what methods to use for the function pointers that had to be passed to the method. He used the Marshal class. Since my 'buffer' was coming back corrupted, I began to wonder about the Marshal class.
So I created some methods of my own, which called the Marshal class, so I could perform some diagnostics and trouble shooting.
'Dim allocproc As ALLOCPROC = New ALLOCPROC(AddressOf Marshal.AllocHGlobal)
Dim allocproc As ALLOCPROC = New ALLOCPROC(AddressOf alloc)
'Dim reallocproc As REALLOCPROC = New REALLOCPROC(AddressOf Marshal.ReAllocHGlobal)
Dim reallocproc As REALLOCPROC = New REALLOCPROC(AddressOf realloc)
'Dim freeproc As FREEPROC = New FREEPROC(AddressOf Marshal.FreeHGlobal)
Dim freeProc As FREEPROC = New FREEPROC(AddressOf free)
Dim subset As UInt16() = New UInt16(4) {48, 49, 50, 51, 71}
Dim name As String = "name"I got some interesting results. Nothing. Here are the methods that are now used by the delegates.
Friend Sub free(ByVal MemBlock As IntPtr)
Marshal.FreeHGlobal(MemBlock)
Console.WriteLine("Free MemBlock")
Return
End Sub
Friend Function realloc(ByVal MemBlock As IntPtr, ByVal Size As IntPtr) As IntPtr
Dim bufferSize As Integer = IntPtr.Size
Return Marshal.ReAllocHGlobal(MemBlock, Size)
Console.WriteLine("Realloc MemBlock")
End Function
Friend Function alloc(ByVal Size As Integer) As IntPtr
Return Marshal.AllocHGlobal(Size)
Console.WriteLine("Alloc MemBlock")
End FunctionI got nothing. I never got any messages on the Console. The methods were apparently never even being called. Yet, I still got the Success message at the end. And the 'buffer' variable was still somehow corrupted and set to Nothing/null without the delegates being invoking my methods.
I don't know what you think, but those result don't help. The C++ code calls functions with the same name as my new VB methods above, which are defined within stdio.h, if that means anything to anyone. I am tempted to write a C++ wrapper DLL around the code in the link with the C++ code so that managed code gain utilize those same methods.
Rudy =8^D
Mark the best replies as answers. "Fooling computers since 1971."- Edited by Rudedog2MVP Tuesday, March 08, 2011 2:19 PM
-
Tuesday, March 08, 2011 2:17 PM
F.Y.I.
Module TTF
' for usSubsetFormat
Public Const CFP_SUBSET As Int32 = 0
Public Const CFP_SUBSET1 As Int32 = 1
Public Const CFP_DELTA As Int32 = 2
'/* for usSubsetPlatform ID values */
Public Const CFP_UNICODE_PLATFORMID As Int32 = 0
Public Const CFP_APPLE_PLATFORMID As Int32 = 1
Public Const CFP_ISO_PLATFORMID As Int32 = 2
Public Const CFP_MS_PLATFORMID As Int32 = 3
' for usSubsetEncoding values
Public Const CFP_STD_MAC_CHAR_SET As Int32 = 0 ' goes with TTFSUB_APPLE_PLATFORMID
Public Const CFP_SYMBOL_CHAR_SET As Int32 = 0 ' goes with TTFSUB_MS_PLATFORMID
Public Const CFP_UNICODE_CHAR_SET As Int32 = 1 ' goes with TTFSUB_MS_PLATFORMID
Public Const CFP_DONT_CARE As Int32 = &HFFFF
' for usSubsetLanguage values
Public Const CFP_LANG_KEEP_ALL As Int32 = 0 '
' for usFlags values
Public Const CFP_FLAGS_NONE As Int32 = 0 '
Public Const CFP_FLAGS_SUBSET As Int32 = 1 ' if bit off, don't subset
Public Const CFP_FLAGS_COMPRESS As Int32 = 2 ' if bit off, don't compress
Public Const CFP_FLAGS_TTF As Int32 = 4 ' if bit off, its a TTF
Public Const CFP_FLAGS_GLYPHLIST As Int32 = 8 ' if bit off, list is characters
' for usModes
Public Const MFP_SUBSET As Int32 = 0 ' Copy a Straight Subset Font package to Dest buffer
Public Const MFP_SUBSET1 As Int32 = 1 ' Expand a format 1 font into a format 3 font
Public Const MFP_DELTA As Int32 = 2 ' Merge a format 2 with a format 3 font
End Module
' links
'
' http://social.msdn.microsoft.com/Forums/en-US/windowsxps/thread/355c4ee9-c9be-4b00-86d7-a5200156936b/
'
'/* for usSubsetFormat */
'#define TTFCFP_SUBSET 0 /* Straight Subset Font - Backward compatibility */
'#define TTFCFP_SUBSET1 1 /* Subset font with full TTO and Kern tables. For later merge */
'#define TTFCFP_DELTA 2 /* Delta font, for merge with a subset1 font */
'/* for usSubsetPlatform ID values */
'#define TTFCFP_UNICODE_PLATFORMID 0
'#define TTFCFP_APPLE_PLATFORMID 1
'#define TTFCFP_ISO_PLATFORMID 2
'#define TTFCFP_MS_PLATFORMID 3
'/* for usSubsetEncoding values */
'#define TTFCFP_STD_MAC_CHAR_SET 0 /* goes with TTFSUB_APPLE_PLATFORMID */
'#define TTFCFP_SYMBOL_CHAR_SET 0 /* goes with TTFSUB_MS_PLATFORMID */
'#define TTFCFP_UNICODE_CHAR_SET 1 /* goes with TTFSUB_MS_PLATFORMID */
'#define TTFCFP_DONT_CARE 0xFFFF
'/* for usSubsetLanguage values */
'#define TTFCFP_LANG_KEEP_ALL 0
'/* for usFlags values */
'#define TTFCFP_FLAGS_SUBSET 0x0001 /* if bit off, don't subset */
'#define TTFCFP_FLAGS_COMPRESS 0x0002 /* if bit off, don't compress */
'#define TTFCFP_FLAGS_TTC 0x0004 /* if bit off, its a TTF */
'#define TTFCFP_FLAGS_GLYPHLIST 0x0008 /* if bit off, list is characters */
'/* for usModes */
'#define TTFMFP_SUBSET 0 /* copy a Straight Subset Font package to Dest buffer */
'#define TTFMFP_SUBSET1 1 /* Expand a format 1 font into a format 3 font */
'#define TTFMFP_DELTA 2 /* Merge a format 2 with a format 3 font */
The commented lines of code are from the file fontsub.h, which is found in the Windows SDK.
Mark the best replies as answers. "Fooling computers since 1971." -
Thursday, March 17, 2011 6:02 PM
Thank JGrouse. Your program is perctely working.
Do you have any idea about converting ttf file to svg file. If yes, please share your thoughts..thanks
-
Monday, March 21, 2011 9:51 PM
Hi JGrouse
Your .net 4.0 code creating ttf sub set file but it seems it includes empty placeholders for every font character that's been removed. Can we remove plcaeholders also for characters that we have not included in the subset file.
-
Tuesday, March 22, 2011 8:02 PM
I have some not so good news when it comes to finding a resolution to the original problem in the MSDN forums.
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/52587c2d-52e4-4991-af06-2416d3e9d4b6
Rudy =8^D
Mark the best replies as answers. "Fooling computers since 1971." -
Wednesday, August 31, 2011 12:46 PM
Unfortunatly, I have returned to this issue, though we have upgraded to VS 2010 we are still using .NET 2.0 so the 4.0 solution is still not accapable for us... anyone have anynew Ideas?


