예제 #1
0
        Box CreateTestBox1(string text = null, float fontSize = 20)
        {
            HorizontalStackBox hbox = new HorizontalStackBox();

            //hbox.SetBounds(20, 20, 100, 21);
            //
            if (text != null)
            {
                LoadFont();
                int    length             = text.Length;
                char[] ch                 = text.ToCharArray();
                float  font_size_in_Point = fontSize;

                _glyphMeshStore.SetFont(_latinModernMathFont, font_size_in_Point);//20= font size
                _glyphMeshStore.FlipGlyphUpward = true;
                float px_scale = _latinModernMathFont.CalculateScaleToPixelFromPointSize(font_size_in_Point);

                for (int i = 0; i < length; ++i)
                {
                    ushort glyphIndex = _latinModernMathFont.GetGlyphIndex((int)ch[i]);
                    ushort advW       = _latinModernMathFont.GetAdvanceWidthFromGlyphIndex(glyphIndex);//unscale glyph width
                    var    t          = _latinModernMathFont.GetGlyph(glyphIndex);
                    //now scale it to specific font size

                    int advW_s = (int)System.Math.Round(px_scale * advW);


                    GlyphBox b1 = NewGlyphBox();

                    b1.Character         = ch[i];
                    b1.GlyphIndex        = glyphIndex;
                    b1.AdvanceWidthScale = advW_s;
                    //b1.SetBounds(0, 0, 10, fontSize*2);

                    if (b1 is VxsGlyphBox vxsGlyphBox)
                    {
                        vxsGlyphBox.GlyphVxs = _glyphMeshStore.GetGlyphMesh(glyphIndex);
                    }


                    hbox.AddChild(b1);
                }//*/
            }
            else
            {
                for (int i = 0; i < 5; ++i)
                {
                    GlyphBox b1 = NewGlyphBox();
                    b1.SetBounds(0, 0, 10, 20);
                    hbox.AddChild(b1);
                }
            }

            hbox.Layout();
            return(hbox);
        }
예제 #2
0
        Box CreateTestBox4()
        {
            VerticalStackBox vbox1 = new VerticalStackBox();

            vbox1.AddChild(CreateTestBox3());
            vbox1.AddChild(CreateTestBox3());
            vbox1.Layout();


            GlyphBox h_sepBar = NewGlyphBox();

            h_sepBar.SetSize(vbox1.Width, 5);
            vbox1.Insert(1, h_sepBar);
            vbox1.Layout();
            return(vbox1);
        }
예제 #3
0
 protected override void SetGlyphVxs(GlyphBox glyphBox, Typeface typeface, float sizeInPoint)
 {
     if (glyphBox is VxsGlyphBox vxsGlyphBox)
     {
         _glyphMeshStore.SetFont(typeface, sizeInPoint);//20= font size
         _glyphMeshStore.FlipGlyphUpward = true;
         if (glyphBox.IsItalic)
         {
             _glyphMeshStore.SimulateOblique = glyphBox.IsItalic;
         }
         vxsGlyphBox.GlyphVxs = _glyphMeshStore.GetGlyphMesh(glyphBox.GlyphIndex);
         if (_glyphMeshStore.SimulateOblique)
         {
             _glyphMeshStore.SimulateOblique = false;
         }
     }
 }
예제 #4
0
        void AssignGlyphVxs(GlyphBox glyphBox, float fontSize = 20)
        {
            LoadFont();
            float font_size_in_Point = fontSize;
            char  ch = glyphBox.Character;

            _glyphMeshStore.SetFont(_latinModernMathFont, font_size_in_Point);//20= font size
            _glyphMeshStore.FlipGlyphUpward = true;
            float px_scale = _latinModernMathFont.CalculateScaleToPixelFromPointSize(font_size_in_Point);

            ushort glyphIndex = _latinModernMathFont.GetGlyphIndex((int)ch);
            ushort advW       = _latinModernMathFont.GetAdvanceWidthFromGlyphIndex(glyphIndex);//unscale glyph width
            //now scale it to specific font size

            int advW_s = (int)System.Math.Round(px_scale * advW);

            glyphBox.GlyphIndex        = glyphIndex;
            glyphBox.AdvanceWidthScale = advW_s;

            if (glyphBox is VxsGlyphBox vxsGlyphBox)
            {
                vxsGlyphBox.GlyphVxs = _glyphMeshStore.GetGlyphMesh(glyphIndex);
            }
        }
