diff --git a/gerbview/block.cpp b/gerbview/block.cpp
index 477264f58f..bff0cc2ac3 100644
--- a/gerbview/block.cpp
+++ b/gerbview/block.cpp
@@ -45,9 +45,6 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel,
                                      wxDC*             DC,
                                      bool              erase );
 
-static bool IsGbrItemInBox( BLOCK_SELECTOR& aBlocklocate, GERBER_DRAW_ITEM* aItem );
-
-
 /* Return the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
  *  the key (ALT, SHIFT ALT ..)
  */
@@ -292,7 +289,7 @@ void WinEDA_GerberFrame::Block_Delete( wxDC* DC )
     {
         nextitem = item->Next();
         GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
-        if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
+        if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
             gerb_item->DeleteStructure();
     }
 
@@ -324,7 +321,7 @@ void WinEDA_GerberFrame::Block_Move( wxDC* DC )
     for( ; item; item = item->Next() )
     {
         GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
-        if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
+        if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
             gerb_item->Move( delta );
     }
 
@@ -355,7 +352,7 @@ void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
     for( ; item; item = item->Next() )
     {
         GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
-        if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
+        if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
         {
             /* this item must be duplicated */
             BOARD_ITEM* new_item = gerb_item->Copy();
@@ -367,17 +364,3 @@ void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
     DrawPanel->Refresh();
 }
 
-
-/* Test if the structure PtStruct is inside the block
- * Returns true or false
- */
-bool IsGbrItemInBox( BLOCK_SELECTOR& aBlocklocate, GERBER_DRAW_ITEM* aItem )
-{
-    if( aBlocklocate.Inside( aItem->m_Start ) )
-        return true;
-
-    if( aBlocklocate.Inside( aItem->m_End ) )
-        return true;
-
-    return false;
-}
diff --git a/gerbview/class_GERBER.cpp b/gerbview/class_GERBER.cpp
index f90f23c414..29006a3774 100644
--- a/gerbview/class_GERBER.cpp
+++ b/gerbview/class_GERBER.cpp
@@ -127,18 +127,19 @@ void GERBER::ResetDefaultValues()
     m_Relative = false;                             // false = absolute Coord,
                                                     // true = relative Coord
     m_NoTrailingZeros = false;                      // true: trailing zeros deleted
-    m_MirrorA    = false;                           // true: miror / axe A (default = X)
-    m_MirrorB    = false;                           // true: miror / axe B (default = Y)
-    m_SwapAxis  = false;                            // false if A = X, B = Y; true if A =Y, B = Y
+    m_MirrorA  = false;                             // true: miror / axe A (default = X)
+    m_MirrorB  = false;                             // true: miror / axe B (default = Y)
+    m_SwapAxis = false;                             // false if A = X, B = Y; true if A =Y, B = Y
+    m_ImageOffset.x = m_ImageOffset.y = 0;          // Coord Offset, from IO command
+    m_Offset.x  = m_Offset.y = 0;                   // Coord Offset, from OF command
+    m_Rotation  = 0;                                // Allowed 0, 90, 180, 270
     m_Has_DCode = false;                            // true = DCodes in file
                                                     // false = no DCode->
                                                     // search for separate DCode file
-
     m_FmtScale.x = m_FmtScale.y = 4;                // Initialize default format to 3.4 => 4
-    m_FmtLen.x   = m_FmtLen.y = 3+4;                // Initialize default format len = 3+4
+    m_FmtLen.x   = m_FmtLen.y = 3 + 4;              // Initialize default format len = 3+4
 
     m_LayerScale.x = m_LayerScale.y = 1.0;          // scale (A and B) this layer
-    m_Rotation     = 0;                             // Allowed 0, 90, 180, 270
     m_Iterpolation = GERB_INTERPOL_LINEAR_1X;       // Linear, 90 arc, Circ.
     m_360Arc_enbl  = false;                         // 360 deg circular
                                                     // interpolation disable
diff --git a/gerbview/class_GERBER.h b/gerbview/class_GERBER.h
index 44e8bbee2a..4df560fea3 100644
--- a/gerbview/class_GERBER.h
+++ b/gerbview/class_GERBER.h
@@ -47,7 +47,8 @@ public:
     wxSize             m_FmtScale;                                      // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
     wxSize             m_FmtLen;                                        // Nb chars per coord. ex fmt 2.3, m_FmtLen = 5
     wxRealPoint        m_LayerScale;                                    // scale (X and Y) of layer.
-    int                m_Rotation;
+    int                m_Rotation;                                      // Image rotation (0, 90, 180, 270
+                                                                        // Note these values are stored in 0.1 degrees
     int                m_Iterpolation;                                  // Linear, 90 arc, Circ.
     bool               m_ImageNegative;                                 // true = Negative image
     int                m_Current_Tool;                                  // Current Tool (Dcode) number selected
diff --git a/gerbview/class_aperture_macro.cpp b/gerbview/class_aperture_macro.cpp
index 256038d7e2..68ef9dc6a9 100644
--- a/gerbview/class_aperture_macro.cpp
+++ b/gerbview/class_aperture_macro.cpp
@@ -147,6 +147,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
          * type is not stored in parameters list, so the first parameter is exposure
          */
         curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric );
