2005-07-08  Kristian Høgsberg  <krh@redhat.com>

        * glib/poppler-page.cc (poppler_page_set_selection_alpha): Add
        this function to initialize the alpha channel when using the
        splash backend.

        * poppler/TextOutputDev.cc (visitLine): Add missing scaling of
        intra-line selection edges.
diff --git a/ChangeLog b/ChangeLog
index c8717ca..29e3db5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-08  Kristian Høgsberg  <krh@redhat.com>
+
+	* glib/poppler-page.cc (poppler_page_set_selection_alpha): Add
+	this function to initialize the alpha channel when using the
+	splash backend.
+
+	* poppler/TextOutputDev.cc (visitLine): Add missing scaling of
+	intra-line selection edges.
+
 2005-07-07  Kristian Høgsberg  <krh@redhat.com>
 
 	* glib/poppler-page.cc (poppler_page_prepare_output_dev): Account
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 8604906..6ffd1e4 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -259,7 +259,7 @@
 }
 
 #elif defined (HAVE_SPLASH)
-
+ 
 typedef struct {
 } OutputDevData;
 
@@ -314,6 +314,8 @@
 	  dst[0] = splashRGB8R(*src);
 	  dst[1] = splashRGB8G(*src); 
 	  dst[2] = splashRGB8B(*src);
+	  if (pixbuf_n_channels == 4)
+	    dst[3] = 0;
 	  dst += pixbuf_n_channels;
 	  src++;
 	}
@@ -423,6 +425,59 @@
   return region;
 }
 
+#if defined (HAVE_CAIRO)
+
+static void
+poppler_page_set_selection_alpha (PopplerPage      *page,
+				  double            scale,
+				  GdkPixbuf        *pixbuf,
+				  PopplerRectangle *selection)
+{
+  /* Cairo doesn't need this, since cairo generates an alpha channel. */ 
+}
+
+#elif defined (HAVE_SPLASH)
+
+static void
+poppler_page_set_selection_alpha (PopplerPage      *page,
+				  double            scale,
+				  GdkPixbuf        *pixbuf,
+				  PopplerRectangle *selection)
+{
+  GdkRegion *region;
+  gint n_rectangles, i, x, y;
+  GdkRectangle *rectangles;
+  int pixbuf_rowstride, pixbuf_n_channels;
+  guchar *pixbuf_data, *dst;
+
+  pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
+  pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+  pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+
+  if (pixbuf_n_channels != 4)
+    return;
+
+  region = poppler_page_get_selection_region (page, scale, selection);
+
+  gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
+  for (i = 0; i < n_rectangles; i++) {
+    for (y = 0; y < rectangles[i].height; y++) {
+      dst = pixbuf_data + (rectangles[i].y + y) * pixbuf_rowstride +
+	rectangles[i].x * pixbuf_n_channels;
+      for (x = 0; x < rectangles[i].width; x++) {
+	  dst[3] = 0xff;
+	  dst += pixbuf_n_channels;
+      }
+    }
+  }
+
+  g_free (rectangles);
+
+  gdk_region_destroy (region);
+}
+
+#endif
+
 void
 poppler_page_render_selection (PopplerPage *page,
 			       gdouble      scale,
@@ -445,6 +500,8 @@
 
   poppler_page_copy_to_pixbuf (page, pixbuf, &data);
 
+  poppler_page_set_selection_alpha (page, scale, pixbuf, selection);
+
   /* We'll need a function to destroy page->text_dev and page->gfx
    * when the application wants to get rid of them.
    *
diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index 75256ec..654373b 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -3111,19 +3111,22 @@
   int i;
 
   margin = (line->yMax - line->yMin) / 8;
-  x1 = floor (line->xMax * scale);
-  y1 = floor ((line->yMin - margin) * scale);
-  x2 = ceil (line->xMin * scale);
-  y2 = ceil ((line->yMax + margin) * scale);
+  x1 = line->xMax;
+  y1 = line->yMin - margin;
+  x2 = line->xMin;
+  y2 = line->yMax + margin;
 
   for (i = 0; i < line->len; i++) {
     if (selection->x1 < line->edge[i + 1] && line->edge[i] < x1)
-      x1 = floor (line->edge[i]);
+      x1 = line->edge[i];
     if (line->edge[i] < selection->x2)
-      x2 = ceil (line->edge[i + 1]);
+      x2 = line->edge[i + 1];
   }
 
-  rect = new PDFRectangle (x1, y1, x2, y2);
+  rect = new PDFRectangle (floor (x1 * scale), 
+			   floor (y1 * scale),
+			   ceil (x2 * scale),
+			   ceil (y2 * scale));
   list->append (rect);
 }