Ejemplo n.º 1
0
        private void Parse_MouseDown(object sender, MouseButtonEventArgs e)
        {
            canvasString = InputTextBox.Text;
            canvasString = canvasString.Replace(" ", "");
            if (canvasString == "")
            {
                imageCanvas.Source = null;
                return;
            }

            if (ParseFormula())
            {
                imageCanvas.Source = null;
                return;
            }
            TexFormula formula = Parse_Formula(canvasString);

            if (formula == null)
            {
                return;
            }
            TexRenderer renderer = formula.GetRenderer(TexStyle.Display, 20.0, "Arial");

            savePng            = renderer.RenderToBitmap(0.0, 0.0);
            imageCanvas.Source = savePng;
        }
Ejemplo n.º 2
0
        private void Render()
        {
            // Create formula object from input text.
            if (texFormula == null)
            {
                formulaContainerElement.Visual = null;
                return;
            }

            // Render formula to visual.
            var visual   = new DrawingVisual();
            var renderer = texFormula.GetRenderer(TexStyle.Display, Scale);

            using (var drawingContext = visual.RenderOpen())
            {
                renderer.Render(drawingContext, 0, 0);
            }
            formulaContainerElement.Visual = visual;
        }
Ejemplo n.º 3
0
        protected override void Write([NotNull] WpfRenderer renderer, [NotNull] MathInline obj)
        {
            var text = obj.Content.Text.Substring(obj.Content.Start, obj.Content.Length);

            TexFormula formula = null;

            try
            {
                formula = formulaParser.Parse(text);
            }
            catch (Exception)
            {
                renderer.WriteInline(new Run("[!!FORMULA PARSE ERROR!!]")
                {
                    Tag = obj
                });
                return;
            }

            var fontSize        = renderer.CurrentFontSize();
            var formulaRenderer = formula.GetRenderer(TexStyle.Display, fontSize, "Arial");
            var geo             = formulaRenderer.RenderToGeometry(0, 0);
            var geoD            = new System.Windows.Media.GeometryDrawing(Brushes.Black, null, geo);
            var di      = new DrawingImage(geoD);
            var uiImage = new System.Windows.Controls.Image()
            {
                Source = di
            };

            uiImage.Height = formulaRenderer.RenderSize.Height;                                                                         // size image to match rendersize -> get a zoom of 100%
            uiImage.Margin = new System.Windows.Thickness(0, 0, 0, -formulaRenderer.RenderSize.Height * formulaRenderer.RelativeDepth); // Move image so that baseline matches that of text
            var uiInline = new System.Windows.Documents.InlineUIContainer()
            {
                Child             = uiImage,
                Background        = Brushes.Yellow,
                BaselineAlignment = System.Windows.BaselineAlignment.Baseline,
                Tag = obj,
            };

            renderer.WriteInline(uiInline);
        }
