Coder Social home page Coder Social logo

Comments (10)

SamHFrancis avatar SamHFrancis commented on June 2, 2024 1

Hey Chris, thanks for that info! I created this PR #7 and added a cascade list example to the demo project. Please take a look when you get a moment.

from swash.

SamHFrancis avatar SamHFrancis commented on June 2, 2024

Hi Chris, font cascading would be a great feature to add. I have considered it before and couldn't think of a great solution. I didn't have a personal need for it at the time so I just let it go. I'll revisit it tonight/tomorrow and see what I can come up with. Ideas are welcome!

from swash.

AccuPhoenix01 avatar AccuPhoenix01 commented on June 2, 2024

So I was trying something, it appears to work (first time I ran it, so not like this is stress tested):

In the file Font.swift
Add to the public protocol:
static var cascadeList: [UIFontDescriptor]? { get }

add to the public extension Font:
static var cascadeList: [UIFontDescriptor]? { nil }

around line 78 (after the guard var font = UIfont... else):

if Self.cascadeList != nil {
            let cascadedFontDescriptor = font.fontDescriptor.addingAttributes([.cascadeList: Self.cascadeList])
            return UIFont(descriptor: cascadedFontDescriptor, size: size)
        }

return UIFont 
}

In my class where I declare my enum, add the list of font descriptors:

enum Solis: String, Font {
    case thin = "Solis-Thin"
...
static var cascadeList: [UIFontDescriptor]? =
                            [UIFontDescriptor(fontAttributes: [.name: "AmericanTypewriter-Condensed"]),
                             UIFontDescriptor(fontAttributes: [.name: "AvenirNextCondensed-BoldItalic"])]

Of course maybe we should do some checks to see if the fonts exist. Or maybe the font descriptor building happens inside of your Font.swift class and the cascade list is simply a list of strings of font names, so they can be verified, and less code for users to write, we just build our list in order like:

static var cascadeList: [String]? = ["AmericanTypewriter-Condensed", "AvenirNextCondensed-BoldItalic"]

from swash.

SamHFrancis avatar SamHFrancis commented on June 2, 2024

Yes, we could do something like that, like we did with boldTextMapping. The big question here is, do we want the cascade lists to be global static properties for each font? Or do we want the flexibility of defining the lists per-instance, which vanilla UIKit allows? Or both? I've never used this feature before. Might there be cases where different labels using the same Latin font would require different cascaded fonts?

I messed around with it a bit last night and came up with this. It's a per-instance implementation but a similar construct might apply to the static property implementation.

So, as I see it, this is the dream:

MyLatinFont.regular.of(
    textStyle: .body,
    cascadeList: [MyCyrillicFont.regular, MyArabicFont.regular]
)

Where cascadeList is of type [Font] and has a default parameter value of []. It's concise and type-safe. But it doesn't work. We can't create an array of Fonts because the protocol has Self requirements. I toyed around with dropping those requirements but I think they're there for good reasons.

So, instead, we could end up with something like this:

MyLatinFont.regular.of(
    textStyle: .body,
    cascadeList: [
        .init(MyCyrillicFont.regular),
        .init(MyArabicFont.regular)
    ]
)

where cascadeList is a new type [CascadingFontProperties]

public struct CascadingFontProperties {
    public let fontName: String
    public let boldFontName: String?

    public init<F: Font>(_ font: F) {
        self.fontName = font.rawValue
        self.boldFontName = F.boldTextMapping?[font]?.rawValue
    }
}

This allows for boldTextMapping to be used by the cascading fonts too. It would require import Swash If you initialize them any other way than .init() in the function call as I did above. But you'd probably want to define some standard cascade lists elsewhere anyway.

from swash.

AccuPhoenix01 avatar AccuPhoenix01 commented on June 2, 2024

Great ideas! I didn't even think of per instance, that's creative.

I'm considering how I'm planning to use it, and for my needs I don't see myself ever using a per-instance cascade list. It's certainly possible that maybe someone would one day need that, but for my use I am going to have MyLatinFont and then MyCyrillicFont and maybe MyArabicFont and that's pretty much it for the whole app. I believe that I'll want to apply them in the same cascade order onto all my text/labels in the same manner. So from that aspect, it would seem to me to be more efficient if I did only have to declare the list once in my font enum (global like how I did it in my example).

The alternative for any user who really needs a different cascade list on their base font could be to make another FONT enum with a different cascade list.

enum Solis: String, Font {
    case regular = "Solis-Regular"
	...
    
    static let boldTextMapping: [Solis: Solis]? = [
        regular: medium,
        ...
    ]
    
    static var cascadeList: [String]? =
                            MyCyrillicFontName, MyArabicFontName]
}

enum SolisAlternateCascade: String, Font {
   ...
    static var cascadeList: [String]? =
                            MyOtherFontName, MyOther2FontName]
}

My thought is that for an app overall, it would be designed with a core list of fonts and not need to stray too far from a pretty short list of main fonts, and alternate language fonts. If there's someone making an app with different fonts/cascades on every label, they are probably outside the norm.

As for new type [CascadingFontProperties], yes actually that sounds pretty good. Because I think that the cascade fonts should also properly handle the Bold setting as well (if possible, though if not I would prioritize the basic font/language support over style support). Can that be used in the global fashion then?

from swash.

SamHFrancis avatar SamHFrancis commented on June 2, 2024

Ok, yeah let's keep it global then. We can add optional per-instance support in the future if it's deemed useful. I'll make a PR for it.

from swash.

SamHFrancis avatar SamHFrancis commented on June 2, 2024

@AccuPhoenix01 Do you know of a font (preferably baked into iOS) that doesn't support a particular set of symbols? I'd like to test this out.

from swash.

SamHFrancis avatar SamHFrancis commented on June 2, 2024

And one that does support those characters and is not the system font.

from swash.

AccuPhoenix01 avatar AccuPhoenix01 commented on June 2, 2024

Sorry to not get back, um I'm going to have to look. I don't know offhand.

from swash.

AccuPhoenix01 avatar AccuPhoenix01 commented on June 2, 2024

www.iosfonts.com if you didn't know about that as a listing of iOS fonts.

It appears that:
Al Nile, Damascus is only Arabic
Kailasa is only Hindi?
Farah is something only, not sure the language

Has no Cyrillic or Arabic:
Didot, Papyrus

Has Cyrillic letters but no Arabic letters:
American Typewriter, Baskerville, Copperplate, Hoeffler

Can't find a Cyrillic only font from the list.

from swash.

Related Issues (4)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.