Questions similar to this appear on the MicroStation Programming Forum.
Q You are writing code that must show a numerical fraction, and want to use any font to display that text. You are looking for answers to questions like these …
A We've written a VBA project that creates fractional text such as ¾. You can create a fraction using any font, whether TrueType or a legacy RSC font. Another term for that type of display is a stacked fraction.
Engineers, scientists and draftspeople using the Imperial system of measurement often want to express a number as a fraction, such as 15⁄16. Some fonts provide a limited number of common fractions such as ¾ and ⅔. However, engineering models are often dimensioned in sixteenths, thirty-seconds or sixty-fourths, which are not available in most fonts.
Bentley Systems solved that problem decades ago by provided
RSC fonts (resource fonts) for MicroStation.
For example, the ENGINEERING
font includes
glyphs
for fractions up to 63⁄64.
By that we mean that a single character includes everything you see in that fraction.
RSC fonts are great in MicroStation and let us dimension a DGN element with a fractional number.
Assuming you know the character code of the glyph in the RSC font, you can create it in VBA using the Chr$()
function.
Unfortunately, other programs (e.g. Microsoft Office
or Adobe
PDF),
don't recognise those RSC fonts.
Consequently, you can't ask MicroStation to create accurately a PDF that displays a DGN model that includes fractions.
Likewise, you can't copy-and-paste a fractional dimension into your Microsoft Word document.
Most desktop office applications recognise fonts that follow the TrueType standards. MicroStation is also capable of using TrueType fonts. TrueType fonts were introduced with MicroStation V8 in 2001.
If you use TrueType fonts in MicroStation, text can be rendered accurately in other applications such as Microsoft Office and in PDF files. However, TrueType fonts typically provide only a small number of fractional glyphs. That leaves us with the question: How to render a fraction using any font?
How can we create a fraction using any font? The answer lies in MicroStation's text composition capabilities. MicroStation's text dialog provide many ways to manipulate text …
The text editor's right-click pop-up menu contains items that are used to copy, move, delete, and select text, and insert fields derived from properties. The Insert Stacked Fraction menu item pops the Insert Stacked Fraction dialog …
That dialog enables us to compose a fraction using the current font, whether that be TrueType or a RSC font. We are not restricted to the limited number of fractions embedded in a RSC font, but are free to write ridiculous fractions such as 131⁄437.
This article shows how to write code in VBA that mimics the MicroStation text editor's fraction composition tool. There is no API for MicroStation's text editor, so we must improvise.
If you're not interested in the code, you can skip the following explanation and download the VBA project. The project is freeware and includes the source code.
The FractionText VBA project shows the dialog (VBA UserForm
) when you start the macro …
vba run FractionText
The dialog contains a text box for prefix and suffix strings. They frame the fraction string that is composed from the user interface in the Fraction pane. The composed string is displayed in the Result text box.
The Fraction pane works like MicroStation's text editor fraction tool. Specify a numerator and denominator, which together make the fraction. In the screenshot, we've specified 3 as the numerator, and 16 as the denominator. The resulting fraction is 3/16.
Other controls let us specify a vertical offset and a size for the fraction.
The vertical offset adjusts the Y-origin of the fraction text element relative to the prefix text. The offset is expressed as a percentage of the text height.
The size adjusts the scale of the fraction text element relative to the prefix text. The size is expressed as a percentage of the text height.
We want to put the DGN text into a DGN container, so that the relative position of each component is fixed. For example, if you subsequently want to perform some operation on the text elements that represent the fraction, you want all those elements to move together. In the screenshot below, there are several text elements in a container …
3
in this example)
/
in this example)
16
in this example)
MicroStation's idiom for a container is either a cell or a text node. A cell is the most adaptable container, because it can include not only text but also other graphic elements. A text node is a text-only container, and is what MicroStation creates when you use the fraction tool in the text editor.
We couldn't decide which to use, so provide both.
The VBA code lets you create either a cell or a text node:
the Create Cell and Create Text option buttons let you decide at run-time.
The VBA code contains classes clsCreateCell
and clsCreateTextNode
, so you can invoke your preferred container.
clsTextPlacer
is a VBA tool that Implements IPrimitiveCommandEvents
.
Once started, it lets you place the fraction text interactively.
Depending on your choice of cell or text node, it invokes one of
classes clsCreateCell
or clsCreateTextNode
to create a container element.
This class is straightforward: it creates a text element for each of the prefix, fraction and suffix strings,
and puts them into an array of Element
.
For each text element, it adjusts the origin and size to create a horizontal layout.
It creates a CellElement
from that array,
which is passed to the placement tool.
Creation of a TextNodeElement
is complicated by VBA's simplistic API.
VBA creates a multi-line TextNodeElement
(vertically-aligned) list of TextElement
s.
We want to adjust the coordinate and size of each TextElement
in the TextNodeElement
,
to create a horizontal alignment.
The TextNodeElement
API lets us add text strings to the node, with TextNodeElement.AddTextLine (line As String)
.
It doesn't let us add a TextElement
, so we have no opportunity to modify the text origin or size.
Instead, we implement a hack …
TextNodeElement
and add our strings to it
TextNodeElement
using the saved element ID
TextNodeElement
using the saved element ID
TextNodeElement
You may think that it's odd to read the cloned TextNodeElement
twice.
I found that when I assign the text style to a component, it resets the component's geometry.
By modifying and writing the text styles, then re-reading the temporary text node, we avoid that problem.
The text node API is bizarre!
Finally, the edited TextNodeElement
is passed to the placement tool
A sample project is available. It includes code similar to that above and the progress form.
You can download a ZIP file, and then extract Fraction.mvba
to a folder
that MicroStation can find. A good place to put it would be
..\Workspace\Standards\macros
, or any other folder specified
in the MS_VBASEARCHDIRECTORIES
configuration variable.
Start the macro with this MicroStation key-in …
vba run [Fractions]modMain.Main
Post questions about MicroStation programming to the MicroStation Programming Forum.