~wpf-math-dev/wpf-math/devel

« back to all changes in this revision

Viewing changes to WpfMath/AccentedAtom.cs

  • Committer: Alex Regueiro
  • Date: 2010-06-05 23:00:18 UTC
  • Revision ID: alexreg@gmail.com-20100605230018-wk0jl38tjcla09yh
Put all classes in library in WpfMath namespace.
Added RenderToBitmap method on TexRenderer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
using System.Linq;
4
4
using System.Text;
5
5
 
6
 
// Atom representing base atom with accent above it.
7
 
internal class AccentedAtom : Atom
 
6
namespace WpfMath
8
7
{
9
 
    public AccentedAtom(Atom baseAtom, string accentName)
10
 
    {
11
 
        this.BaseAtom = baseAtom;
12
 
        this.AccentAtom = SymbolAtom.GetAtom(accentName);
13
 
 
14
 
        if (this.AccentAtom.Type != TexAtomType.Accent)
15
 
            throw new ArgumentException("The specified symbol name is not an accent.", "accent");
16
 
    }
17
 
 
18
 
    public AccentedAtom(Atom baseAtom, TexFormula accent)
19
 
    {
20
 
        var rootSymbol = accent.RootAtom as SymbolAtom;
21
 
        if (rootSymbol == null)
22
 
            throw new ArgumentException("The formula for the accent is not a single symbol.", "accent");
23
 
        this.AccentAtom = (SymbolAtom)rootSymbol;
24
 
 
25
 
        if (this.AccentAtom.Type != TexAtomType.Accent)
26
 
            throw new ArgumentException("The specified symbol name is not an accent.", "accent");
27
 
    }
28
 
 
29
 
    // Atom over which accent symbol is placed.
30
 
    public Atom BaseAtom
31
 
    {
32
 
        get;
33
 
        private set;
34
 
    }
35
 
 
36
 
    // Atom representing accent symbol to place over base atom.
37
 
    public SymbolAtom AccentAtom
38
 
    {
39
 
        get;
40
 
        private set;
41
 
    }
42
 
 
43
 
    public override Box CreateBox(TexEnvironment environment)
44
 
    {
45
 
        var texFont = environment.TexFont;
46
 
        var style = environment.Style;
47
 
 
48
 
        // Create box for base atom.
49
 
        var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());
50
 
        var skew = 0d;
51
 
        if (this.BaseAtom is CharSymbol)
52
 
            skew = texFont.GetSkew(((CharSymbol)this.BaseAtom).GetCharFont(texFont), style);
53
 
 
54
 
        // Find character of best scale for accent symbol.
55
 
        var accentChar = texFont.GetCharInfo(AccentAtom.Name, style);
56
 
        while (texFont.HasNextLarger(accentChar))
57
 
        {
58
 
            var nextLargerChar = texFont.GetNextLargerCharInfo(accentChar, style);
59
 
            if (nextLargerChar.Metrics.Width > baseBox.Width)
60
 
                break;
61
 
            accentChar = nextLargerChar;
62
 
        }
63
 
 
64
 
        var resultBox = new VerticalBox();
65
 
 
66
 
        // Create and add box for accent symbol.
67
 
        Box accentBox;
68
 
        var accentItalicWidth = accentChar.Metrics.Italic;
69
 
        if (accentItalicWidth > TexUtilities.FloatPrecision)
70
 
        {
71
 
            accentBox = new HorizontalBox(new CharBox(environment, accentChar));
72
 
            accentBox.Add(new StrutBox(accentItalicWidth, 0, 0, 0));
73
 
        }
74
 
        else
75
 
        {
76
 
            accentBox = new CharBox(environment, accentChar);
77
 
        }
78
 
        resultBox.Add(accentBox);
79
 
 
80
 
        var delta = Math.Min(baseBox.Height, texFont.GetXHeight(style, accentChar.FontId));
81
 
        resultBox.Add(new StrutBox(0, -delta, 0, 0));
82
 
 
83
 
        // Centre and add box for base atom. Centre base box and accent box with respect to each other.
84
 
        var boxWidthsDiff = (baseBox.Width - accentBox.Width) / 2;
85
 
        accentBox.Shift = skew + Math.Max(boxWidthsDiff, 0);
86
 
        if (boxWidthsDiff < 0)
87
 
            baseBox = new HorizontalBox(baseBox, accentBox.Width, TexAlignment.Center);
88
 
        resultBox.Add(baseBox);
89
 
 
90
 
        // Adjust height and depth of result box.
91
 
        var depth = baseBox.Depth;
92
 
        var totalHeight = resultBox.Height + resultBox.Depth;
93
 
        resultBox.Depth = depth;
94
 
        resultBox.Height = totalHeight - depth;
95
 
 
96
 
        return resultBox;
 
8
    // Atom representing base atom with accent above it.
 
9
    internal class AccentedAtom : Atom
 
10
    {
 
11
        public AccentedAtom(Atom baseAtom, string accentName)
 
12
        {
 
13
            this.BaseAtom = baseAtom;
 
14
            this.AccentAtom = WpfMath.SymbolAtom.GetAtom(accentName);
 
15
 
 
16
            if (this.AccentAtom.Type != TexAtomType.Accent)
 
17
                throw new ArgumentException("The specified symbol name is not an accent.", "accent");
 
18
        }
 
19
 
 
20
        public AccentedAtom(Atom baseAtom, TexFormula accent)
 
21
        {
 
22
            var rootSymbol = accent.RootAtom as WpfMath.SymbolAtom;
 
23
            if (rootSymbol == null)
 
24
                throw new ArgumentException("The formula for the accent is not a single symbol.", "accent");
 
25
            this.AccentAtom = (WpfMath.SymbolAtom)rootSymbol;
 
26
 
 
27
            if (this.AccentAtom.Type != TexAtomType.Accent)
 
28
                throw new ArgumentException("The specified symbol name is not an accent.", "accent");
 
29
        }
 
30
 
 
31
        // Atom over which accent symbol is placed.
 
32
        public Atom BaseAtom
 
33
        {
 
34
            get;
 
35
            private set;
 
36
        }
 
37
 
 
38
        // Atom representing accent symbol to place over base atom.
 
39
        public WpfMath.SymbolAtom AccentAtom
 
40
        {
 
41
            get;
 
42
            private set;
 
43
        }
 
44
 
 
45
        public override Box CreateBox(WpfMath.TexEnvironment environment)
 
46
        {
 
47
            var texFont = environment.TexFont;
 
48
            var style = environment.Style;
 
49
 
 
50
            // Create box for base atom.
 
51
            var baseBox = this.BaseAtom == null ? WpfMath.StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());
 
52
            var skew = 0d;
 
53
            if (this.BaseAtom is CharSymbol)
 
54
                skew = texFont.GetSkew(((CharSymbol)this.BaseAtom).GetCharFont(texFont), style);
 
55
 
 
56
            // Find character of best scale for accent symbol.
 
57
            var accentChar = texFont.GetCharInfo(AccentAtom.Name, style);
 
58
            while (texFont.HasNextLarger(accentChar))
 
59
            {
 
60
                var nextLargerChar = texFont.GetNextLargerCharInfo(accentChar, style);
 
61
                if (nextLargerChar.Metrics.Width > baseBox.Width)
 
62
                    break;
 
63
                accentChar = nextLargerChar;
 
64
            }
 
65
 
 
66
            var resultBox = new WpfMath.VerticalBox();
 
67
 
 
68
            // Create and add box for accent symbol.
 
69
            Box accentBox;
 
70
            var accentItalicWidth = accentChar.Metrics.Italic;
 
71
            if (accentItalicWidth > WpfMath.TexUtilities.FloatPrecision)
 
72
            {
 
73
                accentBox = new WpfMath.HorizontalBox(new CharBox(environment, accentChar));
 
74
                accentBox.Add(new WpfMath.StrutBox(accentItalicWidth, 0, 0, 0));
 
75
            }
 
76
            else
 
77
            {
 
78
                accentBox = new CharBox(environment, accentChar);
 
79
            }
 
80
            resultBox.Add(accentBox);
 
81
 
 
82
            var delta = Math.Min(baseBox.Height, texFont.GetXHeight(style, accentChar.FontId));
 
83
            resultBox.Add(new WpfMath.StrutBox(0, -delta, 0, 0));
 
84
 
 
85
            // Centre and add box for base atom. Centre base box and accent box with respect to each other.
 
86
            var boxWidthsDiff = (baseBox.Width - accentBox.Width) / 2;
 
87
            accentBox.Shift = skew + Math.Max(boxWidthsDiff, 0);
 
88
            if (boxWidthsDiff < 0)
 
89
                baseBox = new WpfMath.HorizontalBox(baseBox, accentBox.Width, TexAlignment.Center);
 
90
            resultBox.Add(baseBox);
 
91
 
 
92
            // Adjust height and depth of result box.
 
93
            var depth = baseBox.Depth;
 
94
            var totalHeight = resultBox.Height + resultBox.Depth;
 
95
            resultBox.Depth = depth;
 
96
            resultBox.Height = totalHeight - depth;
 
97
 
 
98
            return resultBox;
 
99
        }
97
100
    }
98
101
}