--- /dev/null
+.project
+.classpath
+.settings/
+.svn/
+target/
+bin/
+out/
+*.ipr
+*.iml
+.idea
+.java-version
--- /dev/null
+CHANGELOG Hedgecode ChessHog
+============================
+
+v.0.1 [2020-XX-XX]
+------------------
+- Initial release of the project
+- ...
--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+***************************************************************************
+
+ Copyright (c) 2018-2020 Hedgecode. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
--- /dev/null
+
+Hedgecode ChessHog
+Copyright (c) 2018-2020 Hedgecode. All rights reserved.
+
+This product includes software developed at
+Hedgecode (https://hedgecode.org/).
--- /dev/null
+## Hedgecode ChessHog
+
+### Description
+
+Hedgecode ChessHog is a chess project that includes modules with different functionality, such as:
+
+* own internal format for the presentation of chess games and positions, which makes
+ it possible to use this project as API library for various chess Java applications;
+* ability to work with various formats of chess games and diagrams (e.g. PGN, FEN),
+ including the functionality of generating chess positions in ASCII format,
+ as well as Wikipedia format;
+* provide full functionality for working with UCI (Universal Chess Interface) protocol,
+ which allows both connecting external UCI engines and developing your own
+ using API of UCI module with a set of necessary interfaces described in it;
+* building chess diagrams in the form of images with a diverse set of chess pieces;
+* ability to record chess games and positions in the form of a QR code,
+ as well as recognition of this chess QR code.
+
+### Links
+
+Below are links to the project description pages:
+- [ENG](https://lib.hedgecode.org/chesshog/)
+- [RUS](https://lib.hedgecode.org/chesshog/ru/)
+
+Copyright © 2018–2020 [Hedgecode](https://hedgecode.org/).
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
public static void main(String[] args) {
+ ChessHogConsole.init();
}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess;
+
+import java.time.LocalDateTime;
+import java.util.Calendar;
+
+/**
+ * ChessHog utility class for working with console.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ChessHogConsole {
+
+ private static final String[] ASCII_LOGO = {
+ " _______ _ _ ",
+ " | | _|_ _| |___ ___ ___ ___ _| |___ ",
+ " | | -_| . | . | -_| _| . | . | -_| ",
+ " | |___|___|_ |___|___|___|___|___| ",
+ " |___|___| |___| _ _ ",
+ " ___| |_ ___ ___ ___| |_ ___ ___ ",
+ " | _| | -_|_ -|_ -| | . | . | ",
+ " |___|_|_|___|___|___|_|_|___|_ | ",
+ " |___| "
+ };
+
+ private static final String COPYRIGHT = "Copyright (c) Hedgecode";
+
+ private static boolean logMode = false;
+
+ private ChessHogConsole() {
+ }
+
+ public static void setLogMode(boolean isLogMode) {
+ logMode = isLogMode;
+ }
+
+ public static void console(String message) {
+ System.out.println(
+ String.format(
+ logMode ? "[%1$tT] %2$s" : "%2$s",
+ LocalDateTime.now(),
+ message == null ? "" : message
+ )
+ );
+ }
+
+ public static void empty() {
+ console(null);
+ }
+
+ public static void init() {
+ asciiLogo();
+ copyright();
+ version();
+ empty();
+ os();
+ java();
+ }
+
+ private static void asciiLogo() {
+ for (String line : ASCII_LOGO) {
+ console(line);
+ }
+ }
+
+ private static void copyright() {
+ int inceptionYear = Integer.parseInt(
+ ChessHogProperties.get("chesshog.inception.year")
+ );
+ int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+ String copyright = currentYear > inceptionYear
+ ? String.format("%s-%s %s", inceptionYear, currentYear, COPYRIGHT)
+ : String.format("%s %s", currentYear, COPYRIGHT);
+ console(
+ alignCenter(copyright)
+ );
+ }
+
+ private static void version() {
+ console(
+ alignCenter(
+ String.format(
+ "v. %s", ChessHogProperties.get("chesshog.version")
+ )
+ )
+ );
+ }
+
+ private static void os() {
+ console(
+ String.format(
+ "OS: %s %s %s",
+ System.getProperty("os.name"),
+ System.getProperty("os.version"),
+ System.getProperty("os.arch")
+ )
+ );
+ }
+
+ private static void java() {
+ console(
+ String.format(
+ "JRE: %s %s",
+ System.getProperty("java.runtime.name"),
+ System.getProperty("java.runtime.version")
+ )
+ );
+ console(
+ String.format(
+ "JVM: %s %s %s",
+ System.getProperty("java.vm.vendor"),
+ System.getProperty("java.vm.name"),
+ System.getProperty("java.vm.version")
+ )
+ );
+ }
+
+ private static String alignCenter(String message) {
+ int indent = (ASCII_LOGO[0].length() + message.length()) / 2;
+ return String.format(
+ "%" + indent + "s",
+ message
+ );
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * ChessHog properties holder.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ChessHogProperties {
+
+ /** Properties file. */
+ private static final String PROPERTIES_FILE = "chesshog.properties";
+
+ /** Properties. */
+ private static final Properties PROPERTIES;
+
+ /**
+ * Static properties initialization.
+ */
+ static {
+ PROPERTIES = new Properties();
+ readProperties(PROPERTIES_FILE, PROPERTIES, true);
+ }
+
+ /**
+ * @param propsFile Properties file name.
+ * @param props Properties.
+ * @param throwExc Flag indicating whether to throw an exception or not.
+ */
+ public static void readProperties(String propsFile, Properties props, boolean throwExc) {
+ try (InputStream is = ChessHogProperties.class.getClassLoader().getResourceAsStream(propsFile)) {
+ if (is == null) {
+ if (throwExc)
+ throw new RuntimeException("Failed to find properties file: " + propsFile);
+ else
+ return;
+ }
+
+ props.load(is);
+ }
+ catch (IOException e) {
+ throw new RuntimeException("Failed to read properties file: " + propsFile, e);
+ }
+ }
+
+ /**
+ * Empty string for not found properties.
+ */
+ private static final String EMPTY = "";
+
+ /**
+ * Gets property value.
+ *
+ * @param key Property key.
+ * @return Property value (possibly empty string, but never {@code null}).
+ */
+ public static String get(String key) {
+ return PROPERTIES.getProperty(key, EMPTY);
+ }
+
+ /**
+ * Private constructor.
+ */
+ private ChessHogProperties() {
+ }
+
+}
--- /dev/null
+# Copyright (c) 2018-2019. Developed by Hedgecode.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+chesshog.version=0.1-SNAPSHOT
+chesshog.build=0
+chesshog.revision=DEV
+chesshog.inception.year=2018
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Hedgecode ChessHog DB Engine Module</name>
+ <name>Hedgecode ChessHog DB Etude</name>
<description>
- Hedgecode ChessHog DB Engine Module.
+ Hedgecode ChessHog DB Etude Module.
</description>
<properties>
- <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
<hibernateCoreVersion>5.3.7.Final</hibernateCoreVersion>
<hibernateJpaApiVersion>1.0.1.Final</hibernateJpaApiVersion>
<mysqlVersion>8.0.13</mysqlVersion>
<dependencies>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog</artifactId>
- <version>${chessHogVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.hedgecode.chess</groupId>
<artifactId>chesshog-core</artifactId>
<version>${chessHogVersion}</version>
</dependency>
--- /dev/null
+/*
+ * Copyright (c) 2018. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.db
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+
+import javax.persistence.Persistence
+
+def factory = Persistence.createEntityManagerFactory("db-etude-persistence-unit")
+def manager = factory.createEntityManager()
+
+manager.getTransaction().begin()
+
+//manager.persist new ServerNode(firstName: "Test", lastName: "Server")
+
+manager.getTransaction().commit()
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Hedgecode ChessHog Format Module.
</description>
- <properties>
- <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog</artifactId>
- <version>${chessHogVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.hedgecode.chess</groupId>
<artifactId>chesshog-core</artifactId>
<version>${chessHogVersion}</version>
</dependency>
+++ /dev/null
-/*
- * Copyright (c) 2018-2019. Developed by Hedgecode.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.hedgecode.chess.img;
-
-import java.io.File;
-
-/**
- *
- *
- * @author Dmitry Samoshin aka gotty
- */
-public abstract class AbstractImageLoader implements ImageLoader {
-
- protected static final File IMAGES_PATH = new File(
- ImageLoader.class.getResource(
- ImageConstants.RESOURCE_ROOT_DIR + ImageConstants.RESOURCE_IMAGES_DIR
- ).getPath()
- );
-
- private Type loadType;
-
- public AbstractImageLoader() {
- this.loadType = Type.STATELESS;
- }
-
- protected abstract void clear();
-
- @Override
- public Type loadType() {
- return loadType;
- }
-
- protected void setLoadType(Type loadType) {
- if (Type.STATELESS.equals(loadType)) {
- clear();
- }
- this.loadType = loadType;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2018-2019. Developed by Hedgecode.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.hedgecode.chess.img.board;
-
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.imageio.ImageIO;
-
-import org.hedgecode.chess.img.AbstractImageLoader;
-import org.hedgecode.chess.img.ImageConstants;
-import org.hedgecode.chess.img.ImageException;
-import org.hedgecode.chess.img.ImageFilter;
-
-/**
- *
- *
- * @author Dmitry Samoshin aka gotty
- */
-public class BoardLoader extends AbstractImageLoader {
-
- private static final File SQUARES_PATH = new File(IMAGES_PATH, ImageConstants.RESOURCE_SQUARES_DIR);
-
- private static final String SQUARE_DARK = ImageConstants.DARK_SQUARE_FILENAME;
- private static final String SQUARE_LIGHT = ImageConstants.LIGHT_SQUARE_FILENAME;
-
- private static final String[] SQUARE_NAMES = {SQUARE_DARK, SQUARE_LIGHT};
-
- private Map<String, Board> squareSetMap = new HashMap<>();
-
- @Override
- public Board load(String name) throws ImageException {
- Board board = null;
- SquarePair<BufferedImage> squarePair = null;
- if (Type.STATELESS.equals(loadType()) || !squareSetMap.containsKey(name)) {
- File boardPath = new File(SQUARES_PATH, name);
- if (boardPath.exists() && boardPath.isDirectory()) {
- squarePair = loadSquares(name, boardPath);
- }
- if (squarePair != null) {
- board = Board.create(squarePair);
- if (Type.STATEFUL.equals(loadType())) {
- squareSetMap.put(name, board);
- }
- }
- } else {
- board = squareSetMap.get(name);
- }
- return board;
- }
-
- @Override
- public void unload(String name) {
- if (Type.STATEFUL.equals(loadType()) && squareSetMap.containsKey(name)) {
- squareSetMap.remove(name);
- }
- }
-
- @Override
- protected void clear() {
- squareSetMap.clear();
- }
-
- private SquarePair<BufferedImage> loadSquares(String name, File boardPath) throws ImageException {
- BufferedImage dark = null, light = null;
- File[] images = boardPath.listFiles(new ImageFilter(SQUARE_NAMES));
- if (images != null) {
- for (File image : images) {
- if (image.isFile()) {
- String filename = image.getName();
- try {
- switch (filename.substring(0, filename.lastIndexOf('.'))) {
- case SQUARE_DARK:
- dark = ImageIO.read(image);
- break;
- case SQUARE_LIGHT:
- light = ImageIO.read(image);
- break;
- }
- } catch (IOException e) {
- throw new ImageException(e.getMessage()); // todo: locale
- }
- }
- }
- }
- return (dark != null && light != null) ? SquarePair.create(dark, light) : null;
- }
-
-}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.hedgecode.chess</groupId>
+ <artifactId>chesshog</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chesshog-graphics</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Hedgecode ChessHog Graphics</name>
+ <description>
+ Hedgecode ChessHog Graphics Module.
+ </description>
+
+ <properties>
+ <transcoderVersion>1.11</transcoderVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.hedgecode.chess</groupId>
+ <artifactId>chesshog-core</artifactId>
+ <version>${chessHogVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hedgecode.chess</groupId>
+ <artifactId>chesshog-format</artifactId>
+ <version>${chessHogVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.xmlgraphics</groupId>
+ <artifactId>batik-transcoder</artifactId>
+ <version>${transcoderVersion}</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+import java.awt.image.BufferedImage;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hedgecode.chess.img.fs.FileSystemDetector;
+import org.hedgecode.chess.img.fs.FileSystemContractor;
+
+/**
+ * Abstract common image loader with type state of saved resources.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public abstract class AbstractImageLoader implements ImageLoader {
+
+ private static final String IMAGES_DIR =
+ ImageConstants.RESOURCE_ROOT_DIR.concat(ImageConstants.RESOURCE_IMAGES_DIR);
+
+ private static final int DEF_IMAGE_SIZE = 100;
+
+ private Type loadType;
+
+ private URI imageResourceUri;
+
+ public AbstractImageLoader() {
+ loadType = Type.STATELESS;
+ try {
+ if (FileSystemDetector.detectJar(getImageResourceUri())) {
+ loadType = Type.STATEFUL;
+ }
+ } catch (ImageException ignored) {
+ }
+ }
+
+ protected abstract void clear();
+
+ @Override
+ public Type loadType() {
+ return loadType;
+ }
+
+ protected void setLoadType(Type loadType) {
+ if (Type.STATELESS.equals(loadType)) {
+ clear();
+ }
+ this.loadType = loadType;
+ }
+
+ protected URI getImageResourceUri() throws ImageException {
+ if (imageResourceUri == null) {
+ try {
+ imageResourceUri = getClass().getResource(IMAGES_DIR).toURI();
+ } catch (URISyntaxException e) {
+ throw new ImageException("image.unable.access.resource");
+ }
+ }
+ return imageResourceUri;
+ }
+
+ protected Map<String, BufferedImage> loadImages(String imagesPath, ImageFilter filter)
+ throws ImageException
+ {
+ return loadImages(imagesPath, filter, DEF_IMAGE_SIZE);
+ }
+
+ protected Map<String, BufferedImage> loadImages(String imagesPath, ImageFilter filter, int size)
+ throws ImageException
+ {
+ Map<String, BufferedImage> images = new HashMap<>();
+ try (FileSystemContractor fsc = FileSystemDetector.detect(getImageResourceUri())) {
+ try (DirectoryStream<Path> ds =
+ Files.newDirectoryStream(
+ fsc.getPath(imagesPath), filter
+ )
+ ) {
+ ImageFormatShaper formatShaper = ImageFormatShaper.getInstance();
+ for (Path file : ds) {
+ String fileName = file.getFileName().toString();
+ String baseName = FilenameUtils.getBaseName(fileName).toLowerCase();
+ String imageFormat = FilenameUtils.getExtension(fileName).toLowerCase();
+ images.put(
+ baseName,
+ formatShaper.shape(
+ imageFormat,
+ fsc.getResourceAsStream(file),
+ size
+ )
+ );
+ }
+ }
+ } catch (Exception e) {
+ throw new ImageException("image.unable.access.resource", e.getMessage());
+ }
+ return images;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+import java.awt.image.RenderedImage;
+
+import org.hedgecode.chess.position.Position;
+
+/**
+ * Storage class for chess diagrams.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class Diagram {
+
+ private Position position;
+ private RenderedImage image;
+
+ Diagram(Position position, RenderedImage image) {
+ this.position = position;
+ this.image = image;
+ }
+
+ public Position getPosition() {
+ return position;
+ }
+
+ public RenderedImage getImage() {
+ return image;
+ }
+
+}
/*
- * Copyright (c) 2018. Developed by Hedgecode.
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import org.hedgecode.chess.position.Square;
/**
- *
+ * Builder for chess diagrams.
*
* @author Dmitry Samoshin aka gotty
*/
}
@Override
- public String build(Position position) {
- return ""; // todo
- }
-
- @Override
- public RenderedImage build(Position position, String boardType, String pieceType)
+ public Diagram build(Position position, String boardType, String pieceType)
throws ImageException
{
Map<Square, ColorPiece> squares = position.getSquares();
PieceSet pieces = pieceSetLoader.load(pieceType);
if (board == null || pieces == null) {
- throw new ImageException("Couldn't find image resources!"); // todo: locale
+ throw new ImageException("image.unable.find.resource");
}
int squareSize = board.squareSize();
- BufferedImage diagram = board.render();
- Graphics diagramGraphics = diagram.getGraphics();
+ BufferedImage image = board.getBoard();
+ Graphics imageGraphics = image.getGraphics();
for (int y = 0; y < Square.getSize(); ++y) {
for (int x = 0; x < Square.getSize(); ++x) {
Square square = Square.getSquare(x, Square.getSize() - (y + 1));
ColorPiece colorPiece = squares.get(square);
if (colorPiece != null) {
- diagramGraphics.drawImage(
+ imageGraphics.drawImage(
pieces.get(colorPiece).getScaledInstance(
squareSize, squareSize, Image.SCALE_SMOOTH
- ),
+ ), // todo: scale in other place
x * squareSize,
y * squareSize,
null
}
}
}
- return diagram;
+ return new Diagram(
+ position, image
+ );
}
public static ImageBuilder getInstance() {
public static void main(String[] args) throws IOException, ImageException {
ImageIO.write(
- DiagramBuilder.getInstance().build(Positions.INITIAL.getPosition(), "test", "shade"),
+ DiagramBuilder.getInstance().build(
+ Positions.INITIAL.getPosition(), "test", "chess24"
+ ).getImage(),
ImageFormat.PNG.name(),
new File("chessboard" + "." + ImageFormat.PNG.getExt())
);
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+/**
+ * Utilities for path, file name and extension manipulation.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class FilenameUtils {
+
+ private static final String EMPTY_STRING = "";
+
+ private static final char EXTENSION_SEPARATOR = '.';
+
+ private static final char UNIX_SEPARATOR = '/';
+ private static final char WINDOWS_SEPARATOR = '\\';
+
+ private static final String PATH_COLON = ":";
+
+ private static final String JAR_SEPARATOR = ".jar!";
+
+ private static final String OS = System.getProperty("os.name").toLowerCase();
+
+ private static final String WIN_OS_TEMPLATE = "win";
+
+ public static String getName(final String fileName) {
+ if (fileName == null) {
+ return null;
+ }
+ final int endPathIndex = Math.max(
+ fileName.lastIndexOf(UNIX_SEPARATOR),
+ fileName.lastIndexOf(WINDOWS_SEPARATOR)
+ );
+ return fileName.substring(endPathIndex + 1);
+ }
+
+ public static String getBaseName(final String fileName) {
+ return removeExtension(
+ getName(fileName)
+ );
+ }
+
+ public static String getExtension(final String fileName) {
+ if (fileName == null) {
+ return null;
+ }
+ final int extensionPos = fileName.lastIndexOf(EXTENSION_SEPARATOR);
+ return extensionPos < 0
+ ? EMPTY_STRING
+ : fileName.substring(extensionPos + 1);
+ }
+
+ public static String getFullPath(final String parentDir, final String... childDirs) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(parentDir);
+ if (childDirs.length > 0) {
+ for (String childDir : childDirs) {
+ sb.append(isWindows() ? WINDOWS_SEPARATOR : UNIX_SEPARATOR).append(childDir);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static String fixPath(final String path) {
+ if (isWindows()) {
+ return path.startsWith(String.valueOf(UNIX_SEPARATOR))
+ && path.contains(PATH_COLON)
+ ? path.substring(1)
+ : path;
+ }
+ return path;
+ }
+
+ public static String getPathFromJar(final String jarPath) {
+ final int jarEndPos = jarPath.lastIndexOf(JAR_SEPARATOR);
+ return jarEndPos < 0
+ ? EMPTY_STRING
+ : jarPath.substring(jarEndPos + JAR_SEPARATOR.length());
+ }
+
+ private static String removeExtension(final String fileName) {
+ if (fileName == null) {
+ return null;
+ }
+ final int extensionPos = fileName.lastIndexOf(EXTENSION_SEPARATOR);
+ return extensionPos < 0
+ ? fileName
+ : fileName.substring(0, extensionPos);
+ }
+
+ private static boolean isWindows() {
+ return (OS.contains(WIN_OS_TEMPLATE));
+ }
+
+ private FilenameUtils() {
+ throw new AssertionError(
+ "No org.hedgecode.chess.img.FilenameUtils instances!"
+ );
+ }
+
+}
package org.hedgecode.chess.img;
+import org.hedgecode.chess.position.Position;
+
/**
- * Image working Exception.
+ * Common image builder interface.
*
* @author Dmitry Samoshin aka gotty
*/
-public class ImageException extends Exception {
-
- private String message;
-
- public ImageException(String message) {
- this.message = message;
- }
+public interface ImageBuilder {
- public String getMessage() {
- return message;
- }
+ Diagram build(Position position, String boardType, String pieceType) throws ImageException;
}
public static final String DARK_SQUARE_FILENAME = "dark";
public static final String LIGHT_SQUARE_FILENAME = "light";
+ public static final String BOARD_FILENAME = "board";
+
+ public static final String LOCALE_BUNDLE_FILE = "org.hedgecode.chess.img.LocalStrings";
private ImageConstants() {
throw new AssertionError(
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+import java.util.ResourceBundle;
+
+/**
+ * Image load/build Exception.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ImageException extends Exception {
+
+ private static final ResourceBundle LOCALE_BUNDLE =
+ ResourceBundle.getBundle(ImageConstants.LOCALE_BUNDLE_FILE);
+
+ private String localeKey;
+ private String message;
+
+ public ImageException(String localeKey) {
+ this.localeKey = localeKey;
+ this.message = null;
+ }
+
+ public ImageException(String localeKey, String message) {
+ this.localeKey = localeKey;
+ this.message = message;
+ }
+
+ public String getLocaleKey() {
+ return localeKey;
+ }
+
+ public String getMessage() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(LOCALE_BUNDLE.getString(localeKey));
+ if (message != null)
+ sb.append(": [").append(message).append("]");
+ return sb.toString();
+ }
+
+}
package org.hedgecode.chess.img;
-import java.io.File;
-import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
/**
- *
+ * Filter for images by name and extention.
*
* @author Dmitry Samoshin aka gotty
+ * @see DirectoryStream.Filter
*/
-public class ImageFilter implements FilenameFilter {
+public class ImageFilter implements DirectoryStream.Filter<Path> {
private static final String[] IMAGES_EXTS = ImageFormat.getAllExts();
}
@Override
- public boolean accept(File dir, String name) {
- return isImageName(name) && isImageExt(name);
+ public boolean accept(Path file) throws IOException {
+ if (Files.isDirectory(file)) {
+ return false;
+ }
+ String filename = file.getFileName().toString();
+ return acceptExt(filename) && acceptName(filename);
}
- private boolean isImageName(String name) {
+ private boolean acceptName(String filename) {
if (names != null) {
- name = name.substring(0, name.lastIndexOf('.'));
+ String name = FilenameUtils.getBaseName(filename);
for (String imageName : names) {
if (imageName.equalsIgnoreCase(name))
return true;
return true;
}
- private boolean isImageExt(String ext) {
- ext = ext.substring(ext.lastIndexOf('.') + 1);
+ private boolean acceptExt(String filename) {
+ String ext = FilenameUtils.getExtension(filename);
for (String imageExt : IMAGES_EXTS) {
if (imageExt.equalsIgnoreCase(ext))
return true;
/*
- * Copyright (c) 2018. Developed by Hedgecode.
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import javax.imageio.ImageIO;
/**
- * Supported image formats for reading/writing.
+ * Supported image formats for reading/writing, indicated by type.
*
* @author Dmitry Samoshin aka gotty
*/
public enum ImageFormat {
- PNG ( new String[]{"png"} ),
- GIF ( new String[]{"gif"} ),
- JPG ( new String[]{"jpg", "jpeg"} ),
- SVG ( new String[]{"svg"} ), // todo
- BMP ( new String[]{"bmp", "wbmp"} );
+ PNG ( Type.BITMAP, new String[]{"png"} ),
+ GIF ( Type.BITMAP, new String[]{"gif"} ),
+ JPG ( Type.BITMAP, new String[]{"jpg", "jpeg"} ),
+ BMP ( Type.BITMAP, new String[]{"bmp", "wbmp"} ),
+ SVG ( Type.VECTOR, new String[]{"svg"} );
- private String[] fortmatExts;
+ enum Type {
+
+ BITMAP,
+ VECTOR
+
+ }
+
+ private Type formatType;
+ private String[] formatExts;
private boolean isRead;
private boolean isWrite;
private static String[] allAvailableExts;
- ImageFormat(String[] exts) {
- fortmatExts = exts;
+ ImageFormat(Type type, String[] exts) {
+ formatType = type;
+ formatExts = exts;
isRead = isExist(
- ImageIO.getReaderFormatNames(), fortmatExts
+ ImageIO.getReaderFormatNames(), formatExts
);
isWrite = isExist(
- ImageIO.getWriterFormatNames(), fortmatExts
+ ImageIO.getWriterFormatNames(), formatExts
);
}
+ public Type getType() {
+ return formatType;
+ }
+
public String getExt() {
- return fortmatExts[0];
+ return formatExts[0];
}
public String[] getExts() {
- return fortmatExts;
+ return formatExts;
}
public boolean isRead() {
return false;
}
-
-/*
- public static void main(String[] args) {
- ImageFormat imageFormat = JPG;
- System.out.println("Supported format: " + imageFormat);
- imageFormat = findFormat("jpeg");
- imageFormat = findFormat("svg");
- imageFormat = findFormat("jpeeg");
- }
-*/
-
}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hedgecode.chess.img.bitmap.BitmapImageShaper;
+import org.hedgecode.chess.img.vector.VectorImageShaper;
+
+import static org.hedgecode.chess.img.ImageFormat.Type;
+
+/**
+ * Shaper for images, indicated by type format.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class ImageFormatShaper {
+
+ private static ImageFormatShaper _instance = new ImageFormatShaper();
+
+ private Map<Type, ImageShaper> imageShapers = new HashMap<>();
+
+ private ImageFormatShaper() {
+ imageShapers.put(
+ Type.BITMAP,
+ BitmapImageShaper.create()
+ );
+ imageShapers.put(
+ Type.VECTOR,
+ VectorImageShaper.create()
+ );
+ }
+
+ public BufferedImage shape(String imageFormat, InputStream imageStream, int size)
+ throws ImageException
+ {
+ ImageFormat format = ImageFormat.findFormat(imageFormat);
+ if (format != null) {
+ ImageShaper imageShaper = imageShapers.get(
+ format.getType()
+ );
+ return imageShaper.shape(imageStream, size);
+ } else {
+ throw new ImageException("image.unknown.image.format", imageFormat);
+ }
+ }
+
+ public static ImageFormatShaper getInstance() {
+ return _instance;
+ }
+
+}
package org.hedgecode.chess.img;
/**
- *
+ * Common image loader interface.
*
* @author Dmitry Samoshin aka gotty
*/
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Common image shaper interface.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface ImageShaper {
+
+ BufferedImage shape(InputStream imageStream, int size) throws ImageException;
+
+ BufferedImage shape(URL imageUrl, int size) throws ImageException;
+
+ BufferedImage shape(File imageFile, int size) throws ImageException;
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.bitmap;
+
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+
+import org.hedgecode.chess.img.ImageException;
+import org.hedgecode.chess.img.ImageShaper;
+
+/**
+ * Shaper for bitmap images.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class BitmapImageShaper implements ImageShaper {
+
+ private BitmapImageShaper() {
+ }
+
+ @Override
+ public BufferedImage shape(InputStream imageStream, int size) throws ImageException {
+ try {
+ return scaledImage(
+ ImageIO.read(imageStream),
+ size
+ );
+ } catch (IOException e) {
+ throw new ImageException("image.unable.load.bitmap", e.getMessage());
+ }
+ }
+
+ @Override
+ public BufferedImage shape(URL imageUrl, int size) throws ImageException {
+ try {
+ return scaledImage(
+ ImageIO.read(imageUrl),
+ size
+ );
+ } catch (IOException e) {
+ throw new ImageException("image.unable.load.bitmap", e.getMessage());
+ }
+ }
+
+ @Override
+ public BufferedImage shape(File imageFile, int size) throws ImageException {
+ try {
+ return scaledImage(
+ ImageIO.read(imageFile),
+ size
+ );
+ } catch (IOException e) {
+ throw new ImageException("image.unable.load.bitmap", e.getMessage());
+ }
+ }
+
+ private BufferedImage scaledImage(BufferedImage image, int size) {
+ if (image.getWidth() == size && image.getHeight() == size) {
+ return image;
+ }
+ BufferedImage scaledImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
+ Graphics graphics = scaledImage.createGraphics();
+ graphics.drawImage(
+ image.getScaledInstance(size, size, BufferedImage.SCALE_SMOOTH),
+ 0, 0, null
+ );
+ graphics.dispose();
+ return scaledImage;
+ }
+
+ public static ImageShaper create() {
+ return new BitmapImageShaper();
+ }
+
+}
import org.hedgecode.chess.position.Square;
/**
- *
+ * Storage class for chess board images.
*
* @author Dmitry Samoshin aka gotty
*/
public class Board {
+ private BufferedImage board;
private SquarePair<BufferedImage> squares;
+
private int squareSize;
- Board(SquarePair<BufferedImage> squares) {
+ private Board(SquarePair<BufferedImage> squares) {
this.squares = squares;
int width = Math.max(squares.getDark().getWidth(), squares.getLight().getWidth());
int height = Math.max(squares.getDark().getHeight(), squares.getLight().getHeight());
this.squareSize = Math.max(width, height);
}
+ private Board(BufferedImage board) {
+ this.board = board;
+ this.squareSize = Math.max(board.getWidth(), board.getHeight()) / Square.getSize();
+ }
+
public int squareSize() {
return squareSize;
}
return squareSize * Square.getSize();
}
- public BufferedImage render() {
+ public BufferedImage getBoard() {
+ if (board == null && squares != null) {
+ board = renderBoard();
+ }
+ return board;
+ }
+
+ private BufferedImage renderBoard() {
BufferedImage board = new BufferedImage(
squareSize * Square.getSize(),
squareSize * Square.getSize(),
return board;
}
+ public static Board create(BufferedImage board) {
+ return new Board(board);
+ }
+
public static Board create(SquarePair<BufferedImage> squares) {
return new Board(squares);
}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.board;
+
+import java.awt.image.BufferedImage;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hedgecode.chess.img.AbstractImageLoader;
+import org.hedgecode.chess.img.FilenameUtils;
+import org.hedgecode.chess.img.ImageConstants;
+import org.hedgecode.chess.img.ImageException;
+import org.hedgecode.chess.img.ImageFilter;
+
+/**
+ * Loader for chess board's set of images.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class BoardLoader extends AbstractImageLoader {
+
+ private static final String SQUARES_DIR = ImageConstants.RESOURCE_SQUARES_DIR;
+
+ private static final String SQUARE_DARK = ImageConstants.DARK_SQUARE_FILENAME;
+ private static final String SQUARE_LIGHT = ImageConstants.LIGHT_SQUARE_FILENAME;
+
+ private static final String BOARD = ImageConstants.BOARD_FILENAME;
+
+ private static final String[] BOARD_SQUARE_NAMES = { BOARD, SQUARE_DARK, SQUARE_LIGHT };
+
+ private Map<String, Board> squareSetMap = new HashMap<>();
+
+ @Override
+ public Board load(String name) throws ImageException {
+ Board board;
+ if (Type.STATELESS.equals(loadType()) || !squareSetMap.containsKey(name)) {
+ String boardPath = FilenameUtils.getFullPath(SQUARES_DIR, name);
+ board = loadBoard(boardPath);
+ if (Type.STATEFUL.equals(loadType())) {
+ squareSetMap.put(name, board);
+ }
+ } else {
+ board = squareSetMap.get(name);
+ }
+ return board;
+ }
+
+ @Override
+ public void unload(String name) {
+ if (Type.STATEFUL.equals(loadType()) && squareSetMap.containsKey(name)) {
+ squareSetMap.remove(name);
+ }
+ }
+
+ @Override
+ protected void clear() {
+ squareSetMap.clear();
+ }
+
+ private Board loadBoard(String boardPath) throws ImageException {
+ Map<String, BufferedImage> images =
+ loadImages(
+ boardPath,
+ new ImageFilter(BOARD_SQUARE_NAMES)
+ );
+ BufferedImage board = images.get(BOARD);
+ SquarePair<BufferedImage> squarePair = SquarePair.create(
+ images.get(SQUARE_DARK), images.get(SQUARE_LIGHT)
+ );
+ if (board == null && !squarePair.isFilled()) {
+ throw new ImageException("image.incomplete.board.set", boardPath);
+ }
+ return board != null
+ ? Board.create(board)
+ : Board.create(squarePair);
+ }
+
+}
import java.util.Objects;
/**
- *
+ * Storage class for set of images of chess board squares.
*
* @author Dmitry Samoshin aka gotty
*/
private final T dark;
private final T light;
- SquarePair(T dark, T light) {
+ private SquarePair(T dark, T light) {
this.dark = dark;
this.light = light;
}
return light;
}
+ public boolean isFilled() {
+ if (this.dark == null || this.light == null) {
+ return false;
+ }
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof SquarePair)) {
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.fs;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+import org.hedgecode.chess.img.FilenameUtils;
+
+/**
+ * Default FileSystem contractor.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class DefFileSystemContractor implements FileSystemContractor {
+
+ private FileSystem fileSystem;
+ private String rootPath;
+
+ DefFileSystemContractor(URI uri) {
+ fileSystem = FileSystems.getDefault();
+ rootPath = FilenameUtils.fixPath(uri.getPath());
+ }
+
+ @Override
+ public FileSystem getFileSystem() {
+ return fileSystem;
+ }
+
+ @Override
+ public Path getPath(String path) {
+ return fileSystem.getPath(rootPath, path);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(Path file) throws IOException {
+ return new FileInputStream(file.toString());
+ }
+
+ @Override
+ public void close() throws Exception {
+ // do nothing
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.fs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+
+/**
+ * Common FileSystem contractor interface.
+ *
+ * @author Dmitry Samoshin aka gotty
+ * @see FileSystem
+ */
+public interface FileSystemContractor extends AutoCloseable {
+
+ FileSystem getFileSystem();
+
+ Path getPath(String path);
+
+ InputStream getResourceAsStream(Path file) throws IOException;
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.fs;
+
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * FileSystem Detector.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class FileSystemDetector {
+
+ private static final String JAR_SCHEME_NAME = "jar";
+
+ public static FileSystemContractor detect(URI uri) throws IOException {
+ if (JAR_SCHEME_NAME.equals(uri.getScheme())) {
+ return new JarFileSystemContractor(uri);
+ } else {
+ return new DefFileSystemContractor(uri);
+ }
+ }
+
+ public static boolean detectJar(URI uri) {
+ return JAR_SCHEME_NAME.equals(uri.getScheme());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.fs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.util.Collections;
+
+import org.hedgecode.chess.img.FilenameUtils;
+
+/**
+ * FileSystem contractor for jar-files.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JarFileSystemContractor implements FileSystemContractor {
+
+ private FileSystem fileSystem;
+ private String rootPath;
+
+ JarFileSystemContractor(URI uri) throws IOException {
+ fileSystem = FileSystems.newFileSystem(
+ uri, Collections.<String, String>emptyMap()
+ );
+ rootPath = FilenameUtils.getPathFromJar(uri.toString());
+ }
+
+ @Override
+ public FileSystem getFileSystem() {
+ return fileSystem;
+ }
+
+ @Override
+ public Path getPath(String path) {
+ return fileSystem.getPath(rootPath, path);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(Path file) throws IOException {
+ return getClass().getResourceAsStream(file.toString());
+ }
+
+ @Override
+ public void close() throws Exception {
+ fileSystem.close();
+ }
+
+}
import org.hedgecode.chess.position.Piece;
/**
- *
+ * Storage class for set of images of chess pieces.
*
* @author Dmitry Samoshin aka gotty
*/
private static String[] allPieceNames;
- PieceSet() {
+ private PieceSet() {
}
public void add(String name, BufferedImage image) {
return pieceSetMap.get(colorPiece);
}
- public boolean isFull() {
+ public boolean isFilled() {
for (ColorPiece colorPiece : ColorPiece.values()) {
if (!pieceSetMap.containsKey(colorPiece)
|| (pieceSetMap.get(colorPiece) == null)) {
package org.hedgecode.chess.img.piece;
-import java.io.File;
-import java.io.IOException;
+import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
-import javax.imageio.ImageIO;
-
import org.hedgecode.chess.img.AbstractImageLoader;
+import org.hedgecode.chess.img.FilenameUtils;
import org.hedgecode.chess.img.ImageConstants;
import org.hedgecode.chess.img.ImageException;
import org.hedgecode.chess.img.ImageFilter;
/**
- *
+ * Loader for chess piece's set of images.
*
* @author Dmitry Samoshin aka gotty
*/
public class PieceSetLoader extends AbstractImageLoader {
- private static final File PIECES_PATH = new File(IMAGES_PATH, ImageConstants.RESOURCE_PIECES_DIR);
+ private static final String PIECES_DIR = ImageConstants.RESOURCE_PIECES_DIR;
private static final String[] PIECES_NAMES = PieceSet.getAllPieceNames();
@Override
public PieceSet load(String name) throws ImageException {
- PieceSet pieceSet = null;
+ PieceSet pieceSet;
if (Type.STATELESS.equals(loadType()) || !pieceSetMap.containsKey(name)) {
- File piecePath = new File(PIECES_PATH, name);
- if (piecePath.exists() && piecePath.isDirectory()) {
- pieceSet = loadPieces(piecePath);
- }
- if (Type.STATEFUL.equals(loadType()) && pieceSet != null) {
+ String piecePath = FilenameUtils.getFullPath(PIECES_DIR, name);
+ pieceSet = loadPieces(piecePath);
+ if (Type.STATEFUL.equals(loadType())) {
pieceSetMap.put(name, pieceSet);
}
} else {
pieceSetMap.clear();
}
- private PieceSet loadPieces(File piecePath) throws ImageException {
+ private PieceSet loadPieces(String piecePath) throws ImageException {
PieceSet pieceSet = PieceSet.create();
- File[] images = piecePath.listFiles(new ImageFilter(PIECES_NAMES));
- if (images != null) {
- for (File image : images) {
- if (image.isFile()) {
- String filename = image.getName();
- try {
- pieceSet.add(
- filename.substring(0, filename.lastIndexOf('.')),
- ImageIO.read(image)
- );
- } catch (IOException e) {
- throw new ImageException(e.getMessage()); // todo: locale
- }
- }
- }
+ Map<String, BufferedImage> images =
+ loadImages(
+ piecePath,
+ new ImageFilter(PIECES_NAMES)
+ );
+ for (String name : PIECES_NAMES) {
+ pieceSet.add(
+ name,
+ images.get(name)
+ );
+ }
+ if (!pieceSet.isFilled()) {
+ throw new ImageException("image.incomplete.piece.set", piecePath);
}
- return pieceSet.isFull() ? pieceSet : null;
+ return pieceSet;
}
}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.vector;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+import org.apache.batik.transcoder.TranscoderException;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+import org.apache.batik.transcoder.image.ImageTranscoder;
+
+import org.hedgecode.chess.img.ImageFormat;
+
+/**
+ * Transcoder for vector square images to {@link BufferedImage}.
+ *
+ * @author Dmitry Samoshin aka gotty
+ * @see ImageTranscoder
+ */
+public class SquareImageTranscoder extends ImageTranscoder {
+
+ private final int type;
+ private BufferedImage image;
+
+ SquareImageTranscoder(int type) {
+ this.type = type;
+ }
+
+ SquareImageTranscoder(int type, int size) {
+ this.type = type;
+ addTranscodingHint(ImageTranscoder.KEY_WIDTH, (float) size);
+ addTranscodingHint(ImageTranscoder.KEY_HEIGHT, (float) size);
+
+ }
+
+ @Override
+ protected void setImageSize(float width, float height) {
+ if (width > 0 && height > 0) {
+ super.setImageSize(width, height);
+ }
+ }
+
+ @Override
+ public BufferedImage createImage(int width, int height) {
+ return new BufferedImage(width, height, type);
+ }
+
+ @Override
+ public void writeImage(BufferedImage image, TranscoderOutput to) throws TranscoderException {
+ this.image = image;
+ }
+
+ public BufferedImage transcode(InputStream inputStream) throws TranscoderException {
+ transcode(
+ new TranscoderInput(inputStream),
+ null
+ );
+ return getImage();
+ }
+
+ public BufferedImage getImage() {
+ return image;
+ }
+
+
+ public static void main(String[] args) throws TranscoderException, IOException {
+ SquareImageTranscoder imageTranscoder =
+ new SquareImageTranscoder(BufferedImage.TYPE_INT_ARGB); // , 250
+ ImageIO.write(
+ imageTranscoder.transcode(
+ ClassLoader.getSystemResourceAsStream("images/pieces/spatial/bb.svg")
+ ),
+ ImageFormat.PNG.name(),
+ new File("bishop" + "." + ImageFormat.PNG.getExt())
+ );
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.img.vector;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.batik.transcoder.TranscoderException;
+
+import org.hedgecode.chess.img.ImageException;
+import org.hedgecode.chess.img.ImageShaper;
+
+/**
+ * Shaper for vector images.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class VectorImageShaper implements ImageShaper {
+
+ private VectorImageShaper() {
+ }
+
+ @Override
+ public BufferedImage shape(InputStream imageStream, int size) throws ImageException {
+ SquareImageTranscoder imageTranscoder =
+ new SquareImageTranscoder(BufferedImage.TYPE_INT_ARGB, size);
+ try {
+ return imageTranscoder.transcode(imageStream);
+ } catch (TranscoderException e) {
+ throw new ImageException("image.unable.load.vector", e.getMessage());
+ }
+ }
+
+ @Override
+ public BufferedImage shape(URL imageUrl, int size) throws ImageException {
+ try {
+ return shape(
+ imageUrl.openStream(),
+ size
+ );
+ } catch (IOException e) {
+ throw new ImageException("image.unable.load.vector", e.getMessage());
+ }
+ }
+
+ @Override
+ public BufferedImage shape(File imageFile, int size) throws ImageException {
+ try {
+ return shape(
+ new FileInputStream(imageFile),
+ size
+ );
+ } catch (FileNotFoundException e) {
+ throw new ImageException("image.unable.load.vector", e.getMessage());
+ }
+ }
+
+ public static ImageShaper create() {
+ return new VectorImageShaper();
+ }
+
+}
--- /dev/null
+# Copyright (c) 2018-2019. Developed by Hedgecode.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Default localized string information
+# Localized for Locale en_US
+
+image.unable.access.resource=Unable to access resources of graphic module
+image.unable.find.resource=Unable to find image resources
+image.unable.load.bitmap=Unable to load bitmap image
+image.unable.load.vector=Unable to load vector image
+image.unknown.image.format=Unknown image format
+image.incomplete.board.set=Incomplete board set for load
+image.incomplete.piece.set=Incomplete piece set for load
--- /dev/null
+# Copyright (c) 2018-2019. Developed by Hedgecode.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Localized for Locale ru_RU
+
+image.unable.access.resource=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0434\u043E\u0441\u0442\u0443\u043F \u043A \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043C \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0433\u043E \u043C\u043E\u0434\u0443\u043B\u044F
+image.unable.find.resource=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0439\u0442\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044B
+image.unable.load.bitmap=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0440\u0430\u0441\u0442\u0440\u043E\u0432\u043E\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435
+image.unable.load.vector=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0432\u0435\u043A\u0442\u043E\u0440\u043D\u043E\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435
+image.unknown.image.format=\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F
+image.incomplete.board.set=\u041D\u0435\u043F\u043E\u043B\u043D\u044B\u0439 \u043D\u0430\u0431\u043E\u0440 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0448\u0430\u0445\u043C\u0430\u0442\u043D\u043E\u0439 \u0434\u043E\u0441\u043A\u0438
+image.incomplete.piece.set=\u041D\u0435\u043F\u043E\u043B\u043D\u044B\u0439 \u043D\u0430\u0431\u043E\u0440 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0448\u0430\u0445\u043C\u0430\u0442\u043D\u044B\u0445 \u0444\u0438\u0433\u0443\u0440
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Hedgecode ChessHog Hedgefish Module.
</description>
- <properties>
- <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog</artifactId>
- <version>${chessHogVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.hedgecode.chess</groupId>
<artifactId>chesshog-core</artifactId>
<version>${chessHogVersion}</version>
</dependency>
</description>
<properties>
- <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
<zxingVersion>3.3.3</zxingVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog</artifactId>
+ <artifactId>chesshog-core</artifactId>
<version>${chessHogVersion}</version>
</dependency>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog-core</artifactId>
+ <artifactId>chesshog-format</artifactId>
<version>${chessHogVersion}</version>
</dependency>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog-format</artifactId>
+ <artifactId>chesshog-graphics</artifactId>
<version>${chessHogVersion}</version>
</dependency>
<dependency>
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode;
+
+import org.hedgecode.chess.ChessHogConsole;
+
+/**
+ * Chess QR Code Main Application.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class ChessQRCodeApp {
+
+ private static final String[] QRCODE_MODULE_LOGO = {
+ " _ ",
+ " ___ ___ ___ ___ _| |___ ",
+ " | . | _| _| . | . | -_| ",
+ " |_ |_| |___|___|___|___| ",
+ " |_| _ _ ",
+ " _____ ___ _| |_ _| |___ ",
+ " | | . | . | | | | -_| ",
+ " |_|_|_|___|___|___|_|___| ",
+ " "
+ };
+
+ public static void main(String[] args) {
+
+ ChessHogConsole.init();
+
+ for (String line : QRCODE_MODULE_LOGO) {
+ ChessHogConsole.console(line);
+ }
+
+ }
+
+}
\ No newline at end of file
* limitations under the License.
*/
-package org.hedgecode.chess;
+package org.hedgecode.chess.qrcode;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
private ChessQRCodeConstants() {
throw new AssertionError(
- "No org.hedgecode.chess.ChessQRCodeConstants instances!"
+ "No org.hedgecode.chess.qrcode.ChessQRCodeConstants instances!"
);
}
import java.util.ResourceBundle;
-import org.hedgecode.chess.ChessQRCodeConstants;
-
/**
* Chess-specific QR Codes read/write/parse Exception.
*
package org.hedgecode.chess.qrcode;
/**
- * Mode of data type stored in Chess-specific QR Codes.
+ * Mode of data type stored in chess-specific QR Codes.
*
* @author Dmitry Samoshin aka gotty
*/
FEN,
TCD,
PGN,
- TCG;
+ TCG,
+ ZIP;
- static final int CODE_LENGTH = 3;
+ public static final int CODE_LENGTH = 3;
- boolean isPosition() {
+ public boolean isPosition() {
return FEN.equals(this) || TCD.equals(this);
}
- boolean isGame() {
+ public boolean isGame() {
return PGN.equals(this) || TCG.equals(this);
}
+ public boolean isArchive() {
+ return ZIP.equals(this);
+ }
+
public static ChessQRCodeMode byCode(String code) {
for (ChessQRCodeMode mode : ChessQRCodeMode.values()) {
if (mode.name().equals(code))
import com.google.zxing.qrcode.decoder.Decoder;
import com.google.zxing.qrcode.detector.Detector;
-import org.hedgecode.chess.ChessQRCodeConstants;
-
/**
* Chess-specific QR Codes reader (image decoder).
*
private static ChessQRCodeReader _instance = new ChessQRCodeReader();
- private ChessQRCodeReader() {
+ protected ChessQRCodeReader() {
decoder = new Decoder();
}
);
}
- ChessQRCodeMode mode = ChessQRCodeMode.byCode(
- decoderResult.getText().substring(0, ChessQRCodeMode.CODE_LENGTH)
- );
-
- if (mode == null) {
- throw new ChessQRCodeException(
- ChessQRCodeException.Type.READ, "read.unknown.chess.mode"
- );
- }
-
- return new ChessQRResult(
- mode,
- decoderResult.getText().substring(ChessQRCodeMode.CODE_LENGTH)
- );
+ return createResult(decoderResult);
/*
ResultPoint[] points = detectorResult.getPoints();
*/
}
+ protected ChessQRResult createResult(DecoderResult decoderResult) throws ChessQRCodeException {
+ String result = decoderResult.getText();
+
+ ChessQRCodeMode mode = ChessQRResult.getMode(result);
+ if (mode == null) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.READ, "read.unknown.chess.mode"
+ );
+ }
+
+ return new ChessQRResult(
+ mode,
+ ChessQRResult.getContents(result)
+ );
+ }
+
public static ChessQRCodeReader getInstance() {
return _instance;
}
public static void main(String[] args) {
try {
ChessQRResult qrCodeResult = ChessQRCodeReader.getInstance().read(
- new File("MyQRCode.png")
+ new File("qrcode.png")
);
System.out.println("Decoded format = " + qrCodeResult.getMode());
System.out.println("Decoded text = " + qrCodeResult.getContents());
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;
-import org.hedgecode.chess.ChessQRCodeConstants;
import org.hedgecode.chess.img.ImageFormat;
/**
private static final int DEF_QUIET_ZONE_SIZE = 4;
private static final int DEF_QRCODE_BIT_SIZE = 250;
+ private static final int MIN_QRCODE_BIT_SIZE = 50;
private static final ErrorCorrectionLevel DEF_ERR_CORR_LEVEL = ErrorCorrectionLevel.H; // todo: Q
private static ChessQRCodeWriter _instance = new ChessQRCodeWriter();
- private ChessQRCodeWriter() {
+ protected ChessQRCodeWriter() {
}
public void write(ChessQRCodeMode mode, String contents, ImageFormat format, String qrCodeFilePath)
);
}
- private BitMatrix encode(
+ protected BitMatrix encode(
ChessQRCodeMode mode,
String contents,
int width, int height,
);
}
- if (width < 0 || height < 0) { // todo
+ if (Math.min(width, height) < MIN_QRCODE_BIT_SIZE) { // todo: check for Version
throw new ChessQRCodeException(
ChessQRCodeException.Type.WRITE, "write.qrcode.size.incorrect"
);
}
+ String qrCodeContents = mode.name().concat(contents);
+
int quietZone = DEF_QUIET_ZONE_SIZE;
ErrorCorrectionLevel errorCorrectionLevel = DEF_ERR_CORR_LEVEL;
}
hints = newHints;
- String qrCodeText = mode.name().concat(contents);
-
QRCode qrCode;
try {
qrCode = Encoder.encode(
- qrCodeText, errorCorrectionLevel, hints
+ qrCodeContents, errorCorrectionLevel, hints
);
} catch (WriterException e) {
throw new ChessQRCodeException(
ChessQRCodeMode.FEN,
"rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2",
ImageFormat.PNG,
- "./MyQRCode.png"
+ "./qrcode.png"
);
/*
ChessQRCodeWriter.getInstance().write(
"11.Bf4 b5 12.a4 Bb7 13.Re1 Nd5 14.Bg3 Kc8 15.axb5 cxb5 16.Qd3 Bc6 \n" +
"17.Bf5 exf5 18.Rxe7 Bxe7 19.c4 1-0",
ImageFormat.PNG,
- "./MyQRCode.png"
+ "./qrcode.png"
);
*/
} catch (ChessQRCodeException e) {
static ByteMatrix embedChessLogoPattern(ByteMatrix byteMatrix) {
- if (byteMatrix == null || byteMatrix.getWidth() < CHESS_LOGO_PATTERN_LENGTH + 14) // todo: 14
- return null;
+ if (byteMatrix == null || byteMatrix.getWidth() < CHESS_LOGO_PATTERN_LENGTH + 14)
+ return null; // todo: check for Version
int xStart = (byteMatrix.getWidth() - CHESS_LOGO_PATTERN_LENGTH) / 2;
int yStart = (byteMatrix.getHeight() - CHESS_LOGO_PATTERN_LENGTH) / 2;
import org.hedgecode.chess.position.Position;
/**
- * Result storage for Chess-specific QR Codes data.
+ * Result storage for chess-specific QR Codes data.
*
* @author Dmitry Samoshin aka gotty
*/
private Position position;
private Game game;
- ChessQRResult(ChessQRCodeMode mode, String contents) {
+ public ChessQRResult(ChessQRCodeMode mode, String contents) {
this.mode = mode;
this.contents = contents;
}
+/*
ChessQRResult(Position position) {
this.position = position;
}
ChessQRResult(Game game) {
this.game = game;
}
+*/
public ChessQRCodeMode getMode() {
return mode;
}
}
+ public static ChessQRCodeMode getMode(String contents) {
+ return ChessQRCodeMode.byCode(
+ contents.substring(0, ChessQRCodeMode.CODE_LENGTH)
+ );
+ }
+
+ public static String getContents(String contents) {
+ return contents.substring(ChessQRCodeMode.CODE_LENGTH);
+ }
+
}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode.zip;
+
+import java.io.File;
+
+import com.google.zxing.common.DecoderResult;
+
+import org.hedgecode.chess.qrcode.ChessQRCodeException;
+import org.hedgecode.chess.qrcode.ChessQRCodeMode;
+import org.hedgecode.chess.qrcode.ChessQRCodeReader;
+import org.hedgecode.chess.qrcode.ChessQRResult;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ZipChessQRCodeReader extends ChessQRCodeReader {
+
+ private static ZipChessQRCodeReader _instance = new ZipChessQRCodeReader();
+
+ protected ZipChessQRCodeReader() {
+ super();
+ }
+
+ @Override
+ protected ChessQRResult createResult(DecoderResult decoderResult) throws ChessQRCodeException {
+ String result = decoderResult.getText();
+ ChessQRCodeMode mode = ChessQRResult.getMode(result);
+
+ if (ChessQRCodeMode.ZIP.equals(mode)) {
+ String contents = ZipContentInflater.inflate(
+ ChessQRResult.getContents(result)
+ );
+
+ mode = ChessQRResult.getMode(contents);
+ if (mode == null) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.READ, "read.unknown.chess.mode"
+ );
+ }
+
+ return new ChessQRResult(
+ mode,
+ ChessQRResult.getContents(contents)
+ );
+ } else {
+ return super.createResult(decoderResult);
+ }
+ }
+
+ public static ZipChessQRCodeReader getInstance() {
+ return _instance;
+ }
+
+
+ public static void main(String[] args) {
+ try {
+ ChessQRResult qrCodeResult = ZipChessQRCodeReader.getInstance().read(
+ new File("qrcode.png")
+ );
+ System.out.println("Decoded format = " + qrCodeResult.getMode());
+ System.out.println("Decoded text = " + qrCodeResult.getContents());
+ } catch (ChessQRCodeException e) {
+ System.out.println("Could not decode QR Code. Exception: " + e.getMessage());
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode.zip;
+
+import java.util.Map;
+
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.common.BitMatrix;
+import org.hedgecode.chess.img.ImageFormat;
+import org.hedgecode.chess.qrcode.ChessQRCodeException;
+import org.hedgecode.chess.qrcode.ChessQRCodeMode;
+import org.hedgecode.chess.qrcode.ChessQRCodeWriter;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ZipChessQRCodeWriter extends ChessQRCodeWriter {
+
+ private static ChessQRCodeWriter _instance = new ZipChessQRCodeWriter();
+
+ protected ZipChessQRCodeWriter() {
+ super();
+ }
+
+ @Override
+ protected BitMatrix encode(
+ ChessQRCodeMode mode,
+ String contents,
+ int width, int height,
+ Map<EncodeHintType,?> hints)
+ throws ChessQRCodeException
+ {
+ if (mode == null || mode.isArchive()) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.WRITE, "write.qrcode.mode.null"
+ );
+ }
+
+ if (contents == null || contents.isEmpty()) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.WRITE, "write.qrcode.contents.empty"
+ );
+ }
+
+ String zipContents = ZipContentDeflater.deflate(
+ mode.name().concat(contents)
+ );
+
+ return super.encode(
+ ChessQRCodeMode.ZIP, zipContents, width, height, hints
+ );
+ }
+
+ public static ChessQRCodeWriter getInstance() {
+ return _instance;
+ }
+
+
+ public static void main(String[] args) {
+ try {
+ ZipChessQRCodeWriter.getInstance().write(
+ ChessQRCodeMode.PGN,
+ "1.e4 c6 2.d4 d5 3.Nc3 dxe4 4.Nxe4 Nd7 5.Ng5 Ngf6 6.Bd3 e6 7.N1f3 h6\n" +
+ "8.Nxe6 Qe7 9.O-O fxe6 10.Bg6+ Kd8 {Каспаров встряхнул головой} \n" +
+ "11.Bf4 b5 12.a4 Bb7 13.Re1 Nd5 14.Bg3 Kc8 15.axb5 cxb5 16.Qd3 Bc6 \n" +
+ "17.Bf5 exf5 18.Rxe7 Bxe7 19.c4 1-0",
+ ImageFormat.PNG,
+ "./qrcode.png"
+ );
+ } catch (ChessQRCodeException e) {
+ System.out.println("Could not generate QR Code, Exception: " + e.getMessage());
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode.zip;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import org.hedgecode.chess.qrcode.ChessQRCodeConstants;
+import org.hedgecode.chess.qrcode.ChessQRCodeException;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ZipContentDeflater {
+
+ public static String deflate(String contents) throws ChessQRCodeException {
+ byte[] bytes = contents.getBytes(
+ ChessQRCodeConstants.CHARSET
+ );
+ if (bytes.length > ZipContentUtils.getMaxContentLength()) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.PARSE, "zip.max.length.error"
+ );
+ }
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ DeflaterOutputStream zout = new DeflaterOutputStream(
+ bout, new Deflater(Deflater.BEST_COMPRESSION)
+ );
+ try {
+ try {
+ zout.write(bytes);
+ } finally {
+ zout.close();
+ bout.close();
+ }
+ } catch (IOException e) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.PARSE, "zip.deflate.write.error", e.getMessage()
+ );
+ }
+ return ZipContentUtils.base64Encode(
+ ZipContentUtils.concat(
+ bytes.length,
+ bout.toByteArray()
+ )
+ );
+ }
+
+
+ public static void main(String[] args) throws ChessQRCodeException {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 10; ++i) {
+ sb.append(i).append("bla-bla-bla").append(i);
+ }
+ String zipContents = ZipContentDeflater.deflate(sb.toString());
+ System.out.println("Zip Contents: " + zipContents);
+ System.out.println("Zip length: " + zipContents.length());
+ String contents = ZipContentInflater.inflate(zipContents);
+ System.out.println("Unzip Contents: " + contents);
+ System.out.println("Unziip length: " + contents.length());
+ System.out.println("Equals: " + sb.toString().equals(contents));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.zip.InflaterInputStream;
+
+import org.hedgecode.chess.qrcode.ChessQRCodeConstants;
+import org.hedgecode.chess.qrcode.ChessQRCodeException;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ZipContentInflater {
+
+ public static String inflate(String zipContents) throws ChessQRCodeException {
+ byte[] zipBytes = ZipContentUtils.base64Decode(zipContents);
+ int length = ZipContentUtils.getZipLength(zipBytes);
+ if (length > ZipContentUtils.getMaxContentLength()) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.PARSE, "zip.max.length.error"
+ );
+ }
+ byte[] resultBytes = new byte[length];
+ InflaterInputStream zin = new InflaterInputStream(
+ new ByteArrayInputStream(
+ ZipContentUtils.getZipBytes(zipBytes)
+ )
+ );
+ try {
+ try {
+ length = zin.read(resultBytes, 0, length); // todo : check length
+ } finally {
+ zin.close();
+ }
+ } catch (IOException e) {
+ throw new ChessQRCodeException(
+ ChessQRCodeException.Type.PARSE, "zip.inflate.read.error", e.getMessage()
+ );
+ }
+ return new String(
+ resultBytes, 0, length, ChessQRCodeConstants.CHARSET
+ );
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode.zip;
+
+import java.util.Arrays;
+import java.util.Base64;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ZipContentUtils {
+
+ private static final int LENGTH_BYTE_COUNT = 4;
+
+ private static final int MAX_CONTENT_LENGTH = 65536;
+
+ public static int getMaxContentLength() {
+ return MAX_CONTENT_LENGTH;
+ }
+
+ public static int getZipLength(byte[] zipBytes) {
+ return fromByteArray(
+ Arrays.copyOf(zipBytes, LENGTH_BYTE_COUNT)
+ );
+ }
+
+ public static byte[] getZipBytes(byte[] zipBytes) {
+ return Arrays.copyOfRange(
+ zipBytes, LENGTH_BYTE_COUNT, zipBytes.length
+ );
+ }
+
+ public static byte[] concat(int length, byte[] bytes) {
+ return concat(
+ toByteArray(length),
+ bytes
+ );
+ }
+
+ public static String base64Encode(byte[] bytes) {
+ return Base64.getEncoder().encodeToString(bytes);
+ }
+
+ public static byte[] base64Decode(String value) {
+ return Base64.getDecoder().decode(value);
+ }
+
+ private static byte[] toByteArray(int value) {
+ return new byte[] {
+ (byte) (value >> 24),
+ (byte) (value >> 16),
+ (byte) (value >> 8),
+ (byte) (value)
+ };
+ }
+
+ private static int fromByteArray(byte[] bytes) {
+ return bytes[0] << 24
+ | (bytes[1] & 0xFF) << 16
+ | (bytes[2] & 0xFF) << 8
+ | (bytes[3] & 0xFF);
+ }
+
+ private static byte[] concat(byte[]... byteArrays) {
+ int length = 0;
+ for (byte[] bytes : byteArrays) {
+ length += bytes.length;
+ }
+ byte[] concatBytes = new byte[length];
+ length = 0;
+ for (byte[] bytes : byteArrays) {
+ if (bytes.length == 0)
+ continue;
+ System.arraycopy(bytes, 0, concatBytes, length, bytes.length);
+ length += bytes.length;
+ }
+ return concatBytes;
+ }
+
+ private ZipContentUtils() {
+ throw new AssertionError(
+ "No org.hedgecode.chess.qrcode.zip.ZipContentUtils instances!"
+ );
+ }
+
+}
write.qrcode.size.incorrect=Incorrect QR Code size specified
write.qrcode.chess.incorrect=Specified size is not suitable for chess QR Code
write.zxing.qrcode.error=Error encoding of QR code
+zip.max.length.error=Content length exceeds maximum size
+zip.deflate.write.error=Error deflating of content
+zip.inflate.read.error=Error inflating of content
write.qrcode.size.incorrect=\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E \u0437\u0430\u0434\u0430\u043D \u0440\u0430\u0437\u043C\u0435\u0440 QR \u043A\u043E\u0434\u0430
write.qrcode.chess.incorrect=\u0417\u0430\u0434\u0430\u043D\u043D\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 \u043D\u0435 \u043F\u043E\u0434\u0445\u043E\u0434\u0438\u0442 \u0434\u043B\u044F \u0448\u0430\u0445\u043C\u0430\u0442\u043D\u043E\u0433\u043E QR \u043A\u043E\u0434\u0430
write.zxing.qrcode.error=\u041E\u0448\u0438\u0431\u043A\u0430 \u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F QR \u043A\u043E\u0434\u0430
+zip.max.length.error=\u0414\u043B\u0438\u043D\u0430 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E \u043F\u0440\u0435\u0432\u044B\u0448\u0430\u0435\u0442 \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440
+zip.deflate.write.error=\u041E\u0448\u0438\u0431\u043A\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E
+zip.inflate.read.error=\u041E\u0448\u0438\u0431\u043A\u0430 \u0440\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E
* limitations under the License.
*/
-package org.hedgecode.chess;
+package org.hedgecode.chess.qrcode;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
- * Chess QR Code Main Application.
+ * Tests for {@link ChessQRCodeWriter}.
*
* @author Dmitry Samoshin aka gotty
*/
-public final class ChessQRCodeApp {
-
- public static void main(String[] args) {
+@RunWith(JUnit4.class)
+public class ChessQRCodeReaderTest extends Assert {
+ @Test
+ public void decode() throws Exception {
}
--- /dev/null
+/*
+ * Copyright (c) 2018-2019. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.qrcode;
+
+import java.io.File;
+
+import javax.imageio.ImageIO;
+
+import org.hedgecode.chess.img.DiagramBuilder;
+import org.hedgecode.chess.img.ImageFormat;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.hedgecode.chess.Builders;
+import org.hedgecode.chess.Parsers;
+import org.hedgecode.chess.position.Position;
+
+/**
+ * Tests for {@link ChessQRCodeWriter}.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+@RunWith(JUnit4.class)
+public class ChessQRCodeWriterTest extends Assert {
+
+ private static final String QR_CODE_IMAGE_PATH = "./QRCodeTest.png";
+
+ @Test
+ public void generate() throws Exception {
+ //String expected = "rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2";
+ String expected = "1r2k1r1/pbppnp1p/1b3P2/8/Q7/B1PB1q2/P4PPP/3R2K1 w - - 0 21";
+ //String expected = "4kb1r/p2n1ppp/4q3/4p1B1/4P3/1Q6/PPP2PPP/2KR4 w k - 0 16";
+
+ Position expectedPosition = Parsers.FEN.parser().parse(
+ expected
+ );
+
+ ChessQRCodeWriter.getInstance().write(
+ ChessQRCodeMode.TCD,
+ Builders.TCD.builder().build(expectedPosition),
+ ImageFormat.PNG,
+ QR_CODE_IMAGE_PATH
+ );
+
+ File file = new File(QR_CODE_IMAGE_PATH);
+ String actual = ChessQRCodeReader.getInstance().read(
+ file
+ ).getContents();
+
+ Position actualPosition = Parsers.TCD.parser().parse(
+ actual
+ );
+
+
+/*
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+*/
+
+ System.out.println(actual);
+
+ ImageIO.write(
+ DiagramBuilder.getInstance().build(actualPosition, "test", "shade"),
+ "PNG",
+ new File("chessboard.png")
+ );
+
+
+ System.out.println(
+ Builders.ASCII.builder().build(actualPosition)
+ );
+
+
+ }
+
+}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2019. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Hedgecode ChessHog UCI Module.
</description>
- <properties>
- <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.hedgecode.chess</groupId>
- <artifactId>chesshog</artifactId>
- <version>${chessHogVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.hedgecode.chess</groupId>
<artifactId>chesshog-core</artifactId>
<version>${chessHogVersion}</version>
</dependency>
<?xml version='1.0' encoding='UTF-8'?>
<!--
- ~ Copyright (c) 2018. Developed by Hedgecode.
+ ~ Copyright (c) 2018-2020. Developed by Hedgecode.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
<module>chesshog-core</module>
<module>chesshog-format</module>
<module>chesshog-uci</module>
+ <module>chesshog-graphics</module>
<module>chesshog-hedgefish</module>
<module>chesshog-dbetude</module>
<module>chesshog-qrcode</module>
<parent>
<groupId>org.hedgecode.maven</groupId>
<artifactId>lib-parent</artifactId>
- <version>2</version>
+ <version>3</version>
<relativePath>../lib-parent/pom.xml</relativePath>
</parent>
<name>Hedgecode ChessHog</name>
<description>
- Hedgecode ChessHog.
+ Hedgecode ChessHog is a chess project that includes modules with different functionality, such as:
+
+ * own internal format for the presentation of chess games and positions, which makes
+ it possible to use this project as API library for various chess Java applications;
+ * ability to work with various formats of chess games and diagrams (e.g. PGN, FEN),
+ including the functionality of generating chess positions in ASCII format,
+ as well as Wikipedia format;
+ * provide full functionality for working with UCI (Universal Chess Interface) protocol,
+ which allows both connecting external UCI engines and developing your own
+ using API of UCI module with a set of necessary interfaces described in it;
+ * building chess diagrams in the form of images with a diverse set of chess pieces;
+ * ability to record chess games and positions in the form of a QR code,
+ as well as recognition of this chess QR code.
</description>
<inceptionYear>2018</inceptionYear>
</distributionManagement>
<properties>
+ <chessHogVersion>0.1-SNAPSHOT</chessHogVersion>
<junitVersion>4.12</junitVersion>
<commonsConfigVersion>1.10</commonsConfigVersion>
<commonsCollectionVersion>3.2.1</commonsCollectionVersion>