Skip to content

Commit

Permalink
feat: add support for chineseType, fallbackFont, and `declareEngl…
Browse files Browse the repository at this point in the history
…ishFont` options
  • Loading branch information
kirklin committed Aug 30, 2023
1 parent 9dc4eda commit 3a599a9
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 44 deletions.
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { FontType } from "./types";

export const fontType: FontType[] = ["chinese", "helvetica", "italics", "song", "imitation-song", "new-song", "li"];
69 changes: 32 additions & 37 deletions src/defaultChineseFonts.ts → src/core.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
const macosSimplifiedChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC", "Hiragino Sans GB", "Heiti SC"];
const macosTraditionalChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC"];
const windowsSimplifiedChinese = ["Microsoft YaHei"];
const windowsTraditionalChinese = ["Microsoft Jhenghei"];
const linuxSimplifiedChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans"];
const linuxTraditionalChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans"];
import { fontType } from "./constants";
import type { ChineseType, FontType } from "./types";

export const macosSimplifiedChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC", "Hiragino Sans GB", "Heiti SC"];
export const macosTraditionalChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC"];
export const windowsSimplifiedChinese = ["Microsoft YaHei"];
export const windowsTraditionalChinese = ["Microsoft Jhenghei"];
export const linuxSimplifiedChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans"];
export const linuxTraditionalChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans"];

