issue #364, clip window support

This commit is contained in:
kraus 2018-10-27 22:44:42 +02:00
parent b6d9e4329a
commit f907d00a0e
5 changed files with 160 additions and 51 deletions

View File

@ -144,6 +144,12 @@ class U8G2 : public Print
/* u8g2 */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
void setMaxClipWindow(void) { u8g2_SetMaxClipWindow(&u8g2); }
void setClipWindow(u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1) {
u8g2_SetClipWindow(&u8g2, clip_x0, clip_y0, clip_x1, clip_y1 ); }
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
u8g2_uint_t getDisplayHeight(void) { return u8g2_GetDisplayHeight(&u8g2); }
u8g2_uint_t getDisplayWidth(void) { return u8g2_GetDisplayWidth(&u8g2); }

View File

@ -82,6 +82,15 @@
*/
#define U8G2_WITH_ONE_PIXEL_OPTIMIZATION
/*
Enable clip window support:
void u8g2_SetMaxClipWindow(u8g2_t *u8g2)
void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 )
Setting a clip window will restrict all drawing to this window.
Clip window support requires about 200 bytes flash memory on AVR systems
*/
//#define U8G2_WITH_CLIP_WINDOW_SUPPORT
/*
The following macro enables the HVLine speed optimization.
@ -290,7 +299,7 @@ struct u8g2_struct
u8g2_uint_t buf_y0;
u8g2_uint_t buf_y1;
/* display dimensions in pixel for the user, calculated in u8g2_update_dimension_common(), used in u8g2_draw_hv_line_2dir() */
/* display dimensions in pixel for the user, calculated in u8g2_update_dimension_common() */
u8g2_uint_t width;
u8g2_uint_t height;
@ -302,6 +311,15 @@ struct u8g2_struct
u8g2_uint_t user_y0; /* upper edge of the buffer */
u8g2_uint_t user_y1; /* lower edge of the buffer (excluded) */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
/* clip window */
u8g2_uint_t clip_x0; /* left corner of the clip window */
u8g2_uint_t clip_x1; /* right corner of the clip window (excluded) */
u8g2_uint_t clip_y0; /* upper edge of the clip window */
u8g2_uint_t clip_y1; /* lower edge of the clip window (excluded) */
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
/* information about the current font */
const uint8_t *font; /* current font for all text procedures */
// removed: const u8g2_kerning_t *kerning; /* can be NULL */
@ -311,6 +329,11 @@ struct u8g2_struct
u8g2_font_decode_t font_decode; /* new font decode structure */
u8g2_font_info_t font_info; /* new font info structure */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
/* 1 of there is an intersection between user_?? and clip_?? box */
uint8_t is_page_clip_window_intersection;
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
uint8_t font_height_mode;
int8_t font_ref_ascent;
int8_t font_ref_descent;
@ -325,12 +348,6 @@ struct u8g2_struct
// the following variable should be renamed to is_buffer_auto_clear
uint8_t is_auto_page_clear; /* set to 0 to disable automatic clear of the buffer in firstPage() and nextPage() */
// removed, there is now the new index table
//#ifdef __unix__
// uint16_t last_unicode;
// const uint8_t *last_font_data;
//#endif
};
#define u8g2_GetU8x8(u8g2) ((u8x8_t *)(u8g2))
@ -399,6 +416,9 @@ extern const u8g2_cb_t u8g2_cb_mirror;
*/
void u8g2_SetMaxClipWindow(u8g2_t *u8g2);
void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 );
void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_draw_ll_hvline_cb ll_hvline_cb, const u8g2_cb_t *u8g2_cb);
void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);

View File

@ -45,6 +45,8 @@
#include "u8g2.h"
#include <assert.h>
/*==========================================================*/
/* intersection procedure */
/*
Description:
@ -114,6 +116,10 @@ static uint8_t u8g2_clip_intersection2(u8g2_uint_t *ap, u8g2_uint_t *len, u8g2_u
}
/*==========================================================*/
/* draw procedures */
/*
x,y Upper left position of the line within the pixel buffer
len length of the line in pixel, len must not be 0
@ -129,7 +135,7 @@ void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uin
/* clipping happens before the display rotation */
/* transform to pixel buffer coordinates */
y -= u8g2->tile_curr_row*8;
y -= u8g2->pixel_curr_row;
u8g2->ll_hvline(u8g2, x, y, len, dir);
}
@ -146,48 +152,52 @@ void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len
/* Make a call to the callback function (e.g. u8g2_draw_l90_r0). */
/* The callback may rotate the hv line */
/* after rotation this will call u8g2_draw_hv_line_4dir() */
if ( len != 0 )
{
/* convert to two directions */
if ( len > 1 )
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
if ( u8g2->is_page_clip_window_intersection != 0 )
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
if ( len != 0 )
{
if ( dir == 2 )
/* convert to two directions */
if ( len > 1 )
{
x -= len;
x++;
if ( dir == 2 )
{
x -= len;
x++;
}
else if ( dir == 3 )
{
y -= len;
y++;
}
}
else if ( dir == 3 )
dir &= 1;
/* clip against the user window */
if ( dir == 0 )
{
y -= len;
y++;
if ( y < u8g2->user_y0 )
return;
if ( y >= u8g2->user_y1 )
return;
if ( u8g2_clip_intersection2(&x, &len, u8g2->user_x0, u8g2->user_x1) == 0 )
return;
}
else
{
if ( x < u8g2->user_x0 )
return;
if ( x >= u8g2->user_x1 )
return;
if ( u8g2_clip_intersection2(&y, &len, u8g2->user_y0, u8g2->user_y1) == 0 )
return;
}
}
dir &= 1;
/* clip against the user window */
if ( dir == 0 )
{
if ( y < u8g2->user_y0 )
return;
if ( y >= u8g2->user_y1 )
return;
if ( u8g2_clip_intersection2(&x, &len, u8g2->user_x0, u8g2->user_x1) == 0 )
return;
}
else
{
if ( x < u8g2->user_x0 )
return;
if ( x >= u8g2->user_x1 )
return;
if ( u8g2_clip_intersection2(&y, &len, u8g2->user_y0, u8g2->user_y1) == 0 )
return;
}
u8g2->cb->draw_l90(u8g2, x, y, len, dir);
}
u8g2->cb->draw_l90(u8g2, x, y, len, dir);
}
}
void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)

