/** 标记指定文本行的矩形区域为无效 */ static void TextLayer_InvalidateRowRect( LCUI_TextLayer *layer, int i_row ) { LCUI_Rect rect; if( TextLayer_GetRowRect( layer, i_row, &rect ) == 0 ) { DirtyRectList_Add( &layer->dirty_rect, &rect ); } }
/** * 标记部件内的一个区域为无效的,以使其重绘 * @param[in] w 目标部件 * @param[in] r 矩形区域 * @param[in] box_type 区域相对于何种框进行定位 */ void Widget_InvalidateArea( LCUI_Widget w, LCUI_Rect *r, int box_type ) { LCUI_Rect rect; Widget_AdjustArea( w, r, &rect, box_type ); DirtyRectList_Add( &w->dirty_rects, &rect ); while( w = w->parent, w && !w->has_dirty_child ) { w->has_dirty_child = TRUE; } }
/** 标记指定文本行的矩形区域为无效 */ static void TextLayer_InvalidateRowRectEx( LCUI_TextLayer *layer, int i_row, int start, int end ) { int ret; LCUI_Rect rect; ret = TextLayer_GetRowRectEx( layer, i_row, start, end, &rect ); if( ret == 0 ) { DirtyRectList_Add( &layer->dirty_rect, &rect ); } }
static int _Widget_ProcInvalidArea( LCUI_Widget w, LCUI_BOOL is_root, int x, int y, LCUI_Rect *valid_box, LCUI_DirtyRectList *rlist ) { int i, n, count; LCUI_Widget child; LCUI_Rect rect, child_box, *r; count = n = LinkedList_GetTotal( &w->dirty_rects ); /* 取出当前记录的脏矩形 */ for( i=0; i<n; ++i ) { LinkedList_Goto( &w->dirty_rects, 0 ); r = (LCUI_Rect*)LinkedList_Get( &w->dirty_rects ); /* 若有独立位图缓存,则重绘脏矩形区域 */ if( Graph_IsValid(&w->graph) ) { LCUI_PaintContextRec_ paint; paint.rect = *r; Graph_Quote( &paint.canvas, &w->graph, &paint.rect ); Widget_OnPaint( w, &paint ); } /* 转换为相对于父部件的坐标 */ rect.x = r->x; rect.y = r->y; /* 如果当前是根部件,则不用加上自身坐标 */ if( !is_root ) { rect.x += w->base.box.graph.x; rect.y += w->base.box.graph.y; } rect.w = r->w; rect.h = r->h; /* 取出与容器内有效区域相交的区域 */ if( LCUIRect_GetOverlayRect(&rect, valid_box, &rect) ) { /* 转换相对于根级部件的坐标 */ rect.x += x; rect.y += y; DirtyRectList_Add( rlist, &rect ); } LinkedList_Delete( &w->dirty_rects ); } /* 若子级部件没有脏矩形记录 */ if( !w->has_dirty_child ) { return count; } /* 缩小有效区域到当前部件内容框内,若没有重叠区域,则不向子级部件递归 */ if( !LCUIRect_GetOverlayRect(valid_box, &w->base.box.content, &child_box) ) { return count; } /* 转换有效区域的坐标,相对于当前部件的内容框 */ child_box.x -= w->base.box.content.x; child_box.y -= w->base.box.content.y; n = LinkedList_GetTotal( &w->children ); /* 向子级部件递归 */ for( i=0; i<n; ++i ) { child = (LCUI_Widget)LinkedList_Get( &w->children ); if( !child->style.visible ) { continue; } count += _Widget_ProcInvalidArea( child, FALSE, child->base.box.graph.x + x, child->base.box.graph.y + y, &child_box, rlist ); } return count; }
/** 标记指定范围内容的文本行的矩形为无效 */ void TextLayer_InvalidateRowsRect( LCUI_TextLayer *layer, int start_row, int end_row ) { int i, x, y; LCUI_Rect rect; TextRowData *p_row; /* 先计算在有效区域内的起始行的Y轴坐标 */ y = layer->offset_y; for( i=0; i<start_row; ++i ) { p_row = layer->row_list.rowdata[i]; y += p_row->top_spacing; y += p_row->max_height; y += p_row->bottom_spacing; } if( end_row < 0 ) { end_row = layer->row_list.rows-1; } for( i=start_row; i<=end_row; ++i ) { p_row = layer->row_list.rowdata[i]; /* 根据对齐方式,计算该行的位置 */ switch( layer->text_align ) { case TEXT_ALIGN_CENTER: x = (layer->max_width - p_row->max_width)/2; break; case TEXT_ALIGN_RIGHT: x = layer->max_width - p_row->max_width; break; case TEXT_ALIGN_LEFT: default: x = 0; break; } y += p_row->top_spacing; rect.x = layer->offset_x + x; rect.y = y; y += p_row->max_height; y += p_row->bottom_spacing; rect.width = p_row->max_width; rect.height = p_row->max_height; if( rect.x < 0 ) { rect.width += x; rect.x = 0; } else if( rect.x >= layer->max_width ) { continue; } if( rect.x + rect.width >= layer->max_width ) { rect.width = layer->max_width - rect.x; } if( rect.y < 0 ) { rect.height += y; rect.y = 0; } else if( rect.y >= layer->max_height ) { continue; } if( rect.y + rect.height >= layer->max_height ) { rect.height = layer->max_height - rect.y; } DirtyRectList_Add( &layer->dirty_rect, &rect ); } }