API Question oapiCreateFont & using custom fonts

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
Hello, :hello:

I've been playing with SketchPad recently and I found it rather straightforward. There is, however, a point that is very unclear to me.

The "oapiCreateFont" function is supposed to allow you importing fonts into the graphic client. So, according to what I've seen in the Deltaglider SDK sample, it works that way :

Code:
oapi::Font *font = oapiCreateFont (17, false, "[B]MyFont[/B]", FONT_NORMAL);
skp->SetFont(font);
...
mycode...
...
skp->ReleaseFont(font)

Problem is the char * face parameter, in bold above. In "Draw.h" we can read this :

* \note Overloaded font implementations should understand at least the
* following generic face names: "Fixed" (fixed pitch font), "Sans"
* (sans-serif font, and "Serif" (serif font) and translate them to
* appropriate specific fonts, e.g. "Courier" or "Courier New" for "Fixed",
* "Helvetica" or "Arial" for "Sans", and "Times" or "Times New Roman" for
* "Serif".
* \note If a font name is not recognised, the \e prop value should be
* checked. If prop==true, the default "Sans" font should be used. If
* false, the default "Fixed" font should be used.
*/

This is where I get lost.

What I am supposed to write as a string ? The name of the font file located in Windows\Fonts ?

I don't get that part at all :

* following generic face names: "Fixed" (fixed pitch font), "Sans"
* (sans-serif font, and "Serif" (serif font) and translate them to
* appropriate specific fonts, e.g. "Courier" or "Courier New" for "Fixed",
* "Helvetica" or "Arial" for "Sans", and "Times" or "Times New Roman" for
* "Serif".

How the function "translates" Fixed or Sans to an "appropriate specific font" ? How to have control on what "appropriate specific font" is chosen ?

To sum it up, I want to display a Cyrillic font on Orbiter HUD from my (european) computer. I have a Cyrillic font but can't get it into Orbiter.

Thanks for your help, :tiphat:
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Sans, Serif, and Fixed (or Monospace) are aliases for standard system fonts that are used as: Sans Serif typeface - in Windows it's "Arial" font, [ame=http://en.wikipedia.org/wiki/Serif]Serif[/ame] typeface - in Windows it's "Times New Roman" font, and [ame=http://en.wikipedia.org/wiki/Monospaced_font]Monospaced[/ame] (or fixed pitch) typeface - in Windows it's "Courier New" font. Other systems or changed system settings may define different fonts that are used as serif, sans, fixed fonts.

For example code tags or [font="monospace"][/font] tags here on forums are displayed when viewed in Windows with "Courier New" font, which is mono-spaced, but in Linux they use different one ("Luxi Mono" in my case).


This means for you, that if you use for font: "Sans" - the function should get the standard sans serif font defined in system, "Serif" - the function should get the standard serif font, "Fixed" - the function should return the standard monospaced font.

If you define explicit fonts by their name, these explicit fonts will be used if they are installed in system. Otherwise, if you use "sans", "serif", "fixed", the selected fonts can be different between different systems or users, but although they will use different font name, the displayed result should be similar.

BTW. You don't use the file name of the font from "Windows\Fonts" but the name of the font (for example from Control Panel, or font selection box in Office, etc.).
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
If you define explicit fonts by their name, these explicit fonts will be used if they are installed in system

Thanks, I got the default system fonts aliases thing. But now, if I want to get a specific font like, let's say, Lucida Sans Unicode :

Code:
oapi::Font *font = oapiCreateFont (17, false, "[B]Lucida Sans Unicode[/B]", FONT_NORMAL);
skp->SetFont(font);
...
mycode...
...
skp->ReleaseFont(font)

I get the "Courier New" font if the proportional flag is set false, and the "Arial" font if it is set true, but not "Lucida Sans Unicode". Which is the consequence of the name being not recognized :

* \note If a font name is not recognised, the \e prop value should be
* checked. If prop==true, the default "Sans" font should be used. If
* false, the default "Fixed" font should be used.

But I don't see what I'm doing wrong... :hmm:

... or I didn't understood "define explicit fonts by their name" or how to do it...
 
Last edited:

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
As it's written in the API reference:
Other font names may not be recognised by all graphics clients. In
that case, the default fixed or sans-serif font will be used, depending on the value of prop.
Graphics clients (in-line included) may, but need not return the explicit fonts if other fonts than those 3 defined are used.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
Graphics clients (in-line included) may, but need not return the explicit fonts if other fonts than those 3 defined are used.

Yes, but the problem is I'm currently trying to get it work with the default in-line client, and it returns happily the explicit fonts, no matter what font name I enter in the "facename" string.

In fact, it recognizes only the 3 explicit font names, and doesn't recognize anything else.

So, is there a way to use another font that those 3 explicits, or am I fighting against windmills ? :shrug:
 
Last edited:

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
In fact, it recognizes only the 3 explicit font names, and doesn't recognize anything else.

This is why (GDIClient):
Code:
GDIFont::GDIFont (int height, bool prop, const char *face, Style style, int orientation): oapi::Font (height, prop, face, style, orientation)
{
	char *def_fixedface = "Courier New";
	char *def_sansface = "Arial";
	char *def_serifface = "Times New Roman";

	if (!_stricmp (face, "fixed")) {
		face = def_fixedface;
	} else if (!_stricmp (face, "sans")) {
		face = def_sansface;
	} else if (!_stricmp (face, "serif")) {
		face = def_serifface;
	} else if (_stricmp (face, def_fixedface) &&
			   _stricmp (face, def_sansface) &&
			   _stricmp (face, def_serifface)) {
		face = (prop ? def_sansface : def_fixedface);
	}
	int weight = (style & BOLD ? FW_BOLD : FW_NORMAL);
	DWORD italic = (style & ITALIC ? TRUE : FALSE);
	DWORD underline = (style & UNDERLINE ? TRUE : FALSE);
	hFont = CreateFont (height, 0, orientation, orientation, weight, italic, underline, 0, 0, 3, 2, 1, 49, face);
}
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
Still, I know that Thorton (russian) & No_Matter (french) individually managed to write things on the HUD in Cyrillic, I've seen screenshots.

That will remain a mystery I guess... :hailprobe:
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Still, I know that Thorton (russian) & No_Matter (french) individually managed to write things on the HUD in Cyrillic, I've seen screenshots.

That will remain a mystery I guess... :hailprobe:

Arial font and Courier New, as also Times New Roman define Cyrillic. They are Unicode.

There's no mystery. Just look at the character table.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
What will happen if you define your Unicode string as wchar_t and use WideCharToMultiByte function to convert it to CP_UTF8 char string for displaying?
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
I will try that tomorrow...

I just tried to change my system code page from 1251 to 1252 using the language XP control panel. That way VC++2008 compiles cyrillic characters without showing errors. But Orbiter in-line client didn't like it at all :



And when I use the chcp command, it tells me that the "French" setting is page 850 (not 1152 as said VC++) and the "Russian" setting is page 866 (not 1251).

:compbash: :suicide:
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
In fact, it recognizes only the 3 explicit font names, and doesn't recognize anything else.

Unfortunately that is true. It's probably an implementation error I don't think it was ment to work like that from the first place. In a debugging purposes in the D3D9Client you can put the "asterix" in the front of the name like "*Tahoma" to actually use the font but it won't work with the inline engine.

---------- Post added at 08:03 ---------- Previous post was at 07:40 ----------

What will happen if you define your Unicode string as wchar_t and use WideCharToMultiByte function to convert it to CP_UTF8 char string for displaying?

Let me know if that works with the inline engine. If it does then I can try to implement it in the D3D9Client. But it's a little problematic because the client will pre-render all fonts into a textures, therefore, it can't use the entire unicode range. I would need a list of the ranges those are needed. Also it looks like the western codepage from 0x80 to 0xFF seems to contain unicode charters from here and there. It would be easier from the D3D9Client point of view if the oapiCreateFont function would allow to declare the codepage.

---------- Post added at 08:33 ---------- Previous post was at 08:03 ----------

I don't think it works. As far as I can tell TextOut doesn't know how to print UTF-8. Therefore, UTF-8 string would need to be converted into a wchar and then written using TextOutW() in the GDIClient. It might be better to have a different Text() function for wchar strings in the SketchPad.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,283
Reaction score
3,250
Points
203
Location
Toulouse
Jarmonik, you're the best !! :bighug:

At worse, I'll do a "D3D9 Russian" and a "D3D7 English" version. I guess that a line could be included in the .scn file : depending of the value returned, the .dll could process the english part or the russian part of the code. It would even allow users to get the english version under D3D9.

Notice : what you can read under is just english into cyrillic, not russian, it was only to test the thing :



Edit : of course, if Dr. Martins could implement the same thing in the in-line D3D7 client, that would be the best ! ;)

Edit2 : and maybe that would draw more Japanese/Chinese/Indian (tongues that have their own alphabet or ideograms) etc... people into Orbiter...
 
Last edited:
Top