예제 #5
0
        Box CreateTestBox5()
        {
            HorizontalStackBox hbox = new HorizontalStackBox();

            hbox.SetLocation(50, 50);
            hbox.AddChild(CreateTestBox4());
            hbox.AddChild(CreateTestBox4_1());
            hbox.Layout();

            float height = hbox.Height;//set height to cover all blog

            GlyphBox openBar = NewGlyphBox();

            openBar.SetSize(5, height);
            hbox.Insert(0, openBar);

            GlyphBox verticalBar2 = NewGlyphBox();

            verticalBar2.SetSize(5, height);
            hbox.AddChild(verticalBar2);//add last
            hbox.Layout();

            return(hbox);
        }
예제 #6
0
        protected override void CreateCustomNotation(EncloseNotation notation,
                                                     float thickness, float w, float h,
                                                     HorizontalStackBox hbox, float maxLeft, float maxTop, float extend, float over,
                                                     EncloseBox encloseBox)
        {
            //notations that only custom lines

            using (Tools.BorrowVxs(out VertexStore vsx1, out VertexStore vsx2))
                using (Tools.BorrowStroke(out Stroke stroke))
                    using (Tools.BorrowPathWriter(vsx1, out PathWriter pathWriter))
                    {
                        var customVsxBox = new MyCustomNotationVsxBox();
                        stroke.LineJoin = LineJoin.Bevel;
                        stroke.Width    = thickness;
                        int useVxs = 1;//default = vxs1
                        switch (notation)
                        {
                        default:
                            useVxs = 0;//not match only lines notation
                            break;

                        case EncloseNotation.actuarial:
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(w, 0);
                            pathWriter.LineTo(w, h);
                            break;

                        case EncloseNotation.box:
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(0, h);
                            pathWriter.LineTo(w, h);
                            pathWriter.LineTo(w, 0);
                            pathWriter.LineTo(0, 0);
                            break;

                        case EncloseNotation.left:
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(0, h);
                            break;

                        case EncloseNotation.right:
                            pathWriter.MoveTo(w, 0);
                            pathWriter.LineTo(w, h);
                            break;

                        case EncloseNotation.top:
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(w, 0);
                            break;

                        case EncloseNotation.bottom:
                            pathWriter.MoveTo(0, h);
                            pathWriter.LineTo(w, h);
                            break;

                        case EncloseNotation.updiagonalstrike:
                            pathWriter.MoveTo(0, h);
                            pathWriter.LineTo(w, 0);
                            break;

                        case EncloseNotation.downdiagonalstrike:
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(w, h);
                            break;

                        case EncloseNotation.verticalstrike:
                            pathWriter.MoveTo(w / 2f, 0);
                            pathWriter.LineTo(w / 2f, h);
                            break;

                        case EncloseNotation.horizontalstrike:
                            pathWriter.MoveTo(0, h / 2f);
                            pathWriter.LineTo(w, h / 2f);
                            break;

                        case EncloseNotation.madruwb:
                            pathWriter.MoveTo(w, 0);
                            pathWriter.LineTo(w, h);
                            pathWriter.LineTo(0, h);
                            break;

                        case EncloseNotation.updiagonalarrow:
                            double arrowAngleDegree = Math.Atan(h / w) * 180.0 / Math.PI;
                            double arrowLength      = Math.Sqrt(Math.Pow(h, 2) + Math.Pow(w, 2));//pythagoras

                            float arrowWing = GetPixelScale() * 150;
                            pathWriter.MoveTo(0, 0);
                            pathWriter.LineTo(arrowLength, 0);
                            pathWriter.LineTo(arrowLength - arrowWing, -arrowWing);
                            pathWriter.LineTo(arrowLength - arrowWing, arrowWing);
                            pathWriter.LineTo(arrowLength, 0);

                            AffineMat mat = AffineMat.Iden();
                            mat.RotateDeg(-arrowAngleDegree);
                            mat.Translate(0, h);
                            mat.TransformToVxs(vsx1, vsx2);

                            useVxs = 2;
                            break;

                        case EncloseNotation.phasorangle:
                            float angleWidth  = 640 * GetPixelScale();  //x 637.5
                            float angleHeight = 1160 * GetPixelScale(); //y 1162.5
                            float shiftH      = h - angleHeight;
                            pathWriter.MoveTo(angleWidth, shiftH);
                            pathWriter.LineTo(0, angleHeight + shiftH);
                            pathWriter.LineTo(maxLeft - angleWidth + w, angleHeight + shiftH);

                            customVsxBox.BeforeBaseBox = angleWidth;
                            break;

                        case EncloseNotation.longdiv:
                            GlyphBox ldiv = NewGlyphBox();
                            ldiv.Character = ')';
                            AssignGlyphVxs(ldiv);
                            ldiv.Layout();

                            Box actualDiv = StretchHeightIfStretchable(ldiv, hbox.Height + over);
                            actualDiv.Layout();
                            customVsxBox.NotationBox = actualDiv;
                            float shiftLeft = maxLeft - actualDiv.Width;
                            float shiftTop  = maxTop - over;
                            actualDiv.SetLocation(shiftLeft, -shiftTop - over);
                            pathWriter.MoveTo(shiftLeft, shiftTop);
                            pathWriter.LineTo(shiftLeft + hbox.Width + actualDiv.Width + extend, shiftTop);
                            pathWriter.Stop();

                            customVsxBox.BeforeBaseBox = actualDiv.Width + extend;
                            break;

                        case EncloseNotation.radical:
                            GlyphBox radical = NewGlyphBox();
                            radical.Character = (char)0x221A;
                            AssignGlyphVxs(radical);
                            radical.Layout();

                            Box actualRadical = StretchHeightIfStretchable(radical, hbox.Height + over);
                            actualRadical.Layout();
                            float shiftLeft1 = maxLeft - actualRadical.Width;
                            float shiftTop1  = maxTop - over;
                            actualRadical.SetLocation(shiftLeft1, -shiftTop1 - over);
                            customVsxBox.NotationBox = actualRadical;

                            pathWriter.MoveTo(shiftLeft1 + actualRadical.Width, shiftTop1);
                            pathWriter.LineTo(shiftLeft1 + actualRadical.Width + hbox.Width + extend, shiftTop1);
                            pathWriter.Stop();

                            customVsxBox.BeforeBaseBox = actualRadical.Width + extend;
                            break;

                        case EncloseNotation.roundedbox:
                            using (Tools.BorrowRoundedRect(out var roundedRect))
                            {
                                roundedRect.SetRadius(over, over, over, over, over, over, over, over);
                                roundedRect.SetRect(0, 0, w, h);
                                roundedRect.MakeVxs(vsx1);
                                customVsxBox.CustomVxs = stroke.CreateTrim(vsx1);
                            }
                            customVsxBox.BeforeBaseBox = over;
                            break;

                        case EncloseNotation.circle:
                            using (Tools.BorrowEllipse(out Ellipse ellipse))
                            {
                                float xLength = hbox.Width / 2 + maxLeft;
                                float yLength = hbox.Height / 2 + maxTop;

                                ellipse.Set(xLength, yLength, xLength, yLength);
                                ellipse.MakeVxs(vsx1);
                                customVsxBox.CustomVxs     = stroke.CreateTrim(vsx1);
                                customVsxBox.BeforeBaseBox = maxLeft;
                            }
                            break;
                        }
                        if (useVxs > 0)
                        {
                            if (useVxs == 1)
                            {
                                customVsxBox.CustomVxs = stroke.CreateTrim(vsx1);
                            }
                            else if (useVxs == 2)
                            {
                                customVsxBox.CustomVxs = stroke.CreateTrim(vsx2);
                            }
                            encloseBox.NotationBoxs.Add(customVsxBox);
                        }
                    }
        }
