1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-23 16:25:26 +03:00

[CANVAS] Fix leftover pixels when drawing the home direction arrow

Since the arrow is taller than the width of a grid slow, it overflows
the slot a bit when it's rotated by 90º. Also, simplify the algorithm
for drawing it a bit so it transmits a bit less data per redrawing.
This commit is contained in:
Alberto García Hierro 2020-07-07 21:09:53 +01:00
parent 4f3e7a3d5e
commit 59f160f21f
5 changed files with 26 additions and 20 deletions

View file

@ -1310,7 +1310,7 @@ static bool osdDrawSingleElement(uint8_t item)
else
{
int homeDirection = GPS_directionToHome - DECIDEGREES_TO_DEGREES(osdGetHeading());
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX, elemPosY), homeDirection, true);
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX, elemPosY), homeDirection);
}
} else {
// No home or no fix or unknown heading, blink.

View file

@ -120,32 +120,41 @@ void osdCanvasDrawVario(displayPort_t *display, displayCanvas_t *canvas, const o
prev = zvel;
}
void osdCanvasDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees, bool eraseBefore)
void osdCanvasDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees)
{
UNUSED(display);
const int top = 6;
const int topInset = -2;
const int bottom = -6;
const int width = 5;
// Since grid slots are not square, when we rotate the arrow
// it overflows horizontally a bit. Making a square-ish arrow
// doesn't look good, so it's better to overstep the grid slot
// boundaries a bit and then clean after ourselves.
const int overflow = 3;
int px;
int py;
osdDrawPointGetPixels(&px, &py, display, canvas, p);
displayCanvasClipToRect(canvas, px, py, canvas->gridElementWidth, canvas->gridElementHeight);
if (eraseBefore) {
displayCanvasSetFillColor(canvas, DISPLAY_CANVAS_COLOR_TRANSPARENT);
displayCanvasFillRect(canvas, px, py, canvas->gridElementWidth, canvas->gridElementHeight);
}
displayCanvasClearRect(canvas, px - overflow, py, canvas->gridElementWidth + overflow * 2, canvas->gridElementHeight);
displayCanvasSetFillColor(canvas, DISPLAY_CANVAS_COLOR_WHITE);
displayCanvasSetStrokeColor(canvas, DISPLAY_CANVAS_COLOR_BLACK);
displayCanvasCtmRotate(canvas, -DEGREES_TO_RADIANS(180 + degrees));
displayCanvasCtmTranslate(canvas, px + canvas->gridElementWidth / 2, py + canvas->gridElementHeight / 2);
displayCanvasFillStrokeTriangle(canvas, 0, 6, 5, -6, -5, -6);
// Main triangle
displayCanvasFillStrokeTriangle(canvas, 0, top, width, bottom, -width, bottom);
// Inset triangle
displayCanvasSetFillColor(canvas, DISPLAY_CANVAS_COLOR_TRANSPARENT);
displayCanvasFillStrokeTriangle(canvas, 0, -2, 6, -7, -6, -7);
displayCanvasMoveToPoint(canvas, 6, -7);
displayCanvasSetStrokeColor(canvas, DISPLAY_CANVAS_COLOR_TRANSPARENT);
displayCanvasStrokeLineToPoint(canvas, -6, -7);
displayCanvasFillTriangle(canvas, 0, topInset, width + 1, bottom - 1, -width, bottom - 1);
// Draw bottom strokes of the triangle
displayCanvasMoveToPoint(canvas, -width, bottom - 1);
displayCanvasStrokeLineToPoint(canvas, 0, topInset);
displayCanvasStrokeLineToPoint(canvas, width, bottom - 1);
}
static void osdDrawArtificialHorizonLevelLine(displayCanvas_t *canvas, int width, int pos, int margin)

View file

@ -33,7 +33,7 @@ typedef struct displayCanvas_s displayCanvas_t;
typedef struct osdDrawPoint_s osdDrawPoint_t;
void osdCanvasDrawVario(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float zvel);
void osdCanvasDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees, bool eraseBefore);
void osdCanvasDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees);
void osdCanvasDrawArtificialHorizon(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float pitchAngle, float rollAngle);
void osdCanvasDrawHeadingGraph(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, int heading);
bool osdCanvasDrawSidebars(displayPort_t *display, displayCanvas_t *canvas);

View file

@ -88,17 +88,14 @@ void osdDrawVario(displayPort_t *display, displayCanvas_t *canvas, const osdDraw
#endif
}
void osdDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees, bool eraseBefore)
void osdDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees)
{
#if !defined(USE_CANVAS)
UNUSED(eraseBefore);
#endif
uint8_t gx;
uint8_t gy;
#if defined(USE_CANVAS)
if (canvas) {
osdCanvasDrawDirArrow(display, canvas, p, degrees, eraseBefore);
osdCanvasDrawDirArrow(display, canvas, p, degrees);
} else {
#endif
osdDrawPointGetGrid(&gx, &gy, display, canvas, p);

View file

@ -76,7 +76,7 @@ void osdDrawVario(displayPort_t *display, displayCanvas_t *canvas, const osdDraw
// Draws an arrow at the given point, where 0 degrees points to the top of the viewport and
// positive angles result in clockwise rotation. If eraseBefore is true, the rect surrouing
// the arrow will be erased first (need for e.g. the home arrow, since it uses multiple symbols)
void osdDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees, bool eraseBefore);
void osdDrawDirArrow(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float degrees);
void osdDrawArtificialHorizon(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float rollAngle, float pitchAngle);
// Draws a heading graph with heading given as 0.1 degree steps i.e. [0, 3600). It uses 9 horizontal
// grid slots.