Index: /trunk/themes/smartpocket/js/smartpocket.js
===================================================================
--- /trunk/themes/smartpocket/js/smartpocket.js	(revision 26348)
+++ /trunk/themes/smartpocket/js/smartpocket.js	(revision 26349)
@@ -28,14 +28,6 @@
 			}
 		});
-		$(window).bind('orientationchange', set_thumbnails_width);
-		set_thumbnails_width();
+		var spThumbs = new SPThumbs(SPThumbsOpts);
   });
 }(window, window.jQuery, window.Code.PhotoSwipe));
 
-function set_thumbnails_width() {
-	var dpr = 1 //window.devicePixelRatio>1 ? window.devicePixelRatio : 1
-		, nb_thumbs = Math.max(2, Math.ceil($('.thumbnails').width() / (var_thumb_width/dpr+2*5)))
-		, width = Math.floor(1000000 / nb_thumbs) / 10000;
-	$('.thumbnails li').css('width', width+'%');
-}
-
Index: /trunk/themes/smartpocket/js/thumb.arrange.js
===================================================================
--- /trunk/themes/smartpocket/js/thumb.arrange.js	(revision 26349)
+++ /trunk/themes/smartpocket/js/thumb.arrange.js	(revision 26349)
@@ -0,0 +1,170 @@
+
+function SPTLine(margin, rowHeight) {
+	this.elements = new Array;
+	this.margin = margin;
+	this.rowHeight = rowHeight;
+	this.maxHeight = 0;
+}
+
+SPTLine.prototype = {
+	width: 0,
+	elementsWidth: 0,
+	firstThumbIndex: 0,
+
+	add: function($elt, absIndex) {
+		if (this.elements.length === 0)
+			this.firstThumbIndex = absIndex;
+		if (!$elt.data("w"))
+		{
+			var w=$elt.width(), h=$elt.height();
+			if (h > this.rowHeight) {
+				w = Math.round(w * this.rowHeight/h);
+				h = this.rowHeight;
+			}
+			$elt.data("w", w)
+				.data("h", h);
+		}
+
+		var eltObj = {
+			$elt: $elt,
+			w: $elt.data("w"),
+			h: $elt.data("h")
+		};
+		this.elements.push(eltObj);
+
+		if (eltObj.h > this.maxHeight)
+			this.maxHeight = eltObj.h;
+
+		this.width += this.margin + eltObj.w;
+		this.elementsWidth += eltObj.w;
+	},
+
+	clear: function() {
+		if (!this.elements.length) return;
+		this.width = this.elementsWidth = 0;
+		this.maxHeight = 0;
+		this.elements.length = 0;
+	}
+}
+
+
+function SPThumbs(options) {
+	this.opts = options;
+
+	this.$thumbs = $('.thumbnails');
+	if (this.$thumbs.length==0) return;
+	this.$thumbs.css('text-align', 'left');
+
+	this.opts.extraRowHeight = 0;
+	if (window.devicePixelRatio > 1) {
+		var dpr = window.devicePixelRatio;
+		this.opts.extraRowHeight = 6; /*loose sharpness but only for small screens when we could "almost" fit with full sharpness*/
+		this.opts.rowHeight = Math.round(this.opts.rowHeight / dpr ) + this.opts.extraRowHeight;
+	}
+	this.process();
+
+	var that = this;
+	$(window).on('resize', function() {
+		if (Math.abs(that.$thumbs.width() - that.prevContainerWidth)>1)
+			that.process();
+	})
+		.on('RVTS_loaded', function(evt, down) {
+			that.process( down && that.$thumbs.width() == that.prevContainerWidth ? that.prevLastLineFirstThumbIndex : 0);
+		} );
+}
+
+SPThumbs.prototype = {
+	prevContainerWidth:0,
+	prevLastLineFirstThumbIndex: 0,
+
+	process: function(startIndex) {
+		startIndex = startIndex ? startIndex : 0;
+		var containerWidth  = this.$thumbs.width()
+			, maxExtraMarginPerThumb = 1;
+		this.prevContainerWidth = containerWidth;
+
+		var $elts = $('li.liVisible>a>img', this.$thumbs)
+			, line  = new SPTLine(this.opts.hMargin, this.opts.rowHeight);
+
+		for (var i=startIndex; i<$elts.length; i++) {
+			var $elt = $( $elts[i] );
+
+			line.add($elt, i);
+			if (line.width >= containerWidth - maxExtraMarginPerThumb * line.elements.length) {
+				this.processLine(line, containerWidth);
+				line.clear();
+			}
+		};
+
+		if(line.elements.length)
+			this.processLine(line, containerWidth, true);
+		this.prevLastLineFirstThumbIndex = line.firstThumbIndex;
+	},
+
+	processLine: function(line, containerWidth, lastLine) {
+		var toRecover, eltW, eltH
+			, rowHeight = line.maxHeight ? line.maxHeight : line.elements[0].h;
+
+		if (line.width / containerWidth > 1.01) {
+			var ratio = line.elementsWidth / (line.elementsWidth + containerWidth - line.width);
+			var adjustedRowHeight = rowHeight / (1 + (ratio-1) * 0.95 );
+			adjustedRowHeight = 6 * Math.round( adjustedRowHeight/6 );
+			if (adjustedRowHeight < rowHeight / ratio ) {
+				adjustedRowHeight = Math.ceil( rowHeight / ratio );
+				var missing = this.opts.rowHeight - this.opts.extraRowHeight - adjustedRowHeight;
+				if (missing>0 && missing<6)
+					adjustedRowHeight += missing;
+			}
+			if (adjustedRowHeight < rowHeight)
+				rowHeight = adjustedRowHeight;
+		}
+		else if (lastLine)
+			rowHeight = Math.min( rowHeight, this.opts.rowHeight - this.opts.extraRowHeight);
+
+		toRecover = line.width - containerWidth;
+		if (lastLine)
+			toRecover = 0;
+
+		for(var i=0; i<line.elements.length; i++) {
+			var eltObj = line.elements[i]
+				, eltW=eltObj.w
+				, eltH=eltObj.h
+				, eltToRecover;
+
+			if (i==line.elements.length-1)
+				eltToRecover = toRecover;
+			else
+				eltToRecover = Math.round(toRecover * eltW / line.elementsWidth);
+
+			toRecover -= eltToRecover;
+			line.elementsWidth -= eltW;
+
+			if (eltH > rowHeight ) {
+				eltW = Math.round( eltW * rowHeight/eltObj.h );
+				eltH = rowHeight;
+				eltToRecover -= eltObj.w - eltW;
+				if (lastLine)
+					eltToRecover = 0;
+			}
+
+			this.reposition(eltObj.$elt, eltW, eltH, eltW-eltToRecover, rowHeight);
+		}
+	},
+
+	reposition: function($img, imgW, imgH, liW, liH) {
+		$img.attr("width", imgW)
+			.attr("height", imgH);
+
+		$img.closest("li").css( {
+			width: liW+"px",
+			height: liH+"px"
+		});
+
+		$img.parent("a").css( {
+			left: Math.round((liW-imgW)/2)+"px",
+			top: Math.round((liH-imgH)/2)+"px"
+		});
+	}
+
+}
+
Index: /trunk/themes/smartpocket/template/thumbnails.tpl
===================================================================
--- /trunk/themes/smartpocket/template/thumbnails.tpl	(revision 26348)
+++ /trunk/themes/smartpocket/template/thumbnails.tpl	(revision 26349)
@@ -1,32 +1,38 @@
 {if !empty($thumbnails)}
