#include "wx/gtk/private.h"
#include "wx/gtk/private/object.h"
+#include "wx/private/textmeasure.h"
//-----------------------------------------------------------------------------
// local defines
wxCHECK_RET( IsOk(), wxT("invalid window dc") );
+ x = XLOG2DEV(x);
+ y = YLOG2DEV(y);
+
+ pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
+ const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
+ int oldSize = 0;
+ const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
+ if (isScaled)
{
- x = XLOG2DEV(x);
- y = YLOG2DEV(y);
+ //TODO: when Pango >= 1.6 is required, use pango_matrix_scale()
+ // If there is a user or actually any scale applied to
+ // the device context, scale the font.
- pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
- const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
- int oldSize = 0;
- const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
- if (isScaled)
- {
- //TODO: when Pango >= 1.6 is required, use pango_matrix_scale()
- // If there is a user or actually any scale applied to
- // the device context, scale the font.
+ // scale font description
+ oldSize = pango_font_description_get_size(m_fontdesc);
+ pango_font_description_set_size(m_fontdesc, int(oldSize * m_scaleY));
- // scale font description
- oldSize = pango_font_description_get_size(m_fontdesc);
- pango_font_description_set_size(m_fontdesc, int(oldSize * m_scaleY));
+ // actually apply scaled font
+ pango_layout_set_font_description( m_layout, m_fontdesc );
+ }
- // actually apply scaled font
- pango_layout_set_font_description( m_layout, m_fontdesc );
- }
+ int w, h;
+ pango_layout_get_pixel_size(m_layout, &w, &h);
- int w, h;
- pango_layout_get_pixel_size(m_layout, &w, &h);
-
- const GdkColor* bg_col = NULL;
- if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
- bg_col = m_textBackgroundColour.GetColor();
-
- // rotate the text
- PangoMatrix matrix = PANGO_MATRIX_INIT;
- pango_matrix_rotate (&matrix, angle);
- pango_context_set_matrix (m_context, &matrix);
- pango_layout_context_changed (m_layout);
-
- // To be compatible with MSW, the rotation axis must be in the old
- // top-left corner.
- // Calculate the vertices of the rotated rectangle containing the text,
- // relative to the old top-left vertex.
- // We could use the matrix for this, but it's simpler with trignonometry.
- double rad = DegToRad(angle);
- // the rectangle vertices are counted clockwise with the first one
- // being at (0, 0)
- double x2 = w * cos(rad);
- double y2 = -w * sin(rad); // y axis points to the bottom, hence minus
- double x4 = h * sin(rad);
- double y4 = h * cos(rad);
- double x3 = x4 + x2;
- double y3 = y4 + y2;
- // Then we calculate max and min of the rotated rectangle.
- wxCoord maxX = (wxCoord)(dmax(dmax(0, x2), dmax(x3, x4)) + 0.5),
- maxY = (wxCoord)(dmax(dmax(0, y2), dmax(y3, y4)) + 0.5),
- minX = (wxCoord)(dmin(dmin(0, x2), dmin(x3, x4)) - 0.5),
- minY = (wxCoord)(dmin(dmin(0, y2), dmin(y3, y4)) - 0.5);
-
- gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY,
- m_layout, NULL, bg_col);
-
- if (setAttrs)
- pango_layout_set_attributes(m_layout, NULL);
-
- // clean up the transformation matrix
- pango_context_set_matrix(m_context, NULL);
+ const GdkColor* bg_col = NULL;
+ if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
+ bg_col = m_textBackgroundColour.GetColor();
- if (isScaled)
- {
- // reset unscaled size
- pango_font_description_set_size( m_fontdesc, oldSize );
+ // rotate the text
+ PangoMatrix matrix = PANGO_MATRIX_INIT;
+ pango_matrix_rotate (&matrix, angle);
+ pango_context_set_matrix (m_context, &matrix);
+ pango_layout_context_changed (m_layout);
+
+ // To be compatible with MSW, the rotation axis must be in the old
+ // top-left corner.
+ // Calculate the vertices of the rotated rectangle containing the text,
+ // relative to the old top-left vertex.
+ // We could use the matrix for this, but it's simpler with trignonometry.
+ double rad = DegToRad(angle);
+ // the rectangle vertices are counted clockwise with the first one
+ // being at (0, 0)
+ double x2 = w * cos(rad);
+ double y2 = -w * sin(rad); // y axis points to the bottom, hence minus
+ double x4 = h * sin(rad);
+ double y4 = h * cos(rad);
+ double x3 = x4 + x2;
+ double y3 = y4 + y2;
+ // Then we calculate max and min of the rotated rectangle.
+ wxCoord maxX = (wxCoord)(dmax(dmax(0, x2), dmax(x3, x4)) + 0.5),
+ maxY = (wxCoord)(dmax(dmax(0, y2), dmax(y3, y4)) + 0.5),
+ minX = (wxCoord)(dmin(dmin(0, x2), dmin(x3, x4)) - 0.5),
+ minY = (wxCoord)(dmin(dmin(0, y2), dmin(y3, y4)) - 0.5);
+
+ gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY,
+ m_layout, NULL, bg_col);
- // actually apply unscaled font
- pango_layout_set_font_description( m_layout, m_fontdesc );
- }
+ if (setAttrs)
+ pango_layout_set_attributes(m_layout, NULL);
+
+ // clean up the transformation matrix
+ pango_context_set_matrix(m_context, NULL);
+
+ if (isScaled)
+ {
+ // reset unscaled size
+ pango_font_description_set_size( m_fontdesc, oldSize );
- CalcBoundingBox(x+minX, y+minY);
- CalcBoundingBox(x+maxX, y+maxY);
+ // actually apply unscaled font
+ pango_layout_set_font_description( m_layout, m_fontdesc );
}
+
+ CalcBoundingBox(x+minX, y+minY);
+ CalcBoundingBox(x+maxX, y+maxY);
}
void wxWindowDCImpl::DoGetTextExtent(const wxString &string,
wxCoord *descent, wxCoord *externalLeading,
const wxFont *theFont) const
{
- if ( width )
- *width = 0;
- if ( height )
- *height = 0;
- if ( descent )
- *descent = 0;
- if ( externalLeading )
- *externalLeading = 0;
-
- if (string.empty())
- return;
-
- // ensure that theFont is always non-NULL
+ // ensure we work with a valid font
+ const wxFont *fontToUse;
if ( !theFont || !theFont->IsOk() )
- theFont = &m_font;
-
- // and use it if it's valid
- if ( theFont->IsOk() )
- {
- pango_layout_set_font_description
- (
- m_layout,
- theFont->GetNativeFontInfo()->description
- );
- }
-
- // Set layout's text
- const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(string, *theFont);
- if ( !dataUTF8 )
- {
- // hardly ideal, but what else can we do if conversion failed?
- return;
- }
+ fontToUse = &m_font;
+ else
+ fontToUse = theFont;
- pango_layout_set_text(m_layout, dataUTF8, -1);
+ wxCHECK_RET( fontToUse->IsOk(), wxT("invalid font") );
- int h;
- pango_layout_get_pixel_size(m_layout, width, &h);
- if (descent)
- {
- PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
- int baseline = pango_layout_iter_get_baseline(iter);
- pango_layout_iter_free(iter);
- *descent = h - PANGO_PIXELS(baseline);
- }
- if (height)
- *height = h;
-
- // Reset old font description
- if (theFont->IsOk())
- pango_layout_set_font_description( m_layout, m_fontdesc );
+ wxTextMeasure txm(GetOwner(), fontToUse);
+ txm.GetTextExtent(string, width, height, descent, externalLeading);
}
bool wxWindowDCImpl::DoGetPartialTextExtents(const wxString& text,
wxArrayInt& widths) const
{
- const size_t len = text.length();
- widths.Empty();
- widths.Add(0, len);
-
- if (text.empty())
- return true;
-
- // Set layout's text
- const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(text, m_font);
- if ( !dataUTF8 )
- {
- // hardly ideal, but what else can we do if conversion failed?
- wxLogLastError(wxT("DoGetPartialTextExtents"));
- return false;
- }
-
- pango_layout_set_text(m_layout, dataUTF8, -1);
+ wxCHECK_MSG( m_font.IsOk(), false, wxT("Invalid font") );
- // Calculate the position of each character based on the widths of
- // the previous characters
-
- // Code borrowed from Scintilla's PlatGTK
- PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
- PangoRectangle pos;
- pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
- size_t i = 0;
- while (pango_layout_iter_next_cluster(iter))
- {
- pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
- int position = PANGO_PIXELS(pos.x);
- widths[i++] = position;
- }
- while (i < len)
- widths[i++] = PANGO_PIXELS(pos.x + pos.width);
- pango_layout_iter_free(iter);
-
- return true;
+ wxTextMeasure txm(GetOwner(), &m_font);
+ return txm.GetPartialTextExtents(text, widths, m_scaleX);
}