private void UpdateRange(double scroll, long scrollLinesPossible, bool scrollToEnd) { Extent newExtent = lineRange.RelExtent(scrollLinesPossible); if (scrollToEnd) { UpdateRange(-1, Origin.End, Origin.End); } else if (newExtent != null) { UpdateRange(newExtent.Begin, Origin.Begin, Origin.Begin); } else { int linesOnScreen = FullyVisibleLines; double lineLen = (double)(lineRange.LastExtent.End - lineRange.FirstExtent.Begin) / lineRange.ExtentsCount; double vis = linesOnScreen * lineLen; double streamLenMod = lineRange.StreamLength - vis; long pos; Origin origin; double sValue = scrollPosition ?? 0.5; // 0.5: No correction double cFactor = 1 - sValue * (1 - sValue) * 4; if (sValue <= 0.5) { origin = Origin.Begin; pos = ToRange(RoundToLongRange(LineAt(0).Begin + streamLenMod * scroll), 0, lineRange.StreamLength - 1); long p = RoundToLongRange(cFactor * (sValue * streamLenMod - pos)); pos = ToRange(pos + p, 0, lineRange.StreamLength - 1); // Position at the begin of the line pos += Round(sValue * lineLen); // Position within the line } else { origin = Origin.End; pos = ToRange(RoundToLongRange(LineAt(linesOnScreen - 1).End + streamLenMod * scroll), 0, lineRange.StreamLength); long p = RoundToLongRange(cFactor * ((lineRange.StreamLength - (1 - sValue) * streamLenMod) - pos)); pos = ToRange(pos + p, 0, lineRange.StreamLength); // Position at the end of the line pos -= lineRange.StreamLength + 1; // --> From the end of the stream pos -= Round((1 - sValue) * lineLen); // Position within the line } UpdateRange(pos, origin, Origin.Begin); } }