+{$row_height=216}
+{$hmargin=4}
+{$vmargin=5}
+{$container_margin=-10}
+
 {combine_script id='klass' path='themes/smartpocket/js/klass.min.js'}
 {combine_script id='photoswipe' path='themes/smartpocket/js/code.photoswipe.jquery.min.js' require='klass,jquery.mobile'}
 {combine_script id='smartpocket' path='themes/smartpocket/js/smartpocket.js' require='photoswipe'}
-{combine_script id='jquery.ajaxmanager' path='themes/default/js/plugins/jquery.ajaxmanager.js' load='footer'}
-{combine_script id='thumbnails.loader' path='themes/default/js/thumbnails.loader.js' require='jquery.ajaxmanager' load='footer'}
+{combine_script id='sp.thumb.arrange' path='themes/smartpocket/js/thumb.arrange.js' require='jquery' load='footer'}
 {footer_script}
-  var var_loop = {if $smartpocket.loop}true{else}false{/if}, var_autohide = {$smartpocket.autohide}, var_trad = "{'More Information'|@translate}", var_thumb_width={$thumbnail_derivative_params->max_width()};
+var var_loop = {if $smartpocket.loop}true{else}false{/if}, var_autohide = {$smartpocket.autohide}, var_trad = "{'More Information'|@translate}";
+var SPThumbsOpts ={ hMargin:{$hmargin},rowHeight:{$row_height}};
 {/footer_script}
-
+{$thumb_picker->init($row_height)}
+{html_style}
+.thumbnails .liEmpty{ display:none}
+.thumbnails LI{ margin-left:{$hmargin}px; margin-bottom:{$vmargin}px}
+.thumbnails { margin:0 {$container_margin}px 0 {$container_margin-$hmargin}px}
+{/html_style}
 <ul class="thumbnails">
 {foreach from=$thumbnails item=thumbnail}{strip}
-{assign var=derivative value=$pwg->derivative($thumbnail_derivative_params, $thumbnail.src_image)}
+{$derivative=$thumb_picker->pick($thumbnail.src_image)}
 {if isset($page_selection[$thumbnail.id]) and !isset($thumbnail.representative_ext)}
