font-ocl.lua /size: 23 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
font-ocl
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to font-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- todo : user list of colors
10 11
local
tostring
,
tonumber
,
next
=
tostring
,
tonumber
,
next
12
local
round
,
max
=
math
.
round
,
math
.
round
13
local
gsub
,
find
=
string
.
gsub
,
string
.
find
14
local
sortedkeys
,
sortedhash
,
concat
=
table
.
sortedkeys
,
table
.
sortedhash
,
table
.
concat
15
local
setmetatableindex
=
table
.
setmetatableindex
16 17
local
formatters
=
string
.
formatters
18
local
tounicode
=
fonts
.
mappings
.
tounicode
19 20
local
helpers
=
fonts
.
helpers
21 22
local
charcommand
=
helpers
.
commands
.
char
23
local
rightcommand
=
helpers
.
commands
.
right
24
local
leftcommand
=
helpers
.
commands
.
left
25
local
downcommand
=
helpers
.
commands
.
down
26 27
local
otf
=
fonts
.
handlers
.
otf
28
local
otfregister
=
otf
.
features
.
register
29 30
local
f_color
=
formatters
[
"
%.3f %.3f %.3f rg
"
]
31
local
f_gray
=
formatters
[
"
%.3f g
"
]
32 33
if
context
then
34 35
local
startactualtext
=
nil
36
local
stopactualtext
=
nil
37 38
function
otf
.
getactualtext
(
s
)
39
if
not
startactualtext
then
40
startactualtext
=
backends
.
codeinjections
.
startunicodetoactualtextdirect
41
stopactualtext
=
backends
.
codeinjections
.
stopunicodetoactualtextdirect
42
end
43
return
startactualtext
(
s
)
,
stopactualtext
(
)
44
end
45 46
else
47 48
-- Actually we don't need a generic branch at all because (according the the
49
-- internet) other macro packages rely on hb for emoji etc and never used this
50
-- feature of the font loader. So maybe I should just remove this from generic.
51 52
local
tounicode
=
fonts
.
mappings
.
tounicode16
53 54
function
otf
.
getactualtext
(
s
)
55
return
56
"
/Span << /ActualText <feff
"
.
.
s
.
.
"
> >> BDC
"
,
57
"
EMC
"
58
end
59 60
end
61 62
local
sharedpalettes
=
{
}
63 64
local
hash
=
setmetatableindex
(
function
(
t
,
k
)
65
local
v
=
{
"
pdf
"
,
"
direct
"
,
k
}
66
t
[
k
]
=
v
67
return
v
68
end
)
69 70
if
context
then
71 72
-- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] -- looks bad
73
-- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] -- looks okay
74 75
local
colors
=
attributes
.
list
[
attributes
.
private
(
'
color
'
)
]
or
{
}
76
local
transparencies
=
attributes
.
list
[
attributes
.
private
(
'
transparency
'
)
]
or
{
}
77 78
function
otf
.
registerpalette
(
name
,
values
)
79
sharedpalettes
[
name
]
=
values
80
local
color
=
lpdf
.
color
81
local
transparency
=
lpdf
.
transparency
82
local
register
=
colors
.
register
83
for
i
=
1
,
#
values
do
84
local
v
=
values
[
i
]
85
if
v
=
=
"
textcolor
"
then
86
values
[
i
]
=
false
87
else
88
local
c
=
nil
89
local
t
=
nil
90
if
type
(
v
)
=
=
"
table
"
then
91
c
=
register
(
name
,
"
rgb
"
,
92
max
(
round
(
(
v
.
r
or
0
)
*
255
)
,
255
)
/
255
,
93
max
(
round
(
(
v
.
g
or
0
)
*
255
)
,
255
)
/
255
,
94
max
(
round
(
(
v
.
b
or
0
)
*
255
)
,
255
)
/
255
95
)
96
else
97
c
=
colors
[
v
]
98
t
=
transparencies
[
v
]
99
end
100
if
c
and
t
then
101
values
[
i
]
=
hash
[
color
(
1
,
c
)
.
.
"
"
.
.
transparency
(
t
)
]
102
elseif
c
then
103
values
[
i
]
=
hash
[
color
(
1
,
c
)
]
104
elseif
t
then
105
values
[
i
]
=
hash
[
color
(
1
,
t
)
]
106
end
107
end
108
end
109
end
110 111
else
-- for generic
112 113
function
otf
.
registerpalette
(
name
,
values
)
114
sharedpalettes
[
name
]
=
values
115
for
i
=
1
,
#
values
do
116
local
v
=
values
[
i
]
117
if
v
then
118
values
[
i
]
=
hash
[
f_color
(
119
max
(
round
(
(
v
.
r
or
0
)
*
255
)
,
255
)
/
255
,
120
max
(
round
(
(
v
.
g
or
0
)
*
255
)
,
255
)
/
255
,
121
max
(
round
(
(
v
.
b
or
0
)
*
255
)
,
255
)
/
255
122
)
]
123
end
124
end
125
end
126 127
end
128 129
-- We need to force page first because otherwise the q's get outside the font switch and
130
-- as a consequence the next character has no font set (well, it has: the preceding one). As
131
-- a consequence these fonts are somewhat inefficient as each glyph gets the font set. It's
132
-- a side effect of the fact that a font is handled when a character gets flushed. Okay, from
133
-- now on we can use text as literal mode.
134 135
local
function
convert
(
t
,
k
)
136
local
v
=
{
}
137
for
i
=
1
,
#
k
do
138
local
p
=
k
[
i
]
139
local
r
,
g
,
b
=
p
[
1
]
,
p
[
2
]
,
p
[
3
]
140
if
r
=
=
g
and
g
=
=
b
then
141
v
[
i
]
=
hash
[
f_gray
(
r
/
255
)
]
142
else
143
v
[
i
]
=
hash
[
f_color
(
r
/
255
,
g
/
255
,
b
/
255
)
]
144
end
145
end
146
t
[
k
]
=
v
147
return
v
148
end
149 150
-- At some point 'font' mode was added to the engine and we can assume that most distributions
151
-- ship a luatex that has it; ancient versions are no longer supported anyway. Begin 2020 there
152
-- was an actualtext related mail exchange with RM etc. that might result in similar mode keys
153
-- in other tex->pdf programs because there is a bit of inconsistency in the way this is dealt
154
-- with. Best is not to touch this code too much.
155 156
local
mode
=
{
"
pdf
"
,
"
mode
"
,
"
font
"
}
157
local
push
=
{
"
pdf
"
,
"
page
"
,
"
q
"
}
158
local
pop
=
{
"
pdf
"
,
"
page
"
,
"
Q
"
}
159 160
-- see context git repository for older variant (pre 20200501 cleanup)
161 162
local
function
initializeoverlay
(
tfmdata
,
kind
,
value
)
163
if
value
then
164
local
resources
=
tfmdata
.
resources
165
local
palettes
=
resources
.
colorpalettes
166
if
palettes
then
167
--
168
local
converted
=
resources
.
converted
169
if
not
converted
then
170
converted
=
setmetatableindex
(
convert
)
171
resources
.
converted
=
converted
172
end
173
local
colorvalues
=
sharedpalettes
[
value
]
174
local
default
=
false
-- so the text color (bad for icon overloads)
175
if
colorvalues
then
176
default
=
colorvalues
[
#
colorvalues
]
177
else
178
colorvalues
=
converted
[
palettes
[
tonumber
(
value
)
or
1
]
or
palettes
[
1
]
]
or
{
}
179
end
180
local
classes
=
#
colorvalues
181
if
classes
=
=
0
then
182
return
183
end
184
--
185
local
characters
=
tfmdata
.
characters
186
local
descriptions
=
tfmdata
.
descriptions
187
local
properties
=
tfmdata
.
properties
188
--
189
properties
.
virtualized
=
true
190
tfmdata
.
fonts
=
{
191
{
id
=
0
}
192
}
193
--
194
local
getactualtext
=
otf
.
getactualtext
195
local
b
,
e
=
getactualtext
(
tounicode
(
0xFFFD
)
)
196
local
actualb
=
{
"
pdf
"
,
"
page
"
,
b
}
-- saves tables
197
local
actuale
=
{
"
pdf
"
,
"
page
"
,
e
}
-- saves tables
198
--
199
for
unicode
,
character
in
next
,
characters
do
200
local
description
=
descriptions
[
unicode
]
201
if
description
then
202
local
colorlist
=
description
.
colors
203
if
colorlist
then
204
local
u
=
description
.
unicode
or
characters
[
unicode
]
.
unicode
205
local
w
=
character
.
width
or
0
206
local
s
=
#
colorlist
207
local
goback
=
w
~
=
0
and
leftcommand
[
w
]
or
nil
-- needs checking: are widths the same
208
local
t
=
{
209
mode
,
210
not
u
and
actualb
or
{
"
pdf
"
,
"
page
"
,
(
getactualtext
(
tounicode
(
u
)
)
)
}
,
211
push
,
212
}
213
local
n
=
3
214
local
l
=
nil
215
for
i
=
1
,
s
do
216
local
entry
=
colorlist
[
i
]
217
local
v
=
colorvalues
[
entry
.
class
]
or
default
218
if
v
and
l
~
=
v
then
219
n
=
n
+
1
t
[
n
]
=
v
220
l
=
v
221
end
222
n
=
n
+
1
t
[
n
]
=
charcommand
[
entry
.
slot
]
223
if
s
>
1
and
i
<
s
and
goback
then
224
n
=
n
+
1
t
[
n
]
=
goback
225
end
226
end
227
n
=
n
+
1
t
[
n
]
=
pop
228
n
=
n
+
1
t
[
n
]
=
actuale
229
character
.
commands
=
t
230
end
231
end
232
end
233
return
true
234
end
235
end
236
end
237 238
otfregister
{
239
name
=
"
colr
"
,
240
description
=
"
color glyphs
"
,
241
manipulators
=
{
242
base
=
initializeoverlay
,
243
node
=
initializeoverlay
,
244
}
245
}
246 247
do
248 249
local
nofstreams
=
0
250
local
f_name
=
formatters
[
[[
pdf-glyph-%05i
]]
]
251
local
f_used
=
context
and
formatters
[
[[
original:///%s
]]
]
or
formatters
[
[[
%s
]]
]
252
local
hashed
=
{
}
253
local
cache
=
{
}
254 255
local
openpdf
=
pdfe
.
new
256
----- prefix = "data:application/pdf,"
257 258
function
otf
.
storepdfdata
(
pdf
)
259
local
done
=
hashed
[
pdf
]
260
if
not
done
then
261
nofstreams
=
nofstreams
+
1
262
local
f
=
f_name
(
nofstreams
)
263
local
n
=
openpdf
(
pdf
,
#
pdf
,
f
)
264
done
=
f_used
(
n
)
265
hashed
[
pdf
]
=
done
266
end
267
return
done
268
end
269 270
end
271 272
-- I'll probably make a variant for context as we can do it more efficient there than in
273
-- generic.
274 275
local
function
pdftovirtual
(
tfmdata
,
pdfshapes
,
kind
)
-- kind = png|svg
276
if
not
tfmdata
or
not
pdfshapes
or
not
kind
then
277
return
278
end
279
--
280
local
characters
=
tfmdata
.
characters
281
local
properties
=
tfmdata
.
properties
282
local
parameters
=
tfmdata
.
parameters
283
local
hfactor
=
parameters
.
hfactor
284
--
285
properties
.
virtualized
=
true
286
--
287
tfmdata
.
fonts
=
{
288
{
id
=
0
}
-- not really needed
289
}
290
--
291
local
getactualtext
=
otf
.
getactualtext
292
local
storepdfdata
=
otf
.
storepdfdata
293
--
294
local
b
,
e
=
getactualtext
(
tounicode
(
0xFFFD
)
)
295
local
actualb
=
{
"
pdf
"
,
"
page
"
,
b
}
-- saves tables
296
local
actuale
=
{
"
pdf
"
,
"
page
"
,
e
}
-- saves tables
297
--
298
local
vfimage
=
lpdf
and
lpdf
.
vfimage
or
function
(
wd
,
ht
,
dp
,
data
,
name
)
299
local
name
=
storepdfdata
(
data
)
300
return
{
"
image
"
,
{
filename
=
name
,
width
=
wd
,
height
=
ht
,
depth
=
dp
}
}
301
end
302
--
303
for
unicode
,
character
in
sortedhash
(
characters
)
do
-- sort is nicer for svg
304
local
index
=
character
.
index
305
if
index
then
306
local
pdf
=
pdfshapes
[
index
]
307
local
typ
=
type
(
pdf
)
308
local
data
=
nil
309
local
dx
=
nil
310
local
dy
=
nil
311
local
scale
=
1
312
if
typ
=
=
"
table
"
then
313
data
=
pdf
.
data
314
dx
=
pdf
.
x
or
pdf
.
dx
or
0
315
dy
=
pdf
.
y
or
pdf
.
dy
or
0
316
scale
=
pdf
.
scale
or
1
317
elseif
typ
=
=
"
string
"
then
318
data
=
pdf
319
dx
=
0
320
dy
=
0
321
elseif
typ
=
=
"
number
"
then
322
data
=
pdf
323
dx
=
0
324
dy
=
0
325
end
326
if
data
then
327
-- We can delay storage by a lua function in commands: but then we need to
328
-- be able to provide our own mem stream name (so that we can reserve it).
329
-- Anyway, we will do this different in a future version of context.
330
local
bt
=
unicode
and
getactualtext
(
unicode
)
331
local
wd
=
character
.
width
or
0
332
local
ht
=
character
.
height
or
0
333
local
dp
=
character
.
depth
or
0
334
-- The down and right will change too (we can move that elsewhere). We have
335
-- a different treatment in lmtx but the next kind of works. These images are
336
-- a mess anyway as in svg the bbox can be messed up absent). A png image
337
-- needs the x/y. I might normalize this once we move to lmtx exlusively.
338
character
.
commands
=
{
339
not
unicode
and
actualb
or
{
"
pdf
"
,
"
page
"
,
(
getactualtext
(
unicode
)
)
}
,
340
-- lmtx (when we deal with depth in vfimage, currently disabled):
341
-- downcommand [dy * hfactor],
342
-- rightcommand[dx * hfactor],
343
-- vfimage(wd,ht,dp,data,name),
344
-- mkiv
345
downcommand
[
dp
+
dy
*
hfactor
]
,
346
rightcommand
[
dx
*
hfactor
]
,
347
vfimage
(
scale
*
wd
,
ht
,
dp
,
data
,
pdfshapes
.
filename
or
"
"
)
,
348
actuale
,
349
}
350
character
[
kind
]
=
true
351
end
352
end
353
end
354
end
355 356
local
otfsvg
=
otf
.
svg
or
{
}
357
otf
.
svg
=
otfsvg
358
otf
.
svgenabled
=
true
359 360
do
361 362
local
report_svg
=
logs
.
reporter
(
"
fonts
"
,
"
svg conversion
"
)
363 364
local
loaddata
=
io
.
loaddata
365
local
savedata
=
io
.
savedata
366
local
remove
=
os
.
remove
367 368
if
context
then
369 370
local
xmlconvert
=
xml
.
convert
371
local
xmlfirst
=
xml
.
first
372 373
function
otfsvg
.
filterglyph
(
entry
,
index
)
374
-- we only support decompression in lmtx, so one needs to wipe the
375
-- cache when invalid xml is reported
376
local
svg
=
xmlconvert
(
entry
.
data
)
377
local
root
=
svg
and
xmlfirst
(
svg
,
"
/svg[@id='glyph
"
.
.
index
.
.
"
']
"
)
378
local
data
=
root
and
tostring
(
root
)
379
-- report_svg("data for glyph %04X: %s",index,data)
380
return
data
381
end
382 383
else
384 385
function
otfsvg
.
filterglyph
(
entry
,
index
)
-- can be overloaded
386
return
entry
.
data
387
end
388 389
end
390 391
local
runner
=
sandbox
and
sandbox
.
registerrunner
{
392
name
=
"
otfsvg
"
,
393
program
=
"
inkscape
"
,
394
method
=
"
pipeto
"
,
395
template
=
"
--export-area-drawing --shell > temp-otf-svg-shape.log
"
,
396
reporter
=
report_svg
,
397
}
398 399
if
not
runner
then
400
--
401
-- poor mans variant for generic:
402
--
403
runner
=
function
(
)
404
return
io
.
popen
(
"
inkscape --export-area-drawing --shell > temp-otf-svg-shape.log
"
,
"
w
"
)
405
end
406
end
407 408
-- There are svg out there with bad viewBox specifications where shapes lay outside that area,
409
-- but trying to correct that didn't work out well enough so I discarded that code. BTW, we
410
-- decouple the inskape run and the loading run because inkscape is working in the background
411
-- in the files so we need to have unique files.
412
--
413
-- Because a generic setup can be flawed we need to catch bad inkscape runs which add a bit of
414
-- ugly overhead. Bah.
415 416
local
new
=
nil
417 418
local
function
inkscapeformat
(
suffix
)
419
if
new
=
=
nil
then
420
new
=
os
.
resultof
(
"
inkscape --version
"
)
or
"
"
421
new
=
new
=
=
"
"
or
not
find
(
new
,
"
Inkscape%s*0
"
)
422
end
423
return
new
and
"
filename
"
or
suffix
424
end
425 426
function
otfsvg
.
topdf
(
svgshapes
,
tfmdata
)
427
local
pdfshapes
=
{
}
428
local
inkscape
=
runner
(
)
429
if
inkscape
then
430
-- local indices = fonts.getindices(tfmdata)
431
local
descriptions
=
tfmdata
.
descriptions
432
local
nofshapes
=
#
svgshapes
433
local
f_svgfile
=
formatters
[
"
temp-otf-svg-shape-%i.svg
"
]
434
local
f_pdffile
=
formatters
[
"
temp-otf-svg-shape-%i.pdf
"
]
435
local
f_convert
=
formatters
[
"
%s --export-%s=%s\n
"
]
436
local
filterglyph
=
otfsvg
.
filterglyph
437
local
nofdone
=
0
438
local
processed
=
{
}
439
report_svg
(
"
processing %i svg containers
"
,
nofshapes
)
440
statistics
.
starttiming
(
)
441
for
i
=
1
,
nofshapes
do
442
local
entry
=
svgshapes
[
i
]
443
for
index
=
entry
.
first
,
entry
.
last
do
444
local
data
=
filterglyph
(
entry
,
index
)
445
if
data
and
data
~
=
"
"
then
446
local
svgfile
=
f_svgfile
(
index
)
447
local
pdffile
=
f_pdffile
(
index
)
448
savedata
(
svgfile
,
data
)
449
inkscape
:
write
(
f_convert
(
svgfile
,
inkscapeformat
(
"
pdf
"
)
,
pdffile
)
)
450
processed
[
index
]
=
true
451
nofdone
=
nofdone
+
1
452
if
nofdone
%
25
=
=
0
then
453
report_svg
(
"
%i shapes submitted
"
,
nofdone
)
454
end
455
end
456
end
457
end
458
if
nofdone
%
25
~
=
0
then
459
report_svg
(
"
%i shapes submitted
"
,
nofdone
)
460
end
461
report_svg
(
"
processing can be going on for a while
"
)
462
inkscape
:
write
(
"
quit\n
"
)
463
inkscape
:
close
(
)
464
report_svg
(
"
processing %i pdf results
"
,
nofshapes
)
465
for
index
in
next
,
processed
do
466
local
svgfile
=
f_svgfile
(
index
)
467
local
pdffile
=
f_pdffile
(
index
)
468
-- local fntdata = descriptions[indices[index]]
469
-- local bounds = fntdata and fntdata.boundingbox
470
local
pdfdata
=
loaddata
(
pdffile
)
471
if
pdfdata
and
pdfdata
~
=
"
"
then
472
pdfshapes
[
index
]
=
{
473
data
=
pdfdata
,
474
-- x = bounds and bounds[1] or 0,
475
-- y = bounds and bounds[2] or 0,
476
}
477
end
478
remove
(
svgfile
)
479
remove
(
pdffile
)
480
end
481
local
characters
=
tfmdata
.
characters
482
for
k
,
v
in
next
,
characters
do
483
local
d
=
descriptions
[
k
]
484
local
i
=
d
.
index
485
if
i
then
486
local
p
=
pdfshapes
[
i
]
487
if
p
then
488
local
w
=
d
.
width
489
local
l
=
d
.
boundingbox
[
1
]
490
local
r
=
d
.
boundingbox
[
3
]
491
p
.
scale
=
(
r
-
l
)
/
w
492
p
.
x
=
l
493
end
494
end
495
end
496
if
not
next
(
pdfshapes
)
then
497
report_svg
(
"
there are no converted shapes, fix your setup
"
)
498
end
499
statistics
.
stoptiming
(
)
500
if
statistics
.
elapsedseconds
then
501
report_svg
(
"
svg conversion time %s
"
,
statistics
.
elapsedseconds
(
)
or
"
-
"
)
502
end
503
end
504
return
pdfshapes
505
end
506 507
end
508 509
local
function
initializesvg
(
tfmdata
,
kind
,
value
)
-- hm, always value
510
if
value
and
otf
.
svgenabled
then
511
local
svg
=
tfmdata
.
properties
.
svg
512
local
hash
=
svg
and
svg
.
hash
513
local
timestamp
=
svg
and
svg
.
timestamp
514
if
not
hash
then
515
return
516
end
517
local
pdffile
=
containers
.
read
(
otf
.
pdfcache
,
hash
)
518
local
pdfshapes
=
pdffile
and
pdffile
.
pdfshapes
519
if
not
pdfshapes
or
pdffile
.
timestamp
~
=
timestamp
or
not
next
(
pdfshapes
)
then
520
-- the next test tries to catch errors in generic usage but of course can result
521
-- in running again and again
522
local
svgfile
=
containers
.
read
(
otf
.
svgcache
,
hash
)
523
local
svgshapes
=
svgfile
and
svgfile
.
svgshapes
524
pdfshapes
=
svgshapes
and
otfsvg
.
topdf
(
svgshapes
,
tfmdata
,
otf
.
pdfcache
.
writable
,
hash
)
or
{
}
525
containers
.
write
(
otf
.
pdfcache
,
hash
,
{
526
pdfshapes
=
pdfshapes
,
527
timestamp
=
timestamp
,
528
}
)
529
end
530
pdftovirtual
(
tfmdata
,
pdfshapes
,
"
svg
"
)
531
return
true
532
end
533
end
534 535
otfregister
{
536
name
=
"
svg
"
,
537
description
=
"
svg glyphs
"
,
538
manipulators
=
{
539
base
=
initializesvg
,
540
node
=
initializesvg
,
541
}
542
}
543 544
-- This can be done differently e.g. with ffi and gm and we can share code anway. Using
545
-- batchmode in gm is not faster and as it accumulates we would need to flush all
546
-- individual shapes. But ... in context lmtx (and maybe the backport) we will use
547
-- a different and more efficient method anyway. I'm still wondering if I should
548
-- keep color code in generic. Maybe it should be optional.
549 550
local
otfpng
=
otf
.
png
or
{
}
551
otf
.
png
=
otfpng
552
otf
.
pngenabled
=
true
553 554
do
555 556
local
report_png
=
logs
.
reporter
(
"
fonts
"
,
"
png conversion
"
)
557 558
local
loaddata
=
io
.
loaddata
559
local
savedata
=
io
.
savedata
560
local
remove
=
os
.
remove
561 562
local
runner
=
sandbox
and
sandbox
.
registerrunner
{
563
name
=
"
otfpng
"
,
564
program
=
"
gm
"
,
565
template
=
"
convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log
"
,
566
-- reporter = report_png,
567
}
568 569
if
not
runner
then
570
--
571
-- poor mans variant for generic:
572
--
573
runner
=
function
(
)
574
return
os
.
execute
(
"
gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log
"
)
575
end
576
end
577 578
-- Alternatively we can create a single pdf file with -adjoin and then pick up pages from
579
-- that file but creating thousands of small files is no fun either.
580 581
function
otfpng
.
topdf
(
pngshapes
)
582
local
pdfshapes
=
{
}
583
local
pngfile
=
"
temp-otf-png-shape.png
"
584
local
pdffile
=
"
temp-otf-png-shape.pdf
"
585
local
nofdone
=
0
586
local
indices
=
sortedkeys
(
pngshapes
)
-- can be sparse
587
local
nofindices
=
#
indices
588
report_png
(
"
processing %i png containers
"
,
nofindices
)
589
statistics
.
starttiming
(
)
590
for
i
=
1
,
nofindices
do
591
local
index
=
indices
[
i
]
592
local
entry
=
pngshapes
[
index
]
593
local
data
=
entry
.
data
-- or placeholder
594
local
x
=
entry
.
x
595
local
y
=
entry
.
y
596
savedata
(
pngfile
,
data
)
597
runner
(
)
598
pdfshapes
[
index
]
=
{
599
x
=
x
~
=
0
and
x
or
nil
,
600
y
=
y
~
=
0
and
y
or
nil
,
601
data
=
loaddata
(
pdffile
)
,
602
}
603
nofdone
=
nofdone
+
1
604
if
nofdone
%
100
=
=
0
then
605
report_png
(
"
%i shapes processed
"
,
nofdone
)
606
end
607
end
608
report_png
(
"
processing %i pdf results
"
,
nofindices
)
609
remove
(
pngfile
)
610
remove
(
pdffile
)
611
statistics
.
stoptiming
(
)
612
if
statistics
.
elapsedseconds
then
613
report_png
(
"
png conversion time %s
"
,
statistics
.
elapsedseconds
(
)
or
"
-
"
)
614
end
615
return
pdfshapes
616
end
617 618
end
619 620
-- This will change in a future version of context. More direct.
621 622
local
function
initializepng
(
tfmdata
,
kind
,
value
)
-- hm, always value
623
if
value
and
otf
.
pngenabled
then
624
local
png
=
tfmdata
.
properties
.
png
625
local
hash
=
png
and
png
.
hash
626
local
timestamp
=
png
and
png
.
timestamp
627
if
not
hash
then
628
return
629
end
630
local
pdffile
=
containers
.
read
(
otf
.
pdfcache
,
hash
)
631
local
pdfshapes
=
pdffile
and
pdffile
.
pdfshapes
632
if
not
pdfshapes
or
pdffile
.
timestamp
~
=
timestamp
then
633
local
pngfile
=
containers
.
read
(
otf
.
pngcache
,
hash
)
634
local
pngshapes
=
pngfile
and
pngfile
.
pngshapes
635
pdfshapes
=
pngshapes
and
otfpng
.
topdf
(
pngshapes
)
or
{
}
636
containers
.
write
(
otf
.
pdfcache
,
hash
,
{
637
pdfshapes
=
pdfshapes
,
638
timestamp
=
timestamp
,
639
}
)
640
end
641
--
642
pdftovirtual
(
tfmdata
,
pdfshapes
,
"
png
"
)
643
return
true
644
end
645
end
646 647
otfregister
{
648
name
=
"
sbix
"
,
649
description
=
"
sbix glyphs
"
,
650
manipulators
=
{
651
base
=
initializepng
,
652
node
=
initializepng
,
653
}
654
}
655 656
otfregister
{
657
name
=
"
cblc
"
,
658
description
=
"
cblc glyphs
"
,
659
manipulators
=
{
660
base
=
initializepng
,
661
node
=
initializepng
,
662
}
663
}
664 665
if
context
then
666 667
-- untested in generic and might clash with other color trickery
668
-- anyway so let's stick to context only
669 670
local
function
initializecolor
(
tfmdata
,
kind
,
value
)
671
if
value
=
=
"
auto
"
then
672
return
673
initializeoverlay
(
tfmdata
,
kind
,
value
)
or
674
initializesvg
(
tfmdata
,
kind
,
value
)
or
675
initializepng
(
tfmdata
,
kind
,
value
)
676
elseif
value
=
=
"
overlay
"
then
677
return
initializeoverlay
(
tfmdata
,
kind
,
value
)
678
elseif
value
=
=
"
svg
"
then
679
return
initializesvg
(
tfmdata
,
kind
,
value
)
680
elseif
value
=
=
"
png
"
or
value
=
=
"
bitmap
"
then
681
return
initializepng
(
tfmdata
,
kind
,
value
)
682
else
683
-- forget about it
684
end
685
end
686 687
otfregister
{
688
name
=
"
color
"
,
689
description
=
"
color glyphs
"
,
690
manipulators
=
{
691
base
=
initializecolor
,
692
node
=
initializecolor
,
693
}
694
}
695 696
end
697