+        curPos = aParent->GetABPosition( curPos );
         int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2;
         if( !aFilledShape )
             GRCircle( aClipBox, aDC, curPos, radius, 0, aColor );
@@ -170,12 +171,15 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         if( rotation )
         {
             for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
-                RotatePoint( &polybuffer[ii], rotation );
+                RotatePoint( &polybuffer[ii], -rotation );
         }
 
         // Move to current position:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+        {
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+        }
 
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -196,12 +200,15 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         if( rotation )
         {
             for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
-                RotatePoint( &polybuffer[ii], rotation );
+                RotatePoint( &polybuffer[ii], -rotation );
         }
 
         // Move to current position:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+        {
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+        }
 
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -222,12 +229,15 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         if( rotation )
         {
             for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
-                RotatePoint( &polybuffer[ii], rotation );
+                RotatePoint( &polybuffer[ii], -rotation );
         }
 
         // Move to current position:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+        {
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+        }
 
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -255,11 +265,14 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
             subshape_poly = polybuffer;
             int sub_rotation = rotation + 900 * ii;
             for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
-                RotatePoint( &subshape_poly[jj], sub_rotation );
+                RotatePoint( &subshape_poly[jj], -sub_rotation );
 
             // Move to current position:
             for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
+            {
                 subshape_poly[jj] += curPos;
+                subshape_poly[jj] = aParent->GetABPosition( subshape_poly[jj] );
+            }
 
             GRClosedPoly( aClipBox, aDC,
                           subshape_poly.size(), &subshape_poly[0], true, aAltColor,
@@ -283,6 +296,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         int gap = scale( params[4].GetValue( tool ), gerberMetric );
         int numCircles = wxRound( params[5].GetValue( tool ) );
 
+        // Draw circles:
+        wxPoint center = aParent->GetABPosition( curPos );
         // adjust outerDiam by this on each nested circle
         int diamAdjust = (gap + penThickness); //*2;     //Should we use * 2 ?
         for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
@@ -292,12 +307,12 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
             if( !aFilledShape )
             {
                 // draw the border of the pen's path using two circles, each as narrow as possible
-                GRCircle( aClipBox, aDC, curPos, outerDiam / 2, 0, aColor );
-                GRCircle( aClipBox, aDC, curPos, outerDiam / 2 - penThickness, 0, aColor );
+                GRCircle( aClipBox, aDC, center, outerDiam / 2, 0, aColor );
+                GRCircle( aClipBox, aDC, center, outerDiam / 2 - penThickness, 0, aColor );
             }
             else    // Filled mode
             {
-                GRCircle( aClipBox, aDC, curPos,
+                GRCircle( aClipBox, aDC, center,
                           (outerDiam - penThickness) / 2, penThickness, aColor );
             }
         }
@@ -305,17 +320,15 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         // Draw the cross:
         ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
 
-        // shape rotation:
         rotation = wxRound( params[8].GetValue( tool ) * 10.0 );
-        if( rotation )
-        {
-            for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
-                RotatePoint( &polybuffer[ii], rotation );
-        }
-
-        // Move to current position:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+        {
+            // shape rotation:
+            RotatePoint( &polybuffer[ii], -rotation );
+            // Move to current position:
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+        }
 
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -344,13 +357,15 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         // shape rotation:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
         {
-            NEGATE(polybuffer[ii].y);
-            RotatePoint( &polybuffer[ii], rotation );
+            RotatePoint( &polybuffer[ii], -rotation );
        }
 
         // Move to current position:
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+        {
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+        }
 
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -372,9 +387,9 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         rotation  = wxRound( params[5].GetValue( tool ) * 10.0 );
         for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
         {
-            NEGATE(polybuffer[ii].y);
-            RotatePoint( &polybuffer[ii], rotation );
+            RotatePoint( &polybuffer[ii], -rotation );
             polybuffer[ii] += curPos;
+            polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
         }
         GRClosedPoly( aClipBox, aDC,
                       polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
@@ -441,7 +456,6 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM*     aParent,
         {
             RotatePoint( &aBuffer[ii], -angle );
             aBuffer[ii] += start;
-            NEGATE( aBuffer[ii].y );
         }
     }
     break;
