RE: [ft-devel] Rotated text
Frank, I've added some brief answers to your questions below. Best regards, Graham -Original Message- From: Frank W. Miller [mailto:[EMAIL PROTECTED] Sent: 07 July 2008 04:59 To: 'Graham Asher'; freetype-devel@nongnu.org Subject: RE: [ft-devel] Rotated text Thanks very much for the reply. I have a few questions as you might guess. Your mapping software looks really great btw. FM -Original Message- From: Graham Asher [mailto:[EMAIL PROTECTED] Sent: Sunday, July 06, 2008 5:19 AM To: 'Frank W. Miller'; freetype-devel@nongnu.org Subject: RE: [ft-devel] Rotated text Frank, I'm sorry that I don't have time to look at your example, but I have successfully drawn rotated text (and text along a path, for that matter) using FreeType, and I can give you some pieces of advice. 1. Either (i) use an FT_Matrix to set the font transform (call FT_Set_Transform), or (ii), create an unrotated outline glyph for each character and then rotate it using FT_Glyph_Transform. I assume from the fact that you say that your code 'spins' the text that you know how to set the transform parameters. FM: I have been using both FT_Matrix and FT_Set_Transform successfully as you have guessed. I've had a little trouble figuring out where 0 degrees is. In the sample code on the FreeType site, it seems to be the positive y axis. When I tweaked it, I was able to get that go be the positive x axis, which seems more logical to me. GA: It doesn't matter where 0 degrees is - 0 degrees can be regarded as 'unrotated'. 2. Use the advance vector after it has been transformed. This is outline_glyph-root.advance (assuming that outline_glyph is your FT_OutlineGlyph object), and is a 16.16 fixed-point number. You will need to keep track of the current glyph origin in 16.16 format, to avoid the text 'looking like arse', because... FM: The way the code works, there is a pen variable of type FT_Vector. The pen x and y components are set to the origin prior to entering a for loop. Each iteration of the for loop does this: 1) FT_Set_Transform 2) FT_Load_Char, 3) draw the bitmap, and 4) advance the pen using the face-glyph-advance. It seems like one of two things is happening, either my rendering of the bitmap does not fall on the baseline correctly or the pen advance is not following the baseline. My guess is its my bitmap rendering but I don't know for sure. GA: You need to store your pen variable in 16.16 coordinates. Add the x component of face-glyph-advance to pen.x and the y component to pen.y after drawing each glyph. 3. When you rasterize every glyph except the first one, it needs to be offset to the sub-pixel position of its origin. For example: if your first glyph has an unrotated baseline length of 8 pixels and you rotate the text by 20 degrees, the rotated advance will be (8 * cos 20,8 * sin 20) = (7.518, 2.736). Thus, if your first glyph origin was at (0,0), your second glyph origin needs to be at (7.518,2.736) to avoid a jiggling effect. Do this by applying an offset of the fractional parts of the coordinates to each glyph as you rasterize it, then drawing the glyph at the integer coordinates. Thus, in this example, you need to offset the glyph by (0.518,0.736) and draw at (7,2). FreeType works in 64ths of pixels when rasterizing, so you do this by calling FT_Glyph_Transform with a delta argument of (0.518 * 64,0.736 * 64) = (33,47) before converting the outline glyph to a bitmap. FM: Huh? This makes me wonder even more what I'm doing in my previous comment. Is my baseline length my width or pitch from the previous glyph? This is what's causing me trouble I think. Maybe I'm too new to this but there aren't that many things I can play with here, at least from what I see in the documentation. I do the rotation using the matrix. I use width and pitch and rows to figure out the bitmap size and I can take the advance.x 6 and advance.y 6 to get movements on the origin of each glyph. I'm not following where your application of the rotation angle to the baseline length is coming from. Can you be more specific about what fields in what structures you are talking about? GA: The baseline length ( that is, the advance, measured along the baseline) is the vector length of the advance. To use my previous example, the baseline length is 8 pixels - the value before rotation. The glyph bitmap pitch is irrelevant. You say and I can take the advance.x 6 and advance.y 6 to get movements on the origin of each glyph but that is a mistake. advance.x and advance.y are stored in 16.16 format. To convert to 64ths of a pixel (26.6 format) you need to shift right by 10, not by 6. You also said I'm not following where your application of the rotation angle to the baseline length is coming from. Can you be more specific about what fields in what structures you are talking about? Yes: FreeType applies the rotation to the advance in FT_Glyph_Transform. The code is FT_Vector_Transform( glyph-advance, matrix ); which
RE: [ft-devel] Rotated text
Thanks very much for the reply. I have a few questions as you might guess. Your mapping software looks really great btw. FM -Original Message- From: Graham Asher [mailto:[EMAIL PROTECTED] Sent: Sunday, July 06, 2008 5:19 AM To: 'Frank W. Miller'; freetype-devel@nongnu.org Subject: RE: [ft-devel] Rotated text Frank, I'm sorry that I don't have time to look at your example, but I have successfully drawn rotated text (and text along a path, for that matter) using FreeType, and I can give you some pieces of advice. 1. Either (i) use an FT_Matrix to set the font transform (call FT_Set_Transform), or (ii), create an unrotated outline glyph for each character and then rotate it using FT_Glyph_Transform. I assume from the fact that you say that your code 'spins' the text that you know how to set the transform parameters. FM: I have been using both FT_Matrix and FT_Set_Transform successfully as you have guessed. I've had a little trouble figuring out where 0 degrees is. In the sample code on the FreeType site, it seems to be the positive y axis. When I tweaked it, I was able to get that go be the positive x axis, which seems more logical to me. 2. Use the advance vector after it has been transformed. This is outline_glyph-root.advance (assuming that outline_glyph is your FT_OutlineGlyph object), and is a 16.16 fixed-point number. You will need to keep track of the current glyph origin in 16.16 format, to avoid the text 'looking like arse', because... FM: The way the code works, there is a pen variable of type FT_Vector. The pen x and y components are set to the origin prior to entering a for loop. Each iteration of the for loop does this: 1) FT_Set_Transform 2) FT_Load_Char, 3) draw the bitmap, and 4) advance the pen using the face-glyph-advance. It seems like one of two things is happening, either my rendering of the bitmap does not fall on the baseline correctly or the pen advance is not following the baseline. My guess is its my bitmap rendering but I don't know for sure. 3. When you rasterize every glyph except the first one, it needs to be offset to the sub-pixel position of its origin. For example: if your first glyph has an unrotated baseline length of 8 pixels and you rotate the text by 20 degrees, the rotated advance will be (8 * cos 20,8 * sin 20) = (7.518, 2.736). Thus, if your first glyph origin was at (0,0), your second glyph origin needs to be at (7.518,2.736) to avoid a jiggling effect. Do this by applying an offset of the fractional parts of the coordinates to each glyph as you rasterize it, then drawing the glyph at the integer coordinates. Thus, in this example, you need to offset the glyph by (0.518,0.736) and draw at (7,2). FreeType works in 64ths of pixels when rasterizing, so you do this by calling FT_Glyph_Transform with a delta argument of (0.518 * 64,0.736 * 64) = (33,47) before converting the outline glyph to a bitmap. FM: Huh? This makes me wonder even more what I'm doing in my previous comment. Is my baseline length my width or pitch from the previous glyph? This is what's causing me trouble I think. Maybe I'm too new to this but there aren't that many things I can play with here, at least from what I see in the documentation. I do the rotation using the matrix. I use width and pitch and rows to figure out the bitmap size and I can take the advance.x 6 and advance.y 6 to get movements on the origin of each glyph. I'm not following where your application of the rotation angle to the baseline length is coming from. Can you be more specific about what fields in what structures you are talking about? 4. Rotated text looks much better when it is anti-aliased. But you knew that already ;-) FM: I want to get it working before I worry about anti-aliasing, but I will of course want to add that at some point. Thanks again for the advice. Due to my newbieness, its as clear as mud right now. :( Thanks, FM ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Rotated text
OK, lets try this again. I've posted the source code for what I'm trying to do. If you build this application you can run it with these arguments: rotate font text where font is a TrueType font file and text is some string text, e.g. text. This should get you the text spinning inside of a 640x480 window. The trouble is, as you'll see, its looks like arse. The characters are not aligned as they should be. Any advice on this would be very helpful. The source code is at: http://sipuseragent.net/download/rotate.tgz Thanks, FM On Thu, 2008-07-03 at 23:03 -0600, Frank W. Miller wrote: Greetings, I've been wrestling with rotated text. I've read all the documentation and have been working with the example code. I'm having some real trouble understanding how the advance, width, and rows fields in the rendered bitmap can be used to compute a bbox. Here's what I'm really hoping can be done: The following image is supposed to be the word text rotated up by about 15 degrees or so off the x axis. Sorry, my ascii rendering is not what it could be. The rendered text is supposed to be inside a bounding box, or at least, why I think of as a bounding box. [w,h] +-+ | * * | | * *** | | * * ** * | | * * * * * * *| | ** * * * * ** | | * * ** * | | * * * | |** | +-+ [0,0] So, taking the sample code, to get [w,h], I've tried to just sum up the advance.x and advance.y fields after each glyph rendering. That doesn't seem quite right. When I actually render the text, it appears to go off to the left a little from what I feed the bitmap routine as [0,0]. I suppose I need to take into account the width and rows fields in the bitmap too but I'm not sure how to do it. This may be completely out to lunch, but if anyone has any suggestions, I'd appreciate it. Thanks, FM ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel