Index: includes/ImageGallery.php
===================================================================
--- includes/ImageGallery.php	(revision 19718)
+++ includes/ImageGallery.php	(working copy)
@@ -16,18 +16,21 @@
 	var $mImages, $mShowBytes, $mShowFilename;
 	var $mCaption = false;
 	var $mSkin = false;
-	
+
 	/**
 	 * Is the gallery on a wiki page (i.e. not a special page)
 	 */
 	var $mParsing;
-	
+
 	/**
 	 * Contextual title, used when images are being screened
 	 * against the bad image list
 	 */
 	private $contextTitle = false;
 
+	private $mPerRow = 0; // How many images wide should the gallery be (0 = fluid)?
+	private $mWidths = 120, $mHeights = 120; // How wide/tall each thumbnail should be
+
 	/**
 	 * Create a new image gallery object.
 	 */
@@ -44,7 +47,7 @@
 	function setParsing( $val = true ) {
 		$this->mParsing = $val;
 	}
-	
+
 	/**
 	 * Set the caption (as plain text)
 	 *
@@ -53,17 +56,50 @@
 	function setCaption( $caption ) {
 		$this->mCaption = htmlspecialchars( $caption );
 	}
-	
+
 	/**
 	 * Set the caption (as HTML)
 	 *
 	 * @param $caption Caption
 	 */
-	function setCaptionHtml( $caption ) {
+	public function setCaptionHtml( $caption ) {
 		$this->mCaption = $caption;
 	}
 
 	/**
+	 * Set how many images will be displayed per row. 0 = fit to user's screen.
+	 *
+	 * @param int $num >= 0; invalid numbers will be rejected
+	 */
+	public function setPerRow( $num ) {
+		if ($num >= 0 && is_int($num)) {
+			$this->mPerRow = $num;
+		}
+	}
+
+	/**
+	 * Set how wide each image will be, in pixels.
+	 *
+	 * @param int $num > 0; invalid numbers will be ignored
+	 */
+	public function setWidths( $num ) {
+		if ($num > 0 && is_int($num)) {
+			$this->mWidths = $num;
+		}
+	}
+
+	/**
+	 * Set how high each image will be, in pixels.
+	 *
+	 * @param int $num > 0; invalid numbers will be ignored
+	 */
+	public function setHeights( $num ) {
+		if ($num > 0 && is_int($num)) {
+			$this->mHeights = $num;
+		}
+	}
+
+	/**
 	 * Instruct the class to use a specific skin for rendering
 	 *
 	 * @param $skin Skin object
@@ -71,7 +107,7 @@
 	function useSkin( $skin ) {
 		$this->mSkin = $skin;
 	}
-	
+
 	/**
 	 * Return the skin that should be used
 	 *
@@ -151,10 +187,11 @@
 
 		$sk = $this->getSkin();
 
-		$s = '<table class="gallery" cellspacing="0" cellpadding="0">';
-		if( $this->mCaption )
-			$s .= '<td class="galleryheader" colspan="4"><big>' . $this->mCaption . '</big></td>';
-		
+		$s = '<div class="gallery">';
+		if( $this->mCaption ) {
+			$s .= "\n\t<div class=\"galleryheader\">" . $this->mCaption . '</div>';
+		}
+
 		$i = 0;
 		foreach ( $this->mImages as $pair ) {
 			$img =& $pair[0];
@@ -164,18 +201,19 @@
 
 			if( $nt->getNamespace() != NS_IMAGE ) {
 				# We're dealing with a non-image, spit out the name and be done with it.
-				$thumbhtml = '<div style="height: 152px;">' . htmlspecialchars( $nt->getText() ) . '</div>';
+				$thumbhtml = "\n\t\t".'<div style="height: '.($this->mHeights+32).'px; width: '.($this->mWidths+30).'px;">'
+					. htmlspecialchars( $nt->getText() ) . '</div>';
  			} elseif( $this->mParsing && wfIsBadImage( $nt->getDBkey(), $this->getContextTitle() ) ) {
 				# The image is blacklisted, just show it as a text link.
-				$thumbhtml = '<div style="height: 152px;">'
+				$thumbhtml = "\n\t\t".'<div style="height: '.($this->mHeights+32).'px; width: '.($this->mWidths+30).'px;">'
 					. $sk->makeKnownLinkObj( $nt, htmlspecialchars( $nt->getText() ) ) . '</div>';
-			} else if( !( $thumb = $img->getThumbnail( 120, 120, $wgGenerateThumbnailOnParse ) ) ) {
+			} elseif( !( $thumb = $img->getThumbnail( $this->mWidths, $this->mHeights, $wgGenerateThumbnailOnParse ) ) ) {
 				# Error generating thumbnail.
-				$thumbhtml = '<div style="height: 152px;">'
+				$thumbhtml = "\n\t\t".'<div style="height: '.($this->mHeights+32).'px; width: '.($this->mWidths+30).'px;">'
 					. htmlspecialchars( $img->getLastError() ) . '</div>';
 			} else {
-				$vpad = floor( ( 150 - $thumb->height ) /2 ) - 2;
-				$thumbhtml = '<div class="thumb" style="padding: ' . $vpad . 'px 0;">'
+				$vpad = floor( ( 30 + $this->mHeights - $thumb->height ) /2 ) - 2;
+				$thumbhtml = "\n\t\t".'<div class="thumb" style="padding: ' . $vpad . 'px 0; width: '.($this->mWidths+30).';">'
 					. $sk->makeKnownLinkObj( $nt, $thumb->toHtml() ) . '</div>';
 			}
 
@@ -202,21 +240,20 @@
 			# in version 4.8.6 generated crackpot html in its absence, see:
 			# http://bugzilla.wikimedia.org/show_bug.cgi?id=1765 -Ævar
 
-			$s .= ($i%4==0) ? '<tr>' : '';
-			$s .= '<td><div class="gallerybox">' . $thumbhtml
-				. '<div class="gallerytext">' . "\n" . $textlink . $text . $nb
-				. "</div></div></td>\n";
-			$s .= ($i%4==3) ? '</tr>' : '';
+			$s .= "\n\t".'<div class="gallerybox"';
+			if ( $this->mPerRow && $i % $this->mPerRow == 1 ) {
+				$s .= ' style="clear: both;"';
+			}
+			$s .= '>' . $thumbhtml
+				. "\n\t\t" . '<div class="gallerytext">' . "\n" . $textlink . $text . $nb
+				. "\n\t\t</div>\n\t</div>\n";
 			$i++;
 		}
-		if( $i %4 != 0 ) {
-			$s .= "</tr>\n";
-		}
-		$s .= '</table>';
+		$s .= '</div>';
 
 		return $s;
 	}
-	
+
 	/**
 	 * @return int Number of images in the gallery
 	 */
Index: includes/Parser.php
===================================================================
--- includes/Parser.php	(revision 19720)
+++ includes/Parser.php	(working copy)
@@ -4310,6 +4310,15 @@
 			$caption = $this->replaceInternalLinks( $caption );
 			$ig->setCaptionHtml( $caption );
 		}