@@ -471,7 +485,6 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM*     aParent,
                                        tool ), aUnitsMetric );
 
         // Build poly:
-        NEGATE( lowerLeft.y );
         aBuffer.push_back( lowerLeft );
         lowerLeft.y += size.y;          // Upper left
         aBuffer.push_back( lowerLeft );
@@ -479,10 +492,6 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM*     aParent,
         aBuffer.push_back( lowerLeft );
         lowerLeft.y -= size.y;          // lower right
         aBuffer.push_back( lowerLeft );
-
-        // Negate y coordinates:
-        for( unsigned ii = 0; ii < aBuffer.size(); ii++ )
-            NEGATE( aBuffer[ii].y );
     }
     break;
 
diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp
index 0f543fc607..6e5da6bb69 100644
--- a/gerbview/class_gerber_draw_item.cpp
+++ b/gerbview/class_gerber_draw_item.cpp
@@ -112,11 +112,13 @@ GERBER_DRAW_ITEM* GERBER_DRAW_ITEM::Copy() const
  * offsets, axis selection, scale, rotation
  * @param aXYPosition = position in Y,X gerber axis
  * @return const wxPoint& - The position in A,B axis.
+ * Because draw axis is top to bottom, the final y coordinates is negated
  */
-wxPoint GERBER_DRAW_ITEM::GetABPosition( wxPoint& aXYPosition )
+wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition )
 {
     /* Note: RS274Xrevd_e is obscure about the order of transforms:
      * For instance: Rotation must be made after or before mirroring ?
+     * Note: if something is changed here, GetYXPosition must reflect changes
      */
     wxPoint abPos = aXYPosition;
 
@@ -126,14 +128,41 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( wxPoint& aXYPosition )
     abPos.x = wxRound( abPos.x * m_drawScale.x );
     abPos.y = wxRound( abPos.y * m_drawScale.y );
     if( m_imageParams->m_Rotation )
-        RotatePoint( &abPos, m_imageParams->m_Rotation );
+        RotatePoint( &abPos, -m_imageParams->m_Rotation );
     if( m_mirrorA )
         NEGATE( abPos.x );
-    if( m_mirrorB )
+    // abPos.y must be negated, because draw axis is top to bottom
+    if( !m_mirrorB )
         NEGATE( abPos.y );
     return abPos;
 }
 
+/**
+ * Function GetXYPosition
+ * returns the image position of aPosition for this object.
+ * Image position is the value of aPosition, modified by image parameters:
+ * offsets, axis selection, scale, rotation
+ * @param aABPosition = position in A,B plotter axis
+ * @return const wxPoint - The given position in X,Y axis.
+ */
+wxPoint GERBER_DRAW_ITEM::GetXYPosition(const wxPoint& aABPosition )
+{
+    // do the inverse tranform made by GetABPosition
+   wxPoint xyPos = aABPosition;
+
+    if( m_mirrorA )
+        NEGATE( xyPos.x );
+    if( !m_mirrorB )
+        NEGATE( xyPos.y );
+    if( m_imageParams->m_Rotation )
+        RotatePoint( &xyPos, m_imageParams->m_Rotation );
+    xyPos.x = wxRound( xyPos.x / m_drawScale.x );
+    xyPos.y = wxRound( xyPos.y / m_drawScale.y );
+    xyPos  -= m_layerOffset + m_imageParams->m_ImageOffset;
+    if( m_swapAxis )
+        EXCHG( xyPos.x, xyPos.y );
+    return xyPos;
+}
 
 /** function SetLayerParameters
  * Initialize draw parameters from Image and Layer parameters
@@ -216,6 +245,9 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
     EDA_Rect bbox( m_Start, wxSize( 1, 1 ) );
 
     bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
+
+    bbox.SetOrigin(GetXYPosition( bbox.GetOrigin() ) );
+    bbox.SetEnd(GetXYPosition( bbox.GetEnd() ) );
     return bbox;
 }
 
@@ -223,15 +255,16 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
 /**
  * Function Move
  * move this object.
- * @param const wxPoint& aMoveVector - the move vector for this object.
+ * @param const wxPoint& aMoveVector - the move vector for this object, in AB plotter axis.
  */
 void GERBER_DRAW_ITEM::Move( const wxPoint& aMoveVector )
 {
-    m_Start     += aMoveVector;
-    m_End       += aMoveVector;
-    m_ArcCentre += aMoveVector;
+    wxPoint xymove = GetXYPosition( aMoveVector );
+    m_Start     += xymove;
+    m_End       += xymove;
+    m_ArcCentre += xymove;
     for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
-        m_PolyCorners[ii] += aMoveVector;
+        m_PolyCorners[ii] += xymove;
 }
 
 
