mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
Face down images and cards rework (#11873)
Face down changes: * GUI: added visible face down type and real card name for controller/owner (opponent can see it after game ends); * GUI: added day/night button to view real card for controller/owner (opponent can see it after game ends); * game: fixed that faced-down card can render symbols, abilities and other hidden data from a real card; * images: added image support for normal faced-down cards; * images: added image support for morph and megamorph faced-down cards; * images: added image support for foretell faced-down cards; Other changes: * images: fixed missing tokens from DDD set; * images: no more client restart to apply newly downloaded images or render settings; * images: improved backface image quality (use main menu -> symbols to download it);
This commit is contained in:
parent
4901de12c1
commit
e38a79f231
104 changed files with 2178 additions and 1495 deletions
|
|
@ -1517,7 +1517,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
public void setConnectButtonText(String status) {
|
||||
this.btnConnect.setText(status);
|
||||
changeGUISize(); // Needed to layout the tooltbar after text length change
|
||||
|
||||
// Needed to layout the tooltbar after text length change
|
||||
// TODO: need research, is it actual?
|
||||
GUISizeHelper.refreshGUIAndCards();
|
||||
|
||||
this.btnConnect.repaint();
|
||||
this.btnConnect.revalidate();
|
||||
}
|
||||
|
|
@ -1741,8 +1745,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
}
|
||||
|
||||
public void changeGUISize() {
|
||||
ImageCaches.flush();
|
||||
/**
|
||||
* Refresh whole GUI including cards and card images.
|
||||
* Use it after new images downloaded, new fonts or theme settings selected.
|
||||
*/
|
||||
public void refreshGUIAndCards() {
|
||||
ImageCaches.clearAll();
|
||||
|
||||
setGUISize();
|
||||
|
||||
setGUISizeTooltipContainer();
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ public class MageRoundPane extends JPanel {
|
|||
private int Y_OFFSET = 30;
|
||||
private final Color defaultBackgroundColor = new Color(141, 130, 112, 200); // color of the frame of the popup window
|
||||
private Color backgroundColor = defaultBackgroundColor;
|
||||
private static final SoftValuesLoadingCache<ShadowKey, BufferedImage> SHADOW_IMAGE_CACHE;
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> IMAGE_CACHE;
|
||||
private static final SoftValuesLoadingCache<ShadowKey, BufferedImage> ROUND_PANEL_SHADOW_IMAGES_CACHE;
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> ROUND_PANEL_IMAGES_CACHE;
|
||||
|
||||
static {
|
||||
SHADOW_IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(MageRoundPane::createShadowImage));
|
||||
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(MageRoundPane::createImage));
|
||||
ROUND_PANEL_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(MageRoundPane::createImage));
|
||||
ROUND_PANEL_SHADOW_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(MageRoundPane::createShadowImage));
|
||||
}
|
||||
|
||||
private static final class ShadowKey {
|
||||
|
|
@ -132,7 +132,7 @@ public class MageRoundPane extends JPanel {
|
|||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.drawImage(IMAGE_CACHE.getOrThrow(new Key(getWidth(), getHeight(), X_OFFSET, Y_OFFSET, backgroundColor)), 0, 0, null);
|
||||
g.drawImage(ROUND_PANEL_IMAGES_CACHE.getOrThrow(new Key(getWidth(), getHeight(), X_OFFSET, Y_OFFSET, backgroundColor)), 0, 0, null);
|
||||
}
|
||||
|
||||
private static BufferedImage createImage(Key key) {
|
||||
|
|
@ -146,7 +146,7 @@ public class MageRoundPane extends JPanel {
|
|||
Graphics2D g2 = image.createGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
BufferedImage shadow = SHADOW_IMAGE_CACHE.getOrThrow(new ShadowKey(w, h));
|
||||
BufferedImage shadow = ROUND_PANEL_SHADOW_IMAGES_CACHE.getOrThrow(new ShadowKey(w, h));
|
||||
|
||||
{
|
||||
int xOffset = (shadow.getWidth() - w) / 2;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import mage.client.util.audio.AudioManager;
|
|||
import mage.client.util.sets.ConstructedFormats;
|
||||
import mage.components.ImagePanel;
|
||||
import mage.components.ImagePanelStyle;
|
||||
import mage.constants.MageObjectType;
|
||||
import mage.game.command.Dungeon;
|
||||
import mage.game.command.Emblem;
|
||||
import mage.game.command.Plane;
|
||||
|
|
@ -396,7 +397,7 @@ public class MageBook extends JComponent {
|
|||
draftRating.setBounds(rectangle.x, rectangle.y + cardImg.getCardLocation().getCardHeight() + dy, cardDimensions.getFrameWidth(), 20);
|
||||
draftRating.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
draftRating.setFont(jLayeredPane.getFont().deriveFont(jLayeredPane.getFont().getStyle() | Font.BOLD));
|
||||
if (card.isOriginalACard()) {
|
||||
if (card.getMageObjectType().equals(MageObjectType.CARD)) {
|
||||
// card
|
||||
draftRating.setText("draft rating: " + RateCard.rateCard(card, null));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ public class MageCardComparator implements CardViewComparator {
|
|||
bCom = RateCard.rateCard(b, null);
|
||||
break;
|
||||
case 10:
|
||||
aCom = a.getColorIdentityStr();
|
||||
bCom = b.getColorIdentityStr();
|
||||
aCom = a.getOriginalColorIdentity();
|
||||
bCom = b.getOriginalColorIdentity();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
|
|||
case 9:
|
||||
return RateCard.rateCard(c, null);
|
||||
case 10:
|
||||
return ManaSymbols.getClearManaCost(c.getColorIdentityStr());
|
||||
return ManaSymbols.getClearManaCost(c.getOriginalColorIdentity());
|
||||
default:
|
||||
return "error";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2928,8 +2928,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
save(prefs, dialog.sliderCardSizeMinBattlefield, KEY_GUI_CARD_BATTLEFIELD_MIN_SIZE, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.sliderCardSizeMaxBattlefield, KEY_GUI_CARD_BATTLEFIELD_MAX_SIZE, "true", "false", UPDATE_CACHE_POLICY);
|
||||
|
||||
// do as worker job
|
||||
GUISizeHelper.changeGUISize();
|
||||
// refresh full GUI with new settings
|
||||
GUISizeHelper.refreshGUIAndCards();
|
||||
}
|
||||
|
||||
private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitButtonActionPerformed
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package mage.client.dialog;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.abilities.icon.*;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.*;
|
||||
|
|
@ -184,6 +185,18 @@ public class TestCardRenderDialog extends MageDialog {
|
|||
if (perm.isTransformable()) {
|
||||
perm.setTransformed(true);
|
||||
}
|
||||
|
||||
// workaround to apply face down image and other settings
|
||||
if (perm.isFaceDown(game)) {
|
||||
BecomesFaceDownCreatureEffect.makeFaceDownObject(
|
||||
game,
|
||||
null,
|
||||
perm,
|
||||
BecomesFaceDownCreatureEffect.findFaceDownType(game, perm),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
PermanentView cardView = new PermanentView(perm, permCard, controllerId, game);
|
||||
cardView.setInViewerOnly(false); // must false for face down
|
||||
return cardView;
|
||||
|
|
@ -386,9 +399,9 @@ public class TestCardRenderDialog extends MageDialog {
|
|||
|
||||
List<CardView> cardViews = new ArrayList<>();
|
||||
|
||||
/* test morphed
|
||||
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "263", 0, 0, 0, false, null)); // mountain
|
||||
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "185", 0, 0, 0, true, null)); // Judith, the Scourge Diva
|
||||
//* test face down
|
||||
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "263", 0, 0, 0, false, false, null)); // mountain
|
||||
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "185", 0, 0, 0, true, false, null)); // Judith, the Scourge Diva
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "DIS", "153")); // Odds // Ends (split card)
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "ELD", "38")); // Animating Faerie (adventure card)
|
||||
cardViews.add(createFaceDownCard(game, playerOpponent.getId(), "ELD", "38", false, false, false)); // face down
|
||||
|
|
@ -414,7 +427,7 @@ public class TestCardRenderDialog extends MageDialog {
|
|||
cardViews.add(createHandCard(game, playerYou.getId(), "AKH", "210")); // Dusk // Dawn
|
||||
//*/
|
||||
|
||||
//* test adventure cards in hands
|
||||
/* test adventure cards in hands
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "ELD", "14")); // Giant Killer
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "WOE", "222")); // Cruel Somnophage
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "WOE", "227")); // Gingerbread Hunter
|
||||
|
|
@ -430,7 +443,7 @@ public class TestCardRenderDialog extends MageDialog {
|
|||
cardViews.add(createHandCard(game, playerYou.getId(), "MKM", "155")); // Case of the Locked Hothouse
|
||||
//*/
|
||||
|
||||
//* test case, class and saga cards in hands
|
||||
/* test case, class and saga cards in hands
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "MKM", "113")); // Case of the Burning Masks
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "MKM", "155")); // Case of the Locked Hothouse
|
||||
cardViews.add(createHandCard(game, playerYou.getId(), "AFR", "6")); // Cleric Class
|
||||
|
|
@ -504,7 +517,7 @@ public class TestCardRenderDialog extends MageDialog {
|
|||
PermanentView oldPermanent = (PermanentView) main.getGameCard();
|
||||
PermanentView newPermament = new PermanentView(
|
||||
oldPermanent,
|
||||
game.getCard(oldPermanent.getOriginalId()),
|
||||
game.getCard(oldPermanent.getId()),
|
||||
UUID.randomUUID(),
|
||||
game
|
||||
);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public class MageActionCallback implements ActionCallback {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e, TransferData data, boolean doubleClick) {
|
||||
public void mouseClicked(MouseEvent e, TransferData data, boolean doubleClick) {
|
||||
// send mouse clicked event to the card's area and other cards list components for processing
|
||||
if (e.isConsumed()) {
|
||||
return;
|
||||
|
|
@ -720,7 +720,7 @@ public class MageActionCallback implements ActionCallback {
|
|||
switch (enlargeMode) {
|
||||
case COPY:
|
||||
if (cardView instanceof PermanentView) {
|
||||
image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()).getImage();
|
||||
image = ImageCache.getCardImageOriginal(((PermanentView) cardView).getOriginal()).getImage();
|
||||
}
|
||||
break;
|
||||
case ALTERNATE:
|
||||
|
|
@ -729,10 +729,14 @@ public class MageActionCallback implements ActionCallback {
|
|||
&& !cardView.isFlipCard()
|
||||
&& !cardView.canTransform()
|
||||
&& ((PermanentView) cardView).isCopy()) {
|
||||
image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()).getImage();
|
||||
image = ImageCache.getCardImageOriginal(((PermanentView) cardView).getOriginal()).getImage();
|
||||
} else {
|
||||
image = ImageCache.getImageOriginalAlternateName(cardView).getImage();
|
||||
image = ImageCache.getCardImageAlternate(cardView).getImage();
|
||||
displayCard = displayCard.getSecondCardFace();
|
||||
if (displayCard == null) {
|
||||
// opponent's face down cards are hidden, so no alternative
|
||||
displayCard = cardPanel.getOriginal();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -745,7 +749,6 @@ public class MageActionCallback implements ActionCallback {
|
|||
} else {
|
||||
logger.warn("No Card preview Pane in Mage Frame defined. Card: " + cardView.getName());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.warn("Problem dring display of enlarged card", e);
|
||||
}
|
||||
|
|
@ -786,6 +789,7 @@ public class MageActionCallback implements ActionCallback {
|
|||
|
||||
private void displayCardInfo(CardView card, Image image, BigCard bigCard) {
|
||||
if (image instanceof BufferedImage) {
|
||||
// IMAGE MODE
|
||||
// XXX: scaled to fit width
|
||||
bigCard.setCard(card.getId(), enlargeMode, image, card.getRules(), card.isToRotate());
|
||||
// if it's an ability, show only the ability text as overlay
|
||||
|
|
@ -795,6 +799,7 @@ public class MageActionCallback implements ActionCallback {
|
|||
bigCard.hideTextComponent();
|
||||
}
|
||||
} else {
|
||||
// TEXT MODE
|
||||
JXPanel panel = GuiDisplayUtil.getDescription(card, bigCard.getWidth(), bigCard.getHeight());
|
||||
panel.setVisible(true);
|
||||
bigCard.hideTextComponent();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ package mage.client.themes;
|
|||
|
||||
import mage.abilities.hint.HintUtils;
|
||||
import mage.abilities.icon.CardIconColor;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.ImageCaches;
|
||||
import org.mage.card.arcane.SvgUtils;
|
||||
import org.mage.plugins.card.images.ImageCache;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
|
|
@ -350,6 +351,6 @@ public enum ThemeType {
|
|||
}
|
||||
|
||||
// reload card icons and other rendering things from cache - it can depend on current theme
|
||||
ImageCache.clearCache();
|
||||
GUISizeHelper.refreshGUIAndCards();
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
*/
|
||||
public final class CardsViewUtil {
|
||||
|
||||
|
|
|
|||
|
|
@ -84,9 +84,11 @@ public final class GUISizeHelper {
|
|||
return new Font("Arial", Font.PLAIN, 14);
|
||||
}
|
||||
|
||||
public static void changeGUISize() {
|
||||
public static void refreshGUIAndCards() {
|
||||
calculateGUISizes();
|
||||
MageFrame.getInstance().changeGUISize();
|
||||
if (MageFrame.getInstance() != null) {
|
||||
MageFrame.getInstance().refreshGUIAndCards();
|
||||
}
|
||||
}
|
||||
|
||||
public static void calculateGUISizes() {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
package mage.client.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* GUI: collect info about all used image caches, so it can be cleared from a single place
|
||||
*
|
||||
* @author draxdyn
|
||||
*/
|
||||
|
|
@ -22,7 +22,11 @@ public final class ImageCaches {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static void flush() {
|
||||
/**
|
||||
* Global method to clear all images cache.
|
||||
* Warning, GUI must be refreshed too for card updates, so use GUISizeHelper.refreshGUIAndCards instead
|
||||
*/
|
||||
public static void clearAll() {
|
||||
for (Cache<?, ?> map : IMAGE_CACHES) {
|
||||
map.invalidateAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,11 +55,10 @@ public final class TransformedImageCache {
|
|||
}
|
||||
}
|
||||
|
||||
private static final SoftValuesLoadingCache<Key, SoftValuesLoadingCache<BufferedImage, BufferedImage>> IMAGE_CACHE;
|
||||
private static final SoftValuesLoadingCache<Key, SoftValuesLoadingCache<BufferedImage, BufferedImage>> TRANSFORMED_IMAGES_CACHE;
|
||||
|
||||
static {
|
||||
// TODO: can we use a single map?
|
||||
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(TransformedImageCache::createTransformedImageCache));
|
||||
TRANSFORMED_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(TransformedImageCache::createTransformedImageCache));
|
||||
}
|
||||
|
||||
private static SoftValuesLoadingCache<BufferedImage, BufferedImage> createTransformedImageCache(Key key) {
|
||||
|
|
@ -139,6 +138,6 @@ public final class TransformedImageCache {
|
|||
if (resHeight < 3) {
|
||||
resHeight = 3;
|
||||
}
|
||||
return IMAGE_CACHE.getOrThrow(new Key(resWidth, resHeight, angle)).getOrThrow(image);
|
||||
return TRANSFORMED_IMAGES_CACHE.getOrThrow(new Key(resWidth, resHeight, angle)).getOrThrow(image);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ public abstract class CardPanel extends MagePermanent implements ComponentListen
|
|||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) (g.create());
|
||||
|
||||
// Deferr to subclasses
|
||||
// Defer to subclasses
|
||||
paintCard(g2d);
|
||||
|
||||
// Done, dispose of the context
|
||||
|
|
@ -854,7 +854,7 @@ public abstract class CardPanel extends MagePermanent implements ComponentListen
|
|||
// VIEW mode (user can change card side at any time by n/d button)
|
||||
this.guiTransformed = !this.guiTransformed;
|
||||
|
||||
if (dayNightButton != null) { // if transformbable card is copied, button can be null
|
||||
if (dayNightButton != null) { // if transformable card is copied, button can be null
|
||||
BufferedImage image = this.isTransformed() ? ImageManagerImpl.instance.getNightImage() : ImageManagerImpl.instance.getDayImage();
|
||||
dayNightButton.setIcon(new ImageIcon(image));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ import mage.constants.SubType;
|
|||
import mage.util.DebugUtil;
|
||||
import mage.view.CardView;
|
||||
import mage.view.CounterView;
|
||||
import mage.view.PermanentView;
|
||||
import mage.view.StackAbilityView;
|
||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||
import org.mage.plugins.card.images.ImageCache;
|
||||
import org.mage.plugins.card.images.ImageCacheData;
|
||||
|
|
@ -37,7 +35,7 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
|
||||
private static final long serialVersionUID = -3272134219262184411L;
|
||||
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelRenderModeImage::createImage));
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> IMAGE_MODE_RENDERED_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelRenderModeImage::createImage));
|
||||
|
||||
private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter
|
||||
|
||||
|
|
@ -472,11 +470,7 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
@Override
|
||||
public Image getImage() {
|
||||
if (this.hasImage) {
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage().getImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(getGameCard()).getImage();
|
||||
}
|
||||
return ImageCache.getCardImageOriginal(getGameCard()).getImage();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -492,7 +486,7 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
// draw background (selected/chooseable/playable)
|
||||
MageCardLocation cardLocation = getCardLocation();
|
||||
g2d.drawImage(
|
||||
IMAGE_CACHE.getOrThrow(
|
||||
IMAGE_MODE_RENDERED_CACHE.getOrThrow(
|
||||
new Key(getInsets(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
|
|
@ -640,14 +634,9 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
|
||||
Util.threadPool.submit(() -> {
|
||||
try {
|
||||
final ImageCacheData data;
|
||||
if (getGameCard().isFaceDown()) {
|
||||
data = getFaceDownImage();
|
||||
} else {
|
||||
data = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight());
|
||||
}
|
||||
ImageCacheData data = ImageCache.getCardImage(getGameCard(), getCardWidth(), getCardHeight());
|
||||
|
||||
// show path on miss image
|
||||
// save missing image
|
||||
if (data.getImage() == null) {
|
||||
setFullPath(data.getPath());
|
||||
}
|
||||
|
|
@ -665,21 +654,6 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
});
|
||||
}
|
||||
|
||||
private ImageCacheData getFaceDownImage() {
|
||||
// TODO: add download default images
|
||||
if (isPermanent() && getGameCard() instanceof PermanentView) {
|
||||
if (((PermanentView) getGameCard()).isMorphed()) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.getManifestImage();
|
||||
}
|
||||
} else if (this.getGameCard() instanceof StackAbilityView) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.getCardbackImage();
|
||||
}
|
||||
}
|
||||
|
||||
private int getManaWidth(String manaCost, int symbolMarginX) {
|
||||
int width = 0;
|
||||
manaCost = manaCost.replace("\\", "");
|
||||
|
|
|
|||
|
|
@ -3,46 +3,40 @@ package org.mage.card.arcane;
|
|||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import mage.cards.action.ActionCallback;
|
||||
import mage.client.util.ImageCaches;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.view.CardView;
|
||||
import mage.view.CounterView;
|
||||
import mage.view.PermanentView;
|
||||
import mage.view.StackAbilityView;
|
||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||
import org.mage.plugins.card.images.ImageCache;
|
||||
import org.mage.plugins.card.images.ImageCacheData;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Render mode: MTGO
|
||||
*
|
||||
*/
|
||||
public class CardPanelRenderModeMTGO extends CardPanel {
|
||||
|
||||
//
|
||||
// https://www.mtg.onl/evolution-of-magic-token-card-frame-design/
|
||||
|
||||
// Map of generated images
|
||||
private static final Cache<ImageKey, BufferedImage> IMAGE_CACHE = CacheBuilder
|
||||
.newBuilder()
|
||||
.maximumSize(3000)
|
||||
.expireAfterAccess(60, TimeUnit.MINUTES)
|
||||
.softValues()
|
||||
.build();
|
||||
private static final Cache<ImageKey, BufferedImage> MTGO_MODE_RENDERED_CACHE = ImageCaches.register(
|
||||
CacheBuilder
|
||||
.newBuilder()
|
||||
.maximumSize(3000)
|
||||
.expireAfterAccess(60, TimeUnit.MINUTES)
|
||||
.softValues()
|
||||
.build()
|
||||
);
|
||||
|
||||
// The art image for the card, loaded in from the disk
|
||||
private BufferedImage artImage;
|
||||
|
||||
// The faceart image for the card, loaded in from the disk (based on artid from mtgo)
|
||||
private BufferedImage faceArtImage;
|
||||
|
||||
// Factory to generate card appropriate views
|
||||
private final CardRendererFactory cardRendererFactory = new CardRendererFactory();
|
||||
|
||||
|
|
@ -161,11 +155,7 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
if (artImage == null) {
|
||||
return null;
|
||||
}
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage().getImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(getGameCard()).getImage();
|
||||
}
|
||||
return ImageCache.getCardImageOriginal(getGameCard()).getImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -173,16 +163,21 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
// Render the card if we don't have an image ready to use
|
||||
if (cardImage == null) {
|
||||
// Try to get card image from cache based on our card characteristics
|
||||
ImageKey key = new ImageKey(getGameCard(), artImage,
|
||||
getCardWidth(), getCardHeight(),
|
||||
isChoosable(), isSelected(), isTransformed());
|
||||
ImageKey key = new ImageKey(
|
||||
getGameCard(),
|
||||
artImage,
|
||||
getCardWidth(),
|
||||
getCardHeight(),
|
||||
isChoosable(),
|
||||
isSelected(),
|
||||
isTransformed()
|
||||
);
|
||||
try {
|
||||
cardImage = IMAGE_CACHE.get(key, this::renderCard);
|
||||
} catch (ExecutionException e) {
|
||||
cardImage = MTGO_MODE_RENDERED_CACHE.get(key, this::renderCard);
|
||||
} catch (Exception e) {
|
||||
// TODO: research and replace with logs, message and backface image
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// No cached copy exists? Render one and cache it
|
||||
}
|
||||
|
||||
// And draw the image we now have
|
||||
|
|
@ -237,8 +232,6 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
// Use the art image and current rendered image from the card
|
||||
artImage = impl.artImage;
|
||||
cardRenderer.setArtImage(artImage);
|
||||
faceArtImage = impl.faceArtImage;
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
cardImage = impl.cardImage;
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +245,6 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
cardImage = null;
|
||||
cardRenderer = cardRendererFactory.create(getGameCard());
|
||||
cardRenderer.setArtImage(artImage);
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
|
||||
// Repaint
|
||||
repaint();
|
||||
|
|
@ -264,7 +256,6 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
artImage = null;
|
||||
cardImage = null;
|
||||
cardRenderer.setArtImage(null);
|
||||
cardRenderer.setFaceArtImage(null);
|
||||
|
||||
// Stop animation
|
||||
setTappedAngle(isTapped() ? CardPanel.TAPPED_ANGLE : 0);
|
||||
|
|
@ -276,29 +267,18 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
// See if the image is already loaded
|
||||
//artImage = ImageCache.tryGetImage(gameCard, getCardWidth(), getCardHeight());
|
||||
//this.cardRenderer.setArtImage(artImage);
|
||||
|
||||
// Submit a task to draw with the card art when it arrives
|
||||
if (artImage == null) {
|
||||
final int stamp = ++updateArtImageStamp;
|
||||
Util.threadPool.submit(() -> {
|
||||
try {
|
||||
final BufferedImage srcImage;
|
||||
final BufferedImage faceArtSrcImage;
|
||||
if (getGameCard().isFaceDown()) {
|
||||
// Nothing to do
|
||||
srcImage = null;
|
||||
faceArtSrcImage = null;
|
||||
} else {
|
||||
srcImage = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight()).getImage();
|
||||
faceArtSrcImage = ImageCache.getFaceImage(getGameCard(), getCardWidth(), getCardHeight()).getImage();
|
||||
}
|
||||
|
||||
srcImage = ImageCache.getCardImage(getGameCard(), getCardWidth(), getCardHeight()).getImage();
|
||||
UI.invokeLater(() -> {
|
||||
if (stamp == updateArtImageStamp) {
|
||||
artImage = srcImage;
|
||||
cardRenderer.setArtImage(srcImage);
|
||||
faceArtImage = faceArtSrcImage;
|
||||
cardRenderer.setFaceArtImage(faceArtSrcImage);
|
||||
|
||||
if (srcImage != null) {
|
||||
// Invalidate and repaint
|
||||
cardImage = null;
|
||||
|
|
@ -317,21 +297,6 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
return new CardPanelAttributes(getCardWidth(), getCardHeight(), isChoosable(), isSelected(), isTransformed());
|
||||
}
|
||||
|
||||
private ImageCacheData getFaceDownImage() {
|
||||
// TODO: add download default images
|
||||
if (isPermanent() && getGameCard() instanceof PermanentView) {
|
||||
if (((PermanentView) getGameCard()).isMorphed()) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.getManifestImage();
|
||||
}
|
||||
} else if (this.getGameCard() instanceof StackAbilityView) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.getCardbackImage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the card to a new BufferedImage at it's current dimensions
|
||||
*
|
||||
|
|
|
|||
|
|
@ -55,10 +55,7 @@ public abstract class CardRenderer {
|
|||
protected final CardView cardView;
|
||||
|
||||
// The card image
|
||||
protected BufferedImage artImage;
|
||||
|
||||
// The face card image
|
||||
protected BufferedImage faceArtImage;
|
||||
protected BufferedImage artImage; // TODO: make sure it changed/reset on face down/up change
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Common layout metrics between all cards
|
||||
|
|
@ -206,7 +203,7 @@ public abstract class CardRenderer {
|
|||
}
|
||||
|
||||
// The Draw Method
|
||||
// The draw method takes the information caculated by the constructor
|
||||
// The draw method takes the information calculated by the constructor
|
||||
// and uses it to draw to a concrete size of card and graphics.
|
||||
public void draw(Graphics2D g, CardPanelAttributes attribs, BufferedImage image) {
|
||||
|
||||
|
|
@ -313,51 +310,6 @@ public abstract class CardRenderer {
|
|||
}
|
||||
|
||||
private boolean lessOpaqueRulesTextBox = false;
|
||||
protected void drawFaceArtIntoRect(Graphics2D g, int x, int y, int w, int h, int alternate_h, Rectangle2D artRect, boolean shouldPreserveAspect) {
|
||||
// Perform a process to make sure that the art is scaled uniformly to fill the frame, cutting
|
||||
// off the minimum amount necessary to make it completely fill the frame without "squashing" it.
|
||||
double fullCardImgWidth = faceArtImage.getWidth();
|
||||
double fullCardImgHeight = faceArtImage.getHeight();
|
||||
double artWidth = fullCardImgWidth;
|
||||
double artHeight = fullCardImgHeight;
|
||||
double targetWidth = w;
|
||||
double targetHeight = h;
|
||||
double targetAspect = targetWidth / targetHeight;
|
||||
if (!shouldPreserveAspect) {
|
||||
// No adjustment to art
|
||||
} else if (targetAspect * artHeight < artWidth) {
|
||||
// Trim off some width
|
||||
artWidth = targetAspect * artHeight;
|
||||
} else {
|
||||
// Trim off some height
|
||||
artHeight = artWidth / targetAspect;
|
||||
}
|
||||
try {
|
||||
/*BufferedImage subImg
|
||||
= faceArtImage.getSubimage(
|
||||
(int) (artRect.getX() * fullCardImgWidth), (int) (artRect.getY() * fullCardImgHeight),
|
||||
(int) artWidth, (int) artHeight);*/
|
||||
RenderingHints rh = new RenderingHints(
|
||||
RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g.setRenderingHints(rh);
|
||||
if (fullCardImgWidth > fullCardImgHeight) {
|
||||
g.drawImage(faceArtImage,
|
||||
x, y,
|
||||
(int) targetWidth, (int) targetHeight,
|
||||
null);
|
||||
} else {
|
||||
g.drawImage(faceArtImage,
|
||||
x, y,
|
||||
(int) targetWidth, alternate_h, // alernate_h is roughly (targetWidth / 0.74)
|
||||
null);
|
||||
lessOpaqueRulesTextBox = true;
|
||||
}
|
||||
} catch (RasterFormatException e) {
|
||||
// At very small card sizes we may encounter a problem with rounding error making the rect not fit
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw +1/+1 and other counters
|
||||
protected void drawCounters(Graphics2D g) {
|
||||
|
|
@ -532,10 +484,4 @@ public abstract class CardRenderer {
|
|||
public void setArtImage(Image image) {
|
||||
artImage = CardRendererUtils.toBufferedImage(image);
|
||||
}
|
||||
|
||||
// Set the card art image (CardPanel will give it to us when it
|
||||
// is loaded and ready)
|
||||
public void setFaceArtImage(Image image) {
|
||||
faceArtImage = CardRendererUtils.toBufferedImage(image);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class GlowText extends JLabel {
|
|||
private Color glowColor;
|
||||
private boolean wrap;
|
||||
private int lineCount = 0;
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> IMAGE_CACHE;
|
||||
private static final SoftValuesLoadingCache<Key, BufferedImage> GLOW_TEXT_IMAGES_CACHE;
|
||||
|
||||
private static final class Key {
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ public class GlowText extends JLabel {
|
|||
}
|
||||
|
||||
static {
|
||||
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(GlowText::createGlowImage));
|
||||
GLOW_TEXT_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(GlowText::createGlowImage));
|
||||
}
|
||||
|
||||
public void setGlow(Color glowColor, int size, float intensity) {
|
||||
|
|
@ -153,7 +153,7 @@ public class GlowText extends JLabel {
|
|||
}
|
||||
|
||||
public BufferedImage getGlowImage() {
|
||||
return IMAGE_CACHE.getOrThrow(new Key(getWidth(), getHeight(), getText(), getFont(), getForeground(), glowSize, glowIntensity, glowColor, wrap));
|
||||
return GLOW_TEXT_IMAGES_CACHE.getOrThrow(new Key(getWidth(), getHeight(), getText(), getFont(), getForeground(), glowSize, glowIntensity, glowColor, wrap));
|
||||
}
|
||||
|
||||
private static BufferedImage createGlowImage(Key key) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import mage.client.dialog.PreferencesDialog;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.MageObjectType;
|
||||
import mage.constants.SubType;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.SubTypes;
|
||||
import mage.view.CardView;
|
||||
import mage.view.PermanentView;
|
||||
|
|
@ -26,27 +27,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*
|
||||
private void cardRendererBasedRender(Graphics2D g) {
|
||||
// Prepare for draw
|
||||
g.translate(cardXOffset, cardYOffset);
|
||||
int cardWidth = this.cardWidth - cardXOffset;
|
||||
int cardHeight = this.cardHeight - cardYOffset;
|
||||
|
||||
// AA on
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
// Renderer
|
||||
CardRenderer render = new ModernCardRenderer(gameCard, transformed);
|
||||
Image img = imagePanel.getSrcImage();
|
||||
if (img != null) {
|
||||
render.setArtImage(img);
|
||||
}
|
||||
render.draw(g, cardWidth, cardHeight);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author stravant@gmail.com, JayDi85
|
||||
* <p>
|
||||
|
|
@ -285,7 +265,8 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
protected void drawBackground(Graphics2D g) {
|
||||
// Draw background, in 3 parts
|
||||
|
||||
if (cardView.isFaceDown()) {
|
||||
if (false && cardView.isFaceDown()) {
|
||||
// TODO: delete un-used code?!
|
||||
// Just draw a brown rectangle
|
||||
drawCardBack(g);
|
||||
} else {
|
||||
|
|
@ -392,16 +373,9 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
|
||||
@Override
|
||||
protected void drawArt(Graphics2D g) {
|
||||
if ((artImage != null || faceArtImage != null) && !cardView.isFaceDown()) {
|
||||
|
||||
boolean useFaceArt = false;
|
||||
if (faceArtImage != null && !isZendikarFullArtLand()) {
|
||||
useFaceArt = true;
|
||||
}
|
||||
|
||||
if (artImage != null) {
|
||||
// Invention rendering, art fills the entire frame
|
||||
if (useInventionFrame()) {
|
||||
useFaceArt = false;
|
||||
drawArtIntoRect(g,
|
||||
borderWidth, borderWidth,
|
||||
cardWidth - 2 * borderWidth, cardHeight - 2 * borderWidth,
|
||||
|
|
@ -412,7 +386,6 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
Rectangle2D sourceRect = getArtRect();
|
||||
|
||||
if (cardView.getMageObjectType() == MageObjectType.SPELL) {
|
||||
useFaceArt = false;
|
||||
ArtRect rect = cardView.getArtRect();
|
||||
if (rect != ArtRect.NORMAL) {
|
||||
sourceRect = rect.rect;
|
||||
|
|
@ -421,14 +394,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
}
|
||||
|
||||
// Normal drawing of art from a source part of the card frame into the rect
|
||||
if (useFaceArt) {
|
||||
int alternate_height = cardHeight - boxHeight * 2 - totalContentInset;
|
||||
drawFaceArtIntoRect(g,
|
||||
totalContentInset + 1, totalContentInset + boxHeight,
|
||||
contentWidth - 2, typeLineY - totalContentInset - boxHeight,
|
||||
alternate_height,
|
||||
sourceRect, shouldPreserveAspect);
|
||||
} else if (cardView.getArtRect() == ArtRect.FULL_LENGTH_RIGHT) {
|
||||
if (cardView.getArtRect() == ArtRect.FULL_LENGTH_RIGHT) {
|
||||
drawArtIntoRect(g,
|
||||
contentWidth / 2 + totalContentInset + 1, totalContentInset + boxHeight,
|
||||
contentWidth / 2 - 1, typeLineY - totalContentInset - boxHeight,
|
||||
|
|
@ -713,27 +679,20 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
|
||||
public void drawZendikarCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
||||
Color boxColor, Paint paint) {
|
||||
|
||||
BufferedImage artToUse = faceArtImage;
|
||||
boolean hadToUseFullArt = false;
|
||||
if (faceArtImage == null) {
|
||||
if (artImage == null) {
|
||||
return;
|
||||
}
|
||||
hadToUseFullArt = true;
|
||||
artToUse = artImage;
|
||||
if (artImage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedImage artToUse = artImage;
|
||||
int srcW = artToUse.getWidth();
|
||||
int srcH = artToUse.getHeight();
|
||||
|
||||
if (hadToUseFullArt) {
|
||||
// Get a box based on the standard scan from gatherer.
|
||||
// Width = 185/223 pixels (centered)
|
||||
// Height = 220/310, 38 pixels from top
|
||||
int subx = 19 * srcW / 223;
|
||||
int suby = 38 * srcH / 310;
|
||||
artToUse = artImage.getSubimage(subx, suby, 185 * srcW / 223, 220 * srcH / 310);
|
||||
}
|
||||
// Get a box based on the standard scan from gatherer.
|
||||
// Width = 185/223 pixels (centered)
|
||||
// Height = 220/310, 38 pixels from top
|
||||
int subx = 19 * srcW / 223;
|
||||
int suby = 38 * srcH / 310;
|
||||
artToUse = artImage.getSubimage(subx, suby, 185 * srcW / 223, 220 * srcH / 310);
|
||||
|
||||
Path2D.Double curve = new Path2D.Double();
|
||||
|
||||
|
|
@ -762,26 +721,19 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
public void drawBFZCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
||||
int topxdelta, int endydelta,
|
||||
Color boxColor, Paint paint) {
|
||||
BufferedImage artToUse = faceArtImage;
|
||||
boolean hadToUseFullArt = false;
|
||||
if (faceArtImage == null) {
|
||||
if (artImage == null) {
|
||||
return;
|
||||
}
|
||||
hadToUseFullArt = true;
|
||||
artToUse = artImage;
|
||||
if (artImage == null) {
|
||||
return;
|
||||
}
|
||||
BufferedImage artToUse = artImage;
|
||||
int srcW = artToUse.getWidth();
|
||||
int srcH = artToUse.getHeight();
|
||||
|
||||
if (hadToUseFullArt) {
|
||||
// Get a box based on the standard scan from gatherer.
|
||||
// Width = 185/223 pixels (centered)
|
||||
// Height = 220/310, 38 pixels from top
|
||||
int subx = 19 * srcW / 223;
|
||||
int suby = 38 * srcH / 310;
|
||||
artToUse = artImage.getSubimage(subx, suby, 185 * srcW / 223, 220 * srcH / 310);
|
||||
}
|
||||
// Get a box based on the standard scan from gatherer.
|
||||
// Width = 185/223 pixels (centered)
|
||||
// Height = 220/310, 38 pixels from top
|
||||
int subx = 19 * srcW / 223;
|
||||
int suby = 38 * srcH / 310;
|
||||
artToUse = artImage.getSubimage(subx, suby, 185 * srcW / 223, 220 * srcH / 310);
|
||||
|
||||
Path2D.Double curve = new Path2D.Double();
|
||||
curve.moveTo(x + topxdelta, y);
|
||||
|
|
@ -907,23 +859,13 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
int availableWidth = w - manaCostWidth + 2;
|
||||
|
||||
// Draw the name
|
||||
String nameStr;
|
||||
if (cardView.isFaceDown()) {
|
||||
if (cardView instanceof PermanentView && ((PermanentView) cardView).isManifested()) {
|
||||
nameStr = "Manifest: " + cardView.getName();
|
||||
} else {
|
||||
nameStr = "Morph: " + cardView.getName();
|
||||
}
|
||||
} else {
|
||||
nameStr = baseName;
|
||||
}
|
||||
if (!nameStr.isEmpty()) {
|
||||
AttributedString str = new AttributedString(nameStr);
|
||||
if (!baseName.isEmpty()) {
|
||||
AttributedString str = new AttributedString(baseName);
|
||||
str.addAttribute(TextAttribute.FONT, boxTextFont);
|
||||
TextMeasurer measure = new TextMeasurer(str.getIterator(), g.getFontRenderContext());
|
||||
int breakIndex = measure.getLineBreakIndex(0, availableWidth);
|
||||
if (breakIndex < nameStr.length()) {
|
||||
str = new AttributedString(nameStr);
|
||||
if (breakIndex < baseName.length()) {
|
||||
str = new AttributedString(baseName);
|
||||
str.addAttribute(TextAttribute.FONT, boxTextFontNarrow);
|
||||
measure = new TextMeasurer(str.getIterator(), g.getFontRenderContext());
|
||||
breakIndex = measure.getLineBreakIndex(0, availableWidth);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,8 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
|
||||
@Override
|
||||
protected void drawBackground(Graphics2D g) {
|
||||
if (cardView.isFaceDown()) {
|
||||
if (false && cardView.isFaceDown()) {
|
||||
// TODO: delete un-used code?!
|
||||
drawCardBack(g);
|
||||
} if (isAdventure()) {
|
||||
super.drawBackground(g);
|
||||
|
|
@ -206,7 +207,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
protected void drawArt(Graphics2D g) {
|
||||
if (isAdventure) {
|
||||
super.drawArt(g);
|
||||
} else if (artImage != null && !cardView.isFaceDown()) {
|
||||
} else if (artImage != null) {
|
||||
if (isAftermath()) {
|
||||
Rectangle2D topRect = ArtRect.AFTERMATH_TOP.rect;
|
||||
int topLineY = (int) (leftHalf.ch * TYPE_LINE_Y_FRAC);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import mage.cards.MageCard;
|
|||
import mage.cards.MagePermanent;
|
||||
import mage.cards.action.ActionCallback;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.ImageCaches;
|
||||
import mage.interfaces.plugin.CardPlugin;
|
||||
import mage.view.CardView;
|
||||
import mage.view.CounterView;
|
||||
|
|
@ -667,7 +668,7 @@ public class CardPluginImpl implements CardPlugin {
|
|||
LOGGER.info("Symbols download finished");
|
||||
dialog.dispose();
|
||||
ManaSymbols.loadImages();
|
||||
ImageCache.clearCache();
|
||||
GUISizeHelper.refreshGUIAndCards();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -710,6 +711,6 @@ public class CardPluginImpl implements CardPlugin {
|
|||
|
||||
@Override
|
||||
public BufferedImage getOriginalImage(CardView card) {
|
||||
return ImageCache.getImageOriginal(card).getImage();
|
||||
return ImageCache.getCardImageOriginal(card).getImage();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,17 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
private final String name;
|
||||
private Source source;
|
||||
private final Destination destination;
|
||||
private final boolean forceToDownload; // download image everytime, do not keep old image
|
||||
private final Property<State> state = properties.property("state", State.NEW);
|
||||
private final Property<String> message = properties.property("message");
|
||||
private final Property<Exception> error = properties.property("error");
|
||||
private final BoundedRangeModel progress = new DefaultBoundedRangeModel();
|
||||
|
||||
public DownloadJob(String name, Source source, Destination destination) {
|
||||
public DownloadJob(String name, Source source, Destination destination, boolean forceToDownload) {
|
||||
this.name = name;
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.forceToDownload = forceToDownload;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -155,6 +157,10 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
return destination;
|
||||
}
|
||||
|
||||
public boolean isForceToDownload() {
|
||||
return forceToDownload;
|
||||
}
|
||||
|
||||
public static Source fromURL(final String url) {
|
||||
return fromURL(CardImageUtils.getProxyFromPreferences(), url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ public class Downloader extends AbstractLaternaBean {
|
|||
Destination dst = job.getDestination();
|
||||
BoundedRangeModel progress = job.getProgress();
|
||||
|
||||
if (dst.isValid()) {
|
||||
if (dst.isValid() && !job.isForceToDownload()) {
|
||||
// already done
|
||||
progress.setMaximum(1);
|
||||
progress.setValue(1);
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import static org.mage.plugins.card.dl.DownloadJob.fromURL;
|
||||
import static org.mage.plugins.card.dl.DownloadJob.toFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class CardFrames implements Iterable<DownloadJob> {
|
||||
|
||||
private static final String FRAMES_PATH = File.separator + "frames";
|
||||
private static final File DEFAULT_OUT_DIR = new File("plugins" + File.separator + "images" + FRAMES_PATH);
|
||||
private static File outDir = DEFAULT_OUT_DIR;
|
||||
|
||||
static final String BASE_DOWNLOAD_URL = "http://ct-magefree.rhcloud.com/resources/img/";
|
||||
static final String TEXTURES_FOLDER = "textures";
|
||||
static final String PT_BOXES_FOLDER = "pt";
|
||||
|
||||
private static final String[] TEXTURES = {"U", "R", "G", "B", "W", "A",
|
||||
"BG_LAND", "BR_LAND", "WU_LAND", "WB_LAND", "UB_LAND", "GW_LAND", "RW_LAND",
|
||||
"RG_LAND", "GU_LAND", "UR_LAND"
|
||||
// NOT => "BW_LAND","BU_LAND","WG_LAND","WR_LAND",
|
||||
};
|
||||
private static final String[] PT_BOXES = {"U", "R", "G", "B", "W", "A"};
|
||||
|
||||
public CardFrames(String path) {
|
||||
if (path == null) {
|
||||
useDefaultDir();
|
||||
} else {
|
||||
changeOutDir(path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DownloadJob> iterator() {
|
||||
List<DownloadJob> jobs = new ArrayList<>();
|
||||
for (String texture : TEXTURES) {
|
||||
jobs.add(generateDownloadJob(TEXTURES_FOLDER, texture));
|
||||
}
|
||||
for (String pt_box : PT_BOXES) {
|
||||
jobs.add(generateDownloadJob(PT_BOXES_FOLDER, pt_box));
|
||||
}
|
||||
return jobs.iterator();
|
||||
}
|
||||
|
||||
private DownloadJob generateDownloadJob(String dirName, String name) {
|
||||
File dst = new File(outDir, name + ".png");
|
||||
String url = BASE_DOWNLOAD_URL + dirName + '/' + name + ".png";
|
||||
return new DownloadJob("frames-" + dirName + '-' + name, fromURL(url), toFile(dst));
|
||||
}
|
||||
|
||||
private void useDefaultDir() {
|
||||
outDir = DEFAULT_OUT_DIR;
|
||||
}
|
||||
|
||||
private void changeOutDir(String path) {
|
||||
File file = new File(path + FRAMES_PATH);
|
||||
if (file.exists()) {
|
||||
outDir = file;
|
||||
} else {
|
||||
file.mkdirs();
|
||||
if (file.exists()) {
|
||||
outDir = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import static org.mage.plugins.card.dl.DownloadJob.toFile;
|
|||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
||||
/**
|
||||
* TODO: outdated, delete and use xmage tokens instead ?!
|
||||
* Used when we need to point to direct links to download resources from.
|
||||
*
|
||||
* @author noxx
|
||||
|
|
@ -20,11 +21,9 @@ public class DirectLinksForDownload implements Iterable<DownloadJob> {
|
|||
private static final Map<String, String> directLinks = new LinkedHashMap<>();
|
||||
|
||||
public static final String cardbackFilename = "cardback.jpg";
|
||||
public static final String foretellFilename = "foretell.jpg";
|
||||
|
||||
static {
|
||||
directLinks.put(cardbackFilename, "https://upload.wikimedia.org/wikipedia/en/a/aa/Magic_the_gathering-card_back.jpg");
|
||||
directLinks.put(foretellFilename, "https://api.scryfall.com/cards/tkhm/23/en?format=image");
|
||||
}
|
||||
|
||||
private final File outDir;
|
||||
|
|
@ -42,7 +41,8 @@ public class DirectLinksForDownload implements Iterable<DownloadJob> {
|
|||
|
||||
for (Map.Entry<String, String> url : directLinks.entrySet()) {
|
||||
File dst = new File(outDir, url.getKey());
|
||||
jobs.add(new DownloadJob(url.getKey(), fromURL(url.getValue()), toFile(dst)));
|
||||
// download images every time (need to update low quality image)
|
||||
jobs.add(new DownloadJob(url.getKey(), fromURL(url.getValue()), toFile(dst), true));
|
||||
}
|
||||
return jobs.iterator();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,6 +337,6 @@ public class GathererSets implements Iterable<DownloadJob> {
|
|||
set = codeReplacements.get(set);
|
||||
}
|
||||
String url = "https://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=" + set + "&size=small&rarity=" + urlRarity;
|
||||
return new DownloadJob(set + '-' + rarity, fromURL(url), toFile(dst));
|
||||
return new DownloadJob(set + '-' + rarity, fromURL(url), toFile(dst), false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public class GathererSymbols implements Iterable<DownloadJob> {
|
|||
|
||||
String url = format(urlFmt, sizes[modSizeIndex], symbol);
|
||||
|
||||
return new DownloadJob(sym, fromURL(url), toFile(dst));
|
||||
return new DownloadJob(sym, fromURL(url), toFile(dst), false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -96,15 +96,13 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
// double faced cards (modal double faces cards too)
|
||||
if (card.isTwoFacedCard()) {
|
||||
if (card.isSecondSide()) {
|
||||
// back face - must be prepared before
|
||||
logger.warn("Can't find back face info in prepared list "
|
||||
+ card.getName() + " (" + card.getSet() + ") #" + card.getCollectorId());
|
||||
return new CardImageUrls(null, null);
|
||||
} else {
|
||||
// front face - can be downloaded normally as basic card
|
||||
}
|
||||
if (card.isSecondSide()) {
|
||||
// back face - must be prepared before
|
||||
logger.warn("Can't find back face info in prepared list "
|
||||
+ card.getName() + " (" + card.getSet() + ") #" + card.getCollectorId());
|
||||
return new CardImageUrls(null, null);
|
||||
} else {
|
||||
// front face - can be downloaded normally as basic card
|
||||
}
|
||||
|
||||
// basic cards by api call (redirect to img link)
|
||||
|
|
@ -219,7 +217,7 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
int needPrepareCount = 0;
|
||||
int currentPrepareCount = 0;
|
||||
for (CardDownloadData card : downloadList) {
|
||||
if (card.isTwoFacedCard() && card.isSecondSide()) {
|
||||
if (card.isSecondSide()) {
|
||||
needPrepareCount++;
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +230,7 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
// prepare the back face URL
|
||||
if (card.isTwoFacedCard() && card.isSecondSide()) {
|
||||
if (card.isSecondSide()) {
|
||||
currentPrepareCount++;
|
||||
try {
|
||||
String url = getFaceImageUrl(proxy, card, card.isToken());
|
||||
|
|
|
|||
|
|
@ -1275,9 +1275,9 @@ public class ScryfallImageSupportTokens {
|
|||
put("DDE/Saproling", "https://api.scryfall.com/cards/tdde/3/en?format=image");
|
||||
|
||||
// DDD
|
||||
put("DDD/Beast/1", "https://api.scryfall.com/cards/tddd/1/en?format=image");
|
||||
put("DDD/Beast/2", "https://api.scryfall.com/cards/tddd/2/en?format=image");
|
||||
put("DDD/Elephant", "https://api.scryfall.com/cards/tddd/3/en?format=image");
|
||||
put("DDD/Beast/1", "https://api.scryfall.com/cards/tddd/T1/en?format=image");
|
||||
put("DDD/Beast/2", "https://api.scryfall.com/cards/tddd/T2/en?format=image");
|
||||
put("DDD/Elephant", "https://api.scryfall.com/cards/tddd/T3/en?format=image");
|
||||
|
||||
// SOM
|
||||
put("SOM/Cat", "https://api.scryfall.com/cards/tsom/1/en?format=image");
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
|
||||
import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG;
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
||||
|
|
@ -105,7 +106,7 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
if (destFile.exists() && (destFile.length() > 0)) {
|
||||
continue;
|
||||
}
|
||||
try(FileOutputStream stream = new FileOutputStream(destFile)) {
|
||||
try (FileOutputStream stream = new FileOutputStream(destFile)) {
|
||||
// base64 transform
|
||||
String data64 = foundedData.get(searchCode);
|
||||
Base64.Decoder dec = Base64.getDecoder();
|
||||
|
|
@ -166,16 +167,14 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
}
|
||||
}
|
||||
|
||||
private String destFile = "";
|
||||
|
||||
public ScryfallSymbolsDownloadJob() {
|
||||
// download init
|
||||
super("Scryfall symbols source", fromURL(""), toFile(DOWNLOAD_TEMP_FILE)); // url setup on preparing stage
|
||||
this.destFile = DOWNLOAD_TEMP_FILE;
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryfallDownloadOnFinishedListener(this.destFile));
|
||||
super("Scryfall symbols source", fromURL(""), toFile(DOWNLOAD_TEMP_FILE), true); // url setup on preparing stage
|
||||
String destFile = DOWNLOAD_TEMP_FILE;
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryfallDownloadOnFinishedListener(destFile));
|
||||
|
||||
// clear dest file (always download new data)
|
||||
File file = new File(this.destFile);
|
||||
// duplicate a forceToDownload param above, but it's ok to clear temp file anyway
|
||||
File file = new File(destFile);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,37 +14,18 @@ public class CardDownloadData {
|
|||
private String set;
|
||||
private final String collectorId;
|
||||
private final Integer imageNumber;
|
||||
private boolean token;
|
||||
private final boolean twoFacedCard;
|
||||
private final boolean secondSide;
|
||||
private boolean flipCard;
|
||||
private boolean flippedSide;
|
||||
private boolean splitCard;
|
||||
private final boolean usesVariousArt;
|
||||
private String tokenClassName;
|
||||
private boolean isToken;
|
||||
private boolean isSecondSide;
|
||||
private boolean isFlippedSide;
|
||||
private boolean isSplitCard;
|
||||
private final boolean isUsesVariousArt;
|
||||
|
||||
public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer imageNumber) {
|
||||
this(name, setCode, collectorId, usesVariousArt, imageNumber, false);
|
||||
}
|
||||
|
||||
public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer imageNumber, boolean token) {
|
||||
this(name, setCode, collectorId, usesVariousArt, imageNumber, token, false, false, "");
|
||||
}
|
||||
|
||||
public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer imageNumber, boolean token, boolean twoFacedCard, boolean secondSide) {
|
||||
this(name, setCode, collectorId, usesVariousArt, imageNumber, token, twoFacedCard, secondSide, "");
|
||||
}
|
||||
|
||||
public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer imageNumber, boolean token, boolean twoFacedCard, boolean secondSide, String tokenClassName) {
|
||||
public CardDownloadData(String name, String setCode, String collectorId, boolean isUsesVariousArt, Integer imageNumber) {
|
||||
this.name = name;
|
||||
this.set = setCode;
|
||||
this.collectorId = collectorId;
|
||||
this.usesVariousArt = usesVariousArt;
|
||||
this.isUsesVariousArt = isUsesVariousArt;
|
||||
this.imageNumber = imageNumber;
|
||||
this.token = token;
|
||||
this.twoFacedCard = twoFacedCard;
|
||||
this.secondSide = secondSide;
|
||||
this.tokenClassName = tokenClassName;
|
||||
}
|
||||
|
||||
public CardDownloadData(final CardDownloadData card) {
|
||||
|
|
@ -53,14 +34,11 @@ public class CardDownloadData {
|
|||
this.set = card.set;
|
||||
this.collectorId = card.collectorId;
|
||||
this.imageNumber = card.imageNumber;
|
||||
this.token = card.token;
|
||||
this.twoFacedCard = card.twoFacedCard;
|
||||
this.secondSide = card.secondSide;
|
||||
this.flipCard = card.flipCard;
|
||||
this.flippedSide = card.flippedSide;
|
||||
this.splitCard = card.splitCard;
|
||||
this.usesVariousArt = card.usesVariousArt;
|
||||
this.tokenClassName = card.tokenClassName;
|
||||
this.isToken = card.isToken;
|
||||
this.isSecondSide = card.isSecondSide;
|
||||
this.isFlippedSide = card.isFlippedSide;
|
||||
this.isSplitCard = card.isSplitCard;
|
||||
this.isUsesVariousArt = card.isUsesVariousArt;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -81,14 +59,11 @@ public class CardDownloadData {
|
|||
if (!Objects.equals(this.collectorId, other.collectorId)) {
|
||||
return false;
|
||||
}
|
||||
if (this.token != other.token) {
|
||||
return false;
|
||||
}
|
||||
if (this.twoFacedCard != other.twoFacedCard) {
|
||||
if (this.isToken != other.isToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.secondSide == other.secondSide;
|
||||
return this.isSecondSide == other.isSecondSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -98,9 +73,8 @@ public class CardDownloadData {
|
|||
hash = 47 * hash + (this.set != null ? this.set.hashCode() : 0);
|
||||
hash = 47 * hash + (this.collectorId != null ? this.collectorId.hashCode() : 0);
|
||||
hash = 47 * hash + (this.imageNumber != null ? this.imageNumber.hashCode() : 0);
|
||||
hash = 47 * hash + (this.token ? 1 : 0);
|
||||
hash = 47 * hash + (this.twoFacedCard ? 1 : 0);
|
||||
hash = 47 * hash + (this.secondSide ? 1 : 0);
|
||||
hash = 47 * hash + (this.isToken ? 1 : 0);
|
||||
hash = 47 * hash + (this.isSecondSide ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -149,28 +123,20 @@ public class CardDownloadData {
|
|||
this.set = set;
|
||||
}
|
||||
|
||||
public void setTokenClassName(String tokenClassName) {
|
||||
this.tokenClassName = tokenClassName;
|
||||
}
|
||||
|
||||
public String getAffectedClassName() {
|
||||
return tokenClassName.isEmpty() ? name.replaceAll("[^a-zA-Z0-9]", "") : tokenClassName;
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
return token;
|
||||
return isToken;
|
||||
}
|
||||
|
||||
public void setToken(boolean token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public boolean isTwoFacedCard() {
|
||||
return twoFacedCard;
|
||||
this.isToken = token;
|
||||
}
|
||||
|
||||
public boolean isSecondSide() {
|
||||
return secondSide;
|
||||
return isSecondSide;
|
||||
}
|
||||
|
||||
public void setSecondSide(boolean isSecondSide) {
|
||||
this.isSecondSide = isSecondSide;
|
||||
}
|
||||
|
||||
public String getDownloadName() {
|
||||
|
|
@ -181,20 +147,12 @@ public class CardDownloadData {
|
|||
this.downloadName = downloadName;
|
||||
}
|
||||
|
||||
public boolean isFlipCard() {
|
||||
return flipCard;
|
||||
}
|
||||
|
||||
public void setFlipCard(boolean flipCard) {
|
||||
this.flipCard = flipCard;
|
||||
}
|
||||
|
||||
public boolean isSplitCard() {
|
||||
return splitCard;
|
||||
return isSplitCard;
|
||||
}
|
||||
|
||||
public void setSplitCard(boolean splitCard) {
|
||||
this.splitCard = splitCard;
|
||||
this.isSplitCard = splitCard;
|
||||
}
|
||||
|
||||
public Integer getImageNumber() {
|
||||
|
|
@ -202,14 +160,14 @@ public class CardDownloadData {
|
|||
}
|
||||
|
||||
public boolean getUsesVariousArt() {
|
||||
return usesVariousArt;
|
||||
return isUsesVariousArt;
|
||||
}
|
||||
|
||||
public boolean isFlippedSide() {
|
||||
return flippedSide;
|
||||
return isFlippedSide;
|
||||
}
|
||||
|
||||
public void setFlippedSide(boolean flippedSide) {
|
||||
this.flippedSide = flippedSide;
|
||||
this.isFlippedSide = flippedSide;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import mage.client.MageFrame;
|
|||
import mage.client.dialog.DownloadImagesDialog;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.client.util.CardLanguage;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.ImageCaches;
|
||||
import mage.client.util.sets.ConstructedFormats;
|
||||
import mage.remote.Connection;
|
||||
import net.java.truevfs.access.TFile;
|
||||
|
|
@ -437,14 +439,19 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
&& !"0".equals(card.getCardNumber())
|
||||
&& !card.getSetCode().isEmpty()) {
|
||||
String cardName = card.getName();
|
||||
CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, false, card.isDoubleFaced(), card.isNightCard());
|
||||
CardDownloadData url = new CardDownloadData(
|
||||
cardName,
|
||||
card.getSetCode(),
|
||||
card.getCardNumber(),
|
||||
card.usesVariousArt(),
|
||||
0);
|
||||
url.setSecondSide(card.isNightCard());
|
||||
|
||||
// variations must have diff file names with additional postfix
|
||||
if (url.getUsesVariousArt()) {
|
||||
url.setDownloadName(createDownloadName(card));
|
||||
}
|
||||
|
||||
url.setFlipCard(card.isFlipCard());
|
||||
url.setSplitCard(card.isSplitCard());
|
||||
|
||||
// main side
|
||||
|
|
@ -467,7 +474,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
card.getSetCode(),
|
||||
secondSideCard.getCardNumber(),
|
||||
card.usesVariousArt(),
|
||||
0, false, card.isDoubleFaced(), true);
|
||||
0
|
||||
);
|
||||
url.setSecondSide(true);
|
||||
allCardsUrls.add(url);
|
||||
}
|
||||
if (card.isFlipCard()) {
|
||||
|
|
@ -479,9 +488,10 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
card.getSetCode(),
|
||||
card.getCardNumber(),
|
||||
card.usesVariousArt(),
|
||||
0, false, card.isDoubleFaced(), card.isNightCard());
|
||||
cardDownloadData.setFlipCard(true);
|
||||
0
|
||||
);
|
||||
cardDownloadData.setFlippedSide(true);
|
||||
cardDownloadData.setSecondSide(card.isNightCard());
|
||||
allCardsUrls.add(cardDownloadData);
|
||||
}
|
||||
if (card.getMeldsToCardName() != null) {
|
||||
|
|
@ -500,7 +510,8 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
card.getSetCode(),
|
||||
meldsToCard.getCardNumber(),
|
||||
card.usesVariousArt(),
|
||||
0, false, false, false);
|
||||
0
|
||||
);
|
||||
allCardsUrls.add(url);
|
||||
}
|
||||
if (card.isModalDoubleFacedCard()) {
|
||||
|
|
@ -512,7 +523,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
card.getSetCode(),
|
||||
card.getCardNumber(),
|
||||
card.usesVariousArt(),
|
||||
0, false, true, true);
|
||||
0
|
||||
);
|
||||
cardDownloadData.setSecondSide(true);
|
||||
allCardsUrls.add(cardDownloadData);
|
||||
}
|
||||
} else if (card.getCardNumber().isEmpty() || "0".equals(card.getCardNumber())) {
|
||||
|
|
@ -531,9 +544,8 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
token.getSetCode(),
|
||||
"0",
|
||||
false,
|
||||
token.getImageNumber(),
|
||||
true
|
||||
);
|
||||
token.getImageNumber());
|
||||
card.setToken(true);
|
||||
allCardsUrls.add(card);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
|
@ -674,8 +686,8 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString());
|
||||
enableDialogButtons();
|
||||
|
||||
// reset images cache
|
||||
ImageCache.clearCache();
|
||||
// reset GUI and cards to use new images
|
||||
GUISizeHelper.refreshGUIAndCards();
|
||||
}
|
||||
|
||||
static String convertStreamToString(InputStream is) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package org.mage.plugins.card.images;
|
||||
|
||||
import com.google.common.collect.ComputationException;
|
||||
import mage.abilities.icon.CardIconColor;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.util.ImageCaches;
|
||||
import mage.client.util.SoftValuesLoadingCache;
|
||||
import mage.client.util.TransformedImageCache;
|
||||
import mage.view.CardView;
|
||||
import net.java.truevfs.access.TFile;
|
||||
import net.java.truevfs.access.TFileInputStream;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.card.arcane.CardPanelRenderModeImage;
|
||||
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
||||
|
|
@ -21,17 +22,9 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class stores ALL card images in a cache with soft values. this means
|
||||
* This class stores ALL card images in a cache with soft values. This means
|
||||
* that the images may be garbage collected when they are not needed any more,
|
||||
* but will be kept as long as possible.
|
||||
* <p>
|
||||
* Key format: "[cardname]#[setname]#[type]#[collectorID]#[image size]#[additional data]"
|
||||
*
|
||||
* <li>#Normal: request for unrotated image</li>
|
||||
* <li>#Tapped: request for rotated image</li>
|
||||
* <li>#Cropped: request for cropped image that is used for Shandalar like card
|
||||
* look</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
|
@ -39,195 +32,105 @@ public final class ImageCache {
|
|||
|
||||
private static final Logger LOGGER = Logger.getLogger(ImageCache.class);
|
||||
|
||||
private static final SoftValuesLoadingCache<String, ImageCacheData> IMAGE_CACHE; // cards and tokens
|
||||
private static final SoftValuesLoadingCache<String, ImageCacheData> FACE_IMAGE_CACHE;
|
||||
private static final SoftValuesLoadingCache<String, ImageCacheData> CARD_ICONS_CACHE;
|
||||
// global cache for both mtgo and image render modes
|
||||
private static final SoftValuesLoadingCache<String, ImageCacheData> SHARED_CARD_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(ImageCache::createCardOrTokenImage));
|
||||
private static final SoftValuesLoadingCache<String, ImageCacheData> SHARED_CARD_ICONS_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(ImageCache::createIcon));
|
||||
|
||||
/**
|
||||
* Common pattern for keys. See ImageCache.getKey for structure info
|
||||
*/
|
||||
private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)");
|
||||
// format: name #setcode #imagenumber #cardnumber #size #usesVariousArt
|
||||
private static final Pattern CARD_IMAGE_KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)");
|
||||
|
||||
// format: size #icon #color
|
||||
private static final Pattern CARD_ICON_KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)");
|
||||
|
||||
static {
|
||||
// softValues() = Specifies that each value (not key) stored in the map should be wrapped in a SoftReference
|
||||
// (by default, strong references are used). Softly-referenced objects will be garbage-collected in a
|
||||
// globally least-recently-used manner, in response to memory demand.
|
||||
IMAGE_CACHE = SoftValuesLoadingCache.from(key -> {
|
||||
try {
|
||||
boolean usesVariousArt = false;
|
||||
if (key.matches(".*#usesVariousArt.*")) {
|
||||
usesVariousArt = true;
|
||||
key = key.replace("#usesVariousArt", "");
|
||||
}
|
||||
Matcher m = KEY_PATTERN.matcher(key);
|
||||
|
||||
if (m.matches()) {
|
||||
String name = m.group(1);
|
||||
String setCode = m.group(2);
|
||||
Integer type = Integer.parseInt(m.group(3));
|
||||
String collectorId = m.group(4);
|
||||
if (collectorId.equals("null")) {
|
||||
collectorId = "0";
|
||||
}
|
||||
|
||||
CardDownloadData info = new CardDownloadData(name, setCode, collectorId, usesVariousArt, type);
|
||||
|
||||
boolean cardback = false;
|
||||
String path;
|
||||
if (collectorId.isEmpty() || "0".equals(collectorId)) {
|
||||
// TOKEN
|
||||
// can be a normal token or a token from card (see embalm ability)
|
||||
info.setToken(true);
|
||||
TFile tokenFile;
|
||||
|
||||
// try normal token
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
tokenFile = getTFile(path);
|
||||
|
||||
// try token from card
|
||||
// TODO: return image from another set on empty image?
|
||||
if (tokenFile == null || !tokenFile.exists()) {
|
||||
CardDownloadData tempInfo = new CardDownloadData(info);
|
||||
tempInfo.setToken(false);
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
tokenFile = getTFile(path);
|
||||
}
|
||||
|
||||
// try unknown token image
|
||||
if (tokenFile == null || !tokenFile.exists()) {
|
||||
// TODO: replace empty token by other default card, not cardback
|
||||
cardback = true;
|
||||
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
|
||||
}
|
||||
} else {
|
||||
// CARD
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
}
|
||||
|
||||
TFile file = getTFile(path);
|
||||
if (file == null) {
|
||||
return new ImageCacheData(path, null);
|
||||
}
|
||||
|
||||
if (cardback) {
|
||||
// TODO: is there any different in images styles? Cardback must be from scryfall, not wizards
|
||||
// need cardback image
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
} else {
|
||||
// need normal card image
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getWizardsCard(image);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Requested image doesn't fit the requirement for key (<cardname>#<setname>#<collectorID>): " + key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof ComputationException) {
|
||||
throw (ComputationException) ex;
|
||||
} else {
|
||||
throw new ComputationException(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
FACE_IMAGE_CACHE = SoftValuesLoadingCache.from(key -> {
|
||||
try {
|
||||
Matcher m = KEY_PATTERN.matcher(key);
|
||||
|
||||
if (m.matches()) {
|
||||
String name = m.group(1);
|
||||
String setCode = m.group(2);
|
||||
// skip type
|
||||
// skip collectorId
|
||||
|
||||
String path = CardImageUtils.generateFaceImagePath(name, setCode);
|
||||
TFile file = getTFile(path);
|
||||
if (file == null) {
|
||||
return new ImageCacheData(path, null);
|
||||
}
|
||||
|
||||
BufferedImage image = loadImage(file);
|
||||
return new ImageCacheData(path, image);
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Requested face image doesn't fit the requirement for key (<cardname>#<artid>#: " + key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof ComputationException) {
|
||||
throw (ComputationException) ex;
|
||||
} else {
|
||||
throw new ComputationException(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CARD_ICONS_CACHE = SoftValuesLoadingCache.from(key -> {
|
||||
try {
|
||||
Matcher m = CARD_ICON_KEY_PATTERN.matcher(key);
|
||||
|
||||
if (m.matches()) {
|
||||
int cardSize = Integer.parseInt(m.group(1));
|
||||
String resourceName = m.group(2);
|
||||
CardIconColor cardIconColor = CardIconColor.valueOf(m.group(3));
|
||||
BufferedImage image = ImageManagerImpl.instance.getCardIcon(resourceName, cardSize, cardIconColor);
|
||||
return new ImageCacheData(resourceName, image);
|
||||
} else {
|
||||
throw new RuntimeException("Wrong card icons image key format: " + key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof ComputationException) {
|
||||
throw (ComputationException) ex;
|
||||
} else {
|
||||
throw new ComputationException(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
IMAGE_CACHE.invalidateAll();
|
||||
FACE_IMAGE_CACHE.invalidateAll();
|
||||
CARD_ICONS_CACHE.invalidateAll();
|
||||
}
|
||||
|
||||
private ImageCache() {
|
||||
}
|
||||
|
||||
public static ImageCacheData getCardbackImage() {
|
||||
String path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
|
||||
BufferedImage image = ImageCache.loadImage(getTFile(path));
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
private static ImageCacheData createCardOrTokenImage(String key) {
|
||||
boolean usesVariousArt = false;
|
||||
if (key.matches(".*#usesVariousArt.*")) {
|
||||
usesVariousArt = true;
|
||||
key = key.replace("#usesVariousArt", "");
|
||||
}
|
||||
Matcher m = CARD_IMAGE_KEY_PATTERN.matcher(key);
|
||||
|
||||
if (m.matches()) {
|
||||
String name = m.group(1);
|
||||
String setCode = m.group(2);
|
||||
Integer imageNumber = Integer.parseInt(m.group(3));
|
||||
String collectorId = m.group(4);
|
||||
if (collectorId.equals("null")) {
|
||||
collectorId = "0";
|
||||
}
|
||||
|
||||
CardDownloadData info = new CardDownloadData(name, setCode, collectorId, usesVariousArt, imageNumber);
|
||||
|
||||
boolean cardback = false;
|
||||
String path;
|
||||
if (collectorId.isEmpty() || "0".equals(collectorId)) {
|
||||
// TOKEN
|
||||
// can be a normal token or a token from card (see embalm ability)
|
||||
info.setToken(true);
|
||||
TFile tokenFile;
|
||||
|
||||
// try normal token
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
tokenFile = getTFile(path);
|
||||
|
||||
// try token from card
|
||||
// TODO: unused code?
|
||||
// TODO: return image from another set on empty image?
|
||||
if (tokenFile == null || !tokenFile.exists()) {
|
||||
CardDownloadData tempInfo = new CardDownloadData(info);
|
||||
tempInfo.setToken(false);
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
tokenFile = getTFile(path);
|
||||
}
|
||||
|
||||
// try unknown token image
|
||||
if (tokenFile == null || !tokenFile.exists()) {
|
||||
// TODO: replace empty token by other default card, not cardback
|
||||
cardback = true;
|
||||
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
|
||||
}
|
||||
} else {
|
||||
// CARD
|
||||
path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
}
|
||||
|
||||
TFile file = getTFile(path);
|
||||
if (file == null) {
|
||||
return new ImageCacheData(path, null);
|
||||
}
|
||||
|
||||
if (cardback) {
|
||||
// TODO: is there any different in images styles? Cardback must be from scryfall, not wizards
|
||||
// need cardback image
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
} else {
|
||||
// need normal card image
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getWizardsCard(image);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown card image's key format: " + key);
|
||||
}
|
||||
}
|
||||
|
||||
public static ImageCacheData getMorphImage() {
|
||||
// TODO: replace by downloadable morth image
|
||||
CardDownloadData info = new CardDownloadData("Morph", "KTK", "0", false, 0);
|
||||
info.setToken(true);
|
||||
String path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
|
||||
TFile file = getTFile(path);
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
}
|
||||
|
||||
public static ImageCacheData getManifestImage() {
|
||||
// TODO: replace by downloadable manifestest image
|
||||
CardDownloadData info = new CardDownloadData("Manifest", "FRF", "0", false, 0);
|
||||
info.setToken(true);
|
||||
String path = CardImageUtils.buildImagePathToCardOrToken(info);
|
||||
|
||||
TFile file = getTFile(path);
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getRoundCorner(image);
|
||||
return new ImageCacheData(path, image);
|
||||
private static ImageCacheData createIcon(String key) {
|
||||
Matcher m = CARD_ICON_KEY_PATTERN.matcher(key);
|
||||
if (m.matches()) {
|
||||
int cardSize = Integer.parseInt(m.group(1));
|
||||
String resourceName = m.group(2);
|
||||
CardIconColor cardIconColor = CardIconColor.valueOf(m.group(3));
|
||||
BufferedImage image = ImageManagerImpl.instance.getCardIcon(resourceName, cardSize, cardIconColor);
|
||||
return new ImageCacheData(resourceName, image);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown card icon's key format: " + key);
|
||||
}
|
||||
}
|
||||
|
||||
public static BufferedImage getRoundCorner(BufferedImage image) {
|
||||
|
|
@ -269,61 +172,52 @@ public final class ImageCache {
|
|||
}
|
||||
}
|
||||
|
||||
public static ImageCacheData getImageOriginal(CardView card) {
|
||||
return getImage(getKey(card, card.getName(), 0));
|
||||
/** Find image for current side
|
||||
*/
|
||||
public static ImageCacheData getCardImageOriginal(CardView card) {
|
||||
return getCardImage(getKey(card, card.getName(), 0));
|
||||
}
|
||||
|
||||
public static ImageCacheData getImageOriginalAlternateName(CardView card) {
|
||||
return getImage(getKey(card, card.getAlternateName(), 0));
|
||||
/**
|
||||
* Find image for other side
|
||||
*/
|
||||
public static ImageCacheData getCardImageAlternate(CardView card) {
|
||||
return getCardImage(getKey(card, card.getAlternateName(), 0));
|
||||
}
|
||||
|
||||
public static ImageCacheData getCardIconImage(String resourceName, int iconSize, String cardColorName) {
|
||||
return getCardIconImage(getCardIconKey(resourceName, iconSize, cardColorName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Image corresponding to the key
|
||||
*/
|
||||
private static ImageCacheData getImage(String key) {
|
||||
private static ImageCacheData getCardImage(String key) {
|
||||
try {
|
||||
ImageCacheData data = IMAGE_CACHE.getOrNull(key);
|
||||
ImageCacheData data = SHARED_CARD_IMAGES_CACHE.getOrNull(key);
|
||||
return data != null ? data : new ImageCacheData("ERROR: key - " + key, null);
|
||||
} catch (ComputationException ex) {
|
||||
// too low memory
|
||||
if (ex.getCause() instanceof NullPointerException) {
|
||||
return new ImageCacheData("ERROR: low memory?", null);
|
||||
} catch (Exception e) {
|
||||
if (e.getCause() instanceof NullPointerException) {
|
||||
// low memory error???
|
||||
return new ImageCacheData("ERROR: possible low memory", null);
|
||||
} else {
|
||||
// other error
|
||||
LOGGER.error("Error while loading card image: " + e, e);
|
||||
return new ImageCacheData("ERROR: see client logs for details", null);
|
||||
}
|
||||
LOGGER.error(ex, ex);
|
||||
return new ImageCacheData("ERROR: see logs", null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Image corresponding to the key
|
||||
*/
|
||||
private static ImageCacheData getFaceImage(String key) {
|
||||
try {
|
||||
ImageCacheData data = FACE_IMAGE_CACHE.getOrNull(key);
|
||||
return data != null ? data : new ImageCacheData("ERROR: key " + key, null);
|
||||
} catch (ComputationException ex) {
|
||||
if (ex.getCause() instanceof NullPointerException) {
|
||||
return new ImageCacheData("ERROR: low memory?", null);
|
||||
}
|
||||
LOGGER.error(ex, ex);
|
||||
return new ImageCacheData("ERROR: see logs", null);
|
||||
}
|
||||
}
|
||||
|
||||
private static ImageCacheData getCardIconImage(String key) {
|
||||
try {
|
||||
ImageCacheData data = CARD_ICONS_CACHE.getOrNull(key);
|
||||
ImageCacheData data = SHARED_CARD_ICONS_CACHE.getOrNull(key);
|
||||
return data != null ? data : new ImageCacheData("ERROR: key - " + key, null);
|
||||
} catch (ComputationException ex) {
|
||||
if (ex.getCause() instanceof NullPointerException) {
|
||||
return new ImageCacheData("ERROR: low memory?", null);
|
||||
} catch (Exception e) {
|
||||
if (e.getCause() instanceof NullPointerException) {
|
||||
// low memory error???
|
||||
return new ImageCacheData("ERROR: possible low memory", null);
|
||||
} else {
|
||||
// other error
|
||||
LOGGER.error("Error while loading card icon: " + e, e);
|
||||
return new ImageCacheData("ERROR: see client logs for details", null);
|
||||
}
|
||||
LOGGER.error(ex, ex);
|
||||
return new ImageCacheData("ERROR: see logs", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +226,7 @@ public final class ImageCache {
|
|||
* the cache.
|
||||
*/
|
||||
private static ImageCacheData tryGetImage(String key) {
|
||||
return IMAGE_CACHE.peekIfPresent(key);
|
||||
return SHARED_CARD_IMAGES_CACHE.peekIfPresent(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -343,7 +237,11 @@ public final class ImageCache {
|
|||
* @param imageSize - size info, 0 to use original image (with max size)
|
||||
*/
|
||||
private static String getKey(CardView card, String cardName, int imageSize) {
|
||||
return (card.isToken() ? cardName.replace(" Token", "") : cardName)
|
||||
String imageFileName = card.getImageFileName();
|
||||
if (imageFileName.isEmpty()) {
|
||||
imageFileName = cardName;
|
||||
}
|
||||
return imageFileName.replace(" Token", "")
|
||||
+ '#' + card.getExpansionSetCode()
|
||||
+ '#' + card.getImageNumber()
|
||||
+ '#' + card.getCardNumber()
|
||||
|
|
@ -420,9 +318,9 @@ public final class ImageCache {
|
|||
* @param height
|
||||
* @return
|
||||
*/
|
||||
public static ImageCacheData getImage(CardView card, int width, int height) {
|
||||
public static ImageCacheData getCardImage(CardView card, int width, int height) {
|
||||
String key = getKey(card, card.getName(), width);
|
||||
ImageCacheData data = getImage(key);
|
||||
ImageCacheData data = getCardImage(key);
|
||||
if (data.getImage() == null) {
|
||||
LOGGER.debug("Image doesn't exists in the cache: " + key);
|
||||
return data;
|
||||
|
|
@ -438,23 +336,6 @@ public final class ImageCache {
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image appropriate to display the card in the picture panel
|
||||
*
|
||||
* @param card
|
||||
* @param width
|
||||
* @param height
|
||||
* @return
|
||||
*/
|
||||
public static ImageCacheData getFaceImage(CardView card, int width, int height) {
|
||||
String key = getFaceKey(card, card.getName(), card.getExpansionSetCode());
|
||||
ImageCacheData data = getFaceImage(key);
|
||||
if (data.getImage() == null) {
|
||||
LOGGER.debug(key + " (faceimage) not found");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image appropriate to display for a card in a picture panel,
|
||||
* but only it was ALREADY LOADED. That is, the call is immediate and will
|
||||
|
|
|
|||
|
|
@ -146,37 +146,47 @@ public final class CardImageUtils {
|
|||
*/
|
||||
public static String buildImagePathToCardView(CardView card) {
|
||||
String imageFile;
|
||||
if (card.getMageObjectType().isUseTokensRepository()) {
|
||||
// token images
|
||||
String imageFileName = card.getImageFileName();
|
||||
if (imageFileName.isEmpty()) {
|
||||
imageFileName = card.getName();
|
||||
}
|
||||
|
||||
if (imageFileName.isEmpty()) {
|
||||
return "ERROR: empty image file name, object type - " + card.getMageObjectType();
|
||||
}
|
||||
|
||||
if (card.getMageObjectType().isUseTokensRepository()
|
||||
|| card.getExpansionSetCode().equals(TokenRepository.XMAGE_TOKENS_SET_CODE)) {
|
||||
// token images or inner cards like face down
|
||||
CardDownloadData cardData = new CardDownloadData(
|
||||
card.getName().replace(" Token", ""),
|
||||
imageFileName.replace(" Token", ""),
|
||||
card.getExpansionSetCode(),
|
||||
"0",
|
||||
false,
|
||||
card.getImageNumber(),
|
||||
true);
|
||||
card.getCardNumber(),
|
||||
card.getUsesVariousArt(),
|
||||
card.getImageNumber());
|
||||
cardData.setToken(true);
|
||||
imageFile = CardImageUtils.buildImagePathToCardOrToken(cardData);
|
||||
} else {
|
||||
TokenRepository.instance.getAll();
|
||||
// card images
|
||||
// workaround to find various art settings first
|
||||
// TODO: no needs in workaround?! ?!
|
||||
boolean usesVariousArt = false;
|
||||
CardInfo cardInfo = CardRepository.instance.findCardWithPreferredSetAndNumber(
|
||||
card.getName(),
|
||||
card.getExpansionSetCode(),
|
||||
card.getCardNumber()
|
||||
);
|
||||
if (cardInfo != null) {
|
||||
CardDownloadData cardData = new CardDownloadData(
|
||||
cardInfo.getName(),
|
||||
cardInfo.getSetCode(),
|
||||
cardInfo.getCardNumber(),
|
||||
cardInfo.usesVariousArt(),
|
||||
card.getImageNumber()
|
||||
);
|
||||
imageFile = CardImageUtils.buildImagePathToCardOrToken(cardData);
|
||||
} else {
|
||||
imageFile = "ERROR: can't find card info in repository - " + card.getName();
|
||||
usesVariousArt = cardInfo.usesVariousArt();
|
||||
}
|
||||
CardDownloadData cardData = new CardDownloadData(
|
||||
imageFileName,
|
||||
card.getExpansionSetCode(),
|
||||
card.getCardNumber(),
|
||||
card.getUsesVariousArt(), // TODO: need to use usesVariousArt instead card?
|
||||
card.getImageNumber()
|
||||
);
|
||||
imageFile = CardImageUtils.buildImagePathToCardOrToken(cardData);
|
||||
}
|
||||
return imageFile;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue