Jump to content
  • Advertisement
Sign in to follow this  
TheMightyDude

DrawText with whitespaces issue :(

This topic is 3783 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 All I am using code based on the code thats in the DirectX9 User Interfaces book, and I have a problem. When I type in the TextBox Control the cursor moves left and right when enerting and removing text, however spaces doesn's make the cursor move if the last character is a space ("test ") is displayed as ("test"), I saw in another post that ID3DXFont::DrawText() when used to calculate the size of the rect doesn't count the whitespaces at the end of the text, and the reason for this was due to whitespaces don't get rendered or something on those lines. My problem is how would I get it to place the cursor to include the whitespaces at the end of the text? I thought of having m_endspaces var that gets incremented each time a whitespace is added, and reset it to 0 if a non-whitespace is added. Is this the right way to do it, or is their a more better way to do it? Any help would be great :) Anyway here is the 2 bits of code where i am having problems with:
// Code to calculate the String Width.
FLOAT CXTextBox::GetStringWidth(std::string String)
{
    RECT String_Info;
    ZeroMemory(&String_Info, sizeof(RECT)); 

    if(m_Font)
    {
        m_Font->DrawText(NULL, String.c_str(), String.length(), &String_Info, DT_CALCRECT, D3DCOLOR_XRGB(0,0,0));
    }
// .right seems to be 0 when String equals a whitespace :(
    return (float)String_Info.right;
}
// Code that handles the TextBox Rendering.
bool CXTextBox::OnRender()
{
    D3DXVECTOR2 Abs;
    RECT Rct;

    ZeroMemory(&Abs, sizeof(D3DXVECTOR2));

    GetAbsolutePosition(&Abs);

    Rct.left    = (long)Abs.x;
    Rct.top     = (long)Abs.y;
    Rct.right   = (long)Abs.x + GetWidth();
    Rct.bottom  = (long)Abs.y + GetHeight();
    m_Font->DrawText(NULL, m_Text.c_str(), m_Text.length(), &Rct, DT_LEFT , D3DCOLOR_XRGB(255,255,255));

    if(m_Focus)
    {
        if(m_CaretVisible)
        {
            D3DXVECTOR2 Absolute[2];
            ZeroMemory(Absolute, sizeof(D3DXVECTOR2) * 2);

            Absolute[0].x = Abs.x + m_CaretVector[0].x;
            Absolute[0].y = Abs.y + m_CaretVector[0].y+2;
            Absolute[1].x = Abs.x + m_CaretVector[0].x;
            Absolute[1].y = Abs.y + m_CaretVector[0].y +2+ (10 * 96/72);//GetHeight();

            m_CaretLine->Draw(Absolute, 2, D3DCOLOR_XRGB(255,255,255));
            m_CaretVisible = false;
        }
        else
        {
            m_CaretVisible = true;
        }
    }
    return true;
}
Thanks in andvance Paul Kirby [Edited by - TheMightyDude on May 9, 2008 10:33:27 AM]

Share this post


Link to post
Share on other sites
Advertisement
Check this one.
It is texture based font drawing, easy to implement, and faster than normal DrawText calls.
It draws spaces also [smile], so you will have no problems like this.

Share this post


Link to post
Share on other sites
Thanks for the reply

Quote:
Original post by streamer
Check this one.
It is texture based font drawing, easy to implement, and faster than normal DrawText calls.
It draws spaces also [smile], so you will have no problems like this.


I took at the dx9 version of his code, run ok and displayed fine, however you cant compile their code due to half their header files are not included in their archives, that’s not too much of an issue, I will most probably be able to look through the code to see how they have done it (hopefully).

My code displays fine, but its where I use DrawText() with the DT_CALCRECT flag so that it returns the size of the RECT needed, and that returns a size of 0 for whitespaces.

Come to think of it FastFont wouldn't really solve my issue, its not the displaying that I am having problems with, its calculating the width of the string which is used to calculate where to put my flashing(blinking) cursor prompt (i.e. |).

I guess I could have a very small loop that searches the string in reverse for whitespaces and counts them and multiplies that by about 5, it then adds that to the RECT, this will only be done when I add, remove or modify anything in the string, so it shouldn't be much of an impact.

As I have already said, thanks for your reply, I now have another way to display text if needed :)

Here is how it looks so far:
Engine_20080509_01

The TextBox is what I am working on atm, and thats just below the Button, and I haven't added any borders around it yet either, I just wanted to sort my issue out first :)

Thanks
paul Kirby

Share this post


Link to post
Share on other sites
Thanks for your reply.

Quote:
Original post by Evil Steve
Have you tried using GetTextExtentPoint32 to calculate the required size instead? I'm not sure if that ignores trailing whitespace too, but it might not - should be quick to check anyway.


