ER ev3_lcd_draw_line()

in ev3-api/src/ev3api_lcd.c [114:195]


ER ev3_lcd_draw_line(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
	// TODO: refactor this
#define SOLID (0)
#define setPixel(x,y) bitmap_set_pixel(lcd_screen, (x), (y), true)

	// From LeJOS
	int32_t transY = 0, transX = 0;
	int32_t style = SOLID;

	// Uses Bresenham's line algorithm
	y0 += transY;
	y1 += transY;
	x0 += transX;
	x1 += transX;
	int32_t dy = y1 - y0;
	int32_t dx = x1 - x0;
	int32_t stepx, stepy;
	bool_t skip = false;
	if (style == SOLID && (dx == 0 || dy == 0)) {
		// Special case horizontal and vertical lines
		if (dx <= 0) {
			x0 = x1;
			dx = -dx;
		}
		if (dy <= 0) {
			y0 = y1;
			dy = -dy;
		}
#if 1 // Our version
		bitmap_bitblt(NULL, x0, y0, lcd_screen, x0, y0, dx + 1, dy + 1, ROP_SET);
#else // LeJOS
		bitBlt(imageBuf, width, height, x0, y0, imageBuf, width, height, x0, y0,
				dx + 1, dy + 1, (rgbColor == BLACK ? ROP_SET : ROP_CLEAR));
#endif
		return E_OK;
	}
	if (dy < 0) {
		dy = -dy;
		stepy = -1;
	} else {
		stepy = 1;
	}
	if (dx < 0) {
		dx = -dx;
		stepx = -1;
	} else {
		stepx = 1;
	}
	dy <<= 1; // dy is now 2*dy
	dx <<= 1; // dx is now 2*dx

	setPixel(x0, y0);
	if (dx > dy) {
		int32_t fraction = dy - (dx >> 1);  // same as 2*dy - dx
		while (x0 != x1) {
			if (fraction >= 0) {
				y0 += stepy;
				fraction -= dx; // same as fraction -= 2*dx
			}
			x0 += stepx;
			fraction += dy; // same as fraction -= 2*dy
			if ((style == SOLID) || !skip)
				setPixel(x0, y0);
			skip = !skip;
		}
	} else {
		int32_t fraction = dx - (dy >> 1);
		while (y0 != y1) {
			if (fraction >= 0) {
				x0 += stepx;
				fraction -= dy;
			}
			y0 += stepy;
			fraction += dx;
			if ((style == SOLID) || !skip)
				setPixel(x0, y0);
			skip = !skip;
		}
	}

	return E_OK;
}