From 7c660323f0189512c79f1d0cb55d015e17d885ef Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Sun, 7 Apr 2019 17:46:32 +0200 Subject: [PATCH] Use SVG graphics to draw chess pieces. Use SVG graphics to draw chess pieces instead of a custom font. This should fix the problem where some android devices ignore the requested font so the chess pieces are drawn as two overlapping regular letters. This should also make it easier to add alternative piece sets in the future. --- .../src/main/assets/fonts/ChessCases.ttf | Bin 9532 -> 0 bytes .../src/main/assets/pieces/chesscases.zip | Bin 0 -> 12467 bytes .../java/com/larvalabs/svgandroid/SVG.java | 4 +- .../com/larvalabs/svgandroid/SVGParser.java | 151 ++++++++++++------ .../java/org/petero/droidfish/DroidFish.java | 2 + .../java/org/petero/droidfish/PieceSet.java | 136 ++++++++++++++++ .../org/petero/droidfish/view/ChessBoard.java | 60 ++----- 7 files changed, 255 insertions(+), 98 deletions(-) delete mode 100644 DroidFishApp/src/main/assets/fonts/ChessCases.ttf create mode 100644 DroidFishApp/src/main/assets/pieces/chesscases.zip create mode 100644 DroidFishApp/src/main/java/org/petero/droidfish/PieceSet.java diff --git a/DroidFishApp/src/main/assets/fonts/ChessCases.ttf b/DroidFishApp/src/main/assets/fonts/ChessCases.ttf deleted file mode 100644 index b5a7a93a31b40a3577da3569f30ef6693d924766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9532 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 diff --git a/DroidFishApp/src/main/assets/pieces/chesscases.zip b/DroidFishApp/src/main/assets/pieces/chesscases.zip new file mode 100644 index 0000000000000000000000000000000000000000..ba32f4c2ea6b0781806fbcc658bd588668326ee6 GIT binary patch literal 12467 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 colorReplace) throws SVGParseException { + return SVGParser.parse(svgData, colorReplace, false); } /** * Parse SVG data from a string. * * @param svgData the string containing SVG XML data. - * @param searchColor the color in the SVG to replace. - * @param replaceColor the color with which to replace the search color. + * @param colorReplace Map from colors in the SVG to colors to use instead. May be null. * @return the parsed SVG. * @throws SVGParseException if there is an error while parsing. */ - public static SVG getSVGFromString(String svgData, int searchColor, int replaceColor) throws SVGParseException { - return SVGParser.parse(new ByteArrayInputStream(svgData.getBytes()), searchColor, replaceColor, false); + public static SVG getSVGFromString(String svgData, + HashMap colorReplace) throws SVGParseException { + return SVGParser.parse(new ByteArrayInputStream(svgData.getBytes()), colorReplace, false); } /** @@ -135,13 +136,13 @@ public class SVGParser { * * @param resources the Android context * @param resId the ID of the raw resource SVG. - * @param searchColor the color in the SVG to replace. - * @param replaceColor the color with which to replace the search color. + * @param colorReplace Map from colors in the SVG to colors to use instead. May be null. * @return the parsed SVG. * @throws SVGParseException if there is an error while parsing. */ - public static SVG getSVGFromResource(Resources resources, int resId, int searchColor, int replaceColor) throws SVGParseException { - return SVGParser.parse(resources.openRawResource(resId), searchColor, replaceColor, false); + public static SVG getSVGFromResource(Resources resources, int resId, + HashMap colorReplace) throws SVGParseException { + return SVGParser.parse(resources.openRawResource(resId), colorReplace, false); } /** @@ -149,15 +150,15 @@ public class SVGParser { * * @param assetMngr the Android asset manager. * @param svgPath the path to the SVG file in the application's assets. - * @param searchColor the color in the SVG to replace. - * @param replaceColor the color with which to replace the search color. + * @param colorReplace Map from colors in the SVG to colors to use instead. May be null. * @return the parsed SVG. * @throws SVGParseException if there is an error while parsing. * @throws IOException if there was a problem reading the file. */ - public static SVG getSVGFromAsset(AssetManager assetMngr, String svgPath, int searchColor, int replaceColor) throws SVGParseException, IOException { + public static SVG getSVGFromAsset(AssetManager assetMngr, String svgPath, + Map colorReplace) throws SVGParseException, IOException { InputStream inputStream = assetMngr.open(svgPath); - SVG svg = getSVGFromInputStream(inputStream, searchColor, replaceColor); + SVG svg = getSVGFromInputStream(inputStream, colorReplace); inputStream.close(); return svg; } @@ -172,7 +173,7 @@ public class SVGParser { return doPath(pathString); } - private static SVG parse(InputStream in, Integer searchColor, Integer replaceColor, boolean whiteMode) throws SVGParseException { + private static SVG parse(InputStream in, Map colorReplace, boolean whiteMode) throws SVGParseException { // Util.debug("Parsing SVG..."); try { // long start = System.currentTimeMillis(); @@ -181,7 +182,7 @@ public class SVGParser { XMLReader xr = sp.getXMLReader(); final Picture picture = new Picture(); SVGHandler handler = new SVGHandler(picture); - handler.setColorSwap(searchColor, replaceColor); + handler.setColorSwap(colorReplace); handler.setWhiteMode(whiteMode); xr.setContentHandler(handler); xr.parse(new InputSource(in)); @@ -405,17 +406,29 @@ public class SVGParser { case '6': case '7': case '8': - case '9': - if (prevCmd == 'm' || prevCmd == 'M') { - cmd = (char) (((int) prevCmd) - 1); - break; - } else if (prevCmd == 'c' || prevCmd == 'C') { - cmd = prevCmd; - break; - } else if (prevCmd == 'l' || prevCmd == 'L') { - cmd = prevCmd; - break; + case '9': { + boolean handled = true; + switch (prevCmd) { + case 'm': + cmd = 'l'; + break; + case 'M': + cmd = 'L'; + break; + case 'l': case 'L': + case 'c': case 'C': + case 's': case 'S': + case 'q': case 'Q': + case 't': case 'T': + cmd = prevCmd; + break; + default: + handled = false; + break; } + if (handled) + break; + } default: { ph.advance(); prevCmd = cmd; @@ -539,6 +552,44 @@ public class SVGParser { lastY = y; break; } + case 'Q': + case 'q': { + wasCurve = true; + float x1 = ph.nextFloat(); + float y1 = ph.nextFloat(); + float x = ph.nextFloat(); + float y = ph.nextFloat(); + if (cmd == 'q') { + x1 += lastX; + x += lastX; + y1 += lastY; + y += lastY; + } + p.quadTo(x1, y1, x, y); + lastX1 = x1; + lastY1 = y1; + lastX = x; + lastY = y; + break; + } + case 'T': + case 't': { + wasCurve = true; + float x = ph.nextFloat(); + float y = ph.nextFloat(); + if (cmd == 't') { + x += lastX; + y += lastY; + } + float x1 = 2 * lastX - lastX1; + float y1 = 2 * lastY - lastY1; + p.quadTo(x1, y1, x, y); + lastX1 = x1; + lastY1 = y1; + lastX = x; + lastY = y; + break; + } case 'A': case 'a': { float rx = ph.nextFloat(); @@ -778,8 +829,7 @@ public class SVGParser { RectF bounds = null; RectF limits = new RectF(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); - Integer searchColor = null; - Integer replaceColor = null; + Map colorReplace = null; boolean whiteMode = false; @@ -793,9 +843,8 @@ public class SVGParser { paint.setAntiAlias(true); } - public void setColorSwap(Integer searchColor, Integer replaceColor) { - this.searchColor = searchColor; - this.replaceColor = replaceColor; + public void setColorSwap(Map colorReplace) { + this.colorReplace = colorReplace; } public void setWhiteMode(boolean whiteMode) { @@ -934,19 +983,27 @@ public class SVGParser { private void doColor(Properties atts, Integer color, boolean fillMode) { int c = (0xFFFFFF & color) | 0xFF000000; - if (searchColor != null && searchColor.intValue() == c) { - c = replaceColor; + int opac = -1; + if (colorReplace != null) { + Integer replaceColor = colorReplace.get(c); + if (replaceColor != null) { + c = replaceColor; + opac = replaceColor >>> 24; + } + } + if (opac == -1) { + Float opacity = atts.getFloat("opacity", false); + if (opacity == null) { + opacity = atts.getFloat(fillMode ? "fill-opacity" : "stroke-opacity", false); + } + if (opacity == null) { + opac = 255; + } else { + opac = (int) (255 * opacity); + } } paint.setColor(c); - Float opacity = atts.getFloat("opacity", false); - if (opacity == null) { - opacity = atts.getFloat(fillMode ? "fill-opacity" : "stroke-opacity", false); - } - if (opacity == null) { - paint.setAlpha(255); - } else { - paint.setAlpha((int) (255 * opacity)); - } + paint.setAlpha(opac); } private boolean hidden = false; diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java b/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java index c0233ba..81ef19a 100644 --- a/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java +++ b/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java @@ -1370,6 +1370,7 @@ public class DroidFish extends Activity pgnOptions.exp.clockInfo = settings.getBoolean("exportTime", false); ColorTheme.instance().readColors(settings); + PieceSet.instance().readPrefs(settings); cb.setColors(); overrideViewAttribs(); @@ -2867,6 +2868,7 @@ public class DroidFish extends Activity builder.setSingleChoiceItems(themeNames, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { ColorTheme.instance().setTheme(settings, item); + PieceSet.instance().readPrefs(settings); cb.setColors(); gameTextListener.clear(); ctrl.prefsChanged(false); diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/PieceSet.java b/DroidFishApp/src/main/java/org/petero/droidfish/PieceSet.java new file mode 100644 index 0000000..fd2451b --- /dev/null +++ b/DroidFishApp/src/main/java/org/petero/droidfish/PieceSet.java @@ -0,0 +1,136 @@ +package org.petero.droidfish; + +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; + +import com.larvalabs.svgandroid.SVG; +import com.larvalabs.svgandroid.SVGParser; + +import org.petero.droidfish.gamelogic.Piece; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** Handle rendering of chess pieces. */ +public class PieceSet { + private static PieceSet inst = null; + + private HashMap nameToPieceType; + private SVG[] svgTable = new SVG[Piece.nPieceTypes]; + private Bitmap[] bitmapTable = new Bitmap[Piece.nPieceTypes]; + private int cachedSquareSize = -1; + private int cachedWhiteColor = 0xffffffff; + private int cachedBlackColor = 0xff000000; + + /** Get singleton instance. */ + public static PieceSet instance() { + if (inst == null) + inst = new PieceSet(); + return inst; + } + + private PieceSet() { + nameToPieceType = new HashMap<>(); + nameToPieceType.put("wk.svg", Piece.WKING); + nameToPieceType.put("wq.svg", Piece.WQUEEN); + nameToPieceType.put("wr.svg", Piece.WROOK); + nameToPieceType.put("wb.svg", Piece.WBISHOP); + nameToPieceType.put("wn.svg", Piece.WKNIGHT); + nameToPieceType.put("wp.svg", Piece.WPAWN); + nameToPieceType.put("bk.svg", Piece.BKING); + nameToPieceType.put("bq.svg", Piece.BQUEEN); + nameToPieceType.put("br.svg", Piece.BROOK); + nameToPieceType.put("bb.svg", Piece.BBISHOP); + nameToPieceType.put("bn.svg", Piece.BKNIGHT); + nameToPieceType.put("bp.svg", Piece.BPAWN); + + parseSvgData(cachedWhiteColor, cachedBlackColor); + } + + /** Re-parse SVG data if piece properties have changed. */ + final void readPrefs(SharedPreferences settings) { + ColorTheme ct = ColorTheme.instance(); + int whiteColor = ct.getColor(ColorTheme.BRIGHT_PIECE); + int blackColor = ct.getColor(ColorTheme.DARK_PIECE); + if (whiteColor != cachedWhiteColor || blackColor != cachedBlackColor) { + recycleBitmaps(); + parseSvgData(whiteColor, blackColor); + cachedWhiteColor = whiteColor; + cachedBlackColor = blackColor; + cachedSquareSize = -1; + } + } + + /** Return a bitmap for the specified piece type and square size. */ + public Bitmap getPieceBitmap(int pType, int sqSize) { + if (sqSize != cachedSquareSize) { + recycleBitmaps(); + createBitmaps(sqSize); + cachedSquareSize = sqSize; + } + return bitmapTable[pType]; + } + + private void parseSvgData(int whiteColor, int blackColor) { + HashMap colorReplace = new HashMap<>(); + colorReplace.put(0xffffffff, whiteColor); + colorReplace.put(0xff000000, blackColor); + try { + ZipInputStream zis = getZipStream(); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.isDirectory()) { + String name = entry.getName(); + Integer pType = nameToPieceType.get(name); + if (pType != null) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buf = new byte[4096]; + int len; + while ((len = zis.read(buf)) != -1) + bos.write(buf, 0, len); + buf = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(buf); + svgTable[pType] = SVGParser.getSVGFromInputStream(bis, colorReplace); + } + } + zis.closeEntry(); + } + zis.close(); + } catch (IOException ex) { + throw new RuntimeException("Cannot read chess pieces data", ex); + } + } + + private ZipInputStream getZipStream() throws IOException { + InputStream is = DroidFishApp.getContext().getAssets().open("pieces/chesscases.zip"); + return new ZipInputStream(is); + } + + private void recycleBitmaps() { + for (int i = 0; i < Piece.nPieceTypes; i++) { + if (bitmapTable[i] != null) { + bitmapTable[i].recycle(); + bitmapTable[i] = null; + } + } + } + + private void createBitmaps(int sqSize) { + for (int i = 0; i < Piece.nPieceTypes; i++) { + SVG svg = svgTable[i]; + if (svg != null) { + Bitmap bm = Bitmap.createBitmap(sqSize, sqSize, Bitmap.Config.ARGB_8888); + Canvas bmCanvas = new Canvas(bm); + bmCanvas.drawPicture(svg.getPicture(), new Rect(0, 0, sqSize, sqSize)); + bitmapTable[i] = bm; + } + } + } +} diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java b/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java index 598698c..c0e3c92 100644 --- a/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java +++ b/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.List; import org.petero.droidfish.ColorTheme; +import org.petero.droidfish.PieceSet; import org.petero.droidfish.gamelogic.Move; import org.petero.droidfish.gamelogic.Piece; import org.petero.droidfish.gamelogic.Position; @@ -30,12 +31,12 @@ import org.petero.droidfish.gamelogic.UndoInfo; import org.petero.droidfish.tb.ProbeResult; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; -import android.graphics.Typeface; import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; @@ -51,7 +52,6 @@ public abstract class ChessBoard extends View { public boolean cursorVisible; protected int x0, y0; public int sqSize; - int pieceXDelta, pieceYDelta; // top/left pixel draw position relative to square public boolean flipped; public boolean drawSquareLabels; public boolean toggleSelection; @@ -79,8 +79,7 @@ public abstract class ChessBoard extends View { protected Paint brightPaint; private Paint selectedSquarePaint; private Paint cursorSquarePaint; - private Paint whitePiecePaint; - private Paint blackPiecePaint; + private Paint piecePaint; private Paint labelPaint; private Paint decorationPaint; private ArrayList moveMarkPaint; @@ -93,7 +92,6 @@ public abstract class ChessBoard extends View { cursorX = cursorY = 0; cursorVisible = false; x0 = y0 = sqSize = 0; - pieceXDelta = pieceYDelta = -1; flipped = false; drawSquareLabels = false; toggleSelection = false; @@ -111,11 +109,8 @@ public abstract class ChessBoard extends View { cursorSquarePaint.setStyle(Paint.Style.STROKE); cursorSquarePaint.setAntiAlias(true); - whitePiecePaint = new Paint(); - whitePiecePaint.setAntiAlias(true); - - blackPiecePaint = new Paint(); - blackPiecePaint.setAntiAlias(true); + piecePaint = new Paint(); + piecePaint.setAntiAlias(true); labelPaint = new Paint(); labelPaint.setAntiAlias(true); @@ -134,10 +129,6 @@ public abstract class ChessBoard extends View { if (isInEditMode()) return; - Typeface chessFont = Typeface.createFromAsset(getContext().getAssets(), "fonts/ChessCases.ttf"); - whitePiecePaint.setTypeface(chessFont); - blackPiecePaint.setTypeface(chessFont); - setColors(); } @@ -148,8 +139,6 @@ public abstract class ChessBoard extends View { brightPaint.setColor(ct.getColor(ColorTheme.BRIGHT_SQUARE)); selectedSquarePaint.setColor(ct.getColor(ColorTheme.SELECTED_SQUARE)); cursorSquarePaint.setColor(ct.getColor(ColorTheme.CURSOR_SQUARE)); - whitePiecePaint.setColor(ct.getColor(ColorTheme.BRIGHT_PIECE)); - blackPiecePaint.setColor(ct.getColor(ColorTheme.DARK_PIECE)); labelPaint.setColor(ct.getColor(ColorTheme.SQUARE_LABEL)); decorationPaint.setColor(ct.getColor(ColorTheme.DECORATION)); for (int i = 0; i < ColorTheme.MAX_ARROWS; i++) @@ -369,7 +358,6 @@ public abstract class ChessBoard extends View { int sqSizeW = getSqSizeW(width); int sqSizeH = getSqSizeH(height); int sqSize = Math.min(sqSizeW, sqSizeH); - pieceXDelta = pieceYDelta = -1; labelBounds = null; if (height > width) { int p = getMaxHeightPercentage(); @@ -394,8 +382,6 @@ public abstract class ChessBoard extends View { final int width = getWidth(); final int height = getHeight(); sqSize = Math.min(getSqSizeW(width), getSqSizeH(height)); - blackPiecePaint.setTextSize(sqSize); - whitePiecePaint.setTextSize(sqSize); labelPaint.setTextSize(sqSize/4.0f); decorationPaint.setTextSize(sqSize/3.0f); computeOrigin(width, height); @@ -507,41 +493,15 @@ public abstract class ChessBoard extends View { protected final void drawPiece(Canvas canvas, int xCrd, int yCrd, int p) { if (blindMode) return; - String psb, psw; - boolean rotate = false; - switch (p) { - default: - case Piece.EMPTY: psb = null; psw = null; break; - case Piece.WKING: psb = "H"; psw = "k"; break; - case Piece.WQUEEN: psb = "I"; psw = "l"; break; - case Piece.WROOK: psb = "J"; psw = "m"; break; - case Piece.WBISHOP: psb = "K"; psw = "n"; break; - case Piece.WKNIGHT: psb = "L"; psw = "o"; break; - case Piece.WPAWN: psb = "M"; psw = "p"; break; - case Piece.BKING: psb = "N"; psw = "q"; rotate = true; break; - case Piece.BQUEEN: psb = "O"; psw = "r"; rotate = true; break; - case Piece.BROOK: psb = "P"; psw = "s"; rotate = true; break; - case Piece.BBISHOP: psb = "Q"; psw = "t"; rotate = true; break; - case Piece.BKNIGHT: psb = "R"; psw = "u"; rotate = true; break; - case Piece.BPAWN: psb = "S"; psw = "v"; rotate = true; break; - } - if (psb != null) { - if (pieceXDelta < 0) { - Rect bounds = new Rect(); - blackPiecePaint.getTextBounds("H", 0, 1, bounds); - pieceXDelta = (sqSize - (bounds.left + bounds.right)) / 2; - pieceYDelta = (sqSize - (bounds.top + bounds.bottom)) / 2; - } - rotate ^= flipped; - rotate = false; // Disabled for now + + Bitmap bm = PieceSet.instance().getPieceBitmap(p, sqSize); + if (bm != null) { + boolean rotate = flipped & false; // Disabled for now if (rotate) { canvas.save(); canvas.rotate(180, xCrd + sqSize * 0.5f, yCrd + sqSize * 0.5f); } - xCrd += pieceXDelta; - yCrd += pieceYDelta; - canvas.drawText(psw, xCrd, yCrd, whitePiecePaint); - canvas.drawText(psb, xCrd, yCrd, blackPiecePaint); + canvas.drawBitmap(bm, xCrd, yCrd, piecePaint); if (rotate) canvas.restore(); }