Qt-interest Archive, January 2008
Drawing single-pixel-wide text on an image
Message 1 in thread
Hi,
I use QPainter::drawText to draw strings on a QImage in various text
sizes. I use QFont::setPointSize to set the size of the text to draw. In
some cases, I'd like to draw characters using thin (single-pixel-wide)
lines, so, for example, the character 'L' would look as if I drew 2
lines, a horizontal one and a vertical one, with a pen width of 1. How
do I do that? At first, I thought this was a matter of selecting a font
that is just made of a series of lines, but I couldn't find any such
font. Whichever font I use, drawing large text makes each character
"thick". I'd like the characters to use the same width and height they
do now, but use thin lines.
Thanks,
Shlomy
--
[ signature omitted ]
Message 2 in thread
> -----Original Message-----
> From: Shlomy Reinstein [mailto:shlomy@xxxxxxxxxxxxxx]
> Sent: Wednesday, 2 January 2008 20:35
> To: qt-interest@xxxxxxxxxxxxx
> Subject: Drawing single-pixel-wide text on an image
>
>
> Hi,
>
> I use QPainter::drawText to draw strings on a QImage in various text
> sizes. I use QFont::setPointSize to set the size of the text
> to draw. In
> some cases, I'd like to draw characters using thin (single-pixel-wide)
> lines, so, for example, the character 'L' would look as if I drew 2
> lines, a horizontal one and a vertical one, with a pen width of 1. How
> do I do that? At first, I thought this was a matter of
> selecting a font
> that is just made of a series of lines, but I couldn't find any such
> font. Whichever font I use, drawing large text makes each character
> "thick". I'd like the characters to use the same width and height they
> do now, but use thin lines.
>
> Thanks,
> Shlomy
>
Hi Shlomy,
I think you will probably need a custom font!
Nonetheless, I suggest you try something like:
painter.save();
painter.setFont( font_that_you_like );
painter.setFontSize( very_large_value );
painter.setScale( big_x_factor, smaller_y_factor );
// draw thin text
painter.restore();
Set the y_factor to counteract the font size, and give you the height that
you want.
Set the x_factor to a larger value to squash the characters and squeeze the
vertical lines.
Hope that helps,
Tony Rietwyk
--
[ signature omitted ]
Message 3 in thread
On Wed, 2008-01-02 at 11:35 +0200, Shlomy Reinstein wrote:
> Hi,
>
> I use QPainter::drawText to draw strings on a QImage in various text
> sizes. I use QFont::setPointSize to set the size of the text to draw. In
> some cases, I'd like to draw characters using thin (single-pixel-wide)
> lines, so, for example, the character 'L' would look as if I drew 2
> lines, a horizontal one and a vertical one, with a pen width of 1. How
> do I do that? At first, I thought this was a matter of selecting a font
> that is just made of a series of lines, but I couldn't find any such
> font. Whichever font I use, drawing large text makes each character
> "thick". I'd like the characters to use the same width and height they
> do now, but use thin lines.
That's going to be very difficult. I'm in the same boat almost as you in
that my application would *prefer* vector fonts that I can draw with
line segments. That's what you're looking for essentially, a vector
font. What I ended up having to do was add support for Truetype and
Type1, I'm glad I did but it was a bit of work.
Truetype fonts are constructed using line segments and second order
bezier curves. They basically are polygon outlines with hole outlines
within those polygons as necessary. When they are drawn, they are just
rendered with a scanline rasterizer which has no problem dealing with
the outline soup. That's the simple and easy explanation, the reality
gets a bit more technical than that. =)
Type1 fonts are identical but instead use line segments and third order
bezier curves. Otherwise same principles as truetype applies.
Since these fonts basically are drawn using rasterized polygons there is
no way to guarantee a 1-pixel line thickness as there is no such line as
what you're looking for defined. Maybe with your own custom rasterizer
you could do such a thing, but it'd definitely not be easy to implement
and probably difficult, if even possible at all, to get to look decent.
What you need are either vector fonts, try googling for hershey vector
fonts, or bitmap fonts. For the hershey vector fonts, their data is
plaintext ascii with one character per line and there is a way to decode
all those characters into meaningful lime segments. If you google enough
you should come across it.
That definitely would allow you to do what you want, but you'd be
limited to that set of fonts and nothing else. It is however scalable.
Other than that, the only remaining solution I can think of would be to
use a bitmap based font with characters drawn the way you want. Of
course, that's even more limiting than the vector fonts as now you can't
even scale.
But with truetype, type 1, and equivalent fonts? I Just don't see it
happening realistically.
Stephan
--
[ signature omitted ]