Ejemplo n.º 1
0
 public static CanvasSvgDocument GenerateSvgDocument(
     ICanvasResourceCreator device,
     double width,
     double height,
     SVGPathReciever path)
 {
     return(GenerateSvgDocument(device, width, height, new List <SVGPathReciever> {
         path
     }));
 }
Ejemplo n.º 2
0
        public static async Task ExportSvgAsync(
            ExportStyle style,
            InstalledFont selectedFont,
            FontVariant selectedVariant,
            Character selectedChar,
            CanvasTypography typography)
        {
            try
            {
                string name = GetFileName(selectedFont, selectedVariant, selectedChar, "svg");
                if (await PickFileAsync(name, "SVG", new[] { ".svg" }) is StorageFile file)
                {
                    CachedFileManager.DeferUpdates(file);
                    var device = Utils.CanvasDevice;

                    var textColor = style == ExportStyle.Black ? Colors.Black : Colors.White;

                    /* SVG Exports render at fixed size - but a) they're vectors, and b) they're
                     * inside an auto-scaling viewport. So rendersize is *largely* pointless */
                    float canvasH = 1024f, canvasW = 1024f, fontSize = 1024f;

                    using (CanvasTextLayout layout = new CanvasTextLayout(device, $"{selectedChar.Char}", new CanvasTextFormat
                    {
                        FontSize = fontSize,
                        FontFamily = selectedVariant.Source,
                        FontStretch = selectedVariant.FontFace.Stretch,
                        FontWeight = selectedVariant.FontFace.Weight,
                        FontStyle = selectedVariant.FontFace.Style,
                        HorizontalAlignment = CanvasHorizontalAlignment.Center
                    }, canvasW, canvasH))
                    {
                        layout.SetTypography(0, 1, typography);

                        using (CanvasGeometry temp = CanvasGeometry.CreateText(layout))
                        {
                            var    b     = temp.ComputeBounds();
                            double scale = Math.Min(1, Math.Min(canvasW / b.Width, canvasH / b.Height));

                            Matrix3x2 transform =
                                Matrix3x2.CreateTranslation(new Vector2((float)-b.Left, (float)-b.Top))
                                * Matrix3x2.CreateScale(new Vector2((float)scale));

                            using (CanvasGeometry geom = temp.Transform(transform))
                            {
                                /*
                                 * Unfortunately this only constructs a monochrome path, if we want color
                                 * Win2D does not yet expose the neccessary API's to get the individual glyph
                                 * layers that make up a colour glyph.
                                 *
                                 * We'll need to handle this in C++/CX if we want to do this at some point.
                                 */

                                SVGPathReciever rc = new SVGPathReciever();
                                geom.SendPathTo(rc);

                                Rect bounds = geom.ComputeBounds();
                                using (CanvasSvgDocument document = Utils.GenerateSvgDocument(device, bounds.Width, bounds.Height, rc))
                                {
                                    ((CanvasSvgNamedElement)document.Root.FirstChild).SetColorAttribute("fill", textColor);
                                    await Utils.WriteSvgAsync(document, file);
                                }
                            }
                        }
                    }

                    await CachedFileManager.CompleteUpdatesAsync(file);
                }
            }
            catch (Exception ex)
            {
                await SimpleIoc.Default.GetInstance <IDialogService>()
                .ShowMessageBox(ex.Message, Localization.Get("SaveImageError"));
            }
        }