Blame SOURCES/paps-fix-cpi.patch

2b6473
diff --git a/src/libpaps.c b/src/libpaps.c
2b6473
index b6363a7..1b80257 100644
2b6473
--- a/src/libpaps.c
2b6473
+++ b/src/libpaps.c
2b6473
@@ -55,6 +55,9 @@ typedef struct {
2b6473
   double last_pos_x;
2b6473
   double scale_x;
2b6473
   double scale_y;
2b6473
+  double width;
2b6473
+  double height;
2b6473
+  double cpi;
2b6473
 } paps_private_t;
2b6473
 
2b6473
 
2b6473
@@ -88,6 +91,26 @@ paps_t *paps_new()
2b6473
 }
2b6473
 
2b6473
 void
2b6473
+paps_set_paper_size(paps_t  *paps_,
2b6473
+		    gdouble  width,
2b6473
+		    gdouble  height)
2b6473
+{
2b6473
+	paps_private_t *paps = (paps_private_t *)paps_;
2b6473
+
2b6473
+	paps->width = width;
2b6473
+	paps->height = height;
2b6473
+}
2b6473
+
2b6473
+void
2b6473
+paps_set_cpi(paps_t  *paps_,
2b6473
+	     gdouble  cpi)
2b6473
+{
2b6473
+	paps_private_t *paps = (paps_private_t *)paps_;
2b6473
+
2b6473
+	paps->cpi = cpi;
2b6473
+}
2b6473
+
2b6473
+void
2b6473
 paps_set_scale(paps_t  *paps_,
2b6473
 	       gdouble  scale_x,
2b6473
 	       gdouble  scale_y)