View File

@ -38,6 +38,30 @@
#include <assert.h>
/*============================================*/
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
void u8g2_SetMaxClipWindow(u8g2_t *u8g2)
{
u8g2->clip_x0 = 0;
u8g2->clip_y0 = 0;
u8g2->clip_x1 = (u8g2_uint_t)~(u8g2_uint_t)0;
u8g2->clip_y1 = (u8g2_uint_t)~(u8g2_uint_t)0;
}
#endif
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 )
{
u8g2->clip_x0 = clip_x0;
u8g2->clip_y0 = clip_y0;
u8g2->clip_x1 = clip_x1;
u8g2->clip_y1 = clip_y1;
u8g2->cb->update(u8g2);
}
#endif
/*============================================*/
/*
This procedure is called after setting up the display (u8x8 structure).
@ -64,6 +88,9 @@ void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_
u8g2->is_auto_page_clear = 1;
u8g2->cb = u8g2_cb;
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_SetMaxClipWindow(u8g2); /* assign a clip window before the update() callback is called */
#endif
u8g2->cb->update(u8g2);
u8g2_SetFontPosBaseline(u8g2); /* issue 195 */
@ -96,13 +123,14 @@ void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
static void u8g2_update_dimension_common(u8g2_t *u8g2)
{
const u8x8_display_info_t *display_info = u8g2_GetU8x8(u8g2)->display_info;
u8g2_uint_t t;
t = u8g2->tile_buf_height;
t *= 8;
u8g2->pixel_buf_height = t;
t = u8g2_GetU8x8(u8g2)->display_info->tile_width;
t = display_info->tile_width;
#ifndef U8G2_16BIT
if ( t >= 32 )
t = 31;
@ -116,8 +144,8 @@ static void u8g2_update_dimension_common(u8g2_t *u8g2)
t = u8g2->tile_buf_height;
/* handle the case, where the buffer is larger than the (remaining) part of the display */
if ( t + u8g2->tile_curr_row > u8g2_GetU8x8(u8g2)->display_info->tile_height )
t = u8g2_GetU8x8(u8g2)->display_info->tile_height - u8g2->tile_curr_row;
if ( t + u8g2->tile_curr_row > display_info->tile_height )
t = display_info->tile_height - u8g2->tile_curr_row;
t *= 8;
u8g2->buf_y0 = u8g2->pixel_curr_row;
@ -126,17 +154,47 @@ static void u8g2_update_dimension_common(u8g2_t *u8g2)
#ifdef U8G2_16BIT
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
u8g2->width = display_info->pixel_width;
u8g2->height = display_info->pixel_height;
#else
u8g2->width = 240;
if ( u8g2_GetU8x8(u8g2)->display_info->pixel_width <= 240 )
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
if ( display_info->pixel_width <= 240 )
u8g2->width = display_info->pixel_width;
u8g2->height = display_info->pixel_height;
#endif
}
/*==========================================================*/
/* apply clip window */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
static void u8g2_apply_clip_window(u8g2_t *u8g2)
{
/* check aganst the current user_??? window */
if ( u8g2_IsIntersection(u8g2, u8g2->clip_x0, u8g2->clip_y0, u8g2->clip_x1, u8g2->clip_y1) == 0 )
{
u8g2->is_page_clip_window_intersection = 0;
}
else
{
u8g2->is_page_clip_window_intersection = 1;
if ( u8g2->user_x0 < u8g2->clip_x0 )
u8g2->user_x0 = u8g2->clip_x0;
if ( u8g2->user_x1 > u8g2->clip_x1 )
u8g2->user_x1 = u8g2->clip_x1;
if ( u8g2->user_y0 < u8g2->clip_y0 )
u8g2->user_y0 = u8g2->clip_y0;
if ( u8g2->user_y1 > u8g2->clip_y1 )
u8g2->user_y1 = u8g2->clip_y1;
}
}
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
/*==========================================================*/
void u8g2_update_dimension_r0(u8g2_t *u8g2)
{
u8g2_update_dimension_common(u8g2);
@ -147,6 +205,10 @@ void u8g2_update_dimension_r0(u8g2_t *u8g2)
u8g2->user_y0 = u8g2->buf_y0;
u8g2->user_y1 = u8g2->buf_y1;
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
// printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1);
}
@ -164,6 +226,9 @@ void u8g2_update_dimension_r1(u8g2_t *u8g2)
u8g2->user_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (which is the real pixel width) */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
//printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1);
}
@ -182,6 +247,9 @@ void u8g2_update_dimension_r2(u8g2_t *u8g2)
u8g2->user_y0 = u8g2->height - u8g2->buf_y1;
u8g2->user_y1 = u8g2->height - u8g2->buf_y0;
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
// printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1);
}
@ -203,6 +271,9 @@ void u8g2_update_dimension_r3(u8g2_t *u8g2)
u8g2->user_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (pixel_width) */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
// printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1);
}

View File

@ -38,6 +38,8 @@
8440 152 420 9012 2334 HelloWorld.elf
8422
8470
8676
*/