Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 41 additions & 33 deletions CSharpMath.Editor/Extensions/DisplayEditingExtensions.List.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,48 +86,56 @@ public static MathListIndex IndexForPoint<TFont, TGlyph>(this ListDisplay<TFont,
return MathListIndex.IndexAtLocation(index.AtomIndex - 1, MathListSubIndexType.BetweenBaseAndScripts, MathListIndex.Level0Index(1));
return index;
}

public static PointF? PointForIndex<TFont, TGlyph>(this ListDisplay<TFont, TGlyph> self, TypesettingContext<TFont, TGlyph> context, MathListIndex index) where TFont : IFont<TGlyph> {
if (index is null) return null;

PointF? position;
if (index.AtomIndex == self.Range.End)
// Special case the edge of the range
PointF? position = null;
var nonScripted =
self.Displays
.Where(d => !(d is ListDisplay<TFont, TGlyph> ld &&
ld.LinePosition != Enumerations.LinePosition.Regular))
.ToArray();
if (index.SubIndexType == MathListSubIndexType.None &&
nonScripted.Length > 0 &&
nonScripted.All(d => d.Range.End <= index.AtomIndex)) {
position = new PointF(self.Width, 0);
else if (self.Range.Contains(index.AtomIndex) && self.SubDisplayForIndex(index) is IDisplay<TFont, TGlyph> display)
switch (index.SubIndexType) {
case MathListSubIndexType.BetweenBaseAndScripts:
var nucleusPosition = index.AtomIndex + index.SubIndex.AtomIndex;
position = display.PointForIndex(context, MathListIndex.Level0Index(nucleusPosition));
break;
case MathListSubIndexType.None:
if (!display.HasScript) {
position = display.PointForIndex(context, index);
} else {
var mainPosition = display.PointForIndex(context, index);
position = self.Displays.SingleOrDefault(d =>
d is ListDisplay<TFont, TGlyph> ld && ld.IndexInParent == index.AtomIndex - 1)
is IDisplay<TFont, TGlyph> scripted && mainPosition != null
? new PointF(mainPosition.Value.X + scripted.Width, 0)
: mainPosition;
}
break;
default:
// Recurse
position = display.PointForIndex(context, index.SubIndex);
break;
}
else
// Outside the range
return null;

} else {
if (index.AtomIndex == self.Range.End) {
// Special case the edge of the range
position = new PointF(self.Width, 0);
} else if (self.Range.Contains(index.AtomIndex) && self.SubDisplayForIndex(index) is IDisplay<TFont, TGlyph> display)
switch (index.SubIndexType) {
case MathListSubIndexType.BetweenBaseAndScripts:
var nucleusPosition = index.AtomIndex + index.SubIndex.AtomIndex;
position = display.PointForIndex(context, MathListIndex.Level0Index(nucleusPosition));
break;
case MathListSubIndexType.None:
if (!display.HasScript) {
position = display.PointForIndex(context, index);
} else {
var mainPosition = display.PointForIndex(context, index);
position = self.Displays.SingleOrDefault(d =>
d is ListDisplay<TFont, TGlyph> ld && ld.IndexInParent == index.AtomIndex - 1)
is IDisplay<TFont, TGlyph> scripted && mainPosition != null
? new PointF(mainPosition.Value.X + scripted.Width, 0)
: mainPosition;
}
break;
default:
// Recurse
position = display.PointForIndex(context, index.SubIndex);
break;
} else
// Outside the range
return null;
}
if (position is PointF found) {
// Convert bounds from our coordinate system before returning
found.X += self.Position.X;
found.Y += self.Position.Y;
return found;
}
else
} else
// We didn't find the position
return null;
}
Expand Down