/** * Find where to split a string to make it fit a width. * * \param[in] fstyle style for this text * \param[in] string UTF-8 string to measure * \param[in] length length of string, in bytes * \param[in] x width available * \param[out] char_offset updated to offset in string of actual_x, [1..length] * \param[out] actual_x updated to x coordinate of character closest to x * \return NSERROR_OK or appropriate error code on faliure * * On exit, char_offset indicates first character after split point. * * \note char_offset of 0 must never be returned. * * Returns: * char_offset giving split point closest to x, where actual_x <= x * else * char_offset giving split point closest to x, where actual_x > x * * Returning char_offset == length means no split possible */ static nserror nsfont_split(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { int index = length; PangoFontDescription *desc; PangoContext *context; PangoLayout *layout; PangoLayoutLine *line; context = gdk_pango_context_get(); layout = pango_layout_new(context); desc = nsfont_style_to_description(fstyle); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); pango_layout_set_text(layout, string, length); /* Limit width of layout to the available width */ pango_layout_set_width(layout, x * PANGO_SCALE); /* Request word wrapping */ pango_layout_set_wrap(layout, PANGO_WRAP_WORD); /* Prevent pango treating linebreak characters as line breaks */ pango_layout_set_single_paragraph_mode(layout, TRUE); /* Obtain the second line of the layout (if there is one) */ line = pango_layout_get_line(layout, 1); if (line != NULL) { /* Pango split the text. The line's start_index indicates the * start of the character after the line break. */ index = line->start_index; } g_object_unref(layout); g_object_unref(context); *char_offset = index; /* Obtain the pixel offset of the split character */ nsfont_width(fstyle, string, index, actual_x); return NSERROR_OK; }
static bool nsfont_position_in_string(const plot_font_style_t *style, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { HDC hdc = GetDC(NULL); HFONT font = get_font(style); HFONT fontbak = SelectObject(hdc, font); SIZE s; int offset; GetTextExtentExPoint(hdc, string, length, x, &offset, NULL, &s); *char_offset = (size_t)offset; nsfont_width(style, string, *char_offset, actual_x); font = SelectObject(hdc, fontbak); DeleteObject(font); ReleaseDC(NULL, hdc); return true; }