@@ -376,20 +409,17 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect*      aClipBox,
     std::vector<wxPoint> points;
 
     points = m_PolyCorners;
-    if( aOffset != wxPoint( 0, 0 ) )
+    for( unsigned ii = 0; ii < points.size(); ii++ )
     {
-        for( unsigned ii = 0; ii < points.size(); ii++ )
-        {
-            points[ii] += aOffset;
-            points[ii]  = GetABPosition( points[ii] );
-        }
+        points[ii] += aOffset;
+        points[ii]  = GetABPosition( points[ii] );
     }
 
     GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilledShape, aColor, aColor );
 }
 
 
-/** Function DisplayInfoBase
+/** Function DisplayInfo
  * has knowledge about the frame and how and where to put status information
  * about this object into the frame's message panel.
  * Display info about the track segment only, and does not calculate the full track length
@@ -398,28 +428,59 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect*      aClipBox,
 void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
 {
     wxString msg;
-    BOARD*   board = ( (WinEDA_BasePcbFrame*) frame )->GetBoard();
 
     frame->ClearMsgPanel();
-
     msg = ShowGBRShape();
     frame->AppendMsgPanel( _( "Type" ), msg, DARKCYAN );
 
-    /* Display layer */
-    msg = board->GetLayerName( m_Layer );
-    frame->AppendMsgPanel( _( "Layer" ), msg, BROWN );
+    // Display D_Code value:
+    msg.Printf( wxT("%d"), m_DCode);
+    frame->AppendMsgPanel( _( "D Code" ), msg, RED );
+
+    // Display Image name
+    if(m_imageParams)
+    {
+        msg = m_imageParams->m_ImageName;
+        frame->AppendMsgPanel( _( "Image name" ), msg, BROWN );
+    }
+
+    // Display graphic layer number
+    msg.Printf( wxT("%d"), GetLayer()+1);
+    frame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
+
+    // This next info can be see as debug info, so it can be disabled
+#if 1
+    // Display offset
+    wxPoint tmp = m_layerOffset + m_imageParams->m_ImageOffset;
+    msg.Printf( wxT("X=%f Y=%f"), (double)tmp.x/10000, (double)tmp.y/10000);
+    frame->AppendMsgPanel( _( "Offset" ), msg, DARKRED );
+
+    // Display rotation
+    msg.Printf( wxT("%d"), m_imageParams->m_Rotation/10);
+    frame->AppendMsgPanel( _( "Image rotation" ), msg, DARKRED );
+
+    // Display mirroring
+    msg.Printf( wxT("X%d Y%d"), m_mirrorA, m_mirrorB);
+    frame->AppendMsgPanel( _( "Mirror" ), msg, DARKRED );
+
+    // Display AB axis swap
+    msg = m_swapAxis ? wxT("A=Y B=X") : wxT("A=X B=Y");
+    frame->AppendMsgPanel( _( "AB axis" ), msg, DARKRED );
+#endif
 }
 
 
 /**
  * Function HitTest
  * tests if the given wxPoint is within the bounds of this object.
- * @param ref_pos A wxPoint to test
+ * @param aRefPos A wxPoint to test in AB axis
  * @return bool - true if a hit, else false
  */
-bool GERBER_DRAW_ITEM::HitTest( const wxPoint& ref_pos )
+bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos )
 {
-    // TODO: a better analyse od the shape (perhaps create a D_CODE::HitTest for flashed items)
+    wxPoint ref_pos = GetXYPosition( aRefPos );
+
+    // TODO: a better analyse of the shape (perhaps create a D_CODE::HitTest for flashed items)
     int     radius = MIN( m_Size.x, m_Size.y ) >> 1;
 
     // delta is a vector from m_Start to m_End (an origin of m_Start)
@@ -447,14 +508,16 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& ref_pos )
  * Function HitTest (overlayed)
  * tests if the given EDA_Rect intersect this object.
  * For now, an ending point must be inside this rect.
