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 text file represents a text (case-sensitive) for which the metrics will be
|
55
|
captured. Metrics will be computed for each font in the font file (and combinations of its size
|
56
|
and attributes), each text being set one per line.
|
57
|
|
58
|
Each line in the font file has this format: name,size,bold,italic,underline.
|
59
|
where:".
|
60
|
- name: is the font name (case insensitive)
|
61
|
- size: is the font size, integer. if not specified, metrics for 1 to max-size are captured
|
62
|
- bold: true if the bold metrics are captured. false otherwise
|
63
|
- italic: true if the italic metrics are captured. false otherwise
|
64
|
- underline: true if the underline metrics are captured. false otherwise
|
65
|
|
66
|
If any of the bold/italic/underline flags are missing, metrics for flag set/unset are captured.
|
67
|
*/
|
68
|
|
69
|
def var maxSize as int init 20.
|
70
|
def stream fnames.
|
71
|
def stream flines.
|
72
|
def stream frpt.
|
73
|
def var showdpiwarning as log init true.
|
74
|
def var fontFile as char init "font-list.txt".
|
75
|
def var textFile as char init "ui_strings.txt".
|
76
|
|
77
|
message "Enter the maximum font size (<= 1638):" update maxSize.
|
78
|
message "Enter the file name with the font list:" update fontFile format "x(32)".
|
79
|
message "Enter the file name with the text list:" update textFile format "x(32)".
|
80
|
|
81
|
file-info:file-name = fontFile.
|
82
|
if file-info:file-type = ? then do:
|
83
|
message "File" fontFile "does not exist or is not accessible".
|
84
|
return.
|
85
|
end.
|
86
|
|
87
|
file-info:file-name = textFile.
|
88
|
if file-info:file-type = ? then do:
|
89
|
message "File" textFile "does not exist or is not accessible".
|
90
|
return.
|
91
|
end.
|
92
|
|
93
|
procedure CreateFontIndirectA external "gdi32".
|
94
|
def input param lplf as long.
|
95
|
def return param hfont as long.
|
96
|
end.
|
97
|
|
98
|
procedure DeleteObject external "gdi32".
|
99
|
def input param hgdiobj as long.
|
100
|
def return param res as long.
|
101
|
end.
|
102
|
|
103
|
procedure SelectObject external "gdi32".
|
104
|
def input param hdc as long.
|
105
|
def input param hgdiobj as long.
|
106
|
def return param res as long.
|
107
|
end.
|
108
|
|
109
|
procedure GetTextMetricsA external "gdi32".
|
110
|
def input param hdc as long.
|
111
|
def input param lptm as long.
|
112
|
def return param returnvalue as long.
|
113
|
end.
|
114
|
|
115
|
procedure GetTextExtentPointA external "gdi32".
|
116
|
def input param hdc as long.
|
117
|
def input param lpctstr as long.
|
118
|
def input param sz as long.
|
119
|
def input param lsz as long.
|
120
|
def return param returnvalue as long.
|
121
|
end.
|
122
|
|
123
|
procedure GetDC external "user32.dll".
|
124
|
def input param ihwnd as long.
|
125
|
def return param hdc as long.
|
126
|
end.
|
127
|
|
128
|
procedure ReleaseDC external "user32.dll".
|
129
|
def input param ihwnd as long.
|
130
|
def input param hdc as long.
|
131
|
def return param res as long.
|
132
|
end.
|
133
|
|
134
|
procedure GetDeviceCaps external "gdi32".
|
135
|
def input param hdc as long.
|
136
|
def input param nindex as long.
|
137
|
def return param res as long.
|
138
|
end.
|
139
|
|
140
|
procedure getMetrics.
|
141
|
def input param line as char.
|
142
|
def input param fontname as char.
|
143
|
def input param fontsize as int.
|
144
|
def input-output param lp as memptr.
|
145
|
def input param fbold as log.
|
146
|
def input param fitalic as log.
|
147
|
def input param funderline as log.
|
148
|
|
149
|
def var res as int.
|
150
|
def var hdc as integer.
|
151
|
def var dpi as int.
|
152
|
def var LOGPIXELSY as int init 90.
|
153
|
def var err as log init false.
|
154
|
|
155
|
run GetDc(input current-window:hwnd, output hdc).
|
156
|
|
157
|
/* get DPI */
|
158
|
run GetDeviceCaps(input hdc, input LOGPIXELSY, output dpi).
|
159
|
if showdpiwarning and dpi <> 96
|
160
|
then do:
|
161
|
message "DPI is" dpi "instead of 96!" view-as alert-box.
|
162
|
showdpiwarning = false.
|
163
|
end.
|
164
|
|
165
|
/* create font */
|
166
|
def var hfont as int64.
|
167
|
def var lplf as memptr.
|
168
|
set-size(lplf) = 5 * 4 + 8 * 1 + 1 * 32.
|
169
|
def var i as int.
|
170
|
do i = 1 to get-size(lplf):
|
171
|
put-byte(lplf, i) = 0.
|
172
|
end.
|
173
|
put-long(lplf, (1 - 1) * 4 + 1) = -1 * int64(round(fontsize * dpi / 72.0, 2)).
|
174
|
put-long(lplf, (5 - 1) * 4 + 1) = (if fbold then 700 else 0).
|
175
|
put-byte(lplf, 5 * 4 + 1) = (if fitalic then 1 else 0).
|
176
|
put-byte(lplf, 5 * 4 + 2) = (if funderline then 1 else 0).
|
177
|
put-string(lplf, 5 * 4 + 8 + 1) = fontname.
|
178
|
run CreateFontIndirectA(input get-pointer-value(lplf), output hfont).
|
179
|
|
180
|
/* select font */
|
181
|
def var foohdc as integer.
|
182
|
run SelectObject(input hdc, input hfont, output foohdc).
|
183
|
|
184
|
/* write string */
|
185
|
def var lpstr as memptr.
|
186
|
set-size(lpstr) = length(line) + 1.
|
187
|
put-string(lpstr, 1) = line.
|
188
|
|
189
|
/* get metrics */
|
190
|
set-size(lp) = 2 * 4.
|
191
|
run GetTextExtentPointA(input hdc, input get-pointer-value(lpstr), input length(line), input get-pointer-value(lp), output res).
|
192
|
if res = 0 then err = yes.
|
193
|
|
194
|
/* delete hfont */
|
195
|
run DeleteObject(input hfont, output res).
|
196
|
if res = 0 then err = yes.
|
197
|
|
198
|
run ReleaseDC(input current-window:hwnd, input hdc, output res).
|
199
|
if res = 0 then err = yes.
|
200
|
|
201
|
/* delete the lplf */
|
202
|
set-size(lplf) = 0.
|
203
|
/* delete the lpstr */
|
204
|
set-size(lpstr) = 0.
|
205
|
|
206
|
if err
|
207
|
then do:
|
208
|
message "GetTextMetrics failed for" fontname fontsize ". Memory leak?".
|
209
|
quit.
|
210
|
end.
|
211
|
|
212
|
end.
|
213
|
|
214
|
procedure recordMetrics.
|
215
|
def input param line as char.
|
216
|
def input param fname as char.
|
217
|
def input param sz as int.
|
218
|
def input param fbold as log.
|
219
|
def input param fitalic as log.
|
220
|
def input param funderline as log.
|
221
|
|
222
|
def var lp as memptr.
|
223
|
def var h as int.
|
224
|
def var w as int.
|
225
|
|
226
|
run getMetrics(line, fname, sz, input-output lp, fbold, fitalic, funderline).
|
227
|
w = get-long(lp, 1).
|
228
|
h = get-long(lp, 1 + 4).
|
229
|
|
230
|
put stream frpt unformatted space(6)
|
231
|
'<font name="' fname '" '
|
232
|
'size="' sz '" '
|
233
|
'bold="' trim(string(fbold, "true/false")) '" '
|
234
|
'italic="' trim(string(fitalic, "true/false")) '" '
|
235
|
'underline="' trim(string(funderline, "true/false")) '" '
|
236
|
'width="' w '" '
|
237
|
'height="' h '"/>' skip.
|
238
|
|
239
|
/* delete the lp */
|
240
|
set-size(lp) = 0.
|
241
|
end.
|
242
|
|
243
|
def var line as char.
|
244
|
def var fname as char.
|
245
|
def var sz as int.
|
246
|
def var fxmlname as char.
|
247
|
fxmlname = "text-metrics.xml".
|
248
|
|
249
|
form fname label "Font Name" format "x(32)" line label "Line" sz label "Size" with frame fstate down.
|
250
|
|
251
|
output stream frpt to value(fxmlname).
|
252
|
input stream flines from value(textFile).
|
253
|
|
254
|
put stream frpt unformatted '<?xml version="1.0" encoding="UTF-8"?>' skip.
|
255
|
put stream frpt unformatted '<!DOCTYPE text-list SYSTEM "text-metrics.dtd">' skip.
|
256
|
put stream frpt unformatted "<text-list>" skip.
|
257
|
|
258
|
repeat:
|
259
|
import stream flines unformatted line no-error.
|
260
|
if error-status:error then leave.
|
261
|
|
262
|
def var xline as char.
|
263
|
xline = line.
|
264
|
xline = replace(xline, '&', "&").
|
265
|
xline = replace(xline, '"', """).
|
266
|
xline = replace(xline, "'", "'").
|
267
|
xline = replace(xline, '<', "<").
|
268
|
xline = replace(xline, '>', ">").
|
269
|
|
270
|
put stream frpt unformatted space(3) '<text value="' xline '">' skip.
|
271
|
|
272
|
input stream fnames from value(fontFile).
|
273
|
|
274
|
repeat:
|
275
|
def var fsize as int.
|
276
|
def var fbold as log.
|
277
|
def var fitalic as log.
|
278
|
def var funder as log.
|
279
|
|
280
|
fname = ?.
|
281
|
fsize = ?.
|
282
|
fbold = ?.
|
283
|
fitalic = ?.
|
284
|
funder = ?.
|
285
|
|
286
|
import stream fnames delimiter "," fname fsize fbold fitalic funder no-error.
|
287
|
if error-status:error then leave.
|
288
|
|
289
|
do sz = (if fsize = ? or fsize = 0 then 1 else fsize) to (if fsize = ? or fsize = 0 then maxSize else fsize):
|
290
|
display fname line sz with frame fstate.
|
291
|
|
292
|
def var i as int.
|
293
|
do i = 1 to 8:
|
294
|
def var cbold as log.
|
295
|
def var citalic as log.
|
296
|
def var cunder as log.
|
297
|
|
298
|
cbold = (i > 4).
|
299
|
citalic = (i = 3 or i = 4 or i = 7 or i = 8).
|
300
|
cunder = i mod 2 = 0.
|
301
|
|
302
|
if (fbold = ? or fbold = cbold) and
|
303
|
(fitalic = ? or fitalic = citalic)and
|
304
|
(funder = ? or funder = cunder)
|
305
|
then run recordMetrics(line, fname, sz, cbold, citalic, cunder).
|
306
|
end.
|
307
|
end.
|
308
|
|
309
|
down with frame fstate.
|
310
|
if frame-line(fstate) = frame-down(fstate)
|
311
|
then up frame-down(fstate) - 1 with frame fstate.
|
312
|
|
313
|
/* force a flush */
|
314
|
output stream frpt close.
|
315
|
output stream frpt to value(fxmlname) append.
|
316
|
end.
|
317
|
|
318
|
put stream frpt unformatted space(3) '</text>' skip.
|
319
|
input stream fnames close.
|
320
|
end.
|
321
|
|
322
|
put stream frpt unformatted "</text-list>" skip.
|
323
|
|
324
|
output stream frpt close.
|
325
|
input stream flines close.
|
326
|
|
327
|
message "The metrics were captured in file:" fxmlname.
|