export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation-song" | "new-song" | "li";
/**
* Generates a list of fonts for the specified character type and font type, with optional fallback font.
* 根据指定的字符类型和字体类型生成字体列表,可以选择性地指定回退字体。
*
* @param characterType - The type of characters to consider: "simplified" or "traditional".
* 要考虑的字符类型:"simplified"(简体)或 "traditional"(繁体)。
* @param chineseType - The type of chinese: "simplified" or "traditional".
* 要考虑的汉字类型:"simplified"(简体)或 "traditional"(繁体)。
* @param fontType - The type of font to generate the list for: "chinese", "helvetica", "italics", "song", "imitation-song", "new-song", or "li".
* 要生成列表的字体类型:"chinese"、"helvetica"、"italics"、"song"、"imitation-song"、"new-song" 或 "li"。
* @param fallbackFont - The fallback font to use if the desired font type is not available. Pass `null` for no fallback.
Expand All @@ -23,21 +25,21 @@ export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation
* 基于指定条件的字体名称数组。
*/
export function generateFontList(
characterType: "simplified" | "traditional",
chineseType: ChineseType,
fontType: FontType,
fallbackFont: string | null = "sans-serif",
declareEnglishFont: boolean = true,
fallbackFont: string[] | null = ["sans-serif"],
declareEnglishFont: string[] = ["Arial"],
): string[] {
const fontList: string[] = [];

// Add English font declaration if required
if (declareEnglishFont) {
fontList.push(`Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`);
fontList.push("Arial");
if (declareEnglishFont.length > 0) {
fontList.push(generatePunctuationFontName(fontType));
fontList.push(...declareEnglishFont);
}

// Determine the appropriate font list based on the character type
if (characterType === "simplified") {
if (chineseType === "simplified") {
const chineseFonts = [macosSimplifiedChinese, windowsSimplifiedChinese, linuxSimplifiedChinese].flat();
// Select the font list based on the font type
switch (fontType) {
Expand Down Expand Up @@ -153,47 +155,37 @@ export function generateFontList(

// Add fallback font if specified
if (fallbackFont !== null) {
fontList.push(fallbackFont);
fontList.push(...fallbackFont);
}

return fontList;
}

export const defaultChineseFonts = {

"chinese": generateFontList("simplified", "chinese"),
// 黑体
"helvetica": generateFontList("simplified", "helvetica"),
// 楷体
"italics": generateFontList("simplified", "italics"),
// 宋体
"song": generateFontList("simplified", "song"),
// 仿宋体
"imitation-song": generateFontList("simplified", "imitation-song"),
// 新宋体
"new-song": generateFontList("simplified", "new-song"),
// 隶书
"li": generateFontList("simplified", "li"),
};
export const defaultChineseFonts: Record<FontType, string[]> = fontType.reduce((fonts, type) => {
fonts[type] = generateFontList("simplified", type);
return fonts;
}, {} as Record<FontType, string[]>);

/**
* Generates a CSS @font-face rule for the specified font type.
* 根据指定的字体类型生成 CSS @font-face 规则。
*
* @param fontType - The type of font to generate the @font-face rule for.
* 要生成 @font-face 规则的字体类型。
*
* @param {string[]} filterFontList - The list of fonts to be filtered out from the default font list.
* 要从默认字体列表中过滤掉的字体列表。
* @returns {string} The generated @font-face CSS rule as a string.
* 生成的 @font-face CSS 规则作为字符串。
*/
export function generateFontFaceRule(fontType: FontType): string {
export function generateFontFaceRule(fontType: FontType, filterFontList: string[]): string {
const fontList = defaultChineseFonts[fontType];
if (!fontList) {
throw new Error(`Font type "${fontType}" is not valid.`);
}

const fontName = `Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`;
const filteredFontList = fontList.filter(font => font !== "Arial"); // Filtering out Arial
const fontName = generatePunctuationFontName(fontType);
// Filtering out specified fonts
const filteredFontList = fontList.filter(font => !filterFontList.includes(font));
const fontSrc = filteredFontList.map(font => `local('${font}')`).join(", ");

return `
Expand All @@ -204,3 +196,6 @@ export function generateFontFaceRule(fontType: FontType): string {
}
`;
}
export function generatePunctuationFontName(fontType: FontType): string {
return `Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`;
}
24 changes: 18 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { toArray } from "@unocss/core";
import type { Preset } from "unocss";
import type { FontType } from "./defaultChineseFonts";
import { defaultChineseFonts, generateFontFaceRule } from "./defaultChineseFonts";
import type { ChineseFontsOptions } from "./types";
import { fontType } from "./constants";
import type { ChineseFontsOptions, FontType } from "./types";
import { defaultChineseFonts, generateFontFaceRule, generateFontList } from "./core";

export * from "./types";

const presetChinese = (options: ChineseFontsOptions = {}): Preset => {
// 解构参数并提供默认值
const { extendTheme = true, themeKey = "fontFamily" } = options;
const {
extendTheme = true,
themeKey = "fontFamily",
chineseType = "simplified",
fallbackFont = ["sans-serif"],
declareEnglishFont = ["Arial"],
} = options;

// 合并字体选项
const fonts = { ...defaultChineseFonts, ...options?.fonts };
const fonts = {
...fontType.reduce((fonts, type) => {
fonts[type] = generateFontList(chineseType, type, fallbackFont, declareEnglishFont);
return fonts;
}, {} as Record<FontType, string[]>),
...options?.fonts,
};

// 转换字体选项为字体对象
const fontObject = Object.fromEntries(
Expand Down Expand Up @@ -46,7 +58,7 @@ const presetChinese = (options: ChineseFontsOptions = {}): Preset => {
}

const fontFacePreflights = Object.keys(defaultChineseFonts).map(fontType => ({
getCSS: () => generateFontFaceRule(<FontType>fontType),
getCSS: () => generateFontFaceRule(<FontType>fontType, declareEnglishFont),
}));

preset.preflights = fontFacePreflights;
Expand Down
38 changes: 37 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,56 @@
/**
* Options for configuring Chinese fonts.
* 配置中文字体的选项。
*/
export interface ChineseFontsOptions {
/**
* Extend the theme object
* 扩展主题对象
* @default true
*/
extendTheme?: boolean;

/**
* Key for the theme object
* 主题对象的键
*
* @default 'fontFamily'
*/
themeKey?: string;

/**
* extend fonts
* Extend fonts
* 扩展字体
*/
fonts?: Record<string, string | string[]>;

/**
* The type of Chinese: "simplified" or "traditional".
* 中文的类型: "simplified"(简体)或 "traditional"(繁体)。
*/
chineseType?: ChineseType;

/**
* Fallback font for Chinese characters.
* 备选字体。
*/
fallbackFont?: string[] | null;

/**
* Declare fonts for English text.
* 声明英文文本的字体。
*/
declareEnglishFont?: string[];
}

/**
* Represents different font types that can be used, including various Chinese fonts and styles.
* 表示可用的不同字体类型,包括各种中文字体和样式。
*/
export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation-song" | "new-song" | "li";

/**
* Represents different types of Chinese characters, such as simplified or traditional.
* 表示不同类型的中文字符,例如简体或繁体。
*/
export type ChineseType = "simplified" | "traditional";

0 comments on commit 3a599a9

Please sign in to comment.