Skip to content

Commit

Permalink
(#63) TexFormulaParser: move to the Shared assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Jan 9, 2023
1 parent 44d3bac commit bcf683c
Show file tree
Hide file tree
Showing 32 changed files with 168 additions and 109 deletions.
3 changes: 2 additions & 1 deletion src/WpfMath.Example/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using WpfMath.Converters;
using WpfMath.Parsers;
using WpfMath.Rendering;

namespace WpfMath.Example;

public partial class MainWindow
{
private readonly TexFormulaParser _formulaParser = new();
private readonly TexFormulaParser _formulaParser = WpfTeXFormulaParser.Instance;

private static ComboBoxItem DemoFormula(string name, string text) =>
new ComboBoxItem { Content = name, DataContext = text };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Media;

namespace WpfMath.Colors
{
internal class CmykColorParser : IColorParser
{
public Color? Parse(IEnumerable<string> components)
public RgbaColor? Parse(IEnumerable<string> components)
{
var componentList = components.ToList();
var hasAlpha = componentList.Count == 5;
Expand Down Expand Up @@ -36,7 +35,7 @@ internal class CmykColorParser : IColorParser
var g = (byte) Math.Round(255.0 * (1.0 - m.Value) * (1.0 - k.Value), MidpointRounding.AwayFromZero);
var b = (byte) Math.Round(255.0 * (1.0 - y.Value) * (1.0 - k.Value), MidpointRounding.AwayFromZero);
var a = (byte) Math.Round(255.0 * aFraction.Value, MidpointRounding.AwayFromZero);
return Color.FromArgb(a, r, g, b);
return RgbaColor.FromArgb(a, r, g, b);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

namespace WpfMath.Colors
{
Expand All @@ -14,9 +13,9 @@ protected FixedComponentCountColorParser(int componentCount)
_componentCount = componentCount;
}

protected abstract Color? ParseComponents(List<string> components);
protected abstract RgbaColor? ParseComponents(List<string> components);

public Color? Parse(IEnumerable<string> components)
public RgbaColor? Parse(IEnumerable<string> components)
{
var componentList = components.ToList();
return componentList.Count == _componentCount ? ParseComponents(componentList) : null;
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Media;

namespace WpfMath.Colors
{
internal class GrayscaleColorParser : IColorParser
{
public Color? Parse(IEnumerable<string> components)
public RgbaColor? Parse(IEnumerable<string> components)
{
var componentList = components.ToList();
var hasAlpha = componentList.Count == 2;
Expand Down Expand Up @@ -38,7 +37,7 @@ internal class GrayscaleColorParser : IColorParser

var colorValue = (byte) Math.Round(gradation * 255.0, MidpointRounding.AwayFromZero);
var a = (byte) Math.Round(alpha.Value * 255.0, MidpointRounding.AwayFromZero);
return Color.FromArgb(a, colorValue, colorValue, colorValue);
return RgbaColor.FromArgb(a, colorValue, colorValue, colorValue);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System.Globalization;
using System.Windows.Media;

namespace WpfMath.Colors
{
internal class HtmlColorParser : SingleComponentColorParser
{
protected override Color? ParseSingleComponent(string component)
protected override RgbaColor? ParseSingleComponent(string component)
{
var isRgb = component.Length == 6;
var isRgba = component.Length == 8;
Expand All @@ -20,15 +19,15 @@ internal class HtmlColorParser : SingleComponentColorParser
var r = (byte) ((colorCode & 0xFF0000) >> 16);
var g = (byte) ((colorCode & 0xFF00) >> 8);
var b = (byte) (colorCode & 0xFF);
return Color.FromRgb(r, g, b);
return RgbaColor.FromRgb(r, g, b);
}
else
{
var r = (byte) ((colorCode & 0xFF0000) >> 24);
var g = (byte) ((colorCode & 0xFF00) >> 16);
var b = (byte) ((colorCode & 0xFF) >> 8);
var a = (byte) (colorCode & 0xFF);
return Color.FromArgb(a, r, g, b);
return RgbaColor.FromArgb(a, r, g, b);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Windows.Media;

namespace WpfMath.Colors
{
Expand All @@ -9,6 +8,6 @@ public interface IColorParser
/// <summary>Parses the color components.</summary>
/// <param name="components">A sequence of the components that were separated by comma.</param>
/// <returns>Either a parsed color or <c>null</c> if it cannot be parsed.</returns>
Color? Parse(IEnumerable<string> components);
RgbaColor? Parse(IEnumerable<string> components);
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Media;
using System.Xml.Linq;
using WpfMath.Data;
using WpfMath.Utils;
Expand All @@ -14,7 +13,7 @@ public class PredefinedColorParser : IColorParser
private const string ResourceName = TexUtilities.ResourcesDataDirectory + "PredefinedColors.xml";
public static readonly PredefinedColorParser Instance = new PredefinedColorParser(ResourceName);

private readonly IReadOnlyDictionary<string, Color> _colors;
private readonly IReadOnlyDictionary<string, RgbaColor> _colors;

private PredefinedColorParser(string resourceName)
{
Expand All @@ -25,7 +24,7 @@ private PredefinedColorParser(string resourceName)
}
}

public Color? Parse(IEnumerable<string> components)
public RgbaColor? Parse(IEnumerable<string> components)
{
var componentList = components.ToList();
var hasAlphaComponent = componentList.Count == 2;
Expand Down Expand Up @@ -59,16 +58,16 @@ private PredefinedColorParser(string resourceName)
return color;
}

private Dictionary<string, Color> Parse(XElement rootElement)
private Dictionary<string, RgbaColor> Parse(XElement rootElement)
{
var colors = new Dictionary<string, Color>();
var colors = new Dictionary<string, RgbaColor>();
foreach (var colorElement in rootElement.Elements("color"))
{
var name = colorElement.AttributeValue("name");
var r = colorElement.AttributeValue("r");
var g = colorElement.AttributeValue("g");
var b = colorElement.AttributeValue("b");
colors.Add(name, Color.FromRgb(Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)));
colors.Add(name, RgbaColor.FromRgb(Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)));
}

return colors;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
#if NET452
using WpfMath.Compatibility;
#endif
Expand Down Expand Up @@ -33,7 +32,7 @@ protected RgbColorParserBase(AlphaChannelMode alphaChannelMode)
protected abstract Tuple<bool, T> TryParseComponent(string component);
protected abstract byte GetByteValue(T val);

protected override Color? ParseComponents(List<string> components)
protected override RgbaColor? ParseComponents(List<string> components)
{
var values = components.Select(x =>
{
Expand All @@ -53,8 +52,8 @@ protected RgbColorParserBase(AlphaChannelMode alphaChannelMode)
alpha = values[index];

return alpha == null || r == null || g == null || b == null
? (Color?) null
: Color.FromArgb(
? (RgbaColor?) null
: RgbaColor.FromArgb(
GetByteValue(alpha.Value),
GetByteValue(r.Value),
GetByteValue(g.Value),
Expand Down
6 changes: 5 additions & 1 deletion src/WpfMath.Shared/Colors/RgbaColor.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
namespace WpfMath.Colors;

public record struct RgbaColor(byte R, byte G, byte B, byte A = 0xff);
public record struct RgbaColor(byte R, byte G, byte B, byte A = 0xff)
{
public static RgbaColor FromArgb(byte a, byte r, byte g, byte b) => new(r, g, b, a);
public static RgbaColor FromRgb(byte r, byte g, byte b) => new(r, g, b);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

namespace WpfMath.Colors
{
Expand All @@ -11,9 +10,9 @@ protected SingleComponentColorParser() : base(1)
{
}

protected abstract Color? ParseSingleComponent(string component);
protected abstract RgbaColor? ParseSingleComponent(string component);

protected override Color? ParseComponents(List<string> components) =>
protected override RgbaColor? ParseComponents(List<string> components) =>
ParseSingleComponent(components.Single());
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions src/WpfMath.Shared/Rendering/IBrushFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using WpfMath.Colors;

namespace WpfMath.Rendering;

public interface IBrushFactory
{
public IPlatformBrush FromColor(RgbaColor color);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using WpfMath.Atoms;
using WpfMath.Rendering;

namespace WpfMath
{
Expand All @@ -8,9 +11,13 @@ internal class TexFormulaHelper
private readonly TexFormulaParser _formulaParser;
private readonly SourceSpan _source;

public TexFormulaHelper(TexFormula formula, SourceSpan source)
public TexFormulaHelper(
TexFormula formula,
SourceSpan source,
IBrushFactory brushFactory,
IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulae)
{
this._formulaParser = new TexFormulaParser();
this._formulaParser = new TexFormulaParser(brushFactory, predefinedFormulae);
this.Formula = formula;
this._source = source;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using WpfMath.Atoms;
using WpfMath.Colors;
using WpfMath.Exceptions;
Expand Down Expand Up @@ -49,8 +46,8 @@ public class TexFormulaParser
private static readonly IList<string> symbols;
private static readonly IList<string> delimeters;
private static readonly HashSet<string> textStyles;
private static readonly IDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulas =
new Dictionary<string, Func<SourceSpan, TexFormula?>>();
// TODO: Architectural solution to make this work faster.
private readonly IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulas;

private static readonly string[][] delimiterNames =
{
Expand All @@ -69,23 +66,10 @@ public class TexFormulaParser

static TexFormulaParser()
{
//
// If start application isn't WPF, pack isn't registered by defaultTexFontParser
//
if (Application.ResourceAssembly == null)
{
Application.ResourceAssembly = Assembly.GetExecutingAssembly();
if (!UriParser.IsKnownScheme("pack"))
UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), "pack", -1);
}

var formulaSettingsParser = new TexPredefinedFormulaSettingsParser();
symbols = formulaSettingsParser.GetSymbolMappings();
delimeters = formulaSettingsParser.GetDelimiterMappings();
textStyles = formulaSettingsParser.GetTextStyles();

var predefinedFormulasParser = new TexPredefinedFormulaParser();
predefinedFormulasParser.Parse(predefinedFormulas);
}

internal static string[][] DelimiterNames
Expand Down Expand Up @@ -136,24 +120,42 @@ private static bool IsWhiteSpace(char ch)
/// <summary>A color parser for cases when the color model isn't specified.</summary>
private readonly IColorParser _defaultColorParser;

private readonly IBrushFactory _brushFactory;

internal TexFormulaParser(
IReadOnlyDictionary<string, ICommandParser> commandRegistry,
IReadOnlyDictionary<string, IColorParser> colorModelParsers,
IColorParser defaultColorParser)
IColorParser defaultColorParser,
IBrushFactory brushFactory,
IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulae)
{
_commandRegistry = commandRegistry;
_colorModelParsers = colorModelParsers;
_defaultColorParser = defaultColorParser;
_brushFactory = brushFactory;
predefinedFormulas = predefinedFormulae;
}

public TexFormulaParser(
IReadOnlyDictionary<string, IColorParser> colorModelParsers,
IColorParser defaultColorParser) : this(StandardCommands.Dictionary, colorModelParsers, defaultColorParser)
IColorParser defaultColorParser,
IBrushFactory brushFactory,
IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulae)
: this(
StandardCommands.Dictionary,
colorModelParsers,
defaultColorParser,
brushFactory,
predefinedFormulae)
{}

public TexFormulaParser() : this(
public TexFormulaParser(
IBrushFactory brushFactory,
IReadOnlyDictionary<string, Func<SourceSpan, TexFormula?>> predefinedFormulae) : this(
StandardColorParsers.Dictionary,
PredefinedColorParser.Instance)
PredefinedColorParser.Instance,
brushFactory,
predefinedFormulae)
{}

public TexFormula Parse(string value, string? textStyle = null) =>
Expand Down Expand Up @@ -550,7 +552,7 @@ private TexFormula ReadScript(

return new Tuple<AtomAppendMode, Atom?>(
AtomAppendMode.Add,
new StyledAtom(source, bodyFormula.RootAtom, null, new SolidColorBrush(color).ToPlatform())); // TODO[#63]: Should read platform brush from color
new StyledAtom(source, bodyFormula.RootAtom, null, _brushFactory.FromColor(color)));
}
case "colorbox":
{
Expand All @@ -562,7 +564,7 @@ private TexFormula ReadScript(

return new Tuple<AtomAppendMode, Atom?>(
AtomAppendMode.Add,
new StyledAtom(source, bodyFormula.RootAtom, new SolidColorBrush(color).ToPlatform(), null));
new StyledAtom(source, bodyFormula.RootAtom, _brushFactory.FromColor(color), null));
// TODO[#63]: ↑ Should read platform brush from color
}
}
Expand All @@ -586,7 +588,7 @@ private TexFormula ReadScript(
/// <summary>Reads an optional square braced color model name, and then a color name.</summary>
/// <returns>Returns a color parsed.</returns>
/// <exception cref="TexParseException">Gets thrown in case of nonexistent color model or color.</exception>
private Color ReadColorModelData(SourceSpan value, ref int position)
private RgbaColor ReadColorModelData(SourceSpan value, ref int position)
{
var colorModelName = ReadElementGroupOptional(
value,
Expand Down Expand Up @@ -628,7 +630,7 @@ private void ProcessEscapeSequence(TexFormula formula,

if (symbolAtom.Type == TexAtomType.Accent)
{
var helper = new TexFormulaHelper(formula, formulaSource);
var helper = new TexFormulaHelper(formula, formulaSource, _brushFactory, predefinedFormulas);
TexFormula accentFormula = ReadScript(formula, value, ref position, environment);
helper.AddAccent(accentFormula, symbolAtom.Name);
}
Expand Down
Loading

0 comments on commit bcf683c

Please sign in to comment.