Well it started to look like it solved it, however that only worked when using repeated letters like "AAAAAAAAAAAAAAAAAAAA" but when using something like "The little brown fox jumped over the fence" it all goes wrong. :(

It seems that GetTextExtentPoint32() doesnt scale with the size of the text (FontSize). :(
I.e its the same no matter the font size.

Oh yeah, it did count the whitespaces.

So it looks like I am going to have to count the amount of whitespaces that are together at the end of the string and mutliply that with the widthScale.

I will also need to use DrawText() to find the widthScale of '.' <- closest size to a whitespace and then add that to the width returned by DrawText() and I should in theroy get the correct width.

There must be a way to do this, because other game that have chat in their games must of had this issue to resolve.

Man id wish M$ would fix this :(

Share this post


Link to post
Share on other sites
Quote:
Original post by TheMightyDude
Well it started to look like it solved it, however that only worked when using repeated letters like "AAAAAAAAAAAAAAAAAAAA" but when using something like "The little brown fox jumped over the fence" it all goes wrong. :(

It seems that GetTextExtentPoint32() doesnt scale with the size of the text (FontSize). :(
I.e its the same no matter the font size.
Weird... From my text rendering code (Slightly modified):

char ch = ' '; // Whatever character to get the width of
// m_hDC is the HDC containing the font

// Get the size of the glyph blackbox
GLYPHMETRICS glyphMetrics;
MAT2 mat;
memset(&mat, 0, sizeof(mat));
mat.eM11.value = 1;
mat.eM22.value = 1;
GetGlyphOutline(m_hDC, ch, GGO_METRICS, &glyphMetrics, 0, NULL, &mat);
// Width is now glyphMetrics.gmCellIncX


You could give that a go. I know for a fact that works correctly.

Quote:
Original post by TheMightyDude
There must be a way to do this, because other game that have chat in their games must of had this issue to resolve.
Most commercial games don't use ID3DXFont, they have their own text renderer.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Quote:
Original post by TheMightyDude
Well it started to look like it solved it, however that only worked when using repeated letters like "AAAAAAAAAAAAAAAAAAAA" but when using something like "The little brown fox jumped over the fence" it all goes wrong. :(

It seems that GetTextExtentPoint32() doesnt scale with the size of the text (FontSize). :(
I.e its the same no matter the font size.
Weird... From my text rendering code (Slightly modified):
*** Source Snippet Removed ***You could give that a go. I know for a fact that works correctly.

Quote:
Original post by TheMightyDude
There must be a way to do this, because other game that have chat in their games must of had this issue to resolve.
Most commercial games don't use ID3DXFont, they have their own text renderer.


Well it must be just me then :(
glyphMetrics.gmCellIncX = -13108 thats not right :(

Also GetGlyphOutline() is returning -1 which is GDI_ERROR isn't it?
So it's failing for some reason :(

Share this post


Link to post
Share on other sites
Yeah, this is an insanely annoying issue and makes me want to throw away the DrawText function for texture-based text rendering.

Wait until you get into multiple line textboxes and caret placing. Oh that will drive you mad.

I think what I ended up doing was declaring a single Textbox control object (not sure if you are using C# or not). I then use the GetPositionFromCharIndex method of the textbox after setting its properties to the same as my textbox control. It works good but still quirky at times.

At this point, after all of the UI work I've done, if I could go back and make another decision, I'd go with texture-based text rendering. More control and better results.

-E

Share this post


Link to post
Share on other sites
Quote:
Original post by TheMightyDude
Well it must be just me then :(
glyphMetrics.gmCellIncX = -13108 thats not right :(

Also GetGlyphOutline() is returning -1 which is GDI_ERROR isn't it?
So it's failing for some reason :(
Typical, that's the bit I cut out [smile]
It returns GDI_ERROR if the font isn't a truetype font. Here's the unmodified code:

// Get the size of the glyph blackbox
GLYPHMETRICS glyphMetrics;
MAT2 mat;
memset(&mat, 0, sizeof(mat));
mat.eM11.value = 1;
mat.eM22.value = 1;
if(GetGlyphOutline(m_hDC, ch, GGO_METRICS, &glyphMetrics, 0, NULL, &mat) == GDI_ERROR)
{
// This is probably not a truetype font - approximate sizes
SIZE sizeGlyph;
if(!GetTextExtentPoint32W(m_hDC, &ch, 1, &sizeGlyph))
{
bRet = false;
break;
}

memset(&glyphMetrics, 0, sizeof(glyphMetrics));
glyphMetrics.gmBlackBoxX = sizeGlyph.cx;
glyphMetrics.gmBlackBoxY = sizeGlyph.cy;
glyphMetrics.gmptGlyphOrigin.x = 0;
glyphMetrics.gmptGlyphOrigin.y = m_nAscent;
glyphMetrics.gmCellIncX = (short)sizeGlyph.cx;
}

See if that's any more use...

Share this post


Link to post
Share on other sites
Quote:
Original post by EnochDagor
Yeah, this is an insanely annoying issue and makes me want to throw away the DrawText function for texture-based text rendering.

Wait until you get into multiple line textboxes and caret placing. Oh that will drive you mad.

I think what I ended up doing was declaring a single Textbox control object (not sure if you are using C# or not). I then use the GetPositionFromCharIndex method of the textbox after setting its properties to the same as my textbox control. It works good but still quirky at times.

At this point, after all of the UI work I've done, if I could go back and make another decision, I'd go with texture-based text rendering. More control and better results.

-E


lol, don't scare me :P
Well i haven't got that far yet, though i am now dreding it :(

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!