aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Utils/PixelSnapHelpers.cs
blob: abd859533bad007c9513aad00751d5480d7c93b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Windows;
using System.Windows.Media;

namespace Tango.Scripting.Editors.Utils
{
	/// <summary>
	/// Contains static helper methods for aligning stuff on a whole number of pixels.
	/// </summary>
	public static class PixelSnapHelpers
	{
		/// <summary>
		/// Gets the pixel size on the screen containing visual.
		/// This method does not take transforms on visual into account.
		/// </summary>
		public static Size GetPixelSize(Visual visual)
		{
			if (visual == null)
				throw new ArgumentNullException("visual");
			PresentationSource source = PresentationSource.FromVisual(visual);
			if (source != null) {
				Matrix matrix = source.CompositionTarget.TransformFromDevice;
				return new Size(matrix.M11, matrix.M22);
			} else {
				return new Size(1, 1);
			}
		}
		
		/// <summary>
		/// Aligns <paramref name="value"/> on the next middle of a pixel.
		/// </summary>
		/// <param name="value">The value that should be aligned</param>
		/// <param name="pixelSize">The size of one pixel</param>
		public static double PixelAlign(double value, double pixelSize)
		{
			// 0 -> 0.5
			// 0.1 -> 0.5
			// 0.5 -> 0.5
			// 0.9 -> 0.5
			// 1 -> 1.5
			return pixelSize * (Math.Round((value / pixelSize) + 0.5) - 0.5);
		}
		
		/// <summary>
		/// Aligns the borders of rect on the middles of pixels.
		/// </summary>
		public static Rect PixelAlign(Rect rect, Size pixelSize)
		{
			rect.X = PixelAlign(rect.X, pixelSize.Width);
			rect.Y = PixelAlign(rect.Y, pixelSize.Height);
			rect.Width = Round(rect.Width, pixelSize.Width);
			rect.Height = Round(rect.Height, pixelSize.Height);
			return rect;
		}
		
		/// <summary>
		/// Rounds <paramref name="point"/> to whole number of pixels.
		/// </summary>
		public static Point Round(Point point, Size pixelSize)
		{
			return new Point(Round(point.X, pixelSize.Width), Round(point.Y, pixelSize.Height));
		}
		
		/// <summary>
		/// Rounds val to whole number of pixels.
		/// </summary>
		public static Rect Round(Rect rect, Size pixelSize)
		{
			return new Rect(Round(rect.X, pixelSize.Width), Round(rect.Y, pixelSize.Height),
			                Round(rect.Width, pixelSize.Width), Round(rect.Height, pixelSize.Height));
		}
		
		/// <summary>
		/// Rounds <paramref name="value"/> to a whole number of pixels.
		/// </summary>
		public static double Round(double value, double pixelSize)
		{
			return pixelSize * Math.Round(value / pixelSize);
		}
		
		/// <summary>
		/// Rounds <paramref name="value"/> to an whole odd number of pixels.
		/// </summary>
		public static double RoundToOdd(double value, double pixelSize)
		{
			return Round(value - pixelSize, pixelSize * 2) + pixelSize;
		}
	}
}
>(s.Length == 2) { newLineType = "\r\n"; } else if (text.GetCharAt(s.Offset) == '\n') { newLineType = "\n"; } else { newLineType = "\r"; } return s.Offset; } } /// <summary> /// Gets whether the specified string is a newline sequence. /// </summary> public static bool IsNewLine(string newLine) { return newLine == "\r\n" || newLine == "\n" || newLine == "\r"; } /// <summary> /// Normalizes all new lines in <paramref name="input"/> to be <paramref name="newLine"/>. /// </summary> public static string NormalizeNewLines(string input, string newLine) { if (input == null) return null; if (!IsNewLine(newLine)) throw new ArgumentException("newLine must be one of the known newline sequences"); SimpleSegment ds = NewLineFinder.NextNewLine(input, 0); if (ds == SimpleSegment.Invalid) // text does not contain any new lines return input; StringBuilder b = new StringBuilder(input.Length); int lastEndOffset = 0; do { b.Append(input, lastEndOffset, ds.Offset - lastEndOffset); b.Append(newLine); lastEndOffset = ds.EndOffset; ds = NewLineFinder.NextNewLine(input, lastEndOffset); } while (ds != SimpleSegment.Invalid); // remaining string (after last newline) b.Append(input, lastEndOffset, input.Length - lastEndOffset); return b.ToString(); } /// <summary> /// Gets the newline sequence used in the document at the specified line. /// </summary> public static string GetNewLineFromDocument(TextDocument document, int lineNumber) { DocumentLine line = document.GetLineByNumber(lineNumber); if (line.DelimiterLength == 0) { // at the end of the document, there's no line delimiter, so use the delimiter // from the previous line line = line.PreviousLine; if (line == null) return Environment.NewLine; } return document.GetText(line.Offset + line.Length, line.DelimiterLength); } } }