3535#include <LCUI/gui/widget.h>
3636#include <LCUI/display.h>
3737
38+ //#define DEBUG_FRAME_RENDER
3839#define ComputeActualPX (VAL ) LCUIMetrics_ComputeActual( VAL, SVT_PX )
3940
41+ #ifdef DEBUG_FRAME_RENDER
42+ #include <LCUI/image.h>
43+ #endif
44+
4045typedef struct LCUI_RectGroupRec_ {
4146 LCUI_Widget widget ;
4247 LinkedList rects ;
4348}LCUI_RectGroupRec , * LCUI_RectGroup ;
4449
45- /** 部件渲染器 */
4650typedef struct LCUI_WidgetRendererRec_ {
47- float x , y ; /**< 目标部件的位置,相对于根级部件 */
48- float content_top ; /**< 内容区的上边距 */
49- float content_left ; /**< 内容区的左边距 */
50- LCUI_Widget target ; /**< 绘制目标 */
51- LCUI_PaintContext paint ; /**< 绘制上下文 */
52- LCUI_PaintContext root_paint ; /**< 根级绘制上下文 */
53- LCUI_Graph content_graph ; /**< 部件的内容区图形缓存 */
54- LCUI_Graph self_graph ; /**< 部件的图形缓存 */
55- LCUI_Graph layer_graph ; /**< 部件的图层缓存,用于承载自身和内容区的图形 */
56- LCUI_Rect content_rect ; /**< 内容区,相对于根级部件 */
57- LCUI_Rect content_paint_rect ; /**< 内容区中需要绘制的区域 */
51+ float x , y ; /**< target widget position, it relative to root canvas */
52+ float content_top ; /**< content area top spacing, it relative to widget canvas */
53+ float content_left ; /**< content area left spacing, it relative to widget canvas */
54+ LCUI_Widget target ; /**< target widget */
55+ LCUI_PaintContext paint ; /**< current target widget paint context */
56+ LCUI_PaintContext root_paint ; /**< root paint context */
57+ LCUI_Graph content_graph ; /**< content canvas */
58+ LCUI_Graph self_graph ; /**< target widget canvas */
59+ LCUI_Graph layer_graph ; /**< layer canvas, used to mix content and self canvas with widget opacity */
60+ LCUI_Rect content_rect ; /**< actual paint rectangle in widget content rectangle, it relative to root canvas */
5861 LCUI_BOOL has_content_graph ;
5962 LCUI_BOOL has_self_graph ;
6063 LCUI_BOOL has_layer_graph ;
@@ -283,6 +286,7 @@ static LCUI_WidgetRenderer WidgetRenderer( LCUI_Widget w,
283286 LCUI_WidgetRenderer parent )
284287{
285288 LCUI_RectF rect ;
289+ LCUI_Rect paint_rect ;
286290 ASSIGN ( that , LCUI_WidgetRenderer );
287291
288292 that -> target = w ;
@@ -299,13 +303,12 @@ static LCUI_WidgetRenderer WidgetRenderer( LCUI_Widget w,
299303 that -> x = that -> y = 0 ;
300304 that -> root_paint = that -> paint ;
301305 }
302- /* 若部件本身是透明的 */
303306 if ( w -> computed_style .opacity < 1.0 ) {
304307 that -> has_self_graph = TRUE;
305308 that -> has_content_graph = TRUE;
306309 that -> has_layer_graph = TRUE;
307310 } else {
308- /* 若使用了圆角边框,则判断当前脏矩形区域是否在圆角边框内
311+ /* if target has rounded corners border...
309312 ...
310313 if( ... ) {
311314 that->has_content_graph = TRUE;
@@ -324,35 +327,44 @@ static LCUI_WidgetRenderer WidgetRenderer( LCUI_Widget w,
324327 that -> paint -> rect .width ,
325328 that -> paint -> rect .height );
326329 }
327- /* 获取内容框相对于图层的间距 */
330+ /* get content rectangle left spacing and top */
328331 that -> content_left = w -> box .padding .x - w -> box .canvas .x ;
329332 that -> content_top = w -> box .padding .y - w -> box .canvas .y ;
330- /* 获取内容区域,相对于根级部件 */
333+ /* get content rectangle, it relative to root canvas */
331334 rect .x = that -> x + that -> content_left ;
332335 rect .y = that -> y + that -> content_top ;
333336 rect .width = w -> box .padding .width ;
334337 rect .height = w -> box .padding .height ;
335- /* 栅格化内容区域 */
336338 LCUIMetrics_ComputeRectActual ( & that -> content_rect , & rect );
337- rect .x -= that -> x ;
338- rect .y -= that -> y ;
339- LCUIMetrics_ComputeRectActual ( & that -> content_paint_rect , & rect );
340- /* 获取内容区域中实际需要绘制的区域 */
339+ /* convert position of paint rectangle to root canvas relative */
340+ rect .x = that -> x ;
341+ rect .y = that -> y ;
342+ LCUIMetrics_ComputeRectActual ( & paint_rect , & rect );
343+ paint_rect .x += that -> paint -> rect .x ;
344+ paint_rect .y += that -> paint -> rect .y ;
345+ paint_rect .width = that -> paint -> rect .width ;
346+ paint_rect .height = that -> paint -> rect .height ;
347+ /* get actual paint rectangle in widget content rectangle */
341348 that -> can_render_centent = LCUIRect_GetOverlayRect (
342- & that -> content_paint_rect , & that -> paint -> rect ,
343- & that -> content_paint_rect
349+ & that -> content_rect , & paint_rect , & that -> content_rect
344350 );
345- /* 转换坐标为相对于绘制区域 */
346- that -> content_paint_rect .x -= that -> paint -> rect .x ;
347- that -> content_paint_rect .y -= that -> paint -> rect .y ;
351+ DEBUG_MSG ( "[%s][%d/%d] content_rect: (%d,%d,%d,%d), "
352+ "canvas_rect: (%d,%d,%d,%d)\n" ,
353+ w -> id , w -> index ,
354+ w -> parent ? w -> parent -> children_show .length : 1 ,
355+ that -> content_rect .x , that -> content_rect .y ,
356+ that -> content_rect .width , that -> content_rect .height ,
357+ that -> paint -> canvas .quote .left ,
358+ that -> paint -> canvas .quote .top ,
359+ that -> paint -> canvas .width ,
360+ that -> paint -> canvas .height );
348361 if ( !that -> can_render_centent ) {
349362 return that ;
350363 }
351- /* 若需要部件内容区的位图缓存 */
352364 if ( that -> has_content_graph ) {
353365 that -> content_graph .color_type = COLOR_TYPE_ARGB ;
354- Graph_Create ( & that -> content_graph , that -> content_paint_rect .width ,
355- that -> content_paint_rect .height );
366+ Graph_Create ( & that -> content_graph , that -> content_rect .width ,
367+ that -> content_rect .height );
356368 }
357369 return that ;
358370}
@@ -395,11 +407,6 @@ static size_t WidgetRenderer_RenderChildren( LCUI_WidgetRenderer that )
395407 & paint_rect ) ) {
396408 continue ;
397409 }
398- if ( !LCUIRect_GetOverlayRect ( & that -> root_paint -> rect ,
399- & paint_rect ,
400- & paint_rect ) ) {
401- continue ;
402- }
403410 if ( that -> has_content_graph ) {
404411 paint .with_alpha = TRUE;
405412 } else {
@@ -426,16 +433,35 @@ static size_t WidgetRenderer_Render( LCUI_WidgetRenderer renderer )
426433 size_t count = 0 ;
427434 LCUI_PaintContextRec self_paint ;
428435 LCUI_WidgetRenderer that = renderer ;
436+ #ifdef DEBUG_FRAME_RENDER
437+ char filename [256 ];
438+ static size_t frame = 0 ;
439+ #endif
429440 /* 如果部件有需要绘制的内容 */
430441 if ( that -> can_render_self ) {
431442 count += 1 ;
432443 self_paint = * that -> paint ;
433444 self_paint .canvas = that -> self_graph ;
434445 Widget_OnPaint ( that -> target , & self_paint );
446+ #ifdef DEBUG_FRAME_RENDER
447+ sprintf ( filename ,
448+ "frame-%lu-%s-self-paint-(%d,%d,%d,%d).png" ,
449+ frame ++ , renderer -> target -> id ,
450+ self_paint .rect .x , self_paint .rect .y ,
451+ self_paint .rect .width ,
452+ self_paint .rect .height );
453+ LCUI_WritePNGFile ( filename , & self_paint .canvas );
454+ #endif
435455 /* 若不需要缓存自身位图则直接绘制到画布上 */
436456 if ( !that -> has_self_graph ) {
437457 Graph_Mix ( & that -> paint -> canvas , & that -> self_graph ,
438458 0 , 0 , that -> paint -> with_alpha );
459+ #ifdef DEBUG_FRAME_RENDER
460+ sprintf ( filename , "frame-%lu-%s-canvas.png" ,
461+ frame ++ , renderer -> target -> id );
462+ LCUI_WritePNGFile ( filename ,
463+ & that -> root_paint -> canvas );
464+ #endif
439465 }
440466 }
441467 if ( that -> can_render_centent ) {
@@ -448,9 +474,15 @@ static size_t WidgetRenderer_Render( LCUI_WidgetRenderer renderer )
448474 if ( !that -> has_layer_graph ) {
449475 if ( that -> has_content_graph ) {
450476 Graph_Mix ( & that -> paint -> canvas , & that -> content_graph ,
451- that -> content_paint_rect .x ,
452- that -> content_paint_rect .y , TRUE );
477+ that -> content_rect .x ,
478+ that -> content_rect .y , TRUE );
453479 }
480+ #ifdef DEBUG_FRAME_RENDER
481+ sprintf ( filename , "frame-%lu-%s-canvas.png" ,
482+ frame ++ , renderer -> target -> id );
483+ LCUI_WritePNGFile ( filename ,
484+ & that -> root_paint -> canvas );
485+ #endif
454486 return count ;
455487 }
456488 /* 若需要绘制的是当前部件图层,则先混合部件自身位图和内容位图,得出当
@@ -459,18 +491,26 @@ static size_t WidgetRenderer_Render( LCUI_WidgetRenderer renderer )
459491 if ( that -> can_render_self ) {
460492 Graph_Copy ( & that -> layer_graph , & that -> self_graph );
461493 Graph_Mix ( & that -> layer_graph , & that -> content_graph ,
462- that -> content_paint_rect .x ,
463- that -> content_paint_rect .y , TRUE );
494+ that -> content_rect .x ,
495+ that -> content_rect .y , TRUE );
464496 } else {
465497 Graph_Create ( & that -> layer_graph , that -> paint -> rect .width ,
466498 that -> paint -> rect .height );
467499 Graph_Replace ( & that -> layer_graph , & that -> content_graph ,
468- that -> content_paint_rect .x ,
469- that -> content_paint_rect .y );
500+ that -> content_rect .x ,
501+ that -> content_rect .y );
470502 }
471503 that -> layer_graph .opacity = that -> target -> computed_style .opacity ;
472504 Graph_Mix ( & that -> paint -> canvas , & that -> layer_graph ,
473505 0 , 0 , that -> paint -> with_alpha );
506+ #ifdef DEBUG_FRAME_RENDER
507+ sprintf ( filename , "frame-%lu-%s-layer.png" ,
508+ frame ++ , renderer -> target -> id );
509+ LCUI_WritePNGFile ( filename , & that -> layer_graph );
510+ sprintf ( filename , "frame-%lu-%s-canvas.png" ,
511+ frame ++ , renderer -> target -> id );
512+ LCUI_WritePNGFile ( filename , & that -> root_paint -> canvas );
513+ #endif
474514 return count ;
475515}
476516
0 commit comments