Link to home
Start Free TrialLog in
Avatar of qocarlos
qocarlosFlag for Saint Kitts and Nevis

asked on

How to draw vertical text

Hi,

Can anyone tell me how to draw text vertically using a mapping mode other than MM_TEXT (e.g. MM_TWIPS)? I managed to draw the text vertically on the screen but when this same text is rendered in a enhanced metafile device context, it appears that the text is rotated by other additional 180 degrees ???
This problem doesn’t happen in MM_TEXT mode though …

Any help will be greatly appreciated!!
Thanks

p.s. (I'm using MFC/Doc/View, VC 6.0)
Avatar of AlexFM
AlexFM

Use lfOrientation font parameter. Font should be true type:

void CMyView::OnDraw(CDC* pDC)
{
  CFont font, *pFont;
  LOGFONT lf;
  pFont = pDC->GetCurrentFont();
  pFont->GetLogFont( &lf );

  lf.lfEscapement = lf.lfOrientation = 900;              // 90 degrees

  font.CreateFontIndirect( &lf );
  pFont = (CFont*)pDC->SelectObject( &font );

  pDC->TextOut( 100, 100, "Hello, world!" );

  pDC->SelectObject( pFont );
}
Another way is using of coordinates transformation.
See SetWorldTransform (may be used in WinNT or later).
Avatar of qocarlos

ASKER

Hi Alex,

Thanks for your comment.
However, I think I was not clear enough on the problem I'm having. I know how to daw text vertically on the screen, the problem is that the text is not correctly rendered in an enhanced metafile device context when the mapping mode is other than MM_TEXT.
For example, if the text is displayed in the screen as this:

H
E
L
L
O

In the metafile I get:
  O
  L
  L
  E
  H

Any idea?


Avatar of Zoppo
Hi qocarlos,


this is the correct behavior:  For all predefined 'mapping-modes' except 'MM_TEXT' the 'positive-y direction' is 'up'.

So, only suitable way is to either implement drawing code in a way that it works correctly with different mapping-modes
or use only one 'kind' of mapping-mode with well-known direction.


ZOPPO
Hi Zoppo,

Yep, I know how the y-axis runs in non MM_TEXT modes.
I'm using MM_TWIPS in my app. Everything works fine with the vertical text except with metafiles. I can print the vertical text with no problems and in the text is displayed properly on the screen. The problem is with the metafiles.

Weirdly enough, if the metafile is pasted in Word 2002, then everything is ok. However, if the metafile is pasted in former versions of MS Word (2000 and earlier) or even in Photoshop, the vertical text is rotated by 180 degrees. This strange, inconsistent behavior is driving me mad.  
I could provide a sample app that shows the problem I’m facing with the metafile.

Thanks for your help!
Show the code that creates the metafile.  I presume you are using CreateEnhMetafile... and not the obsolete CreateMetafile.

One idea is to have MS Word 2000 generate a simple metafile and compare it to one generated by MsWORD 2002... there may be some sort of undocumented difference.  Perhaps a GdiComment or something.
This is the code I'm using to create the (enhanced) metafile:
=================================================
CRect rMargins ,rPaper, rPrintable;
      GetPageInfo(&rMargins, &rPaper, &rPrintable);
      
      CRect rr = rPrintable;
      
      CMetaFileDC * m_pMetaDC = new CMetaFileDC();
      //draw meta file
      CClientDC clientDC(this);
      OnPrepareDC(&clientDC);
      
      
      m_pMetaDC->CreateEnhanced(&clientDC,NULL,NULL,"Metafile");
      m_pMetaDC->m_hAttribDC = clientDC.m_hDC;
      m_pMetaDC->m_bPrinting = true;
      
      //Zoom factor
      long extValue,viewValue;
      
      extValue=labs(m_ScrollRectLog.bottom);
      viewValue=labs(m_ClientRectDev.bottom);
      m_pMetaDC->SetMapMode(MM_ISOTROPIC);
      
      CSize vSize = m_pMetaDC->SetWindowExt(extValue, extValue);
      CSize rSize = m_pMetaDC->SetViewportExt(viewValue,viewValue);
      
      
      m_pMetaDC->SetWindowOrg(m_WinOrg);
      
      DrawHere(m_pMetaDC,rPaper,rPrintable,rMargins); //This is the fucntion that actually draws all the figures and text
      
      
      //close meta file dc and prepare for clipboard;
      HENHMETAFILE hMF = m_pMetaDC->CloseEnhanced();
      
      //copy to clipboard
      OpenClipboard();
      EmptyClipboard();
      ::SetClipboardData(CF_ENHMETAFILE,hMF);
      CloseClipboard();
      //DeleteMetaFile(hMF);
      delete m_pMetaDC;


===================================

If you think it may help, I could send you a demo application with full source code.

Thanks!!
I'm a little short on time for testing, but two things popped out.  First from the MSDN help:

     If lpBounds is NULL, the graphics device interface (GDI) computes the dimensions of the
     smallest rectangle that can enclose the picture drawn by the application. The lpBounds  
     parameter should be supplied where possible.

Try supplying an arbitrary rectangle in the CreateEnhanced() call .

Next, there are member functions for assigning the hDC that might be safer than just using =

-- Dan
Thanks DanRollins and sorry for the delay in getting back to you.

I tried your suggestion on supplying a rectable in CreateEnhanced but it didn't solve the problem.
>Next, there are member functions for assigning the hDC that might be safer than just using =

Thanks for this but to be honest I don't expect this to help with the vertical text problem.

I would really appreciate if you could help me out with this problem. I really need to solve it as soon as possible since I have many users complaining to me about this issue. As I said, I could send you a small demo application. If necessary, I could increase the number of points.

Thanks in advance
Carlos
But it's worth a try, don't you think?  
The MFC programmers usually have a rreason when they supply an accessor fn...
There are two DCs involved and I'm sure that it's critical that they remain in sync and so forth.

You can send me a project to the email addr in my profile... I'd prefer one that is whittled down to the bare minimum to illustrate the problem.

-- Dan
Thanks Dan, I've sent you the demo app.

Carlos
I haven't tweeked exactly why... but this fixes it.

      CAutoFont autofont("Courier New");
      autofont.SetBold(TRUE);
      autofont.SetEscapement( 900 );
      if ( pDC->m_bPrinting ) {                            <------- added
            autofont.SetEscapement(2700);  <------- added
      }                                                              <------- added  
      autofont.SetHeight(300);
      autofont.SetItalic(TRUE);
      CFont *oldFont=pDC->SelectObject(&autofont);
   
      pDC->TextOut(pt.x, pt.y, str);

The clue was that in Word, when you "edit the picture" it says that the rotation of that text is 270 degrees -- though it was clearly being set at 90 in the program.

I don't have much experience with metafiles or even direct GDI -- it's amazing how much programming you can do with dazzling interfaces and never need to actually draw anything!  But I have to think that there may be some internal transformation that takes place between a CDC set for printing and one that is set for the screen.

I tried it only on Win2K in Word2K and WordPad.  In Excel2K, the entire picture is mirror image and that remains a mystery.

If you have continued problems, I suggest switching to the use of DrawText... only because the example used that rather than TextOut.

-- Dan
Thanks Dan,

This solves the problem partially. I guess you’re using Word2000 whilst I’m using Word2002 (Office XP). By using your solution now the metafile is correctly pasted in Word2000 (and WordPad) but it’s not in Word2002 now, that'’s really weird :-( In addition, if you go to Print Preview in the application you can see that the text is now not correct.
I have found that if you select Paste Special (rather than simply Paste) in Word 2002 and then select Image instead of metafile, you get the same result as with Word2000. Furthermore, it seems to me that PowerPoint 2002 uses by default the “Image” format instead of the metafile one. Photoshop does also use the same “Image” format.  
The question is: could it be possible to have a solution that doesn’t depend on the target application?
Interestingly enough, this problem only arises with mapping modes other than MM_TEXT. What I can’t understand is why this problem is not documented somewhere, I shouldn’t be the first who has met this problem!
Thanks for your help. Now at least I can implement a patch for those users working with Word 2000, yet I’d like to have a more ‘universal’ solution.

Carlos
>I tried it only on Win2K in Word2K and WordPad
Oops, forget my comment "I guess you’re using Word2000" ...
I think that it *may* be a universal solution to use DrawText rather than TextOut.  Did you give it a try?

Then, the next thing for you to try would be to start over with an entirely new test program -- written completely from scratch: start with a dialog-based app so that the document/view architecture does not affect anything and you do not use any of the MFC printing logic or eveen CDC class.  All it should do would be to create a metafile with a circle and the vertical text and place it on the clipboard.  That way you can eliminate all of the confusing factors introduced by MFC and that sample app.

Finally, you can use the metafile functions to enumerate each action in the metafile and "decode" it by hand to see what is going one.  On resource here would be to load the file into Word, use its "edit drawing" command and make a small change, then save it and then compare the original to the saved one.

In otherwords, if the two simple suggestions above don't fix the problem, then you have some work ahead of you.

-- Dan
Dan,
I've tried with DrawText but it didn't make any difference.
I know the problem is to do with the mapping mode because everything works fine if I use MM_TEXT. However, I have to use MM:_TWIPS.
If I find that target app (eg Word) makes any internal transformation when pasting the metafile, what should I have to do?
ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Dan,

Right now I don't have the time to find out what's really going wrong with the metafile. I know for sure that the problem has to do with the upside-down nature of the mapping mode used since the MM_TEXT mode gives no problems at all. However, in the mean time, I will use your trick of rotating the font by 270º

Thanks for all your help!
Carlos