CatchFont()
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
CatchFont()
We have:
CatchImage
CatchMusic
CatchSound
CatchSprite
CatchXML
CatchJSON
So why not CatchFont() too? It is sometimes the case that only a specific Font is just right, and 1000s of OpenSource fonts are freely available.
CatchImage
CatchMusic
CatchSound
CatchSprite
CatchXML
CatchJSON
So why not CatchFont() too? It is sometimes the case that only a specific Font is just right, and 1000s of OpenSource fonts are freely available.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: CatchFont()
I agree since years 
+1

+1
Re: CatchFont()
is it possible to load a font if it's not an on disk file (do the os api support that)? that might be the catch
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: CatchFont()
It's certainly possible on WindowsOS and MAC.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: CatchFont()
Example code?IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Re: CatchFont()
Seems not possible on Linux (just checked)
Re: CatchFont()
I have no code example but on OSX you can use ATSFontActivateFromMemory() or on OSX 10.8+ the combination of CGFontCreateWithDataProvider() with CTFontManagerRegisterGraphicsFont()Danilo wrote:Example code?IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: CatchFont()
For Windows see Rashad's example using AddFontMemResourceEx()
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: CatchFont()
Very helpful.wilbert wrote:I have no code exampleDanilo wrote:Example code?IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Re: CatchFont()
ThanksDanilo wrote:Very helpful.

Here's also a code example; works for .ttf and .otf fonts.
Code: Select all
ImportC ""
ATSFontActivateFromMemory(*data, length, context, format, reserved, options, *container)
ATSFontDeactivate(container, refCon, options)
ATSFontFindFromContainer(container, options, count, *oArray, *count)
ATSFontGetPostScriptName(font, options, *name)
EndImport
Procedure CatchFont(Font, *MemoryAddress, Size, Height = 12)
Protected.i result, container, count, atsfont, name
ATSFontActivateFromMemory(*MemoryAddress, Size, 0, 0, 0, 0, @container)
If container = 0
ProcedureReturn 0
EndIf
ATSFontFindFromContainer(container, 0, 0, 0, @count)
If count = 0
ATSFontDeactivate(container, 0, 0)
ProcedureReturn 0
EndIf
ATSFontFindFromContainer(container, 0, 1, @atsfont, 0)
If atsfont = 0
ATSFontDeactivate(container, 0, 0)
ProcedureReturn 0
Else
ATSFontGetPostScriptName(atsfont, 0, @name)
result = LoadFont(Font, PeekS(CocoaMessage(0, name, "UTF8String"), -1, #PB_UTF8), Height)
CFRelease_(name)
ProcedureReturn result
EndIf
EndProcedure
DataSection
FontStart:
IncludeBinary "OpenSans-LightItalic.ttf"
FontEnd:
EndDataSection
myFont = CatchFont(#PB_Any, ?FontStart, ?FontEnd - ?FontStart)
Debug myFont
End
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: CatchFont()
I really don't know anything about Linux OS. The following code can be used to extract the embedded font to the hard drive. On Windows OS, the Font Mapper is updated with function AddFontResource(). Does Linux have a similar mechanism? Could the drive be a small ram disc created via API?
http://www.fontsquirrel.com
http://www.fontsquirrel.com
Code: Select all
Enumeration
#Win
#Ed
#FontFile
#Font
EndEnumeration
Define sThisApp.s = ProgramFilename()
Define sPath.s = GetPathPart(sThisApp) ;or other path specifically required by OS
Define sFontFile.s = sPath + "BRUSHSTP.ttf"
If OpenFile(#FontFile, sFontFile)
WriteData(#FontFile, ?FontStart, (?FontEnd - ?FontStart))
CloseFile(#FontFile)
;Windows API
AddFontResource_(sFontFile)
SendMessage_(#HWND_BROADCAST,#WM_FONTCHANGE, #Null, #Null)
EndIf
LoadFont(#Font, "Brushstroke Plain", 36, #PB_Font_HighQuality)
If OpenWindow(#Win, 0, 0, 400, 200, "Embedded Font", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(#Ed, 10, 10, 380, 180)
SetGadgetFont(#Ed, FontID(#Font))
SetGadgetText(#Ed, "Brushstroke Plain True Type Font")
Repeat
Until WaitWindowEvent(1) = #PB_Event_CloseWindow
EndIf
DataSection
FontStart:
IncludeBinary "C:\OpenSourceFonts\BRUSHSTP.ttf"
FontEnd:
EndDataSection
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: CatchFont()
Not without some format loaders and some weird licensing conflicts which fonts are long known for.
There is such thing as bitmap fonts though.
There is such thing as bitmap fonts though.
Re: CatchFont()
Thanks, wilbert! Unfortunately it seems to have some (typical) problems with font names.wilbert wrote:Here's also a code example; works for .ttf and .otf fonts.Code: Select all
ImportC "" ATSFontActivateFromMemory(*data, length, context, format, reserved, options, *container) ATSFontDeactivate(container, refCon, options) ATSFontFindFromContainer(container, options, count, *oArray, *count) ATSFontGetPostScriptName(font, options, *name) EndImport Procedure CatchFont(Font, *MemoryAddress, Size, Height = 12) Protected.i result, container, count, atsfont, name ATSFontActivateFromMemory(*MemoryAddress, Size, 0, 0, 0, 0, @container) If container = 0 ProcedureReturn 0 EndIf ATSFontFindFromContainer(container, 0, 0, 0, @count) If count = 0 ATSFontDeactivate(container, 0, 0) ProcedureReturn 0 EndIf ATSFontFindFromContainer(container, 0, 1, @atsfont, 0) If atsfont = 0 ATSFontDeactivate(container, 0, 0) ProcedureReturn 0 Else ATSFontGetPostScriptName(atsfont, 0, @name) result = LoadFont(Font, PeekS(CocoaMessage(0, name, "UTF8String"), -1, #PB_UTF8), Height) CFRelease_(name) ProcedureReturn result EndIf EndProcedure DataSection FontStart: IncludeBinary "OpenSans-LightItalic.ttf" FontEnd: EndDataSection myFont = CatchFont(#PB_Any, ?FontStart, ?FontEnd - ?FontStart) Debug myFont End
Example font: http://www.fontspace.com/allen-r-walden/crystal
ATSFontGetPostScriptName() returns "CrystalItalic-" and it does not work.
ATSFontGetName() returns "Crystal Italic" and it does not work.
In both cases a valid ID is returned, but the standard font is used instead.
If I change your procedure to use the string "Crystal" for LoadFont(), it's okay.
Maybe it's better to add a new parameter 'fontName.s' to CatchFont().
Re: CatchFont()
I wanted to simulate the Catch procedure like other Catch procedures PB offers.Danilo wrote:If I change your procedure to use the string "Crystal" for LoadFont(), it's okay.
Maybe it's better to add a new parameter 'fontName.s' to CatchFont().
You are right it doesn't work with this font.

I also tried it with the OSX 10.8+ CTFontManagerRegisterGraphicsFont approach but same results.
Unfortunately I don't know what function Fred uses to load the font.
Adding a name to the procedure would be possible but in that case it's easier just to register the font and use LoadFont after that.
In that case the only required function would be ATSFontActivateFromMemory.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)