1
|
/*
|
2
|
** This program is free software: you can redistribute it and/or modify
|
3
|
** it under the terms of the GNU Affero General Public License as
|
4
|
** published by the Free Software Foundation, either version 3 of the
|
5
|
** License, or (at your option) any later version.
|
6
|
**
|
7
|
** This program is distributed in the hope that it will be useful,
|
8
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
** GNU Affero General Public License for more details.
|
11
|
**
|
12
|
** You may find a copy of the GNU Affero GPL version 3 at the following
|
13
|
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
|
14
|
**
|
15
|
** Additional terms under GNU Affero GPL version 3 section 7:
|
16
|
**
|
17
|
** Under Section 7 of the GNU Affero GPL version 3, the following additional
|
18
|
** terms apply to the works covered under the License. These additional terms
|
19
|
** are non-permissive additional terms allowed under Section 7 of the GNU
|
20
|
** Affero GPL version 3 and may not be removed by you.
|
21
|
**
|
22
|
** 0. Attribution Requirement.
|
23
|
**
|
24
|
** You must preserve all legal notices or author attributions in the covered
|
25
|
** work or Appropriate Legal Notices displayed by works containing the covered
|
26
|
** work. You may not remove from the covered work any author or developer
|
27
|
** credit already included within the covered work.
|
28
|
**
|
29
|
** 1. No License To Use Trademarks.
|
30
|
**
|
31
|
** This license does not grant any license or rights to use the trademarks
|
32
|
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
|
33
|
** of Golden Code Development Corporation. You are not authorized to use the
|
34
|
** name Golden Code, FWD, or the names of any author or contributor, for
|
35
|
** publicity purposes without written authorization.
|
36
|
**
|
37
|
** 2. No Misrepresentation of Affiliation.
|
38
|
**
|
39
|
** You may not represent yourself as Golden Code Development Corporation or FWD.
|
40
|
**
|
41
|
** You may not represent yourself for publicity purposes as associated with
|
42
|
** Golden Code Development Corporation, FWD, or any author or contributor to
|
43
|
** the covered work, without written authorization.
|
44
|
**
|
45
|
** 3. No Misrepresentation of Source or Origin.
|
46
|
**
|
47
|
** You may not represent the covered work as solely your work. All modified
|
48
|
** versions of the covered work must be marked in a reasonable way to make it
|
49
|
** clear that the modified work is not originating from Golden Code Development
|
50
|
** Corporation or FWD. All modified versions must contain the notices of
|
51
|
** attribution required in this license.
|
52
|
*/
|
53
|
/*
|
54
|
Each line in the font file has this format: name,size,bold,italic,underline.
|
55
|
where:".
|
56
|
- name: is the font name (case insensitive)
|
57
|
- size: is the font size for which metrics will be captured, integer. if not specified, metrics from 1 to maxSize are captured
|
58
|
- bold: true if the bold metrics are captured. false otherwise
|
59
|
- italic: true if the italic metrics are captured. false otherwise
|
60
|
- underline: true if the underline metrics are captured. false otherwise
|
61
|
|
62
|
If any of the bold/italic/underline flags are missing, metrics for all combinations of flag set/unset are captured.
|
63
|
*/
|
64
|
|
65
|
def var maxSize as int init 20.
|
66
|
def stream fnames.
|
67
|
def stream frpt.
|
68
|
def var showdpiwarning as log init true.
|
69
|
def var asXml as log init true.
|
70
|
def var fontFile as char init "font-list.txt".
|
71
|
|
72
|
message "Enter the maximum font size (<= 1638):" update maxSize.
|
73
|
message "Enter the file name with the font list:" update fontFile format "x(32)".
|
74
|
|
75
|
file-info:file-name = fontFile.
|
76
|
if file-info:file-type = ? then do:
|
77
|
message "File" fontFile "does not exist or is not accessible".
|
78
|
return.
|
79
|
end.
|
80
|
|
81
|
procedure CreateFontIndirectA external "gdi32".
|
82
|
def input param lplf as long.
|
83
|
def return param hfont as long.
|
84
|
end.
|
85
|
|
86
|
procedure DeleteObject external "gdi32".
|
87
|
def input param hgdiobj as long.
|
88
|
def return param res as long.
|
89
|
end.
|
90
|
|
91
|
procedure SelectObject external "gdi32".
|
92
|
def input param hdc as long.
|
93
|
def input param hgdiobj as long.
|
94
|
def return param res as long.
|
95
|
end.
|
96
|
|
97
|
procedure GetTextMetricsA external "gdi32".
|
98
|
def input param hdc as long.
|
99
|
def input param lptm as long.
|
100
|
def return param returnvalue as long.
|
101
|
end.
|
102
|
|
103
|
procedure GetDC external "user32.dll".
|
104
|
def input param ihwnd as long.
|
105
|
def return param hdc as long.
|
106
|
end.
|
107
|
|
108
|
procedure ReleaseDC external "user32.dll".
|
109
|
def input param ihwnd as long.
|
110
|
def input param hdc as long.
|
111
|
def return param res as long.
|
112
|
end.
|
113
|
|
114
|
procedure GetDeviceCaps external "gdi32".
|
115
|
def input param hdc as long.
|
116
|
def input param nindex as long.
|
117
|
def return param res as long.
|
118
|
end.
|
119
|
|
120
|
procedure getMetrics.
|
121
|
def input param fontname as char.
|
122
|
def input param fontsize as int.
|
123
|
def input-output param lp as memptr.
|
124
|
def input param fbold as log.
|
125
|
def input param fitalic as log.
|
126
|
def input param funderline as log.
|
127
|
|
128
|
def var res as int.
|
129
|
def var hdc as integer.
|
130
|
def var dpi as int.
|
131
|
def var LOGPIXELSY as int init 90.
|
132
|
def var err as log init false.
|
133
|
|
134
|
run GetDc(input current-window:hwnd, output hdc).
|
135
|
|
136
|
/* get DPI */
|
137
|
run GetDeviceCaps(input hdc, input LOGPIXELSY, output dpi).
|
138
|
if showdpiwarning and dpi <> 96
|
139
|
then do:
|
140
|
message "DPI is" dpi "instead of 96!" view-as alert-box.
|
141
|
showdpiwarning = false.
|
142
|
end.
|
143
|
|
144
|
/* create font */
|
145
|
def var hfont as int64.
|
146
|
def var lplf as memptr.
|
147
|
set-size(lplf) = 5 * 4 + 8 * 1 + 1 * 32.
|
148
|
def var i as int.
|
149
|
do i = 1 to get-size(lplf):
|
150
|
put-byte(lplf, i) = 0.
|
151
|
end.
|
152
|
put-long(lplf, (1 - 1) * 4 + 1) = -1 * int64(round(fontsize * dpi / 72.0, 2)).
|
153
|
put-long(lplf, (5 - 1) * 4 + 1) = (if fbold then 700 else 0).
|
154
|
put-byte(lplf, 5 * 4 + 1) = (if fitalic then 1 else 0).
|
155
|
put-byte(lplf, 5 * 4 + 2) = (if funderline then 1 else 0).
|
156
|
put-string(lplf, 5 * 4 + 8 + 1) = fontname.
|
157
|
run CreateFontIndirectA(input get-pointer-value(lplf), output hfont).
|
158
|
|
159
|
/* select font */
|
160
|
def var foohdc as integer.
|
161
|
run SelectObject(input hdc, input hfont, output foohdc).
|
162
|
|
163
|
/* get metrics */
|
164
|
set-size(lp) = 15 * 4 + 5 + 10.
|
165
|
run GetTextMetricsA(input hdc, input get-pointer-value(lp), output res).
|
166
|
if res = 0 then err = yes.
|
167
|
|
168
|
/* delete hfont */
|
169
|
run DeleteObject(input hfont, output res).
|
170
|
if res = 0 then err = yes.
|
171
|
|
172
|
run ReleaseDC(input current-window:hwnd, input hdc, output res).
|
173
|
if res = 0 then err = yes.
|
174
|
|
175
|
/* delete the lplf */
|
176
|
set-size(lplf) = 0.
|
177
|
|
178
|
if err
|
179
|
then do:
|
180
|
message "GetTextMetrics failed for" fontname fontsize ". Memory leak?".
|
181
|
quit.
|
182
|
end.
|
183
|
|
184
|
end.
|
185
|
|
186
|
procedure recordMetrics.
|
187
|
def input param fname as char.
|
188
|
def input param sz as int.
|
189
|
def input param fbold as log.
|
190
|
def input param fitalic as log.
|
191
|
def input param funderline as log.
|
192
|
|
193
|
def var lp as memptr.
|
194
|
def var h as int.
|
195
|
def var avgWidth as int.
|
196
|
def var maxWidth as int.
|
197
|
|
198
|
run getMetrics(fname, sz, input-output lp, fbold, fitalic, funderline).
|
199
|
h = get-long(lp, 1).
|
200
|
avgWidth = get-long(lp, 5 * 4 + 1).
|
201
|
maxWidth = get-long(lp, 6 * 4 + 1).
|
202
|
|
203
|
if asXml then do:
|
204
|
put stream frpt unformatted space(3)
|
205
|
'<font name="' fname '" '
|
206
|
'size="' sz '" '
|
207
|
'bold="' trim(string(fbold, "true/false")) '" '
|
208
|
'italic="' trim(string(fitalic, "true/false")) '" '
|
209
|
'underline="' trim(string(funderline, "true/false")) '" '
|
210
|
'width="' avgWidth '" '
|
211
|
'max-width="' maxWidth '" '
|
212
|
'height="' h '"/>' skip.
|
213
|
end.
|
214
|
else do:
|
215
|
put stream frpt unformatted
|
216
|
fname space(1)
|
217
|
sz space(1)
|
218
|
trim(string(fbold, "true/false")) space(1)
|
219
|
trim(string(fitalic, "true/false")) space(1)
|
220
|
trim(string(funderline, "true/false")) space(1)
|
221
|
avgWidth space(1)
|
222
|
h skip.
|
223
|
end.
|
224
|
/* delete the lp */
|
225
|
set-size(lp) = 0.
|
226
|
end.
|
227
|
|
228
|
def var sz as int.
|
229
|
def var fname as char.
|
230
|
def var fxmlname as char.
|
231
|
fxmlname = (if asXml then "font-metrics.xml" else "font-metrics.csv").
|
232
|
|
233
|
form fname label "Font Name" sz label "Size" with frame fstate down.
|
234
|
|
235
|
output stream frpt to value(fxmlname).
|
236
|
input stream fnames from value(fontFile).
|
237
|
|
238
|
if asXml
|
239
|
then do:
|
240
|
put stream frpt unformatted '<?xml version="1.0" encoding="UTF-8"?>' skip.
|
241
|
put stream frpt unformatted '<!DOCTYPE font-list SYSTEM "font-metrics.dtd">' skip.
|
242
|
put stream frpt unformatted "<font-list>" skip.
|
243
|
end.
|
244
|
|
245
|
repeat:
|
246
|
def var fsize as int.
|
247
|
def var fbold as log.
|
248
|
def var fitalic as log.
|
249
|
def var funder as log.
|
250
|
|
251
|
fname = ?.
|
252
|
fsize = ?.
|
253
|
fbold = ?.
|
254
|
fitalic = ?.
|
255
|
funder = ?.
|
256
|
|
257
|
import stream fnames delimiter "," fname fsize fbold fitalic funder no-error.
|
258
|
if error-status:error then leave.
|
259
|
|
260
|
do sz = (if fsize = ? or fsize = 0 then 1 else fsize) to (if fsize = ? or fsize = 0 then maxSize else fsize):
|
261
|
display fname sz with frame fstate.
|
262
|
|
263
|
def var i as int.
|
264
|
do i = 1 to 8:
|
265
|
def var cbold as log.
|
266
|
def var citalic as log.
|
267
|
def var cunder as log.
|
268
|
|
269
|
cbold = (i > 4).
|
270
|
citalic = (i = 3 or i = 4 or i = 7 or i = 8).
|
271
|
cunder = i mod 2 = 0.
|
272
|
|
273
|
if (fbold = ? or fbold = cbold) and
|
274
|
(fitalic = ? or fitalic = citalic)and
|
275
|
(funder = ? or funder = cunder)
|
276
|
then run recordMetrics(fname, sz, cbold, citalic, cunder).
|
277
|
end.
|
278
|
end.
|
279
|
|
280
|
down 1 with frame fstate.
|
281
|
|
282
|
/* force a flush */
|
283
|
output stream frpt close.
|
284
|
output stream frpt to value(fxmlname) append.
|
285
|
end.
|
286
|
|
287
|
if asXml then put stream frpt unformatted "</font-list>" skip.
|
288
|
|
289
|
output stream frpt close.
|
290
|
input stream fnames close.
|
291
|
|
292
|
message "The metrics were captured in file:" fxmlname.
|