From: Luca C. <luc...@se...> - 2009-03-11 17:08:44
|
Hello, I wrote a simple function which draws a string with the its bounding box centered to the given pCenter parameter: void drawCenteredText (wxPdfDocument& pPDF, wxString const& pString, Vector2f const& pCenter) { float lHeightMM = float (pPDF.GetFontSize ()) / 72.f * 2.54f / 10.f; //Height in mm. double lWidthMM = pPDF.GetStringWidth (pString);//Width in mm. pPDF.SetXY (pCenter.x - lWidthMM / 2.f, pCenter.y - lHeightMM / 2.f); pPDF.Cell (0, 0, pString); } To roughly center the string I need to know how much the actual font height is in millimeters, and for that purpose i use a formula that converts points to mm, assuming that a point is 1/72 inch, and then I convert inch to mm. Is there any better way than this approach? Greetings, Luca |
From: Ulrich T. <ulr...@gm...> - 2009-03-11 19:59:05
|
Luca Cappa schrieb: > I wrote a simple function which draws a string with the its bounding box > centered to the given pCenter parameter: > > void drawCenteredText (wxPdfDocument& pPDF, wxString const& pString, > Vector2f const& pCenter) > { > float lHeightMM = float (pPDF.GetFontSize ()) / 72.f * 2.54f / 10.f; > //Height in mm. No. Your formula is wrong. To get the height in millimeters it should read: float lHeightMM = float (pPDF.GetFontSize ()) / 72.f * 25.4f; > double lWidthMM = pPDF.GetStringWidth (pString);//Width in mm. > pPDF.SetXY (pCenter.x - lWidthMM / 2.f, pCenter.y - lHeightMM / 2.f); > pPDF.Cell (0, 0, pString); > } > > To roughly center the string I need to know how much the actual font > height is in millimeters, and for that purpose i use a formula that > converts points to mm, assuming that a point is 1/72 inch, and then I > convert inch to mm. Is there any better way than this approach? Well, it depends on what you really want to accomplish. The y position corresponds to the baseline of the font. The glyphs of a font usually ascend above and/or descend below the baseline. The font parameters 'ascent' and 'descent' tell you the maximum values. You may access these attributes using the method GetFontDescription. From these values you could deduce a more precise measure for the mean vertical 'center' of the glyphs of the font in use. To convert the values of ascent and descent to millimeters you have to divide them by 1000 and then multiply by the font size in millimeters. As the offset you would then use offset = (ascent-descent) / 2000.f * pPDF.GetFontSize() / 72.f * 25.4f; That is you would set your vertical position to pCenter.y + offset. Regards, Ulrich |
From: Luca C. <luc...@se...> - 2009-03-12 10:00:53
|
Hello, On Wed, 11 Mar 2009 21:00:40 +0100, Ulrich Telle <ulr...@gm...> wrote: > Luca Cappa schrieb: >> I wrote a simple function which draws a string with the its bounding box >> centered to the given pCenter parameter: >> >> void drawCenteredText (wxPdfDocument& pPDF, wxString const& pString, >> Vector2f const& pCenter) >> { >> float lHeightMM = float (pPDF.GetFontSize ()) / 72.f * 2.54f / 10.f; >> //Height in mm. > > No. Your formula is wrong. To get the height in millimeters it should > read: > > float lHeightMM = float (pPDF.GetFontSize ()) / 72.f * 25.4f; Thanks, I already spotted that error :) > The y position corresponds to the baseline of the font. T I expect you to correct me again :) : I tryed to see if the baseline is effectively the Y value passed to wxPdfDocument::SetXY/SetY funtions this way: void BalancerPanel::drawText (wxPdfDocument& pPDF, wxString const& pString, Vector2f const& pCenter) { // // Draw the text with a Cell that has the upperleft border at (pCenter.x, pCenter.y) float lAscent = pPDF.GetFontDescription ().GetAscent (); float lDescent = pPDF.GetFontDescription ().GetDescent (); float lMaximumHeight = (lAscent - lDescent) / 1000.f * pPDF.GetFontSize() / 72.f * 25.4f; pPDF.SetXY (pCenter.x, pCenter.y); pPDF.Cell (0, lMaximumHeight, pString, wxPDF_BORDER_FRAME);//Write around the text a frame with an height //equal to the maximum height of a character of the font. // //Draw the potential baseline in red. wxPdfColour lColor = pPDF.GetDrawColor (); pPDF.SetDrawColor (255, 0, 0); pPDF.Line (pCenter.x, pCenter.y, pCenter.x + 10, pCenter.y); pPDF.SetDrawColor (lColor); } Then I called the above function with: drawText (lPDFDoc, "BagjYIq", Vector2f (10, 10)); which should draw the text with a baseline at 10mm from the start of the page, but as you cound see in the image http://img22.imageshack.us/img22/3844/baseline.png the red line is along the top border of the cell, so a call to SetY sets the baseline-ascent Y value, i.e. the upper limit of the text's font, and not the baseline. > That is you would set your vertical position to pCenter.y + offset. Knowing that the curent position (the one set with SetXY) is the upperleft corner of the text bounding box, then if "offset" is the the maximum height of the font divided by 2, then i would draw some text centered to pCenter with the following code: void drawCenteredText (wxPdfDocument& pPDF, wxString const& pString, Vector2f const& pCenter) { // // Draw a Cell with text centered to pCenter. float lAscent = pPDF.GetFontDescription ().GetAscent (); float lDescent = pPDF.GetFontDescription ().GetDescent (); float lMaximumHeight = (lAscent - lDescent) / 1000.f * pPDF.GetFontSize() / 72.f * 25.4f; double lWidthMM = pPDF.GetStringWidth (pString);//Width in mm. pPDF.SetXY (pCenter.x - lWidthMM / 2.f, pCenter.y - lMaximumHeight / 2.f);//"offset" is basically lMaximumHeight/2 pPDF.Cell (0, lMaximumHeight, pString, wxPDF_BORDER_FRAME); // //Draw the potential baseline in red. wxPdfColour lColor = pPDF.GetDrawColor (); pPDF.SetDrawColor (255, 0, 0); pPDF.Line (pCenter.x, pCenter.y, pCenter.x + 10, pCenter.y); pPDF.SetDrawColor (lColor); } drawCenteredText (lPDFDoc, "BagjYIq", Vector2f (10, 10)); Using the above function gives the passed text string centered to (10mm, 10mm) as you could see in the http://img22.imageshack.us/img22/8194/textcentered.png image. Again correct me if I am wrong, thanks! Luca |
From: Ulrich T. <ulr...@gm...> - 2009-03-12 13:28:40
|
Luca Cappa schrieb: >> The y position corresponds to the baseline of the font. T > > I expect you to correct me again :) No, I have to correct myself. As you observed the y position corresponds roughly to the upper left corner of the text box. The baseline of the font is positioned half of the cell height plus 30% of the font size in user units below, i.e. y_baseline = y + 0.5 * cellheight + 0.3 * fontsize Sorry for the confusion. Regards, Ulrich P.S.: I consider to change the coordinate system in a future version of wxPdfDocument to make the behaviour of several methods more logical and transparent. |
From: Luca C. <luc...@se...> - 2009-03-12 14:01:04
|
Hello, On Thu, 12 Mar 2009 14:30:18 +0100, Ulrich Telle <ulr...@gm...> wrote: > As you observed the y position corresponds > roughly to the upper left corner of the text box. The baseline of the > font is positioned half of the cell height plus 30% of the font size in > user units below, i.e. > > y_baseline = y + 0.5 * cellheight + 0.3 * fontsize > Nice to know, i been to lazy to check the actual code :) > I consider to change the coordinate system in a future version of > wxPdfDocument to make the behaviour of several methods more logical and > transparent. That is a very good news to me, thanks! Greetings, Luca |
From: Ulrich T. <ulr...@gm...> - 2009-03-12 15:26:45
|
Luca Cappa schrieb: >> I consider to change the coordinate system in a future version of >> wxPdfDocument to make the behaviour of several methods more logical and >> transparent. > > That is a very good news to me, thanks! Thanks for the positive reaction. Not all users of wxPdfDocument see it that way since changing the coordinate system means breaking existing code. But in the long run I'm sure it would make using wxPdfDocument easier than now. Probably I introduce this change when going from version 0.x to 1.x. Regards, Ulrich |