From db6e23321a8d9d9005c1faa0da94df3e03e8708a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sat, 26 Sep 2020 21:14:45 +0800 Subject: [PATCH] refactor Border generation on Mobile. The Border images (currently White and Black) will now be based on pixel color from the card texture. It will get the pixel color from card texture pixel xy(1,1) on full images and texture reqion xy on fullborder images. This should fix card sets with mixed white and black bordered cards (example Magazine Insert set (PMEI)). --- .../src/forge/assets/ImageCache.java | 67 +++++++++++-------- .../src/forge/card/CardImage.java | 3 +- .../src/forge/card/CardImageRenderer.java | 9 ++- .../src/forge/card/CardRenderer.java | 12 ++-- 4 files changed, 48 insertions(+), 43 deletions(-) diff --git a/forge-gui-mobile/src/forge/assets/ImageCache.java b/forge-gui-mobile/src/forge/assets/ImageCache.java index 6880658f4f1..41af584d14f 100644 --- a/forge-gui-mobile/src/forge/assets/ImageCache.java +++ b/forge-gui-mobile/src/forge/assets/ImageCache.java @@ -19,6 +19,7 @@ package forge.assets; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; @@ -39,7 +40,9 @@ import forge.properties.ForgeConstants; import forge.util.ImageUtil; import org.apache.commons.lang3.StringUtils; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -77,6 +80,7 @@ public class ImageCache { public static final Texture defaultImage; public static FImage BlackBorder = FSkinImage.IMG_BORDER_BLACK; public static FImage WhiteBorder = FSkinImage.IMG_BORDER_WHITE; + private static final Map Borders = new HashMap<>(); private static boolean imageLoaded, delayLoadRequested; public static void allowSingleLoad() { @@ -99,6 +103,7 @@ public class ImageCache { cache.invalidateAll(); cache.cleanUp(); missingIconKeys.clear(); + Borders.clear(); } public static void disposeTexture(){ @@ -181,6 +186,8 @@ public class ImageCache { if (useDefaultIfNotFound) { image = defaultImage; cache.put(imageKey, defaultImage); + if (Borders.get(image) == null) + Borders.put(image, false); //black border } } return image; @@ -192,8 +199,8 @@ public class ImageCache { e.printStackTrace(); } } - public static TextureRegion croppedBorderImage(Texture image, boolean fullborder) { - if (!fullborder) + public static TextureRegion croppedBorderImage(Texture image) { + if (!image.toString().contains(".fullborder.")) return new TextureRegion(image); float rscale = 0.96f; int rw = Math.round(image.getWidth()*rscale); @@ -202,25 +209,6 @@ public class ImageCache { int ry = Math.round((image.getHeight() - rh)/2f)-2; return new TextureRegion(image, rx, ry, rw, rh); } - public static boolean isWhiteBordered(IPaperCard c) { - if (c == null) - return false; - - CardEdition ed = FModel.getMagicDb().getEditions().get(c.getEdition()); - if (ed != null && ed.isWhiteBorder()) - return true; - return false; - } - public static boolean isWhiteBordered(CardView c) { - if (c == null) - return false; - - CardView.CardStateView state = c.getCurrentState(); - CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode()); - if (ed != null && ed.isWhiteBorder() && state.getFoilIndex() == 0) - return true; - return false; - } public static Color borderColor(IPaperCard c) { if (c == null) return Color.valueOf("#171717"); @@ -271,17 +259,38 @@ public class ImageCache { return true; return false; } - public static FImage getBorderImage(CardView c, boolean canshow) { + public static FImage getBorder(Texture t) { + if (Borders.get(t) == null) + Borders.put(t, isCloserToWhite(getpixelColor(t))); + return Borders.get(t) ? WhiteBorder : BlackBorder; + } + public static FImage getBorderImage(Texture t, boolean canshow) { if (!canshow) return BlackBorder; - if (isWhiteBordered(c)) - return WhiteBorder; - return BlackBorder; + return getBorder(t); } - public static FImage getBorderImage(IPaperCard c) { - if (isWhiteBordered(c)) - return WhiteBorder; - return BlackBorder; + public static FImage getBorderImage(Texture t) { + return getBorder(t); + } + public static String getpixelColor(Texture i) { + if (!i.getTextureData().isPrepared()) { + i.getTextureData().prepare(); //prepare texture + } + //get pixmap from texture data + Pixmap pixmap = i.getTextureData().consumePixmap(); + //get pixel color from x,y texture coordinate based on the image fullborder or not + Color color = new Color(pixmap.getPixel(croppedBorderImage(i).getRegionX()+1, croppedBorderImage(i).getRegionY()+1)); + pixmap.dispose(); + return color.toString(); + } + public static boolean isCloserToWhite(String c){ + if (c == null || c == "") + return false; + int c_r = Integer.parseInt(c.substring(0,2),16); + int c_g = Integer.parseInt(c.substring(2,4),16); + int c_b = Integer.parseInt(c.substring(4,6),16); + int brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000; + return brightness > 155; } public static Color getTint(CardView c) { if (c == null) diff --git a/forge-gui-mobile/src/forge/card/CardImage.java b/forge-gui-mobile/src/forge/card/CardImage.java index ef841355c75..ae4d4a5456a 100644 --- a/forge-gui-mobile/src/forge/card/CardImage.java +++ b/forge-gui-mobile/src/forge/card/CardImage.java @@ -49,13 +49,12 @@ public class CardImage implements FImage { } else { if (Forge.enableUIMask) { - boolean fullborder = image.toString().contains(".fullborder."); if (ImageCache.isExtendedArt(card)) g.drawImage(image, x, y, w, h); else { float radius = (h - w)/8; g.drawfillBorder(3, ImageCache.borderColor(card), x, y, w, h, radius); - g.drawImage(ImageCache.croppedBorderImage(image, fullborder), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f); + g.drawImage(ImageCache.croppedBorderImage(image), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f); } } else diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index 969110d178c..8d9620fd2b2 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -348,7 +348,6 @@ public class CardImageRenderer { if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top); } else { - boolean fullborder = image.toString().contains(".fullborder."); float radius = (h - w)/8; float wh_Adj = ForgeConstants.isGdxPortLandscape && isCurrentCard ? 1.38f:1.0f; float new_w = w*wh_Adj; @@ -371,7 +370,7 @@ public class CardImageRenderer { g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); else { g.drawRotatedImage(FSkin.getBorders().get(0), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image, fullborder), new_x+radius/2-minusxy, new_y+radius/2-minusxy, new_w*croppedArea, new_h*croppedArea, (new_x+radius/2-minusxy) + (new_w*croppedArea) / 2, (new_y+radius/2-minusxy) + (new_h*croppedArea) / 2, -90); + g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x+radius/2-minusxy, new_y+radius/2-minusxy, new_w*croppedArea, new_h*croppedArea, (new_x+radius/2-minusxy) + (new_w*croppedArea) / 2, (new_y+radius/2-minusxy) + (new_h*croppedArea) / 2, -90); } } else g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); @@ -382,7 +381,7 @@ public class CardImageRenderer { g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); else { g.drawRotatedImage(FSkin.getBorders().get(ImageCache.getFSkinBorders(card)), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image, fullborder), new_x + radius / 2-minusxy, new_y + radius / 2-minusxy, new_w * croppedArea, new_h * croppedArea, (new_x + radius / 2-minusxy) + (new_w * croppedArea) / 2, (new_y + radius / 2-minusxy) + (new_h * croppedArea) / 2, isAftermath ? 90 : -90); + g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x + radius / 2-minusxy, new_y + radius / 2-minusxy, new_w * croppedArea, new_h * croppedArea, (new_x + radius / 2-minusxy) + (new_w * croppedArea) / 2, (new_y + radius / 2-minusxy) + (new_h * croppedArea) / 2, isAftermath ? 90 : -90); } } else g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); @@ -391,8 +390,8 @@ public class CardImageRenderer { if (ImageCache.isExtendedArt(card)) g.drawImage(image, x, y, w, h); else { - g.drawImage(ImageCache.getBorderImage(card, canshow), x, y, w, h); - g.drawImage(ImageCache.croppedBorderImage(image, fullborder), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); + g.drawImage(ImageCache.getBorderImage(image, canshow), x, y, w, h); + g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); } } else { if (canshow) diff --git a/forge-gui-mobile/src/forge/card/CardRenderer.java b/forge-gui-mobile/src/forge/card/CardRenderer.java index 46133714499..213e200db7d 100644 --- a/forge-gui-mobile/src/forge/card/CardRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardRenderer.java @@ -459,13 +459,12 @@ public class CardRenderer { if (image == ImageCache.defaultImage) { CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos); } else { - boolean fullborder = image.toString().contains(".fullborder."); if (Forge.enableUIMask) { if (ImageCache.isExtendedArt(pc)) g.drawImage(image, x, y, w, h); else { - g.drawImage(ImageCache.getBorderImage(pc), x, y, w, h); - g.drawImage(ImageCache.croppedBorderImage(image, fullborder), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); + g.drawImage(ImageCache.getBorderImage(image), x, y, w, h); + g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); } } else g.drawImage(image, x, y, w, h); @@ -499,7 +498,6 @@ public class CardRenderer { if (image == ImageCache.defaultImage) { CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos); } else { - boolean fullborder = image.toString().contains(".fullborder."); if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON) && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()) && rotate){ if (Forge.enableUIMask) { @@ -507,7 +505,7 @@ public class CardRenderer { g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); else { g.drawRotatedImage(FSkin.getBorders().get(0), x, y, w, h, x + w / 2, y + h / 2, -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image, fullborder), x+radius/2.3f-minusxy, y+radius/2-minusxy, w*croppedArea, h*croppedArea, (x+radius/2.3f-minusxy) + (w*croppedArea) / 2, (y+radius/2-minusxy) + (h*croppedArea) / 2, -90); + g.drawRotatedImage(ImageCache.croppedBorderImage(image), x+radius/2.3f-minusxy, y+radius/2-minusxy, w*croppedArea, h*croppedArea, (x+radius/2.3f-minusxy) + (w*croppedArea) / 2, (y+radius/2-minusxy) + (h*croppedArea) / 2, -90); } } else g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); @@ -517,8 +515,8 @@ public class CardRenderer { g.drawImage(image, x, y, w, h); else { boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors(); - g.drawBorderImage(ImageCache.getBorderImage(card, canshow), ImageCache.getTint(card), x, y, w, h, t); //tint check for changed colors - g.drawImage(ImageCache.croppedBorderImage(image, fullborder), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); + g.drawBorderImage(ImageCache.getBorderImage(image, canshow), ImageCache.getTint(card), x, y, w, h, t); //tint check for changed colors + g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); } } else { if (canshow)