+		if( isset( $params['perrow'] ) ) {
+			$ig->setPerRow( $params['perrow'] );
+		}
+		if( isset( $params['widths'] ) ) {
+			$ig->setWidths( $params['widths'] );
+		}
+		if( isset( $params['heights'] ) ) {
+			$ig->setHeights( $params['heights'] );
+		}
 
 		$lines = explode( "\n", $text );
 		foreach ( $lines as $line ) {
Index: skins/monobook/main.css
===================================================================
--- skins/monobook/main.css	(revision 19719)
+++ skins/monobook/main.css	(working copy)
@@ -1284,40 +1284,29 @@
 	background-color: #0f0;
 }
 
-table.gallery {
-	border: 1px solid #ccc;
-	margin: 2px;
-	padding: 2px;
-	background-color: white;
+.gallery {
+	margin: 4px;
 }
 
-table.gallery tr {
-	vertical-align: top;
-}
-
-table.gallery td {
-	vertical-align: top;
+.gallerybox {
 	background-color: #f9f9f9;
 	border: solid 2px white;
+	float: left;
+	margin: 2px;
 }
 
-table.gallery td.galleryheader {
+.galleryheader {
 	text-align: center;
-	font-weight: bold;
+	font-weight: bolder;
 }
 
-div.gallerybox {
-	margin: 2px;
-	width:  150px;
-}
-
-div.gallerybox div.thumb {
+.gallerybox .thumb {
 	text-align: center;
 	border: 1px solid #ccc;
 	margin: 2px;
 }
 
-div.gallerytext {
+.gallerytext {
 	font-size: 94%;
 	padding: 2px 4px;
 }