예제 #7
0
        Box CreateMathBox(MathNode node)
        {
            //create box foreach node
            //TODO: most box are glyph box + its text content
            //except some boxes are Horizontal (eg. mrow) or some box are vertical (...)
            //this should be config from DomSpec.xml or Autogen code
            Box result = null;

            switch (node.Name)
            {
            default:
            {
                //text span box
                if (node.Text == null)
                {
                    return(null);
                }
                char[] text_buff = node.Text.ToCharArray();
                if (text_buff.Length == 0)
                {
                    //????
                    return(null);
                }
                else if (text_buff.Length > 1)
                {
                    HorizontalStackBox textSpan = new HorizontalStackBox();
                    textSpan.MathNode = node;
                    for (int i = 0; i < text_buff.Length; ++i)
                    {
                        GlyphBox glyphBox = NewGlyphBox();
                        glyphBox.Character = text_buff[i];
                        textSpan.AddChild(glyphBox);
                    }
                    //return textSpan;
                    result = textSpan;
                }
                else
                {
                    //len=1
                    GlyphBox glyphBox = NewGlyphBox();
                    glyphBox.MathNode  = node;
                    glyphBox.Character = text_buff[0];
                    //return glyphBox;
                    result = glyphBox;
                }
            }
            break;

            case "math":
            case "mrow":
            case "msub":
            case "msup":
            {
                HorizontalStackBox hbox = new HorizontalStackBox();
                hbox.MathNode = node;
                //
                int child_count = node.ChildCount;
                for (int i = 0; i < child_count; ++i)
                {
                    Box childBox = CreateMathBox(node.GetNode(i));
                    if (childBox != null)
                    {
                        hbox.AddChild(childBox);
                    }
                }
                //return hbox;
                result = hbox;
            }
            break;

            case "mfrac":
            case "munder":
            {
                VerticalStackBox vbox = new VerticalStackBox();
                vbox.MathNode = node;

                int child_count = node.ChildCount;
                for (int i = 0; i < child_count; ++i)
                {
                    Box childBox = CreateMathBox(node.GetNode(i));
                    if (childBox != null)
                    {
                        vbox.AddChild(childBox);
                    }
                }
                //return hbox;
                result = vbox;
            }
            break;

            case "mover":
            {
                VerticalStackBox vbox = new VerticalStackBox();
                vbox.MathNode = node;

                int child_count = node.ChildCount;
                if (child_count != 2)        //expect 2
                {
                    return(null);
                }
                Box baseBox = CreateMathBox(node.GetNode(0));
                Box overBox = CreateMathBox(node.GetNode(1));
                vbox.AddChild(overBox);
                vbox.AddChild(baseBox);
                //return hbox;
                result = vbox;
            }
            break;
            }
            if (result != null)
            {
                AssignGlyphVxs(result);
            }
            return(result);
        }
