diff --git a/bigpicture.c b/bigpicture.c
index cda0fad0dff7ae2794d6b5e1b608337e796be023..6437a72c93b354709a769790fd789240f69d5092 100644
--- a/bigpicture.c
+++ b/bigpicture.c
@@ -90,27 +90,41 @@ gdouble pixelsPerBase(const gint displayWidth, const IntRange const *displayRang
 }
 
 
+/* Invert the given coord's position within the given range. Only invert if the bool is true; otherwise
+ * returns the original coord */
+static int invertCoord(const int coord, const IntRange const *range, const gboolean invert)
+{
+  int result = invert ? range->max - coord + range->min : coord;
+  return result;
+}
+
+
 /* Convert a base index to an x coord within the given rectangle. Returns the number of pixels 
  * from the left edge (including the start of the rectangle) to where the base lies. displayRev 
  * should be passed as true if the display is toggled (i.e. low values on the right and high 
- * values on the left). */
-gint convertBaseIdxToGridPos(const gint baseIdx, 
+ * values on the left). Clips the result to the rectangle if clip is true */
+gint convertBaseIdxToGridPos(const gint dnaIdx, 
 			     const GdkRectangle const *rect, 
-			     const IntRange const *displayRange)
+			     const IntRange const *dnaDispRange,
+                             const gboolean displayRev,
+                             const gboolean clip)
 {
   gint result = UNSET_INT;
   
-  gdouble numBasesFromEdge = (gdouble)(baseIdx - displayRange->min); /* 0-based index from edge */
-  if (numBasesFromEdge < 0)
+  int baseIdx = invertCoord(dnaIdx, dnaDispRange, displayRev);
+  
+  gdouble numBasesFromEdge = (gdouble)(baseIdx - dnaDispRange->min); /* 0-based index from edge */
+
+  if (clip && numBasesFromEdge < 0)
     {
       numBasesFromEdge = 0;
     }
   
-  gint pixelsFromEdge = (int)(numBasesFromEdge * pixelsPerBase(rect->width, displayRange));
+  gint pixelsFromEdge = (int)(numBasesFromEdge * pixelsPerBase(rect->width, dnaDispRange));
   
   result = rect->x + pixelsFromEdge;
   
-  if (result > rect->x + rect->width)
+  if (clip && result > rect->x + rect->width)
     {
       result = rect->x + rect->width;
     }
@@ -188,13 +202,16 @@ static void drawVerticalGridLineHeaders(GtkWidget *header,
   BlxViewContext *bc = bigPictureGetContext(bigPicture);
   GridHeaderProperties *headerProperties = gridHeaderGetProperties(header);
   BigPictureProperties *bpProperties = bigPictureGetProperties(bigPicture);
+  
+  /* Get the display range in dna coords */
+  IntRange dnaDispRange;
+  convertDisplayRangeToDnaRange(&bpProperties->displayRange, bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dnaDispRange);
 
   const int direction = bc->displayRev ? -1 : 1; /* to subtract instead of add when display reversed */
   
-  /* Get the first base index (in terms of the nucleotide coords) and round it to a nice round
-   * number. We'll offset all of the gridlines by the distance between this and the real start coord. */
-  const int realFirstBaseIdx = convertDisplayIdxToDnaIdx(bpProperties->displayRange.min, bc->seqType, 1, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange);
-  const int firstBaseIdx = roundToValue(realFirstBaseIdx, bpProperties->roundTo);
+  /* Get the first base index and round it to a nice round number. We'll offset all of the gridlines 
+   * by the distance between this and the real start coord. */
+  const int firstBaseIdx = roundToValue(dnaDispRange.min, bpProperties->roundTo);
   
   /* Calculate the top and bottom heights for the lines. */
   const gint bottomBorder = headerProperties->headerRect.y + headerProperties->headerRect.height;
@@ -211,8 +228,7 @@ static void drawVerticalGridLineHeaders(GtkWidget *header,
       int numBasesFromLeft = bpProperties->basesPerCell * hCell;
       int baseIdx = firstBaseIdx + (numBasesFromLeft * direction);
 
-      const int displayIdx = convertDnaIdxToDisplayIdx(baseIdx, bc->seqType, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange, NULL);
-      const int x = convertBaseIdxToGridPos(displayIdx, &headerProperties->headerRect, &bpProperties->displayRange);
+      const int x = convertBaseIdxToGridPos(baseIdx, &headerProperties->headerRect, &dnaDispRange, bc->displayRev, TRUE);
       
       if (x > minX && x < maxX)
 	{
@@ -667,16 +683,25 @@ static gboolean onExposeGridHeader(GtkWidget *header, GdkEventExpose *event, gpo
 }
 
 
-/* Convert an x coord on the given widget to a base index */
-gint convertWidgetPosToBaseIdx(const gint widgetPos, 
-                               const GdkRectangle const *displayRect,  
-                               const IntRange const *displayRange)
+/* Convert an x coord on the given widget to a base index (in nucleotide coords) */
+static gint convertWidgetPosToBaseIdx(const gint widgetPos, 
+                                      const GdkRectangle const *displayRect,  
+                                      const IntRange const *dnaDispRange,
+                                      const gboolean displayRev)
 {
   gint result = UNSET_INT;
   
   int distFromEdge = (int)((gdouble)widgetPos - (gdouble)displayRect->x);
-  int basesFromEdge = distFromEdge / pixelsPerBase(displayRect->width, displayRange);
-  result = displayRange->min + basesFromEdge;
+  int basesFromEdge = distFromEdge / pixelsPerBase(displayRect->width, dnaDispRange);
+  
+  if (displayRev)
+    {
+      result = dnaDispRange->max - basesFromEdge;
+    }
+  else
+    {
+      result = dnaDispRange->min + basesFromEdge;
+    }
   
   return result;
 }
@@ -687,15 +712,19 @@ gint convertWidgetPosToBaseIdx(const gint widgetPos,
  * Only does anything if the preview box centre is set. */
 void drawPreviewBox(GtkWidget *bigPicture, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *displayRect, GdkRectangle *highlightRect)
 {
-  BigPictureProperties *bigPictureProperties = bigPictureGetProperties(bigPicture);
+  BigPictureProperties *bpProperties = bigPictureGetProperties(bigPicture);
+  BlxViewContext *bc = bigPictureGetContext(bigPicture);
   
-  if (bigPictureProperties->previewBoxCentre == UNSET_INT)
+  if (bpProperties->previewBoxCentre == UNSET_INT)
     {
       return;
     }
 
-  int previewBoxCentre = bigPictureProperties->previewBoxCentre;
-  const IntRange const *displayRange = &bigPictureProperties->displayRange;
+  int previewBoxCentre = bpProperties->previewBoxCentre;
+  
+  /* Get the display range in dna coords */
+  IntRange dnaDispRange;
+  convertDisplayRangeToDnaRange(&bpProperties->displayRange, bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dnaDispRange);
   
   /* Find the x coord for the left edge of the preview box (or the right edge, if
    * the display is right-to-left). */
@@ -703,15 +732,14 @@ void drawPreviewBox(GtkWidget *bigPicture, GdkDrawable *drawable, GdkGC *gc, Gdk
   
   /* Convert it to the base index and back again so that we get it rounded to the position of
    * the nearest base. */
-  int baseIdx = convertWidgetPosToBaseIdx(x, displayRect, displayRange);
-  int xRounded = convertBaseIdxToGridPos(baseIdx, displayRect, displayRange);
+  int baseIdx = convertWidgetPosToBaseIdx(x, displayRect, &dnaDispRange, bc->displayRev);
+  int xRounded = convertBaseIdxToGridPos(baseIdx, displayRect, &dnaDispRange, bc->displayRev, TRUE);
   
   /* The other dimensions of the preview box are the same as the current highlight box. */
   GdkRectangle previewRect = {xRounded, highlightRect->y, highlightRect->width, highlightRect->height};
 
-  BlxViewContext *bc = bigPictureGetContext(bigPicture);
   GdkColor *previewBoxColor = getGdkColor(BLXCOLOR_PREVIEW_BOX, bc->defaultColors, FALSE, bc->usePrintColors);
-  drawHighlightBox(drawable, &previewRect, bigPictureProperties->previewBoxLineWidth, previewBoxColor);
+  drawHighlightBox(drawable, &previewRect, bpProperties->previewBoxLineWidth, previewBoxColor);
 }
 
 
@@ -732,22 +760,28 @@ void showPreviewBox(GtkWidget *bigPicture, const int x)
  * the preview box.  */
 void acceptAndClearPreviewBox(GtkWidget *bigPicture, const int xCentre, GdkRectangle *displayRect, GdkRectangle *highlightRect)
 {
-  IntRange *displayRange = bigPictureGetDisplayRange(bigPicture);
+  BlxViewContext *bc = bigPictureGetContext(bigPicture);
+  BigPictureProperties *bpProperties = bigPictureGetProperties(bigPicture);
+  
+  /* Get the display range in dna coords */
+  IntRange dnaDispRange;
+  convertDisplayRangeToDnaRange(&bpProperties->displayRange, bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dnaDispRange);
   
   /* Find the base index where the new scroll range will start. This is the leftmost
    * edge of the preview box if numbers increase in the normal left-to-right direction, 
    * or the rightmost edge if the display is reversed. */
-  int x = getLeftCoordFromCentre(xCentre, highlightRect->width, displayRect);
-  int baseIdx = convertWidgetPosToBaseIdx(x, displayRect, displayRange);
+  const int x = getLeftCoordFromCentre(xCentre, highlightRect->width, displayRect);
+  const int baseIdx = convertWidgetPosToBaseIdx(x, displayRect, &dnaDispRange, bc->displayRev);
   
   /* Clear the preview box */
   bigPictureSetPreviewBoxCentre(bigPicture, UNSET_INT);
   
   /* Update the detail view's scroll pos to start at the new base. The base index is in terms of
-   * the display coords, so the coord's sequence type is whatever the displayed sequence type is */
+   * the nucleotide coords so we need to convert to display coords */
+  const int displayIdx = convertDnaIdxToDisplayIdx(baseIdx, bc->seqType, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange, NULL);
+  
   GtkWidget *detailView = bigPictureGetDetailView(bigPicture);
-  const BlxSeqType seqType = detailViewGetSeqType(detailView);  /* displayed seq type */
-  setDetailViewStartIdx(detailView, baseIdx, seqType);
+  setDetailViewStartIdx(detailView, displayIdx, bc->seqType);
   
   gtk_widget_queue_draw(bigPicture);
 }
diff --git a/bigpicture.h b/bigpicture.h
index e3ccb5f808394b6e4d7d1097416ffa88883b31eb..45f6dac88d87193a8a4a4358f970ca74a7822a19 100644
--- a/bigpicture.h
+++ b/bigpicture.h
@@ -97,8 +97,6 @@ void			      refreshBigPictureDisplayRange(GtkWidget *bigPicture, const gboolean
 void			      calculateNumVCells(GtkWidget *bigPicture);
 void			      bigPictureRedrawAll(GtkWidget *bigPicture);
 
-gint                          convertWidgetPosToBaseIdx(const gint widgetPos, const GdkRectangle const *displayRect, const IntRange const *displayRange);
-
 void                          drawPreviewBox(GtkWidget *bigPicture, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *displayRect, GdkRectangle *highlightRect);
 void                          showPreviewBox(GtkWidget *bigPicture, const int x);
 void                          acceptAndClearPreviewBox(GtkWidget *bigPicture, const int xCentre, GdkRectangle *displayRect, GdkRectangle *highlightRect);
@@ -109,9 +107,11 @@ void			      zoomWholeBigPicture(GtkWidget *bigPicture);
 gdouble			      pixelsPerBase(const gint displayWidth, 
 					    const IntRange const *displayRange);
 
-gint			      convertBaseIdxToGridPos(const gint baseIdx, 
+gint			      convertBaseIdxToGridPos(const gint dnaIdx, 
 						      const GdkRectangle const *gridRect, 
-						      const IntRange const *displayRange);
+						      const IntRange const *dnaDispRange,
+                                                      const gboolean displayRev,
+                                                      const gboolean clip);
 
 int			      getLeftCoordFromCentre(const int centreCoord, 
 						     const int width, 
diff --git a/bigpicturegrid.c b/bigpicturegrid.c
index 8dc2bc0c0f6268df0c14ba638416fcce7bac0ced..3f1a7c80664bbfebf115686fc64ab381990cc7cc 100644
--- a/bigpicturegrid.c
+++ b/bigpicturegrid.c
@@ -15,6 +15,7 @@
 #include <SeqTools/utilities.h>
 #include <math.h>
 #include <string.h>
+#include <stdlib.h>
 
 
 #define BIG_PICTURE_MSP_LINE_NAME	"BigPictureMspLine"
@@ -107,11 +108,15 @@ static void drawVerticalGridLines(GtkWidget *grid,
   GridProperties *properties = gridGetProperties(grid);
   BigPictureProperties *bpProperties = bigPictureGetProperties(properties->bigPicture);
   
+    /* Get the display range in dna coords */
+  IntRange dnaDispRange;
+  convertDisplayRangeToDnaRange(&bpProperties->displayRange, bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dnaDispRange);
+
   const int direction = bc->displayRev ? -1 : 1; /* to subtract instead of add when display reversed */
   
   /* Get the first base index (in terms of the nucleotide coords) and round it to a nice round
    * number. We'll offset all of the gridlines by the distance between this and the real start coord. */
-  const int realFirstBaseIdx = convertDisplayIdxToDnaIdx(bpProperties->displayRange.min,bc-> seqType, 1, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange);
+  const int realFirstBaseIdx = convertDisplayIdxToDnaIdx(bpProperties->displayRange.min, bc->seqType, 1, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange);
   const int firstBaseIdx = roundToValue(realFirstBaseIdx, bpProperties->roundTo);
   
   /* Calculate the top and bottom heights for the lines. */
@@ -128,8 +133,7 @@ static void drawVerticalGridLines(GtkWidget *grid,
       int numBasesFromLeft = bpProperties->basesPerCell * hCell;
       int baseIdx = firstBaseIdx + (numBasesFromLeft * direction);
 
-      const int displayIdx = convertDnaIdxToDisplayIdx(baseIdx, bc->seqType, 1, bc->numFrames, bc->displayRev, &bc->refSeqRange, NULL);
-      const int x = convertBaseIdxToGridPos(displayIdx, &properties->gridRect, &bpProperties->displayRange);
+      const int x = convertBaseIdxToGridPos(baseIdx, &properties->gridRect, &dnaDispRange, bc->displayRev, TRUE);
 
       if (x > minX && x < maxX)
 	{
@@ -200,20 +204,15 @@ void calculateMspLineDimensions(GtkWidget *grid,
   BlxViewContext *bc = gridGetContext(grid);
   GridProperties *gridProperties = gridGetProperties(grid);
 
-  const IntRange const *displayRange = bigPictureGetDisplayRange(gridProperties->bigPicture);
-  const int frame = mspGetRefFrame(msp, bc->seqType);
+  /* Get the display range in dna coords */
+  IntRange dnaDispRange;
+  convertDisplayRangeToDnaRange(gridGetDisplayRange(grid), bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dnaDispRange);
 
-  /* Find the coordinates of the start and end base in this match sequence, and convert to display coords */
-  const int coord1 = convertDnaIdxToDisplayIdx(msp->qRange.min, bc->seqType, frame, bc->numFrames, bc->displayRev, &bc->refSeqRange, NULL);
-  const int coord2 = convertDnaIdxToDisplayIdx(msp->qRange.max, bc->seqType, frame, bc->numFrames, bc->displayRev, &bc->refSeqRange, NULL);
-  
-  /* Convert the coords to grid positions. The grid positions we use are for the left edge
-   * of the coord, so to draw the end coord inclusively we need to increase the max coord by 1 */
-  const int minCoord = min(coord1, coord2);
-  const int maxCoord = max(coord1, coord2) + 1;
+  const int x1 = convertBaseIdxToGridPos(msp->qRange.min, &gridProperties->gridRect, &dnaDispRange, bc->displayRev, TRUE);
+  const int x2 = convertBaseIdxToGridPos(msp->qRange.max, &gridProperties->gridRect, &dnaDispRange, bc->displayRev, TRUE);
   
-  int xMin = convertBaseIdxToGridPos(minCoord, &gridProperties->gridRect, displayRange);
-  int xMax = convertBaseIdxToGridPos(maxCoord, &gridProperties->gridRect, displayRange);
+  const int xMin = min(x1, x2);
+  const int xMax = max(x1, x2);
 
   if (x)
     {
@@ -420,14 +419,25 @@ void calculateHighlightBoxBorders(GtkWidget *grid)
   if (adjustment)
     {
       BigPictureProperties *bigPictureProperties = bigPictureGetProperties(properties->bigPicture);
+      BlxViewContext *bc = gridGetContext(grid);
 
-      IntRange *displayRange = gridGetDisplayRange(grid);
-      int firstBaseIdx = adjustment->value;
+      /* Get the grid display range in dna coords */
+      IntRange gridRange;
+      convertDisplayRangeToDnaRange(gridGetDisplayRange(grid), bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &gridRange);
 
-      properties->highlightRect.x = convertBaseIdxToGridPos(firstBaseIdx, &properties->gridRect, displayRange);
-      properties->highlightRect.y = 0; //properties->gridRect.y - bigPictureProperties->highlightBoxYPad;
+      /* Get the detail view display range in dna coords */
+      GtkWidget *detailView = gridGetDetailView(grid);
+      IntRange dvRange;
+      convertDisplayRangeToDnaRange(detailViewGetDisplayRange(detailView), bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dvRange);
+
+      /* Get the x coords for the start and end of the detail view display range */
+      const int x1 = convertBaseIdxToGridPos(dvRange.min, &properties->gridRect, &gridRange, bc->displayRev, TRUE);
+      const int x2 = convertBaseIdxToGridPos(dvRange.max, &properties->gridRect, &gridRange, bc->displayRev, TRUE);
+      
+      properties->highlightRect.x = min(x1, x2);
+      properties->highlightRect.y = 0;
       
-      properties->highlightRect.width = roundNearest((gdouble)adjustment->page_size * pixelsPerBase(properties->gridRect.width, displayRange));
+      properties->highlightRect.width = abs(x1 - x2);
       properties->highlightRect.height = properties->gridRect.height + (bigPictureProperties->charHeight / 2) + properties->mspLineHeight + (2 * bigPictureProperties->highlightBoxYPad);
     }
 }
diff --git a/exonview.c b/exonview.c
index d61e301b49ed92af88b46a7e39df3306213a226b..f3b90485999d2737261f6b4b42803fbf661c9c51 100644
--- a/exonview.c
+++ b/exonview.c
@@ -14,6 +14,7 @@
 #include <SeqTools/blxwindow.h>
 #include <SeqTools/utilities.h>
 #include <string.h>
+#include <stdlib.h>
 
 #define DEFAULT_EXON_HEIGHT			 10
 #define DEFAULT_EXON_HEIGHT_BUMPED		 7
@@ -31,6 +32,8 @@ typedef struct _ExonViewProperties
     
     GdkRectangle exonViewRect;	      /* The drawing area for the exon view */
     GdkRectangle highlightRect;       /* The area that the highlight box will cover (indicating the current detail-view display range) */
+    
+    int exonHeight;                   /* the height of an individual exon */ 
   } ExonViewProperties;
 
 
@@ -86,23 +89,36 @@ void callFuncOnAllBigPictureExonViews(GtkWidget *widget, gpointer data)
 
 
 /* Draw an exon */
-static void drawExon(const MSP const *msp, GdkDrawable *drawable, DrawData *data, const BlxSequence *blxSeq, const gboolean isSelected, int x, int y, int width, int height)
+static void drawExon(const MSP const *msp, 
+                     DrawData *data, 
+                     const BlxSequence *blxSeq, 
+                     const gboolean isSelected, 
+                     const int x, 
+                     const int y,
+                     const int width,
+                     const int height)
 {
   /* Draw the fill rectangle */
   const GdkColor *fillColor = mspGetColor(msp, data->bc->defaultColors, blxSeq, isSelected, data->bc->usePrintColors, TRUE);
   gdk_gc_set_foreground(data->gc, fillColor);
-  gdk_draw_rectangle(drawable, data->gc, TRUE, x, y, width, height);
+  gdk_draw_rectangle(data->drawable, data->gc, TRUE, x, y, width, height);
   
   /* Draw outline (exon box outline always the same (unselected) color; only intron lines change when selected) */
   const GdkColor *lineColor = mspGetColor(msp, data->bc->defaultColors, blxSeq, isSelected, data->bc->usePrintColors, FALSE);
   gdk_gc_set_foreground(data->gc, lineColor);
-  gdk_draw_rectangle(drawable, data->gc, FALSE, x, y, width, height);
-  
+  gdk_draw_rectangle(data->drawable, data->gc, FALSE, x, y, width, height);
 }
 
 
 /* Draw an intron */
-static void drawIntron(const MSP const *msp, GdkDrawable *drawable, DrawData *data, const BlxSequence *blxSeq, const gboolean isSelected, int x, int y, int width, int height)
+static void drawIntron(const MSP const *msp, 
+                       DrawData *data, 
+                       const BlxSequence *blxSeq, 
+                       const gboolean isSelected, 
+                       const int x, 
+                       const int y, 
+                       const int width, 
+                       const int height)
 {
   const GdkColor *lineColor = mspGetColor(msp, data->bc->defaultColors, blxSeq, isSelected, data->bc->usePrintColors, FALSE);
   gdk_gc_set_foreground(data->gc, lineColor);
@@ -110,9 +126,18 @@ static void drawIntron(const MSP const *msp, GdkDrawable *drawable, DrawData *da
   int xMid = x + roundNearest((double)width / 2.0);
   int xEnd = x + width;
   int yMid = y + roundNearest((double)height / 2.0);
+
+  /* Only draw the individual sections if they are in range. For some reason they get drawn in 
+   * the wrong place otherwise. */
+  if (xMid >= data->exonViewRect->x && x <= data->exonViewRect->x + data->exonViewRect->width)
+    {
+      gdk_draw_line(data->drawable, data->gc, x, yMid, xMid, y);
+    }
   
-  gdk_draw_line(drawable, data->gc, x, yMid, xMid, y);
-  gdk_draw_line(drawable, data->gc, xMid, y, xEnd, yMid);
+  if (xEnd >= data->exonViewRect->x && xMid <= data->exonViewRect->x + data->exonViewRect->width)
+    {
+      gdk_draw_line(data->drawable, data->gc, xMid, y, xEnd, yMid);
+    }
 }
 
 
@@ -131,26 +156,39 @@ static gboolean drawExonIntron(const MSP *msp, DrawData *data, const gboolean is
   IntRange mspDisplayRange;
   intrangeSetValues(&mspDisplayRange, coord1, coord2); /* sorts out which is min and max */
   
+  /* Include an extra coord either side because we draw slightly over the edges */
+  --mspDisplayRange.min;
+  ++mspDisplayRange.max;
+  
   if (rangesOverlap(&mspDisplayRange, data->displayRange))
     {
       drawn = TRUE;
 
-      /* The grid pos gives the left edge of the coord, so to be inclusive we draw to the max coord + 1 */
-      const int xMin = convertBaseIdxToGridPos(mspDisplayRange.min, data->exonViewRect, data->displayRange);
-      const int xMax = convertBaseIdxToGridPos(mspDisplayRange.max + 1, data->exonViewRect, data->displayRange);
+      /* Get the display range in dna coords */
+      IntRange dnaDispRange;
+      convertDisplayRangeToDnaRange(data->displayRange, data->bc->seqType, data->bc->numFrames, data->bc->displayRev, &data->bc->refSeqRange, &dnaDispRange);
+      
+      /* The grid pos gives the left edge of the coord, so to be inclusive we draw to the end coord + 1
+       * (or end - 1 if the end coord is the lower value) */
+      const int direction = (mspGetRefStrand(msp) == BLXSTRAND_FORWARD) ? 1 : -1;
+      const int qStart = mspGetQStart(msp);
+      const int qEnd = mspGetQEnd(msp) + direction;
       
-      int x = xMin;
-      int width = xMax - xMin;
+      const int x1 = convertBaseIdxToGridPos(qStart, data->exonViewRect, &dnaDispRange, data->bc->displayRev, FALSE);
+      const int x2 = convertBaseIdxToGridPos(qEnd, data->exonViewRect, &dnaDispRange, data->bc->displayRev, FALSE);
+      
+      int x = min(x1, x2);
+      int width = abs(x1 - x2);
       int y = data->y;
       int height = data->height;
       
       if (mspIsExon(msp))
 	{
-	  drawExon(msp, data->drawable, data, blxSeq, isSelected, x, y, width, height);
+	  drawExon(msp, data, blxSeq, isSelected, x, y, width, height);
 	}
       else if (mspIsIntron(msp))
 	{
-	  drawIntron(msp, data->drawable, data, blxSeq, isSelected, x, y, width, height);
+	  drawIntron(msp, data, blxSeq, isSelected, x, y, width, height);
 	}
     }
   
@@ -225,9 +263,14 @@ static void drawExonView(GtkWidget *exonView, GdkDrawable *drawable)
                    bigPictureProperties->highlightBoxMinWidth, 
                    highlightBoxColor);
 
+  /* Set a clip rectangle for drawing the exons and introns (because they are drawn "over the
+   * edges" to make sure intron lines have the correct slope etc.) */
+  GdkGC *gc = gdk_gc_new(drawable);
+  gdk_gc_set_clip_origin(gc, 0, 0);
+  gdk_gc_set_clip_rectangle(gc, &properties->exonViewRect);
+  
   /* Draw the exons and introns. Since we could have a lot of them in the loop, extract all the
    * info we need now and pass it around so we don't have to look for this stuff each time. */
-  GdkGC *gc = gdk_gc_new(drawable);
   
   DrawData drawData = {
     drawable,
@@ -245,7 +288,7 @@ static void drawExonView(GtkWidget *exonView, GdkDrawable *drawable)
     FALSE,
     properties->yPad,
     properties->exonViewRect.y,
-    properties->exonViewRect.height
+    properties->exonHeight
   };
   
   /* If the view is compressed (i.e. exons will overlap each other), then
@@ -324,32 +367,35 @@ void calculateExonViewHeight(GtkWidget *exonView)
 	}
     }
   
-  const int newHeight = (numExons * (properties->exonViewRect.height + properties->yPad)) + (2 * properties->yPad);
+  properties->exonViewRect.height = (numExons * (properties->exonHeight + properties->yPad)) + (2 * properties->yPad);
   
-  gtk_widget_set_size_request(exonView, -1, newHeight);
+  gtk_widget_set_size_request(exonView, -1, properties->exonViewRect.height);
 }
 
 
 void calculateExonViewHighlightBoxBorders(GtkWidget *exonView)
 {
   ExonViewProperties *properties = exonViewGetProperties(exonView);
+  BlxViewContext *bc = bigPictureGetContext(properties->bigPicture);
   
-  /* Calculate how many pixels from the left edge of the widget to the first base in the range. Truncating
-   * the double to an int after the multiplication means we can be up to 1 pixel out, but this should be fine. */
+  /* Get the big picture display range in dna coords */
+  IntRange bpRange;
+  convertDisplayRangeToDnaRange(bigPictureGetDisplayRange(properties->bigPicture), bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &bpRange);
+
+  /* Get the detail view display range in dna coords */
+  IntRange dvRange;
   GtkWidget *detailView = bigPictureGetDetailView(properties->bigPicture);
-  GtkAdjustment *adjustment = detailViewGetAdjustment(detailView);
+  convertDisplayRangeToDnaRange(detailViewGetDisplayRange(detailView), bc->seqType, bc->numFrames, bc->displayRev, &bc->refSeqRange, &dvRange);
   
-  if (adjustment)
-    {
-      IntRange *displayRange = bigPictureGetDisplayRange(properties->bigPicture);
-      int firstBaseIdx = adjustment->value;
-      
-      properties->highlightRect.x = convertBaseIdxToGridPos(firstBaseIdx, &properties->exonViewRect, displayRange);
-      properties->highlightRect.y = 0; //properties->exonViewRect.y - bigPictureProperties->highlightBoxYPad;
-      
-      properties->highlightRect.width = roundNearest((gdouble)adjustment->page_size * pixelsPerBase(properties->exonViewRect.width, displayRange));
-      properties->highlightRect.height = exonView->allocation.height; //properties->exonViewRect.height + (2 * bigPictureProperties->highlightBoxYPad);
-    }
+  /* Calculate how many pixels from the left edge of the widget to the first base in the range. */
+  const int x1 = convertBaseIdxToGridPos(dvRange.min, &properties->exonViewRect, &bpRange, bc->displayRev, TRUE);
+  const int x2 = convertBaseIdxToGridPos(dvRange.max, &properties->exonViewRect, &bpRange, bc->displayRev, TRUE);
+  
+  properties->highlightRect.x = min(x1, x2);
+  properties->highlightRect.y = 0;
+  
+  properties->highlightRect.width = abs(x1 - x2);
+  properties->highlightRect.height = exonView->allocation.height;
 }
 
 
@@ -404,6 +450,8 @@ static void exonViewCreateProperties(GtkWidget *exonView,
       properties->exonViewRect.y      = DEFAULT_EXON_YPAD;
       properties->exonViewRect.width  = 0;
       properties->exonViewRect.height = DEFAULT_EXON_HEIGHT;
+
+      properties->exonHeight          = DEFAULT_EXON_HEIGHT;
       
       gtk_widget_set_size_request(exonView, 0, DEFAULT_EXON_HEIGHT + (2 * DEFAULT_EXON_YPAD));
 
@@ -439,12 +487,12 @@ void exonViewSetExpanded(GtkWidget *exonView, const gboolean expanded)
   if (expanded)
     {
       properties->yPad = DEFAULT_EXON_YPAD_BUMPED;
-      properties->exonViewRect.height = DEFAULT_EXON_HEIGHT_BUMPED;
+      properties->exonHeight = DEFAULT_EXON_HEIGHT_BUMPED;
     }
   else 
     {
       properties->yPad = DEFAULT_EXON_YPAD;
-      properties->exonViewRect.height = DEFAULT_EXON_HEIGHT;
+      properties->exonHeight = DEFAULT_EXON_HEIGHT;
     }
   
   calculateExonViewHeight(exonView);
diff --git a/utilities.c b/utilities.c
index dbf35c41cfbad90773fb7df21dcbe42afa8477d6..cd33c0d56e22225aa58b0a24bb2de2dc190d6ebb 100644
--- a/utilities.c
+++ b/utilities.c
@@ -741,6 +741,20 @@ char getRefSeqBase(char *refSeq,
 }
 
 
+/* Convert the given range of display coords to dna coords */
+void convertDisplayRangeToDnaRange(const IntRange const * displayRange, 
+                                   const BlxSeqType displaySeqType,
+                                   const int numFrames,
+                                   const gboolean displayRev,
+                                   const IntRange const *refSeqRange,
+                                   IntRange *result)
+{
+  const int q1 = convertDisplayIdxToDnaIdx(displayRange->min, displaySeqType, 1, 1, numFrames, displayRev, refSeqRange); /* 1st base in 1st reading frame */
+  const int q2 = convertDisplayIdxToDnaIdx(displayRange->max, displaySeqType, numFrames, numFrames, numFrames, displayRev, refSeqRange); /* last base in last frame */
+  intrangeSetValues(result, q1, q2);
+}
+
+
 /* Given an index into the displayed sequence, a reading frame, and the base number within that
  * reading frame, return the index into the DNA sequence that will give the equivalent DNA base.
  * If the display sequence is a peptide sequence, it will convert the coord to a DNA coord. If the
diff --git a/utilities.h b/utilities.h
index 529af30c0e29832e14af9d4a44070a567a917e54..249eefd38d2dacd14cf90ce9a51fa30170cf910e 100644
--- a/utilities.h
+++ b/utilities.h
@@ -190,6 +190,13 @@ void		      boundsLimitValue(int *value, const IntRange const *range);
 void                  boundsLimitRange(IntRange *range, const IntRange const *limit, const gboolean maintainLen);
 char		      convertBaseToCorrectCase(const char charToConvert, const BlxSeqType seqType);
 
+void                  convertDisplayRangeToDnaRange(const IntRange const * displayRange, 
+                                                    const BlxSeqType displaySeqType,
+                                                    const int numFrames,
+                                                    const gboolean displayRev,
+                                                    const IntRange const *refSeqRange,
+                                                    IntRange *result);
+
 int		      convertDisplayIdxToDnaIdx(const int inputIdx, 
 						const BlxSeqType inputIdxType,
 						const int frame,