Page 1 of 2
CatchFont()
Posted: Sat Feb 27, 2016 12:20 am
by IdeasVacuum
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.
Re: CatchFont()
Posted: Sat Feb 27, 2016 7:51 am
by Bisonte
I agree since years
+1
Re: CatchFont()
Posted: Sat Feb 27, 2016 8:16 am
by davido
+1
Perhaps there's a Catch?
Re: CatchFont()
Posted: Sat Feb 27, 2016 8:25 am
by Keya
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
Re: CatchFont()
Posted: Sat Feb 27, 2016 1:12 pm
by IdeasVacuum
It's certainly possible on WindowsOS and MAC.
Re: CatchFont()
Posted: Sun Feb 28, 2016 8:28 am
by Danilo
IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Example code?
Re: CatchFont()
Posted: Sun Feb 28, 2016 8:47 am
by Fred
Seems not possible on Linux (just checked)
Re: CatchFont()
Posted: Sun Feb 28, 2016 8:53 am
by wilbert
Danilo wrote:IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Example code?
I have no code example but on OSX you can use ATSFontActivateFromMemory() or on OSX 10.8+ the combination of CGFontCreateWithDataProvider() with CTFontManagerRegisterGraphicsFont()
Re: CatchFont()
Posted: Sun Feb 28, 2016 1:20 pm
by IdeasVacuum
For Windows see Rashad's example using
AddFontMemResourceEx()
Re: CatchFont()
Posted: Sun Feb 28, 2016 1:35 pm
by Danilo
wilbert wrote:Danilo wrote:IdeasVacuum wrote:It's certainly possible on WindowsOS and MAC.
Example code?
I have no code example
Very helpful.
Re: CatchFont()
Posted: Sun Feb 28, 2016 3:32 pm
by wilbert
Danilo wrote:Very helpful.
Thanks
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
Re: CatchFont()
Posted: Mon Feb 29, 2016 2:53 am
by IdeasVacuum
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
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
Re: CatchFont()
Posted: Mon Feb 29, 2016 7:06 am
by tj1010
Not without some format loaders and some weird licensing conflicts which fonts are long known for.
There is such thing as bitmap fonts though.
Re: CatchFont()
Posted: Tue Mar 01, 2016 5:53 am
by Danilo
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
Thanks, wilbert! Unfortunately it seems to have some (typical) problems with font names.
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()
Posted: Tue Mar 01, 2016 7:10 am
by wilbert
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().
I wanted to simulate the Catch procedure like other Catch procedures PB offers.
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.