@nebutra/fonts 0.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/NOTICE-FONTS.md +27 -0
- package/README.md +61 -115
- package/dist/chunk-FUPJK5RT.js +20 -0
- package/dist/chunk-FUPJK5RT.js.map +1 -0
- package/dist/chunk-JHYTIKKY.js +38 -0
- package/dist/chunk-JHYTIKKY.js.map +1 -0
- package/dist/generated/index.d.ts +19 -25
- package/dist/generated/index.js +12 -16
- package/dist/generated/index.js.map +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/next-cjk.d.ts +40 -45
- package/dist/next-cjk.js +10 -3
- package/dist/next.d.ts +3 -2
- package/dist/next.js +32 -6
- package/dist/next.js.map +1 -1
- package/generated/index.ts +28 -0
- package/generated/subset-manifest.json +20 -20
- package/package.json +27 -13
- package/src/cjk-font-face.tsx +53 -0
- package/src/index.test.ts +39 -0
- package/src/index.ts +105 -0
- package/src/next-cjk.test.ts +56 -0
- package/src/next-cjk.ts +54 -0
- package/src/next.ts +148 -0
- package/vendor/dm-sans/OFL.txt +93 -0
- package/vendor/misans/LICENSE.txt +13 -0
- package/dist/chunk-MI5GQA6D.js +0 -27
- package/dist/chunk-MI5GQA6D.js.map +0 -1
- package/generated/vivo-sans-cn.css +0 -55
- package/generated/vivo-sans-sc-400.woff2 +0 -0
- package/generated/vivo-sans-sc-500.woff2 +0 -0
- package/generated/vivo-sans-sc-600.woff2 +0 -0
- package/generated/vivo-sans-sc-700.woff2 +0 -0
- package/vendor/vivo-sans/LICENCE-vivo-Sans.txt +0 -37
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { MISANS_FILES, MISANS_UNICODE_RANGE } from "../generated/index";
|
|
5
|
+
import { misansFontFaceCss } from "./cjk-font-face";
|
|
6
|
+
import { FONT_REGISTRY } from "./index";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* MiSans is CDN-hosted (its licence forbids distributing the font on its own,
|
|
10
|
+
* and this repo is public). Only content-hashed keys are committed; the host is
|
|
11
|
+
* resolved per deployment by publicAssetUrl(). DM Sans is self-hosted through
|
|
12
|
+
* next/font/local in ./next-cjk.ts, a compile-time transform — read as TEXT.
|
|
13
|
+
*/
|
|
14
|
+
const read = (rel: string) => readFileSync(fileURLToPath(new URL(rel, import.meta.url)), "utf8");
|
|
15
|
+
const NEXT_CJK_SOURCE = read("./next-cjk.ts");
|
|
16
|
+
const GENERATED_INDEX = read("../generated/index.ts");
|
|
17
|
+
|
|
18
|
+
describe("MiSans wiring", () => {
|
|
19
|
+
it("commits keys, never a host", () => {
|
|
20
|
+
for (const { key } of MISANS_FILES) {
|
|
21
|
+
expect(key).toMatch(/^fonts\/misans\/misans-\d{3}\.[0-9a-f]{10}\.woff2$/);
|
|
22
|
+
}
|
|
23
|
+
expect(GENERATED_INDEX).not.toMatch(/https?:\/\//);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("declares one @font-face per weight against the given origin", () => {
|
|
27
|
+
const css = misansFontFaceCss("https://assets.example.test/");
|
|
28
|
+
for (const { key, weight } of MISANS_FILES) {
|
|
29
|
+
expect(css).toContain(`font-weight:${weight};`);
|
|
30
|
+
expect(css).toContain(`src:url("https://assets.example.test/${key}") format("woff2")`);
|
|
31
|
+
}
|
|
32
|
+
expect(css.match(/@font-face/g)).toHaveLength(MISANS_FILES.length);
|
|
33
|
+
expect(css).toContain("font-display:swap");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("carries a CJK-only unicode-range, so Latin never downloads a CJK file", () => {
|
|
37
|
+
expect(misansFontFaceCss("https://a.test")).toContain(`unicode-range:${MISANS_UNICODE_RANGE}`);
|
|
38
|
+
expect(MISANS_UNICODE_RANGE).not.toMatch(/U\+00[0-7]/i);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("never loads a MiSans binary through next/font", () => {
|
|
42
|
+
expect(NEXT_CJK_SOURCE).not.toMatch(/misans-\d{3}\.woff2/);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("registers the variable the token stacks reference", () => {
|
|
46
|
+
expect(FONT_REGISTRY.misans).toBe("--font-misans");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("DM Sans wiring", () => {
|
|
51
|
+
it("self-hosts the variable Latin subset under the heading variable", () => {
|
|
52
|
+
expect(NEXT_CJK_SOURCE).toContain('path: "../generated/dm-sans.woff2"');
|
|
53
|
+
expect(NEXT_CJK_SOURCE).toContain('variable: "--font-dm-sans"');
|
|
54
|
+
expect(FONT_REGISTRY["dm sans display"]).toBe("--font-dm-sans");
|
|
55
|
+
});
|
|
56
|
+
});
|
package/src/next-cjk.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nebutra/fonts/next/cjk — the self-hosted brand faces (server-only).
|
|
3
|
+
*
|
|
4
|
+
* The Latin brand face lives here through `next/font/local` so first-party apps work
|
|
5
|
+
* offline, in CI and in the network sandbox (`next/font/google` fails there):
|
|
6
|
+
*
|
|
7
|
+
* - MiSans — the Simplified-Chinese face — is CDN-hosted; see <CjkFontFace /> below.
|
|
8
|
+
* - DM Sans — the Latin display/heading face (SIL OFL). Chosen the same day
|
|
9
|
+
* from the same measurement (DeepSeek, Databricks). Body/UI Latin stays
|
|
10
|
+
* Geist: its tabular figures are what dense dashboard tables need.
|
|
11
|
+
*
|
|
12
|
+
* WHY A SEPARATE ENTRY FROM `./next`: that module declares ~16
|
|
13
|
+
* `next/font/google` faces for the theme / DESIGN.md registry; importing it for
|
|
14
|
+
* the brand faces would drag those build-time downloads into every app. `./next`
|
|
15
|
+
* re-exports this file, so an app already applying `fontRegistryClassName`
|
|
16
|
+
* still needs one import.
|
|
17
|
+
*
|
|
18
|
+
* next/font is a compile-time transform: SWC statically analyses the call, so
|
|
19
|
+
* the options object is spelled out as a literal.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import localFont from "next/font/local";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* MiSans is NOT loaded here: its licence forbids distributing the font on its
|
|
26
|
+
* own and this repository is public (vivo Sans was removed for the same reason,
|
|
27
|
+
* b5e73db35). The subsets are served from the deployment's asset CDN and
|
|
28
|
+
* declared by <CjkFontFace />, re-exported below — render it in the root
|
|
29
|
+
* layout next to this class name. The token stacks reference
|
|
30
|
+
* var(--font-misans, "MiSans"): with no variable set, the literal family name
|
|
31
|
+
* resolves to that @font-face.
|
|
32
|
+
*/
|
|
33
|
+
export { CjkFontFace, misansFontFaceCss } from "./cjk-font-face";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* DM Sans — one variable file (opsz 9–40, wght 100–1000), Latin subset, 67KB.
|
|
37
|
+
* Preloaded: headings render above the fold on most pages.
|
|
38
|
+
*/
|
|
39
|
+
export const dmSans = localFont({
|
|
40
|
+
src: [{ path: "../generated/dm-sans.woff2", weight: "100 1000", style: "normal" }],
|
|
41
|
+
display: "swap",
|
|
42
|
+
variable: "--font-dm-sans",
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Apply to <html> next to the Geist loaders so `--font-dm-sans` exists:
|
|
47
|
+
*
|
|
48
|
+
* className={`${GeistSans.variable} ${GeistMono.variable} ${cjkFontClassName}`}
|
|
49
|
+
*
|
|
50
|
+
* The name predates DM Sans; it now carries both brand faces so every app that
|
|
51
|
+
* already applies it picks them up without a layout change.
|
|
52
|
+
*/
|
|
53
|
+
export const brandFontClassName = dmSans.variable;
|
|
54
|
+
export const cjkFontClassName = brandFontClassName;
|
package/src/next.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nebutra/fonts/next — build-time self-hosted OSS font faces (server-only).
|
|
3
|
+
*
|
|
4
|
+
* Each face is loaded via next/font/google, which downloads the font AT BUILD
|
|
5
|
+
* TIME and self-hosts it from the app's own origin — there are ZERO runtime
|
|
6
|
+
* requests to Google (no IP leak / GDPR concern, no third-party runtime
|
|
7
|
+
* dependency). Each face exposes a CSS variable; the browser only fetches a
|
|
8
|
+
* given font file when an element actually uses that variable, so declaring the
|
|
9
|
+
* whole registry is cheap.
|
|
10
|
+
*
|
|
11
|
+
* Apply `fontRegistryClassName` to <html> so the `--font-*` variables exist;
|
|
12
|
+
* the appearance layer then prepends the matching `var(--font-*)` (see the
|
|
13
|
+
* client-safe map in `@nebutra/fonts`) when a theme / DESIGN.md font matches.
|
|
14
|
+
*
|
|
15
|
+
* All declarations use a literal options object — next/font statically analyses
|
|
16
|
+
* the call, so the config must NOT be computed. Variable fonts omit `weight`.
|
|
17
|
+
* Keep the `variable` names in sync with FONT_REGISTRY in `../index.ts`.
|
|
18
|
+
*
|
|
19
|
+
* The brand faces live in `./next-cjk` — DM Sans (next/font/local, no Google
|
|
20
|
+
* fetch) and <CjkFontFace /> for the CDN-hosted MiSans — and are re-exported
|
|
21
|
+
* here for discoverability. They are NOT folded into `fontRegistryClassName`:
|
|
22
|
+
* they are core typography, not optional theme faces, and every app wires them
|
|
23
|
+
* the same way — `${cjkFontClassName}` on <html> beside the Geist loaders and
|
|
24
|
+
* <CjkFontFace /> in the root layout. Apps that only need them should import
|
|
25
|
+
* `@nebutra/fonts/next/cjk` directly so they don't pull in the Google faces below.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
DM_Sans,
|
|
30
|
+
Figtree,
|
|
31
|
+
Fira_Code,
|
|
32
|
+
Fraunces,
|
|
33
|
+
Inter,
|
|
34
|
+
Inter_Tight,
|
|
35
|
+
JetBrains_Mono,
|
|
36
|
+
Lexend,
|
|
37
|
+
Manrope,
|
|
38
|
+
Montserrat,
|
|
39
|
+
Outfit,
|
|
40
|
+
Playfair_Display,
|
|
41
|
+
Plus_Jakarta_Sans,
|
|
42
|
+
Roboto_Mono,
|
|
43
|
+
Sora,
|
|
44
|
+
Source_Code_Pro,
|
|
45
|
+
Source_Serif_4,
|
|
46
|
+
Space_Grotesk,
|
|
47
|
+
Work_Sans,
|
|
48
|
+
} from "next/font/google";
|
|
49
|
+
|
|
50
|
+
export { brandFontClassName, CjkFontFace, cjkFontClassName, dmSans } from "./next-cjk";
|
|
51
|
+
|
|
52
|
+
const inter = Inter({ subsets: ["latin"], display: "swap", variable: "--font-inter" });
|
|
53
|
+
const interTight = Inter_Tight({
|
|
54
|
+
subsets: ["latin"],
|
|
55
|
+
display: "swap",
|
|
56
|
+
variable: "--font-reg-inter-tight",
|
|
57
|
+
});
|
|
58
|
+
const spaceGrotesk = Space_Grotesk({
|
|
59
|
+
subsets: ["latin"],
|
|
60
|
+
display: "swap",
|
|
61
|
+
variable: "--font-space-grotesk",
|
|
62
|
+
});
|
|
63
|
+
const playfairDisplay = Playfair_Display({
|
|
64
|
+
subsets: ["latin"],
|
|
65
|
+
display: "swap",
|
|
66
|
+
variable: "--font-playfair-display",
|
|
67
|
+
});
|
|
68
|
+
const fraunces = Fraunces({
|
|
69
|
+
subsets: ["latin"],
|
|
70
|
+
display: "swap",
|
|
71
|
+
variable: "--font-reg-fraunces",
|
|
72
|
+
});
|
|
73
|
+
const jetbrainsMono = JetBrains_Mono({
|
|
74
|
+
subsets: ["latin"],
|
|
75
|
+
display: "swap",
|
|
76
|
+
variable: "--font-jetbrains-mono",
|
|
77
|
+
});
|
|
78
|
+
const manrope = Manrope({ subsets: ["latin"], display: "swap", variable: "--font-reg-manrope" });
|
|
79
|
+
const sora = Sora({ subsets: ["latin"], display: "swap", variable: "--font-reg-sora" });
|
|
80
|
+
const workSans = Work_Sans({
|
|
81
|
+
subsets: ["latin"],
|
|
82
|
+
display: "swap",
|
|
83
|
+
variable: "--font-reg-work-sans",
|
|
84
|
+
});
|
|
85
|
+
const dmSans = DM_Sans({ subsets: ["latin"], display: "swap", variable: "--font-reg-dm-sans" });
|
|
86
|
+
const plusJakartaSans = Plus_Jakarta_Sans({
|
|
87
|
+
subsets: ["latin"],
|
|
88
|
+
display: "swap",
|
|
89
|
+
variable: "--font-reg-plus-jakarta-sans",
|
|
90
|
+
});
|
|
91
|
+
const outfit = Outfit({ subsets: ["latin"], display: "swap", variable: "--font-reg-outfit" });
|
|
92
|
+
const figtree = Figtree({ subsets: ["latin"], display: "swap", variable: "--font-reg-figtree" });
|
|
93
|
+
const montserrat = Montserrat({
|
|
94
|
+
subsets: ["latin"],
|
|
95
|
+
display: "swap",
|
|
96
|
+
variable: "--font-reg-montserrat",
|
|
97
|
+
});
|
|
98
|
+
const lexend = Lexend({ subsets: ["latin"], display: "swap", variable: "--font-reg-lexend" });
|
|
99
|
+
const firaCode = Fira_Code({
|
|
100
|
+
subsets: ["latin"],
|
|
101
|
+
display: "swap",
|
|
102
|
+
variable: "--font-reg-fira-code",
|
|
103
|
+
});
|
|
104
|
+
const robotoMono = Roboto_Mono({
|
|
105
|
+
subsets: ["latin"],
|
|
106
|
+
display: "swap",
|
|
107
|
+
variable: "--font-reg-roboto-mono",
|
|
108
|
+
});
|
|
109
|
+
const sourceSerif4 = Source_Serif_4({
|
|
110
|
+
subsets: ["latin"],
|
|
111
|
+
display: "swap",
|
|
112
|
+
variable: "--font-reg-source-serif-4",
|
|
113
|
+
});
|
|
114
|
+
const sourceCodePro = Source_Code_Pro({
|
|
115
|
+
subsets: ["latin"],
|
|
116
|
+
display: "swap",
|
|
117
|
+
variable: "--font-reg-source-code-pro",
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
/** All registry faces, in declaration order. */
|
|
121
|
+
export const FONT_REGISTRY_FACES = [
|
|
122
|
+
inter,
|
|
123
|
+
interTight,
|
|
124
|
+
spaceGrotesk,
|
|
125
|
+
playfairDisplay,
|
|
126
|
+
sourceSerif4,
|
|
127
|
+
fraunces,
|
|
128
|
+
jetbrainsMono,
|
|
129
|
+
manrope,
|
|
130
|
+
sora,
|
|
131
|
+
workSans,
|
|
132
|
+
dmSans,
|
|
133
|
+
plusJakartaSans,
|
|
134
|
+
outfit,
|
|
135
|
+
figtree,
|
|
136
|
+
montserrat,
|
|
137
|
+
lexend,
|
|
138
|
+
firaCode,
|
|
139
|
+
robotoMono,
|
|
140
|
+
sourceCodePro,
|
|
141
|
+
] as const;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Space-joined `.variable` classNames for every registry face. Apply to <html>
|
|
145
|
+
* so all `--font-*` registry variables are defined (font files lazy-load on
|
|
146
|
+
* first use). Combine with the app's own Geist faces.
|
|
147
|
+
*/
|
|
148
|
+
export const fontRegistryClassName = FONT_REGISTRY_FACES.map((face) => face.variable).join(" ");
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2014 The DM Sans Project Authors (https://github.com/googlefonts/dm-fonts)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
MiSans 字体知识产权许可协议 (MiSans Font IP License Agreement)
|
|
2
|
+
Source: https://hyperos.mi.com/font/zh/download/ — retrieved 2026-09-25
|
|
3
|
+
|
|
4
|
+
本《MiSans 字体知识产权许可协议》(以下简称“协议”)是您与小米科技有限责任公司(以下简称“小米”或“许可方”)之间有关安装、使用 MiSans 字体(以下简称“MiSans”或“MiSans 字体”)的法律协议。您在使用 MiSans 的所有或任何部分前,应接受本协议中规定的所有条款和条件。安装、使用 MiSans 的行为表示您同意接受本协议所有条款的约束。否则,请不要安装或使用 MiSans,并应立即销毁和删除所有 MiSans 字体包。
|
|
5
|
+
根据本协议的条款和条件,许可方在此授予您一份不可转让的、非独占的、免版税的、可撤销的、全球性的版权许可,使您依照本协议约定使用 MiSans 字体,前提是符合下列条件:
|
|
6
|
+
您应在软件中特别注明使用了 MiSans 字体。
|
|
7
|
+
您不得对 MiSans 字体或其任何单独组件进行改编或二次开发。
|
|
8
|
+
您不得单独将 MiSans 字体或其组件对外租赁、再许可、给予、出借或进一步分发字体软件或其任何副本以及重新分发或售卖。此限制不适用于您使用 MiSans 字体创作的任何其他作品。如您使用 MiSans 字体创作宣传素材、logo、应用 App 等,您有权分发或出售该作品。
|
|
9
|
+
|
|
10
|
+
FAQ (https://hyperos.mi.com/font/zh/faq/):
|
|
11
|
+
- 是否需要付费?不需要。MiSans Global 所有的字体都是供全球免费商用。
|
|
12
|
+
- 是否可以用作嵌入式字体?可以。但您应在软件中特别注明使用了 MiSans 字体。
|
|
13
|
+
- 我可以在软件中修改编辑、二次创作字体吗?您可以自由调节字体的粗细、间距等。但您不得单独将 MiSans 字体或其组件进行外观上的更改。
|
package/dist/chunk-MI5GQA6D.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// src/next-cjk.ts
|
|
2
|
-
import localFont from "next/font/local";
|
|
3
|
-
var vivoSansCn = localFont({
|
|
4
|
-
src: [
|
|
5
|
-
{ path: "../generated/vivo-sans-sc-400.woff2", weight: "400", style: "normal" },
|
|
6
|
-
{ path: "../generated/vivo-sans-sc-500.woff2", weight: "500", style: "normal" },
|
|
7
|
-
{ path: "../generated/vivo-sans-sc-600.woff2", weight: "600", style: "normal" },
|
|
8
|
-
{ path: "../generated/vivo-sans-sc-700.woff2", weight: "700", style: "normal" }
|
|
9
|
-
],
|
|
10
|
-
declarations: [
|
|
11
|
-
{
|
|
12
|
-
prop: "unicode-range",
|
|
13
|
-
value: "U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF"
|
|
14
|
-
}
|
|
15
|
-
],
|
|
16
|
-
display: "swap",
|
|
17
|
-
preload: false,
|
|
18
|
-
adjustFontFallback: false,
|
|
19
|
-
variable: "--font-vivo-sans-sc"
|
|
20
|
-
});
|
|
21
|
-
var cjkFontClassName = vivoSansCn.variable;
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
vivoSansCn,
|
|
25
|
-
cjkFontClassName
|
|
26
|
-
};
|
|
27
|
-
//# sourceMappingURL=chunk-MI5GQA6D.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/next-cjk.ts"],"sourcesContent":["/**\n * @nebutra/fonts/next/cjk — the self-hosted Simplified-Chinese face (server-only).\n *\n * WHY A SEPARATE ENTRY FROM `./next`: that module declares ~16 `next/font/google`\n * faces for the theme / DESIGN.md registry. Importing it just to get the CJK face\n * would drag those build-time Google downloads into every app — and this repo has\n * a known trap where `next/font/google` fails outright in a network-sandboxed dev\n * server. This file imports `next/font/local` ONLY: the woff2 files ship in the\n * package, so it works offline, in CI, and in the sandbox. `./next` re-exports it,\n * so an app already applying `fontRegistryClassName` still only needs one import.\n *\n * WHY SELF-HOSTED AT ALL: Geist has no CJK coverage, so without this every Chinese\n * character falls back to whatever the OS supplies — PingFang on macOS, Microsoft\n * YaHei on Windows, something else on Android. Chinese copy is a first-class\n * surface here (see docs/microcopy/), so the face is pinned rather than left to\n * the OS.\n *\n * The files are built by `pnpm --filter @nebutra/fonts subset:cjk`; the literal\n * `src` list below mirrors VIVO_SANS_CN_SOURCES in ../generated/index.ts (a drift\n * test in ./next-cjk.test.ts asserts they agree). It is spelled out rather than\n * spread because next/font is a compile-time transform — SWC statically analyses\n * this call, so the options object cannot be computed.\n *\n * FONT ATTRIBUTION (vivo Sans 字体知识产权许可协议 clause 2.1):\n * 您应在软件中特别注明使用了vivo Sans 字体 — this software uses the vivo Sans\n * typeface. See ../vendor/vivo-sans/LICENCE-vivo-Sans.txt and the package README.\n */\n\nimport localFont from \"next/font/local\";\n\n/**\n * vivo Sans SC — 400 / 500 / 600 / 700 static subsets.\n *\n * - `preload: false` on purpose. Each weight is ~490 KB; preloading them on every\n * route would tax Latin-only pages for nothing. The browser fetches a weight\n * only when a glyph in the `unicode-range` below actually renders.\n * - `declarations` carries that `unicode-range` (CJK blocks only — no ASCII, no\n * Latin, no general punctuation), so a Latin-only page can never trigger a CJK\n * download even if a font stack somewhere is written the wrong way round. Curly\n * quotes, the em dash and the ellipsis are deliberately left to Geist: they are\n * the codepoints Latin and Chinese copy share.\n * - `adjustFontFallback: false` — next/font's metric-matched fallback is derived\n * from Arial, which is meaningless for a Han face and would add a size-adjusted\n * ghost face into the same family.\n * - 700 is a real Bold subset (not synthetic). Without it, CSS weight matching\n * collapses 700 → 600 and the mixed-script ladder flattens against Geist.\n * `font-synthesis: none` still forbids faux bold for any weight we do not ship.\n */\nexport const vivoSansCn = localFont({\n src: [\n { path: \"../generated/vivo-sans-sc-400.woff2\", weight: \"400\", style: \"normal\" },\n { path: \"../generated/vivo-sans-sc-500.woff2\", weight: \"500\", style: \"normal\" },\n { path: \"../generated/vivo-sans-sc-600.woff2\", weight: \"600\", style: \"normal\" },\n { path: \"../generated/vivo-sans-sc-700.woff2\", weight: \"700\", style: \"normal\" },\n ],\n declarations: [\n {\n prop: \"unicode-range\",\n value: \"U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF\",\n },\n ],\n display: \"swap\",\n preload: false,\n adjustFontFallback: false,\n variable: \"--font-vivo-sans-sc\",\n});\n\n/**\n * Apply to <html> next to the Geist loaders so `--font-vivo-sans-sc` exists:\n *\n * className={`${GeistSans.variable} ${GeistMono.variable} ${cjkFontClassName}`}\n *\n * The token stacks (`--font-sans` / `--font-cn` / `--font-display` in\n * @nebutra/tokens) reference the variable AFTER Geist, so Geist keeps Latin and\n * the numerals and only CJK falls through to this face.\n */\nexport const cjkFontClassName = vivoSansCn.variable;\n"],"mappings":";AA4BA,OAAO,eAAe;AAoBf,IAAM,aAAa,UAAU;AAAA,EAClC,KAAK;AAAA,IACH,EAAE,MAAM,uCAAuC,QAAQ,OAAO,OAAO,SAAS;AAAA,IAC9E,EAAE,MAAM,uCAAuC,QAAQ,OAAO,OAAO,SAAS;AAAA,IAC9E,EAAE,MAAM,uCAAuC,QAAQ,OAAO,OAAO,SAAS;AAAA,IAC9E,EAAE,MAAM,uCAAuC,QAAQ,OAAO,OAAO,SAAS;AAAA,EAChF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,UAAU;AACZ,CAAC;AAWM,IAAM,mBAAmB,WAAW;","names":[]}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* vivo-sans-cn.css — GENERATED FILE, DO NOT EDIT.
|
|
3
|
-
* Written by packages/design/fonts/scripts/subset-cjk.mjs (`pnpm --filter
|
|
4
|
-
* @nebutra/fonts subset:cjk`). Re-run it after adding Chinese copy; the
|
|
5
|
-
* character set is collected from the repo's zh* message catalogs by glob.
|
|
6
|
-
*
|
|
7
|
-
* 4282 characters per face. Source: vivo Sans SC (static Brand faces),
|
|
8
|
-
* licensed — see vendor/vivo-sans/LICENCE-vivo-Sans.txt. Per clause 2.1 of that
|
|
9
|
-
* agreement: 您应在软件中特别注明使用了vivo Sans 字体 / this software uses the
|
|
10
|
-
* vivo Sans typeface.
|
|
11
|
-
*
|
|
12
|
-
* STACK ORDER: use "Geist, vivo Sans SC, …" — Geist first so it keeps Latin and
|
|
13
|
-
* the numerals (tabular figures, tighter x-height), with CJK falling through to
|
|
14
|
-
* vivo Sans SC. The unicode-range below contains no Latin, ASCII or general
|
|
15
|
-
* punctuation, so Latin-only text never downloads a CJK file.
|
|
16
|
-
*
|
|
17
|
-
* font-display: swap — the fallback (PingFang / YaHei) paints immediately and is
|
|
18
|
-
* replaced when the subset arrives; CJK text must never be invisible.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
@font-face {
|
|
22
|
-
font-family: "vivo Sans SC";
|
|
23
|
-
font-style: normal;
|
|
24
|
-
font-weight: 400;
|
|
25
|
-
font-display: swap;
|
|
26
|
-
src: url("./vivo-sans-sc-400.woff2") format("woff2");
|
|
27
|
-
unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@font-face {
|
|
31
|
-
font-family: "vivo Sans SC";
|
|
32
|
-
font-style: normal;
|
|
33
|
-
font-weight: 500;
|
|
34
|
-
font-display: swap;
|
|
35
|
-
src: url("./vivo-sans-sc-500.woff2") format("woff2");
|
|
36
|
-
unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@font-face {
|
|
40
|
-
font-family: "vivo Sans SC";
|
|
41
|
-
font-style: normal;
|
|
42
|
-
font-weight: 600;
|
|
43
|
-
font-display: swap;
|
|
44
|
-
src: url("./vivo-sans-sc-600.woff2") format("woff2");
|
|
45
|
-
unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@font-face {
|
|
49
|
-
font-family: "vivo Sans SC";
|
|
50
|
-
font-style: normal;
|
|
51
|
-
font-weight: 700;
|
|
52
|
-
font-display: swap;
|
|
53
|
-
src: url("./vivo-sans-sc-700.woff2") format("woff2");
|
|
54
|
-
unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
|
|
55
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
vivo Sans字体知识产权许可协议
|
|
2
|
-
|
|
3
|
-
本《vivo Sans字体知识产权许可协议》(以下简称“协议”)是您与维沃移动通信有限公司(以下简称“vivo”或“许可⽅”)之间有关安装、使⽤vivo Sans字体(以下简称“vivo Sans”或“vivo Sans字体”)的法律协议。您在使⽤vivo Sans字体的所有或任何部分前,应接受本协议中规定的所有条款和条件。安装、使⽤vivo Sans主体的⾏为表示您同意接受本协议所有条款的约束。否则,请不要安装和/或使⽤vivo Sans字体,并应⽴即销毁和删除所有 vivo Sans字体包。
|
|
4
|
-
|
|
5
|
-
1.定义
|
|
6
|
-
1.1 “vivo Sans字体”代表许可⽅在本协议项下提供并明确标记为“vivo Sans”的字体软件,包括但不限于以各种形式、格式及媒介存在的源代码、数据库、⽂档等。
|
|
7
|
-
1.2 “⽤户”或“您”代表⾏使本协议授予许可的⾃然⼈、法⼈或⾮法⼈组织。⽤户应依照本协议安装、使⽤vivo Sans字体。
|
|
8
|
-
1.3 “使⽤”是指安装、下载、复制、展览或以其他⽅式通过利⽤vivo Sans字体⽽获益的⾏为。
|
|
9
|
-
|
|
10
|
-
2.授权许可
|
|
11
|
-
根据本协议的条款和条件,许可⽅在此授予您⼀份不可转让的、⾮独占的、免版税的、可撤销的、全球性的版权许可,使您依照本协议约定使⽤vivo Sans字体,前提是符合下列条件:
|
|
12
|
-
2.1您应在软件中特别注明使⽤了vivo Sans 字体。
|
|
13
|
-
2.2您不得对vivo Sans字体或其任何单独组件进⾏改编或⼆次开发。
|
|
14
|
-
2.3您不得单独将vivo Sans字体或其组件对外租赁、再许可、给予、出借或进⼀步分发字体软件或其任何副本以及重新分发或售卖。此限制不适⽤于您使⽤vivo Sans字体创作的任何其他作品。如您使⽤vivo Sans字体创作宣传素材、logo、应⽤App等,您有权分发或出售该作品。
|
|
15
|
-
2.4您应在vivo Sans字体的任何副本中保留版权声明和本协议。
|
|
16
|
-
2.5不可将vivo Sans字体⽤于任何违法⽤途。
|
|
17
|
-
|
|
18
|
-
3.知识产权
|
|
19
|
-
vivo Sans字体软件及其所包含的字体以及vivo授权您制作的任何副本均为vivo的知识产品,本字库软件的结构、组织和代码以及与本字库软件相关的所有信息均为vivo的商业秘密。本字库软件及其所包含的字体受《中华⼈⺠共和国著作权法》、《计算机软件保护条例》和其他知识产权法律法规及国际公约、条约的保护。除本协议中明确的许可,vivo不授予您对vivo Sans字体相关的其他知识产权权利。
|
|
20
|
-
|
|
21
|
-
4.免责声明
|
|
22
|
-
4.1 vivo Sans是按“原样”提供的。许可⽅不对本协议作出任何明示、暗示或依照相关法律规定的担保,包括但不限于对适销性、所有权、就某⼀⽤途的适⽤性或不侵犯版权、专利、商标或其他权利的保证。
|
|
23
|
-
4.2 在任何情况下,许可⽅及其关联公司均不对任何直接、间接、特殊、附带或间接的损害(包括但不限于购买替代商品或服务)负责。⽆论根据合同理论、侵权⾏为(包括过失)理论、严格责任理论或其他法律理论,因使⽤或⽆法使⽤ vivo Sans字体,即使许可⽅及其关联公司已被告知存在这种损害的可能性,⽽导致的任何⽅式的业务中断,使⽤数据或利润的损失,许可⽅及其关联公司不承担任何责任。
|
|
24
|
-
4.3 您需明确承担使⽤ vivo Sans字体的所有责任和⻛险。如果⽆法证明vivo Sans字体有任何缺陷,您将承担所有必要的服务、修复或纠正的全部费⽤。
|
|
25
|
-
|
|
26
|
-
5.许可终⽌
|
|
27
|
-
⼀旦您违反本协议的相关条款,vivo随时有权终⽌本协议、收回授权,并要求您承担相应法律责任。
|
|
28
|
-
|
|
29
|
-
6.适⽤法律与管辖
|
|
30
|
-
本协议适⽤中华⼈⺠共和国的法律。如您与vivo就本协议的相关问题发⽣争议,您与vivo均有权向广东省东莞市第二人民法院提起诉讼。
|
|
31
|
-
|
|
32
|
-
7.⼀般规定
|
|
33
|
-
7.1 本协议是vivo与您之间有关vivo Sans软件及其所包含的字体的最新许可协议,它将取代先前所有与本字库软件相关的陈述、承诺、宣传或许可协议。
|
|
34
|
-
7.2 如果您对本协议有任何疑问或者希望获得有关字体授权许可的任何信息,请通过如下⽅式与vivo联系:
|
|
35
|
-
维沃移动通信有限公司
|
|
36
|
-
地址:广东省东莞市长安镇维沃路1号
|
|
37
|
-
邮箱:vivo@vivo.com.cn
|