sile-typesetter / sile

The SILE Typesetter — Simon’s Improved Layout Engine
https://sile-typesetter.org
MIT License
1.66k stars 98 forks source link

Can't render character in a specific region. (/usr/localshare/sile/core/font.lua:68: invalid value (nil) at index 1 in table for 'concat') #531

Closed Yoxem closed 1 year ago

Yoxem commented 6 years ago

I want to make a package to set the font of characters in latin region to a specific one, and I modified font-fallback.lua to archive it. the command is defined below:

local fontlist = {}
-- set the font in Latin region
SILE.registerCommand("latin-font:add",function(o,c)
  fontlist = o
end)
-- clear the latin form
SILE.registerCommand("latin-font:clear", function()``
  fontlist = {}
end)

and I add the funciton isLatin (adopted from simoncozens')

local isLatin = function(c)
  return (c > 0x20 and c <= 0x24F) or (c>=0x300 and c<=0x36F)
    or (c >= 0x1DC0 and c<= 0x1EFF) or (c >= 0x2C60 and c <= 0x2c7F)
end

the coded I modified from font-fallback.lua (named test.lua in folder

"packages") is listed below:

SILE.shapers.harfbuzzWithLatin = SILE.shapers.harfbuzz {

  shapeToken = function (self, text, options)

    local items = {}
    optionSet = { options } 
    local latinOptionSet =  {std.tree.clone(options)}
    if fontlist ~= {} then
      latinOptionSet[1].family = fontlist["family"]
    end

......
            if startOfNotdefRun > -1 then
              shapeQueue:addJob(start + newItems[startOfNotdefRun].index,
                                start + newItems[i].index - 1)
              SU.debug("fonts", "adding run "..shapeQueue:lastJob())
              startOfNotdefRun = -1
            end

        newItems[i].fontOptions = options

            -- if the newItem[i] is a latin char, render it with the latin-font-setting
            if isLatin(SU.codepoint(newItems[i].text)) then
                      newItems[i].fontOptions = latinOptionSet
               end

            -- There might be multiple glyphs for the same index
            if not items[start + newItems[i].index] then
              items[start + newItems[i].index] = newItems[i]
......

The test file (test.sil):

\begin[class=zplain]{document}
\font[family=Noto Sans CJK TC,language=zh]
\script[src=packages/font-fallback]
\script[src=packages/test]
\latin-font:add[family=FreeSans]
\begin{raggedright}
這 (it) 是 (is) 測試 (a test)。
\end{raggedright}
\end{document}

However, when I compile it, it shows the error:

This is SILE 0.9.5-unreleased
<test.sil>

Error detected:
/usr/local/share/sile/core/font.lua:68: invalid value (nil) at index 1 in table for 'concat'

It said that the font is not defined, but I have defined it. How to solve the problem? the files is here: test.zip

alerque commented 6 years ago

I haven't looked into this in depth, but isn't character-wise application of font families going to throw off all other string handling functions? This doesn't seem like it is conceptually the right approach to the problem. It sounds like you are trying to set a fallback family for character sets not included in a font, is that correct?

Yoxem commented 6 years ago

It's similar to fallback font, but I just want to set a specific latin font to all the alphabets in a latin region, and set another CJK font for the characters in CJK region. I don't want to render Latin alphabets with the Latin-alphabet glyphs in a CJK font.

alerque commented 6 years ago

I think I get what you're after @Yoxem, but you are kind of being jinxed by somebody else's hacked solution. I suggest you work around this for now using the fontforge python scripts to strip all the Latin glyphs from your CJK fonts of choice. Then the font fallback system will work as expected. SILE does not yet have a way to address character ranges with a style (like CSS does) and hacking it in the way you were trying is likely to break other aspects of the process.

Omikhleia commented 1 year ago

This 4+ year old issue is still valid? From a casual reader viewpoint, it's very unclear what were the expectations for considering it answered or not, or what the next steps should have been.

ctrlcctrlv commented 1 year ago

Agreed.