160 lines
4.1 KiB
TypeScript
160 lines
4.1 KiB
TypeScript
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import type { LocalizerType } from '../types/Util';
|
|
import { strictAssert } from './assert';
|
|
|
|
const FONT_MAP = {
|
|
base: [
|
|
'sans-serif',
|
|
'sans-serif',
|
|
'sans-serif',
|
|
'serif',
|
|
'serif',
|
|
'sans-serif',
|
|
],
|
|
latin: [
|
|
'Inter',
|
|
'Inter',
|
|
'Inter',
|
|
'"EB Garamond"',
|
|
'Parisienne',
|
|
'"Barlow Condensed"',
|
|
],
|
|
cyrillic: [
|
|
'Inter',
|
|
'Inter',
|
|
'Inter',
|
|
'"EB Garamond"',
|
|
'"American Typewriter Semibold", "Cambria Bold"',
|
|
'"SF Pro Light (System Light)", "Calibri Light"',
|
|
],
|
|
devanagari: [
|
|
'"Kohinoor Devanagari Regular", "Utsaah Regular"',
|
|
'"Kohinoor Devanagari Regular", "Utsaah Regular"',
|
|
'"Kohinoor Devanagari Semibold", "Utsaah Bold"',
|
|
'"Devanagari Sangam MN Regular", "Kokila Regular"',
|
|
'"Devanagari Sangam MN Bold", "Kokila Bold"',
|
|
'"Kohinoor Devanagari Light", "Utsaah Regular"',
|
|
],
|
|
arabic: [
|
|
'"SF Arabic Regular", "Segoe UI Arabic Regular"',
|
|
'"SF Arabic Regular", "Segoe UI Arabic Regular"',
|
|
'"SF Arabic Bold", "Segoe UI Arabic Bold"',
|
|
'"Geeza Pro Regular", "Sakkal Majalla Regular"',
|
|
'"Geeza Pro Bold", "Sakkal Majalla Bold"',
|
|
'"SF Arabic Black", "Segoe UI Arabic Bold"',
|
|
],
|
|
japanese: [
|
|
'"Hiragino Sans W3"',
|
|
'"Hiragino Sans W3"',
|
|
'"Hiragino Sans W7"',
|
|
'"Hiragino Mincho Pro W3"',
|
|
'"Hiragino Mincho Pro W6"',
|
|
'"Hiragino Maru Gothic Pro N"',
|
|
],
|
|
zhhk: [
|
|
'"PingFang HK Regular", "MingLiU Regular"',
|
|
'"PingFang HK Regular", "MingLiU Regular"',
|
|
'"PingFang HK Semibold", "MingLiU Regular"',
|
|
'"PingFang HK Ultralight", "MingLiU Regular"',
|
|
'"PingFang HK Thin", "MingLiU Regular"',
|
|
'"PingFang HK Light", "MingLiU Regular"',
|
|
],
|
|
zhtc: [
|
|
'"PingFang TC Regular", "JhengHei TC Regular"',
|
|
'"PingFang TC Regular", "JhengHei TC Regular"',
|
|
'"PingFang TC Semibold", "JhengHei TC Bold"',
|
|
'"PingFang TC Ultralight", "JhengHei TC Light"',
|
|
'"PingFang TC Thin", "JhengHei TC Regular"',
|
|
'"PingFang TC Light", "JhengHei TC Bold"',
|
|
],
|
|
zhsc: [
|
|
'"PingFang SC Regular", SimHei',
|
|
'"PingFang SC Regular", SimHei',
|
|
'"PingFang SC Semibold", SimHei',
|
|
'"PingFang SC Ultralight", SimHei',
|
|
'"PingFang SC Thin", SimHei',
|
|
'"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,
|
|
textStyleIndex: number,
|
|
i18n?: LocalizerType
|
|
): string {
|
|
strictAssert(
|
|
textStyleIndex >= 0 && textStyleIndex <= 5,
|
|
'text style is not between 0-5'
|
|
);
|
|
|
|
const fonts: Array<string> = [FONT_MAP.base[textStyleIndex]];
|
|
|
|
if (fontSniffer.hasArabic(text)) {
|
|
fonts.push(FONT_MAP.arabic[textStyleIndex]);
|
|
}
|
|
|
|
if (fontSniffer.hasCJK(text)) {
|
|
const locale = i18n?.getLocale();
|
|
|
|
if (locale === 'zh-TW') {
|
|
fonts.push(FONT_MAP.zhtc[textStyleIndex]);
|
|
} else if (locale === 'zh-HK') {
|
|
fonts.push(FONT_MAP.zhhk[textStyleIndex]);
|
|
} else {
|
|
fonts.push(FONT_MAP.zhsc[textStyleIndex]);
|
|
}
|
|
}
|
|
|
|
if (fontSniffer.hasCyrillic(text)) {
|
|
fonts.push(FONT_MAP.cyrillic[textStyleIndex]);
|
|
}
|
|
|
|
if (fontSniffer.hasDevanagari(text)) {
|
|
fonts.push(FONT_MAP.devanagari[textStyleIndex]);
|
|
}
|
|
|
|
if (fontSniffer.hasJapanese(text)) {
|
|
fonts.push(FONT_MAP.japanese[textStyleIndex]);
|
|
}
|
|
|
|
if (fontSniffer.hasLatin(text)) {
|
|
fonts.push(FONT_MAP.latin[textStyleIndex]);
|
|
}
|
|
|
|
return fonts.reverse().join(', ');
|
|
}
|