Skip to content

Commit

Permalink
Add support for decoding Apple native font via factory
Browse files Browse the repository at this point in the history
Expands on the current iOS factory method to decode raw font data (from file) to adding a second font decoding function that can use a native Apple font (`UIFont` / `NSFont`). This reuses some of the logic from fallback fonts. There's one main difference - while we are calculating weight and width, those get ignored in addition to size; the font data returned seems to be used as vector(?) data to draw characters in the weight / width as defined in a text run, rather than overridden by any supplied font. But, we need to provide a weight and width when obtaining a Rive font from cpp, so we re-use the logic.

Diffs=
414c142f2 Add support for decoding Apple native font via factory (#8180)

Co-authored-by: David Skuza <david@rive.app>
  • Loading branch information
dskuza and dskuza committed Sep 19, 2024
1 parent 6a8244e commit a3ae86e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
48212b2bbd1f55028502f0669ea2be69c7a62694
414c142f2c11ef3ad2cfa9fd0a1ed18dc7f9f98f
47 changes: 31 additions & 16 deletions Source/Renderer/RiveFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,30 @@

static NSArray<id<RiveFallbackFontProvider>>* _fallbackFonts = nil;

static rive::rcp<rive::Font> findFallbackFont(rive::Span<const rive::Unichar> missing)
static rive::rcp<rive::Font> riveFontFromNativeFont(id font)
{
// For each descriptor…
for (id<RiveFallbackFontProvider> fallback in RiveFont.fallbackFonts)
uint16_t weight = 400;
if ([font conformsToProtocol:@protocol(RiveWeightProvider)])
{
id fallbackFont = fallback.fallbackFont;
weight = [font riveWeightValue];
}

uint16_t weight = 400;
if ([fallbackFont conformsToProtocol:@protocol(RiveWeightProvider)])
{
weight = [fallbackFont riveWeightValue];
}
uint8_t width = 100;
if ([font conformsToProtocol:@protocol(RiveFontWidthProvider)])
{
width = [font riveFontWidthValue];
}

uint8_t width = 100;
if ([fallbackFont conformsToProtocol:@protocol(RiveFontWidthProvider)])
{
width = [fallbackFont riveFontWidthValue];
}
CTFontRef ctFont = (__bridge CTFontRef)font;
return HBFont::FromSystem((void*)ctFont, weight, width);
}

CTFontRef ctFont = (__bridge CTFontRef)fallbackFont;
auto font = HBFont::FromSystem((void*)ctFont, weight, width);
static rive::rcp<rive::Font> findFallbackFont(rive::Span<const rive::Unichar> missing)
{
// For each descriptor…
for (id<RiveFallbackFontProvider> fallback in RiveFont.fallbackFonts)
{
auto font = riveFontFromNativeFont(fallback.fallbackFont);
if (font->hasGlyph(missing))
{
rive::rcp<rive::Font> rcFont = rive::rcp<rive::Font>(font);
Expand Down Expand Up @@ -181,6 +184,18 @@ - (RiveFont*)decodeFont:(nonnull NSData*)data
initWithFont:instance->decodeFont(rive::Span<const uint8_t>(bytes, [data length]))];
}

#if TARGET_OS_IPHONE
- (RiveFont*)decodeUIFont:(UIFont*)font
{
return [[RiveFont alloc] initWithFont:riveFontFromNativeFont(font)];
}
#else
- (RiveFont*)decodeNSFont:(NSFont*)font
{
return [[RiveFont alloc] initWithFont:riveFontFromNativeFont(font)];
}
#endif

- (RiveAudio*)decodeAudio:(nonnull NSData*)data
{
UInt8* bytes = (UInt8*)[data bytes];
Expand Down
5 changes: 5 additions & 0 deletions Source/Renderer/include/RiveFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface RiveFactory : NSObject
- (RiveFont*)decodeFont:(NSData*)data;
#if TARGET_OS_IPHONE
- (RiveFont*)decodeUIFont:(UIFont*)data NS_SWIFT_NAME(decodeFont(_:));
#else
- (RiveFont*)decodeNSFont:(NSFont*)data NS_SWIFT_NAME(decodeFont(_:));
#endif
- (RiveRenderImage*)decodeImage:(NSData*)data;
- (RiveAudio*)decodeAudio:(NSData*)data;
@end
Expand Down

0 comments on commit a3ae86e

Please sign in to comment.