Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed assets/fonts/AllertaStencil.ttf
Binary file not shown.
Binary file added assets/fonts/BaseballClub.otf
Binary file not shown.
Binary file added assets/fonts/BeachDay.otf
Binary file not shown.
Binary file added assets/fonts/Bolton.ttf
Binary file not shown.
Binary file added assets/fonts/ButterChicken.ttf
Binary file not shown.
Binary file added assets/fonts/Chaser.otf
Binary file not shown.
Binary file added assets/fonts/ColorSport.ttf
Binary file not shown.
Binary file added assets/fonts/FungkyBrow.otf
Binary file not shown.
Binary file added assets/fonts/Hanky.otf
Binary file not shown.
Binary file added assets/fonts/Kurvaceous.otf
Binary file not shown.
Binary file added assets/fonts/LuckiestGuy.ttf
Binary file not shown.
Binary file added assets/fonts/MilkyWay.ttf
Binary file not shown.
Binary file added assets/fonts/NatureKeystone.otf
Binary file not shown.
Binary file added assets/fonts/RacingGames.otf
Binary file not shown.
Binary file added assets/fonts/Sakana.ttf
Binary file not shown.
Binary file added assets/fonts/SauceTomato.otf
Binary file not shown.
Binary file added assets/fonts/SundayMagic.otf
Binary file not shown.
Binary file added assets/fonts/Valty.otf
Binary file not shown.
Binary file added assets/fonts/VintageBrowner.otf
Binary file not shown.
Binary file added assets/fonts/VintageRubicon.otf
Binary file not shown.
Binary file added assets/fonts/Voegies.ttf
Binary file not shown.
Binary file added assets/fonts/ss-diamond.otf
Binary file not shown.
Binary file added assets/fonts/ss-malibu.otf
Binary file not shown.
20 changes: 10 additions & 10 deletions pretty_gpx/common/data/place_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ def get_start_end_named_points(gpx_track: GpxTrack | MultiGpxTrack) -> list[Scat

if get_distance_m(lonlat_1=(start_lon, start_lat),
lonlat_2=(end_lon, end_lat)) < 1000:
# Start and end are too close, skip name and position of end point
end = ScatterPoint(name=None,
lon=start_lon,
lat=start_lat,
category=ScatterPointCategory.END)
# Start and end are too close, skip name of end point
end_name = None
else:
# Start and end are far enough, keep name of end point only if different from start
name = get_place_name(lon=end_lon, lat=end_lat)
end = ScatterPoint(name=name if name != start.name else None,
lon=end_lon,
lat=end_lat,
category=ScatterPointCategory.END)
end_name = get_place_name(lon=end_lon, lat=end_lat)
if end_name == start.name:
end_name = None

end = ScatterPoint(name=end_name,
lon=end_lon,
lat=end_lat,
category=ScatterPointCategory.END)

return [start, end]
87 changes: 80 additions & 7 deletions pretty_gpx/common/drawing/utils/fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Fonts."""
import os
from enum import Enum
from typing import Final

from matplotlib.font_manager import FontProperties

Expand All @@ -10,14 +11,86 @@

class CustomFont(Enum):
"""Custom Fonts Enum."""
DEJA_VU_SANS_BOLD = FontProperties(family="DejaVu Sans", weight="bold")
LOBSTER = FontProperties(family="Lobster", fname=os.path.join(FONTS_DIR, "Lobster.ttf"))
MONOTON = FontProperties(family="Monoton", fname=os.path.join(FONTS_DIR, "Monoton.ttf"))
GOCHI_HAND = FontProperties(family="Gochi Hand", fname=os.path.join(FONTS_DIR, "GochiHand.ttf"))
EMILIO_20 = FontProperties(family="Emilio 20", fname=os.path.join(FONTS_DIR, "Emilio20.ttf"))
ALLERTA_STENCIL = FontProperties(family="Allerta Stencil", fname=os.path.join(FONTS_DIR, "AllertaStencil.ttf"))
DEJA_VU_SANS_BOLD = FontProperties(weight="bold")
LOBSTER = FontProperties(fname=os.path.join(FONTS_DIR, "Lobster.ttf"))
MONOTON = FontProperties(fname=os.path.join(FONTS_DIR, "Monoton.ttf"))
GOCHI_HAND = FontProperties(fname=os.path.join(FONTS_DIR, "GochiHand.ttf"))
EMILIO_20 = FontProperties(fname=os.path.join(FONTS_DIR, "Emilio20.ttf"))
BASEBALL_CLUB = FontProperties(fname=os.path.join(FONTS_DIR, "BaseballClub.otf"))
BEACHDAY = FontProperties(fname=os.path.join(FONTS_DIR, "BeachDay.otf"))
BUTTER_CHICKEN = FontProperties(fname=os.path.join(FONTS_DIR, "ButterChicken.ttf"))
COLOR_SPORT = FontProperties(fname=os.path.join(FONTS_DIR, "ColorSport.ttf"))
HANKY = FontProperties(fname=os.path.join(FONTS_DIR, "Hanky.otf"))
LUCKIEST_GUY = FontProperties(fname=os.path.join(FONTS_DIR, "LuckiestGuy.ttf"))
MILKY_WAY = FontProperties(fname=os.path.join(FONTS_DIR, "MilkyWay.ttf"))
SAKANA = FontProperties(fname=os.path.join(FONTS_DIR, "Sakana.ttf"))
SAUCE_TOMATO = FontProperties(fname=os.path.join(FONTS_DIR, "SauceTomato.otf"))
SUNDAY_MAGIC = FontProperties(fname=os.path.join(FONTS_DIR, "SundayMagic.otf"))
VALTY = FontProperties(fname=os.path.join(FONTS_DIR, "Valty.otf"))

BOLTON = FontProperties(fname=os.path.join(FONTS_DIR, "Bolton.ttf"))
CHASER = FontProperties(fname=os.path.join(FONTS_DIR, "Chaser.otf"))
FUNGKY_BROW = FontProperties(fname=os.path.join(FONTS_DIR, "FungkyBrow.otf"))
KURVACEOUS = FontProperties(fname=os.path.join(FONTS_DIR, "Kurvaceous.otf"))
NATURE_KEYSTONE = FontProperties(fname=os.path.join(FONTS_DIR, "NatureKeystone.otf"))
RACING_GAMES = FontProperties(fname=os.path.join(FONTS_DIR, "RacingGames.otf"))
SS_DIAMOND = FontProperties(fname=os.path.join(FONTS_DIR, "ss-diamond.otf"))
SS_MALIBU = FontProperties(fname=os.path.join(FONTS_DIR, "ss-malibu.otf"))
VINTAGE_BROWNER = FontProperties(fname=os.path.join(FONTS_DIR, "VintageBrowner.otf"))
VINTAGE_RUBICON = FontProperties(fname=os.path.join(FONTS_DIR, "VintageRubicon.otf"))
VOEGIES = FontProperties(fname=os.path.join(FONTS_DIR, "Voegies.ttf"))

@property
def font_name(self) -> str:
"""Get the font name."""
"""Get the name of the FontProperties object."""
return self.value.get_name()


ANNOTATION_FONT: Final = CustomFont.DEJA_VU_SANS_BOLD

TITLE_FONTS: Final = (
CustomFont.LOBSTER,
CustomFont.MONOTON,
CustomFont.GOCHI_HAND,
CustomFont.EMILIO_20,
CustomFont.BASEBALL_CLUB,
CustomFont.BEACHDAY,
CustomFont.BUTTER_CHICKEN,
CustomFont.COLOR_SPORT,
CustomFont.HANKY,
CustomFont.LUCKIEST_GUY,
CustomFont.MILKY_WAY,
CustomFont.SAKANA,
CustomFont.SAUCE_TOMATO,
CustomFont.SUNDAY_MAGIC,
CustomFont.VALTY,
CustomFont.BOLTON,
CustomFont.FUNGKY_BROW,
CustomFont.NATURE_KEYSTONE,
CustomFont.RACING_GAMES,
CustomFont.SS_DIAMOND,
CustomFont.SS_MALIBU,
CustomFont.VINTAGE_RUBICON,
CustomFont.VOEGIES,
)

STATS_FONTS: Final = (
CustomFont.LOBSTER,
CustomFont.GOCHI_HAND,
CustomFont.BASEBALL_CLUB,
CustomFont.BEACHDAY,
CustomFont.BUTTER_CHICKEN,
CustomFont.LUCKIEST_GUY,
CustomFont.SAKANA,
CustomFont.SAUCE_TOMATO,
CustomFont.SUNDAY_MAGIC,
CustomFont.BOLTON,
CustomFont.CHASER,
CustomFont.KURVACEOUS,
CustomFont.NATURE_KEYSTONE,
CustomFont.RACING_GAMES,
CustomFont.SS_DIAMOND,
CustomFont.SS_MALIBU,
CustomFont.VINTAGE_RUBICON,
CustomFont.VOEGIES,
)
6 changes: 4 additions & 2 deletions pretty_gpx/rendering_modes/city/drawing/city_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from pretty_gpx.common.drawing.utils.color_theme import DarkTheme
from pretty_gpx.common.drawing.utils.drawing_figure import A4Float
from pretty_gpx.common.drawing.utils.drawing_figure import MetersFloat
from pretty_gpx.common.drawing.utils.fonts import ANNOTATION_FONT
from pretty_gpx.common.drawing.utils.fonts import CustomFont
from pretty_gpx.common.drawing.utils.fonts import TITLE_FONTS
from pretty_gpx.common.drawing.utils.plt_marker import MarkerType
from pretty_gpx.common.drawing.utils.scatter_point import ScatterPointCategory
from pretty_gpx.rendering_modes.city.data.roads import CityRoadPrecision
Expand Down Expand Up @@ -85,7 +87,7 @@ def default() -> "CityParams":
ScatterPointCategory.END: AnnotatedScatterParams(arrow_linewidth=A4Float(mm=0.5),
fontsize=A4Float(mm=3.0))
},
annot_fontproperties=CustomFont.DEJA_VU_SANS_BOLD.value,
annot_fontproperties=ANNOTATION_FONT.value,
annot_ha="center",
annot_va="center",
city_roads_lw={
Expand Down Expand Up @@ -124,5 +126,5 @@ def default() -> "CityParams":

centered_title_font_color="cyan",
centered_title_font_size=A4Float(mm=20),
centered_title_fontproperties=CustomFont.LOBSTER.value
centered_title_fontproperties=TITLE_FONTS[0].value
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from pretty_gpx.common.drawing.components.annotated_scatter import ScatterParams
from pretty_gpx.common.drawing.utils.color_theme import DarkTheme
from pretty_gpx.common.drawing.utils.drawing_figure import A4Float
from pretty_gpx.common.drawing.utils.fonts import ANNOTATION_FONT
from pretty_gpx.common.drawing.utils.fonts import CustomFont
from pretty_gpx.common.drawing.utils.fonts import TITLE_FONTS
from pretty_gpx.common.drawing.utils.plt_marker import MarkerType
from pretty_gpx.common.drawing.utils.scatter_point import ScatterPointCategory
from pretty_gpx.rendering_modes.mountain.drawing.mountain_colors import MOUNTAIN_COLOR_THEMES
Expand Down Expand Up @@ -69,7 +71,7 @@ def default() -> "MountainParams":
ScatterPointCategory.END: AnnotatedScatterParams(arrow_linewidth=A4Float(mm=0.5),
fontsize=A4Float(mm=3.0))
},
annot_fontproperties=CustomFont.DEJA_VU_SANS_BOLD.value,
annot_fontproperties=ANNOTATION_FONT.value,
annot_ha="center",
annot_va="center",
mountain_background_color=MOUNTAIN_COLOR_THEMES[DarkTheme.BLUE_PURPLE_YELLOW].background_color,
Expand All @@ -93,5 +95,5 @@ def default() -> "MountainParams":

centered_title_font_color="cyan",
centered_title_font_size=A4Float(mm=20),
centered_title_fontproperties=CustomFont.LOBSTER.value
centered_title_fontproperties=TITLE_FONTS[0].value
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from pretty_gpx.common.drawing.components.annotated_scatter import ScatterParams
from pretty_gpx.common.drawing.utils.color_theme import DarkTheme
from pretty_gpx.common.drawing.utils.drawing_figure import A4Float
from pretty_gpx.common.drawing.utils.fonts import ANNOTATION_FONT
from pretty_gpx.common.drawing.utils.fonts import CustomFont
from pretty_gpx.common.drawing.utils.fonts import TITLE_FONTS
from pretty_gpx.common.drawing.utils.plt_marker import MarkerType
from pretty_gpx.common.drawing.utils.scatter_point import ScatterPointCategory
from pretty_gpx.rendering_modes.mountain.drawing.mountain_colors import MOUNTAIN_COLOR_THEMES
Expand Down Expand Up @@ -69,7 +71,7 @@ def default() -> "MultiMountainParams":
ScatterPointCategory.END: AnnotatedScatterParams(arrow_linewidth=A4Float(mm=0.5),
fontsize=A4Float(mm=3.0))
},
annot_fontproperties=CustomFont.DEJA_VU_SANS_BOLD.value,
annot_fontproperties=ANNOTATION_FONT.value,
annot_ha="center",
annot_va="center",
mountain_background_color=MOUNTAIN_COLOR_THEMES[DarkTheme.BLUE_PURPLE_YELLOW].background_color,
Expand All @@ -93,5 +95,5 @@ def default() -> "MultiMountainParams":

centered_title_font_color="cyan",
centered_title_font_size=A4Float(mm=20),
centered_title_fontproperties=CustomFont.LOBSTER.value
centered_title_fontproperties=TITLE_FONTS[0].value
)
53 changes: 53 additions & 0 deletions pretty_gpx/test/test_fonts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/python3
"""Test Fonts."""

from collections.abc import Iterable
from io import BytesIO
from warnings import catch_warnings

import matplotlib
import matplotlib.pyplot as plt
import pytest
from matplotlib.font_manager import findfont

from pretty_gpx.common.drawing.utils.fonts import CustomFont
from pretty_gpx.common.drawing.utils.fonts import STATS_FONTS
from pretty_gpx.common.utils.asserts import assert_isfile


def test_fonts_available() -> None:
"""Test that all fonts are available."""
for font in CustomFont:
font_path = findfont(font.value)
assert_isfile(font_path, msg=f"Font {font.value.get_name()} not found at {font_path}")


def test_fonts_matplotlib() -> None:
"""Test that matplotlib can use the fonts."""
matplotlib.use('Agg')
plt.figure()
for font in CustomFont:
plt.text(0.5, 0.5, "This is a Test", fontproperties=font.value)
plt.gcf()
plt.close()


def __assert_available_glyphs(fonts: Iterable[CustomFont], string_to_test: str) -> None:
"""Assert that all glyphs present in the input `string_to_test` are available in the fonts."""
matplotlib.use('Agg')
plt.figure()
with catch_warnings(record=True) as wlist:
for font in fonts:
plt.text(0.5, 0.5, string_to_test, fontproperties=font.value)
plt.savefig(BytesIO(), format='png')
plt.close()
assert len(wlist) == 0, "\n".join([str(w) for w in wlist])


def test_stats_fonts_matplotlib_numbers() -> None:
"""Test that matplotlib can use the stats fonts with numbers."""
with pytest.raises(AssertionError):
__assert_available_glyphs(fonts=list(CustomFont), string_to_test="1234567890 +-")

__assert_available_glyphs(fonts=STATS_FONTS, string_to_test="123456789")
__assert_available_glyphs(fonts=STATS_FONTS, string_to_test="+-")
11 changes: 11 additions & 0 deletions pretty_gpx/ui/pages/city/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
"""City Page."""
from dataclasses import dataclass

from pretty_gpx.common.drawing.utils.drawing_figure import A4Float
from pretty_gpx.common.drawing.utils.fonts import STATS_FONTS
from pretty_gpx.common.drawing.utils.scatter_point import ScatterPointCategory
from pretty_gpx.rendering_modes.city.data.roads import CityRoadPrecision
from pretty_gpx.rendering_modes.city.drawing.city_colors import CITY_COLOR_THEMES
from pretty_gpx.rendering_modes.city.drawing.city_drawer import CityDrawer
from pretty_gpx.rendering_modes.city.drawing.city_params import CityParams
from pretty_gpx.ui.pages.template.ui_font_and_size_select import UiFontAndSizeSelect
from pretty_gpx.ui.pages.template.ui_input import UiInputInt
from pretty_gpx.ui.pages.template.ui_manager import UiManager
from pretty_gpx.ui.pages.template.ui_toggle import UiToggle
Expand All @@ -22,6 +25,7 @@ class CityUiManager(UiManager[CityDrawer]):
"""City Ui Manager."""
uphill: UiInputInt
road_max_precision: UiToggle[CityRoadPrecision]
stats_font: UiFontAndSizeSelect

def __init__(self) -> None:
drawer = CityDrawer(params=CityParams.default(), top_ratio=0.18, bot_ratio=0.22, margin_ratio=0.1)
Expand All @@ -37,6 +41,10 @@ def __init__(self) -> None:
tooltip="Change the roads level of details",
on_change=self.on_click_update,
start_key=CityRoadPrecision.MEDIUM.pretty_name)
self.stats_font = UiFontAndSizeSelect(label="Stats' Font",
fonts=STATS_FONTS,
start_fontsize=A4Float(mm=14),
on_change=self.on_click_update)

@staticmethod
def get_chat_msg() -> list[str]:
Expand All @@ -60,6 +68,9 @@ def update_drawer_params(self) -> None:

self.drawer.params.profile_fill_color = theme.track_color
self.drawer.params.profile_font_color = theme.background_color
self.drawer.params.profile_font_size = self.stats_font.fontsize
self.drawer.params.profile_fontproperties = self.stats_font.font.value

self.drawer.params.centered_title_font_color = theme.point_color
self.drawer.params.centered_title_fontproperties = self.font.font.value
self.drawer.params.centered_title_font_size = self.font._current_fontsize
Expand Down
12 changes: 12 additions & 0 deletions pretty_gpx/ui/pages/mountain/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
"""Mountain Page."""
from dataclasses import dataclass

from pretty_gpx.common.drawing.utils.drawing_figure import A4Float
from pretty_gpx.common.drawing.utils.fonts import STATS_FONTS
from pretty_gpx.common.drawing.utils.scatter_point import ScatterPointCategory
from pretty_gpx.rendering_modes.mountain.drawing.hillshading import AZIMUTHS
from pretty_gpx.rendering_modes.mountain.drawing.mountain_colors import MOUNTAIN_COLOR_THEMES
from pretty_gpx.rendering_modes.mountain.drawing.mountain_drawer import MountainDrawer
from pretty_gpx.rendering_modes.mountain.drawing.mountain_params import MountainParams
from pretty_gpx.ui.pages.template.ui_font_and_size_select import UiFontAndSizeSelect
from pretty_gpx.ui.pages.template.ui_input import UiInputInt
from pretty_gpx.ui.pages.template.ui_manager import UiManager
from pretty_gpx.ui.pages.template.ui_toggle import UiToggle
Expand All @@ -22,6 +25,7 @@ class MountainUiManager(UiManager[MountainDrawer]):
"""Mountain Ui Manager."""
uphill: UiInputInt
azimuth: UiToggle[int]
stats_font: UiFontAndSizeSelect

def __init__(self) -> None:
drawer = MountainDrawer(params=MountainParams.default(), top_ratio=0.18, bot_ratio=0.22, margin_ratio=0.1)
Expand All @@ -35,6 +39,10 @@ def __init__(self) -> None:
self.azimuth = UiToggle[int].create(mapping=AZIMUTHS,
tooltip="Select the azimuth angle for the hillshading",
on_change=self.on_click_update)
self.stats_font = UiFontAndSizeSelect(label="Stats' Font",
fonts=STATS_FONTS,
start_fontsize=A4Float(mm=14),
on_change=self.on_click_update)

@staticmethod
def get_chat_msg() -> list[str]:
Expand All @@ -53,8 +61,12 @@ def update_drawer_params(self) -> None:
self.drawer.params.mountain_background_color = theme.background_color
self.drawer.params.mountain_dark_mode = theme.dark_mode
self.drawer.params.mountain_azimuth = self.azimuth.value

self.drawer.params.profile_fill_color = theme.track_color
self.drawer.params.profile_font_color = theme.background_color
self.drawer.params.profile_font_size = self.stats_font.fontsize
self.drawer.params.profile_fontproperties = self.stats_font.font.value

self.drawer.params.centered_title_font_color = theme.peak_color
self.drawer.params.centered_title_fontproperties = self.font.font.value
self.drawer.params.centered_title_font_size = self.font._current_fontsize
Expand Down
Loading