Ejemplo n.º 4
0
        public void SaveGeometry(string filename)
        {
            TexFormulaParser formulaParser = new TexFormulaParser();

            if (filename == null)
            {
                return;
            }

            // Create formula object from input text.
            TexFormula formula = null;

            try
            {
                formula = formulaParser.Parse(Formula);
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred while parsing the given input:" + Environment.NewLine +
                                Environment.NewLine + ex.Message, "WPF-Math Example", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            // Create formula object from input text.

            if (formula == null)
            {
                return;
            }
            var renderer = formula.GetRenderer(TexStyle.Display, Scale, SystemTextFontName);

            using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                var geometry = renderer.RenderToGeometry(0, 0);

                var svgPathText = ConvertGeometry(geometry);
                var svgText     = AddSVGHeader(svgPathText);
                using (var writer = new StreamWriter(fs))
                    writer.WriteLine(svgText);
            }
        }
        /// <inheritdoc/>
        public (Stream bitmapStream, string placement, int yoffset, int width96thInch, int height96thInch) Parse(string text, string fontFamily, double fontSize, double dpiResolution, bool isIntendedForHelp1File)
        {
            TexFormula formula = null;

            try
            {
                formula = _formulaParser.Parse(text);
            }
            catch (Exception)
            {
                return(null, null, 0, 0, 0);
            }

            double cyAscent;
            double cyDescent;
            double cyMiddle;
            {
                var gdiFont      = new System.Drawing.Font(fontFamily, (float)fontSize, System.Drawing.FontStyle.Regular);
                int iCellSpace   = gdiFont.FontFamily.GetLineSpacing(gdiFont.Style);
                int iEmHeight    = gdiFont.FontFamily.GetEmHeight(gdiFont.Style);
                int iCellAscent  = gdiFont.FontFamily.GetCellAscent(gdiFont.Style);
                int iCellDescent = gdiFont.FontFamily.GetCellDescent(gdiFont.Style);
                cyAscent  = fontSize * iCellAscent / iEmHeight;
                cyDescent = fontSize * iCellDescent / iEmHeight;
                cyMiddle  = cyAscent / 3; // is only a first guess, details coming from the Wpf font
                gdiFont.Dispose();
                var ff = new FontFamily(fontFamily);
                var tf = new Typeface(ff, System.Windows.FontStyles.Normal, System.Windows.FontWeights.Normal, System.Windows.FontStretches.Normal);
                if (tf.TryGetGlyphTypeface(out var gtf))
                {
                    cyMiddle = Math.Floor(fontSize * gtf.Height * gtf.StrikethroughPosition);
                }
            }

            var formulaRenderer = formula.GetRenderer(TexStyle.Display, fontSize, fontFamily);
            // the placement of the image depends on the depth value
            var absoluteDepth  = formulaRenderer.RenderSize.Height * formulaRenderer.RelativeDepth;
            var absoluteAscent = formulaRenderer.RenderSize.Height * (1 - formulaRenderer.RelativeDepth);

            double yoffset = 0;

            BitmapSource bmp;
            int          width96thInch, height96thInch;
            string       alignment;


            if (isIntendedForHelp1File)
            {
                // dictionary that holds the number of additional pixels neccessary to exactly align the formula, and the value is the alignment
                var sort = new SortedDictionary <double, (double, string)>();

                if (formulaRenderer.RelativeDepth < (1 / 16.0)) // if the formulas baseline is almost at the bottom of the image
                {
                    sort.Add(0, (0.0, "baseline"));             // then we can use baseline as vertical alight
                }
                if (absoluteAscent <= cyAscent)                 // if our formula is higher than the top of the text
                {
                    yoffset = cyAscent - absoluteAscent;
                    sort.Add(Math.Abs(yoffset), (yoffset, "texttop")); // then we can use texttop alignment, and we shift the formula downwards (positive offset)
                }
                if (absoluteDepth <= cyDescent)                        // then we can use bottom alignment, and we shift the formula upwards (negative offset)
                {
                    yoffset = absoluteDepth - cyDescent;
                    sort.Add(Math.Abs(yoffset), (yoffset, "bottom"));
                }

                {
                    // Alignment: middle
                    // Note that this is a moving target: we must change the vertical size of the image, but by that
                    // we change the middle of the image, which changes again the offset...
                    if (isIntendedForHelp1File)
                    {
                        yoffset = absoluteDepth - absoluteAscent; // in help1 file, the baseline of text is aligned with the middle of the image
                    }
                    else
                    {
                        yoffset = 2 * cyMiddle + absoluteDepth - absoluteAscent; // if yoffset is negative, then pad at the bottom, else pad at the top
                    }
                    sort.Add(Math.Abs(yoffset), (yoffset, "middle"));
                }

                var firstEntry = sort.First();
                (bmp, width96thInch, height96thInch) = RenderToBitmap(formulaRenderer, 0, firstEntry.Value.Item1, dpiResolution);
                alignment = firstEntry.Value.Item2;
                yoffset   = 0; // 0 as return value
            }
            else // MAML is intended for HTML help (so we can use HTML5 alignment with pixel accuracy        )
            {
                alignment = "baseline";
                var yshift = Math.Ceiling(absoluteAscent) - absoluteAscent; // we shift the formula downwards, so that the new absoluteAscent is Math.Ceiling(absoluteAscent)
                // by providing a positive offset in arg2, the image is lowered compared to the baseline
                (bmp, width96thInch, height96thInch) = RenderToBitmap(formulaRenderer, 0, yshift, dpiResolution);
                yoffset = Math.Ceiling(absoluteAscent) - height96thInch; // number of pixels from image bottom to baseline (negative sign)
            }

            var           fileStream = new MemoryStream();
            BitmapEncoder encoder    = new PngBitmapEncoder();

            encoder.Frames.Add(BitmapFrame.Create(bmp));
            encoder.Save(fileStream);
            fileStream.Seek(0, SeekOrigin.Begin);

            return(fileStream, alignment, (int)Math.Round(yoffset), width96thInch, height96thInch);
        }
