[NTG-context] Is rendering furigana over horizontal or vertical japanese text doable in ConTeXt?
Hans Hagen
j.hagen at freedom.nl
Sun Aug 21 12:00:59 CEST 2022
On 8/21/2022 10:24 AM, 黄复雄 via ntg-context wrote:
> Currently, the ruby module does not seem to support cjk fonts? I have
> a preliminary implementation of furigana(pinyin in Chinese) as:
Actually a few years ago I added some basic new features for doing
vertical scripts effciently but (as often with these things) there was
not that much follow up because no one seems to need / use it (or be
triggered by the fact that it can be used).
The attached files show two methods ... manual work as well as semi
automatic (one needs to patch one font file for some recent optimizations).
As you can see, rubies work ok. Now, before trying to improve this, it
makes more sense to think about what kind of vertical support is
actually needed becaus in order for that to work ok it really has to
work with other mechanism as well and there is only so much that tex can
do.
Hans
-----------------------------------------------------------------
Hans Hagen | PRAGMA ADE
Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl
-----------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-directions-005.pdf
Type: application/pdf
Size: 21019 bytes
Desc: not available
URL: <http://mailman.ntg.nl/pipermail/ntg-context/attachments/20220821/641a6905/attachment-0002.pdf>
-------------- next part --------------
\noheaderandfooterlines
% in font-imp-scripts, line 145, comment a few lines
%
% orientate = function(character)
% local width = character.width or 0
% local height = character.height or 0
% local depth = character.depth or 0
% -- character.width = height + depth + rightshift + rightshift
% character.height = width - downshift
% character.depth = shift
% -- character.xoffset = height + rightshift
% -- character.yoffset = - downshift
% -- character.orientation = orientation
% end
\dontcomplain
\setuplayout[middle]
\starttext
\startluacode
local nuts = nodes.nuts
local nextglyph = nuts.traversers.glyph
local nextnode = nuts.traversers.node
local newhlist = nuts.pool.hlist
local newglue = nuts.pool.glue
local newpenalty = nuts.pool.penalty
local getprev = nuts.getprev
local setnext = nuts.setnext
local getnext = nuts.getnext
local setprev = nuts.setprev
local getboth = nuts.getboth
local setboth = nuts.setboth
local setlink = nuts.setlink
local getlist = nuts.getlist
local setlist = nuts.setlist
local setwhd = nuts.setwhd
local getwhd = nuts.getwhd
local getid = nuts.getid
local getchar = nuts.getchar
local getbox = nuts.getbox
local getdimensions = nuts.dimensions
local setorientation = nuts.setorientation
local getorientation = nuts.getorientation
local glyph_code = nodes.nodecodes.glyph
local kern_code = nodes.nodecodes.kern
function document.manipulate_one(boxnumber)
local box = getbox(1000)
local list = getlist(b)
local all = { }
for n, c, f in nextglyph, list do
if c > 200 then
all[n] = true
end
end
local o = 4 * 65536
for n, how in next, all do
local prev, next = getboth(n)
setboth(n)
local l = newhlist(n)
local w, h, d = getwhd(n)
setlink(prev,l,next)
if how then
setwhd(l,h+d+o,w,0)
setorientation(l,0x003,0,0,h,d-o)
end
if n == list then
setlist(box,l)
end
end
end
local function flushrange(head,current,first,last)
local prev = getprev(first)
local next = getnext(last)
local list = newhlist(first)
setprev(first)
setnext(last)
local w, h, d = getdimensions(first)
setwhd(list,h+d,w,0)
setlink(prev,list,next)
setorientation(list,0x001,0,0,h,d)
if first == head then
return list, list
else
return head, list
end
end
local function flushchar(head,current)
local next = getnext(current)
local glue = newglue(n,655360)
setlink(current,glue,next)
return head, glue
end
function document.manipulate_two(boxnumber)
local box = getbox(1000)
local head = getlist(box)
local first = false
local last = false
local current = head
while current do
local id = getid(current)
if id == glyph_code then
if getchar(current) < 200 then
if first then
last = current
else
first = current
last = current
end
else
if first then
head, current = flushrange(head,current,first,last)
first = false
end
head, current = flushchar(head,current)
end
elseif id == kern_code then
if first then
last = current
end
elseif first then
head, current = flushrange(head,current,first,last)
first = false
end
current = getnext(current)
end
if first then
head, current = flushrange(head,current,first,last)
end
setlist(box,head)
end
\stopluacode
% % % % % % % % % %
\setuptolerance[verytolerant,stretch]
\definefont[NotoCJK][NotoSanstc-Regular*default @ 24pt] \setupinterlinespace[40pt]
\unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}}
\setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript}
\ctxlua{document.manipulate_one(1000)}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
\page
\setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规\ruby{范}{x}汉字表 \stripe{test #1} }\stopscript}
\ctxlua{document.manipulate_one(1000)}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
\page
\setupinterlinespace[40pt]
\definefontfeature
[vertical]
[vertical={%
orientation=3,%
down=.1,%
right=.1,%
ranges={%
cjkcompatibility,%
cjkcompatibilityforms,%
cjkcompatibilityideographs,%
cjkcompatibilityideographssupplement,%
cjkradicalssupplement,%
% cjkstrokes,%
cjksymbolsandpunctuation,%
cjkunifiedideographs,%
cjkunifiedideographsextensiona,%
cjkunifiedideographsextensionb,%
cjkunifiedideographsextensionc,%
cjkunifiedideographsextensiond,%
cjkunifiedideographsextensione,%
cjkunifiedideographsextensionf,%
}%
}]
\definefont[NotoCJKvertical][NotoSanstc-Regular*default,vertical @ 24pt]
\showglyphs
\unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}}
\setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
\page
\setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规\ruby{范}{x}汉字表 \stripe{test #1} }\stopscript}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
% \stopscript
\stoptext
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-directions-006.pdf
Type: application/pdf
Size: 19235 bytes
Desc: not available
URL: <http://mailman.ntg.nl/pipermail/ntg-context/attachments/20220821/641a6905/attachment-0003.pdf>
-------------- next part --------------
\dontcomplain
% in font-imp-scripts, line 145, comment a few lines
%
% orientate = function(character)
% local width = character.width or 0
% local height = character.height or 0
% local depth = character.depth or 0
% -- character.width = height + depth + rightshift + rightshift
% character.height = width - downshift
% character.depth = shift
% -- character.xoffset = height + rightshift
% -- character.yoffset = - downshift
% -- character.orientation = orientation
% end
\setuplayout[middle]
\starttext
\startluacode
local nuts = nodes.nuts
local nextglyph = nuts.traversers.glyph
local newhlist = nuts.pool.hlist
local getboth = nuts.getboth
local setboth = nuts.setboth
local setlink = nuts.setlink
local getlist = nuts.getlist
local setlist = nuts.setlist
local setwhd = nuts.setwhd
local getwhd = nuts.getwhd
local setorientation = nuts.setorientation
local getbox = nuts.getbox
local xheights = fonts.hashes.xheights
local function is_vertical(c)
return c >= 0x04E00 and c <= 0x09FFF
end
function document.manipulate_one(boxnumber)
local box = getbox(boxnumber)
local list = getlist(box)
local all = { }
for n, c, f in nextglyph, list do
if is_vertical(c) then
all[n] = f
end
end
for n, f in next, all do
local o = .2 * xheights[f]
local prev, next = getboth(n)
setboth(n)
local l = newhlist(n)
local w, h, d = getwhd(n)
setlink(prev,l,next)
setwhd(l,h+d+o,w,0)
setorientation(l,0x003,o/2,-o/2,0,h,d-o)
if n == list then
setlist(box,l)
end
end
end
\stopluacode
\startluacode
function document.manipulate_two(boxnumber)
local box = tex.getbox(boxnumber)
local n = box.list
local function is_vertical(c)
return c >= 0x04E00 and c <= 0x09FFF
end
while n do
if n.id == node.id("glyph") and is_vertical(n.char) then
local o = .2 * fonts.hashes.identifiers[n.font].parameters.xheight
local prev, next = n.prev, n.next
n.next, n.prev = nil, nil
local l = nodes.new("hlist")
l.list = n
local w, h, d = n.width, n.height, n.depth
if prev then
prev.next, l.prev = l, prev
else
box.list = l
end
if next then
l.next, next.prev = next, l
end
l.width, l.height, l.depth = h + d + o, w, 0
l.orientation = 0x003
-- l.xoffset, l.yoffset = o/2, -o/2
l.hoffset, l.doffset = h, d - o
n = next
else
n = n.next
end
end
end
\stopluacode
% % % % % % % % % %
\unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}}
\setuptolerance[verytolerant,stretch]
\definefont[NotoCJK][NotoSanstc-Regular*default @ 24pt] \setupinterlinespace[40pt]
% % % % % % % % % %
\setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript}
\ctxlua{document.manipulate_one(1000)}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
\page
\setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript}
\ctxlua{document.manipulate_two(1000)}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
\page
\setupinterlinespace[40pt]
\definefontfeature
[vertical]
[vertical={%
orientation=3,%
down=.1,%
right=.1,%
ranges={%
cjkcompatibility,%
cjkcompatibilityforms,%
cjkcompatibilityideographs,%
cjkcompatibilityideographssupplement,%
cjkradicalssupplement,%
% cjkstrokes,%
cjksymbolsandpunctuation,%
cjkunifiedideographs,%
cjkunifiedideographsextensiona,%
cjkunifiedideographsextensionb,%
cjkunifiedideographsextensionc,%
cjkunifiedideographsextensiond,%
cjkunifiedideographsextensione,%
cjkunifiedideographsextensionf,%
}%
}]
\definefont[NotoCJKvertical][NotoSanstc-Regular*default,vertical @ 24pt]
\showglyphs
\unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}}
\setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript}
\ruledvbox orientation 1 to \textwidth \bgroup
\hsize \textheight
\unhbox1000
\vfill
\egroup
% \stopscript
\stoptext
More information about the ntg-context
mailing list