- * @param refArea : the given EDA_Rect
+ * @param refArea : the given EDA_Rect in AB plotter axis
  * @return bool - true if a hit, else false
  */
 bool GERBER_DRAW_ITEM::HitTest( EDA_Rect& refArea )
 {
-    if( refArea.Inside( m_Start ) )
+    wxPoint pos = GetABPosition( m_Start );
+    if( refArea.Inside( pos ) )
         return true;
-    if( refArea.Inside( m_End ) )
+    pos = GetABPosition( m_End );
+    if( refArea.Inside( pos ) )
         return true;
     return false;
 }
diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h
index d061f5db4f..a8c8b9b8c3 100644
--- a/gerbview/class_gerber_draw_item.h
+++ b/gerbview/class_gerber_draw_item.h
@@ -81,7 +81,7 @@ public:
     bool        m_ImageNegative;            // true = item in negative image
     bool        m_LayerNegative;            // TRUE = item in negative Layer
 private:
-    GERBER* m_imageParams;                 /* main GERBER info for this item
+    GERBER* m_imageParams;                  /* main GERBER info for this item
                                              * Note: some params stored in this class are common
                                              * to the whole gerber file (i.e) the whole graphic layer
                                              * and some can change when reaging the file, so they
@@ -148,10 +148,20 @@ public:
      * returns the image position of aPosition for this object.
      * Image position is the value of aPosition, modified by image parameters:
      * offsets, axis selection, scale, rotation
-     * @param aXYPosition = position in Y,X gerber axis
-     * @return const wxPoint - The given position in A,B axis.
+     * @param aXYPosition = position in X,Y gerber axis
+     * @return const wxPoint - The given position in plotter A,B axis.
      */
-    wxPoint GetABPosition(wxPoint& aXYPosition );
+    wxPoint GetABPosition(const wxPoint& aXYPosition );
+
+    /**
+     * Function GetXYPosition
+     * returns the image position of aPosition for this object.
+     * Image position is the value of aPosition, modified by image parameters:
+     * offsets, axis selection, scale, rotation
+     * @param aABPosition = position in A,B plotter axis
+     * @return const wxPoint - The given position in X,Y axis.
+     */
+    wxPoint GetXYPosition(const wxPoint& aABPosition );
 
     /**
      * Function GetDcodeDescr
@@ -193,19 +203,19 @@ public:
     /**
      * Function HitTest
      * tests if the given wxPoint is within the bounds of this object.
-     * @param refPos A wxPoint to test
+     * @param aRefPos A wxPoint to test
      * @return bool - true if a hit, else false
      */
-    bool     HitTest( const wxPoint& refPos );
+    bool     HitTest( const wxPoint& aRefPos );
 
     /**
      * Function HitTest (overlayed)
      * tests if the given wxRect intersect this object.
      * For now, an ending point must be inside this rect.
-     * @param refPos A wxPoint to test
+     * @param aRefPos A wxPoint to test
      * @return bool - true if a hit, else false
      */
