rt-thread-official/components/rtgui/common/framebuffer_driver.c

226 lines
5.1 KiB
C

#include <rtgui/rtgui_system.h>
#include <rtgui/driver.h>
#define GET_PIXEL(dst, x, y, type) \
(type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * ((dst)->bits_per_pixel/8))
static void _rgb565_set_pixel(rtgui_color_t *c, int x, int y)
{
*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565(*c);
}
static void _rgb565_get_pixel(rtgui_color_t *c, int x, int y)
{
rt_uint16_t pixel;
pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
/* get pixel from color */
*c = rtgui_color_from_565(pixel);
}
static void _rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
{
rt_ubase_t index;
rt_uint16_t pixel;
rt_uint16_t *pixel_ptr;
/* get pixel from color */
pixel = rtgui_color_to_565(*c);
/* get pixel pointer in framebuffer */
pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
for (index = x1; index < x2; index ++)
{
*pixel_ptr = pixel;
pixel_ptr ++;
}
}
static void _rgb565_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
{
rt_uint8_t *dst;
rt_uint16_t pixel;
rt_ubase_t index;
pixel = rtgui_color_to_565(*c);
dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
for (index = y1; index < y2; index ++)
{
*(rt_uint16_t*)dst = pixel;
dst += rtgui_graphic_get_device()->pitch;
}
}
static void _rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
{
*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565p(*c);
}
static void _rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
{
rt_uint16_t pixel;
pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
/* get pixel from color */
*c = rtgui_color_from_565p(pixel);
}
static void _rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
{
rt_ubase_t index;
rt_uint16_t pixel;
rt_uint16_t *pixel_ptr;
/* get pixel from color */
pixel = rtgui_color_to_565p(*c);
/* get pixel pointer in framebuffer */
pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
for (index = x1; index < x2; index ++)
{
*pixel_ptr = pixel;
pixel_ptr ++;
}
}
static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
{
rt_uint8_t *dst;
rt_uint16_t pixel;
rt_ubase_t index;
pixel = rtgui_color_to_565p(*c);
dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
for (index = y1; index < y2; index ++)
{
*(rt_uint16_t*)dst = pixel;
dst += rtgui_graphic_get_device()->pitch;
}
}
/* draw raw hline */
static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
{
rt_uint8_t *dst;
dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t);
rt_memcpy(dst, pixels, (x2 - x1) * (rtgui_graphic_get_device()->bits_per_pixel/8));
}
const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops =
{
_rgb565_set_pixel,
_rgb565_get_pixel,
_rgb565_draw_hline,
_rgb565_draw_vline,
framebuffer_draw_raw_hline,
};
const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops =
{
_rgb565p_set_pixel,
_rgb565p_get_pixel,
_rgb565p_draw_hline,
_rgb565p_draw_vline,
framebuffer_draw_raw_hline,
};
#define FRAMEBUFFER (rtgui_graphic_get_device()->framebuffer)
#define MONO_PIXEL(framebuffer, x, y) \
((rt_uint8_t**)(framebuffer))[y/8][x]
static void _mono_set_pixel(rtgui_color_t *c, int x, int y)
{
if (*c == white)
MONO_PIXEL(FRAMEBUFFER, x, y) &= ~(1 << (y%8));
else
MONO_PIXEL(FRAMEBUFFER, x, y) |= (1 << (y%8));
}
static void _mono_get_pixel(rtgui_color_t *c, int x, int y)
{
if (MONO_PIXEL(FRAMEBUFFER, x, y) & (1 << (y%8)))
*c = black;
else
*c = white;
}
static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
{
rt_ubase_t index;
if (*c == white)
for (index = x1; index < x2; index ++)
{
MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
}
else
for (index = x1; index < x2; index ++)
{
MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8));
}
}
static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
{
rt_ubase_t index;
if (*c == white)
for (index = y1; index < y2; index ++)
{
MONO_PIXEL(FRAMEBUFFER, x, index) &= ~(1 << (index%8));
}
else
for (index = y1; index < y2; index ++)
{
MONO_PIXEL(FRAMEBUFFER, x, index) |= (1 << (index%8));
}
}
/* draw raw hline */
static void _mono_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
{
rt_ubase_t index;
for (index = x1; index < x2; index ++)
{
if (pixels[index/8] && (1 << (index % 8)))
MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8));
else
MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
}
}
const struct rtgui_graphic_driver_ops _framebuffer_mono_ops =
{
_mono_set_pixel,
_mono_get_pixel,
_mono_draw_hline,
_mono_draw_vline,
_mono_draw_raw_hline,
};
const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_format)
{
switch (pixel_format)
{
case RTGRAPHIC_PIXEL_FORMAT_MONO:
return &_framebuffer_mono_ops;
case RTGRAPHIC_PIXEL_FORMAT_GRAY4:
break;
case RTGRAPHIC_PIXEL_FORMAT_GRAY16:
break;
case RTGRAPHIC_PIXEL_FORMAT_RGB565:
return &_framebuffer_rgb565_ops;
case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
return &_framebuffer_rgb565p_ops;
}
return RT_NULL;
}