C# embedded font laden

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
Ik probeer nu al even om een embedded font te gebruiken in mijn applicatie. Er staan meerdere voorbeelden op internet, maar toch krijg ik het niet voor elkaar. (Op veel fora staat een voorbeeld dat voor een iemand werkt met daarna veel replies dat het niet werkt).

Ik heb op dit moment twee manieren geprobeerd. De eerste manier is een font (.otf in mijn geval) toevoegen aan het project en de build action op embed zetten. Het bestand heet EmigreEigth.otf. Dan probeer ik de font op de volgende manier te laden. (Op deze manier staat het vaak op internet).

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private Font LoadFont[()
        {            
            string nameSpace = Assembly.GetExecutingAssembly().GetName().Name.ToString();            
            Assembly assembly = Assembly.GetExecutingAssembly();
            Stream fontStream = assembly.GetManifestResourceStream(nameSpace + ".EmigreEight.otf");
            // hierbij ook nameSpace + ".Resources.EmigreEight.otf" geprobeerd maar dan is fS null.
            if (fontStream != null)
            {
                byte[] fontBuffer = new Byte[fontStream.Length];
                fontStream.Read(fontBuffer, 0, (int)fontStream.Length);

                IntPtr memPointer = Marshal.AllocCoTaskMem(fontBuffer.Length);
                if (memPointer != null)
                {
                    Marshal.Copy(fontBuffer, 0, memPointer, fontBuffer.Length);
                    fontCollection = new PrivateFontCollection();
                    fontCollection.AddMemoryFont(memPointer, fontBuffer.Length); //FileNotFoundException
                    Font emigreEightFont = new Font(fontCollection.Families[0].Name, 20f);                    
                    Marshal.FreeCoTaskMem(memPointer);
                    return emigreEightFont;
                }
            }
            else { throw new Exception(); }

            return null;
        }


Hier krijg ik dus telkens een file not found exception, terwijl ik wel een stream kan maken van de embedded resource :/. (Als ik hier wat anders in typ blijft fontStream gewoon null).

Nu heb ik het via de ResurceManager geprobeerd.Aan het bestand Resources.resx heb ik het font weer toegevoegd, de resource name is nu EmgireEight. (zonder .otf). Dat levert de volgende code op.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private Font LoadEmbeddedFont(string name)
        {
            Object font = Resources.ResourceManager.GetObject(name);
            if (font != null)
            {
                byte[] fontBuffer = (byte[])font;                
                IntPtr memPointer = Marshal.AllocCoTaskMem(fontBuffer.Length);
                if (memPointer != null)
                {
                    Marshal.Copy(fontBuffer, 0, memPointer, fontBuffer.Length);
                    fontCollection = new PrivateFontCollection();
                    fontCollection.AddMemoryFont(memPointer, fontBuffer.Length);  //fileNotFound exception                   
                    return new Font(fontCollection.Families[0].Name, 20f);
                }
            }           
            return null;
        }


Ook hier weer een fileNotFound exception, ondanks dat ik nu via de resource manager echt 100% zeker weet dat het bestand er is. Ik ben echt radeloos. :/. Kan iemand me een duw in de goede richting geven, het embedded van een font zou toch niet zo moeilijk moeten zijn.

Edit: En een derde variant heeft hetzelfde probleem (overal is de fontBuffer trouwens een goed gevulde byte[])
C#:
1
2
3
4
5
6
7
8
9
        private Font LoadEmbeddedFont2(string name)
        {
            byte[] fontBuffer = (byte[])(Resources.ResourceManager.GetObject(name));
            var handle = GCHandle.Alloc(fontBuffer, GCHandleType.Pinned);
            var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(fontBuffer, 0);
            fontCollection = new PrivateFontCollection();
            fontCollection.AddMemoryFont(ptr, fontBuffer.Length);
            return new Font(fontCollection.Families[0].Name, 10f);                        
        }



(Verder heb ik nog een belangrijke show-stopper gevonden, om er voor te zorgen dat je font ook daadwerkelijk gerenderd wordt, moet je applicatie GDI+ compatible gerendered worden -> zet dus in de controls waarin je dit font wil gebruiken "UseCompatibleTextRendering" op true... dat was ook lastig te vinden, maarja zover was ik nog niet, maar heb zo wel andere mensen kunnen helpen ).

[ Voor 8% gewijzigd door roy-t op 04-06-2010 10:11 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
Ik ben ondertussen een stukje verder, maar het font laad nu wel omdat ik het geconverteerd het naar .TTF. Ik heb twee verschillende font editors gebruikt maar toch wordt het uiteindelijke font in alle 3 de methoden "Microsoft Sans Serif". :/ Andere .ttf's werken wel en de gegenereerde TTFs zien er normaal uit in de windows font viewer.

Edit wat nog vreemder is, is dat als ik via de debugger de font bekijk ik als Name krijg "MS Sans Serif" maar als original name inderdaad EmigreEight... Zelfs als ik
C#:
1
2
3
4
5
6
private Font LoadEmbeddedFont3(string name)
        {
            fontCollection = new PrivateFontCollection();
            fontCollection.AddFontFile("EmigreEight.ttf");
            return new Font(fontCollection.Families[0].Name, 10f);            
        }


doe... WTF

Edit:

Nog wat fonts gedownload, en ik krijg ook deze niet aan de praat. Het lijkt wel alsof ik ondanks al dat gedoe alleen maar geintstalleerde fonts kan gebruiken. Erg raar, wat me wel opvalt is dat ik als ik new Font() doe alleen maar de naam van het font mee geef en niet de daadwerkelijke font collection waar het font in geladen is. Overal wordt het op deze manier gedaan. Zorgt de privateFontCollection ervoor dat een lokale font cache wordt geupdate, of moet ik nog een truuk uithalen om de fonts in een soort van fontcache te krijgen (hier zie ik nergens code voor, zelfs niet op MSDN).

[ Voor 80% gewijzigd door roy-t op 04-06-2010 12:17 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Compileer je je resources met de .NET compiler of met rc.exe (http://stackoverflow.com/...ms-app-in-c/557225#557225)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 12-09 20:23

CodeIT

Code IT

Draai je de code heeeel toevallig op Win2000? http://msdn.microsoft.com...llection.addfontfile.aspx (bij Remarks)
Als je de font gebruikt om naar een image te tekenen, wordt dan ook Sans Serif gebruikt?
Je kunt ook de windows api 'AddFontMemResourceEx' gebruiken, zie http://www.matevarga.com/embedding-fonts-into-windows-forms/

[ Voor 42% gewijzigd door CodeIT op 04-06-2010 12:20 ]


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
@ Snake dat is een goede tip, ik zal eens kijken of ik dat aan de praat krijg.

-> Helaas krijg ik dat niet voor elkaar, ik kan de .res file niet goed gebruiken. Het lijkt er op alsof dit een nogal oude fix is, aangezien ik alleen maar VB5 voorbeelden krijg.

@ CodeIT: ik gebruik gewoon Windows XP met .Net 3.5 dat is het dus helaas niet :(.

Edit:

Nu maar een check ingebouw of het font geinstalleerd is en dat dan maar gebruiken. Ik denk nogsteeds dat mijn private font collection nog iets moet doen om te zorgen dat het font wel ergens in de font pool / cache terecht komt. Maar ik kan nergens vinden wat. Alle voorbeelden op internet die ik gezien heb doen eigenlijk niets meer met de private font collection dan de naam opzoeken van het font dat je wil hebben :/. Dat werkt alleen maar voor fonts die gewoon geinstalleerd zijn.

[ Voor 67% gewijzigd door roy-t op 04-06-2010 13:32 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 12-09 20:23

CodeIT

Code IT

Misschien had je mijn laatste edit gemist, het schijnt toch echt te kunnen via AddFontMemResourceEx. Zie ook: http://stackoverflow.com/...mbedded-font-on-a-textbox

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
CodeIT schreef op vrijdag 04 juni 2010 @ 14:43:
Misschien had je mijn laatste edit gemist, het schijnt toch echt te kunnen via AddFontMemResourceEx. Zie ook: http://stackoverflow.com/...mbedded-font-on-a-textbox
Had ik gemist inderdaad, ga er volgende week even naar kijken :). Nu is het lekker weekend.

Bedankt voor die link trouwens, dat ziet er veelbelovend uit.

~ Mijn prog blog!

Pagina: 1