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 */ /* 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 getDisplayHeight(void) { return u8g2_GetDisplayHeight(&u8g2); }
u8g2_uint_t getDisplayWidth(void) { return u8g2_GetDisplayWidth(&u8g2); } u8g2_uint_t getDisplayWidth(void) { return u8g2_GetDisplayWidth(&u8g2); }

View File

@ -82,6 +82,15 @@
*/ */
#define U8G2_WITH_ONE_PIXEL_OPTIMIZATION #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. The following macro enables the HVLine speed optimization.
@ -290,7 +299,7 @@ struct u8g2_struct
u8g2_uint_t buf_y0; u8g2_uint_t buf_y0;
u8g2_uint_t buf_y1; 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 width;
u8g2_uint_t height; 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_y0; /* upper edge of the buffer */
u8g2_uint_t user_y1; /* lower edge of the buffer (excluded) */ 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 */ /* information about the current font */
const uint8_t *font; /* current font for all text procedures */ const uint8_t *font; /* current font for all text procedures */
// removed: const u8g2_kerning_t *kerning; /* can be NULL */ // 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_decode_t font_decode; /* new font decode structure */
u8g2_font_info_t font_info; /* new font info 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; uint8_t font_height_mode;
int8_t font_ref_ascent; int8_t font_ref_ascent;
int8_t font_ref_descent; int8_t font_ref_descent;
@ -325,12 +348,6 @@ struct u8g2_struct
// the following variable should be renamed to is_buffer_auto_clear // 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() */ 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)) #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_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); void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);

View File

@ -45,6 +45,8 @@
#include "u8g2.h" #include "u8g2.h"
#include <assert.h> #include <assert.h>
/*==========================================================*/
/* intersection procedure */
/* /*
Description: 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 x,y Upper left position of the line within the pixel buffer
len length of the line in pixel, len must not be 0 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 */ /* clipping happens before the display rotation */
/* transform to pixel buffer coordinates */ /* transform to pixel buffer coordinates */
y -= u8g2->tile_curr_row*8; y -= u8g2->pixel_curr_row;
u8g2->ll_hvline(u8g2, x, y, len, dir); 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). */ /* Make a call to the callback function (e.g. u8g2_draw_l90_r0). */
/* The callback may rotate the hv line */ /* The callback may rotate the hv line */
/* after rotation this will call u8g2_draw_hv_line_4dir() */ /* after rotation this will call u8g2_draw_hv_line_4dir() */
if ( len != 0 )
{
/* convert to two directions */ #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
if ( len > 1 ) 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; if ( dir == 2 )
x++; {
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; if ( y < u8g2->user_y0 )
y++; 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);
} }
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);
}
} }
void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len) 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> #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). 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->is_auto_page_clear = 1;
u8g2->cb = u8g2_cb; 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->cb->update(u8g2);
u8g2_SetFontPosBaseline(u8g2); /* issue 195 */ 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) 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; u8g2_uint_t t;
t = u8g2->tile_buf_height; t = u8g2->tile_buf_height;
t *= 8; t *= 8;
u8g2->pixel_buf_height = t; u8g2->pixel_buf_height = t;
t = u8g2_GetU8x8(u8g2)->display_info->tile_width; t = display_info->tile_width;
#ifndef U8G2_16BIT #ifndef U8G2_16BIT
if ( t >= 32 ) if ( t >= 32 )
t = 31; t = 31;
@ -116,8 +144,8 @@ static void u8g2_update_dimension_common(u8g2_t *u8g2)
t = u8g2->tile_buf_height; t = u8g2->tile_buf_height;
/* handle the case, where the buffer is larger than the (remaining) part of the display */ /* 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 ) if ( t + u8g2->tile_curr_row > display_info->tile_height )
t = u8g2_GetU8x8(u8g2)->display_info->tile_height - u8g2->tile_curr_row; t = display_info->tile_height - u8g2->tile_curr_row;
t *= 8; t *= 8;
u8g2->buf_y0 = u8g2->pixel_curr_row; u8g2->buf_y0 = u8g2->pixel_curr_row;
@ -126,17 +154,47 @@ static void u8g2_update_dimension_common(u8g2_t *u8g2)
#ifdef U8G2_16BIT #ifdef U8G2_16BIT
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_width; u8g2->width = display_info->pixel_width;
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_height; u8g2->height = display_info->pixel_height;
#else #else
u8g2->width = 240; u8g2->width = 240;
if ( u8g2_GetU8x8(u8g2)->display_info->pixel_width <= 240 ) if ( display_info->pixel_width <= 240 )
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_width; u8g2->width = display_info->pixel_width;
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_height; u8g2->height = display_info->pixel_height;
#endif #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) void u8g2_update_dimension_r0(u8g2_t *u8g2)
{ {
u8g2_update_dimension_common(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_y0 = u8g2->buf_y0;
u8g2->user_y1 = u8g2->buf_y1; 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", // printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1); // 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_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (which is the real pixel width) */ 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", //printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1); // 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_y0 = u8g2->height - u8g2->buf_y1;
u8g2->user_y1 = u8g2->height - u8g2->buf_y0; 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", // printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1); // 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_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (pixel_width) */ 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", // printf("x0=%d x1=%d y0=%d y1=%d\n",
// u8g2->user_x0, u8g2->user_x1, u8g2->user_y0, u8g2->user_y1); // 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 8440 152 420 9012 2334 HelloWorld.elf
8422 8422
8470
8676
*/ */