LCUI_API LCUI_GraphLayer* GraphLayer_New( void ) { LCUI_GraphLayer * glayer; glayer = (LCUI_GraphLayer*)malloc( sizeof( LCUI_GraphLayer ) ); if( glayer == NULL ) { return NULL; } /* 赋初始值 */ glayer->visible = FALSE; glayer->inherit_alpha = TRUE; glayer->pos.x = glayer->pos.y = glayer->z_index = 0; glayer->padding.left = 0; glayer->padding.top = 0; glayer->padding.bottom = 0; glayer->padding.right = 0; glayer->parent = NULL; /* 初始化图像数据 */ Graph_Init( &glayer->graph ); /* 初始化子图层列表 */ Queue_Init( &glayer->child, 0, NULL ); /* 标记该队列用于存储指针,即使销毁队列后,也不自动释放指针指向的内存空间 */ Queue_UsingPointer( &glayer->child ); return glayer; }
Frames_Play(LCUI_Frames *frames) /* 功能:播放动画 */ { int i, total; LCUI_Frames *tmp_ptr; if( !frames ) { return -1; } frames->state = 1; if(__timer_id == -1){ Queue_Init( &frames_stream, sizeof(LCUI_Frames), NULL ); Queue_UsingPointer( &frames_stream ); __timer_id = set_timer( 50, Process_Frames, TRUE ); } /* 检查该动画是否已存在 */ Queue_Lock( &frames_stream ); total = Queue_GetTotal( &frames_stream ); for( i=0; i<total; ++i ) { tmp_ptr = Queue_Get( &frames_stream, i ); if( tmp_ptr == frames ) { break; } } Queue_Unlock( &frames_stream ); /* 添加至动画更新队列中 */ if( i>=total ) { return Queue_AddPointer(&frames_stream, frames); } return 1; }
static int TextLayer_Text_Insert_NewRow ( LCUI_TextLayer *layer, int row ) /* 在插入新行至指定位置 */ { Text_RowData data; data.pos = Pos(0,0); data.max_size = Size(0,0); data.last_char = NULL; Queue_Init( &data.string, sizeof(LCUI_CharData), NULL ); Queue_SetDataMode( &data.string, QUEUE_DATA_MODE_LINKED_LIST ); Queue_UsingPointer( &data.string ); return Queue_Insert( &layer->rows_data, row, &data ); }
static int TextLayer_Text_Add_NewRow ( LCUI_TextLayer *layer ) /* 添加新行 */ { Text_RowData data; /* 单整行最大尺寸改变时,需要移动整行,目前还未支持此功能 */ data.pos = Pos(0,0); data.max_size = Size(0,0); data.last_char = NULL; Queue_Init( &data.string, sizeof(LCUI_CharData), NULL ); /* 使用链表模式,方便数据的插入 */ Queue_SetDataMode( &data.string, QUEUE_DATA_MODE_LINKED_LIST ); /* 队列成员使用指针,主要是引用text_source_data里面的数据 */ Queue_UsingPointer( &data.string ); return Queue_Add( &layer->rows_data, &data ); }
LCUI_API int GraphLayer_GetGraph( LCUI_GraphLayer *ctnr, LCUI_Graph *graph_buff, LCUI_Rect rect ) { int i, total; uchar_t tmp_alpha, alpha; LCUI_Pos pos, glayer_pos; LCUI_GraphLayer *glayer; LCUI_Queue glayerQ; LCUI_Rect valid_area; LCUI_Graph tmp_graph; /* 检测这个区域是否有效 */ if (rect.x < 0 || rect.y < 0) { return -1; } if (rect.x + rect.width > ctnr->graph.w || rect.y + rect.height > ctnr->graph.h ) { return -1; } if (rect.width <= 0 || rect.height <= 0) { return -2; } if( !Graph_IsValid(graph_buff) ) { graph_buff->color_type = COLOR_TYPE_ARGB; Graph_Create( graph_buff, rect.width, rect.height ); } Graph_Init( &tmp_graph ); Queue_Init( &glayerQ, 0, NULL); Queue_UsingPointer( &glayerQ ); /* 获取rect区域内的图层列表 */ GraphLayer_GetLayers( ctnr, rect, &glayerQ ); total = Queue_GetTotal( &glayerQ ); DEBUG_MSG( "total: %d\n", total ); /* 若记录数为零,则表明该区域没有图层 */ if( total <= 0 ) { /* 若没有父图层,则填充白色 */ if( ctnr == NULL ) { Graph_FillColor( graph_buff, RGB(255,255,255) ); } else { /* 否则使用父图层的图形 */ Graph_Cut( &ctnr->graph, rect, graph_buff ); } /* 销毁记录 */ Queue_Destroy( &glayerQ ); return 0; } /* 从顶层到底层遍历图层,排除被其它图层完全遮挡或者自身完全透明的图层 */ for(i=total-1; i>=0; --i) { glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i ); valid_area = GraphLayer_GetValidRect( ctnr, glayer ); glayer_pos = GraphLayer_GetGlobalPos( ctnr, glayer ); valid_area.x += glayer_pos.x; valid_area.y += glayer_pos.y; alpha = GraphLayer_GetRealAlpha( glayer ); /* 当前图层的透明度小于255的话,就跳过 */ if( alpha < 255 ) { continue; } /* 跳过有alpha通道的图层 */ if( glayer->graph.color_type == COLOR_TYPE_ARGB ) { continue; } /* 如果该图层的有效区域包含目标区域 */ if( rect.x >= valid_area.x && rect.y >= valid_area.y && rect.x + rect.w <= valid_area.x + valid_area.w && rect.y + rect.h <= valid_area.y + valid_area.h ) { /* 移除底层的图层,因为已经被完全遮挡 */ for(total=i-1;total>=0; --total) { Queue_DeletePointer( &glayerQ, 0 ); } goto skip_loop; } } skip_loop: total = Queue_GetTotal( &glayerQ ); DEBUG_MSG( "total: %d\n", total ); if(i <= 0 && ctnr ) { Graph_Cut( &ctnr->graph, rect, graph_buff ); } /* 获取图层列表中的图层 */ for(i=0; i<total; ++i) { glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i ); //_DEBUG_MSG("%p = Queue_Get( %p, %d )\n", glayer, &glayerQ, i); if( !glayer ) { continue; } DEBUG_MSG("%d,%d,%d,%d\n", glayer->pos.x, glayer->pos.y, glayer->graph.w, glayer->graph.h); /* 获取该图层的有效区域及全局坐标 */ pos = GraphLayer_GetGlobalPos( ctnr, glayer ); valid_area = GraphLayer_GetValidRect( ctnr, glayer ); /* 引用该图层的有效区域内的图像 */ Graph_Quote( &tmp_graph, &glayer->graph, valid_area ); //_DEBUG_MSG("valid area: %d,%d,%d,%d, pos: %d,%d, size: %d,%d\n", // valid_area.x, valid_area.y, valid_area.width, valid_area.height, // pos.x, pos.y, glayer->graph.w, glayer->graph.h // ); /* 获取相对坐标 */ pos.x = pos.x - rect.x + valid_area.x; pos.y = pos.y - rect.y + valid_area.y; //_DEBUG_MSG("mix pos: %d,%d\n", pos.x, pos.y); /* 如果该图层没有继承父图层的透明度 */ if( !glayer->inherit_alpha ) { /* 直接叠加至graph_buff */ Graph_Mix( graph_buff, &tmp_graph, pos ); } else { /* 否则,计算该图层应有的透明度 */ alpha = GraphLayer_GetRealAlpha( glayer ); /* 备份该图层的全局透明度 */ tmp_alpha = glayer->graph.alpha; /* 将实际透明度作为全局透明度,参与图像叠加 */ glayer->graph.alpha = alpha; Graph_Mix( graph_buff, &tmp_graph, pos ); /* 还原全局透明度 */ glayer->graph.alpha = tmp_alpha; } } Queue_Destroy( &glayerQ ); return 0; }