Integrating revFont

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, LCMark

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Integrating revFont

Post by LCMark » Mon May 20, 2013 12:31 pm

At the conference, @trevordevore and I got into a discussion and he happened to mention that there was sometimes a strange problem with the system seemingly not allowing the deletion of locally stored font files that had been loaded using revFontLoad. As it turns out, this is because revFontLoad currently uses AddFontResource which inserts fonts globally, rather than locally. (I couldn't quite understand this at the time, but realized just now that AddFontResourceEx which allows loading within an application context wasn't available until Win2k - and at the time revFont was written Win95/98 was still very much the rage).

Anyway, our discussion went on and essentially we could see no reason not to integrate revFont into the engine with proper syntax (its functionality is almost trivial - its more work to support in an external, than it is in the engine). We thought an extension to the 'start using' / 'stop using' syntax would be appropriate:

Code: Select all

start using font <file: expr> [ globally ]
stop using font <file: expr> [ globally ]
or perhaps (if we want to distinguish between the notion of a 'font' and a 'font file'):

Code: Select all

start using font file <file: expr> [ globally ]
stop using font file <file: expr> [ globally ]
I was thinking this might make quite a nice example of a 'how-to' we could write up - it covers merging in syntax with the current rules (i.e. augmenting start/stop commands) and platform-dependent functionality. It is also not just a pedagogic example but something useful.

So, what do people think of the above syntax? Any other suggestions?

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Integrating revFont

Post by trevordevore » Mon May 20, 2013 1:25 pm

I like the syntax that specifically states "file". OS X has ATSFontActivateFromMemory and Windows has Font embedding http://msdn.microsoft.com/en-us/library ... s.85).aspx so it seems that "starting using font" could also be used to load a font from memory at some point in the future.

I started looking at adding this on the way plane ride home but I didn't have the map command example and got stuck.
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

DarScott
Posts: 227
Joined: Fri Jul 28, 2006 12:23 am
Location: Albuquerque
Contact:

Re: Integrating revFont

Post by DarScott » Mon May 20, 2013 10:34 pm

I wonder what the generalization of "start using" might be. This might help in knowing what is expected when other "start using" commands are considered. Or even what is lacking in the current "start using stack".

The "start using stack" command has a corresponding "stacksInUse" property. Perhaps users would expect a "fontsInUse" or "fontfilesInUse" property. The dictionary currently suggests comparing fontNames() before and after loading to show a loaded font list.

Perhaps the default scope should have the same feel as the default (and only) scope of stacks in use.

There might be a problem that some users would try to apply the modify "globally" to stacks, but that may be a concern we can live with.

The "start using stack" allows either a stack name (the stack is loaded or there is a stackFiles entry) or a file reference. Perhaps this could apply in a similar manner to the new command. (And maybe someday it would seem right to have a fontFiles property for stacks.)

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Integrating revFont

Post by trevordevore » Mon May 20, 2013 10:42 pm

Regrading fontFiles of a stack. I don't know that it make sense to have a fontFiles property at the stack level. It seems to me that a font should be a resource of an application rather than a stack. Perhaps once scoped projects have been added to the engine it would make sense to be able to add a font as a resource of the project?
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Integrating revFont

Post by LCMark » Tue May 21, 2013 10:30 am

Due to the way font loading works, it's either global to the system or global to the application - it would be tricky to make it scoped. That being said, a global property 'fontFilesInUse' (or similar) could be handy - it has synergy with 'start using stack'.

I'm not sure there's any problem with 'globally' being used with stacks - we can make that a parse error to ensure expectations are appropriately set.

Moving forward, 'projects' would be the ideal place to put a list of referenced fonts for automatic inclusion (indeed, on iOS, you can't load fonts dynamically I don't think - although I'd have to check, we're currently using UIFont, but CoreText might give us more options). However, dynamic insertion and removal would still be useful on the other platforms I think - even with iOS not allowing it.

