ctrl-kd 2.0.0__tar.gz → 4.0.0__tar.gz
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.
- {ctrl_kd-2.0.0/src/ctrl_kd.egg-info → ctrl_kd-4.0.0}/PKG-INFO +39 -10
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/README.md +38 -9
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/pyproject.toml +7 -1
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0/src/ctrl_kd.egg-info}/PKG-INFO +39 -10
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrl_kd.egg-info/SOURCES.txt +11 -1
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrlkd/__init__.py +4 -2
- ctrl_kd-4.0.0/src/ctrlkd/afm.py +337 -0
- ctrl_kd-4.0.0/src/ctrlkd/cli.py +253 -0
- ctrl_kd-4.0.0/src/ctrlkd/core.py +3414 -0
- ctrl_kd-4.0.0/src/ctrlkd/emit.py +1085 -0
- ctrl_kd-4.0.0/src/ctrlkd/fontmap.py +290 -0
- ctrl_kd-4.0.0/src/ctrlkd/info.py +59 -0
- ctrl_kd-4.0.0/src/ctrlkd/layout.py +341 -0
- ctrl_kd-4.0.0/src/ctrlkd/pdf.py +1938 -0
- ctrl_kd-4.0.0/src/ctrlkd/symbolmap.py +125 -0
- ctrl_kd-4.0.0/src/ctrlkd/typestyles.py +256 -0
- ctrl_kd-4.0.0/src/ctrlkd/writer.py +267 -0
- ctrl_kd-4.0.0/src/ctrlkd/wschange.py +215 -0
- ctrl_kd-4.0.0/tests/test_ctrlkd.py +3915 -0
- ctrl_kd-4.0.0/tests/test_writer.py +322 -0
- ctrl_kd-4.0.0/tests/test_wschange.py +194 -0
- ctrl_kd-2.0.0/src/ctrlkd/cli.py +0 -124
- ctrl_kd-2.0.0/src/ctrlkd/core.py +0 -929
- ctrl_kd-2.0.0/src/ctrlkd/emit.py +0 -577
- ctrl_kd-2.0.0/src/ctrlkd/pdf.py +0 -580
- ctrl_kd-2.0.0/tests/test_ctrlkd.py +0 -1335
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/LICENSE +0 -0
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/setup.cfg +0 -0
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrl_kd.egg-info/dependency_links.txt +0 -0
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrl_kd.egg-info/entry_points.txt +0 -0
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrl_kd.egg-info/top_level.txt +0 -0
- {ctrl_kd-2.0.0 → ctrl_kd-4.0.0}/src/ctrlkd/convert.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctrl-kd
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0
|
|
4
4
|
Summary: Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done.
|
|
5
5
|
Author: Jon Michaels
|
|
6
6
|
License: MIT
|
|
@@ -19,18 +19,33 @@ Dynamic: license-file
|
|
|
19
19
|
|
|
20
20
|
# ctrl-kd
|
|
21
21
|
|
|
22
|
+
```
|
|
23
|
+
__ __ __ __
|
|
24
|
+
_____/ /______/ / / /______/ /
|
|
25
|
+
/ ___/ __/ ___/ /_____/ //_/ __ /
|
|
26
|
+
/ /__/ /_/ / / /_____/ ,< / /_/ /
|
|
27
|
+
\___/\__/_/ /_/ /_/|_|\__,_/
|
|
28
|
+
```
|
|
29
|
+
|
|
22
30
|
Convert WordStar-era files to modern formats. **^KD: save and done.**
|
|
23
31
|
|
|
24
32
|
`ctrl-kd` reads WordStar 4 documents, WordStar 5–7 documents, and WordStar
|
|
25
33
|
**print-to-disk files** (the printer byte stream, captured to a file — a distinct
|
|
26
|
-
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (
|
|
27
|
-
built-in
|
|
34
|
+
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (set on a
|
|
35
|
+
viewer's built-in base-14 fonts — no dependencies, nothing embedded, the page as it would have
|
|
36
|
+
printed: printed mode follows the document's own font blocks *and its own layout
|
|
37
|
+
arithmetic* — the `.lh` in force on each line, and each span placed at the
|
|
38
|
+
per-character advance the file's font blocks declare — while modern mode is the
|
|
39
|
+
same document reflowed for today: its fonts carried, footnotes at the page
|
|
40
|
+
bottom, fontless text in a comfortable reading serif).
|
|
28
41
|
|
|
29
42
|
```console
|
|
30
|
-
$ ctrl-kd ESSAY.WS # -> ESSAY.
|
|
43
|
+
$ ctrl-kd ESSAY.WS # -> ESSAY.rtf: modern reflow, the
|
|
44
|
+
# document's own fonts carried
|
|
45
|
+
$ ctrl-kd --mode printed LETTER.WS # -> LETTER.pdf: the 1990 facsimile
|
|
46
|
+
$ ctrl-kd ESSAY.WS -t md # modern markdown instead
|
|
31
47
|
$ ctrl-kd ESSAY.WS -t html -t rtf # multiple formats
|
|
32
|
-
$ ctrl-kd
|
|
33
|
-
$ ctrl-kd --mode printed LETTER.WS # line-for-line, as it printed in 1990
|
|
48
|
+
$ ctrl-kd --page-settings sawyer X.WS # a known machine's page defaults
|
|
34
49
|
$ ctrl-kd --diagnose MYSTERY.FIL # what IS this file?
|
|
35
50
|
$ ctrl-kd --comments MEMO.WS # include the author's hidden comments
|
|
36
51
|
$ ctrl-kd --no-notes PAPER.WS # body text only, no notes
|
|
@@ -84,16 +99,30 @@ against surviving period printouts of the same documents. Its rules are empirica
|
|
|
84
99
|
breaks — a soft return is where the line broke on paper, so printed output
|
|
85
100
|
keeps it (and reflowed Modern output still joins it). `--diagnose` says
|
|
86
101
|
whether each figure came from the file or from the default.
|
|
102
|
+
`.lh` is **stateful**: it applies from where it appears, so a document that
|
|
103
|
+
changes leading around its headings gets each line's own lead (page capacity
|
|
104
|
+
still uses the document default — see `pdf._printed_cap`). Horizontally,
|
|
105
|
+
printed mode places every span at the per-character advance (HMI, 1/1800in)
|
|
106
|
+
the document's own font blocks declare, scaling a proportional face onto
|
|
107
|
+
that grid with the Adobe Core 14 glyph metrics (`ctrlkd.afm`) — still no
|
|
108
|
+
dependencies, still nothing embedded.
|
|
87
109
|
In `printed` mode footnotes are laid out the way WordStar laid them out: at
|
|
88
110
|
the foot of the page that references them, behind a twenty-dash separator,
|
|
89
111
|
split across pages with `...Continued...` when they do not fit.
|
|
90
112
|
|
|
91
113
|
## Modes
|
|
92
114
|
|
|
93
|
-
* `--mode modern` (default):
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
* `--mode modern` (default; bare runs produce RTF): the document brought to a
|
|
116
|
+
modern audience — reflowed, its own fonts and styles carried, footnotes at
|
|
117
|
+
the page bottom, gaps the file never specified filled with today's
|
|
118
|
+
conventions (a comfortable serif at reading size, one-inch margins).
|
|
119
|
+
* `--mode printed` (bare runs produce PDF): every line as laid out, on the
|
|
120
|
+
era's own page — how it came off the printer. Gaps are filled with 1990's
|
|
121
|
+
conventions instead; `--page-settings` supplies a particular machine's.
|
|
122
|
+
|
|
123
|
+
Version coverage, known limitations (WordStar 6's bare `.pl`, WordStar 3
|
|
124
|
+
status), and how behaviour gets verified: **[FAQ.md](FAQ.md)**, with the
|
|
125
|
+
technical account in **[ERAS.md](ERAS.md)**.
|
|
97
126
|
|
|
98
127
|
## Install
|
|
99
128
|
|
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
# ctrl-kd
|
|
2
2
|
|
|
3
|
+
```
|
|
4
|
+
__ __ __ __
|
|
5
|
+
_____/ /______/ / / /______/ /
|
|
6
|
+
/ ___/ __/ ___/ /_____/ //_/ __ /
|
|
7
|
+
/ /__/ /_/ / / /_____/ ,< / /_/ /
|
|
8
|
+
\___/\__/_/ /_/ /_/|_|\__,_/
|
|
9
|
+
```
|
|
10
|
+
|
|
3
11
|
Convert WordStar-era files to modern formats. **^KD: save and done.**
|
|
4
12
|
|
|
5
13
|
`ctrl-kd` reads WordStar 4 documents, WordStar 5–7 documents, and WordStar
|
|
6
14
|
**print-to-disk files** (the printer byte stream, captured to a file — a distinct
|
|
7
|
-
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (
|
|
8
|
-
built-in
|
|
15
|
+
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (set on a
|
|
16
|
+
viewer's built-in base-14 fonts — no dependencies, nothing embedded, the page as it would have
|
|
17
|
+
printed: printed mode follows the document's own font blocks *and its own layout
|
|
18
|
+
arithmetic* — the `.lh` in force on each line, and each span placed at the
|
|
19
|
+
per-character advance the file's font blocks declare — while modern mode is the
|
|
20
|
+
same document reflowed for today: its fonts carried, footnotes at the page
|
|
21
|
+
bottom, fontless text in a comfortable reading serif).
|
|
9
22
|
|
|
10
23
|
```console
|
|
11
|
-
$ ctrl-kd ESSAY.WS # -> ESSAY.
|
|
24
|
+
$ ctrl-kd ESSAY.WS # -> ESSAY.rtf: modern reflow, the
|
|
25
|
+
# document's own fonts carried
|
|
26
|
+
$ ctrl-kd --mode printed LETTER.WS # -> LETTER.pdf: the 1990 facsimile
|
|
27
|
+
$ ctrl-kd ESSAY.WS -t md # modern markdown instead
|
|
12
28
|
$ ctrl-kd ESSAY.WS -t html -t rtf # multiple formats
|
|
13
|
-
$ ctrl-kd
|
|
14
|
-
$ ctrl-kd --mode printed LETTER.WS # line-for-line, as it printed in 1990
|
|
29
|
+
$ ctrl-kd --page-settings sawyer X.WS # a known machine's page defaults
|
|
15
30
|
$ ctrl-kd --diagnose MYSTERY.FIL # what IS this file?
|
|
16
31
|
$ ctrl-kd --comments MEMO.WS # include the author's hidden comments
|
|
17
32
|
$ ctrl-kd --no-notes PAPER.WS # body text only, no notes
|
|
@@ -65,16 +80,30 @@ against surviving period printouts of the same documents. Its rules are empirica
|
|
|
65
80
|
breaks — a soft return is where the line broke on paper, so printed output
|
|
66
81
|
keeps it (and reflowed Modern output still joins it). `--diagnose` says
|
|
67
82
|
whether each figure came from the file or from the default.
|
|
83
|
+
`.lh` is **stateful**: it applies from where it appears, so a document that
|
|
84
|
+
changes leading around its headings gets each line's own lead (page capacity
|
|
85
|
+
still uses the document default — see `pdf._printed_cap`). Horizontally,
|
|
86
|
+
printed mode places every span at the per-character advance (HMI, 1/1800in)
|
|
87
|
+
the document's own font blocks declare, scaling a proportional face onto
|
|
88
|
+
that grid with the Adobe Core 14 glyph metrics (`ctrlkd.afm`) — still no
|
|
89
|
+
dependencies, still nothing embedded.
|
|
68
90
|
In `printed` mode footnotes are laid out the way WordStar laid them out: at
|
|
69
91
|
the foot of the page that references them, behind a twenty-dash separator,
|
|
70
92
|
split across pages with `...Continued...` when they do not fit.
|
|
71
93
|
|
|
72
94
|
## Modes
|
|
73
95
|
|
|
74
|
-
* `--mode modern` (default):
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
96
|
+
* `--mode modern` (default; bare runs produce RTF): the document brought to a
|
|
97
|
+
modern audience — reflowed, its own fonts and styles carried, footnotes at
|
|
98
|
+
the page bottom, gaps the file never specified filled with today's
|
|
99
|
+
conventions (a comfortable serif at reading size, one-inch margins).
|
|
100
|
+
* `--mode printed` (bare runs produce PDF): every line as laid out, on the
|
|
101
|
+
era's own page — how it came off the printer. Gaps are filled with 1990's
|
|
102
|
+
conventions instead; `--page-settings` supplies a particular machine's.
|
|
103
|
+
|
|
104
|
+
Version coverage, known limitations (WordStar 6's bare `.pl`, WordStar 3
|
|
105
|
+
status), and how behaviour gets verified: **[FAQ.md](FAQ.md)**, with the
|
|
106
|
+
technical account in **[ERAS.md](ERAS.md)**.
|
|
78
107
|
|
|
79
108
|
## Install
|
|
80
109
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ctrl-kd"
|
|
7
|
-
|
|
7
|
+
dynamic = ["version"]
|
|
8
8
|
description = "Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -28,3 +28,9 @@ ctrl-kd = "ctrlkd.cli:main"
|
|
|
28
28
|
|
|
29
29
|
[tool.setuptools.packages.find]
|
|
30
30
|
where = ["src"]
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.dynamic]
|
|
33
|
+
# single source of truth: src/ctrlkd/__init__.py __version__ -- the 4.0.0
|
|
34
|
+
# release shipped with pyproject still saying 3.0.0 because the version
|
|
35
|
+
# lived in two places and the bump hit one (2026-08-06); never again
|
|
36
|
+
version = {attr = "ctrlkd.__version__"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctrl-kd
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0
|
|
4
4
|
Summary: Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done.
|
|
5
5
|
Author: Jon Michaels
|
|
6
6
|
License: MIT
|
|
@@ -19,18 +19,33 @@ Dynamic: license-file
|
|
|
19
19
|
|
|
20
20
|
# ctrl-kd
|
|
21
21
|
|
|
22
|
+
```
|
|
23
|
+
__ __ __ __
|
|
24
|
+
_____/ /______/ / / /______/ /
|
|
25
|
+
/ ___/ __/ ___/ /_____/ //_/ __ /
|
|
26
|
+
/ /__/ /_/ / / /_____/ ,< / /_/ /
|
|
27
|
+
\___/\__/_/ /_/ /_/|_|\__,_/
|
|
28
|
+
```
|
|
29
|
+
|
|
22
30
|
Convert WordStar-era files to modern formats. **^KD: save and done.**
|
|
23
31
|
|
|
24
32
|
`ctrl-kd` reads WordStar 4 documents, WordStar 5–7 documents, and WordStar
|
|
25
33
|
**print-to-disk files** (the printer byte stream, captured to a file — a distinct
|
|
26
|
-
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (
|
|
27
|
-
built-in
|
|
34
|
+
format most converters mangle), and writes plain text, Markdown, HTML, RTF, or PDF (set on a
|
|
35
|
+
viewer's built-in base-14 fonts — no dependencies, nothing embedded, the page as it would have
|
|
36
|
+
printed: printed mode follows the document's own font blocks *and its own layout
|
|
37
|
+
arithmetic* — the `.lh` in force on each line, and each span placed at the
|
|
38
|
+
per-character advance the file's font blocks declare — while modern mode is the
|
|
39
|
+
same document reflowed for today: its fonts carried, footnotes at the page
|
|
40
|
+
bottom, fontless text in a comfortable reading serif).
|
|
28
41
|
|
|
29
42
|
```console
|
|
30
|
-
$ ctrl-kd ESSAY.WS # -> ESSAY.
|
|
43
|
+
$ ctrl-kd ESSAY.WS # -> ESSAY.rtf: modern reflow, the
|
|
44
|
+
# document's own fonts carried
|
|
45
|
+
$ ctrl-kd --mode printed LETTER.WS # -> LETTER.pdf: the 1990 facsimile
|
|
46
|
+
$ ctrl-kd ESSAY.WS -t md # modern markdown instead
|
|
31
47
|
$ ctrl-kd ESSAY.WS -t html -t rtf # multiple formats
|
|
32
|
-
$ ctrl-kd
|
|
33
|
-
$ ctrl-kd --mode printed LETTER.WS # line-for-line, as it printed in 1990
|
|
48
|
+
$ ctrl-kd --page-settings sawyer X.WS # a known machine's page defaults
|
|
34
49
|
$ ctrl-kd --diagnose MYSTERY.FIL # what IS this file?
|
|
35
50
|
$ ctrl-kd --comments MEMO.WS # include the author's hidden comments
|
|
36
51
|
$ ctrl-kd --no-notes PAPER.WS # body text only, no notes
|
|
@@ -84,16 +99,30 @@ against surviving period printouts of the same documents. Its rules are empirica
|
|
|
84
99
|
breaks — a soft return is where the line broke on paper, so printed output
|
|
85
100
|
keeps it (and reflowed Modern output still joins it). `--diagnose` says
|
|
86
101
|
whether each figure came from the file or from the default.
|
|
102
|
+
`.lh` is **stateful**: it applies from where it appears, so a document that
|
|
103
|
+
changes leading around its headings gets each line's own lead (page capacity
|
|
104
|
+
still uses the document default — see `pdf._printed_cap`). Horizontally,
|
|
105
|
+
printed mode places every span at the per-character advance (HMI, 1/1800in)
|
|
106
|
+
the document's own font blocks declare, scaling a proportional face onto
|
|
107
|
+
that grid with the Adobe Core 14 glyph metrics (`ctrlkd.afm`) — still no
|
|
108
|
+
dependencies, still nothing embedded.
|
|
87
109
|
In `printed` mode footnotes are laid out the way WordStar laid them out: at
|
|
88
110
|
the foot of the page that references them, behind a twenty-dash separator,
|
|
89
111
|
split across pages with `...Continued...` when they do not fit.
|
|
90
112
|
|
|
91
113
|
## Modes
|
|
92
114
|
|
|
93
|
-
* `--mode modern` (default):
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
* `--mode modern` (default; bare runs produce RTF): the document brought to a
|
|
116
|
+
modern audience — reflowed, its own fonts and styles carried, footnotes at
|
|
117
|
+
the page bottom, gaps the file never specified filled with today's
|
|
118
|
+
conventions (a comfortable serif at reading size, one-inch margins).
|
|
119
|
+
* `--mode printed` (bare runs produce PDF): every line as laid out, on the
|
|
120
|
+
era's own page — how it came off the printer. Gaps are filled with 1990's
|
|
121
|
+
conventions instead; `--page-settings` supplies a particular machine's.
|
|
122
|
+
|
|
123
|
+
Version coverage, known limitations (WordStar 6's bare `.pl`, WordStar 3
|
|
124
|
+
status), and how behaviour gets verified: **[FAQ.md](FAQ.md)**, with the
|
|
125
|
+
technical account in **[ERAS.md](ERAS.md)**.
|
|
97
126
|
|
|
98
127
|
## Install
|
|
99
128
|
|
|
@@ -7,9 +7,19 @@ src/ctrl_kd.egg-info/dependency_links.txt
|
|
|
7
7
|
src/ctrl_kd.egg-info/entry_points.txt
|
|
8
8
|
src/ctrl_kd.egg-info/top_level.txt
|
|
9
9
|
src/ctrlkd/__init__.py
|
|
10
|
+
src/ctrlkd/afm.py
|
|
10
11
|
src/ctrlkd/cli.py
|
|
11
12
|
src/ctrlkd/convert.py
|
|
12
13
|
src/ctrlkd/core.py
|
|
13
14
|
src/ctrlkd/emit.py
|
|
15
|
+
src/ctrlkd/fontmap.py
|
|
16
|
+
src/ctrlkd/info.py
|
|
17
|
+
src/ctrlkd/layout.py
|
|
14
18
|
src/ctrlkd/pdf.py
|
|
15
|
-
|
|
19
|
+
src/ctrlkd/symbolmap.py
|
|
20
|
+
src/ctrlkd/typestyles.py
|
|
21
|
+
src/ctrlkd/writer.py
|
|
22
|
+
src/ctrlkd/wschange.py
|
|
23
|
+
tests/test_ctrlkd.py
|
|
24
|
+
tests/test_writer.py
|
|
25
|
+
tests/test_wschange.py
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""ctrl-kd — convert WordStar-era files to modern formats. ^KD: save and done."""
|
|
2
2
|
from .core import (detect, parse, parse_ws, parse_printstream, merged_lines,
|
|
3
|
-
Document, Block, Line, Span)
|
|
3
|
+
Document, Block, Line, Span, ParseError)
|
|
4
4
|
from .emit import (emit_text, emit_markdown, emit_html, emit_rtf,
|
|
5
5
|
emitter, get_emitter, formats, load_plugins)
|
|
6
|
+
from .layout import modern_flow, emit_layout # registers the 'layout' format
|
|
6
7
|
from .pdf import emit_pdf # registers the 'pdf' format
|
|
7
8
|
from .convert import convert, select_notes, DEFAULT_NOTE_KINDS, ALL_NOTE_KINDS
|
|
9
|
+
from .info import document_info
|
|
8
10
|
|
|
9
|
-
__version__ = '
|
|
11
|
+
__version__ = '4.0.0'
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"""ctrl-kd — glyph widths for the PDF base-14, as data.
|
|
2
|
+
|
|
3
|
+
WHY THIS EXISTS
|
|
4
|
+
---------------
|
|
5
|
+
Printed mode positions every span at WordStar's own x (pdf.py's HMI
|
|
6
|
+
arithmetic: each font block declares a per-character advance in 1/1800in,
|
|
7
|
+
and that number IS the grid the document was laid out on). Courier lands on
|
|
8
|
+
that grid by construction. A PROPORTIONAL face does not: Times at 12pt sets
|
|
9
|
+
"Chapter One" in whatever width Times happens to want, which is not the width
|
|
10
|
+
WordStar reserved, so the following span would start in the wrong place --
|
|
11
|
+
or, on a 72pt banner, run clean off the paper.
|
|
12
|
+
|
|
13
|
+
The fix needs one number this emitter never had: how wide a string actually
|
|
14
|
+
is in the face it is set in. That is what these tables are.
|
|
15
|
+
|
|
16
|
+
SOURCE
|
|
17
|
+
------
|
|
18
|
+
Adobe's Core 14 AFM metrics -- the font metrics Adobe publishes for the 14
|
|
19
|
+
fonts every PDF viewer must provide, freely redistributable and the reason
|
|
20
|
+
this project can typeset in them without embedding anything. Widths are
|
|
21
|
+
INTEGER units of 1/1000 em, exactly as the AFM files state them; nothing here
|
|
22
|
+
is measured, estimated or scaled. They are numbers, transcribed as data.
|
|
23
|
+
|
|
24
|
+
(Transcribed via the URW base-35 AFMs, which are metric-compatible clones of
|
|
25
|
+
the same faces by construction -- Helvetica A=667 space=278, Times A=722
|
|
26
|
+
space=250, Courier 600 throughout, matching Adobe's published tables.)
|
|
27
|
+
|
|
28
|
+
ENCODING
|
|
29
|
+
--------
|
|
30
|
+
One 256-entry tuple per face, indexed by BYTE VALUE, because that is what
|
|
31
|
+
pdf.py writes: it encodes text as Latin-1 (`_esc`). For the text faces the
|
|
32
|
+
table is built over Latin-1 glyph names, which over 0xA0-0xFF are exactly
|
|
33
|
+
WinAnsiEncoding's. For Symbol and ZapfDingbats it is built over the font's
|
|
34
|
+
OWN encoding -- the codes pdf.py deliberately writes back via
|
|
35
|
+
symbolmap.untransliterate, so a Symbol 'a' really is alpha and really is
|
|
36
|
+
631/1000 wide.
|
|
37
|
+
|
|
38
|
+
(Since 2026-08-05 the text font objects declare /Encoding /WinAnsiEncoding
|
|
39
|
+
and pdf._esc writes cp1252, so bytes, glyphs and these widths agree over the
|
|
40
|
+
whole range -- including the 0x80-0x9F typographic row, overlaid onto the
|
|
41
|
+
Latin-1-named base tables below. The decision this paragraph used to defer
|
|
42
|
+
was made, and the digest pins re-taken with it.)
|
|
43
|
+
|
|
44
|
+
A code with no glyph in a face gets 0. Callers must treat a zero-width string
|
|
45
|
+
as "no metric available" rather than dividing by it (pdf.py does).
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
_HELVETICA = (
|
|
49
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
50
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
51
|
+
278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278,
|
|
52
|
+
556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556,
|
|
53
|
+
1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778,
|
|
54
|
+
667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556,
|
|
55
|
+
333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556,
|
|
56
|
+
556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 0,
|
|
57
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
58
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
59
|
+
278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333,
|
|
60
|
+
400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611,
|
|
61
|
+
667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278,
|
|
62
|
+
722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611,
|
|
63
|
+
556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278,
|
|
64
|
+
556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
_HELVETICA_BOLD = (
|
|
68
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
69
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
70
|
+
278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278,
|
|
71
|
+
556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611,
|
|
72
|
+
975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778,
|
|
73
|
+
667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556,
|
|
74
|
+
333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611,
|
|
75
|
+
611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 0,
|
|
76
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
77
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
78
|
+
278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333,
|
|
79
|
+
400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611,
|
|
80
|
+
722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278,
|
|
81
|
+
722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611,
|
|
82
|
+
556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278,
|
|
83
|
+
611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
_HELVETICA_OBLIQUE = (
|
|
87
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
88
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
89
|
+
278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278,
|
|
90
|
+
556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556,
|
|
91
|
+
1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778,
|
|
92
|
+
667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556,
|
|
93
|
+
333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556,
|
|
94
|
+
556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 0,
|
|
95
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
96
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
97
|
+
278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333,
|
|
98
|
+
400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611,
|
|
99
|
+
667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278,
|
|
100
|
+
722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611,
|
|
101
|
+
556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278,
|
|
102
|
+
556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
_HELVETICA_BOLDOBLIQUE = (
|
|
106
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
107
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
108
|
+
278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278,
|
|
109
|
+
556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611,
|
|
110
|
+
975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778,
|
|
111
|
+
667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556,
|
|
112
|
+
333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611,
|
|
113
|
+
611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 0,
|
|
114
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
115
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
116
|
+
278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333,
|
|
117
|
+
400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611,
|
|
118
|
+
722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278,
|
|
119
|
+
722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611,
|
|
120
|
+
556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278,
|
|
121
|
+
611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
_TIMES_ROMAN = (
|
|
125
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
126
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
127
|
+
250, 333, 408, 500, 500, 833, 778, 180, 333, 333, 500, 564, 250, 333, 250, 278,
|
|
128
|
+
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444,
|
|
129
|
+
921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722,
|
|
130
|
+
556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500,
|
|
131
|
+
333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500,
|
|
132
|
+
500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 0,
|
|
133
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
134
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
135
|
+
250, 333, 500, 500, 500, 500, 200, 500, 333, 760, 276, 500, 564, 333, 760, 333,
|
|
136
|
+
400, 564, 300, 300, 333, 500, 453, 250, 333, 300, 310, 500, 750, 750, 750, 444,
|
|
137
|
+
722, 722, 722, 722, 722, 722, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333,
|
|
138
|
+
722, 722, 722, 722, 722, 722, 722, 564, 722, 722, 722, 722, 722, 722, 556, 500,
|
|
139
|
+
444, 444, 444, 444, 444, 444, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278,
|
|
140
|
+
500, 500, 500, 500, 500, 500, 500, 564, 500, 500, 500, 500, 500, 500, 500, 500,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
_TIMES_BOLD = (
|
|
144
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
145
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
146
|
+
250, 333, 555, 500, 500, 1000, 833, 278, 333, 333, 500, 570, 250, 333, 250, 278,
|
|
147
|
+
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500,
|
|
148
|
+
930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778,
|
|
149
|
+
611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500,
|
|
150
|
+
333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500,
|
|
151
|
+
556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 0,
|
|
152
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
153
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
154
|
+
250, 333, 500, 500, 500, 500, 220, 500, 333, 747, 300, 500, 570, 333, 747, 333,
|
|
155
|
+
400, 570, 300, 300, 333, 556, 540, 250, 333, 300, 330, 500, 750, 750, 750, 500,
|
|
156
|
+
722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 389, 389, 389, 389,
|
|
157
|
+
722, 722, 778, 778, 778, 778, 778, 570, 778, 722, 722, 722, 722, 722, 611, 556,
|
|
158
|
+
500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278,
|
|
159
|
+
500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 500, 556, 500,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
_TIMES_ITALIC = (
|
|
163
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
164
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
165
|
+
250, 333, 420, 500, 500, 833, 778, 214, 333, 333, 500, 675, 250, 333, 250, 278,
|
|
166
|
+
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500,
|
|
167
|
+
920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722,
|
|
168
|
+
611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500,
|
|
169
|
+
333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500,
|
|
170
|
+
500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 0,
|
|
171
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
172
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
173
|
+
250, 389, 500, 500, 500, 500, 275, 500, 333, 760, 276, 500, 675, 333, 760, 333,
|
|
174
|
+
400, 675, 300, 300, 333, 500, 523, 250, 333, 300, 310, 500, 750, 750, 750, 500,
|
|
175
|
+
611, 611, 611, 611, 611, 611, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333,
|
|
176
|
+
722, 667, 722, 722, 722, 722, 722, 675, 722, 722, 722, 722, 722, 556, 611, 500,
|
|
177
|
+
500, 500, 500, 500, 500, 500, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278,
|
|
178
|
+
500, 500, 500, 500, 500, 500, 500, 675, 500, 500, 500, 500, 500, 444, 500, 444,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
_TIMES_BOLDITALIC = (
|
|
182
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
183
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
184
|
+
250, 389, 555, 500, 500, 833, 778, 278, 333, 333, 500, 570, 250, 333, 250, 278,
|
|
185
|
+
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500,
|
|
186
|
+
832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722,
|
|
187
|
+
611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500,
|
|
188
|
+
333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500,
|
|
189
|
+
500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 0,
|
|
190
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
191
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
192
|
+
250, 389, 500, 500, 500, 500, 220, 500, 333, 747, 266, 500, 606, 333, 747, 333,
|
|
193
|
+
400, 570, 300, 300, 333, 576, 500, 250, 333, 300, 300, 500, 750, 750, 750, 500,
|
|
194
|
+
667, 667, 667, 667, 667, 667, 944, 667, 667, 667, 667, 667, 389, 389, 389, 389,
|
|
195
|
+
722, 722, 722, 722, 722, 722, 722, 570, 722, 722, 722, 722, 722, 611, 611, 500,
|
|
196
|
+
500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278,
|
|
197
|
+
500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 444, 500, 444,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
_SYMBOL = (
|
|
201
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
202
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
203
|
+
250, 333, 713, 500, 549, 833, 778, 631, 333, 333, 500, 549, 250, 549, 250, 278,
|
|
204
|
+
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444,
|
|
205
|
+
549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722,
|
|
206
|
+
768, 741, 556, 592, 611, 690, 631, 768, 645, 795, 611, 333, 863, 333, 658, 500,
|
|
207
|
+
500, 631, 549, 549, 494, 631, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549,
|
|
208
|
+
549, 521, 549, 603, 631, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 0,
|
|
209
|
+
790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
210
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
211
|
+
750, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603,
|
|
212
|
+
400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658,
|
|
213
|
+
823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713,
|
|
214
|
+
768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603,
|
|
215
|
+
494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494,
|
|
216
|
+
0, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, 0,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
_ZAPFDINGBATS = (
|
|
220
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
221
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
222
|
+
278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933,
|
|
223
|
+
911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537,
|
|
224
|
+
577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831,
|
|
225
|
+
923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826,
|
|
226
|
+
815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762,
|
|
227
|
+
762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 0,
|
|
228
|
+
390, 390, 317, 317, 276, 276, 509, 509, 410, 410, 234, 234, 334, 334, 0, 0,
|
|
229
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
230
|
+
0, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788,
|
|
231
|
+
788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788,
|
|
232
|
+
788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788,
|
|
233
|
+
788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834,
|
|
234
|
+
873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874,
|
|
235
|
+
0, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, 0,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# Courier is monospaced at 600/1000 em in all four weights -- the AFM files
|
|
239
|
+
# say 600 for every glyph, including the ones the other faces do not have, so
|
|
240
|
+
# a table would be 1024 copies of one number. This is that number.
|
|
241
|
+
COURIER_WIDTH = 600
|
|
242
|
+
|
|
243
|
+
_COURIER = (COURIER_WIDTH,) * 256
|
|
244
|
+
|
|
245
|
+
# basefont name (the PDF /BaseFont, i.e. pdf.BASE14's own values) -> widths
|
|
246
|
+
# WinAnsiEncoding's 0x80-0x9F row -- the typographic range cp1252 adds over
|
|
247
|
+
# Latin-1 (curly quotes, en/em dashes, ellipsis, bullet, dagger, trademark,
|
|
248
|
+
# ligatures). The Latin-1-named base tables above carry 0 there; since
|
|
249
|
+
# pdf._esc writes cp1252 and the font objects declare /WinAnsiEncoding,
|
|
250
|
+
# these slots are real glyphs with real Adobe AFM widths. Slots WinAnsi
|
|
251
|
+
# leaves undefined (0x80 euro on the era's faces, 0x8D, 0x8F, 0x90, 0x9D)
|
|
252
|
+
# stay 0. Applied as an overlay so the hand-transcribed literals above stay
|
|
253
|
+
# exactly as the AFM files list them.
|
|
254
|
+
_WINANSI_HI = {
|
|
255
|
+
# sb₁ flo db₂ ell dag ddg cir pm Scn gsl OE ql qr dl dr bul en em til tm scn gsr oe Zcn zcn Ydi
|
|
256
|
+
'Helvetica': {0x82: 222, 0x83: 556, 0x84: 333, 0x85: 1000,
|
|
257
|
+
0x86: 556, 0x87: 556, 0x88: 333, 0x89: 1000, 0x8A: 667, 0x8B: 333,
|
|
258
|
+
0x8C: 1000, 0x8E: 611, 0x91: 222, 0x92: 222, 0x93: 333, 0x94: 333,
|
|
259
|
+
0x95: 350, 0x96: 556, 0x97: 1000, 0x98: 333, 0x99: 1000, 0x9A: 500,
|
|
260
|
+
0x9B: 333, 0x9C: 944, 0x9E: 500, 0x9F: 667},
|
|
261
|
+
'Helvetica-Bold': {0x82: 278, 0x83: 556, 0x84: 500, 0x85: 1000,
|
|
262
|
+
0x86: 556, 0x87: 556, 0x88: 333, 0x89: 1000, 0x8A: 667, 0x8B: 333,
|
|
263
|
+
0x8C: 1000, 0x8E: 611, 0x91: 278, 0x92: 278, 0x93: 500, 0x94: 500,
|
|
264
|
+
0x95: 350, 0x96: 556, 0x97: 1000, 0x98: 333, 0x99: 1000, 0x9A: 556,
|
|
265
|
+
0x9B: 333, 0x9C: 944, 0x9E: 500, 0x9F: 667},
|
|
266
|
+
'Times-Roman': {0x82: 333, 0x83: 500, 0x84: 444, 0x85: 1000,
|
|
267
|
+
0x86: 500, 0x87: 500, 0x88: 333, 0x89: 1000, 0x8A: 556, 0x8B: 333,
|
|
268
|
+
0x8C: 889, 0x8E: 611, 0x91: 333, 0x92: 333, 0x93: 444, 0x94: 444,
|
|
269
|
+
0x95: 350, 0x96: 500, 0x97: 1000, 0x98: 333, 0x99: 980, 0x9A: 389,
|
|
270
|
+
0x9B: 333, 0x9C: 722, 0x9E: 444, 0x9F: 722},
|
|
271
|
+
'Times-Bold': {0x82: 333, 0x83: 500, 0x84: 500, 0x85: 1000,
|
|
272
|
+
0x86: 500, 0x87: 500, 0x88: 333, 0x89: 1000, 0x8A: 556, 0x8B: 333,
|
|
273
|
+
0x8C: 1000, 0x8E: 667, 0x91: 333, 0x92: 333, 0x93: 500, 0x94: 500,
|
|
274
|
+
0x95: 350, 0x96: 500, 0x97: 1000, 0x98: 333, 0x99: 1000, 0x9A: 389,
|
|
275
|
+
0x9B: 333, 0x9C: 722, 0x9E: 444, 0x9F: 722},
|
|
276
|
+
'Times-Italic': {0x82: 333, 0x83: 500, 0x84: 556, 0x85: 889,
|
|
277
|
+
0x86: 500, 0x87: 500, 0x88: 333, 0x89: 1000, 0x8A: 500, 0x8B: 333,
|
|
278
|
+
0x8C: 944, 0x8E: 556, 0x91: 333, 0x92: 333, 0x93: 556, 0x94: 556,
|
|
279
|
+
0x95: 350, 0x96: 500, 0x97: 889, 0x98: 333, 0x99: 980, 0x9A: 389,
|
|
280
|
+
0x9B: 333, 0x9C: 667, 0x9E: 389, 0x9F: 556},
|
|
281
|
+
'Times-BoldItalic': {0x82: 333, 0x83: 500, 0x84: 500, 0x85: 1000,
|
|
282
|
+
0x86: 500, 0x87: 500, 0x88: 333, 0x89: 1000, 0x8A: 556, 0x8B: 333,
|
|
283
|
+
0x8C: 944, 0x8E: 611, 0x91: 333, 0x92: 333, 0x93: 500, 0x94: 500,
|
|
284
|
+
0x95: 350, 0x96: 500, 0x97: 1000, 0x98: 333, 0x99: 1000, 0x9A: 389,
|
|
285
|
+
0x9B: 333, 0x9C: 722, 0x9E: 389, 0x9F: 611},
|
|
286
|
+
}
|
|
287
|
+
_WINANSI_HI['Helvetica-Oblique'] = _WINANSI_HI['Helvetica']
|
|
288
|
+
_WINANSI_HI['Helvetica-BoldOblique'] = _WINANSI_HI['Helvetica-Bold']
|
|
289
|
+
_COURIER_HI = {k: 600 for k in _WINANSI_HI['Helvetica']}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _overlay(base, hi):
|
|
293
|
+
t = list(base)
|
|
294
|
+
for k, v in hi.items():
|
|
295
|
+
t[k] = v
|
|
296
|
+
return tuple(t)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
WIDTHS = {
|
|
300
|
+
'Courier': _overlay(_COURIER, _COURIER_HI),
|
|
301
|
+
'Courier-Bold': _overlay(_COURIER, _COURIER_HI),
|
|
302
|
+
'Courier-Oblique': _overlay(_COURIER, _COURIER_HI),
|
|
303
|
+
'Courier-BoldOblique': _overlay(_COURIER, _COURIER_HI),
|
|
304
|
+
'Helvetica': _overlay(_HELVETICA, _WINANSI_HI['Helvetica']),
|
|
305
|
+
'Helvetica-Bold': _overlay(_HELVETICA_BOLD, _WINANSI_HI['Helvetica-Bold']),
|
|
306
|
+
'Helvetica-Oblique': _overlay(_HELVETICA_OBLIQUE,
|
|
307
|
+
_WINANSI_HI['Helvetica-Oblique']),
|
|
308
|
+
'Helvetica-BoldOblique': _overlay(_HELVETICA_BOLDOBLIQUE,
|
|
309
|
+
_WINANSI_HI['Helvetica-BoldOblique']),
|
|
310
|
+
'Times-Roman': _overlay(_TIMES_ROMAN, _WINANSI_HI['Times-Roman']),
|
|
311
|
+
'Times-Bold': _overlay(_TIMES_BOLD, _WINANSI_HI['Times-Bold']),
|
|
312
|
+
'Times-Italic': _overlay(_TIMES_ITALIC, _WINANSI_HI['Times-Italic']),
|
|
313
|
+
'Times-BoldItalic': _overlay(_TIMES_BOLDITALIC,
|
|
314
|
+
_WINANSI_HI['Times-BoldItalic']),
|
|
315
|
+
'Symbol': _SYMBOL,
|
|
316
|
+
'ZapfDingbats': _ZAPFDINGBATS,
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def string_width_1000(text, basefont):
|
|
321
|
+
"""Natural width of `text` set in `basefont`, in 1/1000 em.
|
|
322
|
+
|
|
323
|
+
`text` is measured as pdf.py will WRITE it -- encoded cp1252 (the
|
|
324
|
+
declared /WinAnsiEncoding), with anything outside that repertoire
|
|
325
|
+
replaced by '?', which is exactly what `pdf._esc` does. Measuring the
|
|
326
|
+
str directly would count a character the PDF never receives.
|
|
327
|
+
|
|
328
|
+
An unknown basefont falls back to Courier's fixed 600: a face this table
|
|
329
|
+
does not carry cannot be measured, and 600 is this emitter's own default
|
|
330
|
+
pitch, not a guess at the missing face."""
|
|
331
|
+
table = WIDTHS.get(basefont, _COURIER)
|
|
332
|
+
return sum(table[b] for b in text.encode('cp1252', 'replace'))
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def string_width_pt(text, basefont, size):
|
|
336
|
+
"""Natural width of `text` in POINTS at `size`."""
|
|
337
|
+
return string_width_1000(text, basefont) * size / 1000.0
|