Results 1 to 6 of 6

Thread: How do you set the font for use with TextOut onto a surface?

  1. #1

    How do you set the font for use with TextOut onto a surface?

    I am writting text to a DirectX surface and can't seem to change the font...

    Any ideas?
    http://www.c5software.co.uk (site is being developed at the moment)

  2. #2

    How do you set the font for use with TextOut onto a surface?

    If you're using some_surface.GetDC/TextOut/some_surface.ReleaseDC then you can use the stanard GDI functions. In this case, you want to fill out a TLogFont structure. There are a lot of options here for the font name, size, style, and so on -- too many to explain, so have a look at the LOGFONT structure in win32.hlp for more info (as a side note: you can rotate text using the lfOrientation and lfEscapement fields, which is a nice bonus). You then create the font from the LogFont structure using CreateFontIndirect, which returns a HFONT to your new GDI object. You select the object into the DC, draw your text, and select old font back. Something like this [untested]:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000]
    [number=#C00000][reserved=#000000][string=#00C000]var
    FontDesc: TLogFont;
    OldFont: HFONT;
    NewFont: HFONT;
    DC: HDC;
    TheText: String;
    begin
    TheText := 'blah blah blah';

    your_surface.GetDC(DC);

    with FontDesc do
    begin
    lfHeight := 12;
    lfWidth := 0;
    lfEscapement := 0;
    lfOrientation := 0;
    // and so on for all the rest of the fields!
    //...
    end;

    // create a new font based on the description above
    NewFont := CreateFontIndirect(FontDesc);

    // use the new font - we select it into the DC and grab the
    // the return value, which is the old font
    OldFont := SelectObject(DC, NewFont);

    SetBKMode(DC, TRANSPARENT);

    TextOut(DC, x, y, PChar(TheText), Length(TheText));

    // restore the old font
    SelectObject(DC, OldFont);
    DeleteObject(NewFont);

    your_surface.ReleaseDC(DC);
    end;[/pascal]

    (Consider adding try..finally blocks above if appropriate, of course.)

    The above code demonstrates why the GDI sucks ass . If you're already using the VCL then you could probably create and use a TCanvas, making your life simpler. Dunno if it'll work like this, but try it anyway:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000]
    [number=#C00000][reserved=#000000][string=#00C000]var
    Canv: TCanvas;
    DC: HDC;
    begni
    Canv := TCanvas.Create;
    your_surface.GetDC(DC);

    Canv.Handle := DC;

    // now use the canvas as normal!

    Canv.Font.Name := 'Verdana';
    Canv.Font.Size := 12;
    Canv.TextOut(10, 20, 'roxx');

    your_surface.ReleaseDC(DC);
    Canv.Free;
    end;[/pascal]
    The above is untested and is only useful if you want to use the VCL (which you may or may not, due to the size increase).
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  3. #3

    How do you set the font for use with TextOut onto a surface?

    Quote Originally Posted by Alimonster
    If you're using some_surface.GetDC/TextOut/some_surface.ReleaseDC then you can use the stanard GDI functions. In this case, you want to fill out a TLogFont structure. There are a lot of options here for the font name, size, style, and so on -- too many to explain, so have a look at the LOGFONT structure in win32.hlp for more info (as a side note: you can rotate text using the lfOrientation and lfEscapement fields, which is a nice bonus). You then create the font from the LogFont structure using CreateFontIndirect, which returns a HFONT to your new GDI object. You select the object into the DC, draw your text, and select old font back. Something like this [untested]:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000]
    [number=#C00000][reserved=#000000][string=#00C000]var
    FontDesc: TLogFont;
    OldFont: HFONT;
    NewFont: HFONT;
    DC: HDC;
    TheText: String;
    begin
    TheText := 'blah blah blah';

    your_surface.GetDC(DC);

    with FontDesc do
    begin
    lfHeight := 12;
    lfWidth := 0;
    lfEscapement := 0;
    lfOrientation := 0;
    // and so on for all the rest of the fields!
    //...
    end;

    // create a new font based on the description above
    NewFont := CreateFontIndirect(FontDesc);

    // use the new font - we select it into the DC and grab the
    // the return value, which is the old font
    OldFont := SelectObject(DC, NewFont);

    SetBKMode(DC, TRANSPARENT);

    TextOut(DC, x, y, PChar(TheText), Length(TheText));

    // restore the old font
    SelectObject(DC, OldFont);
    DeleteObject(NewFont);

    your_surface.ReleaseDC(DC);
    end;[/pascal]

    (Consider adding try..finally blocks above if appropriate, of course.)

    The above code demonstrates why the GDI sucks ass . If you're already using the VCL then you could probably create and use a TCanvas, making your life simpler. Dunno if it'll work like this, but try it anyway:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000]
    [number=#C00000][reserved=#000000][string=#00C000]var
    Canv: TCanvas;
    DC: HDC;
    begni
    Canv := TCanvas.Create;
    your_surface.GetDC(DC);

    Canv.Handle := DC;

    // now use the canvas as normal!

    Canv.Font.Name := 'Verdana';
    Canv.Font.Size := 12;
    Canv.TextOut(10, 20, 'roxx');

    your_surface.ReleaseDC(DC);
    Canv.Free;
    end;[/pascal]
    The above is untested and is only useful if you want to use the VCL (which you may or may not, due to the size increase).
    Thanks for that Worked a treat! I have now pretty much coded a dx replacement for that TRichEdit I was using. Just need to work out how to calculate the width of the text in bytes so I know when to wrap to the next line...
    http://www.c5software.co.uk (site is being developed at the moment)

  4. #4

    How do you set the font for use with TextOut onto a surface?

    The function TCanvas.TextWidth uses the API function "GetTextExtentPoint32" behind the scenes - it ought to do the trick.
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  5. #5

    How do you set the font for use with TextOut onto a surface?

    I would use DrawTextEx. You can pass a TRect to it and it will wrap the lines for you.

  6. #6

    How do you set the font for use with TextOut onto a surface?

    Quote Originally Posted by Sly
    I would use DrawTextEx. You can pass a TRect to it and it will wrap the lines for you.
    Thanks a lot guys

    Will probably have to use DrawTextEx as the component doesn't have a Canvas.
    http://www.c5software.co.uk (site is being developed at the moment)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •