src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts/DecorationsOverviewRuler/_render
class DecorationsOverviewRuler:	private _render(): void {
		const backgroundColor = this._settings.backgroundColor;
		if (this._settings.overviewRulerLanes === 0) {
			// overview ruler is off
			this._domNode.setBackgroundColor(backgroundColor ? Color.Format.CSS.formatHexA(backgroundColor) : '');
			this._domNode.setDisplay('none');
			return;
		}
		this._domNode.setDisplay('block');
		const canvasWidth = this._settings.canvasWidth;
		const canvasHeight = this._settings.canvasHeight;
		const lineHeight = this._settings.lineHeight;
		const viewLayout = this._context.viewLayout;
		const outerHeight = this._context.viewLayout.getScrollHeight();
		const heightRatio = canvasHeight / outerHeight;
		const decorations = this._context.viewModel.getAllOverviewRulerDecorations(this._context.theme);

		const minDecorationHeight = (Constants.MIN_DECORATION_HEIGHT * this._settings.pixelRatio) | 0;
		const halfMinDecorationHeight = (minDecorationHeight / 2) | 0;

		const canvasCtx = this._domNode.domNode.getContext('2d')!;
		if (backgroundColor) {
			if (backgroundColor.isOpaque()) {
				// We have a background color which is opaque, we can just paint the entire surface with it
				canvasCtx.fillStyle = Color.Format.CSS.formatHexA(backgroundColor);
				canvasCtx.fillRect(0, 0, canvasWidth, canvasHeight);
			} else {
				// We have a background color which is transparent, we need to first clear the surface and
				// then fill it
				canvasCtx.clearRect(0, 0, canvasWidth, canvasHeight);
				canvasCtx.fillStyle = Color.Format.CSS.formatHexA(backgroundColor);
				canvasCtx.fillRect(0, 0, canvasWidth, canvasHeight);
			}
		} else {
			// We don't have a background color
			canvasCtx.clearRect(0, 0, canvasWidth, canvasHeight);
		}

		const x = this._settings.x;
		const w = this._settings.w;

		decorations.sort(OverviewRulerDecorationsGroup.cmp);

		for (const decorationGroup of decorations) {
			const color = decorationGroup.color;
			const decorationGroupData = decorationGroup.data;

			canvasCtx.fillStyle = color;

			let prevLane = 0;
			let prevY1 = 0;
			let prevY2 = 0;
			for (let i = 0, len = decorationGroupData.length / 3; i < len; i++) {
				const lane = decorationGroupData[3 * i];
				const startLineNumber = decorationGroupData[3 * i + 1];
				const endLineNumber = decorationGroupData[3 * i + 2];

				let y1 = (viewLayout.getVerticalOffsetForLineNumber(startLineNumber) * heightRatio) | 0;
				let y2 = ((viewLayout.getVerticalOffsetForLineNumber(endLineNumber) + lineHeight) * heightRatio) | 0;
				const height = y2 - y1;
				if (height < minDecorationHeight) {
					let yCenter = ((y1 + y2) / 2) | 0;
					if (yCenter < halfMinDecorationHeight) {
						yCenter = halfMinDecorationHeight;
					} else if (yCenter + halfMinDecorationHeight > canvasHeight) {
						yCenter = canvasHeight - halfMinDecorationHeight;
					}
					y1 = yCenter - halfMinDecorationHeight;
					y2 = yCenter + halfMinDecorationHeight;
				}

				if (y1 > prevY2 + 1 || lane !== prevLane) {
					// flush prev
					if (i !== 0) {
						canvasCtx.fillRect(x[prevLane], prevY1, w[prevLane], prevY2 - prevY1);
					}
					prevLane = lane;
					prevY1 = y1;
					prevY2 = y2;
				} else {
					// merge into prev
					if (y2 > prevY2) {
						prevY2 = y2;
					}
				}
			}
			canvasCtx.fillRect(x[prevLane], prevY1, w[prevLane], prevY2 - prevY1);
		}

		// Draw cursors
		if (!this._settings.hideCursor && this._settings.cursorColor) {
			const cursorHeight = (2 * this._settings.pixelRatio) | 0;
			const halfCursorHeight = (cursorHeight / 2) | 0;
			const cursorX = this._settings.x[OverviewRulerLane.Full];
			const cursorW = this._settings.w[OverviewRulerLane.Full];
			canvasCtx.fillStyle = this._settings.cursorColor;

			let prevY1 = -100;
			let prevY2 = -100;
			for (let i = 0, len = this._cursorPositions.length; i < len; i++) {
				const cursor = this._cursorPositions[i];

				let yCenter = (viewLayout.getVerticalOffsetForLineNumber(cursor.lineNumber) * heightRatio) | 0;
				if (yCenter < halfCursorHeight) {
					yCenter = halfCursorHeight;
				} else if (yCenter + halfCursorHeight > canvasHeight) {
					yCenter = canvasHeight - halfCursorHeight;
				}
				const y1 = yCenter - halfCursorHeight;
				const y2 = y1 + cursorHeight;

				if (y1 > prevY2 + 1) {
					// flush prev
					if (i !== 0) {
						canvasCtx.fillRect(cursorX, prevY1, cursorW, prevY2 - prevY1);
					}
					prevY1 = y1;
					prevY2 = y2;
				} else {
					// merge into prev
					if (y2 > prevY2) {
						prevY2 = y2;
					}
				}
			}
			canvasCtx.fillRect(cursorX, prevY1, cursorW, prevY2 - prevY1);
		}

		if (this._settings.renderBorder && this._settings.borderColor && this._settings.overviewRulerLanes > 0) {
			canvasCtx.beginPath();
			canvasCtx.lineWidth = 1;
			canvasCtx.strokeStyle = this._settings.borderColor;
			canvasCtx.moveTo(0, 0);
			canvasCtx.lineTo(0, canvasHeight);
			canvasCtx.stroke();

			canvasCtx.moveTo(0, 0);
			canvasCtx.lineTo(canvasWidth, 0);
			canvasCtx.stroke();
		}
	}