This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch feat/fontgis in repository https://gitbox.apache.org/repos/asf/sis.git
commit c179ca9d39d07f6c7e0cdd74af07ab0500e8cbf8 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Mar 13 13:10:59 2024 +0100 Add javafx Glyph and FontGIS dependency. --- optional/build.gradle.kts | 29 ++ .../main/org/apache/sis/gui/internal/FontGIS.java | 467 +++++++++++++++++++++ 2 files changed, 496 insertions(+) diff --git a/optional/build.gradle.kts b/optional/build.gradle.kts index 3f3e90f4eb..eb4ef20301 100644 --- a/optional/build.gradle.kts +++ b/optional/build.gradle.kts @@ -14,6 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import java.nio.file.Files + group = "org.apache.sis" // The version is specified in `gradle.properties`. @@ -129,6 +131,32 @@ fun patchForTests(args : MutableList<String>) { addExport(args, "org.apache.sis.util", "org.apache.sis.test", "org.apache.sis.gui") } +/* + * Download the FontGIS glyphs if not already present — https://viglino.github.io/font-gis/ + * The license is OFL-1.1 (SIL Open Font License), classified by ASF as Category B: + * the file may be included in binary-only form in convenience binaries, + * but shall not be included in source releases. + */ +fun downloadFontGIS() { + var buildDir = file("build"); + val targetFile = File(buildDir, "classes/java/main/org.apache.sis.gui/org/apache/sis/gui/internal/font-gis.ttf") + if (!targetFile.exists()) { + val archiveFolder = File(buildDir, "fontgis") + val archiveFile = File(archiveFolder, "fontgis.tgz") + val archiveEntry = File(archiveFolder, "package/fonts/font-gis.ttf") + val archiveURL = "https://registry.npmjs.org/font-gis/-/font-gis-1.0.5.tgz" + if (!archiveEntry.exists()) { + if (!archiveFile.exists()) { + archiveFolder.mkdirs() + println("Downloading " + archiveURL) + ant.invokeMethod("get", mapOf("src" to archiveURL, "dest" to archiveFile)) + } + ant.invokeMethod("untar", mapOf("src" to archiveFile, "dest" to archiveFolder, "compression" to "gzip")) + } + Files.createLink(targetFile.toPath(), archiveEntry.toPath()) + } +} + /* * Discover and execute JUnit-based tests. */ @@ -153,6 +181,7 @@ tasks.test { * Other attributes are hard-coded in `../buildSrc`. */ tasks.jar { + downloadFontGIS(); manifest { attributes["Main-Class"] = "org.apache.sis.gui.DataViewer" } diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/FontGIS.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/FontGIS.java new file mode 100644 index 0000000000..abb8b6dcba --- /dev/null +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/FontGIS.java @@ -0,0 +1,467 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sis.gui.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Logger; +import javafx.scene.text.Font; +import javafx.scene.control.Label; +import org.apache.sis.util.Static; +import org.apache.sis.system.Modules; +import org.apache.sis.util.logging.Logging; + + +/** + * Creates labels with an icon rendered using Font-GIS. + * Font-GIS is a set of SVG icons and font to use with GIS and spatial analysis tools. + * Those font are not included in source code and are not managed as a Maven dependency neither. + * They are downloaded from the <a href="https://www.npmjs.com/package/font-gis">NPM package</a> + * by the {@code build.gradle.kts} script where the {@code jar} task is executed. + * + * @author Johann Sorel (Geomatys) + * + * @see <a href="https://viglino.github.io/font-gis/">Font-GIS project</a> + */ +public final class FontGIS extends Static { + /** + * The font, or {@code null} if not found or if an error occurred. + * This is loaded at class-initialization time. + */ + private static final Font FONT; + static { + Font font = null; + final String filename = "font-gis.ttf"; + try { + InputStream in = Code.class.getResourceAsStream(filename); + if (in != null) try (in) { + font = Font.loadFont(in, 0); + } else { + // Intentionally caught immediately below. + throw new FileNotFoundException(filename); + } + } catch (IOException e) { + Logging.unexpectedException(Logger.getLogger(Modules.APPLICATION), FontGIS.class, "<cinit>", e); + } + FONT = font; + } + + /** + * Do not allow instantiation of this class. + */ + private FontGIS() { + } + + /** + * Returns a Font-GIS glyph for the given code. + * The code should be one of the {@link Code} constants. + * + * @param code one of the {@link Code} constants. + * @return the label to use as a glyph for the given code. + */ + public static Label glyph(char code) { + return glyph(code, 1); + } + + /** + * Returns a scaled Font-GIS glyph for the given code. + * The code should be one of the {@link Code} constants. + * + * @param code one of the {@link Code} constants. + * @param scale a scale factor to apply on the default font size. + * @return the label to use as a scaled glyph for the given code. + */ + public static Label glyph(final char code, final double scale) { + Font font = FONT; + if (font == null) { + return new Label("\u2B1A"); // Dotted square. + } + final Label glyph = new Label(new String(new char[] {code})); + if (scale != 1) { + font = Font.font(font.getName(), font.getSize() * scale); + } + glyph.setFont(font); + return glyph; + } + + /** + * Unicode values for Font-GIS icons. + * See the <a href="https://viglino.github.io/font-gis/">Font-GIS project</a> for browsing the icons. + * + * <h2>Implementation note</h2> + * Those constants are defined in a separated class for avoiding to load hundreds of field names in memory. + * Because all field values are constants of primitive type, the compiler should inline them in the caller code. + */ + public static final class Code extends Static { + /** + * Do not allow instantiation of this class. + */ + private Code() { + } + + /** + * Unicode value of a Font-GIS icon. + */ + public static final char + NORTH_ARROW = 0xEA8B, + NORTH_ARROW_N = 0xEA8C, + COMPASS = 0xEA90, + COMPASS_NEEDLE = 0xEA91, + COMPASS_ROSE = 0xEA92, + COMPASS_ROSE_N = 0xEA93, + COMPASS_ALT = 0xEB06, + COMPASS_ALT_O = 0xEB07, + ARROW_O = 0xEA3A, + ARROW = 0xEA3B, + MODIFY_LINE = 0xEA3C, + MODIFY_POLY = 0xEA3D, + MODIFY_POLY_O = 0xEA40, + COPY_POINT = 0xEA4F, + COPY_LINE = 0xEA50, + COPY_POLY = 0xEA51, + BUFFER = 0xEA6E, + DIFFERENCE = 0xEA6F, + INTERSECTION = 0xEA70, + UNION = 0xEA71, + SYM_DIFFERENCE = 0xEA72, + MOVE = 0xEA73, + MOVE_ALT = 0xEA74, + OFFSET = 0xEA75, + SNAP = 0xEA76, + SPLIT = 0xEA77, + SPLIT_LINE = 0xEA78, + SPLIT_POLYGON = 0xEA79, + CONVEX_HULL = 0xEAA8, + SELECT_EXTENT = 0xEAAD, + SNAP_ORTHO = 0xEAAE, + COLOR = 0xEAAF, + ROTATE = 0xEAE3, + FLIP_H = 0xEAE4, + FLIP_V = 0xEAE5, + SIMPLIFY = 0xEAE6, + PROJ_POINT = 0xEAE7, + SCALE_POLY = 0xEAE8, + SKELETONIZE = 0xEB17, + DILATATION = 0xEB18, + EROSION = 0xEB19, + TRANSLATE = 0xEB26, + TRANSLATE_X = 0xEB27, + TRANSLATE_Y = 0xEB28, + GPX_FILE = 0xEA99, + GEOJSON_FILE = 0xEA9A, + KML_FILE = 0xEA9B, + WMS = 0xEA9C, + WMTS = 0xEA9D, + WFS = 0xEA9E, + WFS_T = 0xEA9F, + MVT = 0xEAA0, + XYZ = 0xEAA1, + SHAPE_FILE = 0xEAA2, + ESRI_JSON_FILE = 0xEAA3, + TOPOJSON_FILE = 0xEAA4, + FOLDER_MAP = 0xEB2F, + WORLD_FOLDER_O = 0xEB30, + WORLD_FOLDER = 0xEB31, + FOLDER_GLOBE = 0xEB32, + FOLDER_GLOBE_O = 0xEB33, + FOLDER_MAPS = 0xEB34, + FOLDER_POI = 0xEB35, + FOLDER_POI_O = 0xEB36, + FOLDER_POIS = 0xEB37, + EARTH_NET = 0xEB38, + EARTH_NET_O = 0xEB39, + WCS = 0xEB59, + POINT = 0xEA01, + POLYLINE_PT = 0xEA02, + POLYGON_PT = 0xEA03, + POLYGON_HOLE_PT = 0xEA04, + RECTANGLE_PT = 0xEA05, + SQUARE_PT = 0xEA06, + CIRCLE_O = 0xEA07, + POLYLINE = 0xEA09, + POLYGON_O = 0xEA0A, + POLYGON_HOLE_O = 0xEA0B, + RECTANGLE_O = 0xEA0C, + SQUARE_O = 0xEA0D, + POLYGON_HOLE = 0xEA0E, + POLYGON = 0xEA0F, + RECTANGLE = 0xEA10, + SQUARE = 0xEA11, + CIRCLE = 0xEA12, + MULTIPOINT = 0xEA52, + BBOX_ALT = 0xEAA9, + EXTENT_ALT = 0xEAAA, + BBOX = 0xEAAB, + EXTENT = 0xEAAC, + MAP_EXTENT = 0xEAB0, + REGULAR_SHAPE_PT = 0xEAEB, + REGULAR_SHAPE_O = 0xEAEC, + REGULAR_SHAPE = 0xEAED, + LAYER = 0xEA41, + LAYER_O = 0xEA42, + LAYERS = 0xEA43, + LAYERS_O = 0xEA44, + LAYER_UP = 0xEA45, + LAYER_DOWN = 0xEA46, + LAYER_ALT = 0xEA47, + LAYER_ALT_O = 0xEA48, + LAYER_STACK = 0xEA49, + LAYER_STACK_O = 0xEA4A, + LAYER_ADD = 0xEA4B, + LAYER_ADD_O = 0xEA4C, + LAYER_RM = 0xEA4D, + LAYER_RM_O = 0xEA4E, + LAYER_POI = 0xEA6A, + LAYER_DOWNLOAD = 0xEA97, + LAYER_UPLOAD = 0xEA98, + LAYER_ROAD = 0xEAF0, + LAYER_HYDRO = 0xEAF1, + LAYER_LANDCOVER = 0xEAF2, + LAYER_CONTOUR = 0xEAF3, + LAYER_STAT = 0xEAF4, + LAYER_STAT_ALT = 0xEB29, + LAYER_EDIT = 0xEB2D, + LAYER_ALT_EDIT = 0xEB2E, + LAYER_HEIGHT = 0xEB41, + LAYER_2_ADD_O = 0xEB46, + LAYER_2_RM_O = 0xEB47, + LAYER_ALT_ADD_O = 0xEB48, + LAYER_ALT_RM_O = 0xEB49, + LAYER_ALT_X_O = 0xEB4A, + LAYERS_POI = 0xEB4F, + LAYER_ALT_POI = 0xEB50, + EARTH = 0xEA22, + EARTH_EURO_AFRICA = 0xEA23, + EARTH_ATLANTIC = 0xEA24, + EARTH_AMERICA = 0xEA25, + EARTH_PACIFIC = 0xEA26, + EARTH_AUSTRALIA = 0xEA27, + EARTH_ASIA = 0xEA28, + EARTH_NORTH = 0xEA29, + EARTH_SOUTH = 0xEA2A, + EARTH_O = 0xEA2B, + EARTH_EURO_AFRICA_O = 0xEA2C, + EARTH_ATLANTIC_O = 0xEA2D, + EARTH_AMERICA_O = 0xEA2E, + EARTH_PACIFIC_O = 0xEA2F, + EARTH_AUSTRALIA_O = 0xEA30, + EARTH_ASIA_O = 0xEA31, + EARTH_NORTH_O = 0xEA32, + EARTH_SOUTH_O = 0xEA33, + GLOBE = 0xEA36, + GLOBE_O = 0xEA37, + GLOBE_ALT = 0xEA38, + GLOBE_ALT_O = 0xEA39, + GLOBE_POI = 0xEA82, + NETWORK = 0xEABB, + NETWORK_O = 0xEABC, + TAG = 0xEAC1, + TAG_O = 0xEAC2, + TAGS = 0xEAC3, + TAGS_O = 0xEAC4, + EARTH_GEAR = 0xEAD5, + GLOBE_EARTH = 0xEAF8, + GLOBE_EARTH_ALT = 0xEAF9, + GLOBE_FAVORITE = 0xEAFB, + GLOBE_OPTIONS = 0xEAFC, + GLOBE_SHARE = 0xEAFD, + GLOBE_STAR = 0xEAFE, + GLOBE_SMILEY = 0xEAFF, + GLOBE_USER = 0xEB0C, + GLOBE_USERS = 0xEB0D, + GLOBE_SHIELD = 0xEB0E, + EARTH_NETWORK = 0xEB0F, + EARTH_NETWORK_O = 0xEB10, + GLOBE_GEAR = 0xEB11, + MAP = 0xEA53, + MAP_O = 0xEA54, + MAP_POI = 0xEA55, + WORLD_MAP_ALT = 0xEA56, + MAP_ROUTE = 0xEA57, + ROAD_MAP = 0xEA58, + CADASTRE_MAP = 0xEA59, + LANDCOVER_MAP = 0xEA5A, + BUS_MAP = 0xEA5B, + CONTOUR_MAP = 0xEA5C, + HYDRO_MAP = 0xEA5D, + WORLD_MAP = 0xEA68, + PIRATE_MAP = 0xEA6B, + STORY_MAP = 0xEA6D, + MAP_BOOK = 0xEA7A, + MAP_LEGEND = 0xEA85, + MAP_LEGEND_O = 0xEA86, + MAP_OPTIONS = 0xEA94, + MAP_OPTIONS_ALT = 0xEA95, + MAP_PRINT = 0xEA96, + WORLD_MAP_ALT_O = 0xEAB1, + FLOW_MAP = 0xEAB2, + MAP_STAT = 0xEAB3, + STATISTIC_MAP = 0xEAB4, + VORONOI_MAP = 0xEAB7, + TRIANGLE_MAP = 0xEAB8, + PHONE_MAP = 0xEAB9, + HEX_MAP = 0xEABA, + MAP_BOOKMARK = 0xEABD, + MAP_TAG = 0xEABF, + MAP_TAGS = 0xEAC0, + COMPARE_MAP = 0xEAD8, + SWIPE_MAP_V = 0xEAD9, + SWIPE_MAP_H = 0xEADA, + MAGNIFY_MAP = 0xEADB, + MAP_SHARE = 0xEAE0, + MAP_SEND = 0xEAE1, + MAP_SHARE_ALT = 0xEAE2, + MAP_ADD = 0xEAE9, + MAP_RM = 0xEAEA, + MAP_TIME = 0xEAEE, + TIME_MAP = 0xEAEF, + MAP_PLAY = 0xEAF5, + MAP_STAR = 0xEAF6, + MAP_FAVORITE = 0xEAF7, + MAP_SMILEY = 0xEB00, + MAP_CONTROL = 0xEB02, + MAP_LOCK = 0xEB04, + MAP_UNLOCK = 0xEB05, + WEATHER_MAP = 0xEB0B, + STORY_MAP_O = 0xEB2A, + STORY_MAPS = 0xEB2B, + MAP_EDIT = 0xEB2C, + HEIGHT_MAP = 0xEB40, + MAP_USER = 0xEB4B, + MAP_USERS = 0xEB4C, + MEASURE = 0xEA08, + MEASURE_LINE = 0xEA13, + MEASURE_AREA = 0xEA14, + MEASURE_AREA_ALT = 0xEA15, + SCALE = 0xEB01, + AZIMUTH = 0xEB53, + HELP_LARROW = 0xEA3E, + HELP_RARROW = 0xEA3F, + HOME = 0xEB14, + SATELLITE = 0xEB3A, + SATELLITE_EARTH = 0xEB3B, + DRONE = 0xEB3F, + POI = 0xEA16, + POI_O = 0xEA17, + POI_ALT = 0xEA18, + POI_ALT_O = 0xEA19, + PIN = 0xEA1A, + PUSHPIN = 0xEA1B, + POIS = 0xEA1C, + POIS_O = 0xEA1D, + POI_FAVORITE = 0xEA1E, + POI_FAVORITE_O = 0xEA1F, + POI_HOME = 0xEA20, + POI_HOME_O = 0xEA21, + POI_EARTH = 0xEA34, + PIN_EARTH = 0xEA35, + PIRATE_POI = 0xEA6C, + LOCATION_POI = 0xEA83, + LOCATION_POI_O = 0xEA84, + BOOKMARK_POI = 0xEABE, + BOOKMARK_POI_B = 0xEACF, + POI_MAP = 0xEAD6, + POI_MAP_O = 0xEAD7, + LOCATION_MAN = 0xEB15, + LOCATION_MAN_ALT = 0xEB16, + POI_INFO = 0xEB1C, + POI_INFO_O = 0xEB1D, + POSITION = 0xEB22, + POSITION_O = 0xEB23, + POSITION_MAN = 0xEB24, + POI_SLASH = 0xEB4D, + POI_SLASH_O = 0xEB4E, + ROUTE = 0xEA7B, + ROUTE_START = 0xEA7C, + ROUTE_END = 0xEA7D, + CAR = 0xEA7E, + BICYCLE = 0xEA7F, + PEDESTRIAN = 0xEA80, + HIKER = 0xEA81, + LOCATION_ARROW = 0xEA87, + LOCATION_ARROW_O = 0xEA88, + LOCATION = 0xEA89, + LOCATION_ON = 0xEA8A, + DIRECT = 0xEA8D, + REVERS = 0xEA8E, + TIMER = 0xEA8F, + SIGNPOST = 0xEAB5, + DIRECTION = 0xEAB6, + FLAG = 0xEAC5, + FLAG_O = 0xEAC6, + FLAG_START = 0xEAC7, + FLAG_START_O = 0xEAC8, + FLAG_FINISH = 0xEAC9, + FLAG_B = 0xEACA, + FLAB_B_O = 0xEACB, + FLAG_START_B = 0xEACC, + FLAG_START_B_O = 0xEACD, + FLAG_FINISH_B_O = 0xEACE, + START = 0xEAD0, + START_O = 0xEAD1, + STEP = 0xEAD2, + STEP_O = 0xEAD3, + FINISH = 0xEAD4, + DIRECTIONS = 0xEB03, + PHONE_ROUTE = 0xEB08, + PHONE_ROUTE_ALT = 0xEB09, + PHONE_ROUTE_ALT_R = 0xEB0A, + MAP_SEARCH = 0xEA5E, + SEARCH_MAP = 0xEA5F, + SEARCH_POI = 0xEA60, + SEARCH_GLOBE = 0xEA61, + SEARCH_HOME = 0xEA62, + SEARCH_ADDRESS = 0xEA63, + SEARCH_ATTRIBTUES = 0xEA64, + SEARCH_PROPERTIE = 0xEA65, + SEARCH_FEATURE = 0xEA66, + SEARCH_LAYER = 0xEA67, + SEARCH_COUNTRY = 0xEA69, + SEARCH_GLOBE_ALT = 0xEAFA, + SEARCH_COORD = 0xEB12, + SEARCH_DATA = 0xEB13, + ZOOM_IN = 0xEAA5, + ZOOM_OUT = 0xEAA6, + FULL_SCREEN = 0xEAA7, + SCREEN_DUB = 0xEADC, + SCREEN_SPLIT_H = 0xEADD, + SCREEN_SPLIT_V = 0xEADE, + SCREEN_MAG = 0xEADF, + COORD_SYSTEM = 0xEB1A, + COORD_SYSTEM_3D = 0xEB1B, + COORD_SYSTEM_ALT = 0xEB1E, + COORD_SYSTEM_3D_ALT = 0xEB1F, + GRID = 0xEB20, + CUBE_3D = 0xEB21, + COORD_GRID = 0xEB25, + PHOTOGRAMMETRY = 0xEB3C, + D360 = 0xEB3D, + TOPOGRAPHY = 0xEB3E, + GNSS = 0xEB42, + GNSS_ANTENNA = 0xEB43, + TACHEOMETER = 0xEB44, + THEODOLITE = 0xEB45, + PROFILE = 0xEB51, + PROFILE_O = 0xEB52, + SCREEN_DUB1 = 0xEB54, + SCREEN_DUB2 = 0xEB55, + SCREEN_DUB_O = 0xEB56, + SCREEN_MAG_O = 0xEB57, + SCREEN_MAG_ALT = 0xEB58; + } +}