[gimp] Bug 573256 - Text tool appearance doesn't account for DPI



commit 2a88723a40e594fed66956decddfb35e5513ee08
Author: Michael Natterer <mitch gimp org>
Date:   Fri Jun 19 17:08:34 2009 +0200

    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.

 app/text/gimptextlayout-render.c |   28 +------
 app/text/gimptextlayout.c        |  177 ++++++++++++++++++++++++++++++++++++++
 app/text/gimptextlayout.h        |   53 ++++++++----
 app/tools/gimptexttool.c         |   40 +++++++--
 4 files changed, 246 insertions(+), 52 deletions(-)
---
diff --git a/app/text/gimptextlayout-render.c b/app/text/gimptextlayout-render.c
index 8a9cf28..aa7241d 100644
--- a/app/text/gimptextlayout-render.c
+++ b/app/text/gimptextlayout-render.c
@@ -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;
-}
diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c
index 24c96f9..e0e7a2e 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -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)
 {
diff --git a/app/text/gimptextlayout.h b/app/text/gimptextlayout.h
index c27a063..c562ca8 100644
--- a/app/text/gimptextlayout.h
+++ b/app/text/gimptextlayout.h
@@ -35,22 +35,43 @@ struct _GimpTextLayoutClass
 };
 
 
-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);
-
-GimpText       * gimp_text_layout_get_text         (GimpTextLayout *layout);
-PangoLayout    * gimp_text_layout_get_pango_layout (GimpTextLayout *layout);
+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);
+
+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__ */
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 1cbd68f..614ec75 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -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_tmp = first_x;
+      last_tmp  = last_x;
 
-      first_x = PANGO_PIXELS (first_x) + logical_off_x;
-      last_x  = PANGO_PIXELS (last_x)  + logical_off_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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]