Ejemplo n.º 6
0
        protected override void Write([NotNull] WpfRenderer renderer, [NotNull] MathBlock obj)
        {
            string text = string.Empty; // obj.Content.Text.Substring(obj.Content.Start, obj.Content.Length);

            for (int i = 0; i < obj.Lines.Count; ++i)
            {
                var l = obj.Lines.Lines[i];
                text += l.Slice.Text.Substring(l.Slice.Start, l.Slice.Length);
            }

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            TexFormula formula = null;

            try
            {
                formula = formulaParser.Parse(text);
            }
            catch (Exception)
            {
                var paragraph = new Paragraph()
                {
                    Tag = obj
                };
                renderer.Push(paragraph);
                renderer.WriteInline(new Run("[!!FORMULA PARSE ERROR!!]")
                {
                    Tag = obj
                });
                renderer.Pop();
                return;
            }

            var fontSize = renderer.CurrentFontSize();

            if (fontSize <= 0)
            {
                throw new InvalidProgramException();
            }

            var formulaRenderer = formula.GetRenderer(TexStyle.Display, fontSize, "Arial");
            var geo             = formulaRenderer.RenderToGeometry(0, 0);
            var geoD            = new System.Windows.Media.GeometryDrawing(Brushes.Black, null, geo);
            var di      = new DrawingImage(geoD);
            var uiImage = new System.Windows.Controls.Image()
            {
                Source = di
            };

            uiImage.Height = formulaRenderer.RenderSize.Height; // size image to match rendersize -> get a zoom of 100%
            // uiImage.Margin = new System.Windows.Thickness(0, 0, 0, -formulaRenderer.RenderSize.Height * formulaRenderer.RelativeDepth); // Move image so that baseline matches that of text
            var uiBlock = new System.Windows.Documents.BlockUIContainer()
            {
                Child = uiImage,
                Tag   = obj,
            };

            renderer.WriteBlock(uiBlock);
        }
