public void GetContentTypeTest() { // // Setup FileAssocaitons service Settings settings = Settings.CreateDefaultSettings(); ModelLocator.Current.Settings.CopyPropertiesFrom(settings); // obviouslly text string path = "foo.txt"; string type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); // html path = "foo.html"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/html", type); path = "foo.htm"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/html", type); // Something handled by prismcte path = "foo.cs"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-csharp", type); // Defeault path = "foo.xxxx"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); }
public void NewContentTypeEngineTest() { SheetViewModel svm = new SheetViewModel(); (svm.ContentEngine, svm.ContentType, svm.Language) = ContentTypeEngineBase.CreateContentTypeEngine(CteClassName); Assert.NotNull(svm.ContentEngine); Assert.Equal(CteClassName, svm.ContentEngine.GetType().Name); Assert.Equal("text/plain", svm.ContentType); }
public void CreateContentTypeEngine_CteClassName() { foreach (var cte in ContentTypeEngineBase.GetDerivedClassesCollection()) { var CteClassName = cte.GetType().Name; SheetViewModel svm = new SheetViewModel(); (svm.ContentEngine, svm.ContentType, svm.Language) = ContentTypeEngineBase.CreateContentTypeEngine(CteClassName); Assert.NotNull(svm.ContentEngine); Assert.Equal(CteClassName, svm.ContentEngine.GetType().Name); Assert.Equal(cte.SupportedContentTypes[0], svm.ContentType); } }
public async void RenderAsyncTest_FixedPitch() { string shortLine = "This is a line 0123456789"; string longLine = "This is a line 01234567890"; Settings settings = Settings.CreateDefaultSettings(); ModelLocator.Current.Settings.CopyPropertiesFrom(settings); SheetViewModel svm = new SheetViewModel(); (svm.ContentEngine, svm.ContentType, svm.Language) = ContentTypeEngineBase.CreateContentTypeEngine(CteClassName); Assert.NotNull(svm.ContentEngine); Assert.Equal("text/plain", svm.ContentType); svm.ContentEngine.ContentSettings = new ContentSettings(); // Setup page so only 1 line will fit svm.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0); // Setup page so 10 chars can fit across using Bitmap bitmap = new Bitmap(1, 1); bitmap.SetResolution(96, 96); Graphics g = Graphics.FromImage(bitmap); g.PageUnit = GraphicsUnit.Display; // Display is 1/100th" g.TextRenderingHint = ContentTypeEngineBase.TextRenderingHint; // Set a font that's 1" high svm.ContentEngine.ContentSettings.Font = new Core.Models.Font() { Family = "Courier New", Size = 72 }; // 72 points is 1" high System.Drawing.Font font = new System.Drawing.Font(svm.ContentEngine.ContentSettings.Font.Family, svm.ContentEngine.ContentSettings.Font.Size / 72F * 96, svm.ContentEngine.ContentSettings.Font.Style, GraphicsUnit.Pixel); // determine width // Use page settings including lineNumberWidth SizeF proposedSize = new SizeF(10000, font.GetHeight() + (font.GetHeight() / 2)); SizeF size = g.MeasureString(shortLine, font, proposedSize, ContentTypeEngineBase.StringFormat, out int charsFitted, out int linesFilled); ((TextCte)svm.ContentEngine).ContentSettings.LineNumbers = false; svm.ContentEngine.PageSize = new System.Drawing.SizeF(size.Width, font.GetHeight()); // a line will be about 108 high Assert.True(await svm.ContentEngine.SetDocumentAsync(shortLine)); Assert.Equal(1, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); Assert.True(await svm.ContentEngine.SetDocumentAsync($"{shortLine}\n{shortLine}")); Assert.Equal(2, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); Assert.True(await svm.ContentEngine.SetDocumentAsync($"{shortLine}\n{shortLine}\n{shortLine}")); Assert.Equal(3, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); // Test line wrapping // 0123456789 // 0 Assert.True(await svm.ContentEngine.SetDocumentAsync($"{longLine}")); Assert.Equal(2, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); // 0123456789 // 0A Assert.True(await svm.ContentEngine.SetDocumentAsync($"{longLine}A")); Assert.Equal(2, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); // 0123456789 // 0A01234567 // 89 Assert.True(await svm.ContentEngine.SetDocumentAsync($"{longLine}A{longLine}")); Assert.Equal(3, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); }
/// <summary> /// See https://stackoverflow.com/questions/25823910/pscmdlet-dynamic-auto-complete-a-parameter-like-get-process /// </summary> /// <returns></returns> public object GetDynamicParameters() { // We can't report errors here if (WinPrint.Core.Models.ModelLocator.Current.Settings == null) { //System.Console.WriteLine($"Settings are not valid. Check {ServiceLocator.Current.SettingsService.SettingsFileName}."); return(null); } var runtimeDict = new RuntimeDefinedParameterDictionary(); // -PrinterName var printerNames = new List <string>(); using var pd = new PrintDocument(); if (!string.IsNullOrEmpty(PrinterName)) { PrinterName = PrinterName.Trim('\"').Trim('\''); pd.PrinterSettings.PrinterName = PrinterName; foreach (PaperSize size in pd.PrinterSettings.PaperSizes) { printerNames.Add(size.PaperName); } } runtimeDict.Add("PaperSize", new RuntimeDefinedParameter("PaperSize", typeof(string), new Collection <Attribute>() { new ParameterAttribute() { HelpMessage = "The paper size name. E.g. \"Letter\"", ParameterSetName = "Print" }, printerNames.Count > 0 ? new ValidateSetAttribute(printerNames.ToArray()) : null })); // -SheetDefinition // [Parameter(HelpMessage = "Name of the WinPrint sheet definition to use (e.g. \"Default 2-Up\")", // ParameterSetName = "Print")] runtimeDict.Add("SheetDefinition", new RuntimeDefinedParameter("SheetDefinition", typeof(string), new Collection <Attribute>() { new ParameterAttribute() { HelpMessage = "Name of the WinPrint sheet definition to use (e.g. \"Default 2-Up\").", ParameterSetName = "Print" }, ModelLocator.Current.Settings.Sheets.Count > 0 ? new ValidateSetAttribute(ModelLocator.Current.Settings.Sheets.Values.Select(s => s.Name).ToArray()) : null })); // -ContentTypeEngine runtimeDict.Add("ContentTypeEngine", new RuntimeDefinedParameter("ContentTypeEngine", typeof(string), new Collection <Attribute>() { new ParameterAttribute() { HelpMessage = "Optional name of the WinPrint Content Type Engine to use. If specified, automatic selection will be overridden. E.g. \"TextCte\".", ParameterSetName = "Print" }, new ValidateSetAttribute(ContentTypeEngineBase.GetDerivedClassesCollection().Select(cte => cte.GetType().Name).ToArray()) })); return(runtimeDict); }
// This method will be called once at the end of pipeline execution; if no input is received, this method is not called protected override async Task EndProcessingAsync() { await base.EndProcessingAsync().ConfigureAwait(true); Log.Debug("EndProcessingAsync"); if (Config) { Process proc = null; try { var psi = new ProcessStartInfo { UseShellExecute = true, // This is important FileName = ServiceLocator.Current.SettingsService.SettingsFileName }; proc = Process.Start(psi); } catch (Win32Exception e) { // TODO: Better error message (output of stderr?) ServiceLocator.Current.TelemetryService.TrackException(e, false); Log.Error(e, $"Couldn't open settings file {ServiceLocator.Current.SettingsService.SettingsFileName}."); } finally { proc?.Dispose(); } return; } if (WinPrint.Core.Models.ModelLocator.Current.Settings == null) { Log.Fatal(new Exception($"Settings are invalid. See {ServiceLocator.Current.LogService.LogPath} for more information."), ""); return; } SetupUpdateHandler(); // Check for new version if (_installUpdate) { await DoUpdateAsync().ConfigureAwait(true); CleanUpUpdateHandler(); return; } if (_psObjects.Count == 0) { Log.Debug("No objects..."); if (string.IsNullOrEmpty(FileName)) { //Return if no objects or file specified CleanUpUpdateHandler(); return; } } // Whenever we run, check for an update. We use the cancellation token to kill the thread that's doing this // if we exit before getting a version info result back. Checking for updates should never shlow cmd line down. Log.Debug("Kicking off update check thread..."); await Task.Run(() => ServiceLocator.Current.UpdateService.GetLatestVersionAsync(_getVersionCancellationToken.Token).ConfigureAwait(true), _getVersionCancellationToken.Token).ConfigureAwait(true); var rec = new ProgressRecord(1, "Printing", "Printing...") { PercentComplete = 0, StatusDescription = "Initializing winprint" }; WriteProgress(rec); Debug.Assert(_print != null); if (!string.IsNullOrEmpty(PrinterName)) { try { rec.PercentComplete = 10; rec.StatusDescription = $"Setting printer name to {PrinterName}"; WriteProgress(rec); _print.SetPrinter(PrinterName); } catch (InvalidPrinterException) { Log.Information("Installed printers:"); foreach (string printer in PrinterSettings.InstalledPrinters) { Log.Information(" {printer}", printer); } Log.Fatal(new Exception($"{PrinterName} is not a valid printer name. Valid printer names include " + $"{string.Join(", ", PrinterSettings.InstalledPrinters.ToDynamicList().ToArray())}."), ""); CleanUpUpdateHandler(); return; } } if (string.IsNullOrEmpty(Title)) { if (string.IsNullOrEmpty(FileName)) { Title = MyInvocation.MyCommand.Name; } else { Title = FileName; } } // Core requires a fully qualified path. If FileName was provided, ensure it's fully qualified. // Note, Title stays as was provided via -FileName or -Title if (!string.IsNullOrEmpty(FileName) && !Path.IsPathFullyQualified(FileName)) { FileName = Path.GetFullPath(FileName, SessionState.Path.CurrentFileSystemLocation.Path); } SheetSettings sheet = null; string sheetID = null; try { MyInvocation.BoundParameters.TryGetValue("SheetDefinition", out var sheetDefinition); sheet = _print.SheetViewModel.FindSheet((string)sheetDefinition, out sheetID); rec.PercentComplete = 20; rec.StatusDescription = $"Setting Sheet Settings for {sheet.Name}"; WriteProgress(rec); if (Orientation.HasValue) { sheet.Landscape = Orientation == PortraitLandscape.Landscape; } if (LineNumbers.HasValue) { sheet.ContentSettings.LineNumbers = LineNumbers == YesNo.Yes; } // Must set landscape after printer/paper selection _print.PrintDocument.DefaultPageSettings.Landscape = sheet.Landscape; _print.SheetViewModel.SetSheet(sheet); } catch (InvalidOperationException e) { Log.Fatal(new Exception($"Could not find sheet settings. {e.Message}. See {ServiceLocator.Current.LogService.LogPath} for more information."), ""); CleanUpUpdateHandler(); return; } // If Language is provided, use it instead of CTE. if (!MyInvocation.BoundParameters.TryGetValue("Language", out var contentType)) { if (!MyInvocation.BoundParameters.TryGetValue("ContentTypeEngine", out contentType)) { // If neither were specified, smartly pick CTE contentType = ContentTypeEngineBase.GetContentType(FileName); } } if (MyInvocation.BoundParameters.TryGetValue("PaperSize", out var paperSize)) { _print.SetPaperSize((string)paperSize); } rec.PercentComplete = 30; rec.StatusDescription = $"Loading content"; WriteProgress(rec); _print.SheetViewModel.File = FileName; _print.SheetViewModel.Title = Title; _print.PrintingSheet += (s, sheetNum) => { if (sheetNum > 60) { rec.PercentComplete = 95; } else { rec.PercentComplete = 40 + sheetNum; } rec.StatusDescription = $"Printing sheet {sheetNum}"; WriteProgress(rec); Log.Information("Printing sheet {sheetNum}", sheetNum); }; try { if (_psObjects.Count == 0 && !string.IsNullOrEmpty(FileName)) { if (!Path.IsPathFullyQualified(FileName)) { FileName = Path.GetFullPath(FileName, SessionState.Path.CurrentFileSystemLocation.Path); } await _print.SheetViewModel.LoadFileAsync(FileName, (string)contentType).ConfigureAwait(true); } else { // Get $input into a string we can use // See: https://stackoverflow.com/questions/60712580/invoking-cmdlet-from-a-c-based-pscmdlet-providing-input-and-capturing-output var textToPrint = SessionState.InvokeCommand.InvokeScript(@"$input | Out-String", true, PipelineResultTypes.None, _psObjects, null)[0].ToString(); _print.SheetViewModel.Encoding = Encoding.UTF8; await _print.SheetViewModel.LoadStringAsync(textToPrint, (string)contentType).ConfigureAwait(true); } if (_verbose) { Log.Information("FileName: {FileName}", FileName ?? ""); Log.Information("Title: {title}", Title ?? ""); Log.Information("Content Type: {contentType}", _print.SheetViewModel.ContentType); Log.Information("Language: {Language}", _print.SheetViewModel.Language); Log.Information("Content Type Engine: {cte}", _print.SheetViewModel.ContentEngine.GetType().Name); Log.Information("Printer: {printer}", _print.PrintDocument.PrinterSettings.PrinterName); Log.Information("Paper Size: {size}", _print.PrintDocument.DefaultPageSettings.PaperSize.PaperName); Log.Information("Orientation: {s}", _print.PrintDocument.DefaultPageSettings.Landscape ? $"Landscape" : $"Portrait"); Log.Information("Sheet Definition: {name} ({id})", sheet.Name, sheetID); } } catch (System.IO.DirectoryNotFoundException dnfe) { Log.Error(dnfe, "Print failed."); CleanUpUpdateHandler(); return; } catch (System.IO.FileNotFoundException fnfe) { Log.Error(fnfe, "Print failed."); CleanUpUpdateHandler(); return; } catch (InvalidOperationException ioe) { // TODO: Use our own execptions Log.Error(ioe, "Print failed."); CleanUpUpdateHandler(); return; } rec.PercentComplete = 40; rec.StatusDescription = WhatIf ? "Counting" : $"Printing"; WriteProgress(rec); var sheetsCounted = 0; try { var sheetRangeSet = false; if (FromSheet != 0) { _print.PrintDocument.PrinterSettings.FromPage = FromSheet; sheetRangeSet = true; } else { _print.PrintDocument.PrinterSettings.FromPage = 0; } if (ToSheet != 0) { _print.PrintDocument.PrinterSettings.ToPage = ToSheet; sheetRangeSet = true; } else { _print.PrintDocument.PrinterSettings.ToPage = 0; } if (sheetRangeSet) { Log.Information("Printing from sheet {from} to sheet {to}.", _print.PrintDocument.PrinterSettings.FromPage, _print.PrintDocument.PrinterSettings.ToPage); } if (WhatIf) { sheetsCounted = await _print.CountSheets().ConfigureAwait(true); } else { sheetsCounted = await _print.DoPrint().ConfigureAwait(true); } } catch (System.ComponentModel.Win32Exception w32e) { // This can happen when PDF driver can't access PDF file. Log.Error(w32e, "Print failed."); CleanUpUpdateHandler(); return; } // Finalize Progress rec.PercentComplete = -1; rec.StatusDescription = $"Complete"; WriteProgress(rec); // Output via verbose how much printing got done if (_verbose) { Log.Information($"{(WhatIf ? "Would have printed" : "Printed")} {{sheetsCounted}} sheets.", sheetsCounted); } // End by sharing update info, if any if (!string.IsNullOrEmpty(_updateMsg)) { Log.Information(_updateMsg); } CleanUpUpdateHandler(); // Very last thing we do is write to the output if WhatIf was specified if (WhatIf) { WriteObject(sheetsCounted, false); } }
public void GetContentTypeOrLanguageTest() { ServiceLocator.Current.SettingsService.SettingsFileName = $"WinPrint.{GetType().Name}.json"; File.Delete(ServiceLocator.Current.SettingsService.SettingsFileName); var settings = ServiceLocator.Current.SettingsService.ReadSettings(); ModelLocator.Current.Settings.CopyPropertiesFrom(settings); var ftm = ServiceLocator.Current.FileTypeMappingService.Load(); Assert.NotNull(ftm); var langs = ftm.ContentTypes; Assert.NotNull(langs); // For every cte, ensure every supported content type is valid foreach (var c in ContentTypeEngineBase.GetDerivedClassesCollection()) { foreach (var t in c.SupportedContentTypes) { Assert.Contains(langs, l => l.Id == t || l.Aliases.Contains(t)); } } // obviouslly text string path = "foo.txt"; string type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); path = "*.txt"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); path = "text"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); path = "text/plain"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); // html path = "foo.html"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/html", type); path = "foo.htm"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/html", type); // Something handled by prismcte path = "foo.cs"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-csharp", type); path = "*.cs"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-csharp", type); // Defeault path = "foo.json"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("application/json", type); // Default path = "foo.xxxx"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/plain", type); path = ".travis.yml"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-yaml", type); path = ".bashrc"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("application/x-sh", type); path = "Kconfig"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-kconfig", type); path = "kconfig"; type = ContentTypeEngineBase.GetContentType(path); Assert.Equal("text/x-kconfig", type); }
public void CreateContentTypeEngineTests() { // TODO: Mock this out ServiceLocator.Current.SettingsService.SettingsFileName = $"WinPrint.{GetType().Name}.json"; File.Delete(ServiceLocator.Current.SettingsService.SettingsFileName); var settings = ServiceLocator.Current.SettingsService.ReadSettings(); ModelLocator.Current.Settings.CopyPropertiesFrom(settings); // (ContentTypeEngineBase cte, string language) CreateContentTypeEngine(string contentType) ContentTypeEngineBase cte; string contentType, language; var input = "json"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(ContentTypeEngineBase.DefaultSyntaxHighlighterCteNameClassName, cte.GetType().Name); Assert.Equal("application/json", contentType); Assert.Equal("JSON", language); input = "csharp"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(ContentTypeEngineBase.DefaultSyntaxHighlighterCteNameClassName, cte.GetType().Name); Assert.Equal("text/x-csharp", contentType); Assert.Equal("C#", language); //contentType = "markup"; //(cte, language) = ContentTypeEngineBase.CreateContentTypeEngine(contentType); //Assert.NotNull(cte); //Assert.Equal(ContentTypeEngineBase.DefaultSyntaxHighlighterCteNameClassName, cte.GetType().Name); //Assert.Equal(contentType, language); input = "text"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(ContentTypeEngineBase.DefaultCteClassName, cte.GetType().Name); Assert.Equal("text/plain", contentType); Assert.Equal("Plain Text", language); input = "TextCte"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(TextCte).Name, cte.GetType().Name); Assert.Equal("text/plain", contentType); Assert.Equal("Plain Text", language); input = "ansi"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(AnsiCte).Name, cte.GetType().Name); Assert.Equal("text/ansi", contentType); Assert.Equal("ANSI Text", language); input = "AnsiCte"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(AnsiCte).Name, cte.GetType().Name); Assert.Equal("text/plain", contentType); Assert.Equal("Plain Text", language); input = "html"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(HtmlCte).Name, cte.GetType().Name); Assert.Equal("text/html", contentType); Assert.Equal("HTML", language); input = "HtmlCte"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(HtmlCte).Name, cte.GetType().Name); Assert.Equal("text/html", contentType); Assert.Equal("HTML", language); // text/plain should always use default input = "text/plain"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(ContentTypeEngineBase.DefaultCteClassName, cte.GetType().Name); Assert.Equal(input, contentType); Assert.Equal("Plain Text", language); input = "text/ansi"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(AnsiCte).Name, cte.GetType().Name); Assert.Equal(input, contentType); Assert.Equal("ANSI Text", language); input = "text/html"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(HtmlCte).Name, cte.GetType().Name); Assert.Equal(input, contentType); Assert.Equal("HTML", language); input = "text/x-smalltalk"; (cte, contentType, language) = ContentTypeEngineBase.CreateContentTypeEngine(input); Assert.NotNull(cte); Assert.Equal(typeof(AnsiCte).Name, cte.GetType().Name); Assert.Equal(input, contentType); Assert.Equal("Smalltalk", language); }
public async void RenderAsyncTest_LineWrap() { string text = "1"; string ansiText = "[38;2;0;0;207;01m1[39;00m"; Settings settings = Settings.CreateDefaultSettings(); ModelLocator.Current.Settings.CopyPropertiesFrom(settings); SheetViewModel svm = new SheetViewModel(); (svm.ContentEngine, svm.ContentType, svm.Language) = ContentTypeEngineBase.CreateContentTypeEngine(CteClassName); svm.ContentEngine.ContentSettings = new ContentSettings(); // Setup page so only 1 line will fit svm.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0); // Setup page so 10 chars can fit across using Bitmap bitmap = new Bitmap(1, 1); bitmap.SetResolution(96, 96); Graphics g = Graphics.FromImage(bitmap); g.PageUnit = GraphicsUnit.Display; // Display is 1/100th" g.TextRenderingHint = ContentTypeEngineBase.TextRenderingHint; // Set a font that's 1" high svm.ContentEngine.ContentSettings.Font = new Core.Models.Font() { Family = "Courier New", Size = 72 }; // 72 points is 1" high System.Drawing.Font font = new System.Drawing.Font(svm.ContentEngine.ContentSettings.Font.Family, svm.ContentEngine.ContentSettings.Font.Size / 72F * 96, svm.ContentEngine.ContentSettings.Font.Style, GraphicsUnit.Pixel); // determine width // Use page settings including lineNumberWidth SizeF proposedSize = new SizeF(10000, font.GetHeight() + (font.GetHeight() / 2)); SizeF size = g.MeasureString(text, font, proposedSize, ContentTypeEngineBase.StringFormat, out int charsFitted, out int linesFilled); ((AnsiCte)svm.ContentEngine).ContentSettings.LineNumbers = false; svm.ContentEngine.PageSize = new System.Drawing.SizeF(size.Width, font.GetHeight()); // a line will be about 108 high Assert.True(await svm.ContentEngine.SetDocumentAsync("")); Assert.Equal(1, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); Assert.True(await svm.ContentEngine.SetDocumentAsync(text)); Assert.Equal(1, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); Assert.True(await svm.ContentEngine.SetDocumentAsync(ansiText)); Assert.Equal(1, await svm.ContentEngine.RenderAsync(new System.Drawing.Printing.PrinterResolution() { X = 96, Y = 96 }, null)); }