Also render tokens and emblems when not using images

This commit is contained in:
Lyu Zong-Hong
2021-07-27 12:10:26 +09:00
parent d8dfbcf1a3
commit 5f39b98cc5
5 changed files with 54 additions and 32 deletions

View File

@@ -6,6 +6,7 @@ import forge.card.CardDb;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardSplitType; import forge.card.CardSplitType;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.item.PaperToken;
public class ImageUtil { public class ImageUtil {
public static float getNearestHQSize(float baseSize, float actualSize) { public static float getNearestHQSize(float baseSize, float actualSize) {
@@ -29,6 +30,24 @@ public class ImageUtil {
return cp; return cp;
} }
public static PaperToken getPaperTokenFromImageKey(String key) {
if ( key == null ) {
return null;
}
key = key.substring(2);
int index = key.lastIndexOf('_');
if (index != -1) {
String script = key.substring(0, index);
String edition = key.substring(index + 1);
if (script.startsWith("emblem"))
return null;
script = script.replaceAll("[0-9]*$", "");
return StaticData.instance().getAllTokens().getToken(script, edition);
}
return null;
}
public static String getImageRelativePath(PaperCard cp, boolean backFace, boolean includeSet, boolean isDownloadUrl) { public static String getImageRelativePath(PaperCard cp, boolean backFace, boolean includeSet, boolean isDownloadUrl) {
final String nameToUse = cp == null ? null : getNameToUse(cp, backFace); final String nameToUse = cp == null ? null : getNameToUse(cp, backFace);
if (nameToUse == null) { if (nameToUse == null) {

View File

@@ -38,9 +38,11 @@ import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.mortennobel.imagescaling.ResampleOp; import com.mortennobel.imagescaling.ResampleOp;
import forge.game.card.Card;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.gui.FThreads; import forge.gui.FThreads;
import forge.item.IPaperCard;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.localinstance.properties.ForgeConstants; import forge.localinstance.properties.ForgeConstants;
@@ -144,21 +146,24 @@ public class ImageCache {
* the image from file (slower) and then add it to the cache for fast future access. * the image from file (slower) and then add it to the cache for fast future access.
* </p> * </p>
*/ */
public static BufferedImage getOriginalImage(String imageKey, boolean useDefaultIfNotFound) { public static BufferedImage getOriginalImage(String imageKey, boolean useDefaultIfNotFound, CardView cardView) {
if (null == imageKey) { if (null == imageKey) {
return null; return null;
} }
PaperCard pc = null; IPaperCard ipc = null;
boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX); boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX);
if(altState) if(altState)
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length()); imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) { if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) {
pc = ImageUtil.getPaperCardFromImageKey(imageKey); PaperCard pc = ImageUtil.getPaperCardFromImageKey(imageKey);
ipc = pc;
imageKey = ImageUtil.getImageKey(pc, altState, true); imageKey = ImageUtil.getImageKey(pc, altState, true);
if (StringUtils.isBlank(imageKey)) { if (StringUtils.isBlank(imageKey)) {
return _defaultImage; return _defaultImage;
} }
} else if (imageKey.startsWith(ImageKeys.TOKEN_PREFIX)) {
ipc = ImageUtil.getPaperTokenFromImageKey(imageKey);
} }
// Load from file and add to cache if not found in cache initially. // Load from file and add to cache if not found in cache initially.
@@ -202,9 +207,10 @@ public class ImageCache {
// a default "not available" image, however do not add it to the cache, // a default "not available" image, however do not add it to the cache,
// as otherwise it's problematic to update if the real image gets fetched. // as otherwise it's problematic to update if the real image gets fetched.
if (original == null && useDefaultIfNotFound) { if (original == null && useDefaultIfNotFound) {
if (pc != null) { if (ipc != null || cardView != null) {
CardView card = ipc != null ? Card.getCardForUi(ipc).getView() : cardView;
original = new BufferedImage(480, 680, BufferedImage.TYPE_INT_ARGB); original = new BufferedImage(480, 680, BufferedImage.TYPE_INT_ARGB);
FCardImageRenderer.drawCardImage(original.createGraphics(), pc, altState, 480, 680); FCardImageRenderer.drawCardImage(original.createGraphics(), card, altState, 480, 680);
if (!isPreferenceEnabled(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER)) if (!isPreferenceEnabled(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER))
_CACHE.put(imageKey, original); _CACHE.put(imageKey, original);
} else { } else {
@@ -229,7 +235,7 @@ public class ImageCache {
return cached; return cached;
} }
BufferedImage original = getOriginalImage(key, useDefaultImage); BufferedImage original = getOriginalImage(key, useDefaultImage, null);
if (original == null) { return null; } if (original == null) { return null; }
if (original == _defaultImage) { if (original == _defaultImage) {

View File

@@ -105,19 +105,19 @@ public final class CardPicturePanel extends JPanel implements ImageFetcher.Callb
private BufferedImage getImage() { private BufferedImage getImage() {
if (!mayView) { if (!mayView) {
return ImageCache.getOriginalImage(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD), true); return ImageCache.getOriginalImage(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD), true, null);
} }
if (displayed instanceof InventoryItem) { if (displayed instanceof InventoryItem) {
final InventoryItem item = (InventoryItem) displayed; final InventoryItem item = (InventoryItem) displayed;
BufferedImage image = ImageCache.getOriginalImage(item.getImageKey(false), true); BufferedImage image = ImageCache.getOriginalImage(item.getImageKey(false), true, null);
if (ImageCache.isDefaultImage(image) && item instanceof PaperCard) { if (ImageCache.isDefaultImage(image) && item instanceof PaperCard) {
GuiBase.getInterface().getImageFetcher().fetchImage(item.getImageKey(false), this); GuiBase.getInterface().getImageFetcher().fetchImage(item.getImageKey(false), this);
} }
return image; return image;
} else if (displayed instanceof CardStateView) { } else if (displayed instanceof CardStateView) {
CardStateView card = (CardStateView) displayed; CardStateView card = (CardStateView) displayed;
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), false); BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), false, card.getCard());
if (image == null) { if (image == null) {
GuiBase.getInterface().getImageFetcher().fetchImage(card.getImageKey(), this); GuiBase.getInterface().getImageFetcher().fetchImage(card.getImageKey(), this);
} }

View File

@@ -22,12 +22,10 @@ import org.apache.commons.lang3.StringUtils;
import forge.card.CardRarity; import forge.card.CardRarity;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.card.Card;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.card.CardView.CardStateView; import forge.game.card.CardView.CardStateView;
import forge.gui.card.CardDetailUtil; import forge.gui.card.CardDetailUtil;
import forge.gui.card.CardDetailUtil.DetailColors; import forge.gui.card.CardDetailUtil.DetailColors;
import forge.item.PaperCard;
import forge.localinstance.properties.ForgePreferences.FPref; import forge.localinstance.properties.ForgePreferences.FPref;
import forge.localinstance.skin.FSkinProp; import forge.localinstance.skin.FSkinProp;
import forge.model.FModel; import forge.model.FModel;
@@ -148,8 +146,7 @@ public class FCardImageRenderer {
prevImageHeight = h; prevImageHeight = h;
} }
public static void drawCardImage(Graphics2D g, PaperCard pc, boolean altState, int width, int height) { public static void drawCardImage(Graphics2D g, CardView card, boolean altState, int width, int height) {
final CardView card = Card.getCardForUi(pc).getView();
float x = 0, y = 0, w = width, h = height; float x = 0, y = 0, w = width, h = height;
updateStaticFields(g, w, h); updateStaticFields(g, w, h);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

View File

@@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -37,10 +37,10 @@ import forge.toolbox.FSkin.SkinIcon;
import forge.util.ImageUtil; import forge.util.ImageUtil;
/** /**
* Common image-related routines specific to Forge images. * Common image-related routines specific to Forge images.
* *
* @version $Id: FImageUtil.java 25265 2014-03-27 02:18:47Z drdev $ * @version $Id: FImageUtil.java 25265 2014-03-27 02:18:47Z drdev $
* *
*/ */
public final class FImageUtil { public final class FImageUtil {
@@ -52,12 +52,12 @@ public final class FImageUtil {
* Adds a random foil effect if enabled. * Adds a random foil effect if enabled.
* <p> * <p>
* For double-sided cards, returns the front-side image.<br> * For double-sided cards, returns the front-side image.<br>
* For flip cards, returns the un-flipped image. * For flip cards, returns the un-flipped image.
*/ */
public static BufferedImage getImage(final CardStateView card) { public static BufferedImage getImage(final CardStateView card) {
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), true); BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), true, card.getCard());
final int foilIndex = card.getFoilIndex(); final int foilIndex = card.getFoilIndex();
if (image != null && foilIndex > 0) { if (image != null && foilIndex > 0) {
image = getImageWithFoilEffect(image, foilIndex); image = getImageWithFoilEffect(image, foilIndex);
} }
return image; return image;
@@ -126,39 +126,39 @@ public final class FImageUtil {
BufferedImage foilImage = new BufferedImage(cm, plainImage.copyData(null), cm.isAlphaPremultiplied(), null); BufferedImage foilImage = new BufferedImage(cm, plainImage.copyData(null), cm.isAlphaPremultiplied(), null);
final String fl = String.format("foil%02d", foilIndex); final String fl = String.format("foil%02d", foilIndex);
CardFaceSymbols.drawOther(foilImage.getGraphics(), fl, 0, 0, foilImage.getWidth(), foilImage.getHeight()); CardFaceSymbols.drawOther(foilImage.getGraphics(), fl, 0, 0, foilImage.getWidth(), foilImage.getHeight());
return foilImage; return foilImage;
} }
public static SkinIcon getMenuIcon(SkinIcon sourceIcon) { public static SkinIcon getMenuIcon(SkinIcon sourceIcon) {
return sourceIcon.resize(16, 16); return sourceIcon.resize(16, 16);
} }
/** /**
* Gets the nearest rotation for a requested rotation. * Gets the nearest rotation for a requested rotation.
* <p> * <p>
* For example, if {@code nearestRotation} is set to 90 degrees then * For example, if {@code nearestRotation} is set to 90 degrees then
* will return one of 0, 90, 180 or 270 degrees, whichever is nearest to * will return one of 0, 90, 180 or 270 degrees, whichever is nearest to
* {@code requestedRotation}. * {@code requestedRotation}.
* *
*/ */
public static int getRotationToNearest(int requestedRotation, int nearestRotation) { public static int getRotationToNearest(int requestedRotation, int nearestRotation) {
// Ensure requested rotation falls within -360..0..360 degree range first. // Ensure requested rotation falls within -360..0..360 degree range first.
requestedRotation = requestedRotation - (360 * (requestedRotation / 360)); requestedRotation = requestedRotation - (360 * (requestedRotation / 360));
return (int)(Math.rint((double) requestedRotation / nearestRotation) * nearestRotation); return (int)(Math.rint((double) requestedRotation / nearestRotation) * nearestRotation);
} }
/** /**
* Calculates the scale required to best fit contained into container * Calculates the scale required to best fit contained into container
* whilst retaining the aspect ratio. * whilst retaining the aspect ratio.
*/ */
public static double getBestFitScale(int containedW, int containedH, int containerW, int containerH) { public static double getBestFitScale(int containedW, int containedH, int containerW, int containerH) {
double scaleX = (double)containerW / containedW; double scaleX = (double)containerW / containedW;
double scaleY = (double)containerH / containedH; double scaleY = (double)containerH / containedH;
return Math.min(scaleX, scaleY); return Math.min(scaleX, scaleY);
} }
/** /**
* Calculates the scale required to best fit contained into container * Calculates the scale required to best fit contained into container
* whilst retaining the aspect ratio. * whilst retaining the aspect ratio.
*/ */
public static double getBestFitScale(Dimension contained, Dimension container) { public static double getBestFitScale(Dimension contained, Dimension container) {