From 7b0a3f0f96af27aac39c60a2ff095472656ea689 Mon Sep 17 00:00:00 2001 From: Grishka Date: Mon, 27 Mar 2023 04:04:16 +0300 Subject: [PATCH] More media layout optimizations --- .../android/ui/PhotoLayoutHelper.java | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java index ba173466..6ca082e3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java @@ -32,28 +32,33 @@ public class PhotoLayoutHelper{ result.height=MAX_HEIGHT; result.width=MAX_WIDTH;//Math.round(att.getWidth()/(float)att.getHeight()*MAX_HEIGHT); } - result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, result.width, result.height, 0, 0)}; + result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, 0, 0)}; return result; }else if(thumbs.size()==0){ throw new IllegalArgumentException("Empty thumbs array"); } - String orients=""; ArrayList ratios=new ArrayList<>(); int cnt=thumbs.size(); + boolean allAreWide=true, allAreSquare=true; for(Attachment thumb : thumbs){ float ratio=thumb.getWidth()/(float) thumb.getHeight(); - char orient=ratio>1.2 ? 'w' : (ratio<0.8 ? 'n' : 'q'); - orients+=orient; + if(ratio<=1.2f){ + allAreWide=false; + if(ratio<0.8f) + allAreSquare=false; + }else{ + allAreSquare=false; + } ratios.add(ratio); } float avgRatio=!ratios.isEmpty() ? sum(ratios)/ratios.size() : 1.0f; if(cnt==2){ - if(orients.equals("ww") && avgRatio>1.4*maxRatio && (ratios.get(1)-ratios.get(0))<0.2){ // two wide photos, one above the other + if(allAreWide && avgRatio>1.4*maxRatio && (ratios.get(1)-ratios.get(0))<0.2){ // two wide photos, one above the other float h=Math.max(Math.min(MAX_WIDTH/ratios.get(0), Math.min(MAX_WIDTH/ratios.get(1), (MAX_HEIGHT-GAP)/2.0f)), MIN_HEIGHT/2f); result.width=MAX_WIDTH; @@ -61,10 +66,10 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{result.width}; result.rowSizes=new int[]{Math.round(h), Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 1, MAX_WIDTH, h, 0, 0), - new TiledLayoutResult.Tile(1, 1, MAX_WIDTH, h, 0, 1) + new TiledLayoutResult.Tile(1, 1, 0, 0), + new TiledLayoutResult.Tile(1, 1, 0, 1) }; - }else if(orients.equals("ww") || orients.equals("qq")){ // next to each other, same ratio + }else if(allAreWide || allAreSquare){ // next to each other, same ratio float w=((MAX_WIDTH-GAP)/2); float h=Math.max(Math.min(w/ratios.get(0), Math.min(w/ratios.get(1), MAX_HEIGHT)), MIN_HEIGHT); @@ -73,8 +78,8 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{Math.round(w), MAX_WIDTH-Math.round(w)}; result.rowSizes=new int[]{Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 1, w, h, 0, 0), - new TiledLayoutResult.Tile(1, 1, w, h, 1, 0) + new TiledLayoutResult.Tile(1, 1, 0, 0), + new TiledLayoutResult.Tile(1, 1, 1, 0) }; }else{ // next to each other, different ratios float w0=((MAX_WIDTH-GAP)/ratios.get(1)/(1/ratios.get(0)+1/ratios.get(1))); @@ -86,12 +91,12 @@ public class PhotoLayoutHelper{ result.width=Math.round(w0+w1+GAP); result.height=Math.round(h); result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 1, w0, h, 0, 0), - new TiledLayoutResult.Tile(1, 1, w1, h, 1, 0) + new TiledLayoutResult.Tile(1, 1, 0, 0), + new TiledLayoutResult.Tile(1, 1, 1, 0) }; } }else if(cnt==3){ - if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || orients.equals("www")){ // 2nd and 3rd photos are on the next line + if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || allAreWide){ // 2nd and 3rd photos are on the next line float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f); float w2=((MAX_WIDTH-GAP)/2); float h=Math.min(MAX_HEIGHT-hCover-GAP, Math.min(w2/ratios.get(1), w2/ratios.get(2))); @@ -105,9 +110,9 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{Math.round(w2), MAX_WIDTH-Math.round(w2)}; result.rowSizes=new int[]{Math.round(hCover), Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(2, 1, MAX_WIDTH, hCover, 0, 0), - new TiledLayoutResult.Tile(1, 1, w2, h, 0, 1), - new TiledLayoutResult.Tile(1, 1, w2, h, 1, 1) + new TiledLayoutResult.Tile(2, 1, 0, 0), + new TiledLayoutResult.Tile(1, 1, 0, 1), + new TiledLayoutResult.Tile(1, 1, 1, 1) }; }else{ // 2nd and 3rd photos are on the right part float height=Math.min(MAX_HEIGHT, MAX_WIDTH*0.66f/avgRatio); @@ -120,13 +125,13 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{Math.round(wCover), Math.round(w)}; result.rowSizes=new int[]{Math.round(h0), Math.round(h1)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 2, wCover, height, 0, 0), - new TiledLayoutResult.Tile(1, 1, w, h0, 1, 0), - new TiledLayoutResult.Tile(1, 1, w, h1, 1, 1) + new TiledLayoutResult.Tile(1, 2, 0, 0), + new TiledLayoutResult.Tile(1, 1, 1, 0), + new TiledLayoutResult.Tile(1, 1, 1, 1) }; } }else if(cnt==4){ - if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || orients.equals("wwww")){ // 2nd, 3rd and 4th photos are on the next line + if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || allAreWide){ // 2nd, 3rd and 4th photos are on the next line float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f); float h=(MAX_WIDTH-2*GAP)/(ratios.get(1)+ratios.get(2)+ratios.get(3)); float w0=h*ratios.get(1); @@ -143,10 +148,10 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{Math.round(w0), Math.round(w1), MAX_WIDTH-Math.round(w0)-Math.round(w1)}; result.rowSizes=new int[]{Math.round(hCover), Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(3, 1, MAX_WIDTH, hCover, 0, 0), - new TiledLayoutResult.Tile(1, 1, w0, h, 0, 1), - new TiledLayoutResult.Tile(1, 1, w1, h, 1, 1), - new TiledLayoutResult.Tile(1, 1, w2, h, 2, 1), + new TiledLayoutResult.Tile(3, 1, 0, 0), + new TiledLayoutResult.Tile(1, 1, 0, 1), + new TiledLayoutResult.Tile(1, 1, 1, 1), + new TiledLayoutResult.Tile(1, 1, 2, 1), }; }else{ // 2nd, 3rd and 4th photos are on the right part float height=Math.min(MAX_HEIGHT, MAX_WIDTH*0.66f/avgRatio); @@ -161,10 +166,10 @@ public class PhotoLayoutHelper{ result.columnSizes=new int[]{Math.round(wCover), Math.round(w)}; result.rowSizes=new int[]{Math.round(h0), Math.round(h1), Math.round(h2)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 3, wCover, height, 0, 0), - new TiledLayoutResult.Tile(1, 1, w, h0, 1, 0), - new TiledLayoutResult.Tile(1, 1, w, h1, 1, 1), - new TiledLayoutResult.Tile(1, 1, w, h2, 1, 2), + new TiledLayoutResult.Tile(1, 3, 0, 0), + new TiledLayoutResult.Tile(1, 1, 1, 0), + new TiledLayoutResult.Tile(1, 1, 1, 1), + new TiledLayoutResult.Tile(1, 1, 1, 2), }; } }else{ @@ -206,14 +211,15 @@ public class PhotoLayoutHelper{ } } - // Looking for minimum difference between thumbs block height and MAX_HEIGHT (may probably be little over) + // Looking for minimum difference between thumbs block height and maxHeight (may probably be little over) + final int realMaxHeight=Math.min(MAX_HEIGHT, MAX_WIDTH); int[] optConf=null; float optDiff=0; for(int[] conf : tries.keySet()){ float[] heights=tries.get(conf); float confH=GAP*(heights.length-1); for(float h : heights) confH+=h; - float confDiff=Math.abs(confH-MAX_HEIGHT); + float confDiff=Math.abs(confH-realMaxHeight); if(conf.length>1){ if(conf[0]>conf[1] || conf.length>2 && conf[1]>conf[2]){ confDiff*=1.1; @@ -252,7 +258,7 @@ public class PhotoLayoutHelper{ totalWidth+=Math.round(w); if(j