예제 #8
0
        void PaintGlyphBox(GlyphBox box)
        {
            if (box.IsInvisible)
            {
                return;
            }
            float ox = Painter.OriginX;//***
            float oy = Painter.OriginY;

            if (box.HasVxs)
            {
                Color color       = Color.Black;
                float shiftHeight = 0;
                float shiftWidth  = 0;
                var   glyphBound  = box.GetBoundingRect();

                {
                    if (_fromPaintHorizontal.Count > 0 && _fromPaintHorizontal.Peek() && _horizontalHeight.Count > 0)
                    {
                        shiftHeight = _horizontalHeight.Peek();
                    }
                    else
                    {
                        shiftHeight = box.Height;
                    }
                }
                shiftHeight -= box.Height - (float)glyphBound.Height;
                if (MathMLOperatorTable.IsStretchyPropertyOperator(box.Character + ""))
                {
                    var   bounds = box.GetBoundingRect();
                    float bottom = (float)bounds.Bottom;
                    float top    = (float)bounds.Top;
                    if (MathMLOperatorTable.IsFencePropertyOperator(box.Character + ""))
                    {
                        if (box.Stretched)
                        {
                            shiftHeight -= top;
                        }
                    }
                    else if (_fromPaintHorizontal.Peek())
                    {
                        shiftHeight -= top;
                    }
                }

                float x = box.Left + ox + shiftWidth;
                float y = box.Top + oy + shiftHeight;

                Painter.SetOrigin(box.Left + ox + shiftWidth, box.Top + oy + shiftHeight);


                if (box is VxsGlyphBox vxsGlyphBox)
                {
                    Painter.Fill(vxsGlyphBox.GlyphVxs, color);
                }

                Painter.SetOrigin(ox, oy);//restore
            }
            else
            {
                Color color = Color.FromArgb(100, Color.Black);
                Painter.FillRect(box.Left + ox, box.Top + oy, box.Width, box.Height, color);
            }
        }