Friday, August 12, 2022

#1 2010-12-16 11:14:27 am

mekronk
Member
Registered: 2006-07-14
Posts: 122

Determining the Path to a Font file

Hi All,
I need to get the path to a font file selected by users so that it can be used in a do shell script command.  In my applescript studio version, I used an open panel, but I thought maybe there was a more slick way to do it within ASOC.  I've looked through the documentation for NSFont, NSFontManager and NSFontPanel, but nothing jumped out at me.  It seems that for the most part, once you have an NSFont instance, you work with that and there is no need for the path to the corresponding font file.

Offline

 

#2 2010-12-16 05:02:01 pm

leonsimard
Member
From:: Montreal, Canada
Registered: 2009-09-27
Posts: 531

Re: Determining the Path to a Font file

Did you look at NSFontDescriptor? There might be a few methods that could help you, maybe...

Browser: Safari 6533.18.5
Operating System: Mac OS X (10.6)

Offline

 

#3 2010-12-16 07:12:52 pm

rdelmar
Member
From:: Sonoma County, CA
Registered: 2010-03-05
Posts: 1008

Re: Determining the Path to a Font file

I don't think you can get the path to the font file from the font instance -- what do you want to do with your do shell script command?  Maybe you can do what you need within ASOC and not use do shell script.

Offline

 

#4 2010-12-17 11:47:54 am

mekronk
Member
Registered: 2006-07-14
Posts: 122

Re: Determining the Path to a Font file

Thanks for the responses.  No luck with the NSFontDescriptor, at least from what I can tell with my noobie skill of deciphering the documentation.  I'm running a UNIX app with the do shell script command and it requires the posix path of the file it's working on so, unfortunately, there isn't an ASOC alternative.  I think I'll forgo the slick and go with an open panel smile.

Actually, as I'm working on fonts and I don't really know much about font management, if I want to set an initial directory for the panel, can I assume that the users fonts will always be found at "/Library/Fonts/"?   It is for all the macs I've checked.

Offline

 

#5 2010-12-17 12:16:00 pm

leonsimard
Member
From:: Montreal, Canada
Registered: 2009-09-27
Posts: 531

Re: Determining the Path to a Font file

Actually you need to pass "~/Library/Fonts/" to the nsopenpanel for it to open in the user's font folder. The tilde means the current logged in user's home folder path on every machines, no distinction whatsoever. The version you posted was the path to the local font folder on the sartup disk. :-)

It's strange that we can't get access to the font's path. I'll check this when time permits and post back any result.

Good luck with your project!

Browser: Safari 6533.18.5
Operating System: Mac OS X (10.6)

Offline

 

#6 2010-12-17 12:49:14 pm

mekronk
Member
Registered: 2006-07-14
Posts: 122

Re: Determining the Path to a Font file

leonsimard wrote:

Actually you need to pass "~/Library/Fonts/" to the nsopenpanel for it to open in the user's font folder. The tilde means the current logged in user's home folder path on every machines, no distinction whatsoever. The version you posted was the path to the local font folder on the sartup disk. :-)


This is why I asked.  On my system, the font folder in my home folder path is empty.  All my fonts are in the Fonts folder in the Library folder of the start up disk.  Like I said, I don't know anything about font management.  They just magically show up when I want to change them smile.  But it seems that the location can vary, perhaps depending on how they were installed?  Regardless, it seems like it would be useful to have a way of finding the location of the Font folder.  Interestingly, if I use "fonts folder" in applescript, it points to Fonts folder in Library in the system folder.

Offline

 

#7 2010-12-17 12:56:47 pm

leonsimard
Member
From:: Montreal, Canada
Registered: 2009-09-27
Posts: 531

Re: Determining the Path to a Font file

Yeah, well there is so many apps and tools that can play in the fonts folders that it is hard to make sense of it.

Yes in AS you can use fonts folder but if you use either "of system domain" or "of locale domain" or "of user domain" (I could be off on the exact spelling, memory...) then you can specify which one you want. Check in the AppleScript editor, within the library window, the standard additions I think, it will have more details.

Browser: Safari 6533.18.5
Operating System: Mac OS X (10.6)

Offline

 

#8 2010-12-17 02:14:02 pm

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11771
Website

Re: Determining the Path to a Font file

Hi,

in Snow Leopard you can get the path of a NSFont with CTFontDescriptor (a part of CoreText > ApplicationServices.framework)

Applescript:


- (NSString)pathToFont:(NSFont *)font
{
   CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize ((CFStringRef)[font fontName], [font pointSize]);
   CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
   NSString *fontPath = [NSString stringWithString:[(NSURL *)url path]];
   CFRelease(fontRef);
   CFRelease(url);
   return fontPath;
}

The problem is you can't use CoreFoundation code in ASOC.
But you could create a custom Cocoa class and call the method from there


regards

Stefan

Offline

 

#9 2010-12-17 04:46:12 pm

rdelmar
Member
From:: Sonoma County, CA
Registered: 2010-03-05
Posts: 1008

Re: Determining the Path to a Font file

- (NSString)pathToFont:(NSFont *)font


I think this needs to be (NSString *)pathToFont:(NSFont *)font

With that change, StefanK's method worked for me with this call to it:

set myPath to objC's pathToFont_(current application's NSFont's fontWithName_size_("Times-Roman", 12))

objC is a property connected to the blue cube that is of the class GetPath (the name of the .h and .m files where I put Stefan's objective-C code).

Ric

Offline

 

#10 2010-12-17 04:48:32 pm

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11771
Website

Re: Determining the Path to a Font file

rdelmar wrote:

I think this needs to be (NSString *)pathToFont:(NSFont *)font


Of course smile


regards

Stefan

Offline

 

#11 2010-12-17 05:50:31 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6791

Re: Determining the Path to a Font file

FWIW, I think stuff like this is a good reason to consider having a base Objective-C class in your projects that your app delegate inherits from. You can then quickly add methods like this and call them directly, without having to add/instantiate/add property.

Stefan: Is there some special reason you put "NSString stringWithString:" in there?


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#12 2010-12-17 07:23:21 pm

rdelmar
Member
From:: Sonoma County, CA
Registered: 2010-03-05
Posts: 1008

Re: Determining the Path to a Font file

FWIW, I think stuff like this is a good reason to consider having a base Objective-C class in your projects that your app delegate inherits from. You can then quickly add methods like this and call them directly, without having to add/instantiate/add property.


Yeah, I agree -- I sometimes forget about that option.  Another fix that makes the method simpler, is to pass the font name and size instead of the font object -- since you have to call current application's NSFont's fontWithName_size_ and pass it that information anyway and then the objective-C method just gets those values back from the font object (of course, if you already have the font object, then Stefan's way would be easier). So, this is the code I have now:

Applescript:

script FontPathAppDelegate
   property parent : class "GetPath"
   
   on applicationWillFinishLaunching_(aNotification)
       set myPath to pathToFontNamed_size_("Times-Roman", 12)
       log myPath
   end applicationWillFinishLaunching_
   
end script

And the GetPath.m is:

Applescript:

@implementation GetPath

- (NSString *)pathToFontNamed:(NSFont *)fontName size:(CGFloat)fontSize
{
CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize ((CFStringRef)fontName, fontSize);
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
NSString *fontPath = [(NSURL *)url path];
CFRelease(fontRef);
CFRelease(url);
return fontPath;
}
@end

Ric

Offline

 

#13 2010-12-17 07:28:21 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6791

Re: Determining the Path to a Font file

- (NSString *)pathToFontNamed:(NSFont *)fontName size:(CGFloat)fontSize


I think you meant NSString rather than NSFont...


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#14 2010-12-17 08:08:29 pm

rdelmar
Member
From:: Sonoma County, CA
Registered: 2010-03-05
Posts: 1008

Re: Determining the Path to a Font file

Oops!  Yeah, that's what I meant to do (but I forgot to change it from stefan's method, and it worked anyway).

Ric

Offline

 

#15 2010-12-18 02:09:59 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11771
Website

Re: Determining the Path to a Font file

Shane Stanley wrote:

Stefan: Is there some special reason you put "NSString stringWithString:" in there?


I want to make sure to get a retained string before releasing the URL object


regards

Stefan

Offline

 

#16 2010-12-18 04:36:39 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6791

Re: Determining the Path to a Font file

StefanK wrote:

I want to make sure to get a retained string before releasing the URL object


I'm lost. Are you writing this with GC in mind?

I could understand if you were returning url itself, but not its path...


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#17 2010-12-18 04:45:02 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11771
Website

Re: Determining the Path to a Font file

Shane Stanley wrote:

Are you writing this with GC in mind?


No, I'm an old-fashioned memory management guy wink

Probably it's overcautious and not needed,
but my intention is, if the derived path depends on the url object,
it's safer to create a new string object before releasing the url object.


regards

Stefan

Offline

 

#18 2010-12-18 05:26:02 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6791

Re: Determining the Path to a Font file

StefanK wrote:

No, I'm an old-fashioned memory management guy wink


Well as I read things, we still need to manage memory at the CF level, albeit a bit differently.

Probably it's overcautious and not needed,
but my intention is, if the derived path depends on the url object,
it's safer to create a new string object before releasing the url object.


Thanks. So if instead I did something like:

Applescript:

NSString *fontPath = NSMakeCollectable(CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle))

I assume I'd be fine.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#19 2010-12-18 06:18:41 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11771
Website

Re: Determining the Path to a Font file

Shane Stanley wrote:

Applescript:

NSString *fontPath = NSMakeCollectable(CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle))

I assume I'd be fine.


Actually you should write

Applescript:


NSString *fontPath = [NSMakeCollectable(CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle)) autorelease];

