I am trying to emulate this poster which I've found at http://www.brill.com/about/brill-fonts. How could we define different color per script and get a similar glyph poster?
1 Answer
I am using HanaMinA.ttf for this task as a test case. After downloading and installing the font, I have prepared a TeX file mal-fonts.tex
which can be processed by xelatex
or lualatex
.
% run: xelatex or lualatex mal-fonts.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\parindent=0pt
\usepackage{xcolor}
\usepackage{fontspec}
\setmainfont{HanaMinA}
\begin{document}
\input{mal-result.tex}
\end{document}
I am generating mal-result.tex
file by a standalone Lua script mal-fonts.lua
. I've defined several regions (Latin, Extended Latin, Chinese, Japanese etc.) and its color. I am randomly selecting glyphs (function callme
) making sure that two sequantial glyphs won't have the same color, or, I am testing a specific string (function testme
).
We are running:
texlua mal-fonts.lua
lualatex mal-fonts.tex
We are getting this message at the terminal of a number of the processed glyphs:
Processed glyphs: 19 300
I am enclosing the Lua script and a preview of the PDF file with Latin+Japanese sentence and 300 randomly generated glyphs.
The algorithm for generating glyphs could be improved from regions to specific glyphs in a selected font. We are selecting glyphs without further testing, so a specific glyph could be displayed several times, in theory. The script is working fine if we are just testing strings.
Update: I've implemented that idea from the comment section. So the ligatures are preserved. Well, the example looks all the some but it is due to font and used words. The beginning of the generated file (mal-result.tex
) looks like this:
\hfill{\color{green}Hello\ World!\ }\hfill{\color{gray}さようなら}\hfill{\color{green}\ }%
\hfill{\color{red}Ș}\hfill{\color{green}h}\hfill{\color{orange}Κ}\hfill{\color{violet}㌨}\hfill{\color{blue}ö}\hfill{\color{green}a}\hfill
This is the main Lua script (mal-fonts.lua
):
-- I am mal-fonts.lua file...
-- I am checking (generated) string character by character and I use different color as defined in sets data table.
-- I am also saving time by randomly choosing glyphs. The glyph doesn't have to be defined in a specific font (that's a possible improvement, e.g. 198 (hex) in HanaMinA.ttf).
math.randomseed(0) -- to be changed
sets={
{"green","61","7A"},
{"blue","C0","FF"},
{"red","100","2AF"},
{"orange","388","3D1"},
{"cyan","2460","24E9"},
{"magenta","2800","28FF"},
{"yellow","2F00","2FD5"},
{"gray","3041","3096"},
{"violet","3300","337F"},
}
-- Generate a set of glyphs...
function callme(number)
local col=0
local s=""
local last=0
local marker=0
for i=1,number do
col=col+1
if col>#sets then
col=1
--whereto:write("%\n") -- to easy reading
end -- of if col
if #sets==1 then
realcol=col -- =1
else
repeat
realcol=math.random(1,#sets)
until last~=realcol -- This is not effective computation, but it is an experiment.
last=realcol
end -- if #sets...
--realcol -- assures that two glyphs will have different color
-- col -- colors are repated from 1..n
startnum=tonumber(sets[realcol][1],16)
endnum=tonumber(sets[realcol][2],16)
glyph=math.random( startnum,endnum )
--print(i,col,glyph,string.format("%X",glyph)) -- information about specific glyph
s=s..unicode.utf8.char(glyph)
end -- of for i
--print(s)
testme(s)
end -- of function callme
-- Test a string and use a proper color as defined in sets.
function testme(mstring)
io.write(" "..unicode.utf8.len(mstring))
for i=1,unicode.utf8.len(mstring) do
glyph=unicode.utf8.sub(mstring,i,i)
value=unicode.utf8.byte(glyph)
jkey=1 -- if glyph is not predefined
for j=1,#sets do
if value>=tonumber(sets[j][3],16) and value<=tonumber(sets[j][4],16) then jkey=j; break end
end -- of j
if glyph==" " then glyph="\\ " end -- \\; making sure that space will be there
if jkey~=marker then
if i>1 then whereto:write("}") end
whereto:write("\\hfill{\\color{"..sets[jkey][5].."}")
end -- end of if jkey
whereto:write(glyph)
marker=jkey
--print(i,glyph)
end -- of for i
whereto:write("}") -- closing group with \color
whereto:write("%\n")
end -- of function testme
whereto=io.open("mal-result.tex","w")
io.write("Processed glyphs:")
-- Let's run several tests...
testme("Hello World! さようなら ")
callme(300) -- it calls for testme automatically
-- Close a file and end the script
io.write("\n")
whereto:close()
-
Interesting! Why do you run
texlua
separately? If you are concerned about reproducibility, you could just store the seed in the document or the.aux
file. May 16, 2014 at 21:08 -
-
Now, after checking "ll" in "Hello", I have noticed that I am breaking up kerning pairs as I treat each glyph separately in a group (I focused on typesetting poster), it could be improved for production by not entering a new group if script from the previous glyph is the same. Instead of
{\somefont H}{\somefont e}{\somefont l}{\somefont l}{\somefont o}
we would get{\somefont Hello}
.– MalipivoMay 16, 2014 at 21:31 -
If you are interested in serious approach based on glyph classes for large text blocks, please see tex.stackexchange.com/questions/45331/… (XeTeX) and tex.stackexchange.com/a/21691/48028 (LuaTeX)– MalipivoMay 16, 2014 at 22:12
-
It looks that next fine way for displaying scripts is with the help of the
ucharclasses
package.– MalipivoMay 18, 2014 at 8:07