2b6473
@@ -401,7 +424,7 @@ static void draw_contour(paps_private_t *paps,
2b6473
       FT_Face ft_face = pango_ft2_font_get_face(font);
2b6473
       int num_glyphs = glyphs->num_glyphs;
2b6473
       int glyph_idx;
2b6473
-      
2b6473
+
2b6473
       for (glyph_idx=0; glyph_idx
2b6473
         {
2b6473
           PangoGlyphGeometry geometry = glyphs->glyphs[glyph_idx].geometry;
2b6473
@@ -410,7 +433,11 @@ static void draw_contour(paps_private_t *paps,
2b6473
           glyph_pos_x = x_pos + 1.0*geometry.x_offset * scale;
2b6473
           glyph_pos_y = line_start_pos_y - 1.0*geometry.y_offset * scale;
2b6473
 
2b6473
-	  x_pos += geometry.width * scale * paps->scale_x;
2b6473
+	  if (paps->cpi > 0.0L) {
2b6473
+		  x_pos += (1 / paps->cpi * 72.0);
2b6473
+	  } else {
2b6473
+		  x_pos += geometry.width * scale * paps->scale_x;
2b6473
+	  }
2b6473
 
2b6473
           if (glyphs->glyphs[glyph_idx].glyph == PANGO_GLYPH_EMPTY)
2b6473
             continue;
2b6473
diff --git a/src/libpaps.h b/src/libpaps.h
2b6473
index 0b74321..cbb4042 100644
2b6473
--- a/src/libpaps.h
2b6473
+++ b/src/libpaps.h
2b6473
@@ -53,10 +53,16 @@ void paps_free(paps_t *paps);
2b6473
  * @param scale_y y-coordinate scale
2b6473
  *
2b6473
  */
2b6473
-void
2b6473
-paps_set_scale(paps_t  *paps,
2b6473
-	       gdouble  scale_x,
2b6473
-	       gdouble  scale_y);
2b6473
+void paps_set_scale(paps_t  *paps,
2b6473
+		    gdouble  scale_x,
2b6473
+		    gdouble  scale_y);
2b6473
+
2b6473
+void paps_set_paper_size(paps_t  *paps_,
2b6473
+			 gdouble  width,
2b6473
+			 gdouble  height);
2b6473
+
2b6473
+void paps_set_cpi(paps_t  *paps_,
2b6473
+		  gdouble  cpi);
2b6473
 
2b6473
 /** 
2b6473
  * libpaps may currently be used only with a PangoContext that it
2b6473
diff --git a/src/paps.c b/src/paps.c
2b6473
index 334d547..72dbaad 100644
2b6473
--- a/src/paps.c
2b6473
+++ b/src/paps.c
2b6473
@@ -33,6 +33,8 @@
2b6473
 #include <locale.h>
2b6473
 #include <cups/cups.h>
2b6473
 #include <cups/ppd.h>
2b6473
+#include <math.h>
2b6473
+#include <wchar.h>
2b6473
 
2b6473
 #define BUFSIZE 1024
2b6473
 #define DEFAULT_FONT_FAMILY	"Monospace"
2b6473
@@ -594,6 +596,8 @@ int main(int argc, char *argv[])
2b6473
   page_layout.owner = page_owner;
2b6473
   page_layout.cups_mode = cups_mode;
2b6473
 
2b6473
+  paps_set_paper_size(paps, page_width, page_height);
2b6473
+
2b6473
   /* calculate x-coordinate scale */
2b6473
   if (page_layout.cpi > 0.0L)
2b6473
     {
2b6473
@@ -606,7 +610,7 @@ int main(int argc, char *argv[])
2b6473
       w = pango_font_metrics_get_approximate_digit_width (metrics);
2b6473
       if (w > max_width)
2b6473
 	  max_width = w;
2b6473
-      page_layout.scale_x = 1 / page_layout.cpi * 72.0 * PANGO_SCALE / max_width;
2b6473
+      page_layout.scale_x = 1 / page_layout.cpi * 72.0 * (gdouble)PANGO_SCALE / (gdouble)max_width;
2b6473
       pango_font_metrics_unref (metrics);
2b6473
       g_object_unref (G_OBJECT (fontmap));
2b6473
 
2b6473
@@ -614,6 +618,8 @@ int main(int argc, char *argv[])
2b6473
       // update the font size to that width
2b6473
       pango_font_description_set_size (font_description, font_size * page_layout.scale_x);
2b6473
       pango_context_set_font_description (pango_context, font_description);
2b6473
+
2b6473
+      paps_set_cpi(paps, page_layout.cpi);
2b6473
     }
2b6473
 
2b6473
   page_layout.scale_x = page_layout.scale_y = 1.0;
2b6473
@@ -727,119 +733,6 @@ read_file (FILE   *file,
2b6473
   return text;
2b6473
 }
2b6473
 
2b6473
-#if 0
2b6473
-/* Take a UTF8 string and break it into paragraphs on \n characters.
2b6473
- *
2b6473
- * Sorry. I couldn't figure out what this version was supposed to do
2b6473
- *
2b6473
- */
2b6473
-static GList *
2b6473
-split_text_into_paragraphs (PangoContext *pango_context,
2b6473
-                            page_layout_t *page_layout,
2b6473
-                            int paint_width,  /* In pixels */
2b6473
-                            char *text)
2b6473
-{
2b6473
-  char *p = text;
2b6473
-  char *next;
2b6473
-  gunichar wc;
2b6473
-  GList *result = NULL;
2b6473
-  char *last_para = text;
2b6473
-  
2b6473
-  while (p != NULL && *p)
2b6473
-    {
2b6473
-      wc = g_utf8_get_char (p);
2b6473
-      next = g_utf8_next_char (p);
2b6473
-      if (wc == (gunichar)-1)
2b6473
-        {
2b6473
-          fprintf (stderr, "%s: Invalid character in input\n", g_get_prgname ());
2b6473
-          wc = 0;
2b6473
-        }
2b6473
-      if (!*p || !wc || wc == '\n' || wc == '\f')
2b6473
-        {
2b6473
-          Paragraph *para = g_new (Paragraph, 1);
2b6473
-          para->text = last_para;
2b6473
-          para->length = p - last_para;
2b6473
-          para->layout = pango_layout_new (pango_context);
2b6473
-
2b6473
-	  if (cpi > 0.0L && page_layout->do_wordwrap)
2b6473
-	    {
2b6473
-	      PangoRectangle ink_rect, logical_rect;
2b6473
-	      wchar_t *wtext, *wnewtext;
2b6473
-	      gchar *newtext;
2b6473
-	      size_t i, len, wwidth = 0, n;
2b6473
-
2b6473
-	      wtext = g_utf8_to_ucs4 (para->text, para->length, NULL, NULL, NULL);
2b6473
-	      if (wtext == NULL)
2b6473
-	        {
2b6473
-		  fprintf (stderr, "Failed to convert UTF-8 to UCS-4.\n");
2b6473
-                  exit(1);
2b6473
-		}
2b6473
-
2b6473
-	      len = g_utf8_strlen (para->text, para->length);
2b6473
-	      /* the amount of characters to be able to put on the line against CPI */
2b6473
-	      n = page_layout->column_width / 72.0 * cpi;
2b6473
-	      if (len > n)
2b6473
-	        {
2b6473
-		  wnewtext = g_new (wchar_t, wcslen (wtext) + 1);
2b6473
-		  if (wnewtext == NULL)
2b6473
-		    {
2b6473
-		      fprintf (stderr, "Failed to allocate a memory.\n");
2b6473
-		      g_free (wtext);
2b6473
-                      exit(1);
2b6473
-		    }
2b6473
-		  for (i = 0; i < len; i++)
2b6473
-		    {
2b6473
-		      wwidth += wcwidth (wtext[i]);
2b6473
-		      if (wwidth > n)
2b6473
-			  break;
2b6473
-		      wnewtext[i] = wtext[i];
2b6473
-		    }
2b6473
-		  wnewtext[i] = 0L;
2b6473
-
2b6473
-		  newtext = g_ucs4_to_utf8 ((const gunichar *)wnewtext, i, NULL, NULL, NULL);
2b6473
-		  if (newtext == NULL)
2b6473
-		    {
2b6473
-		      fprintf (stderr, "Failed to convert UCS-4 to UTF-8.\n");
2b6473
-                      exit(1);
2b6473
-		    }
2b6473
-
2b6473
-		  pango_layout_set_text (para->layout, newtext, -1);
2b6473
-		  pango_layout_get_extents (para->layout, &ink_rect, &logical_rect);
2b6473
-		  /* update paint_width to wrap_against CPI */
2b6473
-		  paint_width = logical_rect.width / PANGO_SCALE;
2b6473
-		  g_free (newtext);
2b6473
-		  g_free (wnewtext);
2b6473
-		}
2b6473
-	      g_free (wtext);
2b6473
-	    }
2b6473
-          pango_layout_set_text (para->layout, para->text, para->length);
2b6473
-          pango_layout_set_justify (para->layout, page_layout->do_justify);
2b6473
-          pango_layout_set_alignment (para->layout,
2b6473
-                                      page_layout->pango_dir == PANGO_DIRECTION_LTR
2b6473
-                                      ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);
2b6473
-          pango_layout_set_width (para->layout, paint_width * PANGO_SCALE);
2b6473
-          if (page_layout->do_wordwrap)
2b6473
-              pango_layout_set_wrap (para->layout, PANGO_WRAP_WORD_CHAR);
2b6473
-          para->height = 0;
2b6473
-
2b6473
-          if (wc == '\f')
2b6473
-              para->formfeed = 1;
2b6473
-          else
2b6473
-              para->formfeed = 0;
2b6473
-
2b6473
-          last_para = next;
2b6473
-            
2b6473
-          result = g_list_prepend (result, para);
2b6473
-        }
2b6473
-      if (!wc) /* incomplete character at end */
2b6473
-        break;
2b6473
-      p = next;
2b6473
-    }
2b6473
-
2b6473
-  return g_list_reverse (result);
2b6473
-}
2b6473
-#endif
2b6473
-
2b6473
 /* Take a UTF8 string and break it into paragraphs on \n characters
2b6473
  */
2b6473
 static GList *
2b6473
@@ -905,18 +798,85 @@ split_text_into_paragraphs (PangoContext *pango_context,
2b6473
               para->text = last_para;
2b6473
               para->length = p - last_para;
2b6473
               para->layout = pango_layout_new (pango_context);
2b6473
-              //          pango_layout_set_font_description (para->layout, font_description);
2b6473
-              pango_layout_set_text (para->layout, para->text, para->length);
2b6473
+
2b6473
+	      if (page_layout->cpi > 0.0L && page_layout->do_wordwrap) {
2b6473
+		      /* figuring out the correct width from the pango_font_metrics_get_approximate_width()
2b6473
+		       * is really hard and pango_layout_set_wrap() doesn't work properly then.
2b6473
+		       * Those are not reliable to render the characters exactly according to the given CPI.
2b6473
+		       * So Re-calculate the width to wrap up to be comfortable with CPI.
2b6473
+		       */
2b6473
+		      wchar_t *wtext = NULL, *wnewtext = NULL;
2b6473
+		      gchar *newtext = NULL;
2b6473
+		      gsize len, col, i, wwidth = 0;
2b6473
+		      PangoRectangle ink_rect, logical_rect;
2b6473
+
2b6473
+		      wtext = (wchar_t *)g_utf8_to_ucs4(para->text, para->length, NULL, NULL, NULL);
2b6473
+		      if (wtext == NULL) {
2b6473
+			      fprintf(stderr, "%s: Unable to convert UTF-8 to UCS-4.\n", g_get_prgname());
2b6473
+			fail:
2b6473
+			      g_free(wtext);
2b6473
+			      g_free(wnewtext);
2b6473
+			      g_free(newtext);
2b6473
+			      if (page_layout->cups_mode) {
2b6473
+				      /* try to continue parsing text */
2b6473
+				      p = next;
2b6473
+				      continue;
2b6473
+			      } else {
2b6473
+				      exit(1);
2b6473
+			      }
2b6473
+		      }
2b6473
+		      len = g_utf8_strlen(para->text, para->length);
2b6473
+		      /* the amount of characters that can be put on the line against CPI */
2b6473
+		      col = page_layout->column_width / 72.0 * page_layout->cpi;
2b6473
+		      if (len > col) {
2b6473
+			      /* need to wrap up them */
2b6473
+			      wnewtext = g_new(wchar_t, wcslen(wtext) + 1);
2b6473
+			      if (wnewtext == NULL) {
2b6473
+				      fprintf(stderr, "%s: Unable to allocate the memory.\n", g_get_prgname());
2b6473
+				      goto fail;
2b6473
+			      }
2b6473
+			      for (i = 0; i < len; i++) {
2b6473
+				      wwidth += wcwidth(wtext[i]);
2b6473
+				      if (wwidth > col)
2b6473
+					      break;
2b6473
+				      wnewtext[i] = wtext[i];
2b6473
+			      }
2b6473
+			      wnewtext[i] = 0L;
2b6473
+
2b6473
+			      newtext = g_ucs4_to_utf8((const gunichar *)wnewtext, i, NULL, NULL, NULL);
2b6473
+			      if (newtext == NULL) {
2b6473
+				      fprintf(stderr, "%s: Unable to convert UCS-4 to UTF-8.\n", g_get_prgname());
2b6473
+				      goto fail;
2b6473
+			      }
2b6473
+			      pango_layout_set_text(para->layout, newtext, -1);
2b6473
+			      pango_layout_get_extents(para->layout, &ink_rect, &logical_rect);
2b6473
+			      paint_width = logical_rect.width / PANGO_SCALE;
2b6473
+			      g_free(wnewtext);
2b6473
+			      g_free(newtext);
2b6473
+
2b6473
+			      para->length = i;
2b6473
+			      next = g_utf8_offset_to_pointer(para->text, para->length);
2b6473
+			      wc = g_utf8_prev_char(next);
2b6473
+		      } else {
2b6473
+			      pango_layout_set_text(para->layout, para->text, para->length);
2b6473
+		      }
2b6473
+		      g_free(wtext);
2b6473
+		      
2b6473
+		      pango_layout_set_width(para->layout, -1);
2b6473
+	      } else {
2b6473
+		      pango_layout_set_text (para->layout, para->text, para->length);
2b6473
+		      if (page_layout->do_wordwrap) {
2b6473
+			      pango_layout_set_wrap (para->layout, PANGO_WRAP_WORD_CHAR);
2b6473
+			      pango_layout_set_width (para->layout, paint_width * PANGO_SCALE);
2b6473
+		      } else {
2b6473
+			      pango_layout_set_width (para->layout, -1);
2b6473
+		      }
2b6473
+	      }
2b6473
+					      
2b6473
               pango_layout_set_justify (para->layout, page_layout->do_justify);
2b6473
               pango_layout_set_alignment (para->layout,
2b6473
                                           page_layout->pango_dir == PANGO_DIRECTION_LTR
2b6473
                                           ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);
2b6473
-              if (page_layout->do_wordwrap) {
2b6473
-                pango_layout_set_wrap (para->layout, PANGO_WRAP_WORD_CHAR);
2b6473
-                pango_layout_set_width (para->layout, paint_width * PANGO_SCALE);
2b6473
-              } else {
2b6473
-                pango_layout_set_width (para->layout, -1);
2b6473
-              }
2b6473
 
2b6473
               para->height = 0;
2b6473