Beispiel #1
0
static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
{
	register rt_base_t index;
	rtgui_widget_t *owner;

	if (self == RT_NULL) return;

	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;

	/* convert logic to device */
	x1 = x1 + owner->extent.x1;
	x2 = x2 + owner->extent.x1;
	if (x1 > x2) _int_swap(x1, x2);
	y  = y + owner->extent.y1;

	if (rtgui_region_is_flat(&(owner->clip)) == RT_EOK)
	{
		rtgui_rect_t* prect;
		int offset = 0;
		prect = &(owner->clip.extents);

		/* calculate vline intersect */
		if (prect->y1 > y  || prect->y2 <= y ) return;
		if (prect->x2 <= x1 || prect->x1 > x2) return;

		if (prect->x1 > x1) x1 = prect->x1;
		if (prect->x2 < x2) x2 = prect->x2;

		/* patch note: 
		 * We need to adjust the offset when update widget clip!
		 * Of course at ordinary times for 0. General */
		offset = owner->clip.extents.x1 - owner->extent.x1;
		offset = offset * hw_driver->bits_per_pixel/8;
		/* draw hline */
		hw_driver->ops->draw_raw_hline(line_data+offset, x1, x2, y);
	}
	else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
	{
		rtgui_rect_t* prect;
		register rt_base_t draw_x1, draw_x2;

		prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
		draw_x1 = x1;
		draw_x2 = x2;

		/* calculate hline clip */
		if (prect->y1 > y  || prect->y2 <= y ) continue;
		if (prect->x2 <= x1 || prect->x1 > x2) continue;

		if (prect->x1 > x1) draw_x1 = prect->x1;
		if (prect->x2 < x2) draw_x2 = prect->x2;

		/* draw hline */
		hw_driver->ops->draw_raw_hline(line_data + (draw_x1 - x1) * hw_driver->bits_per_pixel/8, draw_x1, draw_x2, y);
	}
}
Beispiel #2
0
/*
 * draw a logic horizontal line on device
 */
static void rtgui_dc_client_draw_hline(struct rtgui_dc* self, int x1, int x2, int y)
{
	register rt_base_t index;
	rtgui_widget_t *owner;

	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;

	/* convert logic to device */
	x1 = x1 + owner->extent.x1;
	x2 = x2 + owner->extent.x1;
	if (x1 > x2) _int_swap(x1, x2);
	y  = y + owner->extent.y1;

	if (owner->clip.data == RT_NULL)
	{
		rtgui_rect_t* prect;

		prect = &(owner->clip.extents);

		/* calculate vline intersect */
		if (prect->y1 > y  || prect->y2 <= y ) return;
		if (prect->x2 <= x1 || prect->x1 > x2) return;

		if (prect->x1 > x1) x1 = prect->x1;
		if (prect->x2 < x2) x2 = prect->x2;

		/* draw hline */
		hw_driver->ops->draw_hline(&(owner->gc.foreground), x1, x2, y);
	}
	else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
	{
		rtgui_rect_t* prect;
		register rt_base_t draw_x1, draw_x2;

		prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
		draw_x1 = x1;
		draw_x2 = x2;

		/* calculate hline clip */
		if (prect->y1 > y  || prect->y2 <= y ) continue;
		if (prect->x2 <= x1 || prect->x1 > x2) continue;

		if (prect->x1 > x1) draw_x1 = prect->x1;
		if (prect->x2 < x2) draw_x2 = prect->x2;

		/* draw hline */
		hw_driver->ops->draw_hline(&(owner->gc.foreground), draw_x1, draw_x2, y);
	}
}
Beispiel #3
0
/*
 * draw a logic vertical line on device
 */
