Skip to content

Provide better support for mixed writing systems #762

@jwiggins

Description

@jwiggins

This is mainly a problem of the AGG backends. Quartz and QPainter backends already have the correct behavior.

Basically, user code should be able to call show_text on the following string: "Kiva Graphics一番😎" and have it render correctly even if the currently selected font only supports Latin characters.

To get to this point, we need to do a few things:

  • Collect writing system information for entries in our font database
  • Build fallback lists for font families and styles
  • Find a library to use, or failing that, write our own function which breaks a string up into chunks which share the same writing system (see: https://stackoverflow.com/questions/9868792/find-out-the-unicode-script-of-a-character)
  • Make low level text drawing functions return the text cursor position after drawing a run of glyphs (or work around the absence by calling get_text_extent on every chunk of a string before drawing)
  • Bring everything together in the show_text method so that mixed strings can be drawn
  • Bonus: Support bidirectional text mixing

This is roughly what Qt does, based on a quick skim of the code: https://code.qt.io/cgit/qt/qtbase.git/

  • QFreeTypeFontDatabase::addTTFile (qtbase.git/tree/src/gui/text/freetype/qfreetypefontdatabase.cpp):
    Scans a font for the following information: weight, style, fixed-width, supported writing systems (unicode range, codepage range), family name
  • QPlatformFontDatabase::fallbacksForFamily (qtbase.git/tree/src/gui/text/qfontdatabase.cpp):
    Takes a style and script ID and returns a list of fonts which support that script with that style (or just support the script)
  • QPainter::drawText (qtbase.git/tree/src/gui/painting/qpainter.cpp): Basically Qt's show_text.
    Uses QStackTextEngine for shaping, breaking of input string. Breaks into QScriptItem objects. Picks the font per item and draws it.
  • QStackTextEngine/QScriptItem/QTextItemInt (qtbase.git/tree/src/gui/text/qtextengine.cpp)
    These are the components which break up a string into chunks which can be shaped and drawn as a unit.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions