mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-02 16:23:20 +01:00
164 lines
5.3 KiB
TypeScript
164 lines
5.3 KiB
TypeScript
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import { TextAttachmentStyleType } from '../types/Attachment.std.ts';
|
|
import type { LocalizerType } from '../types/Util.std.ts';
|
|
import { strictAssert } from './assert.std.ts';
|
|
|
|
const TextStyle = TextAttachmentStyleType;
|
|
|
|
const FONT_MAP = {
|
|
base: {
|
|
[TextStyle.DEFAULT]: 'sans-serif',
|
|
[TextStyle.REGULAR]: 'sans-serif',
|
|
[TextStyle.BOLD]: 'sans-serif',
|
|
[TextStyle.SERIF]: 'serif',
|
|
[TextStyle.SCRIPT]: 'serif',
|
|
[TextStyle.CONDENSED]: 'sans-serif',
|
|
},
|
|
latin: {
|
|
[TextStyle.DEFAULT]: 'Inter',
|
|
[TextStyle.REGULAR]: 'Inter',
|
|
[TextStyle.BOLD]: 'Inter',
|
|
[TextStyle.SERIF]: '"EB Garamond"',
|
|
[TextStyle.SCRIPT]: 'Parisienne',
|
|
[TextStyle.CONDENSED]: '"Barlow Condensed"',
|
|
},
|
|
cyrillic: {
|
|
[TextStyle.DEFAULT]: 'Inter',
|
|
[TextStyle.REGULAR]: 'Inter',
|
|
[TextStyle.BOLD]: 'Inter',
|
|
[TextStyle.SERIF]: '"EB Garamond"',
|
|
[TextStyle.SCRIPT]: '"American Typewriter Semibold", "Cambria Bold"',
|
|
[TextStyle.CONDENSED]: '"SF Pro Light (System Light)", "Calibri Light"',
|
|
},
|
|
devanagari: {
|
|
[TextStyle.DEFAULT]: '"Kohinoor Devanagari Regular", "Utsaah Regular"',
|
|
[TextStyle.REGULAR]: '"Kohinoor Devanagari Regular", "Utsaah Regular"',
|
|
[TextStyle.BOLD]: '"Kohinoor Devanagari Semibold", "Utsaah Bold"',
|
|
[TextStyle.SERIF]: '"Devanagari Sangam MN Regular", "Kokila Regular"',
|
|
[TextStyle.SCRIPT]: '"Devanagari Sangam MN Bold", "Kokila Bold"',
|
|
[TextStyle.CONDENSED]: '"Kohinoor Devanagari Light", "Utsaah Regular"',
|
|
},
|
|
arabic: {
|
|
[TextStyle.DEFAULT]: '"SF Arabic Regular", "Segoe UI Arabic Regular"',
|
|
[TextStyle.REGULAR]: '"SF Arabic Regular", "Segoe UI Arabic Regular"',
|
|
[TextStyle.BOLD]: '"SF Arabic Bold", "Segoe UI Arabic Bold"',
|
|
[TextStyle.SERIF]: '"Geeza Pro Regular", "Sakkal Majalla Regular"',
|
|
[TextStyle.SCRIPT]: '"Geeza Pro Bold", "Sakkal Majalla Bold"',
|
|
[TextStyle.CONDENSED]: '"SF Arabic Black", "Segoe UI Arabic Bold"',
|
|
},
|
|
japanese: {
|
|
[TextStyle.DEFAULT]: '"Hiragino Sans W3"',
|
|
[TextStyle.REGULAR]: '"Hiragino Sans W3"',
|
|
[TextStyle.BOLD]: '"Hiragino Sans W7"',
|
|
[TextStyle.SERIF]: '"Hiragino Mincho Pro W3"',
|
|
[TextStyle.SCRIPT]: '"Hiragino Mincho Pro W6"',
|
|
[TextStyle.CONDENSED]: '"Hiragino Maru Gothic Pro N"',
|
|
},
|
|
zhhk: {
|
|
[TextStyle.DEFAULT]: '"PingFang HK Regular", "MingLiU Regular"',
|
|
[TextStyle.REGULAR]: '"PingFang HK Regular", "MingLiU Regular"',
|
|
[TextStyle.BOLD]: '"PingFang HK Semibold", "MingLiU Regular"',
|
|
[TextStyle.SERIF]: '"PingFang HK Ultralight", "MingLiU Regular"',
|
|
[TextStyle.SCRIPT]: '"PingFang HK Thin", "MingLiU Regular"',
|
|
[TextStyle.CONDENSED]: '"PingFang HK Light", "MingLiU Regular"',
|
|
},
|
|
zhtc: {
|
|
[TextStyle.DEFAULT]: '"PingFang TC Regular", "JhengHei TC Regular"',
|
|
[TextStyle.REGULAR]: '"PingFang TC Regular", "JhengHei TC Regular"',
|
|
[TextStyle.BOLD]: '"PingFang TC Semibold", "JhengHei TC Bold"',
|
|
[TextStyle.SERIF]: '"PingFang TC Ultralight", "JhengHei TC Light"',
|
|
[TextStyle.SCRIPT]: '"PingFang TC Thin", "JhengHei TC Regular"',
|
|
[TextStyle.CONDENSED]: '"PingFang TC Light", "JhengHei TC Bold"',
|
|
},
|
|
zhsc: {
|
|
[TextStyle.DEFAULT]: '"PingFang SC Regular", SimHei',
|
|
[TextStyle.REGULAR]: '"PingFang SC Regular", SimHei',
|
|
[TextStyle.BOLD]: '"PingFang SC Semibold", SimHei',
|
|
[TextStyle.SERIF]: '"PingFang SC Ultralight", SimHei',
|
|
[TextStyle.SCRIPT]: '"PingFang SC Thin", SimHei',
|
|
[TextStyle.CONDENSED]: '"PingFang SC Light", SimHei',
|
|
},
|
|
};
|
|
|
|
const rxArabic = /\p{Script=Arab}/u;
|
|
const rxCJK = /\p{Script=Han}/u;
|
|
const rxCyrillic = /\p{Script=Cyrl}/u;
|
|
const rxDevanagari = /\p{Script=Deva}/u;
|
|
const rxJapanese = /\p{Script=Hira}|\p{Script=Kana}/u;
|
|
const rxLatin = /\p{Script=Latn}/u;
|
|
|
|
export const fontSniffer = {
|
|
hasArabic(text: string): boolean {
|
|
return rxArabic.test(text);
|
|
},
|
|
|
|
hasCJK(text: string): boolean {
|
|
return rxCJK.test(text);
|
|
},
|
|
|
|
hasCyrillic(text: string): boolean {
|
|
return rxCyrillic.test(text);
|
|
},
|
|
|
|
hasDevanagari(text: string): boolean {
|
|
return rxDevanagari.test(text);
|
|
},
|
|
|
|
hasJapanese(text: string): boolean {
|
|
return rxJapanese.test(text);
|
|
},
|
|
|
|
hasLatin(text: string): boolean {
|
|
return rxLatin.test(text);
|
|
},
|
|
};
|
|
|
|
export function getFontNameByTextScript(
|
|
text: string,
|
|
textStyleType: TextAttachmentStyleType,
|
|
i18n?: LocalizerType
|
|
): string {
|
|
strictAssert(
|
|
TextAttachmentStyleType[textStyleType],
|
|
`Invalid textStyleType: ${textStyleType}`
|
|
);
|
|
|
|
const fonts: Array<string> = [FONT_MAP.base[textStyleType]];
|
|
|
|
if (fontSniffer.hasArabic(text)) {
|
|
fonts.push(FONT_MAP.arabic[textStyleType]);
|
|
}
|
|
|
|
if (fontSniffer.hasCJK(text)) {
|
|
const locale = i18n?.getLocale();
|
|
|
|
if (locale === 'zh-TW') {
|
|
fonts.push(FONT_MAP.zhtc[textStyleType]);
|
|
} else if (locale === 'zh-HK') {
|
|
fonts.push(FONT_MAP.zhhk[textStyleType]);
|
|
} else {
|
|
fonts.push(FONT_MAP.zhsc[textStyleType]);
|
|
}
|
|
}
|
|
|
|
if (fontSniffer.hasCyrillic(text)) {
|
|
fonts.push(FONT_MAP.cyrillic[textStyleType]);
|
|
}
|
|
|
|
if (fontSniffer.hasDevanagari(text)) {
|
|
fonts.push(FONT_MAP.devanagari[textStyleType]);
|
|
}
|
|
|
|
if (fontSniffer.hasJapanese(text)) {
|
|
fonts.push(FONT_MAP.japanese[textStyleType]);
|
|
}
|
|
|
|
if (fontSniffer.hasLatin(text)) {
|
|
fonts.push(FONT_MAP.latin[textStyleType]);
|
|
}
|
|
|
|
return fonts.reverse().join(', ');
|
|
}
|