Bug 573256 - Text tool appearance doesn't account for DPI
* app/text/gimptextlayout-render.c: remove private function which creates the transform matrix. * app/text/gimptextlayout.[ch]: add it here as public API. Also add function which transform and untransform PangoRectangles, points and distances using the transform matrix. * app/tools/gimptexttool.c: convert coordinates using above new transform functions when drawing selection and cursor, and when processing mouse events.
This commit is contained in:
@ -32,10 +32,6 @@
|
||||
#include "gimptextlayout-render.h"
|
||||
|
||||
|
||||
static void gimp_text_layout_render_trafo (GimpTextLayout *layout,
|
||||
cairo_matrix_t *trafo);
|
||||
|
||||
|
||||
void
|
||||
gimp_text_layout_render (GimpTextLayout *layout,
|
||||
cairo_t *cr,
|
||||
@ -79,7 +75,7 @@ gimp_text_layout_render (GimpTextLayout *layout,
|
||||
|
||||
cairo_translate (cr, x, y);
|
||||
|
||||
gimp_text_layout_render_trafo (layout, &trafo);
|
||||
gimp_text_layout_get_transform (layout, &trafo);
|
||||
cairo_transform (cr, &trafo);
|
||||
|
||||
if (path)
|
||||
@ -87,25 +83,3 @@ gimp_text_layout_render (GimpTextLayout *layout,
|
||||
else
|
||||
pango_cairo_show_layout (cr, pango_layout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_text_layout_render_trafo (GimpTextLayout *layout,
|
||||
cairo_matrix_t *trafo)
|
||||
{
|
||||
GimpText *text = gimp_text_layout_get_text (layout);
|
||||
gdouble xres;
|
||||
gdouble yres;
|
||||
gdouble norm;
|
||||
|
||||
gimp_text_layout_get_resolution (layout, &xres, &yres);
|
||||
|
||||
norm = 1.0 / yres * xres;
|
||||
|
||||
trafo->xx = text->transformation.coeff[0][0] * norm;
|
||||
trafo->xy = text->transformation.coeff[0][1] * 1.0;
|
||||
trafo->yx = text->transformation.coeff[1][0] * norm;
|
||||
trafo->yy = text->transformation.coeff[1][1] * 1.0;
|
||||
trafo->x0 = 0;
|
||||
trafo->y0 = 0;
|
||||
}
|
||||
|
||||
@ -289,6 +289,183 @@ gimp_text_layout_get_pango_layout (GimpTextLayout *layout)
|
||||
return layout->layout;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_get_transform (GimpTextLayout *layout,
|
||||
cairo_matrix_t *matrix)
|
||||
{
|
||||
GimpText *text;
|
||||
gdouble xres;
|
||||
gdouble yres;
|
||||
gdouble norm;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (matrix != NULL);
|
||||
|
||||
text = gimp_text_layout_get_text (layout);
|
||||
|
||||
gimp_text_layout_get_resolution (layout, &xres, &yres);
|
||||
|
||||
norm = 1.0 / yres * xres;
|
||||
|
||||
matrix->xx = text->transformation.coeff[0][0] * norm;
|
||||
matrix->xy = text->transformation.coeff[0][1] * 1.0;
|
||||
matrix->yx = text->transformation.coeff[1][0] * norm;
|
||||
matrix->yy = text->transformation.coeff[1][1] * 1.0;
|
||||
matrix->x0 = 0;
|
||||
matrix->y0 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_transform_rect (GimpTextLayout *layout,
|
||||
PangoRectangle *rect)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble x, y;
|
||||
gdouble width, height;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (rect != NULL);
|
||||
|
||||
x = rect->x;
|
||||
y = rect->y;
|
||||
width = rect->width;
|
||||
height = rect->height;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
cairo_matrix_transform_point (&matrix, &x, &y);
|
||||
cairo_matrix_transform_distance (&matrix, &width, &height);
|
||||
|
||||
rect->x = ROUND (x);
|
||||
rect->y = ROUND (y);
|
||||
rect->width = ROUND (width);
|
||||
rect->height = ROUND (height);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_transform_point (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble _x = 0.0;
|
||||
gdouble _y = 0.0;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
|
||||
if (x) _x = *x;
|
||||
if (y) _y = *y;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
cairo_matrix_transform_point (&matrix, &_x, &_y);
|
||||
|
||||
if (x) *x = _x;
|
||||
if (y) *y = _y;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_transform_distance (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble _x = 0.0;
|
||||
gdouble _y = 0.0;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
|
||||
if (x) _x = *x;
|
||||
if (y) _y = *y;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
cairo_matrix_transform_distance (&matrix, &_x, &_y);
|
||||
|
||||
if (x) *x = _x;
|
||||
if (y) *y = _y;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_untransform_rect (GimpTextLayout *layout,
|
||||
PangoRectangle *rect)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble x, y;
|
||||
gdouble width, height;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (rect != NULL);
|
||||
|
||||
x = rect->x;
|
||||
y = rect->y;
|
||||
width = rect->width;
|
||||
height = rect->height;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
if (cairo_matrix_invert (&matrix) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_matrix_transform_point (&matrix, &x, &y);
|
||||
cairo_matrix_transform_distance (&matrix, &width, &height);
|
||||
|
||||
rect->x = ROUND (x);
|
||||
rect->y = ROUND (y);
|
||||
rect->width = ROUND (width);
|
||||
rect->height = ROUND (height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_untransform_point (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble _x = 0.0;
|
||||
gdouble _y = 0.0;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
|
||||
if (x) _x = *x;
|
||||
if (y) _y = *y;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
if (cairo_matrix_invert (&matrix) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_matrix_transform_point (&matrix, &_x, &_y);
|
||||
|
||||
if (x) *x = _x;
|
||||
if (y) *y = _y;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_text_layout_untransform_distance (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
gdouble _x = 0.0;
|
||||
gdouble _y = 0.0;
|
||||
|
||||
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
|
||||
|
||||
if (x) _x = *x;
|
||||
if (y) _y = *y;
|
||||
|
||||
gimp_text_layout_get_transform (layout, &matrix);
|
||||
|
||||
if (cairo_matrix_invert (&matrix) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_matrix_transform_distance (&matrix, &_x, &_y);
|
||||
|
||||
if (x) *x = _x;
|
||||
if (y) *y = _y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_text_layout_position (GimpTextLayout *layout)
|
||||
{
|
||||
|
||||
@ -35,22 +35,43 @@ struct _GimpTextLayoutClass
|
||||
};
|
||||
|
||||
|
||||
GType gimp_text_layout_get_type (void) G_GNUC_CONST;
|
||||
GType gimp_text_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpTextLayout * gimp_text_layout_new (GimpText *text,
|
||||
GimpImage *image);
|
||||
gboolean gimp_text_layout_get_size (GimpTextLayout *layout,
|
||||
gint *width,
|
||||
gint *heigth);
|
||||
void gimp_text_layout_get_offsets (GimpTextLayout *layout,
|
||||
gint *x,
|
||||
gint *y);
|
||||
void gimp_text_layout_get_resolution (GimpTextLayout *layout,
|
||||
gdouble *xres,
|
||||
gdouble *yres);
|
||||
GimpTextLayout * gimp_text_layout_new (GimpText *text,
|
||||
GimpImage *image);
|
||||
gboolean gimp_text_layout_get_size (GimpTextLayout *layout,
|
||||
gint *width,
|
||||
gint *heigth);
|
||||
void gimp_text_layout_get_offsets (GimpTextLayout *layout,
|
||||
gint *x,
|
||||
gint *y);
|
||||
void gimp_text_layout_get_resolution (GimpTextLayout *layout,
|
||||
gdouble *xres,
|
||||
gdouble *yres);
|
||||
|
||||
GimpText * gimp_text_layout_get_text (GimpTextLayout *layout);
|
||||
PangoLayout * gimp_text_layout_get_pango_layout (GimpTextLayout *layout);
|
||||
GimpText * gimp_text_layout_get_text (GimpTextLayout *layout);
|
||||
PangoLayout * gimp_text_layout_get_pango_layout (GimpTextLayout *layout);
|
||||
|
||||
void gimp_text_layout_get_transform (GimpTextLayout *layout,
|
||||
cairo_matrix_t *matrix);
|
||||
|
||||
void gimp_text_layout_transform_rect (GimpTextLayout *layout,
|
||||
PangoRectangle *rect);
|
||||
void gimp_text_layout_transform_point (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
void gimp_text_layout_transform_distance (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
void gimp_text_layout_untransform_rect (GimpTextLayout *layout,
|
||||
PangoRectangle *rect);
|
||||
void gimp_text_layout_untransform_point (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
void gimp_text_layout_untransform_distance (GimpTextLayout *layout,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
|
||||
#endif /* __GIMP_TEXT_LAYOUT_H__ */
|
||||
|
||||
@ -1069,6 +1069,7 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
|
||||
layout = gimp_text_layout_get_pango_layout (text_tool->layout);
|
||||
|
||||
pango_layout_get_pixel_extents (layout, &ink_extents, &logical_extents);
|
||||
gimp_text_layout_transform_rect (text_tool->layout, &logical_extents);
|
||||
|
||||
if (ink_extents.x < 0)
|
||||
logical_off_x = -ink_extents.x;
|
||||
@ -1103,6 +1104,7 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
|
||||
g_free (string);
|
||||
|
||||
pango_layout_index_to_pos (layout, cursorx, &crect);
|
||||
gimp_text_layout_transform_rect (text_tool->layout, &crect);
|
||||
|
||||
crect.x = PANGO_PIXELS (crect.x) + logical_off_x;
|
||||
crect.y = PANGO_PIXELS (crect.y) + logical_off_y;
|
||||
@ -1157,14 +1159,21 @@ gimp_text_tool_draw_preedit (GimpDrawTool *draw_tool,
|
||||
|
||||
do
|
||||
{
|
||||
gint firstline, lastline;
|
||||
gint first_x, last_x;
|
||||
gint firstline, lastline;
|
||||
gint first_x, last_x;
|
||||
gdouble first_tmp, last_tmp;
|
||||
|
||||
pango_layout_index_to_line_x (layout, min, 0, &firstline, &first_x);
|
||||
pango_layout_index_to_line_x (layout, max, 0, &lastline, &last_x);
|
||||
pango_layout_index_to_line_x (layout, max, 0, &lastline, &last_x);
|
||||
|
||||
first_x = PANGO_PIXELS (first_x) + logical_off_x;
|
||||
last_x = PANGO_PIXELS (last_x) + logical_off_x;
|
||||
first_tmp = first_x;
|
||||
last_tmp = last_x;
|
||||
|
||||
gimp_text_layout_transform_distance (text_tool->layout, &first_tmp, NULL);
|
||||
gimp_text_layout_transform_distance (text_tool->layout, &last_tmp, NULL);
|
||||
|
||||
first_x = PANGO_PIXELS (first_tmp) + logical_off_x;
|
||||
last_x = PANGO_PIXELS (last_tmp) + logical_off_x;
|
||||
|
||||
if (i >= firstline && i <= lastline)
|
||||
{
|
||||
@ -1173,6 +1182,8 @@ gimp_text_tool_draw_preedit (GimpDrawTool *draw_tool,
|
||||
pango_layout_iter_get_line_extents (line_iter, NULL, &crect);
|
||||
pango_extents_to_pixels (&crect, NULL);
|
||||
|
||||
gimp_text_layout_transform_rect (text_tool->layout, &crect);
|
||||
|
||||
crect.x += logical_off_x;
|
||||
crect.y += logical_off_y;
|
||||
|
||||
@ -1256,14 +1267,21 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool,
|
||||
*/
|
||||
do
|
||||
{
|
||||
gint firstline, lastline;
|
||||
gint first_x, last_x;
|
||||
gint firstline, lastline;
|
||||
gint first_x, last_x;
|
||||
gdouble first_tmp, last_tmp;
|
||||
|
||||
pango_layout_index_to_line_x (layout, min, 0, &firstline, &first_x);
|
||||
pango_layout_index_to_line_x (layout, max, 0, &lastline, &last_x);
|
||||
|
||||
first_x = PANGO_PIXELS (first_x) + logical_off_x;
|
||||
last_x = PANGO_PIXELS (last_x) + logical_off_x;
|
||||
first_tmp = first_x;
|
||||
last_tmp = last_x;
|
||||
|
||||
gimp_text_layout_transform_distance (text_tool->layout, &first_tmp, NULL);
|
||||
gimp_text_layout_transform_distance (text_tool->layout, &last_tmp, NULL);
|
||||
|
||||
first_x = PANGO_PIXELS (first_tmp) + logical_off_x;
|
||||
last_x = PANGO_PIXELS (last_tmp) + logical_off_x;
|
||||
|
||||
if (i >= firstline && i <= lastline)
|
||||
{
|
||||
@ -1272,6 +1290,8 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool,
|
||||
pango_layout_iter_get_line_extents (line_iter, NULL, &crect);
|
||||
pango_extents_to_pixels (&crect, NULL);
|
||||
|
||||
gimp_text_layout_transform_rect (text_tool->layout, &crect);
|
||||
|
||||
crect.x += logical_off_x;
|
||||
crect.y += logical_off_y;
|
||||
|
||||
@ -2238,6 +2258,8 @@ gimp_text_tool_xy_to_offset (GimpTextTool *text_tool,
|
||||
gint offset;
|
||||
gint trailing;
|
||||
|
||||
gimp_text_layout_untransform_point (text_tool->layout, &x, &y);
|
||||
|
||||
/* adjust to offset of logical rect */
|
||||
layout = gimp_text_layout_get_pango_layout (text_tool->layout);
|
||||
pango_layout_get_pixel_extents (layout, &ink_extents, NULL);
|
||||
|
||||
Reference in New Issue
Block a user