-  <li>
-    <a href="{$pwg->derivative_url($picture_derivative_params, $thumbnail.src_image)}" data-picture-url="{$thumbnail.URL}" rel="external">
-     <img {if !$derivative->is_cached()}data-{/if}src="{$derivative->get_url()}" alt="{$thumbnail.TN_ALT}">
-    </a>
-  </li>
-{elseif isset($thumbnail.representative_ext)}
-  <li>
-    <a href="{$thumbnail.URL}" target="_blank" onClick="window.location='{$thumbnail.URL}'">
-     <img {if !$derivative->is_cached()}data-{/if}src="{$derivative->get_url()}" alt="{$thumbnail.TN_ALT}">
-    </a>
-  </li>
+	<li class="liVisible">
+{if !isset($thumbnail.representative_ext)}
+		<a href="{$pwg->derivative_url($picture_derivative_params, $thumbnail.src_image)}" data-picture-url="{$thumbnail.URL}" rel="external">
 {else}
-  <li style="display:none;">
-    <a href="{$pwg->derivative_url($picture_derivative_params, $thumbnail.src_image)}" rel="external"></a>
-  </li>
+		<a href="{$thumbnail.URL}" target="_blank" onClick="window.location='{$thumbnail.URL}'">
 {/if}
+		 <img src="{$derivative->get_url()}" {$derivative->get_size_htm()} alt="{$thumbnail.TN_ALT}">
+{else}
+	<li class="liEmpty">
+		<a href="{$pwg->derivative_url($picture_derivative_params, $thumbnail.src_image)}" rel="external">
+{/if}
+	</a></li>
 {/strip}{/foreach}
 </ul>
Index: /trunk/themes/smartpocket/theme.css
===================================================================
--- /trunk/themes/smartpocket/theme.css	(revision 26348)
+++ /trunk/themes/smartpocket/theme.css	(revision 26349)
@@ -17,9 +17,16 @@
 .ui-field-contain, .ui-br { padding: 5px; border: 0 !important; }
 
-.thumbnails { list-style: none; padding: 0; margin: 0; }
+.thumbnails { list-style: none; padding: 0}
 .thumbnails:after { clear: both; content: "."; display: block; height: 0; visibility: hidden; }
-.thumbnails li { float: left;  }
-.thumbnails li a { display: block; margin: 5px; }
-.thumbnails li img { display: block; width: 100%; height: auto; }
+.thumbnails li {
+	float: left;
+	position: relative;
+	overflow: hidden;
+	display: inline;
+}
+.thumbnails li a { 
+	position: absolute;
+}
+
 #more_link {
   color: #FFFFFF;
Index: /trunk/themes/smartpocket/themeconf.inc.php
===================================================================
--- /trunk/themes/smartpocket/themeconf.inc.php	(revision 26348)
+++ /trunk/themes/smartpocket/themeconf.inc.php	(revision 26349)
@@ -23,4 +23,47 @@
 */
 
+
+class SPThumbPicker
+{
+  var $candidates;
+  var $default;
+  var $height;
+  
+  function init($height)
+  {
+    $this->candidates = array();
+    foreach( ImageStdParams::get_defined_type_map() as $params)
+    {
+      if ($params->max_height() < $height || $params->sizing->max_crop)
+        continue;
+      if ($params->max_height() > 3*$height)
+        break;
+      $this->candidates[] = $params;
+    }
+    $this->default = ImageStdParams::get_custom($height*3, $height, 1, 0, $height );
+    $this->height = $height;
+  }
+  
+  function pick($src_image)
+  {
+    $ok = false;
+    foreach($this->candidates as $candidate)
+    {
+      $deriv = new DerivativeImage($candidate, $src_image);
+      $size = $deriv->get_size();
+      if ($size[1]>=$row_height-2)
+      {
+        $ok = true;
+        break;
+      }
+    }
+    if (!$ok)
+    {
+      $deriv = new DerivativeImage($this->default, $src_image);
+    }
+    return $deriv;
+  }
+}
+
 //Retrive all pictures on thumbnails page
 add_event_handler('loc_index_thumbnails_selection', 'sp_select_all_thumbnails');
@@ -31,5 +74,5 @@
 
   $template->assign('page_selection', array_flip($selection));
-
+  $template->assign('thumb_picker', new SPThumbPicker() );
   return $page['items'];
 }
@@ -49,8 +92,5 @@
 {
   $screen_size = explode('x', $_COOKIE['screen_size']);
-  $derivative_params = new ImageStdParams;
-  $derivative_params->load_from_db();
-
-  foreach ($derivative_params->get_all_type_map() as $type => $map)
+  foreach (ImageStdParams::get_all_type_map() as $type => $map)
   {
     if (max($map->sizing->ideal_size) >= max($screen_size) and min($map->sizing->ideal_size) >= min($screen_size))
