1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
if not modules then modules = { } end modules ['lpdf-fnt'] = {
version = 1.001,
comment = "companion to lpdf-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-- This is experimental code.
local match, gmatch = string.match, string.gmatch
local tonumber, rawget = tonumber, rawget
local pdfe = lpdf.epdf
local pdfreference = lpdf.reference
local pdfreserveobject
updaters.register("backend.update.lpdf",function()
pdfreserveobject = lpdf.reserveobject
end)
local tobemerged = { }
local trace_merge = false trackers.register("graphics.fonts",function(v) trace_merge = v end)
local report_merge = logs.reporter("graphics","fonts")
local function register(usedname,cleanname)
local cleanname = cleanname or fonts.names.cleanname(usedname)
local fontid = fonts.definers.internal { name = cleanname }
if fontid then
local objref = pdfreserveobject()
if trace_merge then
report_merge("registering %a with name %a, id %a and object %a",usedname,cleanname,fontid,objref)
end
return {
id = fontid,
reference = objref,
indices = { },
cleanname = cleanname,
}
end
return false
end
function lpdf.registerfont(usedname,cleanname)
local v = register(usedname,cleanname)
tobemerged[usedname] = v
return v
end
table.setmetatableindex(tobemerged,function(t,k)
return lpdf.registerfont(k)
end)
local function finalizefont(v)
local indextoslot = fonts.helpers.indextoslot
if v then
local id = v.id
local n = 0
for i in next, v.indices do
local u = indextoslot(id,i)
n = n + 1
end
v.n = n
end
end
statistics.register("merged fonts", function()
if next(tobemerged) then
local t = { }
for k, v in table.sortedhash(tobemerged) do
t[#t+1] = string.formatters["%s (+%i)"](k,v.n)
end
return table.concat(t," ")
end
end)
function lpdf.finalizefonts()
for k, v in next, tobemerged do
finalizefont(v)
end
end
callback.register("font_descriptor_objnum_provider",function(name)
local m = rawget(tobemerged,name)
if m then
-- finalizefont(m)
local r = m.reference or 0
if trace_merge then
report_merge("using object %a for font descriptor of %a",r,name)
end
return r
end
return 0
end)
local function getunicodes1(str,indices)
for s in gmatch(str,"beginbfrange%s*(.-)%s*endbfrange") do
for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do
for i=tonumber(first,16),tonumber(last,16) do
indices[i] = true
end
end
end
for s in gmatch(str,"beginbfchar%s*(.-)%s*endbfchar") do
for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
indices[tonumber(old,16)] = true
end
end
end
local function getunicodes2(widths,indices)
for i=1,#widths,2 do
local start = widths[i]
local count = #widths[i+1]
if start and count then
for i=start,start+count-1 do
indices[i] = true
end
end
end
end
local function checkedfonts(pdfdoc,xref,copied,page)
local list = page.Resources.Font
local done = { }
for k, somefont in pdfe.expanded(list) do
if somefont.Subtype == "Type0" and somefont.Encoding == "Identity-H" then
local descendants = somefont.DescendantFonts
if descendants then
for i=1,#descendants do
local d = descendants[i]
if d then
local subtype = d.Subtype
if subtype == "CIDFontType0" or subtype == "CIDFontType2" then
local basefont = somefont.BaseFont
if basefont then
local fontname = match(basefont,"^[A-Z]+%+(.+)$")
local fontdata = tobemerged[fontname]
if fontdata then
local descriptor = d.FontDescriptor
if descriptor then
local okay = false
local widths = d.W
if widths then
getunicodes2(widths,fontdata.indices)
okay = true
else
local tounicode = somefont.ToUnicode
if tounicode then
getunicodes1(tounicode(),fontdata.indices)
okay = true
end
end
if okay then
local r = xref[descriptor]
done[r] = fontdata.reference
end
end
end
end
end
end
end
end
end
end
return next(done) and done
end
function lpdf.epdf.plugin(pdfdoc,xref,copied,page) -- needs checking
local done = checkedfonts(pdfdoc,xref,copied,page)
if done then
return {
FontDescriptor = function(xref,copied,object,key,value,copyobject)
local r = value[3]
local d = done[r]
if d then
return pdfreference(d)
else
return copyobject(xref,copied,object,key,value)
end
end
}
end
end
lpdf.registerdocumentfinalizer(lpdf.finalizefonts)
-- already defined in font-ocl but the context variatn will go here
--
-- function lpdf.vfimage(wd,ht,dp,data,name)
-- return { "image", { filename = name, width = wd, height = ht, depth = dp } }
-- end
|