-    bool     HitTest( EDA_Rect& refArea );
+    bool     HitTest( EDA_Rect& aRefArea );
 
     /**
      * Function GetClass
diff --git a/gerbview/controle.cpp b/gerbview/controle.cpp
index f8368e8693..919e67f0dc 100644
--- a/gerbview/controle.cpp
+++ b/gerbview/controle.cpp
@@ -5,11 +5,9 @@
 #include "fctsys.h"
 #include "common.h"
 #include "class_drawpanel.h"
-
-#include "pcbnew.h"
 #include "gerbview.h"
 
-BOARD_ITEM* WinEDA_GerberFrame::GerberGeneralLocateAndDisplay()
+GERBER_DRAW_ITEM* WinEDA_GerberFrame::GerberGeneralLocateAndDisplay()
 {
     return Locate( CURSEUR_OFF_GRILLE );
 }
diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp
index 575989f575..54e56b5738 100644
--- a/gerbview/dcode.cpp
+++ b/gerbview/dcode.cpp
@@ -310,20 +310,23 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
     case APT_CIRCLE:
         radius = m_Size.x >> 1;
         if( !aFilledShape )
-            GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor );
+            GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
+                      radius, 0, aColor );
         else
             if( m_DrillShape == APT_DEF_NO_HOLE )
-                GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor );
+                GRFilledCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
+                                radius, aColor );
             else if( APT_DEF_ROUND_HOLE == 1 )    // round hole in shape
             {
                 int width = (m_Size.x - m_Drill.x ) / 2;
-                GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor );
+                GRCircle( aClipBox, aDC,  aParent->GetABPosition(aShapePos),
+                          radius - (width / 2), width, aColor );
             }
             else                            // rectangular hole
             {
                 if( m_PolyCorners.size() == 0 )
                     ConvertShapeToPolygon();
-                DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
+                DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
             }
         break;
 
@@ -338,6 +341,8 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
         start.x = aShapePos.x - m_Size.x / 2;
         start.y = aShapePos.y - m_Size.y / 2;
         wxPoint end = start + m_Size;
+        start = aParent->GetABPosition( start );
+        end = aParent->GetABPosition( end );
         if( !aFilledShape )
         {
             GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
@@ -352,7 +357,7 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
         {
             if( m_PolyCorners.size() == 0 )
                 ConvertShapeToPolygon();
-            DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
+            DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
         }
     }
     break;
@@ -375,6 +380,8 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
             end.y   += delta;
             radius   = m_Size.x;
         }
+        start = aParent->GetABPosition( start );
+        end = aParent->GetABPosition( end );
         if( !aFilledShape )
         {
             GRCSegm( aClipBox, aDC, start.x, start.y,
@@ -389,7 +396,7 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
         {
             if( m_PolyCorners.size() == 0 )
                 ConvertShapeToPolygon();
-            DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
+            DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
         }
     }
     break;
@@ -397,7 +404,7 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
     case APT_POLYGON:
         if( m_PolyCorners.size() == 0 )
             ConvertShapeToPolygon();
-        DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
+        DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
         break;
     }
 }
@@ -409,7 +416,8 @@ void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
  * APT_POLYGON is always a polygon, but some complex shapes are also converted to
  * polygons (shapes with holes)
  */
-void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
+void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
+                                 EDA_Rect* aClipBox, wxDC* aDC,
                                  int aColor, bool aFilled,
                                  const wxPoint& aPosition )
 {
@@ -421,6 +429,7 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
     for( unsigned ii = 0; ii < points.size(); ii++ )
     {
         points[ii] += aPosition;
+        points[ii] = aParent->GetABPosition( points[ii] );
     }
 
     GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilled, aColor, aColor );
@@ -557,9 +566,7 @@ void D_CODE::ConvertShapeToPolygon()
             int angle = wxRound( m_Rotation * 10 );
             for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
             {
-                // Remember the Y axis is from top to bottom when draw items.
                 RotatePoint( &m_PolyCorners[jj], -angle );
-                NEGATE( m_PolyCorners[jj].y );
             }
         }
         break;
diff --git a/gerbview/dcode.h b/gerbview/dcode.h
index cecd409511..1839cd5609 100644
--- a/gerbview/dcode.h
+++ b/gerbview/dcode.h
@@ -193,6 +193,7 @@ public:
     /** function DrawFlashedShape
      * Draw the dcode shape for flashed items.
      * When an item is flashed, the DCode shape is the shape of the item
+     * @param aParent = the GERBER_DRAW_ITEM being drawn
      * @param aClipBox = DC clip box (NULL is no clip)
      * @param aDC = device context
      * @param aColor = the normal color to use
@@ -209,13 +210,15 @@ public:
      * Draw some Apertures shapes when they are defined as filled polygons.
      * APT_POLYGON is always a polygon, but some complex shapes are also converted to
      * polygons (shapes with holes, some rotated shapes)
+     * @param aParent = the GERBER_DRAW_ITEM being drawn
      * @param aClipBox = DC clip box (NULL is no clip)
      * @param aDC = device context
      * @param aColor = the normal color to use
      * @param aFilled = true to draw in filled mode, false to draw in skecth mode
      * @param aPosition = the actual shape position
     */
