Get back a CFArray from a declare

I need to be able to find the name of a font from the font file. The appropriate function is CTFontManagerCreateFontDescriptorsFromURL

SWIFT func CTFontManagerCreateFontDescriptorsFromURL(_ fileURL: CFURL!) -> CFArray!

Thanks to Sam Rowlands who taught me how to declare CTFontManagerRegisterFontsForURL ,I already have the fileURL argument together, but I am at a loss about how to get the CFArray value back in Xojo.

declare function CTFontManagerCreateFontDescriptorsFromURL lib "CoreText" ( fontURL as Ptr) as Ptr

Now how can I get the CFArray values ? I cannot rely on MacOSLib since this is for iOS.

Any help will be greatly appreciated.

Declare Function CFArrayGetCount Lib "CoreFoundation" ( CFArrayRef As Ptr ) As Int32 Declare Function CFArrayGetValueAtIndex Lib "CoreFoundation" ( CFArrayRef As Ptr, CFIndex As Int32 ) As Ptr // returns a CTFontDescriptorRef
Don’t forget to release the CFArrayRef.

But why a Int32? Doesn’t CAArayGetCount deliver a CFIndex which is equvalent to Integer?

meant CF, of course …

[quote=161589:@Eli Ott]Declare Function CFArrayGetCount Lib "CoreFoundation" ( CFArrayRef As Ptr ) As Int32 Declare Function CFArrayGetValueAtIndex Lib "CoreFoundation" ( CFArrayRef As Ptr, CFIndex As Int32 ) As Ptr // returns a CTFontDescriptorRef
Don’t forget to release the CFArrayRef.[/quote]

Eli, I appreciate very much your insight, but have to admit I am not quite sure how to apply that. Ultimately, I need to get string containing the name of the font.

How do I apply that to get that out of declare function CTFontManagerCreateFontDescriptorsFromURL lib "CoreText" ( fontURL as Ptr) as Ptr ?

An Xojo Integer is an Int32.

[code]Dim aCFArray As Ptr = CTFontManagerCreateFontDescriptorsFromURL( fileURL )

Dim ub As Int32 = CFArrayGetCount( aCFArray ) - 1
For i As Int32 = 0 To ub
Dim aCTFontDescriptorRef As Ptr = CFArrayGetValueAtIndex( aCFArray, i )
// then use CTFontDescriptorCopyAttribute() to get the name
Next

release( aCFArray )[/code]

Currently on a 32 bit app, but on 64 bit it’s an Int64. That’s why we were talking about a flexible Double as a CGFloat derivative: The Integers will adapt automatically, but for floats there’s Single and Double and no common adaptive class.
http://documentation.xojo.com/index.php/Integer_datatypes

I would never use Integer for a declare. In the transition time from 32 to 64-bit this will IMO lead to problems. Explicitness is important, even if it will mean some more work when adapting the declares for 64-bit - at least that’s how I handle it.

I can understand you caution but see no need for it. On all current systems, integer size is determined by the OS – on a 32 bit system it’s 4 bytes and eight on a 64 bit system. And so it is with Xojo. I’d say you are creating a lot of unnecessary work for yourself this way.

[quote=161600:@Ulrich Bogun]I’d say you are creating a lot of unnecessary work for yourself this way.[/quote]No. Integer is a Xojo shortcut to Int32 - when writing declares I am dealing with C libraries. I really prefer to translate the C function one-to-one to Xojo. Everything else is dangerous in my view.

Sure, do so. It’s better to be a bit too cautious than to run into the problems of different data types. And sorry, Michel, for hijacking your question!
Only with that

it seems to my you have missed this line from the Xojo docs:

But now back to Michel – sorry again!
Michel, I had some conversion routines in my iOSLib, I think for arrays too. Will have a look at it and if not we could setup one.

No, I know that. But I don’t want this automatism when it comes to declares.

It is alright, Ulrich. No need to be sorry. Actually since we are talking declares and the arrival of 64 bit is imminent, it is all the more important to talk about it. We do not want the declares to explode soon :wink:

Actually, after dissecting MacOSLib for examples, I got this working under OSX. I am still amazed it did not crash left and right :wink: Next I will change the libraries names and hopefully it will work the same in iOS.

[code] dim f as folderitem = SpecialFolder.Desktop.child(“zZxkcqD.ttf”)

if f <> nil then
// - We have a True Type Font file, first step to make a CFURL.
// CFURLRef CFURLCreateFromFSRef (
// CFAllocatorRef allocator,
// const struct FSRef *fsRef
// );

