Jump to content
  • Advertisement
Sign in to follow this  
danielw89

Drawing only selected part of text.

This topic is 3316 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I'm calling DrawText function of LPD3DXFONT with DT_CALCRECT flag to get it's width in pixels. Everything is fine. Now the problem: I want to draw only selected part of the string to screen. For example I want to draw from 80 pixel to the last one so I can trim some longs texts. How to do this?

Share this post


Link to post
Share on other sites
Advertisement
You have a few options, but by far the simplest is using IDirect3DDevice9::SetScissorRect(). Don't forget to reset it after drawing the text.

Share this post


Link to post
Share on other sites
This function looks like it's exactly what I want, unfortunately I can't get it to work.

I'm using it like that:

m_pD3Ddev->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);

char tekst[255]; sprintf(tekst, "%s", Winamp.GetTrackTitle());
DrawPlayerTitleTextD3D(PlayerX+12, PlayerY+4, D3DCOLOR_ARGB(255, 255, 255, 255), false, tekst); //This function draws text using ID3DXFONT and a sprite
m_pD3Ddev->SetScissorRect(&TitleRect); //TitleRect is the rect given by DT_CALCRECT in DrawPlayerTitleTextD3D

m_pD3Ddev->SetRenderState(D3DRS_SCISSORTESTENABLE , FALSE);


If I understand the code above correctly, it should erase everything drawn by DrawPlayerTitleTextD3D. It does nothing.

Share this post


Link to post
Share on other sites
Quote:
Original post by danielw89
This function looks like it's exactly what I want, unfortunately I can't get it to work.

I'm using it like that:

m_pD3Ddev->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);

char tekst[255]; sprintf(tekst, "%s", Winamp.GetTrackTitle());
DrawPlayerTitleTextD3D(PlayerX+12, PlayerY+4, D3DCOLOR_ARGB(255, 255, 255, 255), false, tekst); //This function draws text using ID3DXFONT and a sprite
m_pD3Ddev->SetScissorRect(&TitleRect); //TitleRect is the rect given by DT_CALCRECT in DrawPlayerTitleTextD3D

m_pD3Ddev->SetRenderState(D3DRS_SCISSORTESTENABLE , FALSE);


If I understand the code above correctly, it should erase everything drawn by DrawPlayerTitleTextD3D. It does nothing.
Not quite. You need to set it before drawing, not after. Additionally, because ID3DXFont changes the device state and probably disables the scissor rect, you'll probably need to pass a valid ID3DXSprite to ID3DXFont::DrawText(), and call SetScissorRect() after the ID3DXSprite::Begin() call but before ID3DXFont::DrawText().

Share this post


Link to post
Share on other sites
Thanks for your reply, but it still doesn't work. Here's what I did:

I moved the calls associated with SetScissorRect() into my drawing function, now it looks like that:

m_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//a few lines of code that isn't important now
pFont->DrawText(m_pSprite, logbuf, -1, &rct, DT_CALCRECT, dwColor);
TitleRect = rct;
pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
pDevice->SetScissorRect(&TitleRect);
pFont->DrawText(m_pSprite, logbuf, -1, &rct, DT_NOCLIP, dwColor);
pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE , FALSE);
m_pSprite->End();


Probably a stupid mistake, but I can't figure it out.

Share this post


Link to post
Share on other sites
Quote:
Original post by danielw89
Thanks for your reply, but it still doesn't work. Here's what I did:

I moved the calls associated with SetScissorRect() into my drawing function, now it looks like that:

[snip]

Probably a stupid mistake, but I can't figure it out.
DT_CALCRECT will cause the rect to be expanded to multiple lines I believe - you probably want to set the rect to the area you want the text in, not the area ID3DXFont says the text requires.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
DT_CALCRECT will cause the rect to be expanded to multiple lines I believe - you probably want to set the rect to the area you want the text in, not the area ID3DXFont says the text requires.


I'm a bit confused now. Sorry, I'm still a newbie.
Let's say rect given by DT_CALCRECT is named Rect.
Rect.bottom - Rect.top will give height of the text. Only one line. It's 13 pixels in my program.

Now the rect to be scissored: Anything I put there, even constant values... nothing gets cut.

Share this post


Link to post
Share on other sites
Quote:
Original post by danielw89
Quote:
Original post by Evil Steve
DT_CALCRECT will cause the rect to be expanded to multiple lines I believe - you probably want to set the rect to the area you want the text in, not the area ID3DXFont says the text requires.


I'm a bit confused now. Sorry, I'm still a newbie.
Let's say rect given by DT_CALCRECT is named Rect.
Rect.bottom - Rect.top will give height of the text. Only one line. It's 13 pixels in my program.

Now the rect to be scissored: Anything I put there, even constant values... nothing gets cut.
From the docs for ID3DXFont::DrawText:
Quote:
DT_CALCRECT
Determines the width and height of the rectangle. If there are multiple lines of text, ID3DXFont::DrawText uses the width of the rectangle pointed to by the pRect parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, ID3DXFont::DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, ID3DXFont::DrawText returns the height of the formatted text but does not draw the text.
So what is the rect you're passing in to start with? I'm also not sure how ID3DXFont determines if there's multiple lines; I suspect it uses the DT_SINGLELINE flag rather than parsing the string (Since that's what the GDI DrawText() function does).

Share this post


Link to post
Share on other sites
The rect I pass to ID3DXFONT::DrawText():

RECT rct;
rct.left = x - 1;
rct.right = 0;
rct.top = y - 1 ;
rct.bottom = 0;

Variables x and y have values from my function's arguments(declaration looks like that: DrawPlayerTitleTextD3D([...] int x, int y [...])
They have to be dynamic because I want to move my text in the program's runtime.

Share this post


Link to post
Share on other sites
Quote:
Original post by danielw89
The rect I pass to ID3DXFONT::DrawText():

RECT rct;
rct.left = x - 1;
rct.right = 0;
rct.top = y - 1 ;
rct.bottom = 0;

Variables x and y have values from my function's arguments(declaration looks like that: DrawPlayerTitleTextD3D([...] int x, int y [...])
They have to be dynamic because I want to move my text in the program's runtime.
DT_CALCRECT will expand the right edge of the rect to some value >= x-1, but leave the bottom value. That means that your rect is inside out when you pass it to SetScissorRect - the "top" value needs to be < the "bottom" value.

You could always try using a scissor rect of (0, 0) to (400,300) or some value that you're sure intersects your text.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!