-    void                 DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
+    void                 DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
+                                             EDA_Rect* aClipBox, wxDC* aDC, int aColor,
                                              bool aFilled, const wxPoint& aPosition );
 
     /** function ConvertShapeToPolygon
diff --git a/gerbview/dialog_print_using_printer.cpp b/gerbview/dialog_print_using_printer.cpp
index b8702471ef..97a923cd6d 100644
--- a/gerbview/dialog_print_using_printer.cpp
+++ b/gerbview/dialog_print_using_printer.cpp
@@ -16,7 +16,6 @@
 
 #include "gerbview.h"
 #include "wxGerberFrame.h"
-#include "pcbnew.h"
 #include "wxPcbStruct.h"
 #include "pcbplot.h"
 #include "class_board_design_settings.h"
diff --git a/gerbview/edit.cpp b/gerbview/edit.cpp
index d22dd16b29..97ea787322 100644
--- a/gerbview/edit.cpp
+++ b/gerbview/edit.cpp
@@ -26,7 +26,7 @@ void WinEDA_GerberFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
 
     if( m_ID_current_state == 0 )
     {
-        if( DrawStruct && DrawStruct->m_Flags )
+        if( DrawStruct && (DrawStruct->m_Flags & ~DRAW_ERASED) )
         {
             msg.Printf( wxT( "WinEDA_GerberFrame::ProcessCommand err: Struct %d, m_Flags = %X" ),
                         (unsigned) DrawStruct->Type(),
@@ -228,7 +228,7 @@ void WinEDA_GerberFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
     switch( m_ID_current_state )
     {
     case 0:
-        if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) )
+        if( (DrawStruct == NULL) || ((DrawStruct->m_Flags & ~DRAW_ERASED) == 0) )
         {
             DrawStruct = GerberGeneralLocateAndDisplay();
         }
diff --git a/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr b/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr
index cadd73c758..774d97a46c 100644
--- a/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr
+++ b/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr
@@ -44,7 +44,7 @@ G90*
 %ADD14LINE2,0.8X0.5*%
 %ADD15OUTLINE*%
 %ADD16POLYGON,3X-10*%
-%ADD17POLYGON,6X0*%
+%ADD17POLYGON,6X10*%
 %ADD18MOIRE*%
 %ADD19THERMAL*%
 %ADD20LINELOWLEFT*%
diff --git a/gerbview/gerbview.h b/gerbview/gerbview.h
index e9bf28f703..5ffa24523a 100644
--- a/gerbview/gerbview.h
+++ b/gerbview/gerbview.h
@@ -12,6 +12,9 @@
 #include "class_gerber_draw_item.h"
 #include "class_aperture_macro.h"
 
+#define CURSEUR_ON_GRILLE  0
+#define CURSEUR_OFF_GRILLE 1
+
 class WinEDA_GerberFrame;
 //class BOARD;
 
diff --git a/gerbview/initpcb.cpp b/gerbview/initpcb.cpp
index 7817fb03d6..c74f9a53f0 100644
--- a/gerbview/initpcb.cpp
+++ b/gerbview/initpcb.cpp
@@ -46,6 +46,7 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
     GetScreen()->Init();
     setActiveLayer(LAYER_N_BACK);
 
+    SetCurItem( NULL );
     return TRUE;
 }
 
@@ -59,6 +60,8 @@ void WinEDA_GerberFrame::Erase_Current_Layer( bool query )
     if( query && !IsOK( this, msg ) )
         return;
 
+    SetCurItem( NULL );
+
     BOARD_ITEM* item = GetBoard()->m_Drawings;
     BOARD_ITEM * next;
     for( ; item; item = next )
diff --git a/gerbview/locate.cpp b/gerbview/locate.cpp
index e891096771..597577595b 100644
--- a/gerbview/locate.cpp
+++ b/gerbview/locate.cpp
@@ -4,20 +4,56 @@
 
 #include "fctsys.h"
 #include "common.h"
-#include "class_drawpanel.h"
-
-#include "pcbnew.h"
 #include "gerbview.h"
-#include "trigo.h"
+#include "class_gerber_draw_item.h"
 
-
-/* Display the character of the localized STRUCTURE and return a pointer
- * to it.
+/* localize a gerber item and return a pointer to it.
+ * Display info about this item
  */