My only slight hesitation is what the syntax should be (especially in light of a matching global property) particularly with the suggestion of possibly allowing embedded font data. Essentially we have two options I guess:

Code: Select all

start/stop using font file <filename: expr> [ globally ]
the fontFilesInUse
or

Code: Select all

start/stop using font <filename: expr> [ globally ]
the fontsInUse
The former clearly demonstrates what you are manipulating (font files, rather than fonts). Also, the global would then (I guess) be a list of (absolute?) filenames. The latter would be perfectly adequate for both font files and font data - you can snoop 'filename' to see if it is font binary data or a filename; however, it is then unclear what 'fontsInUse' would be. The property name would suggest you'd get a list of names of fonts, however this means the font loading code would have to do a fair bit more work to determine the names of the fonts actually being loaded. Indeed, if we were to allow loading/unloading of fonts as binary data then you'd have to use the name of the font as the key to stop using it which is a little inconsistent.

Another aspect to consider is whether this mechanism 'remembers' the global aspect. i.e. if you do:

Code: Select all

start using font file "myfile.ttf" globally
stop using font file "myfile.ttf"
Should the 'stop' remember the fact the font was loaded globally?

Also (yet another) thing to consider, what should be the key for stop after start... You might pass in a relative path so should that then be the key used to stop using the font? (This would be consistent with the file commands).

DarScott
Posts: 227
Joined: Fri Jul 28, 2006 12:23 am
Location: Albuquerque
Contact:

Re: Integrating revFont

Post by DarScott » Tue May 21, 2013 9:32 pm

I very rarely use (or, maybe, never used) 'start using stack ...' with a file reference. So, my instincts on file references might be off.

I think we have LiveCode language feature examples that take either a value or file reference. And we have some that take a value and we use URL sometimes to get the value. Either of those are "paid for" concepts that can be borrowed. Maybe, in general, those can be unified or one can be preferred.

One advantage of leaving off "file" is that that keeps the font reference general. The first reference implemented might be a file name, but other references or direct (immediate) values can be allowed later. Otherwise, an additional command of the 'start using' style is needed. Or, maybe 'file' can be thought of as the type of reference and this is just a variation of 'start using font'; that is, the first reference type implemented is 'file'. Then I wonder where do we have types of references in LiveCode and what can be borrow there.

So, I guess much of this depends on how we refer to resources in general in the language cleanup.

If a control or a stack needs a font, there might be some convention in indicating that in a property. In any case, that information can be passed on to developers using that component. The designer of that control or stack can decide whether to have that fail to function if the font is missing or limp along with a caveat. The application developer can make sure the font is available. So, I'm OK with the notion that fonts are an application thing. Mostly.

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Integrating revFont

Post by LCMark » Fri May 24, 2013 3:37 pm

Okay, in the interests of moving forward with this a bit, how about settling for this as the initial syntax and semantics:

Code: Select all

start using font file <filename: expr> [ globally ]
stop using font file <filename: expr>
the fontFilesInUse
The rationale here is that there is a difference between a font file and the font(s) it contains and by having an explicit 'file' keyword, it naturally suggests a global 'fontFilesInUse' property which would contain a return-delimited list of filenames of fonts that have been loaded.

In terms of semantics:

start using font file
The given filename is resolved to an absolute path. An attempt is then made to load the given file as a font, system-wide if 'globally' is specified.

If the given file has previously been loaded using this mechanism then it is first unloaded, then re-loaded. (Rationale: This approach means a font can be changed from local to global, or global to local; it also ensures the font is the 'most recently loaded' if there are font files loaded with conflicting names).

If the system doesn't support loading fonts globally, an error is thrown. (Rationale: Using 'globally' on systems that don't support it - e.g. mobile - is essentially an application error, if you are trying to load a font for all processes then you must have a good reason to).

If loading the font file failed, the result should be set to 'can't load font file'. (Rationale: The current general rule with errors is that errors the scripter can avoid should be exceptions, whereas errors the scripter cannot avoid should set the result. There are many reasons why loading a font file could fail, therefore this error should be returned in the result.)

