@ohos-ports/font-list 0.0.0-stage → 2.1.0-beta.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/LICENSE +21 -0
- package/README.md +254 -2
- package/index.d.cts +25 -0
- package/index.d.mts +26 -0
- package/index.d.ts +31 -0
- package/index.js +12 -0
- package/index.mjs +19 -0
- package/libs/core.js +100 -0
- package/libs/darwin/fontlist +0 -0
- package/libs/darwin/fontlist.m +141 -0
- package/libs/darwin/index.js +146 -0
- package/libs/linux/index.js +142 -0
- package/libs/standardize.js +31 -0
- package/libs/win32/fonts.vbs +29 -0
- package/libs/win32/getByPowerShell.js +41 -0
- package/libs/win32/getByVBS.js +81 -0
- package/libs/win32/getDetailedFontsByPowerShell.js +127 -0
- package/libs/win32/index.js +80 -0
- package/package.json +46 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 oldj
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,255 @@
|
|
|
1
|
-
#
|
|
1
|
+
# font-list
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Node.js package for listing system fonts with support for both CommonJS and ES modules.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/font-list)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🖥️ **Cross-platform support**: Works on macOS, Windows, and Linux
|
|
11
|
+
- 📦 **Dual module support**: Compatible with both CommonJS and ES modules
|
|
12
|
+
- 🔍 **Two API methods**: Basic font listing and detailed font information
|
|
13
|
+
- 📝 **TypeScript support**: Includes TypeScript type definitions
|
|
14
|
+
- ⚡ **Async/Promise based**: Modern asynchronous API
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @ohos-ports/font-list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### CommonJS
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
const { getFonts } = require('@ohos-ports/font-list')
|
|
28
|
+
|
|
29
|
+
getFonts()
|
|
30
|
+
.then(fonts => {
|
|
31
|
+
console.log(fonts)
|
|
32
|
+
})
|
|
33
|
+
.catch(err => {
|
|
34
|
+
console.error(err)
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### ES Modules
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { getFonts } from '@ohos-ports/font-list'
|
|
42
|
+
|
|
43
|
+
const fonts = await getFonts()
|
|
44
|
+
console.log(fonts)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### TypeScript
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { getFonts, FontInfo } from '@ohos-ports/font-list'
|
|
51
|
+
|
|
52
|
+
const fonts: string[] = await getFonts()
|
|
53
|
+
const detailedFonts: FontInfo[] = await getFonts2()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API Reference
|
|
57
|
+
|
|
58
|
+
### `getFonts(options?)`
|
|
59
|
+
|
|
60
|
+
Returns a list of font family names available on the system.
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
- `options` (optional): Configuration object
|
|
64
|
+
- `disableQuoting` (boolean): If `true`, font names with spaces won't be wrapped in quotes. Default: `false`
|
|
65
|
+
|
|
66
|
+
**Returns:** `Promise<string[]>`
|
|
67
|
+
|
|
68
|
+
**Example output:**
|
|
69
|
+
```js
|
|
70
|
+
[
|
|
71
|
+
'"Adobe Arabic"',
|
|
72
|
+
'"Adobe Caslon Pro"',
|
|
73
|
+
'Arial',
|
|
74
|
+
'Helvetica',
|
|
75
|
+
...
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Usage examples:**
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
// Default behavior (with quotes for names containing spaces)
|
|
83
|
+
const fonts = await getFonts()
|
|
84
|
+
// Result: ['"Adobe Arabic"', 'Arial', ...]
|
|
85
|
+
|
|
86
|
+
// Disable quoting
|
|
87
|
+
const fonts = await getFonts({ disableQuoting: true })
|
|
88
|
+
// Result: ['Adobe Arabic', 'Arial', ...]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `getFonts2(options?)`
|
|
92
|
+
|
|
93
|
+
Returns detailed font information including both family names and PostScript names.
|
|
94
|
+
|
|
95
|
+
**Parameters:**
|
|
96
|
+
- `options` (optional): Same as `getFonts()`
|
|
97
|
+
- `disableQuoting` (boolean): Default: `false`
|
|
98
|
+
|
|
99
|
+
**Returns:** `Promise<FontInfo[]>`
|
|
100
|
+
|
|
101
|
+
**FontInfo interface:**
|
|
102
|
+
```ts
|
|
103
|
+
interface FontInfo {
|
|
104
|
+
name: string // Original family name
|
|
105
|
+
familyName: string // Standardized family name
|
|
106
|
+
postScriptName: string // PostScript name
|
|
107
|
+
weight: string // Font weight (ultralight, light, regular, medium, semibold, bold, heavy)
|
|
108
|
+
style: string // Font style (normal, italic, oblique)
|
|
109
|
+
width: string // Font width (condensed, normal, expanded)
|
|
110
|
+
monospace: boolean // Whether the font is monospaced
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Example output:**
|
|
115
|
+
```js
|
|
116
|
+
[
|
|
117
|
+
{
|
|
118
|
+
name: 'Adobe Arabic',
|
|
119
|
+
familyName: '"Adobe Arabic"',
|
|
120
|
+
postScriptName: 'AdobeArabic-Regular',
|
|
121
|
+
weight: 'regular',
|
|
122
|
+
style: 'normal',
|
|
123
|
+
width: 'normal',
|
|
124
|
+
monospace: false
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'Arial',
|
|
128
|
+
familyName: 'Arial',
|
|
129
|
+
postScriptName: 'ArialMT',
|
|
130
|
+
weight: 'regular',
|
|
131
|
+
style: 'normal',
|
|
132
|
+
width: 'normal',
|
|
133
|
+
monospace: false
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'Courier New',
|
|
137
|
+
familyName: '"Courier New"',
|
|
138
|
+
postScriptName: 'CourierNewPSMT',
|
|
139
|
+
weight: 'regular',
|
|
140
|
+
style: 'normal',
|
|
141
|
+
width: 'normal',
|
|
142
|
+
monospace: true
|
|
143
|
+
},
|
|
144
|
+
...
|
|
145
|
+
]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Usage examples:**
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
// Get detailed font information
|
|
152
|
+
const detailedFonts = await getFonts2()
|
|
153
|
+
console.log(detailedFonts[0].familyName) // "Adobe Arabic"
|
|
154
|
+
console.log(detailedFonts[0].postScriptName) // AdobeArabic-Regular
|
|
155
|
+
console.log(detailedFonts[0].weight) // regular
|
|
156
|
+
console.log(detailedFonts[0].style) // normal
|
|
157
|
+
console.log(detailedFonts[0].width) // normal
|
|
158
|
+
console.log(detailedFonts[0].monospace) // false
|
|
159
|
+
|
|
160
|
+
// With disabled quoting
|
|
161
|
+
const detailedFonts = await getFonts2({ disableQuoting: true })
|
|
162
|
+
console.log(detailedFonts[0].familyName) // Adobe Arabic
|
|
163
|
+
|
|
164
|
+
// Filter monospace fonts
|
|
165
|
+
const monospaceFonts = detailedFonts.filter(font => font.monospace)
|
|
166
|
+
console.log(monospaceFonts.map(f => f.familyName))
|
|
167
|
+
|
|
168
|
+
// Filter bold fonts
|
|
169
|
+
const boldFonts = detailedFonts.filter(font => font.weight === 'bold')
|
|
170
|
+
console.log(boldFonts.map(f => f.familyName))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Platform Support
|
|
174
|
+
|
|
175
|
+
| Platform | Method | Implementation |
|
|
176
|
+
|----------|--------|--------------|
|
|
177
|
+
| macOS | `system_profiler` | Uses system font database |
|
|
178
|
+
| Windows | PowerShell/VBS | Registry and system font queries |
|
|
179
|
+
| Linux | `fc-list` | Fontconfig library |
|
|
180
|
+
|
|
181
|
+
## Module Formats
|
|
182
|
+
|
|
183
|
+
This package supports both CommonJS and ES modules through dual package exports:
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
// CommonJS
|
|
187
|
+
const { getFonts, getFonts2 } = require('@ohos-ports/font-list')
|
|
188
|
+
|
|
189
|
+
// ES Modules
|
|
190
|
+
import { getFonts, getFonts2 } from '@ohos-ports/font-list'
|
|
191
|
+
|
|
192
|
+
// Default export (ES Modules)
|
|
193
|
+
import fontList from '@ohos-ports/font-list'
|
|
194
|
+
const fonts = await fontList.getFonts()
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Error Handling
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
try {
|
|
201
|
+
const fonts = await getFonts()
|
|
202
|
+
console.log(`Found ${fonts.length} fonts`)
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.error('Failed to get fonts:', error.message)
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Contributing
|
|
209
|
+
|
|
210
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
211
|
+
|
|
212
|
+
### Darwin helper binary
|
|
213
|
+
|
|
214
|
+
The macOS implementation includes a native Objective-C helper binary at
|
|
215
|
+
`libs/darwin/fontlist`. The binary is kept in git so macOS users can clone the
|
|
216
|
+
repository and run it without a local build step. It supports two modes: no
|
|
217
|
+
arguments prints the simple family-name list, while `--detail` (or `-d`) prints
|
|
218
|
+
a JSON array with weight/style/width/monospace metadata.
|
|
219
|
+
|
|
220
|
+
If you change `libs/darwin/fontlist.m`, rebuild the helper binary on macOS
|
|
221
|
+
before submitting the change:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
npm run build:darwin
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
This command requires macOS and Xcode Command Line Tools. It produces a
|
|
228
|
+
universal binary with `x86_64` and `arm64` slices and a default macOS
|
|
229
|
+
deployment target of `11.0`. Set `MACOSX_DEPLOYMENT_TARGET` before running the
|
|
230
|
+
command to override the target for a release build. Windows and Linux
|
|
231
|
+
contributors do not need to run it for JavaScript, type definition,
|
|
232
|
+
documentation, or platform-specific changes outside `libs/darwin`.
|
|
233
|
+
|
|
234
|
+
Pull requests should include the Darwin binary diff only when the
|
|
235
|
+
Objective-C source file changed.
|
|
236
|
+
|
|
237
|
+
### Publishing
|
|
238
|
+
|
|
239
|
+
Releases should be published from macOS. `npm publish` runs `prepublishOnly`,
|
|
240
|
+
which rebuilds the Darwin helper binary before the package is packed and
|
|
241
|
+
published.
|
|
242
|
+
|
|
243
|
+
To inspect the package contents before publishing, run:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
npm run pack:check
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT © [oldj](https://github.com/oldj)
|
|
252
|
+
|
|
253
|
+
## Repository
|
|
254
|
+
|
|
255
|
+
[https://github.com/oldj/node-font-list](https://github.com/oldj/node-font-list)
|
package/index.d.cts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
declare namespace fontList {
|
|
2
|
+
export interface IOptions {
|
|
3
|
+
disableQuoting: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface IFontInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
familyName: string;
|
|
9
|
+
postScriptName: string;
|
|
10
|
+
weight: string;
|
|
11
|
+
style: string;
|
|
12
|
+
width: string;
|
|
13
|
+
monospace: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type FontList = string[];
|
|
17
|
+
export type DetailedFontList = IFontInfo[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const fontList: {
|
|
21
|
+
getFonts(options?: fontList.IOptions): Promise<fontList.FontList>;
|
|
22
|
+
getFonts2(options?: fontList.IOptions): Promise<fontList.DetailedFontList>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export = fontList;
|
package/index.d.mts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface IOptions {
|
|
2
|
+
disableQuoting: boolean;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface IFontInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
familyName: string;
|
|
8
|
+
postScriptName: string;
|
|
9
|
+
weight: string;
|
|
10
|
+
style: string;
|
|
11
|
+
width: string;
|
|
12
|
+
monospace: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type FontList = string[];
|
|
16
|
+
type DetailedFontList = IFontInfo[];
|
|
17
|
+
|
|
18
|
+
export function getFonts(options?: IOptions): Promise<FontList>;
|
|
19
|
+
export function getFonts2(options?: IOptions): Promise<DetailedFontList>;
|
|
20
|
+
|
|
21
|
+
declare const fontList: {
|
|
22
|
+
getFonts(options?: IOptions): Promise<FontList>;
|
|
23
|
+
getFonts2(options?: IOptions): Promise<DetailedFontList>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default fontList;
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author: oldj
|
|
3
|
+
* @homepage: https://oldj.net
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
interface IOptions {
|
|
7
|
+
disableQuoting: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface IFontInfo {
|
|
11
|
+
name: string;
|
|
12
|
+
familyName: string;
|
|
13
|
+
postScriptName: string;
|
|
14
|
+
weight: string;
|
|
15
|
+
style: string;
|
|
16
|
+
width: string;
|
|
17
|
+
monospace: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type FontList = string[];
|
|
21
|
+
type DetailedFontList = IFontInfo[];
|
|
22
|
+
|
|
23
|
+
export function getFonts(options?: IOptions): Promise<FontList>;
|
|
24
|
+
export function getFonts2(options?: IOptions): Promise<DetailedFontList>;
|
|
25
|
+
|
|
26
|
+
declare const fontList: {
|
|
27
|
+
getFonts(options?: IOptions): Promise<FontList>;
|
|
28
|
+
getFonts2(options?: IOptions): Promise<DetailedFontList>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default fontList;
|
package/index.js
ADDED
package/index.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author oldj
|
|
3
|
+
* @blog http://oldj.net
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const { getFonts: _getFonts, getFonts2: _getFonts2 } = require("./libs/core");
|
|
10
|
+
|
|
11
|
+
// ES module exports
|
|
12
|
+
export const getFonts = _getFonts;
|
|
13
|
+
export const getFonts2 = _getFonts2;
|
|
14
|
+
|
|
15
|
+
// Default export
|
|
16
|
+
export default {
|
|
17
|
+
getFonts,
|
|
18
|
+
getFonts2,
|
|
19
|
+
};
|
package/libs/core.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author oldj
|
|
3
|
+
* @blog http://oldj.net
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const standardize = require("./standardize");
|
|
9
|
+
const platform = process.platform;
|
|
10
|
+
|
|
11
|
+
let getFontsFunc;
|
|
12
|
+
let getDetailedFontsFunc;
|
|
13
|
+
|
|
14
|
+
// Initialize platform-specific font retrieval functions
|
|
15
|
+
switch (platform) {
|
|
16
|
+
case "darwin":
|
|
17
|
+
const darwinModule = require("./darwin");
|
|
18
|
+
getFontsFunc = darwinModule.getFonts;
|
|
19
|
+
getDetailedFontsFunc = darwinModule.getDetailedFonts;
|
|
20
|
+
break;
|
|
21
|
+
case "win32":
|
|
22
|
+
const win32Module = require("./win32");
|
|
23
|
+
getFontsFunc = win32Module.getFonts;
|
|
24
|
+
getDetailedFontsFunc = win32Module.getDetailedFonts;
|
|
25
|
+
break;
|
|
26
|
+
case "linux":
|
|
27
|
+
case "openharmony": // HarmonyOS: reuse the linux implementation (fc-list based)
|
|
28
|
+
case "ohos":
|
|
29
|
+
const linuxModule = require("./linux");
|
|
30
|
+
getFontsFunc = linuxModule.getFonts;
|
|
31
|
+
getDetailedFontsFunc = linuxModule.getDetailedFonts;
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
throw new Error(`Error: font-list can not run on ${platform}.`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const defaultOptions = {
|
|
38
|
+
disableQuoting: false,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get system font list
|
|
43
|
+
* @param {Object} options - Options
|
|
44
|
+
* @returns {Promise<string[]>} Array of font names
|
|
45
|
+
*/
|
|
46
|
+
async function getFonts(options) {
|
|
47
|
+
options = Object.assign({}, defaultOptions, options);
|
|
48
|
+
|
|
49
|
+
let fonts = await getFontsFunc();
|
|
50
|
+
fonts = standardize(fonts, options);
|
|
51
|
+
|
|
52
|
+
fonts.sort((a, b) => {
|
|
53
|
+
return a.replace(/^['"]+/, "").toLocaleLowerCase() <
|
|
54
|
+
b.replace(/^['"]+/, "").toLocaleLowerCase()
|
|
55
|
+
? -1
|
|
56
|
+
: 1;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return fonts;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get detailed system font information
|
|
64
|
+
* @param {Object} options - Options
|
|
65
|
+
* @returns {Promise<Array>} Array of detailed font information
|
|
66
|
+
*/
|
|
67
|
+
async function getFonts2(options) {
|
|
68
|
+
options = Object.assign({}, defaultOptions, options);
|
|
69
|
+
|
|
70
|
+
let fonts = await getDetailedFontsFunc();
|
|
71
|
+
fonts = fonts.filter(
|
|
72
|
+
(font) => font.familyName && typeof font.familyName === "string"
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Standardize familyName and pass through new attributes
|
|
76
|
+
fonts = fonts.map((font) => ({
|
|
77
|
+
name: font.familyName,
|
|
78
|
+
familyName: standardize([font.familyName], options)[0],
|
|
79
|
+
postScriptName: font.postScriptName,
|
|
80
|
+
weight: font.weight || "regular",
|
|
81
|
+
style: font.style || "normal",
|
|
82
|
+
width: font.width || "normal",
|
|
83
|
+
monospace: font.monospace || false,
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
// Sort by familyName
|
|
87
|
+
fonts.sort((a, b) => {
|
|
88
|
+
return a.familyName.replace(/^['"]+/, "").toLocaleLowerCase() <
|
|
89
|
+
b.familyName.replace(/^['"]+/, "").toLocaleLowerCase()
|
|
90
|
+
? -1
|
|
91
|
+
: 1;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return fonts;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
getFonts,
|
|
99
|
+
getFonts2,
|
|
100
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#import <AppKit/AppKit.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
#import <string.h>
|
|
4
|
+
|
|
5
|
+
static void printSimpleList(NSArray *fontFamilyNames) {
|
|
6
|
+
for (NSString *familyName in fontFamilyNames) {
|
|
7
|
+
printf("%s\n", [familyName UTF8String]);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static void printDetailedJSON(NSArray *fontFamilyNames, NSFontManager *fontManager) {
|
|
12
|
+
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[fontFamilyNames count]];
|
|
13
|
+
|
|
14
|
+
for (NSString *familyName in fontFamilyNames) {
|
|
15
|
+
NSArray *fontMembers = [fontManager availableMembersOfFontFamily:familyName];
|
|
16
|
+
NSString *postScriptName = familyName;
|
|
17
|
+
NSString *memberStyleName = @"";
|
|
18
|
+
unsigned int memberTraitMask = 0;
|
|
19
|
+
if (fontMembers && fontMembers.count > 0) {
|
|
20
|
+
NSArray *fontInfo = [fontMembers objectAtIndex:0];
|
|
21
|
+
postScriptName = [fontInfo objectAtIndex:0];
|
|
22
|
+
if ([fontInfo count] > 1) {
|
|
23
|
+
memberStyleName = [fontInfo objectAtIndex:1];
|
|
24
|
+
}
|
|
25
|
+
if ([fontInfo count] > 3) {
|
|
26
|
+
memberTraitMask = [[fontInfo objectAtIndex:3] unsignedIntValue];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
NSString *weight = @"regular";
|
|
31
|
+
NSString *style = @"normal";
|
|
32
|
+
NSString *width = @"normal";
|
|
33
|
+
BOOL monospace = NO;
|
|
34
|
+
|
|
35
|
+
NSFont *font = [NSFont fontWithName:postScriptName size:12.0];
|
|
36
|
+
if (font) {
|
|
37
|
+
NSFontDescriptor *descriptor = [font fontDescriptor];
|
|
38
|
+
NSFontSymbolicTraits traits = [descriptor symbolicTraits];
|
|
39
|
+
|
|
40
|
+
if (traits & NSFontMonoSpaceTrait) {
|
|
41
|
+
monospace = YES;
|
|
42
|
+
}
|
|
43
|
+
if (traits & NSFontItalicTrait) {
|
|
44
|
+
style = @"italic";
|
|
45
|
+
}
|
|
46
|
+
if (traits & NSFontCondensedTrait) {
|
|
47
|
+
width = @"condensed";
|
|
48
|
+
} else if (traits & NSFontExpandedTrait) {
|
|
49
|
+
width = @"expanded";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
NSDictionary *traitsDict = [descriptor objectForKey:NSFontTraitsAttribute];
|
|
53
|
+
NSNumber *weightNum = traitsDict[NSFontWeightTrait];
|
|
54
|
+
if (weightNum) {
|
|
55
|
+
CGFloat w = [weightNum doubleValue];
|
|
56
|
+
if (w <= -0.6) weight = @"ultralight";
|
|
57
|
+
else if (w <= -0.3) weight = @"light";
|
|
58
|
+
else if (w <= 0.1) weight = @"regular";
|
|
59
|
+
else if (w <= 0.25) weight = @"medium";
|
|
60
|
+
else if (w <= 0.35) weight = @"semibold";
|
|
61
|
+
else if (w <= 0.5) weight = @"bold";
|
|
62
|
+
else weight = @"heavy";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
NSString *fallbackName = [[NSString stringWithFormat:@"%@ %@ %@", familyName, postScriptName, memberStyleName] lowercaseString];
|
|
67
|
+
if ([weight isEqualToString:@"regular"]) {
|
|
68
|
+
if ([fallbackName containsString:@"ultralight"] || [fallbackName containsString:@"ultra light"] ||
|
|
69
|
+
[fallbackName containsString:@"thin"]) {
|
|
70
|
+
weight = @"ultralight";
|
|
71
|
+
} else if ([fallbackName containsString:@"light"]) {
|
|
72
|
+
weight = @"light";
|
|
73
|
+
} else if ([fallbackName containsString:@"medium"]) {
|
|
74
|
+
weight = @"medium";
|
|
75
|
+
} else if ([fallbackName containsString:@"semibold"] || [fallbackName containsString:@"semi bold"] ||
|
|
76
|
+
[fallbackName containsString:@"demibold"] || [fallbackName containsString:@"demi bold"]) {
|
|
77
|
+
weight = @"semibold";
|
|
78
|
+
} else if ([fallbackName containsString:@"bold"] || (memberTraitMask & NSBoldFontMask)) {
|
|
79
|
+
weight = @"bold";
|
|
80
|
+
} else if ([fallbackName containsString:@"heavy"] || [fallbackName containsString:@"black"]) {
|
|
81
|
+
weight = @"heavy";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if ([style isEqualToString:@"normal"] &&
|
|
85
|
+
([fallbackName containsString:@"italic"] || [fallbackName containsString:@"oblique"] ||
|
|
86
|
+
(memberTraitMask & NSItalicFontMask))) {
|
|
87
|
+
style = @"italic";
|
|
88
|
+
}
|
|
89
|
+
if ([width isEqualToString:@"normal"]) {
|
|
90
|
+
if ([fallbackName containsString:@"condensed"] || [fallbackName containsString:@"narrow"] ||
|
|
91
|
+
(memberTraitMask & NSCondensedFontMask) || (memberTraitMask & NSNarrowFontMask)) {
|
|
92
|
+
width = @"condensed";
|
|
93
|
+
} else if ([fallbackName containsString:@"expanded"] || [fallbackName containsString:@"extended"] ||
|
|
94
|
+
(memberTraitMask & NSExpandedFontMask)) {
|
|
95
|
+
width = @"expanded";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[result addObject:@{
|
|
100
|
+
@"familyName": familyName,
|
|
101
|
+
@"postScriptName": postScriptName,
|
|
102
|
+
@"weight": weight,
|
|
103
|
+
@"style": style,
|
|
104
|
+
@"width": width,
|
|
105
|
+
@"monospace": @(monospace),
|
|
106
|
+
}];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
NSError *error = nil;
|
|
110
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:result
|
|
111
|
+
options:NSJSONWritingPrettyPrinted
|
|
112
|
+
error:&error];
|
|
113
|
+
if (!data) {
|
|
114
|
+
fprintf(stderr, "fontlist: failed to serialize JSON: %s\n",
|
|
115
|
+
error ? [[error localizedDescription] UTF8String] : "unknown error");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
fwrite([data bytes], 1, [data length], stdout);
|
|
119
|
+
fputc('\n', stdout);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
int main(int argc, const char * argv[]) {
|
|
123
|
+
@autoreleasepool {
|
|
124
|
+
BOOL detailed = NO;
|
|
125
|
+
for (int i = 1; i < argc; i++) {
|
|
126
|
+
if (strcmp(argv[i], "--detail") == 0 || strcmp(argv[i], "-d") == 0) {
|
|
127
|
+
detailed = YES;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
NSFontManager *fontManager = [NSFontManager sharedFontManager];
|
|
132
|
+
NSArray *fontFamilyNames = [[fontManager availableFontFamilies] sortedArrayUsingSelector:@selector(compare:)];
|
|
133
|
+
|
|
134
|
+
if (detailed) {
|
|
135
|
+
printDetailedJSON(fontFamilyNames, fontManager);
|
|
136
|
+
} else {
|
|
137
|
+
printSimpleList(fontFamilyNames);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return 0;
|
|
141
|
+
}
|