-BOARD_ITEM* WinEDA_GerberFrame::Locate( int typeloc )
+GERBER_DRAW_ITEM* WinEDA_GerberFrame::Locate( int aTypeloc )
 {
-    // TODO
     MsgPanel->EraseMsgBox();
+    wxPoint ref;
+    bool found = false;
+    if( aTypeloc == CURSEUR_ON_GRILLE )
+        ref = GetScreen()->m_Curseur;
+    else
+        ref = GetScreen()->m_MousePosition;
+
+    int         layer = GetScreen()->m_Active_Layer;
+
+    // Search first on active layer
+    BOARD_ITEM* item = GetBoard()->m_Drawings;
+    GERBER_DRAW_ITEM* gerb_item = NULL;
+    for( ; item; item = item->Next() )
+    {
+        gerb_item = (GERBER_DRAW_ITEM*) item;
+        if( gerb_item->GetLayer()!= layer )
+            continue;
+        if( gerb_item->HitTest( ref ) )
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if( !found ) // Search on all layers
+    {
+        item = GetBoard()->m_Drawings;
+        for( ; item; item = item->Next() )
+        {
+            gerb_item = (GERBER_DRAW_ITEM*) item;
+            if( gerb_item->HitTest( ref ) )
+            {
+                found = true;
+                break;
+            }
+        }
+    }
+    if( found )
+    {
+        gerb_item->DisplayInfo( this );
+        return gerb_item;
+    }
     return NULL;
 }
-
diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp
index 8bb1f05fe7..132e2540bb 100644
--- a/gerbview/rs274d.cpp
+++ b/gerbview/rs274d.cpp
@@ -104,7 +104,6 @@ static void fillFlashedGBRITEM(  GERBER_DRAW_ITEM* aGbrItem,
     aGbrItem->SetLayer( aLayer );
     aGbrItem->m_Size  = aSize;
     aGbrItem->m_Start = aPos;
-    NEGATE( aGbrItem->m_Start.y );
     aGbrItem->m_End   = aGbrItem->m_Start;
     aGbrItem->m_DCode = Dcode_index;
     aGbrItem->m_LayerNegative = aLayerNegative;
@@ -175,10 +174,7 @@ static void fillLineGBRITEM(  GERBER_DRAW_ITEM* aGbrItem,
     aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
 
     aGbrItem->m_Start = aStart;
-    NEGATE( aGbrItem->m_Start.y );
-
     aGbrItem->m_End = aEnd;
-    NEGATE( aGbrItem->m_End.y );
 
     aGbrItem->m_DCode = Dcode_index;
     aGbrItem->m_LayerNegative = aLayerNegative;
@@ -300,10 +296,6 @@ static void fillArcGBRITEM(  GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
     aGbrItem->m_DCode     = Dcode_index;
     aGbrItem->m_ArcCentre = center;
 
-    NEGATE( aGbrItem->m_Start.y );
-    NEGATE( aGbrItem->m_End.y );
-    NEGATE( aGbrItem->m_ArcCentre.y );
-
     aGbrItem->m_LayerNegative = aLayerNegative;
     aGbrItem->m_ImageNegative = aImageNegative;
 
@@ -890,12 +882,10 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
 //                           m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
 
                 gbritem->m_Start = m_PreviousPos;       // m_Start is used as temporary storage
-                NEGATE( gbritem->m_Start.y );
                 if( gbritem->m_PolyCorners.size() == 0 )
                     gbritem->m_PolyCorners.push_back( gbritem->m_Start );
 
                 gbritem->m_End = m_CurrentPos;       // m_End is used as temporary storage
-                NEGATE( gbritem->m_End.y );
                 gbritem->m_PolyCorners.push_back( gbritem->m_End );
 
                 // Set the erasure flag of gbritem if a negative polygon.
diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp
index 1039c6d32e..8dd0cf296e 100644
--- a/gerbview/rs274x.cpp
+++ b/gerbview/rs274x.cpp
@@ -308,7 +308,6 @@ bool GERBER::ExecuteRS274XCommand( int       command,
                 text++;
                 fcoord     = ReadDouble( text );
                 m_Offset.y = wxRound( fcoord * conv_scale );
-                NEGATE( m_Offset.y );
                 break;
             }
         }
@@ -349,7 +348,6 @@ bool GERBER::ExecuteRS274XCommand( int       command,
                 text++;
                 fcoord     = ReadDouble( text );
                 m_ImageOffset.y = wxRound( fcoord * conv_scale );
-                NEGATE( m_ImageOffset.y );
                 break;
             }
         }
diff --git a/gerbview/wxGerberFrame.h b/gerbview/wxGerberFrame.h
index 18e8e6dccf..e2ae25d349 100644
--- a/gerbview/wxGerberFrame.h
+++ b/gerbview/wxGerberFrame.h
@@ -228,8 +228,8 @@ public:
     void         OnSelectOptionToolbar( wxCommandEvent& event );
     void         OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct );
 
-    BOARD_ITEM*  GerberGeneralLocateAndDisplay();
-    BOARD_ITEM*  Locate( int typeloc );
+    GERBER_DRAW_ITEM*  GerberGeneralLocateAndDisplay();
+    GERBER_DRAW_ITEM*  Locate( int typeloc );
 
 
     void         SetToolbars();