static void rtgui_dc_client_draw_vline(struct rtgui_dc* self, int x, int y1, int y2)
{
	register rt_base_t index;
	rtgui_widget_t *owner;

	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;

	x  = x + owner->extent.x1;
	y1 = y1 + owner->extent.y1;
	y2 = y2 + owner->extent.y1;
	if (y1 > y2) _int_swap(y1, y2);

	if (owner->clip.data == RT_NULL)
	{
		rtgui_rect_t* prect;

		prect = &(owner->clip.extents);

		/* calculate vline intersect */
		if (prect->x1 > x   || prect->x2 <= x) return;
		if (prect->y2 <= y1 || prect->y1 > y2) return;

		if (prect->y1 > y1) y1 = prect->y1;
		if (prect->y2 < y2) y2 = prect->y2;

		/* draw vline */
		hw_driver->ops->draw_vline(&(owner->gc.foreground), x, y1, y2);
	}
	else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
	{
		rtgui_rect_t* prect;
		register rt_base_t draw_y1, draw_y2;

		prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
		draw_y1 = y1;
		draw_y2 = y2;

		/* calculate vline clip */
		if (prect->x1 > x   || prect->x2 <= x) continue;
		if (prect->y2 <= y1 || prect->y1 > y2) continue;

		if (prect->y1 > y1) draw_y1 = prect->y1;
		if (prect->y2 < y2) draw_y2 = prect->y2;

		/* draw vline */
		hw_driver->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2);
	}
}
Beispiel #4
0
/* blit a dc to another dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
                                 struct rtgui_point *dc_pt,
                                 struct rtgui_dc *dest,
                                 rtgui_rect_t *rect)
{
    int pitch;
    rt_uint16_t rect_width, rect_height;
    struct rtgui_rect _rect, *dest_rect;
    struct rtgui_point dc_point;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    if (rtgui_dc_get_visible(dest) == RT_FALSE)
        return;

    /* use the (0,0) origin point */
    if (dc_pt == RT_NULL)
        dc_point = rtgui_empty_point;
    else
    {
        dc_point = *dc_pt;
    }

    rtgui_dc_get_rect(dest, &_rect);
    /* use the rect of dest dc */
    if (rect == RT_NULL)
    {
        dest_rect = &_rect;
    }
    else
    {
        dest_rect = rect;
        if (dest_rect->x1 >= _rect.x2 || dest_rect->y1 >= _rect.y2)
            return;
        if (dest_rect->x1 < 0)
        {
            if (-dest_rect->x1 >= dc->width)
                return;
            dc_point.x += -dest_rect->x1;
            dest_rect->x1 = 0;
        }
        if (dest_rect->y1 < 0)
        {
            if (-dest_rect->y1 >= dc->height)
                return;
            dc_point.y += -dest_rect->y1;
            dest_rect->y1 = 0;
        }
        if (dest_rect->x2 > _rect.x2)
            dest_rect->x2 = _rect.x2;
        if (dest_rect->y2 > _rect.y2)
            dest_rect->y2 = _rect.y2;
    }

    if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return;
    if (dc_point.x >= dc->width || dc_point.y >= dc->height) return;

    /* get the minimal width and height */
    rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
    rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);

    if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
    {
        int index;
        rt_uint8_t *line_ptr, *pixels;
        rtgui_blit_line_func blit_line;
        struct rtgui_graphic_driver *hw_driver;

        hw_driver = rtgui_graphic_driver_get_default();
        /* prepare pixel line */
        pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);

        if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
        {
            /* use rtgui_blit */

            struct rtgui_blit_info info = { 0 };
            struct rtgui_widget *owner;

            if (self->type == RTGUI_DC_BUFFER)
                info.a = dc->pixel_alpha;
            else
                info.a = 255;

            /* blit source */
            info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
            info.src_fmt = dc->pixel_format;
            info.src_h = rect_height;
            info.src_w = rect_width;
            info.src_pitch = dc->pitch;
            info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

            owner = ((struct rtgui_dc_hw*)dest)->owner;

            /* blit destination */
            info.dst = (rt_uint8_t*)hw_driver->framebuffer;
            info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
                       (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
            info.dst_fmt = hw_driver->pixel_format;
            info.dst_h = rect_height;
            info.dst_w = rect_width;
            info.dst_pitch = hw_driver->pitch;
            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);

            rtgui_blit(&info);
        }
        else if (dest->type == RTGUI_DC_CLIENT&& hw_driver->framebuffer != RT_NULL)
        {
            /* use rtgui_blit */
            rt_uint8_t bpp, hw_bpp;
            struct rtgui_blit_info info = { 0 };
            struct rtgui_widget *owner;
            struct rtgui_region dest_region;
            struct rtgui_rect dest_extent;
            int num_rects;
            struct rtgui_rect *rects;

            /* get owner */
            owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type);

            dest_extent = *dest_rect;
            rtgui_widget_rect_to_device(owner, &dest_extent);

            rtgui_region_init_with_extents(&dest_region, &dest_extent);
            rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent);
            bpp = rtgui_color_get_bpp(dc->pixel_format);
            hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);

            num_rects = rtgui_region_num_rects(&dest_region);
            rects = rtgui_region_rects(&dest_region);

            /* common info */
            if (self->type == RTGUI_DC_BUFFER)
                info.a = dc->pixel_alpha;
            else
                info.a = 255;
            info.src_fmt = dc->pixel_format;
            info.src_pitch = dc->pitch;

            info.dst_fmt = hw_driver->pixel_format;
            info.dst_pitch = hw_driver->pitch;

            for (index = 0; index < num_rects; index ++)
            {
                struct rtgui_rect *r = &rects[index];

                /* blit source */
                info.src = _dc_get_pixel(dc, dc_point.x + (r->x1 - dest_extent.x1),
                                         dc_point.y + (r->y1 - dest_extent.y1));
                info.src_h = rtgui_rect_height(*r);
                info.src_w = rtgui_rect_width(*r);
                info.src_skip = info.src_pitch - info.src_w * bpp;

                /* blit destination */
                info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch +
                           r->x1 * hw_bpp;
                info.dst_h = rtgui_rect_height(*r);
                info.dst_w = rtgui_rect_width(*r);
                info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;

                rtgui_blit(&info);
            }

            rtgui_region_fini(&dest_region);
        }