Skip to main content

Use Multilingual UTF-8 Strings with any OpenAccess Version


In this article I show you how to use multilingual UTF-8 strings with standard, unmodified OpenAccess oa-22.04p028 release.

In the last  article, I introduced UTF-8, the popular 8 bit encoding of Unicode into multibyte character strings that can represent virtually every written language in history.  I presented the OpenAccess software changes required to fully support UTF-8 and showed you how to convert your existing application software to properly manipulate UTF-8 in the OpenAccess oaString class.

UTF-8 with Standard OpenAccess

You can write an internationalized application based on any standard OpenAccess release by following these simple rules:

  • Upon startup, get the locale from the user environment using,
    setlocale(LC_CTYPE, "");

    If you are using an application framework, it may set the locale for you.  For example, Qt QApplication sets the locale.

  • Only use oaString methods that do not involve a count
  • Perform string  manipulations that do involve a count in a Unicode compatible string class like std::string or Qt QString.  You can in fact use many of the oaString methods that involve a count with UTF-8, but it hardly seems worth the risk and confusion.
  • Only ASCII strings should be converted to oaNames using OpenAccess namespaces.  The resulting oaNames generally end up in netlists, and you don’t want a non-ASCII netlist.  Most namespaces tell you about a non-ASCII character by throwing an exception.
  • If you must use an OpenAccess namespace with a non-ASCII string, use oaNativeNS

That’s all you need to do.  You may already be coding this way.

As a demonstration vehicle, I used vView™, a Qt application that creates a design containing an oaText object, and then displays it.  vView further provides the ability to modify the oaText object.

OpenAccess Text Objects

Now let’s look at rendering text.  OpenAccess provides three classes that represent text displayed on the screen of a graphics editor:

  • oaText
  • oaEvalText
  • oaTextDisplay (base class)

Bounding Box Calculator

Like all oaShapes, text objects have a bounding box.  Since each graphical application renders text on the screen differently, OpenAccess cannot know how big it will appear.  Therefore the application must provide implementations for the oaText::getBBox() and oaTextDisplay::getBBox() methods.

The bounding box calculator can be provided as either a plugin, or as an in-memory instance.  I first made a plugin, but due to the close coupling between the bounding box calculator and text rendering software, I switched to the in-memory model.  Perhaps the best thing about the in-memory model is that it is compiled into your application where it will not get lost.  The OpenAccess plugin search process is a constant source of trouble for developers and users alike.

Translating oaString to QString

When translating a string from an OpenAccess oaString to a Qt QString, use:

QString qString(QString::fromUtf8(static_cast<const char*> (oString)));

Finding the Text Bounding Box

The Qt QFontMetrics::boundingRect() method returns a text bounding box based on the font, size, and of course the string itself.  I could not get QFontMetrics::boundingRect() to work with any text alignment except upperLeft, so I transformed the bounding box according to the OpenAccess oaTextAlign text alignment myself.

Translating oaFont to QFont Family

The OpenAccess font types provided an unwelcome opportunity to exercise artistic license.  I did a bit of research and used the following mapping to Qt font families, keeping in mind that Japanese and Chinese fonts come in only a few varieties due to the large number of characters they contain. Still, you can rely on QFont to always select a reasonable font from among those installed:

const char* qtText::getQFontFamily(const oaFont &oFont){    switch (static_cast<oaFontEnum>(oFont)) {    case oacEuroStyleFont:        // San serif but actually more mid-century modern        return "Sans Serif";    case oacGothicFont:        // Obvious choice        return "Sans Serif";    case oacMathFont:        // Open to interpretation        return "Sans Serif";    case oacRomanFont:        // Obvious choice        return "Serif";    case oacScriptFont:        // Open to interpretation        return "Cursive";    case oacStickFont:        // Open to interpretation        return "Sans Serif";    case oacFixedFont:        // Obvious choice        return "Monospace";    case oacSwedishFont:        // The IKEA logo uses san serif, so thaar you go        return "Sans Serif";    case oacMilSpecFont:        // Lettering that meets US DoD mil-std-130 should be        // all capitals in a sans-serif font        return "Sans Serif";    }}

If you (especially Cadence Virtuoso people) would like to share your recommended font mapping, please share it with us in a comment.

Text Rendering

Text rendering is performed with Qt QPainter.  Convert the oaString to a QString as shown above, and draw it with QPainter::drawText().

Japanese oaText rendered in vView

Translating QString to oaString

When you create an oaText or change its text value, translate the Qt QString to an OpenAccess oaString containing UTF-8.  For example, to set the string value of an existing oaText:

oaString oString(static_cast<const char*>(text.toUtf8()));if (oString.isEmpty()) {    // An empty oaText object is forbidden    oString = " ";}oText->setText(oString);

Note how I use just the oaString constructor, assignment operator, and isEmpty(), none of which involve a count.

UTF-8 in an OpenAccess oaName

Most oaNameSpaces do not allow non-ASCII characters–they throw an exception when they encounter one. The exception is the oaNativeNS.  I do not recommend non-ASCII names that might appear in netlists, but just for amusement I used a Japanese name for the design created within vView:

  • Library name and library path “ライブラリ” (“library” in Japanese)
  • Cell name “設計” (“design” in Chinese or Japanese)
  • View name “layout”.  I use English here because non-standard view names are just wrong.

It works.  The OpenAccess maskLayout viewType is on disk in file,

ライブラリ/#e8#a8#ad#e8#a8#88/layout/layout.oa

where “#e8#a8#ad#e8#a8#88” is the OpenAccess namespace ‘#’ encoding of cell name “設計”.   Also, the lib.defs library definition file properly relates the ‘#’ encoded OpenAccess library name to file path “ライブラリ”:

DEFINE #e3#83#a9#e3#82#a4#e3#83#96#e3#83#a9#e3#83#aa   ライブラリ

Amusing indeed.

Comments

Popular posts from this blog

Would You Like to Read a Removed Post?

You have been redirected to this page because you were looking for a post that I removed. From time to time I remove a post that I think is outdated, but I could be wrong. If you want to read a deleted post, please tell me by adding a comment to this post. Describe the article by telling me the title, URL or content. Thank you and sorry for the trouble.

The Reef Lounge

When I was about four, we vacationed at the Handerly Hotel & Resort in San Diego (formerly the Stardust Motor Hotel).  That place was heaven on earth as far as I was concerned. I loved the pool. Next to the pool there was a bar, and behind the bar was an underwater theater. It was here that I saw one of the most outlandish scenes I have ever witnessed.

Build with CMake in Eclipse

Cross-platform CMake can generate a wide variety of build systems.  The CMake 2.8 project generator for Eclipse does not work, so you must create the project and configure it to build with GNU Make .  Here’s how to do it on Linux.