declare function CFURLCreateFromFSRef lib "Cocoa" ( allocator as Ptr, fsRef as Ptr ) as Ptr
Dim CFURLRef as Ptr = CFUrlCreateFromFSRef( nil, f.MacFSRef )

if CFUrlRef = nil then
  Msgbox "Failed to get the CFURLRef of folder """+ f.nativePath + """"
else
  'SWIFT
  'func CTFontManagerCreateFontDescriptorsFromURL(_ fileURL: CFURL!) -> CFArray!
  
  declare function CTFontManagerCreateFontDescriptorsFromURL lib "Cocoa" ( fontURL as Ptr) as CFTypeRef
  Dim aCFArray As CFTyperef = CTFontManagerCreateFontDescriptorsFromURL( CFURLRef )
  
  'func CTFontDescriptorCopyAttribute(_ descriptor: CTFontDescriptor!,
  '_ attribute: CFString!) -> AnyObject!
  
  declare function CTFontDescriptorCopyAttribute lib "Cocoa" (CTFontDescriptor as Ptr, Attribut as CFStringRef) as CFStringRef
  Dim attribute as CFStringRef = "NSFontVisibleNameAttribute"
  
  declare function CFArrayGetCount lib "CoreFoundation.framework" (theArray as CFTypeRef) as Integer
  declare function CFArrayGetValueAtIndex lib "CoreFoundation.framework" (theArray as CFTypeRef, idx as Integer) as Ptr
  
  
  Dim ub As Int32 = CFArrayGetCount( aCFArray ) - 1
  For i As Int32 = 0 To ub
    Dim aCTFontDescriptorRef As Ptr = CFArrayGetValueAtIndex( aCFArray, i )
    // then use CTFontDescriptorCopyAttribute() to get the name
    System.DebugLog CTFontDescriptorCopyAttribute(aCTFontDescriptorRef, attribute)
  Next
end if

end if

[/code]

The last line release( aCFArray ) triggered an unknown item on aCFArray, which makes sense since it is dimmed in the if-then. But when I placed it within, then it was release that became unknown. So at this time I left it out, hoping the scope of the variable takes care of the cleaning.

Thank you.

Great! Glad to read you found a solution.

Yes, freeing/Releasing memory is something that I couldn’t convince to run too – except for one case in my Introspection routine where it works without a flaw. In the other, very similar routines it doesn’t. But I am afraid this will be a leaking solution. When Apple tells you clear a memory manually, I think it is because ARC does not do so in those cases. As far as I know Xojo uses ARC too.

[quote=161630:@Ulrich Bogun]Great! Glad to read you found a solution.

Yes, freeing/Releasing memory is something that I couldn’t convince to run too – except for one case in my Introspection routine where it works without a flaw. In the other, very similar routines it doesn’t. But I am afraid this will be a leaking solution. When Apple tells you clear a memory manually, I think it is because ARC does not do so in those cases. As far as I know Xojo uses ARC too.[/quote]

Yes, I fear the leak as well, but since I do not envision a listing of 2000 fonts, it should remain within acceptable levels.

Thank you for sharing your experience with release(), it makes me feel better :wink:

But only for internal Xojo objects.

The CFArray needs to be released with CFRelease:

Declare Sub CFRelease Lib "CoreFoundation" ( CFTypeRef As Ptr ) CFRelease( aCFArray )

[quote=161634:@Eli Ott]But only for internal Xojo objects.

The CFArray needs to be released with CFRelease:

Declare Sub CFRelease Lib "CoreFoundation" ( CFTypeRef As Ptr ) CFRelease( aCFArray )[/quote]

Splendid. Thank you Eli :slight_smile:

[quote=161634:@Eli Ott]@Ulrich Bogun As far as I know Xojo uses ARC too.
But only for internal Xojo objects.[/quote]
Are you really sure? Apple has deprecated retain and release from NSObject, and I have never used it for my own declares. The declared controls live as long as they are captured in a Xojo Ptr and I have no memoryleak when I let the Ptr die.

And thanks for the CFRelease declaration. In my project, I am told to free the values (I have a almost complete OS X ObjectiveCRuntime lib that could be easily transferred to iOS), and in one case, after trying out about anything, I succeeded with a call to release?!?!

Xojo ARC and OS X ARC have nothing to do with each other.

When the Apple docs say “you have to release”, you have to.