Refactor Mask/Border on zoomed images

This commit is contained in:
Anthony Calosa
2019-10-09 11:18:19 +08:00
parent 4609b0bb05
commit e1daff65ed
7 changed files with 64 additions and 116 deletions

View File

@@ -34,11 +34,7 @@ public abstract class CachedCardImage implements ImageFetcher.Callback {
}
public Texture getImage() {
return ImageCache.getImage(key, true, false);
}
public Texture getImage(boolean mask) {
return ImageCache.getImage(key, true, mask);
return ImageCache.getImage(key, true);
}
public abstract void onImageFetched();

View File

@@ -344,6 +344,7 @@ public class Graphics {
}
public void fillRoundRect(Color color, float x, float y, float w, float h, float radius) {
//TODO Smooth Rounded Corner???
batch.end(); //must pause batch while rendering shapes
if (alphaComposite < 1) {
color = FSkinColor.alphaColor(color, color.a * alphaComposite);

View File

@@ -82,11 +82,7 @@ public class ImageCache {
}
public static Texture getImage(InventoryItem ii) {
return getImage(ii.getImageKey(false), true, false);
}
public static Texture getImage(InventoryItem ii, Boolean mask) {
return getImage(ii.getImageKey(false), true, mask);
return getImage(ii.getImageKey(false), true);
}
/**
@@ -112,9 +108,6 @@ public class ImageCache {
* </p>
*/
public static Texture getImage(String imageKey, boolean useDefaultIfNotFound) {
return getImage(imageKey, useDefaultIfNotFound, false);
}
public static Texture getImage(String imageKey, boolean useDefaultIfNotFound, boolean maskCard) {
if (StringUtils.isEmpty(imageKey)) {
return null;
}
@@ -133,8 +126,6 @@ public class ImageCache {
Texture image;
if (useDefaultIfNotFound) {
// Load from file and add to cache if not found in cache initially.
if (maskCard)//if we add pixmap modification here, it will slow performance so we do this on the image loader lol :)...
imageKey += "#drawroundcorner#";
image = cache.get(imageKey);
if (image != null) { return image; }

View File

@@ -16,21 +16,15 @@ import forge.ImageKeys;
final class ImageLoader extends CacheLoader<String, Texture> {
@Override
public Texture load(String key) {
boolean mask = key.contains("#drawroundcorner#");
boolean alphaCard = false;
boolean textureFilter = Forge.isTextureFilteringEnabled();
if (key.length() > 4){
if ((key.substring(0,4).contains("LEA/")) || (key.substring(0,2).contains("A/")))
alphaCard = true;
//TODO dont add border on some sets???
}
File file = ImageKeys.getImageFile(key.replaceAll("#drawroundcorner#",""));
File file = ImageKeys.getImageFile(key);
if (file != null) {
FileHandle fh = new FileHandle(file);
Texture t = new Texture(fh, textureFilter);
try {
return generateTexture(fh, t, mask, alphaCard, textureFilter);
Texture t = new Texture(fh, textureFilter);
if (textureFilter)
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
return t;
}
catch (Exception ex) {
Forge.log("Could not read image file " + fh.path() + "\n\nException:\n" + ex.toString());
@@ -38,81 +32,4 @@ final class ImageLoader extends CacheLoader<String, Texture> {
}
return null;
}
public Texture generateTexture(FileHandle fh, Texture t, boolean mask, boolean alphaCard, boolean textureFilter) {
if (!mask) {
if (textureFilter)
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
return t;
}
Pixmap pImage = new Pixmap(fh);
int w = pImage.getWidth();
int h = pImage.getHeight();
int radius = alphaCard ? (h - w) / 6 : (h - w) / 8;
Pixmap pMask = createRoundedRectangle(w, h, radius, Color.RED);
drawPixelstoMask(pImage, pMask);
TextureData textureData = new PixmapTextureData(
pMask, //pixmap to use
Pixmap.Format.RGBA8888,
textureFilter, //use mipmaps
false, true);
t = new Texture(textureData);
if (textureFilter)
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
pImage.dispose();
pMask.dispose();
return t;
}
public Pixmap createRoundedRectangle(int width, int height, int cornerRadius, Color color) {
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
Pixmap ret = new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
//round corners
pixmap.fillCircle(cornerRadius, cornerRadius, cornerRadius);
pixmap.fillCircle(width - cornerRadius - 1, cornerRadius, cornerRadius);
pixmap.fillCircle(cornerRadius, height - cornerRadius - 1, cornerRadius);
pixmap.fillCircle(width - cornerRadius - 1, height - cornerRadius - 1, cornerRadius);
//two rectangle parts
pixmap.fillRectangle(cornerRadius, 0, width - cornerRadius * 2, height);
pixmap.fillRectangle(0, cornerRadius, width, height - cornerRadius * 2);
//draw rounded rectangle
ret.setColor(color);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (pixmap.getPixel(x, y) != 0) ret.drawPixel(x, y);
}
}
pixmap.dispose();
return ret;
}
public void drawPixelstoMask(Pixmap pixmap, Pixmap mask){
int pixmapWidth = mask.getWidth();
int pixmapHeight = mask.getHeight();
Color pixelColor = new Color();
for (int x=0; x<pixmapWidth; x++){
for (int y=0; y<pixmapHeight; y++){
if (mask.getPixel(x, y) != 0) {
Color.rgba8888ToColor(pixelColor, pixmap.getPixel(x, y));
mask.setColor(pixelColor);
mask.drawPixel(x, y);
}
}
}
}
public void blendPixmaps(Pixmap pixmap, Pixmap mask, Pixmap model){
int pixmapWidth = pixmap.getWidth();
int pixmapHeight = pixmap.getHeight();
Color pixelColor = new Color();
Color maskPixelColor = new Color();
for (int x=0; x<pixmapWidth; x++){
for (int y=0; y<pixmapHeight; y++){
Color.rgba8888ToColor(pixelColor, pixmap.getPixel(x, y));
Color.rgba8888ToColor(maskPixelColor, mask.getPixel(x, y));
pixelColor.a = pixelColor.a * maskPixelColor.a;
model.setColor(pixelColor);
model.drawPixel(x, y);
}
}
}
}

View File

@@ -35,12 +35,12 @@ public class CardImage implements FImage {
}
public static Color borderColor(PaperCard c) {
if (c == null)
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
CardEdition ed = FModel.getMagicDb().getEditions().get(c.getEdition());
if (ed != null && ed.isWhiteBorder())
return Color.valueOf("#fffffd");
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
}
@Override

View File

@@ -2,6 +2,7 @@ package forge.card;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Align;
import com.google.common.collect.ImmutableList;
import forge.Graphics;
@@ -323,11 +324,29 @@ public class CardImageRenderer {
x += pieceWidths[i];
}
}
public static TextureRegion croppedBorderImage(Texture image) {
float rscale = 0.96f;
int rw = Math.round(image.getWidth()*rscale);
int rh = Math.round(image.getHeight()*rscale);
int rx = Math.round((image.getWidth() - rw)/2);
int ry = Math.round((image.getHeight() - rh)/2);
TextureRegion rimage = new TextureRegion(image, rx, ry, rw, rh);
return rimage;
}
public static Color borderColor(CardView c) {
if (c == null)
return Color.valueOf("#1d1d1d");
CardStateView state = c.getCurrentState();
CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode());
if (ed != null && ed.isWhiteBorder() && state.getFoilIndex() == 0)
return Color.valueOf("#fffffd");
return Color.valueOf("#1d1d1d");
}
public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard) {
boolean mask = isPreferenceEnabled(ForgePreferences.FPref.UI_ENABLE_BORDER_MASKING);
//this one is currently using the mask, others are cropped and use generated borders from shaperenderer ...
final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(MatchController.instance.getLocalPlayers()), true, mask);
final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(MatchController.instance.getLocalPlayers()), true);
if (image == null) { //draw details if can't draw zoom
drawDetails(g, card, gameView, altState, x, y, w, h);
return;
@@ -344,21 +363,45 @@ public class CardImageRenderer {
drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top);
}
else {
float radius = (h - w)/8;
float wh_Adj = ForgeConstants.isGdxPortLandscape && isCurrentCard ? 1.38f:1.0f;
float new_w = w*wh_Adj;
float new_h = h*wh_Adj;
float new_x = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispW - new_w) / 2:x;
float new_y = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispH - new_h) / 2:y;
float new_xRotate = (dispW - new_h) /2;
float new_yRotate = (dispH - new_w) /2;
boolean rotateSplit = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS);
boolean rotatePlane = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON);
if (rotatePlane && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane())) {
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
if (mask){
if (rotatePlane)
g.fillRoundRect(borderColor(card), new_yRotate, new_yRotate, new_h, new_w, radius);
else
g.fillRoundRect(borderColor(card), x, y, w, h, radius);
g.drawRotatedImage(croppedBorderImage(image), new_x+radius/2.4f, new_y+radius/2, new_w*0.96f, new_h*0.96f, (new_x+radius/2.4f) + (new_w*0.96f) / 2, (new_y+radius/2) + (new_h*0.96f) / 2, -90);
}
else
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
} else if (rotateSplit && isCurrentCard && card.isSplitCard() && canLook) {
boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath");
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
if (mask){
if (rotateSplit)
g.fillRoundRect(borderColor(card), new_xRotate, new_yRotate, new_h, new_w, radius);
else
g.fillRoundRect(borderColor(card), x, y, w, h, radius);
g.drawRotatedImage(croppedBorderImage(image), new_x+radius/2.4f, new_y+radius/2, new_w*0.96f, new_h*0.96f, (new_x+radius/2.4f) + (new_w*0.96f) / 2, (new_y+radius/2) + (new_h*0.96f) / 2, isAftermath ? 90 : -90);
}
else
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
}
else {
g.drawImage(image, x, y, w, h);
if (mask) {
g.fillRoundRect(borderColor(card), x, y, w, h, radius);
g.drawImage(croppedBorderImage(image), x+radius/2.4f, y+radius/2, w*0.96f, h*0.96f);
}
else
g.drawImage(image, x, y, w, h);
}
}
CardRenderer.drawFoilEffect(g, card, x, y, w, h, isCurrentCard && canLook && image != ImageCache.defaultImage);

