diff --git a/LyricsX/CBridge/TouchBarPrivateAPI.h b/LyricsX/CBridge/TouchBarPrivateAPI.h index 1bbc855a..622d5c1b 100644 --- a/LyricsX/CBridge/TouchBarPrivateAPI.h +++ b/LyricsX/CBridge/TouchBarPrivateAPI.h @@ -33,15 +33,25 @@ @interface NSTouchBar (PrivateMethods) -// presentSystemModalFunctionBar:placement:systemTrayItemIdentifier: -// v40@0:8@16q24@32 -+ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier; +// MARK: macOS 10.14 and above -+ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier; ++ (void)presentSystemModalTouchBar:(NSTouchBar *)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier NS_AVAILABLE_MAC(10.14); -+ (void)dismissSystemModalFunctionBar:(NSTouchBar *)touchBar; ++ (void)presentSystemModalTouchBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier NS_AVAILABLE_MAC(10.14); -+ (void)minimizeSystemModalFunctionBar:(NSTouchBar *)touchBar; ++ (void)dismissSystemModalTouchBar:(NSTouchBar *)touchBar NS_AVAILABLE_MAC(10.14); + ++ (void)minimizeSystemModalTouchBar:(NSTouchBar *)touchBar NS_AVAILABLE_MAC(10.14); + +// MARK: macOS 10.13 and below + ++ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier NS_DEPRECATED_MAC(10.12.2, 10.14); + ++ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier NS_DEPRECATED_MAC(10.12.2, 10.14); + ++ (void)dismissSystemModalFunctionBar:(NSTouchBar *)touchBar NS_DEPRECATED_MAC(10.12.2, 10.14); + ++ (void)minimizeSystemModalFunctionBar:(NSTouchBar *)touchBar NS_DEPRECATED_MAC(10.12.2, 10.14); @end diff --git a/LyricsX/Controller/TouchBarLyrics.swift b/LyricsX/Controller/TouchBarLyrics.swift index b4e681f5..6799cdb8 100644 --- a/LyricsX/Controller/TouchBarLyrics.swift +++ b/LyricsX/Controller/TouchBarLyrics.swift @@ -52,7 +52,11 @@ class TouchBarLyrics: NSObject, NSTouchBarDelegate { } @objc private func presentTouchBar() { - NSTouchBar.presentSystemModalFunctionBar(touchBar, systemTrayItemIdentifier: .systemTrayItem) + if #available(OSX 10.14, *) { + NSTouchBar.presentSystemModalTouchBar(touchBar, systemTrayItemIdentifier: .systemTrayItem) + } else { + NSTouchBar.presentSystemModalFunctionBar(touchBar, systemTrayItemIdentifier: .systemTrayItem) + } } @objc private func handleLyricsDisplay() { diff --git a/LyricsX/Supporting Files/Info.plist b/LyricsX/Supporting Files/Info.plist index 6d17bde8..8ac51bf3 100644 --- a/LyricsX/Supporting Files/Info.plist +++ b/LyricsX/Supporting Files/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.4.1 CFBundleVersion - 1918 + 1920 Fabric APIKey diff --git a/LyricsX/Utility/CFExtension.swift b/LyricsX/Utility/CFExtension.swift index 8aa2f04e..37375eb2 100644 --- a/LyricsX/Utility/CFExtension.swift +++ b/LyricsX/Utility/CFExtension.swift @@ -91,6 +91,46 @@ extension CFStringTokenizer { // swiftlint:disable:next force_cast return arr as! [CFStringTokenizerTokenType] } + + func currentFuriganaAnnotation(in string: NSString) -> (NSString, NSRange)? { + let range = currentTokenRange() + let tokenStr = string.substring(with: range) as NSString + guard let latin = currentTokenAttribute(.latinTranscription), + let katakana = latin.applyingTransform(.latinToKatakana, reverse: false) as NSString?, + let hiragana = latin.applyingTransform(.latinToHiragana, reverse: false) as NSString?, + katakana.length > 0, + katakana != tokenStr, + hiragana != tokenStr else { + return nil + } + let prefixLength = tokenStr.commonPrefixLength(with: hiragana) + let suffixLength = tokenStr.commonSuffixLength(with: hiragana) + let trimmedRange = NSRange(location: prefixLength, + length: hiragana.length - prefixLength - suffixLength) + let trimmedString = hiragana.substring(with: trimmedRange) as NSString + let rangeToAnnotate = NSRange(location: range.location + prefixLength, + length: range.length - prefixLength - suffixLength) + return (trimmedString, rangeToAnnotate) + } +} + +private extension NSString { + + func commonPrefixLength(with string: NSString) -> Int { + var i = 0 + while i < length, i < string.length, character(at: i) == string.character(at: i) { + i += 1 + } + return i + } + + func commonSuffixLength(with string: NSString) -> Int { + var i = 0 + while i < length, i < string.length, character(at: length - 1 - i) == string.character(at: string.length - 1 - i) { + i += 1 + } + return i + } } extension CFStringTokenizer: IteratorProtocol, Sequence { diff --git a/LyricsX/View/KaraokeLabel.swift b/LyricsX/View/KaraokeLabel.swift index c021cc7d..e8a1e760 100644 --- a/LyricsX/View/KaraokeLabel.swift +++ b/LyricsX/View/KaraokeLabel.swift @@ -78,26 +78,19 @@ class KaraokeLabel: NSTextField { let shouldDrawFurigana = drawFurigana && string.dominantLanguage == "ja" let tokenizer = CFStringTokenizer.create(string) for tokenType in tokenizer where tokenType.contains(.isCJWordMask) { - let range = tokenizer.currentTokenRange() if isVertical { + let tokenRange = tokenizer.currentTokenRange() let attr: [NSAttributedStringKey: Any] = [ .verticalGlyphForm: true, .baselineOffset: (font?.pointSize ?? 24) * 0.25, ] - attrString.addAttributes(attr, range: range) + attrString.addAttributes(attr, range: tokenRange) } - guard shouldDrawFurigana else { continue } - let tokenStr = string.substring(with: range) as NSString - if let latin = tokenizer.currentTokenAttribute(.latinTranscription), - let katakana = latin.applyingTransform(.latinToKatakana, reverse: false) as NSString?, - let hiragana = latin.applyingTransform(.latinToHiragana, reverse: false) as NSString?, - katakana.length > 0, - katakana != tokenStr, - hiragana != tokenStr { + if let (furigana, range) = tokenizer.currentFuriganaAnnotation(in: string) { var attr: [NSAttributedStringKey: Any] = [.rubyAnnotationSizeFactor: 0.5] attr[.foregroundColor] = textColor // Set ruby text color but it seems doesn't work. - let annotation = CTRubyAnnotation.create(hiragana, attributes: attr) + let annotation = CTRubyAnnotation.create(furigana, attributes: attr) attrString.addAttribute(.rubyAnnotation, value: annotation, range: range) } } diff --git a/README.md b/README.md index 409e18e4..e0e0862e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ LyricsX is a plugin for iTunes, Spotify and Vox, which auto search and download LyricsX for iOS is in beta stage. -Fill in [this form](https://goo.gl/forms/yblfWFbsDZDkYqU53) for TestFlight invitation, and join the [Telegram group](https://telegram.me/LyricsXTestFlight). +[Install via TestFlight](https://testflight.apple.com/join/pjjhQLZJ), and join the [Telegram group](https://telegram.me/LyricsXTestFlight). ## Installation