Comments (10)
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.
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.
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.
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 Font
s 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.
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.
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.
@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.
And one that does support those characters and is not the system font.
from swash.
Sorry to not get back, um I'm going to have to look. I don't know offhand.
from swash.
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)
- Bold system setting support? HOT 3
- Font sizes spreadsheet HOT 4
- SwiftUI support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swash.