Ejemplo n.º 7
0
        private static Table genFormulaeTable(List <Formula> formulae, MainDocumentPart mainPart)
        {
            Table tableOfInputs = new Table();
            var   tableGrid     = new TableGrid();

            tableGrid.AppendChild(new GridColumn());
            tableGrid.AppendChild(new GridColumn());
            tableGrid.AppendChild(new GridColumn());
            tableOfInputs.AppendChild(tableGrid);
            var tableProps = new TableProperties();

            tableProps.AppendChild(new TableLayout()
            {
                Type = TableLayoutValues.Fixed
            });
            tableProps.AppendChild(new TableWidth()
            {
                Width = "9000", Type = TableWidthUnitValues.Dxa
            });
            tableProps.AppendChild(new TableBorders()
            {
                InsideHorizontalBorder = new InsideHorizontalBorder()
                {
                    Color = "c0c0c0", Size = 4, Val = BorderValues.Single
                }
            });
            tableProps.AppendChild(new TableBorders()
            {
                BottomBorder = new BottomBorder()
                {
                    Color = "c0c0c0", Size = 4, Val = BorderValues.Single
                }
            });
            tableProps.AppendChild(new TableBorders()
            {
                TopBorder = new TopBorder()
                {
                    Color = "c0c0c0", Size = 4, Val = BorderValues.Single
                }
            });
            //tableProps.AppendChild(new TableBorders() { LeftBorder = new LeftBorder() { Color = "c0c0c0", Size = 4, Val = BorderValues.Single } });
            //tableProps.AppendChild(new TableBorders() { InsideVerticalBorder = new InsideVerticalBorder() { Color = "c0c0c0", Size = 4, Val = BorderValues.Single } });
            //tableProps.AppendChild(new TableBorders() { RightBorder = new RightBorder() { Color = "c0c0c0", Size = 4, Val = BorderValues.Single } });
            tableOfInputs.AppendChild(tableProps);

            foreach (var item in formulae)
            {
                TableRow row  = new TableRow();
                var      para = new Paragraph();
                para.AppendChild((new Run(new Text(item.Ref))));
                TableCell cell1 = new TableCell();
                cell1.Append(para);
                cell1.Append(new TableCellProperties(new TableCellWidth()
                {
                    Type = TableWidthUnitValues.Dxa, Width = "1200"
                }));
                TableCell cell2 = new TableCell();
                cell2.Append(new TableCellProperties(new TableCellWidth()
                {
                    Type = TableWidthUnitValues.Dxa, Width = "6100"
                }));
                cell2.AppendChild(new Paragraph(new Run(new Text(item.Narrative))));
                //foreach (var formula in item.Expression)
                //{
                //    var mathPara = new Paragraph();
                //    var myMath = new M.OfficeMath(new M.Run(new M.Text(formula + Environment.NewLine) { Space = SpaceProcessingModeValues.Preserve }));
                //    mathPara.AppendChild(myMath);
                //    mathPara.AppendChild(new Run(new Text(" ") { Space = SpaceProcessingModeValues.Preserve }));
                //    cell2.AppendChild(mathPara);
                //}
                foreach (var formula in item.Expression)
                {
                    if (formula != "")
                    {
                        TexFormula formulaToParse = new TexFormula();
                        try
                        {
                            var parser = new TexFormulaParser();
                            formulaToParse = parser.Parse(formula);
                        }
                        catch (Exception)
                        {
                            var parser = new TexFormulaParser();
                            formulaToParse = parser.Parse("Error in LaTeX string...");
                        }
                        var test = formulaToParse.GetRenderer(TexStyle.Script, 100, "Franklin Gothic Book");
                        if (test.RenderSize.Width > 0 && test.RenderSize.Height > 0)
                        {
                            var       formulaImage = formulaToParse.RenderToPng(100, 0, 0, "Franklin Gothic Book");
                            ImagePart imagePart    = mainPart.AddImagePart(ImagePartType.Png);
                            using (var stream = new MemoryStream(formulaImage))
                            {
                                imagePart.FeedData(stream);
                                var img = new BitmapImage();
                                img.BeginInit();
                                img.StreamSource = stream;
                                img.CacheOption  = BitmapCacheOption.OnLoad;
                                img.EndInit();
                                img.Freeze();
                                var paraImage = AddImageToBody(mainPart.GetIdOfPart(imagePart), img.Width * 2.54 / 600, img.Height * 2.54 / 600);
                                cell2.AppendChild(new Paragraph(new Run(paraImage)));
                            }
                        }

                        GC.WaitForPendingFinalizers();
                    }
                    //var myMath = new M.OfficeMath(new M.Run(new M.Text(formula + Environment.NewLine) { Space = SpaceProcessingModeValues.Preserve }));
                    //mathPara.AppendChild(myMath);
                    //mathPara.AppendChild(new Run(new Text(" ") { Space = SpaceProcessingModeValues.Preserve }));
                    //cell2.AppendChild(mathPara);
                }

                if (item.Image != null)
                {
                    ImagePart        imagePart = mainPart.AddImagePart(ImagePartType.Png);
                    var              tempFile  = Path.GetTempFileName();
                    PngBitmapEncoder png       = new PngBitmapEncoder();
                    //CHANGEBITMAP
                    //png.Frames.Add(BitmapFrame.Create(item.Image));
                    var width  = Math.Min(10d, item.Image.Width * 2.54 / 96);
                    var height = ((double)item.Image.Height / (double)item.Image.Width) * width;
                    using (SkiaSharp.SKWStream stm = new SkiaSharp.SKFileWStream(tempFile))
                    {
                        item.Image.Encode(stm, SkiaSharp.SKEncodedImageFormat.Png, 0);
                    }
                    using (FileStream stream = new FileStream(tempFile, FileMode.Open))
                    {
                        imagePart.FeedData(stream);
                    }
                    var paraImage = AddImageToBody(mainPart.GetIdOfPart(imagePart), width, height);
                    cell2.AppendChild(new Paragraph(new Run(paraImage)));
                }

                TableCell cell3 = new TableCell();
                cell3.Append(new Paragraph(new Run(new Text(item.Conclusion))));
                cell3.Append(new TableCellProperties(new TableCellWidth()
                {
                    Type = TableWidthUnitValues.Dxa, Width = "1700"
                }));

                row.Append(cell1, cell2, cell3);
                tableOfInputs.AppendChild(row);
            }
            return(tableOfInputs);
        }