11 Commits

Author SHA1 Message Date
mbabienco a1858443e8 Bump version number 2026-03-12 21:17:27 +09:00
mbabienco f34a7092e4 Resize PDF images too (Docnet rendering) 2026-03-12 21:09:34 +09:00
mbabienco aed85c7555 Use page size and pg items to calc max image size 2026-03-12 20:58:20 +09:00
mbabienco 25f739667d Allow resolving Noto Sans font 2026-03-12 20:56:38 +09:00
mbabienco 1fae3f5341 Redo image resizing
Hack fix guesswork sizing
2026-03-12 20:21:41 +09:00
mbabienco 5dda88521d Add black border around images/pdfs
Makes viewing things with no border/white border much easier.
2026-03-12 19:34:56 +09:00
mbabienco 742ecb148a Simply if statement 2026-03-12 19:07:25 +09:00
mbabienco 4ad4a0852f Bump Magick.NET for vulnerability 2026-03-12 19:02:17 +09:00
mbabienco c44093c5ee Fix wrong About menu title 2026-03-04 21:10:21 +09:00
mbabienco 71f4fda2d4 Remove unneeded TODO comment 2026-03-03 12:54:53 +09:00
mbabienco 478f67aa82 Convert remaining files to file-scoped namespace 2026-03-03 12:54:27 +09:00
16 changed files with 347 additions and 209 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
; Non-commercial use only ; Non-commercial use only
#define MyAppName "MayShow" #define MyAppName "MayShow"
#define MyAppVersion "1.4.0" #define MyAppVersion "1.4.1"
#define MyAppPublisher "Quickity Quack Productions" #define MyAppPublisher "Quickity Quack Productions"
#define MyAppExeName "MayShow.exe" #define MyAppExeName "MayShow.exe"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION="1.4.0" VERSION="1.4.1"
SRC_DIR="src" # user ran script from main folder SRC_DIR="src" # user ran script from main folder
if [ ! -d "$SRC_DIR" ]; then if [ ! -d "$SRC_DIR" ]; then
SRC_DIR= "../src" # try SRC_DIR= "../src" # try
+1 -1
View File
@@ -131,7 +131,7 @@
</Application.Resources> </Application.Resources>
<NativeMenu.Menu> <NativeMenu.Menu>
<NativeMenu> <NativeMenu>
<NativeMenuItem Header="About ReceiptBuilder" Click="AboutOnClick" /> <NativeMenuItem Header="About MayShow" Click="AboutOnClick" />
</NativeMenu> </NativeMenu>
</NativeMenu.Menu> </NativeMenu.Menu>
</Application> </Application>
+1 -3
View File
@@ -4,8 +4,7 @@ using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
namespace MayShow.Helpers namespace MayShow.Helpers;
{
// https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?view=netframework-4.7.2 // https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?view=netframework-4.7.2
class ChangeNotifier : INotifyPropertyChanged class ChangeNotifier : INotifyPropertyChanged
@@ -16,4 +15,3 @@ namespace MayShow.Helpers
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
} }
}
+1 -1
View File
@@ -3,7 +3,7 @@ namespace MayShow.Helpers;
class Constants class Constants
{ {
public static string AppVersion = "1.4.0"; public static string AppVersion = "1.4.1";
public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ]; public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ];
public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ]; public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ];
+2 -2
View File
@@ -12,7 +12,7 @@
<PublishTrimmed>true</PublishTrimmed> <PublishTrimmed>true</PublishTrimmed>
<PublishAot>true</PublishAot> <PublishAot>true</PublishAot>
<AssemblyName>MayShow</AssemblyName> <AssemblyName>MayShow</AssemblyName>
<AssemblyVersion>1.4.0</AssemblyVersion> <!-- Also update Constants version --> <AssemblyVersion>1.4.1</AssemblyVersion> <!-- Also update Constants version -->
<ApplicationIcon>MayShow-icon.ico</ApplicationIcon> <ApplicationIcon>MayShow-icon.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -58,7 +58,7 @@
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets> <PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="PDFsharp-MigraDoc" Version="6.2.4" /> <PackageReference Include="PDFsharp-MigraDoc" Version="6.2.4" />
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.10.3" /> <PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.10.4" />
<PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" /> <PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" />
<PackageReference Include="DialogHost.Avalonia" Version="0.10.4" /> <PackageReference Include="DialogHost.Avalonia" Version="0.10.4" />
<PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" /> <PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" />
+2 -3
View File
@@ -5,8 +5,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace MayShow.ViewModels namespace MayShow.ViewModels;
{
class BaseViewModel : ChangeNotifier class BaseViewModel : ChangeNotifier
{ {
IChangeViewModel _viewModelChanger; IChangeViewModel _viewModelChanger;
@@ -44,4 +44,3 @@ namespace MayShow.ViewModels
#endregion #endregion
} }
}
+186 -39
View File
@@ -28,6 +28,7 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using Docnet.Core.Readers; using Docnet.Core.Readers;
using MigraDoc.DocumentObjectModel.Visitors;
namespace MayShow.ViewModels; namespace MayShow.ViewModels;
@@ -576,6 +577,24 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public byte[]? GetFont(string faceName) public byte[]? GetFont(string faceName)
{ {
LogInfo(string.Format("Loading font {0}", 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") if (faceName == "Noto Sans JP")
{ {
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
@@ -600,6 +619,14 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic) public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic)
{ {
// LogInfo(string.Format("Resolving font name {0}", familyName)); // 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 (familyName == "Noto Sans JP")
{ {
if (bold) if (bold)
@@ -611,11 +638,47 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
return null; return null;
} }
private Paragraph GetFooterParagraph()
{
var footerPar = new Paragraph();
footerPar.Format.Alignment = ParagraphAlignment.Center;
footerPar.Format.Font.Size = 10;
footerPar.AddText("--Page ");
footerPar.AddPageField();
footerPar.AddText(" of ");
footerPar.AddNumPagesField();
footerPar.AddText("--");
footerPar.AddLineBreak();
footerPar.AddText("Report generated on " + DateTime.Now.ToString("f"));
footerPar.Tag = "FooterPar";
footerPar.Format.Font.Name = "Noto Sans";
return footerPar;
}
private decimal GetExistingPageItemHeight(PdfDocumentRenderer pdfRenderer, decimal footerParagraphHeight)
{
pdfRenderer.DocumentRenderer.PrepareDocument();
var currPageCount = pdfRenderer.DocumentRenderer.FormattedDocument?.PageCount;
var heightForExistingItemsOnPage = footerParagraphHeight;
if (currPageCount.HasValue)
{
var renderInfo = pdfRenderer.DocumentRenderer.GetRenderInfoFromPage(currPageCount.Value);
if (renderInfo != null)
{
// Console.WriteLine("Got render info for page: {0}", currPageCount);
foreach (var item in renderInfo)
{
heightForExistingItemsOnPage += (decimal)item.LayoutInfo.ContentArea.Height.Inch;
}
}
}
return heightForExistingItemsOnPage;
}
// 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? // TODO: calculate needed width for images based on page width and margins and all that?
// TODO: resize (non-HEIC) images for smaller size...?
// 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))
@@ -623,12 +686,26 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
await DialogHost.Show(new WarningViewModel("Output directory not found! Please adjust your application Settings before continuing. Output directory: " + outputDir)); await DialogHost.Show(new WarningViewModel("Output directory not found! Please adjust your application Settings before continuing. Output directory: " + outputDir));
return; return;
} }
// setup globals and consts...
GlobalFontSettings.FontResolver = this;
GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver();
const decimal pageWidth = 8.5m;
const decimal pageHeight = 11.0m;
const decimal margin = 0.5m;
const int imageResolution = 72;
const int imageInsertMarginPixels = 30; // we calculate max available; use max - this # for max image size
var maxItemPxWidth = ((pageWidth - (2 * margin)) * imageResolution) - imageInsertMarginPixels;
// start making PDF! // start making PDF!
IsCreatingPDF = true; IsCreatingPDF = true;
var pdfDoc = new Document(); var pdfDoc = new Document();
var outputFileName = ReportTitle + ".pdf"; var outputFileName = ReportTitle + ".pdf";
var folderName = new DirectoryInfo(folderPath).Name; var folderName = new DirectoryInfo(folderPath).Name;
const int imageWidth = 425; const int maxImageWidth = 425;
var imageLineFormat = new MigraDoc.DocumentObjectModel.Shapes.LineFormat()
{
Color = Colors.Black,
Width = Unit.FromPoint(2),
};;
if (folderName.Contains('-')) if (folderName.Contains('-'))
{ {
// see if year/month format // see if year/month format
@@ -643,33 +720,51 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
LogInfo("Auto-changed output file name to " + outputFileName); LogInfo("Auto-changed output file name to " + outputFileName);
} }
} }
// setup initial section (for page characteristics)
var section = pdfDoc.AddSection(); var section = pdfDoc.AddSection();
section.PageSetup.PageFormat = PageFormat.Letter; section.PageSetup.PageFormat = PageFormat.Letter;
section.PageSetup.PageWidth = "8.5in"; section.PageSetup.PageWidth = pageWidth + "in";
section.PageSetup.PageHeight = "11in"; section.PageSetup.PageHeight = pageHeight + "in";
section.PageSetup.TopMargin = "0.5in"; section.PageSetup.TopMargin = margin + "in";
section.PageSetup.RightMargin = "0.5in"; section.PageSetup.RightMargin = margin + "in";
section.PageSetup.BottomMargin = "0.5in"; section.PageSetup.BottomMargin = margin + "in";
section.PageSetup.LeftMargin = "0.5in"; section.PageSetup.LeftMargin = margin + "in";
// setup footer for page number // setup footer for page number
var footerPar = new Paragraph(); var footerPar = GetFooterParagraph();
footerPar.Format.Alignment = ParagraphAlignment.Center;
footerPar.Format.Font.Size = 10;
footerPar.AddText("--Page ");
footerPar.AddPageField();
footerPar.AddText(" of ");
footerPar.AddNumPagesField();
footerPar.AddText("--");
footerPar.AddLineBreak();
footerPar.AddText("Report generated on " + DateTime.Now.ToString("f"));
section.Footers.Primary.Add(footerPar); section.Footers.Primary.Add(footerPar);
// add report title // create a quick PDF doc renderer to measure footer paragraph height
var footerParagraphHeight = 0.4m; // estimate
var footerOnlyPdfDoc = new Document();
var sectionClone = section.Clone();
footerOnlyPdfDoc.Add(sectionClone);
sectionClone.Add(GetFooterParagraph());
var footerPdfRenderer = new PdfDocumentRenderer
{
Document = footerOnlyPdfDoc
};
footerPdfRenderer.DocumentRenderer.PrepareDocument();
var footerRenderInfo = footerPdfRenderer.DocumentRenderer.GetRenderInfoFromPage(1);
if (footerRenderInfo != null)
{
foreach (var item in footerRenderInfo)
{
if (item.DocumentObject.Tag?.ToString() == "FooterPar")
{
Console.WriteLine("Got footer paragraph height!");
footerParagraphHeight = (decimal)item.LayoutInfo.ContentArea.Height.Inch;
break;
}
}
}
// continue setting up document
// First page only: add report title
var reportTitlePar = section.AddParagraph(); var reportTitlePar = section.AddParagraph();
reportTitlePar.Format.Alignment = ParagraphAlignment.Center; reportTitlePar.Format.Alignment = ParagraphAlignment.Center;
reportTitlePar.Format.Font.Size = 16; reportTitlePar.Format.Font.Size = 16;
reportTitlePar.Format.Font.Bold = true; reportTitlePar.Format.Font.Bold = true;
reportTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too reportTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
reportTitlePar.AddText(ReportTitle); reportTitlePar.AddText(ReportTitle);
reportTitlePar.Tag = "TitlePar";
// get converted files directory path and create it if necessary // get converted files directory path and create it if necessary
var convertedDir = Path.Combine(Utilities.GetInternalDataPath(), "converted"); var convertedDir = Path.Combine(Utilities.GetInternalDataPath(), "converted");
if (!Directory.Exists(convertedDir)) if (!Directory.Exists(convertedDir))
@@ -677,8 +772,11 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
Directory.CreateDirectory(convertedDir); Directory.CreateDirectory(convertedDir);
} }
// //
GlobalFontSettings.FontResolver = this; var pdfRenderer = new PdfDocumentRenderer
GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver(); {
Document = pdfDoc,
WorkingDirectory = folderPath
};
var hasAddedData = false; var hasAddedData = false;
for (var i = 0; i < ReportFiles.Count; i++) for (var i = 0; i < ReportFiles.Count; i++)
{ {
@@ -705,12 +803,14 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
imageTitlePar.Format.Font.Bold = true; imageTitlePar.Format.Font.Bold = true;
imageTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too imageTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
imageTitlePar.AddText(string.IsNullOrWhiteSpace(file.Title) ? file.FileName : file.Title); imageTitlePar.AddText(string.IsNullOrWhiteSpace(file.Title) ? file.FileName : file.Title);
imageTitlePar.Tag = "ReceiptTitlePar";
var receiptDatePar = section.AddParagraph(); var receiptDatePar = section.AddParagraph();
receiptDatePar.Format.Alignment = ParagraphAlignment.Center; receiptDatePar.Format.Alignment = ParagraphAlignment.Center;
receiptDatePar.Format.Font.Size = 12; receiptDatePar.Format.Font.Size = 12;
receiptDatePar.Format.Font.Bold = true; receiptDatePar.Format.Font.Bold = true;
receiptDatePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too receiptDatePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
receiptDatePar.AddText(file.ReceiptDate.ToString("yyyy-MM-dd")); receiptDatePar.AddText(file.ReceiptDate.ToString("yyyy-MM-dd"));
receiptDatePar.Tag = "ReceiptDatePar";
if (!string.IsNullOrWhiteSpace(file.Notes)) if (!string.IsNullOrWhiteSpace(file.Notes))
{ {
var imageNotesPar = section.AddParagraph(); var imageNotesPar = section.AddParagraph();
@@ -719,8 +819,10 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
imageNotesPar.Format.Font.Bold = false; imageNotesPar.Format.Font.Bold = false;
imageNotesPar.Format.Font.Name = "Noto Sans JP"; imageNotesPar.Format.Font.Name = "Noto Sans JP";
imageNotesPar.AddText(file.Notes); imageNotesPar.AddText(file.Notes);
imageNotesPar.Tag = "ReceiptNotesPar";
} }
section.AddParagraph(); // add empty line for spacing var emptyPar = section.AddParagraph(); // add empty line for spacing
emptyPar.Tag = "EmptyParagraph";
// now add the image // now add the image
var lowerName = fileName.ToLower(); var lowerName = fileName.ToLower();
var isPDF = lowerName.EndsWith(".pdf"); var isPDF = lowerName.EndsWith(".pdf");
@@ -732,6 +834,14 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
var info = new FileInfo(file.FilePath); var info = new FileInfo(file.FilePath);
uint loadedImageWidth = 0; uint loadedImageWidth = 0;
uint loadedImageHeight = 0; uint loadedImageHeight = 0;
// get max pixel height remaining for items on this page
// (For multi-page PDFs, showing page 2 and on will have more height since they have no title,
// but to keep things consistent we will use the same height for all PDF pages.)
// render up to now on this page and get height remaining in inches
var currPageCount = pdfRenderer.DocumentRenderer.FormattedDocument?.PageCount;
var heightForExistingItemsOnPage = GetExistingPageItemHeight(pdfRenderer, footerParagraphHeight);
var remainingHeightInches = pageHeight - (2 * margin) - heightForExistingItemsOnPage;
var remainingHeightPixels = (remainingHeightInches * imageResolution) - imageInsertMarginPixels;
if (!isPDF) if (!isPDF)
{ {
using var mImage = new MagickImage(info.FullName); using var mImage = new MagickImage(info.FullName);
@@ -777,17 +887,23 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
var image = paragraph.AddImage(filePath); var image = paragraph.AddImage(filePath);
image.LockAspectRatio = true; image.Resolution = imageResolution; // dots per inch
if (!isPDF && loadedImageHeight > 600) image.Tag = "ReceiptImageTag";
paragraph.Tag = "ReceiptImageParagraphTag";
image.LineFormat = imageLineFormat.Clone();
// resize down until it will fit on the page
while (loadedImageHeight > remainingHeightPixels || loadedImageWidth > maxItemPxWidth)
{ {
image.Height = 550; // make sure it will fit on one page // Console.WriteLine("Image height = {0}, width = {1}; decreasing size by 5% to h={2}, w={3}", loadedImageHeight, loadedImageWidth, (uint)Math.Floor(loadedImageHeight * 0.95), (uint)Math.Floor(loadedImageWidth * 0.95));
// keep reducing size by 5% (little by little) until it fits on the page
// ...might skew ever so slightly but should not be noticable...
loadedImageHeight = (uint)Math.Floor(loadedImageHeight * 0.95);
loadedImageWidth = (uint)Math.Floor(loadedImageWidth * 0.95);
} }
else image.Height = loadedImageHeight;
{ image.Width = loadedImageWidth;
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins...
} }
} else // isPDF
else
{ {
// need to render PDF to images // need to render PDF to images
if (_settings.UseDocnetPDFImageRendering) if (_settings.UseDocnetPDFImageRendering)
@@ -826,9 +942,23 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
pgCount == 1 ? "" : "s")); pgCount == 1 ? "" : "s"));
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
// get image height/width off of disk so we can resize down if needed
var image = paragraph.AddImage(convertedPdfImagePath); var image = paragraph.AddImage(convertedPdfImagePath);
image.Width = imageWidth;
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.LineFormat = imageLineFormat.Clone();
using (var firstPdfPageImage = new MagickImage(convertedPdfImagePath))
{
var pdfPageImageWidth = firstPdfPageImage.Width;
var pdfPageImageHeight = firstPdfPageImage.Height;
// resize down until it will fit on the page
while (pdfPageImageHeight > remainingHeightPixels || pdfPageImageWidth > maxItemPxWidth)
{
pdfPageImageHeight = (uint)Math.Floor(pdfPageImageHeight * 0.95);
pdfPageImageWidth = (uint)Math.Floor(pdfPageImageWidth * 0.95);
}
image.Height = pdfPageImageHeight;
image.Width = pdfPageImageWidth;
}
for (var j = 1; j < pgCount; j++) for (var j = 1; j < pgCount; j++)
{ {
section.AddPageBreak(); section.AddPageBreak();
@@ -837,18 +967,37 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
convertedPdfImagePath = RenderPdfPageToImage(docReader, j); convertedPdfImagePath = RenderPdfPageToImage(docReader, j);
image = paragraph.AddImage(convertedPdfImagePath); image = paragraph.AddImage(convertedPdfImagePath);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; image.Width = maxImageWidth;
image.LineFormat = imageLineFormat.Clone();
using (var otherPdfPageImage = new MagickImage(convertedPdfImagePath))
{
var pdfPageImageWidth = otherPdfPageImage.Width;
var pdfPageImageHeight = otherPdfPageImage.Height;
// resize down until it will fit on the page
while (pdfPageImageHeight > remainingHeightPixels || pdfPageImageWidth > maxItemPxWidth)
{
pdfPageImageHeight = (uint)Math.Floor(pdfPageImageHeight * 0.95);
pdfPageImageWidth = (uint)Math.Floor(pdfPageImageWidth * 0.95);
}
image.Height = pdfPageImageHeight;
image.Width = pdfPageImageWidth;
}
} }
} }
} }
else else
{ {
// use older, not-docnet rendering method.
// uses MigraDoc rendering. Does not work with annotations, and since Migradoc
// doesn't let us know how big the image is, we can't do the image resizing, so
// we just do our best.
// render first page (eventually need to improve code to just do everything in a loop) // render first page (eventually need to improve code to just do everything in a loop)
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
var image = paragraph.AddImage(filePath); var image = paragraph.AddImage(filePath);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins... image.Width = maxImageWidth; // can't be too wide now...not sure why...maybe due to margins...
image.LineFormat = imageLineFormat.Clone();
// render other PDF pages, if any // render other PDF pages, if any
// see: https://stackoverflow.com/a/65091204/3938401 // see: https://stackoverflow.com/a/65091204/3938401
var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import); var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import);
@@ -863,20 +1012,18 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
image = paragraph.AddImage(filePath + "#" + j); image = paragraph.AddImage(filePath + "#" + j);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; image.Width = maxImageWidth;
image.LineFormat = imageLineFormat.Clone();
} }
} }
} }
LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath)); LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath));
hasAddedData = true; hasAddedData = true;
} }
var pdfRenderer = new PdfDocumentRenderer
{
Document = pdfDoc,
WorkingDirectory = folderPath
};
LogInfo("Rendering document to PDF file..."); LogInfo("Rendering document to PDF file...");
pdfRenderer.DocumentRenderer.PrepareDocument(); // needed if you make edits after first PrepareDocument() is called
pdfRenderer.RenderDocument(); pdfRenderer.RenderDocument();
// actually save to disk now
string outputPDFFilePath = Path.Join(outputDir, outputFileName); string outputPDFFilePath = Path.Join(outputDir, outputFileName);
LogInfo("Saving PDF document to disk..."); LogInfo("Saving PDF document to disk...");
pdfRenderer.PdfDocument.Save(outputPDFFilePath); pdfRenderer.PdfDocument.Save(outputPDFFilePath);
+2 -3
View File
@@ -4,8 +4,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace MayShow.ViewModels namespace MayShow.ViewModels;
{
class MainWindowViewModel : ChangeNotifier, IChangeViewModel class MainWindowViewModel : ChangeNotifier, IChangeViewModel
{ {
BaseViewModel _currentViewModel; BaseViewModel _currentViewModel;
@@ -47,4 +47,3 @@ namespace MayShow.ViewModels
#endregion #endregion
} }
}
+2 -3
View File
@@ -2,8 +2,8 @@
using MayShow.Helpers; using MayShow.Helpers;
using MayShow.Models; using MayShow.Models;
namespace MayShow.ViewModels namespace MayShow.ViewModels;
{
class WarningDeleteItemViewModel : ChangeNotifier class WarningDeleteItemViewModel : ChangeNotifier
{ {
ReportFile _file; ReportFile _file;
@@ -28,4 +28,3 @@ namespace MayShow.ViewModels
DialogHost.Close("DialogHost", true); DialogHost.Close("DialogHost", true);
} }
} }
}
+1 -1
View File
@@ -11,7 +11,7 @@
MaxWidth="450"> MaxWidth="450">
<StackPanel Orientation="Vertical" <StackPanel Orientation="Vertical"
Spacing="4"> Spacing="4">
<TextBlock Text="MayShow 1.4.0" <TextBlock Text="MayShow 1.4.1"
HorizontalAlignment="Center" HorizontalAlignment="Center"
TextWrapping="Wrap" TextWrapping="Wrap"
FontSize="18" FontSize="18"
+2 -3
View File
@@ -5,8 +5,8 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
namespace MayShow.Views namespace MayShow.Views;
{
public partial class AboutView : UserControl public partial class AboutView : UserControl
{ {
public AboutView() public AboutView()
@@ -36,4 +36,3 @@ namespace MayShow.Views
LicenseTextBlock.Text = licenseText.Trim(); LicenseTextBlock.Text = licenseText.Trim();
} }
} }
}
+2 -3
View File
@@ -3,8 +3,8 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
namespace MayShow.Views namespace MayShow.Views;
{
public partial class EditFile : UserControl public partial class EditFile : UserControl
{ {
public EditFile() public EditFile()
@@ -12,4 +12,3 @@ namespace MayShow.Views
this.InitializeComponent(); this.InitializeComponent();
} }
} }
}
+2 -3
View File
@@ -5,8 +5,8 @@ using Avalonia.Input;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using MayShow.ViewModels; using MayShow.ViewModels;
namespace MayShow.Views namespace MayShow.Views;
{
public partial class MainView : UserControl public partial class MainView : UserControl
{ {
public MainView() public MainView()
@@ -42,4 +42,3 @@ namespace MayShow.Views
} }
} }
} }
}
+2 -3
View File
@@ -3,8 +3,8 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
namespace MayShow.Views namespace MayShow.Views;
{
public partial class WarningDeleteItem : UserControl public partial class WarningDeleteItem : UserControl
{ {
public WarningDeleteItem() public WarningDeleteItem()
@@ -12,4 +12,3 @@ namespace MayShow.Views
this.InitializeComponent(); this.InitializeComponent();
} }
} }
}
+1 -1
View File
@@ -3,7 +3,7 @@
<!-- This manifest is used on Windows only. <!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls. Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests --> For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.4.0.0" name="MayShow.Desktop"/> <assemblyIdentity version="1.4.1.0" name="MayShow.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application> <application>