Index: FL/Fl_Pack.H
===================================================================
--- FL/Fl_Pack.H	(revision 10144)
+++ FL/Fl_Pack.H	(working copy)
@@ -45,8 +45,12 @@
 
 public:
   enum { // values for type(int)
-    VERTICAL = 0,
-    HORIZONTAL = 1
+    VERTICAL   = 0,		//< children stacked vertically (default)
+    HORIZONTAL = 1,		//< children stacked horizontally
+    LEFT       = 0,		//< children stack from left-to-right in HORIZONTAL mode (default)
+    RIGHT      = 2,		//< children stack from right-to-left in HORIZONTAL mode
+    TOP        = 0,		//< children stack from top-to-bottom in VERTICAL mode (default)
+    BOTTOM     = 2		//< children stack from bottom-to-top in VERTICAL mode
   };
 
 protected:
@@ -65,7 +69,12 @@
   */
   void spacing(int i) {spacing_ = i;}
   /** Same as Fl_Group::type() */
-  uchar horizontal() const {return type();}
+  uchar horizontal() const {return type() & HORIZONTAL ? 1 : 0;}
+  uchar vertical()   const {return type() & HORIZONTAL ? 0 : 1;}
+  uchar left()       const {return type() & RIGHT  ? 0 : 1;}
+  uchar right()      const {return type() & RIGHT  ? 1 : 0;}
+  uchar bottom()     const {return type() & BOTTOM ? 1 : 0;}
+  uchar top()        const {return type() & BOTTOM ? 0 : 1;}
 };
 
 #endif
Index: src/Fl_Pack.cxx
===================================================================
--- src/Fl_Pack.cxx	(revision 10144)
+++ src/Fl_Pack.cxx	(working copy)
@@ -43,64 +43,86 @@
 }
 
 void Fl_Pack::draw() {
+  // Inner dimension of widget's box()
   int tx = x()+Fl::box_dx(box());
   int ty = y()+Fl::box_dy(box());
   int tw = w()-Fl::box_dw(box());
   int th = h()-Fl::box_dh(box());
   int rw, rh;
-  int current_position = horizontal() ? tx : ty;
+  int current_position = horizontal() ? (right()  ? tx+tw : tx)
+                                      : (bottom() ? ty+th : ty);
   int maximum_position = current_position;
   uchar d = damage();
   Fl_Widget*const* a = array();
   if (horizontal()) {
+    // Determine overall width of visible children (including spacing)
     rw = -spacing_;
     rh = th;
-    
-    for (int i = children(); i--;)
+    for (int i = children(); i--;) {
       if (child(i)->visible()) {
         if (child(i) != this->resizable()) rw += child(i)->w();
         rw += spacing_;
       }
+    }
   } else {
+    // Determine overall height of visible children (including spacing)
     rw = tw;
     rh = -spacing_;
-    
-    for (int i = children(); i--;)
+    for (int i = children(); i--;) {
       if (child(i)->visible()) {
         if (child(i) != this->resizable()) rh += child(i)->h();
         rh += spacing_;
       }
+    }
   }
+  // Move all children to their positions..
   for (int i = children(); i--;) {
     Fl_Widget* o = *a++;
     if (o->visible()) {
       int X,Y,W,H;
       if (horizontal()) {
-        X = current_position;
+        X = right() ? current_position-o->w() : current_position;
         W = o->w();
         Y = ty;
         H = th;
       } else {
         X = tx;
         W = tw;
-        Y = current_position;
+        Y = bottom() ? current_position-o->h() : current_position;
         H = o->h();
       }
-      // Last child, if resizable, takes all remaining room
-      if(i == 0 && o == this->resizable()) {
-        if(horizontal())
-          W = tw - rw;
-        else
-          H = th - rh;
+      // If resizable, widget at end takes all remaining room
+      if (o == this->resizable()) {
+        if (horizontal()) {
+          if (left() && i==0) {                         // left justified, first item
+            W = tw - rw;
+          } else if (right() && i==(children()-1)) {    // right justified, last item
+            W = tw - rw;
+            X = current_position-W;
+          }
+        } else {
+          // Vertical
+          if (top() && i==0) {                          // top justified, first item
+            H = th - rh;
+          } else if (bottom() && i==(children()-1)) {   // bot justified, last item
+            H = th - rh;
+            Y = current_position-H;
+          }
+        }
       }
-      if (spacing_ && current_position>maximum_position && box() &&
-        (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) {
+      // Fill space between children
+      // if pack has box() and spacing defined..
+      if (spacing_ && box() && (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) {
         fl_color(color());
-        if (horizontal())
-          fl_rectf(maximum_position, ty, spacing_, th);
-        else
-          fl_rectf(tx, maximum_position, tw, spacing_);
+        if ((left()||top()) && current_position>maximum_position) {
+          if (horizontal()) fl_rectf(maximum_position, ty, spacing_, th);
+          else              fl_rectf(tx, maximum_position, tw, spacing_);
+        } else if ((right()||bottom()) && current_position<maximum_position) {
+          if (horizontal()) fl_rectf(maximum_position-spacing_, ty, spacing_, th);
+          else              fl_rectf(tx, maximum_position-spacing_, tw, spacing_);
+        }
       }
+      // Resize child
       if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) {
         o->resize(X,Y,W,H);
         o->clear_damage(FL_DAMAGE_ALL);
@@ -110,31 +132,51 @@
         draw_outside_label(*o);
       } else update_child(*o);
       // child's draw() can change it's size, so use new size:
-      current_position += (horizontal() ? o->w() : o->h());
-      if (current_position > maximum_position)
-        maximum_position = current_position;
-      current_position += spacing_;
+      if (right() || bottom()) {
+        current_position -= (horizontal() ? o->w() : o->h());
+        if (current_position < maximum_position)
+          maximum_position = current_position;
+        current_position -= spacing_;
+      } else {
+        current_position += (horizontal() ? o->w() : o->h());
+        if (current_position > maximum_position)
+          maximum_position = current_position;
+        current_position += spacing_;
+      }
     }
   }
-  
+  // Draw filled area past last widget
+  fl_color(color());
   if (horizontal()) {
-    if (maximum_position < tx+tw && box()) {
-      fl_color(color());
-      fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
+    if (right()) { // right
+      if (maximum_position > tx && box())
+        fl_rectf(tx, ty, maximum_position-tx, th);
+      tw = (tx+tw)-maximum_position;
+    } else {       // left
+      if (maximum_position < tx+tw && box())
+        fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
+      tw = maximum_position-tx;
     }
-    tw = maximum_position-tx;
   } else {
-    if (maximum_position < ty+th && box()) {
-      fl_color(color());
-      fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
+    if (bottom()) {     // bottom
+      if (maximum_position > ty && box())
+        fl_rectf(tx, ty, tw, maximum_position-ty);
+      th = (ty+th)-maximum_position;
+    } else {            // top
+      if (maximum_position < ty+th && box())
+        fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
+      th = maximum_position-ty;
     }
-    th = maximum_position-ty;
   }
-  
+  // Resize self to follow size of packed children
   tw += Fl::box_dw(box()); if (tw <= 0) tw = 1;
   th += Fl::box_dh(box()); if (th <= 0) th = 1;
   if (tw != w() || th != h()) {
-    Fl_Widget::resize(x(),y(),tw,th);
+    if (right() || bottom()) {
+      Fl_Widget::resize(x()+w()-tw,y()+h()-th,tw,th);
+    } else {
+      Fl_Widget::resize(x(),y(),tw,th);
+    }
     d = FL_DAMAGE_ALL;
   }
   if (d&FL_DAMAGE_ALL) {
