title: Printing from Mapsui/SkiaSharp
body: <p>I'm new at using Mapsui/SkiaSharp so forgive me if this is obvious.</p>
  
  <p>I'm trying to print! A map is rendered to an image using <a href="http://mapsui.com/" rel="nofollow noreferrer">Mapsui</a> using the "Render" method below (calls <a href="https://github.com/Mapsui/Mapsui/blob/master/Mapsui.Rendering.Skia/MapRenderer.cs" rel="nofollow noreferrer">Mapsui.Rendering.Skia.MapRenderer</a>) which takes a map, the world extents in Spherical Mercator, and the size of the image (or window). This works fine for screen resolutions.</p>
  
  <p>When I print, because the DPI is higher for the printer, the on-map text is tiny and unreadable. </p>
  
  <p>It may be my inexperience, but I know Skia is accomplished at cross platform rendering for device independence. Mapsui also has a <a href="http://mapsui.com/documentation/skia-scale.html" rel="nofollow noreferrer">specific section in the documentation</a> about scaling but it references using <a href="https://docs.microsoft.com/en-us/dotnet/api/skiasharp.views.forms.skcanvasview.ignorepixelscaling?view=skiasharp-views-forms-1.68.0" rel="nofollow noreferrer">SKCanvasView.IgnorePixelScaling</a> which I don't have access to via the MapRenderer which only acts on a SKCanvas.</p>
  
  <p>Is there something I am missing about rendering for printing?</p>
  
  <p>Is there a printing specific rendering context or pipeline I can use that automatically scales the fonts appropriately, rather than writing the bitmap to the GDI Graphics context? </p>
  
  <p>(code below is the OnPrintPage override from PrintDocument).</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// Do the printing
      /// &lt;/summary&gt;
      /// &lt;param name="e"&gt;&lt;/param&gt;
      protected override void OnPrintPage(PrintPageEventArgs e)
      { 
          try
          {
              // divide by 100 because e.PageBounds is inches times 100
              Size size = new Size(
                  e.PageBounds.Width * (int)(e.Graphics.DpiX / 100.0f),
                  e.PageBounds.Height * (int)(e.Graphics.DpiY / 100.0f));
  
              // draw the bitmap to the graphics context
              using (var image = Renderer.Render(Map, Extents, size))
                  e.Graphics.DrawImage(image, 0, 0, e.PageBounds.Width, e.PageBounds.Height);
  
          }
          catch (Exception ex)
          {
              Trace.TraceError("MapReportPrintDocument.OnPrintPage: Error printing document\r\n{0}", ex);
          }
      }
  </code></pre>
  
  <hr>
  
  <p>Edited to add more details;
  One method of inquiry that's given me some results is the following: rendering to an XpsDocument creates a context where I can let the document context know the DPI, and it automatically adjusts the scaling of the fonts for me. This is not ideal as now I need to manipulate the XPS file to get it printed and there's some wrinkles with that.</p>
  
  <pre><code>    public string RenderToXps(IMap map, Extents extents, SizeF size, float dpi = 72)
      {
          var resolution = Mapsui.Utilities.ZoomHelper.DetermineResolution(extents.Width, extents.Height, size.Width, size.Height);
          var viewport = new Mapsui.Viewport()
          {
              Center = extents.Center.ToMapsui(),
              Resolution = resolution,
              Width = size.Width,
              Height = size.Height
          };
  
          var msMap = map.GetMapsuiMap();
  
          var path = Path.GetTempFileName();
          using (var stream = new SkiaSharp.SKFileWStream(path))
          {
              using (var document = SkiaSharp.SKDocument.CreateXps(stream, dpi))
              {
  
                  var canvas = document.BeginPage(size.Width, size.Height);
                  Renderer.Render(canvas, viewport, msMap.Layers, msMap.Widgets);
                  document.EndPage();
              }
          }
  
          return path;
      }
  </code></pre>