because of the leak of CFURLCopyFileSystemPath.

I just tested this

Applescript:


NSString *fontPath = [(NSURL *)url path];

and it worked perfectly


regards

Stefan

Offline

 

#20 2010-12-20 02:08:04 pm

mekronk
Member
Registered: 2006-07-14
Posts: 122

Re: Determining the Path to a Font file

Uhh ... you guys lost me about 10 posts back when you started talking about custom classes smile.  Would the "Adding Objective-C Code" section in Shane's book be a good place to start the deciphering process?  I've glanced at it but I haven't really gone over it very thoroughly since for some reason when I see the ".h's" and ".m's", my brain seems to go into a shut down mode smile.

Offline

 

#21 2010-12-20 03:58:57 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6791

Re: Determining the Path to a Font file

mekronk wrote:

Would the "Adding Objective-C Code" section in Shane's book be a good place to start the deciphering process?


It would certainly help.

To actually make a class, go to File -> New File, and choose Objective-C class; give it a name, say MyNewClass. You will get two new files. In the .m file, paste the method code from Stefan or Ric between the @implementation and @end statements, then save. Got to the .h file and paste in just the signature of the method -- up to the first { -- before the @end line but outside the { and }. Instead of ending it with a {, end it with a semicolon, like this:

@interface MyNewClass : NSObject {
}
- (NSString *)pathToFontNamed:(NSString *)fontName size:(CGFloat)fontSize;

@end

Save, and you're set. You can either instantiate it (see the chapter Instantiating Script Objects), or you can just change the parent property of your script to the new class, and inherit the method.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#22 2010-12-21 12:23:42 am

mekronk
Member
Registered: 2006-07-14
Posts: 122

Re: Determining the Path to a Font file

Thanks.  I'll give it a try.

Offline

 

#23 2022-03-26 11:17:11 am

mac.jedi
Member
Registered: 2008-04-23
Posts: 44

Re: Determining the Path to a Font file

Greetings,  It's been a long time! 

I need some help please. I've been using this class in a project I started 10 years ago and it's been working fine, but now won't compile.  Below is the code as it stands now.  I know there have been a lot of changes over the years, that I'm not up to date on, so was hoping a kind soul would be able to save me smile.  Thanks so much!


@implementation MyPathToFontClass
- (NSString *)pathToFontNamed:(NSFont *)fontName size:(CGFloat)fontSize
{
    CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize ((const struct __CFString *)fontName, fontSize);
    CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
    NSString *fontPath = [(__bridge NSURL *)url path];
    //CFRelease(fontRef);
    //CFRelease(url);
    return fontPath;
}
@end

I'm getting the following issues:

Unknown type name 'CTFontDescriptorRef'; did you mean 'CFFileDescriptorRef'?
Implicit declaration of function 'CTFontDescriptorCreateWithNameAndSize' is invalid in C99
Implicit declaration of function 'CTFontDescriptorCopyAttribute' is invalid in C99
Use of undeclared identifier 'kCTFontURLAttribute'
- (NSString *)pathToFontNamed:(NSFont *)fontName size:(CGFloat)fontSize > Expected a type
Cast of Objective-C pointer type 'id' to C pointer type 'const struct __CFString *' requires a bridged cast
Use __bridge to convert directly (no change in ownership)
Use CFBridgingRetain call to make an ARC object available as a +1 'const struct __CFString *'
Incompatible integer to pointer conversion initializing 'CFFileDescriptorRef' (aka 'struct __CFFileDescriptor *') with an expression of type 'int'

Offline

 

#24 2022-03-27 11:46:16 am

Mark FX
Member
From:: UK
Registered: 2011-08-12
Posts: 163

Re: Determining the Path to a Font file

@mac.jedi

The first line of the error message tells you that the compiler does not understand the 'CTFontDescriptorRef' class type.

So I suspect that you have upgraded to a newer operating system version, from the one used when creating your original code, and the 'CTFontDescriptorRef' class type is no longer supported on the newer OS version.

It's important to quote your OS version when posting code on this forum, as a lot has changed to the newer "Big Sur" & "Monterey" operating system versions.

This works for me on "High Sierra", but I have not checked it on my "Mojave" or "Catalina" partitions.

Applescript:


- (NSString *)filePathOfFont:(NSFont *)font {
   CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize ((CFStringRef)[font fontName], [font pointSize]);
   CFURLRef fontURL = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
   NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(fontURL) path]];
   return fontPath;
}

//And I would call the function something like this
NSFont *font = [NSFont fontWithName:@"Menlo" size:12.0];
NSString *fontPath = [self filePathOfFont:font];
NSLog(@"%@", fontPath);

Please quote your operating system version for further help.

You do realise that this is an AppleScript forum, and not an Objective-C specific forum ?

Regards Mark

Last edited by Mark FX (2022-03-27 11:54:37 am)

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)