mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 13:02:06 -08:00
* Correct type line rendering for split cards with different types on each half.
* Correct art rendering for Aftermath, Split, and Fuse cards on the stack. Fused cards show as a single card with all the abilities / characteristics of both halves while on the stack.
This commit is contained in:
parent
7e3d276c57
commit
047449f14e
6 changed files with 159 additions and 26 deletions
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.mage.card.arcane;
|
||||
|
||||
import mage.cards.ArtRect;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
|
|
@ -124,7 +125,12 @@ public abstract class CardRenderer {
|
|||
this.cardView = card;
|
||||
this.isTransformed = isTransformed;
|
||||
|
||||
parseRules(card.getRules(), textboxKeywords, textboxRules);
|
||||
if (card.getArtRect() == ArtRect.SPLIT_FUSED) {
|
||||
parseRules(card.getLeftSplitRules(), textboxKeywords, textboxRules);
|
||||
parseRules(card.getRightSplitRules(), textboxKeywords, textboxRules);
|
||||
} else {
|
||||
parseRules(card.getRules(), textboxKeywords, textboxRules);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseRules(List<String> stringRules, ArrayList<TextboxRule> keywords, ArrayList<TextboxRule> rules) {
|
||||
|
|
@ -261,7 +267,7 @@ public abstract class CardRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void drawArtIntoRect(Graphics2D g, int x, int y, int w, int h, Rectangle2D artRect, boolean noAspectAdjust) {
|
||||
protected void drawArtIntoRect(Graphics2D g, int x, int y, int w, int 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 = artImage.getWidth();
|
||||
|
|
@ -271,7 +277,7 @@ public abstract class CardRenderer {
|
|||
double targetWidth = w;
|
||||
double targetHeight = h;
|
||||
double targetAspect = targetWidth / targetHeight;
|
||||
if (noAspectAdjust) {
|
||||
if (!shouldPreserveAspect) {
|
||||
// No adjustment to art
|
||||
} else if (targetAspect * artHeight < artWidth) {
|
||||
// Trim off some width
|
||||
|
|
@ -285,17 +291,10 @@ public abstract class CardRenderer {
|
|||
= artImage.getSubimage(
|
||||
(int) (artRect.getX() * fullCardImgWidth), (int) (artRect.getY() * fullCardImgHeight),
|
||||
(int) artWidth, (int) artHeight);
|
||||
if (noAspectAdjust) {
|
||||
g.drawImage(subImg,
|
||||
borderWidth, borderWidth,
|
||||
cardWidth - 2 * borderWidth, cardHeight - 2 * borderWidth,
|
||||
null);
|
||||
} else {
|
||||
g.drawImage(subImg,
|
||||
x, y,
|
||||
(int) targetWidth, (int) targetHeight,
|
||||
null);
|
||||
}
|
||||
g.drawImage(subImg,
|
||||
x, y,
|
||||
(int) targetWidth, (int) targetHeight,
|
||||
null);
|
||||
} catch (RasterFormatException e) {
|
||||
// At very small card sizes we may encounter a problem with rounding error making the rect not fit
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.mage.card.arcane;
|
||||
|
||||
import mage.cards.ArtRect;
|
||||
import mage.view.CardView;
|
||||
|
||||
/**
|
||||
|
|
@ -11,7 +12,9 @@ public class CardRendererFactory {
|
|||
}
|
||||
|
||||
public CardRenderer create(CardView card, boolean isTransformed) {
|
||||
if (card.isSplitCard()) {
|
||||
if (card.isSplitCard() && card.getArtRect() != ArtRect.SPLIT_FUSED) {
|
||||
// Split fused cards still render with the normal frame, showing all abilities
|
||||
// from both halves in one frame.
|
||||
return new ModernSplitCardRenderer(card, isTransformed);
|
||||
} else {
|
||||
return new ModernCardRenderer(card, isTransformed);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@
|
|||
package org.mage.card.arcane;
|
||||
|
||||
import mage.ObjectColor;
|
||||
import mage.cards.ArtRect;
|
||||
import mage.cards.FrameStyle;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.MageObjectType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.view.CardView;
|
||||
import mage.view.PermanentView;
|
||||
import org.apache.log4j.Logger;
|
||||
|
|
@ -311,7 +314,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
} else if (cardView.getFrameStyle().isFullArt() || (cardView.isToken())) {
|
||||
rect = new Rectangle2D.Float(.079f, .11f, .84f, .63f);
|
||||
} else {
|
||||
rect = new Rectangle2D.Float(.079f, .11f, .84f, .42f);
|
||||
rect = ArtRect.NORMAL.rect;
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
|
@ -346,10 +349,42 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
@Override
|
||||
protected void drawArt(Graphics2D g) {
|
||||
if (artImage != null && !cardView.isFaceDown()) {
|
||||
// Invention rendering, art fills the entire frame
|
||||
if (useInventionFrame()) {
|
||||
drawArtIntoRect(g,
|
||||
borderWidth, borderWidth,
|
||||
cardWidth - 2*borderWidth, cardHeight - 2*borderWidth,
|
||||
getArtRect(), false);
|
||||
}
|
||||
|
||||
boolean shouldPreserveAspect = true;
|
||||
Rectangle2D sourceRect = getArtRect();
|
||||
|
||||
if (cardView.getMageObjectType() == MageObjectType.SPELL) {
|
||||
ArtRect rect = cardView.getArtRect();
|
||||
if (rect == ArtRect.SPLIT_FUSED) {
|
||||
// Special handling for fused, draw the art from both halves stacked on top of one and other
|
||||
// each filling half of the art rect
|
||||
drawArtIntoRect(g,
|
||||
totalContentInset + 1, totalContentInset + boxHeight,
|
||||
contentWidth - 2, (typeLineY - totalContentInset - boxHeight)/2,
|
||||
ArtRect.SPLIT_LEFT.rect, useInventionFrame());
|
||||
drawArtIntoRect(g,
|
||||
totalContentInset + 1, totalContentInset + boxHeight + (typeLineY - totalContentInset - boxHeight)/2,
|
||||
contentWidth - 2, (typeLineY - totalContentInset - boxHeight)/2,
|
||||
ArtRect.SPLIT_RIGHT.rect, useInventionFrame());
|
||||
return;
|
||||
} else if (rect != ArtRect.NORMAL) {
|
||||
sourceRect = rect.rect;
|
||||
shouldPreserveAspect = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal drawing of art from a source part of the card frame into the rect
|
||||
drawArtIntoRect(g,
|
||||
totalContentInset + 1, totalContentInset + boxHeight,
|
||||
contentWidth - 2, typeLineY - totalContentInset - boxHeight,
|
||||
getArtRect(), useInventionFrame());
|
||||
sourceRect, shouldPreserveAspect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -443,7 +478,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
int nameOffset = drawTransformationCircle(g, borderPaint);
|
||||
|
||||
// Draw the name line
|
||||
drawNameLine(g, cardView.getName(), manaCostString,
|
||||
drawNameLine(g, cardView.getDisplayName(), manaCostString,
|
||||
totalContentInset + nameOffset, totalContentInset,
|
||||
contentWidth - nameOffset, boxHeight);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.mage.card.arcane;
|
|||
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.cards.ArtRect;
|
||||
import mage.constants.CardType;
|
||||
import mage.view.CardView;
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
int x, y, w, h, cw, ch;
|
||||
|
||||
String name;
|
||||
String typeLineString;
|
||||
String manaCostString;
|
||||
ObjectColor color;
|
||||
ArrayList<TextboxRule> rules = new ArrayList<>();
|
||||
|
|
@ -51,6 +53,9 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
parseRules(view.getRightSplitRules(), rightHalf.keywords, rightHalf.rules);
|
||||
parseRules(view.getLeftSplitRules(), leftHalf.keywords, leftHalf.rules);
|
||||
|
||||
rightHalf.typeLineString = cardView.getRightSplitTypeLine();
|
||||
leftHalf.typeLineString = cardView.getLeftSplitTypeLine();
|
||||
|
||||
rightHalf.name = cardView.getRightSplitName();
|
||||
leftHalf.name = cardView.getLeftSplitName();
|
||||
|
||||
|
|
@ -186,26 +191,28 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
protected void drawArt(Graphics2D g) {
|
||||
if (artImage != null && !cardView.isFaceDown()) {
|
||||
if (isAftermath()) {
|
||||
Rectangle2D topRect = new Rectangle2D.Double(0.075, 0.113, 0.832, 0.227);
|
||||
Rectangle2D topRect = ArtRect.AFTERMATH_TOP.rect;
|
||||
int topLineY = (int) (leftHalf.ch * TYPE_LINE_Y_FRAC);
|
||||
drawArtIntoRect(g,
|
||||
leftHalf.x, leftHalf.y + boxHeight, leftHalf.cw, topLineY - boxHeight,
|
||||
topRect, false);
|
||||
|
||||
Rectangle2D bottomRect = new Rectangle2D.Double(0.546, 0.562, 0.272, 0.346);
|
||||
Rectangle2D bottomRect = ArtRect.AFTERMATH_BOTTOM.rect;
|
||||
int bottomLineY = (rightHalf.ch - boxHeight) / 2;
|
||||
drawArtIntoRect(g,
|
||||
rightHalf.x + rightHalf.w - bottomLineY, rightHalf.y, bottomLineY - boxHeight, rightHalf.h,
|
||||
bottomRect, false);
|
||||
|
||||
} else {
|
||||
Rectangle2D topRect = new Rectangle2D.Double(0.152, 0.058, 0.386, 0.400);
|
||||
// NOTE: Art rects are reversed here, that is on purpose because we swap the left / right half
|
||||
// of split cards for rendering for consistency between aftermath and normal split
|
||||
Rectangle2D topRect = ArtRect.SPLIT_RIGHT.rect;
|
||||
int topLineY = (int) (leftHalf.ch * TYPE_LINE_Y_FRAC);
|
||||
drawArtIntoRect(g,
|
||||
leftHalf.x + boxHeight, leftHalf.y, topLineY - boxHeight, leftHalf.h,
|
||||
topRect, false);
|
||||
|
||||
Rectangle2D bottomRect = new Rectangle2D.Double(0.152, 0.539, 0.386, 0.400);
|
||||
Rectangle2D bottomRect = ArtRect.SPLIT_LEFT.rect;
|
||||
int bottomLineY = (int) (rightHalf.ch * TYPE_LINE_Y_FRAC);
|
||||
drawArtIntoRect(g,
|
||||
rightHalf.x + boxHeight, rightHalf.y, bottomLineY - boxHeight, rightHalf.h,
|
||||
|
|
@ -252,7 +259,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
|||
half.cw, boxHeight);
|
||||
|
||||
// Draw the type line
|
||||
drawTypeLine(g, getCardTypeLine(),
|
||||
drawTypeLine(g, half.typeLineString,
|
||||
0, typeLineY,
|
||||
half.cw, boxHeight - 4);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue