• 시놉시스

    • Text Kit과 WebKit은 모두 Core Text 기반으로 되어 있다.
    • Core Text를 쓰면 아주 특수한 작업을 할 수 있다.
    • 유니코트 텍스트를 표현하기 위해서는 문자열과 폰트 정보가 필요하다.
      • 문자열 + 폰트 = 글리프
  • Specifying Fonts - 어떤 폰트를 쓸 것인가?

    • Dynamic type
      • iOS7에 처음 등장
      • 용도에 따른 구조화 - 숫자가 아니라 의미적으로 표현
      • 가독성을 높이는 것이 중점
      • 사용자가 크기를 조절한다.
        • 개발자는 모든 경우에 대응할 필요가 있다.
        • 글자 하나하나 뿐 아니라, 글자 사이의 간격도 폰트 크기마다 달라진다
        • 오토레이아웃을 쓰면 편하다.
    // 시스템 폰트 반환
    class func preferredFont(forTextStyle style: UIFont.TextStyle) -> UIFont
    
    // CSS로도 사용 가능
    // -apple-system- prefix가 붙어있다.
    
    • System Font
      • 메타폰트: 시스템 릴리즈마다 달라질 수 있다.(실제로도 달라졌다.)
      • 실제 이름은 숨겨져 있다.(.으로 시작한다)
      • 숨겨져 있는 거 직접 꺼내 쓰지 말고 팩토리 메소드로 쓰면 자동으로 업데이트 된다.
    • Font descriptors
      • 폰트를 표현하는 객체 - 폰트 자체보다 상당히 가볍다.
      • 폰트 프로퍼티에 접근하고 변경할 수 있다.
      • 키-값 형태의 구조
      • descriptor가 표현하는 폰트가 시스템에 존재하지 않을 수 있다.
        • 매칭해서 시스템에서 실제 폰트로 변환한다.
      • NSCoding 프로토콜을 채택해서 자동 직렬화 가능
        • attribute를 꺼내서 수동으로 직렬화 가능
      • 폰트 인스턴스의 특성을 변경할 수 있다.
        • 특정 기능을 활성화 시키거나
        • 캐릭터 셋을 변경하거나
    	// 명시적 매칭
    	func matchingFontDescriptors(withMandatoryKeys mandatoryKeys: Set<UIFontDescriptor.AttributeName>?) -> [UIFontDescriptor]
    	// 암시적 매칭
    	func withSymbolicTraits(_ symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFontDescriptor?
    	init(descriptor: UIFontDescriptor, size pointSize: CGFloat)
    	
    	// 예제
    	
    	let helveticaNeue = UIFontDescriptor(fontAttributes: [.family: "Helvetica Neue"])
    	let matched = helveticaNeue.matchingFontDescriptors(withMandatoryKeys: nil)
    	
    	let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
    	        let boldFontDescriptor = fontDescriptor.withSymbolicTraits(.traitBold)
    	        let boldFont = UIFont(descriptor: boldFontDescriptor!, size: 0.0)
    
    // 폰트 기능 활성화 예제
    	let timeFeatureSettings = [
            [ UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
              UIFontDescriptor.FeatureKey.typeIdentifier: kProportionalNumbersSelector
            ],
            [ UIFontDescriptor.FeatureKey.featureIdentifier: kCharacterAlternativesType,
              UIFontDescriptor.FeatureKey.typeIdentifier: 1
            ]
        ]
    
       let font = UIFont.systemFont(ofSize: 16)
       let descriptor = font.fontDescriptor
       let timeDescriptor = descriptor.addingAttributes([.featureSettings: timeFeatureSettings])
    
       let timeFont = UIFont(descriptor: timeDescriptor, size: 0.0)
    
    // 특정 캐릭터 제거
    	let font = UIFont.systemFont(ofSize: 16)
    	let descriptor = font.fontDescriptor
    	
    	let characterSet = descriptor.object(forKey: .characterSet) as! NSMutableCharacterSet
    	
    	// 눈사람 모양
    	characterSet.removeCharacters(in: NSMakeRange(0x2603, 1)) 
    	let snowmanRemoved = descriptor.addingAttributes([.characterSet: characterSet])
    	
    	let newFont = UIFont(descriptor: snowmanRemoved, size: 0.0)
    
    
    • Adding fonts
      • 지원 컨테이너 타입
        • TTF, TTC, OTF, OTC
      • 지원 포맷
        • Apple Advanced Typography(AAT)
          • morx와 mort가 있는데, iOS는 morx만 지원
        • OpenType: Complex Script(pre-Vista Indic)
      • 추가하기
        • 자동: 앱 번들에 추가한다.
          • Info.plist의 UIAppFonts키로 추가한다.
        • 수동: CTFontManager,
  • Language Tagging

    • 똑같은 글자도 문화권에 따라 다르게 표현될 수 있다.
      • kCTFontLanguagesAttribute 참조
      • 글리프 변경
      • 라인브레이킹
      • font fallback
  • Modifying fallbacks

    • fallback이란? - 어떤 동작을 수행할 수 없을 때, 이를 대체할 수 있는 동작
    • descriptor에 cascadeList를 추가함으로써 가능
    static let cascadeList: UIFontDescriptor.AttributeName