LoadImageFont on OSX & Linux

Started by Yellownakji, April 24, 2019, 08:35:46

Previous topic - Next topic

Yellownakji

So, OSX and Linux don't currently run my tool out-of-box, so of course, i do progressive print debugging to see where the program hangs on run-time; See screenshot below, as you read.

On WIN32, i utilize an OpenType Font (.OTF) and i store it in \DATA\.   OSX and Linux, via Filetype(), will print "OK", like in the example, so the OTF does exist.  However, "a" will continuously be printed, meaning the font variable is still null.  I would like to know >WHY< this kind of checking works on win32, but seemingly not OSX/Linux?  Does anybody know a specific solution for this?

Thanks.

Derron

Works as expected here:


Code (BlitzMax) Select

SuperStrict

'Framework Brl.StandardIO

Graphics 800, 600
SetBlend AlphaBlend

Local f:TImageFont = LoadImageFont("/usr/share/fonts/opentype/freefont/FreeMono.otf", 22, SMOOTHFONT)
If Not f Then Print "load failed"
SetImageFont(f)

Repeat
Cls
DrawText("test font", 10,10)

Flip 0

Until KeyHit(KEY_ESCAPE) Or AppTerminate()


FileType() returns 1 for files and 2 for directories. 0 for nothing.
So in your case it might return "true" if it was a directory too.


bye
Ron

Yellownakji

#2
Well, missing the filename up definitely reports 0.   So, when it reports 1, it's definitely seeing the file.

I noticed that if i remove the path variable and JUST ask for my font in project root (e.g. just typing the name of it), it will load.  and yes, your example works.

So, i went to my "DIR" type/class and i modified all my "\" to "/" and it yeilded the same results; null.   of course, brucey said those were changed at compile so it was preference, but i wanted to test anyways.   What i'd like to know is how to get it to load this file FROM WITHIN the Data folder.  The snippit i shared works on WIN32/64 and it's what i use for checking all my files, when the program launches.   This does not seem to be the case on OSX, which is where i'm primarily testing the code, at the moment.

I know OSX wants everything to be in resources, inside the .APP, but surely since it SEES the file, it could read it.   I'm genuinely confused, Ron.   Linux also does not like this, but i expected that, since they're both unix.

I'm not sure what to change...

Brucey did mention "GetUserAppDir()" but i'd prefer to use the working directory instead of pushing files there.  Is there a function to pull the working directory? (project root)

Derron

#3
So what does "DIR.DATA" contain?

Make sure it does not start with "/" except it is an absolute path.

Or... IF you use already an relative path, try an absolute path instead.
so if your app structure was:
/home/user/myapp/app.bmx
/home/user/myapp/DATA/font.otf

You do not load it via "DATA/font.otf" but via "/home/user/myapp/DATA/font.otf".
Should not really make a difference.

If you do not dare then print the URI you load for LoadImageFont() and paste it to here so we see if this contains some odd stuff.

Within a terminal you could also do this:
test -e /the/uri/you/just/printed.otf || echo file not found

and see if it prints "file not found"



@ working directory
You can use CurrentDir()

bye
Ron

Yellownakji

#4
DIR is a type that contains directory strings.   "Data" is the core directory which contains all the files and sub folders for the project.   [Project Root]\Data\.

The string is "Data\" and i've included the slash so i can just combine the directory string + a filename.    So, Dir.data + fnt.dreamcast =  "data\myriadpro.otf".

I'll see with currentdir().

Thank you.

Edit: Still returns "a", so null.

Edit:  i see you modded your post; i'll look into that really quick.

Derron

#5
Is is "data" or "Data" or "DATA" or ...

As said: just write to here what final string you pass to LoadImageFont(). and you have to double chack for uppercase and lowercase (albeit FileType() should fail then already)

Mac and Linux are case-sensitive, Windows OS not. So it matters if you write "data", "Data" and "Font.otf" or "foNT.otf"


Edit: so if you created "test.bmx" with my testcode above within your project folder - and then altered the url for the font to the one output by your "final string" - does it load the file or not? If it then loads you might be using the "FrameWork" command and miss something which "oddly" is imported on the Windows platform (to allow OTF).

Does it work if you use a TTF file instead?


bye
Ron

Yellownakji

Quote from: Derron on April 24, 2019, 11:33:23
..

The ACTUAL "case" is "Data\MyriadPro.otf", which is what the strings contain.

I printed what i use for LoadImageFont() and it returned exactly that.    Changing the "\" to a "/" actually makes the app hang. hmm.

It hung when i called a TTF, as well.  Switching back to "\", it still prints "a", so null.

I did the terminal suggestion and the output didn't print not found.

I'm not using a framework, so everything should be included, at least i'm told that's what happens when a framework isn't stated.

I tried your example code and like my code, it fails to load.  I changed the string to "Data\MyriadPro.otf" and the internal font was still rendered / "failed" was printed.   I'm not sure why Linux and OSX, tho currently on OSX, does not like this.


Yellownakji

It seems using a "\" and writing the path as one string allows the OTF to load.   

