Refactor font resolving to its own class/file

This commit is contained in:
2026-03-30 20:24:36 +09:00
parent a9674a3f45
commit 534af58f44
4 changed files with 99 additions and 71 deletions
@@ -0,0 +1,82 @@
using System.IO;
using MayShow.Interfaces;
using PdfSharp.Fonts;
namespace MayShow.Helpers;
class PDFFontResolver : IFontResolver
{
private string _runningProcessDirectory;
private ILogger? _logger;
public PDFFontResolver(string runningProcessDirectory, ILogger? logger)
{
_logger = logger;
_runningProcessDirectory = runningProcessDirectory;
}
public byte[]? GetFont(string faceName)
{
_logger?.LogInfo(string.Format("Loading font {0}", faceName));
if (faceName == "Noto Sans")
{
var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans Bold")
{
var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans JP")
{
var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans JP Bold")
{
var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf");
}
return File.ReadAllBytes(path);
}
return null;
}
public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic)
{
// LogInfo(string.Format("Resolving font name {0}", familyName));
if (familyName == "Noto Sans")
{
if (bold)
{
return new FontResolverInfo(familyName + " Bold");
}
return new FontResolverInfo(familyName);
}
if (familyName == "Noto Sans JP")
{
if (bold)
{
return new FontResolverInfo(familyName + " Bold");
}
return new FontResolverInfo(familyName);
}
return null;
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace MayShow.Interfaces;
interface ILogger
{
void LogInfo(string message, params object[]? arguments);
}
@@ -32,7 +32,7 @@ using MigraDoc.DocumentObjectModel.Visitors;
namespace MayShow.ViewModels; namespace MayShow.ViewModels;
class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown class CreatePDFReportViewModel : BaseViewModel, ICanCheckShutdown, ILogger
{ {
private bool _isPerformingInitialLoad; private bool _isPerformingInitialLoad;
private string _processDir; private string _processDir;
@@ -173,7 +173,7 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
} }
} }
private void LogInfo(string message, params object[]? arguments) public void LogInfo(string message, params object[]? arguments)
{ {
var timestamp = string.Format("[{0:s}]", DateTime.Now); var timestamp = string.Format("[{0:s}]", DateTime.Now);
Console.WriteLine(timestamp + " " + message, arguments); Console.WriteLine(timestamp + " " + message, arguments);
@@ -409,7 +409,11 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public async void RemoveAllItems() public async void RemoveAllItems()
{ {
var result = await DialogHost.Show(new ConfirmViewModel("Warning!", "Are you sure you want to remove all items from this report?", "Remove All Items", "Cancel")); var result = await DialogHost.Show(new ConfirmViewModel("Warning!", "Are you sure you want to remove all items from this report?", "Remove All Items", "Cancel")
{
ConfirmButtonUsesDangerStyle = true,
ConfirmTitleIcon = "\uf1f8;"
});
if (result != null && (bool)result) if (result != null && (bool)result)
{ {
ReportFiles.Clear(); ReportFiles.Clear();
@@ -574,70 +578,6 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
} }
} }
public byte[]? GetFont(string faceName)
{
LogInfo(string.Format("Loading font {0}", faceName));
if (faceName == "Noto Sans")
{
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans Bold")
{
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans JP")
{
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
}
return File.ReadAllBytes(path);
}
if (faceName == "Noto Sans JP Bold")
{
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf");
if (!File.Exists(path))
{
path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf");
}
return File.ReadAllBytes(path);
}
return null;
}
public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic)
{
// LogInfo(string.Format("Resolving font name {0}", familyName));
if (familyName == "Noto Sans")
{
if (bold)
{
return new FontResolverInfo(familyName + " Bold");
}
return new FontResolverInfo(familyName);
}
if (familyName == "Noto Sans JP")
{
if (bold)
{
return new FontResolverInfo(familyName + " Bold");
}
return new FontResolverInfo(familyName);
}
return null;
}
private Paragraph GetFooterParagraph() private Paragraph GetFooterParagraph()
{ {
var footerPar = new Paragraph(); var footerPar = new Paragraph();
@@ -678,7 +618,6 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
// https://forum.pdfsharp.net/viewtopic.php?f=2&t=1025 // https://forum.pdfsharp.net/viewtopic.php?f=2&t=1025
private async Task CreatePDF(string folderPath) private async Task CreatePDF(string folderPath)
{ {
// TODO: calculate needed width for images based on page width and margins and all that?
// safety checks // safety checks
var outputDir = _settings.SaveOutputPdfInWorkingDir ? folderPath : _settings.OutputPdfDir; var outputDir = _settings.SaveOutputPdfInWorkingDir ? folderPath : _settings.OutputPdfDir;
if (!Directory.Exists(outputDir)) if (!Directory.Exists(outputDir))
@@ -687,7 +626,7 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
return; return;
} }
// setup globals and consts... // setup globals and consts...
GlobalFontSettings.FontResolver = this; GlobalFontSettings.FontResolver = new PDFFontResolver(_processDir, this);
GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver(); GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver();
const decimal pageWidth = 8.5m; const decimal pageWidth = 8.5m;
const decimal pageHeight = 11.0m; const decimal pageHeight = 11.0m;
@@ -8,6 +8,7 @@ using MayShow.Interfaces;
using MayShow.Models; using MayShow.Models;
using MayShow.Helpers; using MayShow.Helpers;
using MayShows.Helpers; using MayShows.Helpers;
using System;
namespace MayShow.ViewModels; namespace MayShow.ViewModels;
@@ -46,9 +47,10 @@ class StartNewChooseReportViewModel : BaseViewModel
var reportInfo = new PDFReportInfo() var reportInfo = new PDFReportInfo()
{ {
Title = CreatingReportTitle, Title = CreatingReportTitle,
LastSaved = DateTime.Now
}; };
_settings.AllReportInfo.Add(reportInfo); _settings.AllReportInfo.Add(reportInfo);
// ... this sort is slow, technically, but we're not going to have millions of items here, so... // ... this sort and save is slow, technically, but we're not going to have millions of items here, so...
SavedReports = new ObservableCollection<PDFReportInfo>(_settings.AllReportInfo.OrderBy(x => x.Title)); SavedReports = new ObservableCollection<PDFReportInfo>(_settings.AllReportInfo.OrderBy(x => x.Title));
await _settings.SaveSettingsAsync(); await _settings.SaveSettingsAsync();
// create folder for report data // create folder for report data
@@ -67,7 +69,6 @@ class StartNewChooseReportViewModel : BaseViewModel
CreatingReportTitle = ""; // when user comes back they can start another new report CreatingReportTitle = ""; // when user comes back they can start another new report
} }
public void LoadExistingReport(object info) => LoadExistingReportImpl((PDFReportInfo) info); public void LoadExistingReport(object info) => LoadExistingReportImpl((PDFReportInfo) info);
public void LoadExistingReportImpl(PDFReportInfo reportInfo) public void LoadExistingReportImpl(PDFReportInfo reportInfo)
{ {