views:

453

answers:

6

I need to draw a column of vertical text (in Japanese language - it is drawn top-to-bottom instead of left-to-right) in my native C++ Win32 GUI application. I've looked through MSDN and only found how to draw right-to-left text.

How do I output top-to-bottom text except drawing each character separately?

+4  A: 

The straight Win32 API has no way to draw (unrotated) vertical text (with an arbitrary font) in that way except 1 character at at time.

You can do more complex text output with GDI+ But that probably isn't what you want either, since the text will be vertical, but the characters will also be rotated.

Similarly, you can use CreateFont with an lfEscapement value of 900 or 2700 to get rotated text, but this will rotate everything. So that doesn't help either.

To do Japanese Top to Bottom drawing, you want the characters to be unrotated, but the placment of each character to advance in Y but not in X. Windows has no API that does this for all fonts. (you can do right-to-left and left-to-right, but not top-to-bottom).

In theory creating a font with an Orientation of 900 and an escapement of 2700 would do what you want, but it appears that if you set the escapement, then the orientation is ignored for most fonts. It's possible that for Japanese fonts, this will work differently. It's worth spending some time to play with. (see the addendum for more information on this)

I think your best bet is a probably a loop drawing one character at a time with ExtTextOut which gives you full control over the placement of each character.

If you use ETO_OPAQUE to draw the first character in a column, and not with all of the others, then you will be permitted to kern the characters vertically if you need to.

Addendum

Roygbiv points to an interesting article that says that fonts whose names begin with an @ behave differently then other fonts when you use CreateFont a font with an lfEscapement value of 2700, These special fonts produce upright characters while still advancing down the page. So while there is no way to do what you want for arbitrary fonts, you may be able to get it working using certain fonts.

Options for Displaying Text

Out of curiosity, i wrote a small console app to enum fonts and list the names. My Windows Server 2003 machine has not fonts with names beginning with @. But my Windows 7 machine has a few. All seem to be Chinese fonts though, I see no Japanese fonts in the default Windows 7 Ultimate install.

John Knoeller
Untrue - Win32 can do it. See my post.
RED SOFT ADAIR
+1  A: 

In Win32, use the lfEscapement member of a LOGFONT structure to define the rotation of a font:

LOGFONT LogFont

LogFont.lfEscapement = 900;  // 90 degreees rotated text
... // Many more initializations
HFONT newFont = CreateFontIndirect(LogFont);
SelectObject(hdc, newFont);

char tx[255];
strcpy(tx, "vertical text");
TextOut(hdc, x, y, tx, strlen(tx)); // draw a vertical font

For More Information see the online Help of LOGFONT structure and of the CreateFontIndirect Function

RED SOFT ADAIR
Read the question again, rotating the characters doesn't help in this case.
John Knoeller
Hmm - you are right the question means something else.
RED SOFT ADAIR
I take it back, supposedly this _will_ work with some fonts, just not the normal english ones.
John Knoeller
A: 

Just an idea: Did you try using DrawText or DrawTextEx using a very narrow rectangle that just fits the widest character?

RED SOFT ADAIR
That sounds like a bad idea, considering Japanese mixes Kanji, Hiragana and Katakana script.
MSalters
A: 

The method this library uses sounds slow, but if do want it, it appears source code is provided:

http://www.ucancode.net/faq/CDC-DrawText-Drawing-Vertical-Text.htm

You may also find this discussion useful - http://www.eggheadcafe.com/forumarchives/win32programmergdi/Aug2005/post23542233.asp - apparently you need a vertical font (one beginning with @) and the API will take care of the rest.

taspeotis
+1  A: 

The correct answer is:

There are three methods to do this:

  • Using the Edit or RichEdit controls to render your text
  • Using the Uniscribe API
  • Using the TextOut function with a font face name that begins with an at sign (@).

Here is an article that discusses some of these approaches.

Fortunately, with Win32 you do not need to write code to rotate characters. To display text vertically on Windows 2000 and Windows XP, enumerate the available fonts as usual, and select a font whose font face name begins with the at sign (@). Then create a LOGFONT structure, setting both the escapement and the orientation to 270 degrees. Calls to TextOut are the same as for horizontal text.

Yes. Another link: http://msdn.microsoft.com/en-us/library/cc194859.aspx
Hans Passant
A: 

As a quick hack type of answer, what happens if you use a standard control (CEdit for instance) and insert a new-line after every character typed?

John