String() as a wrapper around the variables does not work.  I suppose everything has to be typed manually; annoying.

I wonder why?

Derron

#8
What happens if you did a

DIR.DATA = "Data/"
right before doing
LoadImageFont(DIR.DATA + FNT.DreamCastName, 12, SMOOTHFONT)

and if that still fails, do it this way:
DIR.DATA = "Data/"
local fntName:string = "MyriadPro.otf"
LoadImageFont(DIR.DATA + fntName, 12, SMOOTHFONT)


Also - to check if string concatenation creates issues: does this work then:
LoadImageFont("Data/" + "MyriadPro.otf", 12, SMOOTHFONT)
?

Should work as you said this works:
LoadImageFont("Data/MyriadPro.otf", 12, SMOOTHFONT)

If it needed a backslash - try with the string+string-test above too.

Maybe either DIR.DATA or FNT.DreamCastName are filled automatically by something? Maybe they contain (invisible) characters or an UTF8 encoding or such a thing.


bye
Ron

Derron

Here is a sample code you could try:
Code (BlitzMax) Select

SuperStrict

'Framework Brl.StandardIO

Graphics 800, 600
SetBlend AlphaBlend


'load fonts
Local fontDir:String = "/usr/share/fonts/opentype/freefont"
Local fontFiles:String[]
For Local file:String = EachIn LoadDir(fontDir, True)
If ExtractExt(file).ToLower() = "otf"
fontFiles :+ [file]
Print "Found otf font file: " + fontDir + "/" + file
EndIf
Next

Local fonts:TImageFont[] = New TImageFont[0]
For Local fontFile:String = EachIn fontFiles
Local f:TImageFont = LoadImageFont(fontDir + "/" + fontFile, 22, SMOOTHFONT)
fonts :+ [f] 'null or the actual font
If f
Print "loaded font file: " + fontFile
Else
Print "failed loading font file: " + fontFile
EndIf
Next

Repeat
Cls
For Local i:Int = 0 Until fontFiles.length
Local f:TImageFont = fonts[i]
'sets actual font - or systemfont if null
SetImageFont(f)
If f
DrawText(fontFiles[i], 10,i*20)
Else
DrawText(fontFiles[i] + " FAILED", 10,i*20)
EndIf
Next
SetImageFont(Null) 'systemfont
Flip 0

Until KeyHit(KEY_ESCAPE) Or AppTerminate()



Adjust "fontDir" to your needs.





I wrote the sample code in a way that it utilizes string concatenation.

bye
Ron

Yellownakji

Quote from: Derron on April 24, 2019, 11:56:53
..

I don't quite know what it was, but i found a work around.

Dir.Data = "Data"
Global __OS__SLASH:string

?win32
__... = "\" 'too lazy to type whole var
?macos
__.. = "/"
?

then just do  dir.data = data + __OS...
etc etc.

I'm not sure why "Data/" and "Data\" didn't work for loading but either or /\ could be used with FileSystem() to find a specified file.

My app is up and running.       However, i have another issue and i'm not sure it's worth a new thread or not.

The "caps" buttons does not work.  I did make a custom KEY_CAPSLOCK variable, but it's not detected.  What is the caps button ID for MAC?   also, i'm using OSX via a virtual machine as my main MAC is non-functional.

Derron

You should be able to use "/" on Linux,Mac _and_ Windows.

The constant shouldn't be needed.


@ capslock
You cannot track this state in your application as the outside world (eg. alt-tabbing) allows to change capslock state without your application registering the change.

Each OS has custom functions to find out the current state of the capslock - maybe Brucey has some idea. Will file an issue for this.


bye
Ron

Yellownakji

Quote from: Derron on April 24, 2019, 12:45:45
You should be able to use "/" on Linux,Mac _and_ Windows.

The constant shouldn't be needed.


@ capslock
You cannot track this state in your application as the outside world (eg. alt-tabbing) allows to change capslock state without your application registering the change.

Each OS has custom functions to find out the current state of the capslock - maybe Brucey has some idea. Will file an issue for this.


bye
Ron

On Windows, i use "Key_CapsLock" which i defined as "20".    That does not work on MAC; I will have to see about linux.

Well, in the method i posed above, having a slash variable helped. I'm not really sure what to say.   "/" definitely does not work on windows, on my end.

iWasAdam

the other thing to REALLY aware of is case.
Linux is completely case sensitive, MacOS is generally case sensitive and Windows... Well Windows can't really be too bothered.

So Remember that /Data/ is not the same as /data/

Yellownakji

Quote from: iWasAdam on April 24, 2019, 12:50:20
the other thing to REALLY aware of is case.
Linux is completely case sensitive, MacOS is generally case sensitive and Windows... Well Windows can't really be too bothered.

So Remember that /Data/ is not the same as /data/

Yes, i'm aware of this.   That is why i made the "DIR" type to begin with.   So i can ensure the directories are always labeled properly.

It's only inconsistent in my forum posts because i switch from PC to Mobile and on Mobile, it's kind of annoying to type properly.  Touch screens..