View File

@@ -402,22 +402,22 @@ public class CardRenderer {
}
public static Color borderColor(IPaperCard c) {
if (c == null)
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
CardEdition ed = FModel.getMagicDb().getEditions().get(c.getEdition());
if (ed != null && ed.isWhiteBorder())
return Color.valueOf("#fffffd");
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
}
public static Color borderColor(CardView c) {
if (c == null)
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
CardStateView state = c.getCurrentState();
CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode());
if (ed != null && ed.isWhiteBorder() && state.getFoilIndex() == 0)
return Color.valueOf("#fffffd");
return Color.valueOf("#1c1c1c");
return Color.valueOf("#1d1d1d");
}
public static void drawCard(Graphics g, IPaperCard pc, float x, float y, float w, float h, CardStackPosition pos) {
boolean mask = isPreferenceEnabled(FPref.UI_ENABLE_BORDER_MASKING);
@@ -431,7 +431,7 @@ public class CardRenderer {
if (mask) {
float radius = (h - w)/8;
g.fillRoundRect(borderColor(pc), x, y, w, h, radius);
g.drawImage(croppedBorderImage(image), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f);
g.drawImage(croppedBorderImage(image), x+radius/2.4f, y+radius/2, w*0.96f, h*0.96f);
}
else
g.drawImage(image, x, y, w, h);
@@ -466,7 +466,7 @@ public class CardRenderer {
if (mask) {
float radius = (h - w)/8;
g.fillRoundRect(borderColor(card), x, y, w, h, radius);
g.drawRotatedImage(croppedBorderImage(image), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f, (x+radius/2) + (w*0.96f) / 2, (y+radius/2) + (h*0.96f) / 2, -90);
g.drawRotatedImage(croppedBorderImage(image), x+radius/2.4f, y+radius/2, w*0.96f, h*0.96f, (x+radius/2.4f) + (w*0.96f) / 2, (y+radius/2) + (h*0.96f) / 2, -90);
}
else
g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90);
@@ -475,7 +475,7 @@ public class CardRenderer {
if (mask) {
float radius = (h - w)/8;
g.fillRoundRect(borderColor(card), x, y, w, h, radius);
g.drawImage(croppedBorderImage(image), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f);
g.drawImage(croppedBorderImage(image), x+radius/2.4f, y+radius/2, w*0.96f, h*0.96f);
}
else
g.drawImage(image, x, y, w, h);