Mono.TextEditor.TextViewMargin.InnerDecorateTabsAndSpaces C# (CSharp) Method

InnerDecorateTabsAndSpaces() private method

private InnerDecorateTabsAndSpaces ( Cairo ctx, LayoutWrapper layout, int offset, double x, double y, int selectionStart, int selectionEnd, char spaceOrTab ) : void
ctx Cairo
layout LayoutWrapper
offset int
x double
y double
selectionStart int
selectionEnd int
spaceOrTab char
return void
		void InnerDecorateTabsAndSpaces (Cairo.Context ctx, LayoutWrapper layout, int offset, double x, double y, int selectionStart, int selectionEnd, char spaceOrTab)
		{
			var chars = layout.LineChars;
			if (Array.IndexOf (chars, spaceOrTab) == -1)
				return;

			uint curIndex = 0, byteIndex = 0;
			bool first = true, oldSelected = false;
			var curchunk = layout.Chunks != null ? layout.Chunks.FirstOrDefault () : null;

			var dotThickness = textEditor.Options.Zoom * 2;
			var textEditorWidth = textEditor.Allocation.Width;

			//Get 1st visible character index from left based on HAdjustment
			int index, trailing;
			layout.Layout.XyToIndex ((int)textEditor.HAdjustment.Value, 0, out index, out trailing);

			double ypos;
			if (spaceOrTab == ' ') {
				ypos = System.Math.Floor (y + (LineHeight - dotThickness) / 2);
			} else {
				ypos = 0.5 + System.Math.Floor (y + LineHeight / 2);
			}

			var showOnlySelected = textEditor.Options.ShowWhitespaces != ShowWhitespaces.Always;

			var lastColor = new Cairo.Color ();
			bool firstDraw = true;
			var foregroundColor = ColorStyle.PlainText.Foreground;

			int lastIndex = -1;
			int lastPosX = 0;

			for (int i = index; i < chars.Length; i++) {
				if (spaceOrTab != chars [i])
					continue;

				bool selected = selectionStart <= offset + i && offset + i < selectionEnd;
				if (first || oldSelected != selected) {
					first = false;
					oldSelected = selected;
				}

				if (showOnlySelected && !selected)
					continue;
				int line, posX;
				if (lastIndex == i) {
					posX = lastPosX;
				} else {
					layout.Layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i, ref curIndex, ref byteIndex), false, out line, out posX);
				}
				double xpos = x + posX / Pango.Scale.PangoScale;
				if (xpos > textEditorWidth)
					break;
				layout.Layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i + 1, ref curIndex, ref byteIndex), false, out line, out posX);
				lastPosX = posX;
				lastIndex = i + 1;
				double xpos2 = x + posX / Pango.Scale.PangoScale;
				var col = new Cairo.Color (0, 0, 0);
				if (SelectionColor.TransparentForeground) {
					while (curchunk != null && curchunk.EndOffset < offset + i)
						curchunk = curchunk.Next;
					if (curchunk != null && curchunk.SpanStack.Count > 0 && curchunk.SpanStack.Peek ().Color != "Plain Text") {
						var chunkStyle = ColorStyle.GetChunkStyle (curchunk.SpanStack.Peek ().Color);
						if (chunkStyle != null)
							col = ColorStyle.GetForeground (chunkStyle);
					} else {
						col = foregroundColor;
					}
				} else {
					col = selected ? SelectionColor.Foreground : foregroundColor;
				}

				if (firstDraw || (lastColor.R != col.R && lastColor.G != col.G && lastColor.B != col.B)) {
					ctx.SetSourceRGBA (col.R, col.G, col.B, whitespaceMarkerAlpha);
					lastColor = col;
					firstDraw = false;
				}

				if (spaceOrTab == ' ') {
					ctx.Rectangle (xpos + (xpos2 - xpos - dotThickness) / 2, ypos, dotThickness, dotThickness);
				} else {
					ctx.MoveTo (0.5 + xpos, ypos);
					ctx.LineTo (0.5 + xpos2 - charWidth / 2, ypos);
				}
			}
			if (!firstDraw) {//Atleast one draw was called
				if (spaceOrTab == ' ') {
					ctx.Fill ();
				} else {
					ctx.Stroke ();
				}
			}
		}