corrected grouping behavior
This commit is contained in:
37
WpfTex/LatexEditor/Fonts/GlyphDescriptor.cs
Normal file
37
WpfTex/LatexEditor/Fonts/GlyphDescriptor.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace LatexEditor.Fonts
|
||||
{
|
||||
public struct GlyphDescriptor
|
||||
{
|
||||
public GlyphTypeface Typeface;
|
||||
public ushort Index;
|
||||
public string CharacterName;
|
||||
public double Size;
|
||||
public Point Offset;
|
||||
|
||||
public double AdvanceWidth => Typeface.AdvanceWidths[Index] * Size;
|
||||
public double AdvanceHeight => Typeface.AdvanceHeights[Index] * Size;
|
||||
public double Height => Typeface.Height * Size;
|
||||
|
||||
public GlyphDescriptor(GlyphTypeface typeface, int character)
|
||||
{
|
||||
Typeface = typeface;
|
||||
Index = Typeface.CharacterToGlyphMap[character];
|
||||
CharacterName = ((char) character).ToString();
|
||||
Offset = new Point(0, 0);
|
||||
Size = 1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"'{CharacterName}' ({Index}) {Offset} {AdvanceWidth}x{AdvanceHeight} [{Height}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace LatexEditor.Fonts
|
||||
{
|
||||
public class GlyphInfo
|
||||
{
|
||||
public CmFont Font;
|
||||
public double RelativeSize;
|
||||
public int Char;
|
||||
public Point RelativeOffset;
|
||||
public Point BaselineOrigin;
|
||||
|
||||
public GlyphTypeface Gtf => Font.GlyphTypeface();
|
||||
|
||||
public ushort Index => Gtf.CharacterToGlyphMap[Char];
|
||||
|
||||
public double RelAdvWidth => Gtf.AdvanceWidths[Index];
|
||||
public double RelAdvHeight => Gtf.AdvanceHeights[Index];
|
||||
|
||||
public Point Offset => new Point(
|
||||
BaselineOrigin.X + RelativeOffset.X * RelativeSize,
|
||||
BaselineOrigin.Y + RelativeOffset.Y * RelativeSize);
|
||||
|
||||
public GlyphInfo(CmFont font, int c, Point relativeOffset, Point baselineOrigin, double relativeSize = 1)
|
||||
{
|
||||
Font = font;
|
||||
RelativeSize = relativeSize;
|
||||
RelativeOffset = relativeOffset;
|
||||
BaselineOrigin = baselineOrigin;
|
||||
Char = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Fonts\CmManager.cs" />
|
||||
<Compile Include="Fonts\CmFont.cs" />
|
||||
<Compile Include="Fonts\GlyphInfo.cs" />
|
||||
<Compile Include="Fonts\GlyphDescriptor.cs" />
|
||||
<Compile Include="LatexDocument.cs" />
|
||||
<Compile Include="LatexViewer.cs" />
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
@@ -76,14 +76,8 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Parser\Segments\LatexNull.cs" />
|
||||
<Compile Include="Parser\Parser.cs" />
|
||||
<Compile Include="Parser\Segments\LatexReturn.cs" />
|
||||
<Compile Include="Parser\Segments\LatexRun.cs" />
|
||||
<Compile Include="Parser\LatexParser.cs" />
|
||||
<Compile Include="Parser\Segments\LatexSegment.cs" />
|
||||
<Compile Include="Parser\Segments\LatexSpace.cs" />
|
||||
<Compile Include="Parser\Segments\LatexSuper.cs" />
|
||||
<Compile Include="Parser\Segments\LatexText.cs" />
|
||||
<Compile Include="Parser\Lexer.cs" />
|
||||
<Compile Include="Parser\Token.cs" />
|
||||
<Compile Include="Parser\TokenDescriptor.cs" />
|
||||
|
||||
@@ -4,6 +4,9 @@ using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using LatexEditor.Parser;
|
||||
using LatexEditor.Parser.Segments;
|
||||
|
||||
namespace LatexEditor
|
||||
{
|
||||
@@ -36,30 +39,32 @@ namespace LatexEditor
|
||||
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
Debug.WriteLine(dc, nameof(LatexViewer));
|
||||
Debug.WriteLine(dc.GetType(), nameof(LatexViewer));
|
||||
|
||||
if (string.IsNullOrEmpty(Content)) return;
|
||||
|
||||
var glyphInfoList = Parser.Parser.ToGlyphInfos(Content);
|
||||
var seg = LatexSegment.ToLatexSegment(LatexParser.Tokenize(Content));
|
||||
|
||||
var gtfGroups = glyphInfoList.GroupBy(gi => gi.Gtf);
|
||||
foreach (var gtfGroup in gtfGroups)
|
||||
var gds = seg.GlyphDescriptors.ToList();
|
||||
|
||||
var tfGroups = gds.GroupBy(gd => gd.Typeface);
|
||||
foreach (var tfGroup in tfGroups)
|
||||
{
|
||||
var gtf = gtfGroup.Key;
|
||||
var tf = tfGroup.Key;
|
||||
|
||||
var sizeGroups = gtfGroup.GroupBy(gi => gi.RelativeSize);
|
||||
var sizeGroups = tfGroup.GroupBy(gd => gd.Size);
|
||||
foreach (var sizeGroup in sizeGroups)
|
||||
{
|
||||
var size = sizeGroup.Key;
|
||||
|
||||
var glyphs = sizeGroup.Select(gi => gi.Index).ToList();
|
||||
var advanceWidths = new double[glyphs.Count]; // all zero - position based only on offset
|
||||
var offsets = sizeGroup.Select(gi => new Point(gi.Offset.X * FontSize, gi.Offset.Y * FontSize))
|
||||
var glyphs = sizeGroup.Select(gd => gd.Index).ToList();
|
||||
var advWidths = new double[glyphs.Count]; // base only on offset
|
||||
var offsets = sizeGroup.Select(gd => gd.Offset)
|
||||
.Select(o => new Point(o.X * FontSize, o.Y * FontSize))
|
||||
.ToList();
|
||||
var gr = new GlyphRun(gtf, 0, false, size * FontSize,
|
||||
glyphs, new Point(0, FontSize), advanceWidths,
|
||||
offsets, null, null, null, null, null);
|
||||
var gr = new GlyphRun(
|
||||
tf, 0, false, size * FontSize,
|
||||
glyphs, new Point(0, FontSize), advWidths,
|
||||
offsets, null, null, null, null, null
|
||||
);
|
||||
|
||||
dc.DrawGlyphRun(Brushes.Black, gr);
|
||||
}
|
||||
|
||||
@@ -8,20 +8,20 @@
|
||||
Title="MainWindow" Height="350" Width="525">
|
||||
<Grid>
|
||||
<local:LatexViewer>
|
||||
<!-- e^{\pi i}=-1\{\textrm{in the complex plane}-->
|
||||
{2}{123}
|
||||
<!-- A \ \alpha \quad N \ \nu \\-->
|
||||
<!-- B \ \beta \quad \Xi \ \xi \\-->
|
||||
<!-- \Gamma \ \gamma \quad O \ \omicron \\-->
|
||||
<!-- \Delta \ \delta \quad \Pi \ \pi \\-->
|
||||
<!-- E \ \epsilon \quad P \ \rho \\-->
|
||||
<!-- Z \ \zeta \quad \Sigma \ \sigma \\-->
|
||||
<!-- H \ \eta \quad T \ \tau \\-->
|
||||
<!-- \Theta \ \theta \quad Y \ \upsilon \\-->
|
||||
<!-- I \ \iota \quad \Phi \ \phi \\-->
|
||||
<!-- K \ \kappa \quad X \ \chi \\-->
|
||||
<!-- \Lambda \ \lambda \quad \Psi \ \psi \\-->
|
||||
<!-- M \ \mu \quad \Omega \ \omega-->
|
||||
e^{\pi i}=-1\{\textrm{in the complex plane} \\\\
|
||||
|
||||
A \ \alpha \quad N \ \nu \\
|
||||
B \ \beta \quad \Xi \ \xi \\
|
||||
\Gamma \ \gamma \quad O \ \omicron \\
|
||||
\Delta \ \delta \quad \Pi \ \pi \\
|
||||
E \ \epsilon \quad P \ \rho \\
|
||||
Z \ \zeta \quad \Sigma \ \sigma \\
|
||||
H \ \eta \quad T \ \tau \\
|
||||
\Theta \ \theta \quad Y \ \upsilon \\
|
||||
I \ \iota \quad \Phi \ \phi \\
|
||||
K \ \kappa \quad X \ \chi \\
|
||||
\Lambda \ \lambda \quad \Psi \ \psi \\
|
||||
M \ \mu \quad \Omega \ \omega
|
||||
|
||||
</local:LatexViewer>
|
||||
</Grid>
|
||||
|
||||
@@ -4,14 +4,14 @@ using LatexEditor.Parser.Segments;
|
||||
|
||||
namespace LatexEditor.Parser
|
||||
{
|
||||
public static class Parser
|
||||
public static class LatexParser
|
||||
{
|
||||
// todo: move these tables to an environment class
|
||||
private static readonly Lexer LatexLexer = new Lexer()
|
||||
{
|
||||
new TokenDescriptor("whitespace", @"\s+"),
|
||||
new TokenDescriptor("escape", @"\\([\#\$\%\^\&_\{\}\~\\])", 1),
|
||||
new TokenDescriptor("command", @"\\([^\d\s\\]+|[\ ])", 1),
|
||||
new TokenDescriptor("command", @"\\([^\d\s\\\#\$\%\^\&_{}]+|[\ ])", 1),
|
||||
new TokenDescriptor("command", @"[\#\$\%\^\&_]"),
|
||||
new TokenDescriptor("number", @"\d"),
|
||||
new TokenDescriptor("open", @"\{"),
|
||||
@@ -73,12 +73,6 @@ namespace LatexEditor.Parser
|
||||
["qquad"] = 4,
|
||||
};
|
||||
|
||||
public static IEnumerable<GlyphInfo> ToGlyphInfos(string latex) => ToGlyphInfos(LatexLexer.Tokenize(latex));
|
||||
|
||||
private static IEnumerable<GlyphInfo> ToGlyphInfos(IEnumerable<Token> tokens)
|
||||
{
|
||||
var lss = LatexSegment.ToLatexSegment(tokens);
|
||||
return lss.Glyphs;
|
||||
}
|
||||
public static IEnumerable<Token> Tokenize(string latex) => LatexLexer.Tokenize(latex);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexNull : LatexSegment
|
||||
{
|
||||
public override IEnumerable<GlyphInfo> Glyphs => Enumerable.Empty<GlyphInfo>();
|
||||
public override double RelAdvWidth => 0;
|
||||
public override double RelAdvHeight => 0;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexReturn : LatexSegment
|
||||
{
|
||||
public override IEnumerable<GlyphInfo> Glyphs => Enumerable.Empty<GlyphInfo>();
|
||||
public override double RelAdvWidth => 0;
|
||||
public override double RelAdvHeight { get; }
|
||||
|
||||
public LatexReturn(double relAdvHeight)
|
||||
{
|
||||
RelAdvHeight = relAdvHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexRun : LatexSegment
|
||||
{
|
||||
public override IEnumerable<GlyphInfo> Glyphs => Segments.SelectMany(ls => ls.Glyphs);
|
||||
|
||||
public override double RelAdvWidth { get; }
|
||||
public override double RelAdvHeight { get; }
|
||||
|
||||
public IEnumerable<LatexSegment> Segments { get; set; }
|
||||
|
||||
public LatexRun(IEnumerable<LatexSegment> segments)
|
||||
{
|
||||
Segments = segments;
|
||||
|
||||
// to shift characters into position
|
||||
var x = 0d;
|
||||
var y = 0d;
|
||||
foreach (var segment in Segments)
|
||||
{
|
||||
if (segment is LatexReturn)
|
||||
{
|
||||
x = 0d;
|
||||
y -= segment.RelAdvHeight;
|
||||
continue;
|
||||
}
|
||||
foreach (var gi in segment.Glyphs)
|
||||
{
|
||||
gi.BaselineOrigin.X = x;
|
||||
gi.BaselineOrigin.Y = y;
|
||||
}
|
||||
x += segment.RelAdvWidth;
|
||||
}
|
||||
RelAdvWidth = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using JetBrains.Annotations;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
@@ -6,8 +8,15 @@ namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public abstract class LatexSegment
|
||||
{
|
||||
[NotNull]
|
||||
public abstract IEnumerable<GlyphInfo> Glyphs { get; }
|
||||
public List<LatexSegment> Contents { get; } = new List<LatexSegment>();
|
||||
|
||||
public abstract double Width { get; }
|
||||
public abstract double Height { get; }
|
||||
|
||||
public double Size { get; protected set; } = 1;
|
||||
public Point Offset { get; protected set; } = new Point(0, 0);
|
||||
|
||||
public abstract IEnumerable<LatexGlyph> Glyphs { get; }
|
||||
|
||||
public static LatexSegment ToLatexSegment(IEnumerable<Token> tokens)
|
||||
{
|
||||
@@ -18,15 +27,12 @@ namespace LatexEditor.Parser.Segments
|
||||
segments.Add(ls);
|
||||
|
||||
if (segments.Count == 0)
|
||||
return new LatexNull();
|
||||
return null;
|
||||
if (segments.Count == 1)
|
||||
return segments[0];
|
||||
return new LatexRun(segments);
|
||||
return new LatexNull(segments);
|
||||
}
|
||||
|
||||
public abstract double RelAdvWidth { get; }
|
||||
public abstract double RelAdvHeight { get; }
|
||||
|
||||
private static bool PopLatexSegment(Queue<Token> tokens, out LatexSegment val)
|
||||
{
|
||||
val = null;
|
||||
@@ -37,48 +43,172 @@ namespace LatexEditor.Parser.Segments
|
||||
// todo: tabulate this
|
||||
|
||||
var head = tokens.Dequeue();
|
||||
if (head.TokenName == "letter")
|
||||
val = new LatexText(CmFont.SerifItalic, head.Value);
|
||||
if (head.TokenName == "command")
|
||||
switch (head.TokenName)
|
||||
{
|
||||
if (Parser.GreekLetters.ContainsKey(head.Value))
|
||||
val = new LatexText(CmFont.SerifItalic, Parser.GreekLetters[head.Value]);
|
||||
if (Parser.Spaces.ContainsKey(head.Value))
|
||||
val = new LatexSpace(Parser.Spaces[head.Value]);
|
||||
if (head.Value == "^")
|
||||
if (PopLatexSegment(tokens, out var content))
|
||||
{
|
||||
val = new LatexSuper(content);
|
||||
}
|
||||
else // to prevent possible nullref, but still incorrect.
|
||||
{
|
||||
val = null;
|
||||
return false;
|
||||
}
|
||||
if (val == null) // if no command matches
|
||||
val = new LatexText(CmFont.SerifItalic, head.CapturedString);
|
||||
}
|
||||
if (head.TokenName == "number")
|
||||
val = new LatexText(CmFont.Serif, head.Value);
|
||||
if (head.TokenName == "escape")
|
||||
if (head.Value == "\\")
|
||||
val = new LatexReturn(1);
|
||||
if (head.TokenName == "open")
|
||||
{
|
||||
// todo: fix incorrect glyph placement within {}
|
||||
// Should create a LatexGlyph: LatexSegment, and change LatexSegment.Glyphs
|
||||
// to be of LatexGlyphs.Then, ON ITERATION, not creation, compute the altered positions of
|
||||
// the LatexGlyphs and create the GlyphRuns from that.
|
||||
var segments = new List<LatexSegment>();
|
||||
case "letter":
|
||||
val = new LatexGlyph(CmFont.SerifItalic, head.Value[0]);
|
||||
break;
|
||||
|
||||
case "number":
|
||||
val = new LatexGlyph(CmFont.Serif, head.Value[0]);
|
||||
break;
|
||||
|
||||
case "open": // todo: implement proper lookahead
|
||||
// currently crashes if no closing brace present
|
||||
val = new LatexNull();
|
||||
while (tokens.Peek().TokenName != "close")
|
||||
if (PopLatexSegment(tokens, out var content))
|
||||
segments.Add(content);
|
||||
tokens.Dequeue(); // toss the close
|
||||
val = new LatexRun(segments);
|
||||
val.Contents.Add(content);
|
||||
tokens.Dequeue(); // pop close token
|
||||
break;
|
||||
|
||||
case "command":
|
||||
if (LatexParser.GreekLetters.ContainsKey(head.Value))
|
||||
val = new LatexGlyph(CmFont.Serif, LatexParser.GreekLetters[head.Value]);
|
||||
if (LatexParser.Spaces.ContainsKey(head.Value))
|
||||
val = new LatexSpace(LatexParser.Spaces[head.Value]);
|
||||
if (head.Value == "^")
|
||||
{
|
||||
if (PopLatexSegment(tokens, out var content))
|
||||
{
|
||||
val = content;
|
||||
val.Size *= 0.7;
|
||||
val.Offset = new Point(val.Offset.X, val.Offset.Y + 0.45);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "escape":
|
||||
if (head.Value == "\\")
|
||||
val = new LatexReturn();
|
||||
break;
|
||||
}
|
||||
|
||||
return val != null || PopLatexSegment(tokens, out val);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{GetType().Name}: [{string.Join(", ", Contents.Select(c => "{" + c + "}"))}]";
|
||||
}
|
||||
|
||||
|
||||
public virtual IEnumerable<GlyphDescriptor> GlyphDescriptors
|
||||
{
|
||||
get
|
||||
{
|
||||
var o_x = 0d;
|
||||
var o_y = 0d;
|
||||
foreach (var seg in Contents)
|
||||
{
|
||||
if (seg is LatexReturn)
|
||||
{
|
||||
o_x = 0;
|
||||
o_y -= 1;
|
||||
continue;
|
||||
}
|
||||
foreach (var gd in seg.GlyphDescriptors)
|
||||
{
|
||||
var cp = gd;
|
||||
cp.Size *= Size;
|
||||
cp.Offset.X += o_x + Offset.X;
|
||||
cp.Offset.Y += o_y + Offset.Y;
|
||||
yield return cp;
|
||||
}
|
||||
|
||||
o_x += seg.Width * Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LatexGlyph : LatexSegment
|
||||
{
|
||||
private GlyphDescriptor _glyphDescriptor;
|
||||
public override double Width => _glyphDescriptor.AdvanceWidth * Size;
|
||||
public override double Height => _glyphDescriptor.AdvanceHeight * Size;
|
||||
|
||||
public override IEnumerable<LatexGlyph> Glyphs
|
||||
{
|
||||
get { yield return this; }
|
||||
}
|
||||
|
||||
public int CharId { get; }
|
||||
|
||||
public char Char => (char) CharId;
|
||||
|
||||
public LatexGlyph(CmFont font, int charId)
|
||||
{
|
||||
CharId = charId;
|
||||
_glyphDescriptor = new GlyphDescriptor(font.GlyphTypeface(), CharId);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{base.ToString()}, '{Char}' ({CharId})";
|
||||
}
|
||||
|
||||
public override IEnumerable<GlyphDescriptor> GlyphDescriptors
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = _glyphDescriptor;
|
||||
cp.Size *= Size;
|
||||
cp.Offset.X += Offset.X;
|
||||
cp.Offset.Y += Offset.Y;
|
||||
yield return cp;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: essentially duplicate glyphinfo functionality here
|
||||
// need to make sure that parent has control over offset and new relative size.
|
||||
// Width and Height should account for this.
|
||||
// easiest solution would be an "offset" method that returns a modified clone.
|
||||
}
|
||||
|
||||
public class LatexReturn : LatexSegment
|
||||
{
|
||||
public override double Width => 0;
|
||||
public override double Height => 0;
|
||||
public override IEnumerable<LatexGlyph> Glyphs => Enumerable.Empty<LatexGlyph>();
|
||||
}
|
||||
|
||||
// todo: should be able to implement LatexReturn through latexspace.
|
||||
public class LatexSpace : LatexSegment
|
||||
{
|
||||
public override double Width { get; }
|
||||
public override double Height { get; }
|
||||
public override IEnumerable<LatexGlyph> Glyphs => Enumerable.Empty<LatexGlyph>();
|
||||
|
||||
public LatexSpace(double width, double height = 0)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
|
||||
public class LatexNull : LatexSegment
|
||||
{
|
||||
public override double Width => Contents.Sum(ls => ls.Width);
|
||||
public override double Height => Contents.Max(ls => ls.Height);
|
||||
|
||||
public override IEnumerable<LatexGlyph> Glyphs
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var ls in Contents)
|
||||
foreach (var lg in ls.Glyphs)
|
||||
yield return lg;
|
||||
}
|
||||
}
|
||||
|
||||
public LatexNull()
|
||||
{
|
||||
}
|
||||
|
||||
public LatexNull(IEnumerable<LatexSegment> contents)
|
||||
{
|
||||
Contents.AddRange(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexSpace : LatexSegment
|
||||
{
|
||||
public override IEnumerable<GlyphInfo> Glyphs => Enumerable.Empty<GlyphInfo>();
|
||||
public override double RelAdvWidth { get; }
|
||||
public override double RelAdvHeight { get; }
|
||||
|
||||
public LatexSpace(double relAdvWidth)
|
||||
{
|
||||
RelAdvWidth = relAdvWidth;
|
||||
RelAdvHeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexSuper : LatexSegment
|
||||
{
|
||||
public override IEnumerable<GlyphInfo> Glyphs => Content.Glyphs;
|
||||
|
||||
public override double RelAdvWidth => Content.RelAdvWidth;
|
||||
public override double RelAdvHeight => Content.RelAdvHeight;
|
||||
|
||||
public LatexSegment Content { get; set; }
|
||||
|
||||
public LatexSuper(LatexSegment content)
|
||||
{
|
||||
Content = content;
|
||||
|
||||
foreach (var gi in Content.Glyphs)
|
||||
{
|
||||
gi.RelativeOffset.Y += 1;
|
||||
gi.RelativeSize *= 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using LatexEditor.Fonts;
|
||||
|
||||
namespace LatexEditor.Parser.Segments
|
||||
{
|
||||
public class LatexText : LatexSegment
|
||||
{
|
||||
private readonly List<GlyphInfo> _glyphs = new List<GlyphInfo>();
|
||||
|
||||
public override IEnumerable<GlyphInfo> Glyphs => _glyphs;
|
||||
public override double RelAdvWidth { get; }
|
||||
public override double RelAdvHeight { get; }
|
||||
|
||||
public LatexText(CmFont cmFont, int c)
|
||||
{
|
||||
var gi = new GlyphInfo(cmFont, c, new Point(0, 0), new Point(0, 0));
|
||||
_glyphs.Add(gi);
|
||||
RelAdvWidth = gi.RelAdvWidth;
|
||||
RelAdvHeight = gi.RelAdvHeight;
|
||||
}
|
||||
|
||||
public LatexText(CmFont cmFont, string text)
|
||||
{
|
||||
var x = 0d;
|
||||
foreach (var c in text)
|
||||
{
|
||||
var gi = new GlyphInfo(cmFont, c, new Point(x, 0), new Point(0, 0));
|
||||
_glyphs.Add(gi);
|
||||
x += gi.RelAdvWidth;
|
||||
}
|
||||
RelAdvWidth = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user