How DataFlex Handles Fonts

Font Sizes in DataFlex

DataFlex supports three ways to set a font size:

Physical_FontSize

This is approximately the size of a font in physical pixels. This allows you to set height and width, but you would always want to set the width to 0, allowing Windows to set the width. This varies from computer to computer and is not scalable. This is a legacy interface.

FontSize

This corresponds to the Windows LogicalFont (actually, it’s the positive number style of LogicalFont). This allows you to set height and width, but you would always want to set the width to 0, allowing Windows to set the width. As noted, LogicalFont varies from computer to computer and is not scalable. This is a legacy interface.

FontPointHeight

This corresponds to point height and it scales. FontPointHeight is a new addition to revision 17.0.  This is the property you want to use. It renders FontSize and Physical_FontSize obsolete.

Font Size and Dialog Units

In DataFlex, object sizes and locations are set with dialog units. The GUI or pixel size of a dialog unit is determined by your font size. The average height and average width of characters is used to determine the number of pixels for both a vertical and horizontal dialog unit. The larger the physical font size, the larger the dialog unit will be.

While it should be obvious that changing the font height will change the physical size of a font, it should be noted that changing any font attribute might change the physical size of a font. Whenever the size changes, the dialog unit size changes. In other words, the dialog unit’s size is determined by more than just the font size. If you hold the size constant and change the typeface or font weight, the dialog unit size may change.

How Dialog Units are used

The dialog unit is used by an object’s Size and Location properties as follows:

Restated, an object is located based on its parent’s font metrics, but is sized based on it own font metrics.

The Form_Font Properties

Some objects, such as Form, Combo and Button contain forms. This is a legacy concept. Since these objects are all single item objects, each object will only contain one form. These form objects contain an interface that duplicates the object’s interface. This is the case with font properties, where you have Form_Typeface, Form_FontPointHeight, Form_FontWeight, Form_FontItalics and Form_FontUnderline.

Because forms are a legacy feature, we would normally advise that you not use these properties. With fonts, it turns out that these form properties have an unintended benefit. When you set the form_font properties, the size of control does not change. This has the advantage that the control may line up better with its sibling objects and the disadvantage that the size may not be a good fit for the font.

Therefore, if you want the size of your control to not change based on your font, use the form_font properties. If you want the size of your control to change, use the regular font properties. Don’t use both in the same object.

Use this lightly. Be aware that this is an unintended behavior and that we may provide a better way of handling this in the future.

Global Typeface and Font Height

When an application is run, it needs to acquire a default typeface and font height. Prior to DataFlex 17.0 this was set to a Typeface of “MS Sans Serif” and a Physical_FontSize of 12. Because this uses the Physical_FontSize property, this setting would not scale with different DPIs.

As of DataFlex 17.0 you now simply specify that your default typeface and font height should be the Windows system default. Rather than using Physical_FontSize, the scalable FontPointHeight is used. In Windows Vista and 7, the default is Segoe UI/9pt; in XP it is Tahoma/8pt.

This default typeface and height is applied to DataFlex objects. COM objects will have their own mechanism for font assignment, although the norm will be to use the same Windows default typeface and point height. Therefore, the appearance of DataFlex and COM fonts will be consistent.

How Fonts are Assigned to Objects

Rule 1: When a container object is created, it uses the global font.

Rule 2: When a control object is created, it uses its parent container’s font.

These two rules will explain most of the behaviors you see in an application. They are a simplification of the actual process, which will be described in detail. For now, this may be all you need to know and may wish to skip this section and revisit it later.

Font assignment is somewhat complicated. It is probably best to look at this from two perspectives. The first is an application that assigns no explicit fonts at all. Anytime you set one of the font messages (e.g., Typeface, FontPointHeight, FontWeight), an explicit font is created for that object. Defining custom font characteristics is the second perspective and this makes things more complicated. We will start with the simpler case where there are no custom fonts at all.

Using the Default Font Settings

Font assignment differs with Containers and Controls.

Therefore, in a default setup an explicit font is created for every container. That font is shared by all child controls but not child containers. There are some exceptions here with some objects such as cTextEdit and TreeViews and COM objects.

Assigning your own Font Settings

You create a custom font by setting one of the font properties (e.g., Set FontItalics to True). Once you do that the object will now create its own explicit font and it will not delegate to share a parent font.

When you create a custom font the size of a dialog unit may change, which means that the size of the object and the location of it child objects will change based on the font’s dialog unit. This creates the issue where you might have two forms with the same dialog size (e.g., set Size to 14 100) with different fonts (typeface, weight or height) , which will appear as different sizes on your screen.  Sometimes this is desired and sometimes not. There is an important and useful exception with form fonts. If you create a custom form font, the size of its control does not change.

The complexity of mixing default and custom fonts

There are a number of challenges when you start working with custom fonts.

  1. Containers do not obtain all of their default behavior from their parent. Containers always create their own font using the global typeface and font height. If you had two nested containers A and B you set a font in A, its child (B) would not acquire this font and would use the global font instead. To make this even more confusing, any child controls in A would use the new font, while child controls in B would use the global font.

  2. Containers and controls behave differently. If you place a control and a container inside of a parent container and assign the parent container a custom font, the control will use that font while the container will not. This means that the sizing of the container and control siblings will be different. To make this work the developer would have to apply a custom font to either the child container or child control object.

  3. The existence of fonts and form fonts is confusing. For the most part these two types of fonts do the same thing and they exist for legacy reasons. Normally, we’d tell developers to just use the font interface, but the fact that form fonts do not resize the control can, in certain cases, be useful.

  4. With controls it is not really clear where the font is coming from. It can be shared from its parent container, it can be defined in the control or defined in the control’s form.

  5. When custom fonts are applied after a control is paged, there is a bit of an inconsistency. The control is redisplayed using the new dialog units, but child controls are not relocated using that new metric.

While all of this may seem confusing, this can be simplified by following a few simple guidelines. These will be discussed later, but the important point here is to avoid setting fonts in containers. If you need to set a font, set it in the control. This way containers always use the same metrics for sizing themselves and locating child objects.

 

See Also

Understanding Fonts in DataFlex

Understanding Windows Fonts

How to Use Fonts in DataFlex