stop using font file
The given filename is resolved to an absolute path. An attempt is then made to unload the given file as a font. It will be remembered how the font was previously loaded (globally or locally) so that the correct system call can be made.

If unloading the font file failed, the result should be set to 'can't unload font file'. (Rationale: Again, there are reasons why a font might not be unloadable depending on how the system manages them.).

If there is no font in use with the given filename, then the command as no effect.

the fontFIlesInUse
This property returns a newline-delimited list of absolute paths to all the font files that have been loaded in this session using 'start using font file'.

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Integrating revFont

Post by trevordevore » Fri May 24, 2013 3:40 pm

Sounds good. Ship it! :-)
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Integrating revFont

Post by LCMark » Fri May 24, 2013 3:49 pm

@trevordevore: You mean you don't have a pull-request ready to go yet? ;)

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Integrating revFont

Post by trevordevore » Fri May 24, 2013 3:59 pm

I just need an example of implementing a command and I'm ready to go! I didn't get to see the map demo so I just have the general description of what needed to be done from the doc you handed out.

We (finally) released ScreenSteps 3 this week so I'm ready to tackle a project.
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

Janschenkel
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 977
Joined: Sat Apr 08, 2006 7:47 am
Location: Aalst, Belgium
Contact:

Re: Integrating revFont

Post by Janschenkel » Fri May 24, 2013 4:34 pm

Hi Trevor,

The required changes for the 'map' command are available in a separate branch of Mark's github repository:
https://github.com/runrevmark/livecode/ ... ap_command

Have at! :-)

Jan Schenkel.
Quartam Reports & PDF Library for LiveCode
www.quartam.com

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: Integrating revFont

Post by mwieder » Tue May 28, 2013 8:38 pm

Hmmm... would this support reference counting? What should happen when two applications each start using a font file resource, then one app quits and stops using the font resource? What about if one loads it globally and the other doesn't? Is this OS-specific?

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Integrating revFont

Post by LCMark » Wed May 29, 2013 10:13 am

@mwieder: I'd imagine the OS handles that. Certainly for font files used non-globally then there would be no conflict - the fonts would only be added to the apps internal font-list rather than the system list so there's no conflict there. In terms of adding them 'globally' then this would require experimentation to see on each platform...

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Integrating revFont

Post by LCMark » Wed May 29, 2013 10:28 am

@trevordevore: I had a quick look at platform support for adding/removing fonts and it seems that we can get it working (dynamically) for all platforms eventually (although on iOS probably not until we switch to use CTFont and CoreText, rather than UIFont and UIKit). Therefore, I'd suggest adding the actual platform-dependent methods to MCUIDC as virtual methods (maybe loadfont() / unloadfont()?), implemented on a per-platform basis in MCScreenDC. In terms of adding the syntax, you should take a look at the 'feature-map_command' branch and 'feature-clear_image' branch in my (runrevmark) livecode repository. The latter is (a somewhat small, admittedly!) example of 'cleaving' in new syntax to an existing command.

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Integrating revFont

Post by trevordevore » Fri May 31, 2013 3:20 pm

@runrevmark: I've started work on adding load/unload font in. I've modified uidc.cpp and uidc.h and now I'm working on osxdc.cpp and osxdc.h. Assuming I understood you correctly that is what I should be doing :-) A couple of questions/problems:

1) Do I need to do any specific checks for file access permissions? The revFont external had a check for this but I'm not sure how the engine handles it. Right now I manipulate the font filename with MCS_resolvePath and MCS_pathtoref.

2) The external uses std::map to map the font file to the ATSFontContainerRef so that unload font will work. If I add the following to osxdc.cpp I start getting a compiler error:

#include <string>
#include <map>
std::map<std::string, ATSFontContainerRef> s_font_map;

Error: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/new:94: Redefinition of 'void* operator new(size_t, void*)'

Any idea as to what the problem is? Suggestions?
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

Locked

Return to “Engine Contributors”