pa_font 0.1.2 → 0.2.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/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # @hanyongpa/pa-font
2
+
3
+ OpenType 폰트를 polygon, region, point 데이터로 바꿔 쓰기 위한 작은 geometry 라이브러리입니다.
4
+
5
+ 현재 `package.json` 기준 패키지 이름은 `@hanyongpa/pa-font`로 잡아두었습니다. 실제 publish 전에 원하는 scope나 이름이 있으면 이 값만 바꾸면 됩니다.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @hanyongpa/pa-font
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```js
16
+ import paFont from "@hanyongpa/pa-font";
17
+
18
+ const font = await paFont.load("/assets/font.otf");
19
+
20
+ const shape = font.text("안녕", {
21
+ x: 0,
22
+ y: 200,
23
+ size: 160,
24
+ flatten: 1,
25
+ });
26
+
27
+ const regions = shape.toRegions();
28
+ const points = shape.toPoints({ step: 8 });
29
+ ```
30
+
31
+ ## Paragraph Layout
32
+
33
+ `font.paragraph(...)`는 `pretext.js` 기반으로 자동 줄바꿈되는 문단 레이아웃을 만들고,
34
+ 같은 문단을 canvas 텍스트 렌더링과 `paFont` geometry 변환에 같이 쓸 수 있습니다.
35
+
36
+ ```js
37
+ const paragraph = font.paragraph("캔버스에서 자동 줄바꿈되는 문단입니다.", {
38
+ x: 40,
39
+ y: 80,
40
+ width: 420,
41
+ size: 32,
42
+ fontFamily: "MyFont",
43
+ fontWeight: 400,
44
+ lineHeight: 1.4,
45
+ align: "left",
46
+ whiteSpace: "normal",
47
+ engine: "pretext",
48
+ });
49
+
50
+ paragraph.drawText(ctx, {
51
+ fillStyle: "#111",
52
+ });
53
+
54
+ const shape = paragraph.toShape();
55
+ const regions = paragraph.toRegions({ step: 6, openWidth: 1 });
56
+ const points = paragraph.toPoints({ step: 8, openWidth: 1 });
57
+ ```
58
+
59
+ 폭이 바뀌면 문단만 다시 레이아웃할 수 있습니다.
60
+
61
+ ```js
62
+ const mobile = paragraph.relayout({ width: 280 });
63
+ mobile.drawText(ctx);
64
+ ```
65
+
66
+ 정밀한 `paFont` export용으로는 `layout: "native"`를 사용할 수 있습니다.
67
+
68
+ ```js
69
+ const exact = paragraph.toShape({
70
+ layout: "native",
71
+ step: 4,
72
+ });
73
+ ```
74
+
75
+ ## Core Flow
76
+
77
+ 1. `paFont.load(...)`로 폰트를 로드합니다.
78
+ 2. `font.text(...)` 또는 `font.glyph(...)`로 `PAShape`를 만듭니다.
79
+ 3. `shape.toShape(...)`, `shape.toRegions(...)`, `shape.toPoints(...)` 중 필요한 결과를 꺼냅니다.
80
+
81
+ ## Loading Fonts
82
+
83
+ 브라우저에서 가장 단순한 방식:
84
+
85
+ ```js
86
+ const font = await paFont.load("/assets/font.otf");
87
+ ```
88
+
89
+ 모듈 상대 경로를 기준으로 읽고 싶을 때:
90
+
91
+ ```js
92
+ const font = await paFont.load("./font.otf", {
93
+ base: import.meta.url,
94
+ });
95
+ ```
96
+
97
+ Node에서 바이트로 읽어 넘길 때:
98
+
99
+ ```js
100
+ import { readFile } from "node:fs/promises";
101
+ import paFont from "@hanyongpa/pa-font";
102
+
103
+ const bytes = await readFile("./fonts/font.otf");
104
+ const font = await paFont.load(bytes);
105
+ ```
106
+
107
+ ## Public API
108
+
109
+ ### `font.text(value, options)`
110
+
111
+ 문자열 전체를 하나의 `PAShape`로 만듭니다.
112
+
113
+ ### `font.glyph(value, options)`
114
+
115
+ 한 글자만 `PAShape`로 만듭니다.
116
+
117
+ ### `font.metrics(value, options)`
118
+
119
+ 텍스트 폭과 bounding box만 빠르게 계산합니다.
120
+
121
+ ### `font.paragraph(value, options)`
122
+
123
+ 문단 레이아웃 객체 `paParagraph`를 만듭니다.
124
+
125
+ 자주 쓰는 옵션:
126
+
127
+ - `width`: 문단 폭
128
+ - `lineHeight`: 숫자 `<= 10`이면 배수, 그보다 크면 절대 px
129
+ - `fontFamily`, `fontWeight`, `fontStyle`, `font`: canvas text 측정/렌더링용 폰트 설정
130
+ - `align`: `left | center | right | justify`
131
+ - `whiteSpace`: `normal | pre-wrap | nowrap`
132
+ - `engine`: `pretext | native`
133
+
134
+ 주의:
135
+
136
+ - `drawText()`는 canvas 텍스트 렌더링을 사용합니다.
137
+ - `fontFamily` 또는 `font`는 브라우저에 실제 등록된 폰트와 맞아야 합니다.
138
+ - `paragraph.toShape()`, `paragraph.toRegions()`, `paragraph.toPoints()`는 같은 문단 레이아웃을 `paFont` geometry로 변환합니다.
139
+
140
+ ### `shape.toShape({ step, openWidth })`
141
+
142
+ hole 열기와 재샘플링을 적용한 뒤 새 `PAShape`를 반환합니다.
143
+
144
+ ### `shape.toRegions({ step, openWidth })`
145
+
146
+ 최종 도형을 plain polygon data로 반환합니다.
147
+
148
+ ```js
149
+ const regions = font.glyph("영", { size: 160 }).toRegions({
150
+ step: 8,
151
+ openWidth: 1,
152
+ });
153
+ ```
154
+
155
+ ### `shape.toPoints({ step, openWidth, includeHoles })`
156
+
157
+ 경계를 점 데이터로 샘플링합니다.
158
+
159
+ ### `shape.glyphs()`
160
+
161
+ 문장 shape를 글자별 shape 배열로 분리합니다.
162
+
163
+ ## Build
164
+
165
+ 라이브러리 빌드:
166
+
167
+ ```bash
168
+ npm run build
169
+ ```
170
+
171
+ 패키징 확인:
172
+
173
+ ```bash
174
+ npm run pack:check
175
+ ```