void Graph_ClearShadowArea( LCUI_PaintContext paint, LCUI_Rect *box, LCUI_BoxShadow *shadow ) { int i; LCUI_Graph canvas; LCUI_Rect rect, box_area, rects[4]; rect.w = box->w; rect.h = box->h; rect.x = rect.y = 0; /* 获取内容框区域 */ box_area.x = box->x + BoxShadow_GetBoxX( shadow ); box_area.y = box->y + BoxShadow_GetBoxY( shadow ); box_area.w = BoxShadow_GetBoxWidth( shadow, box->w ); box_area.h = BoxShadow_GetBoxHeight( shadow, box->h ); /* 获取内容框外的阴影区域 */ LCUIRect_CutFourRect( &box_area, &rect, rects ); for( i=0; i<4; ++i ) { if( LCUIRect_GetOverlayRect( &paint->rect, &rects[i], &rects[i] ) ) { rects[i].x -= paint->rect.x; rects[i].y -= paint->rect.y; Graph_Quote( &canvas, &paint->canvas, &rects[i] ); Graph_FillRect( &canvas, ARGB(0,0,0,0), NULL, TRUE ); } } }
static void Graph_DrawInnerShadow( LCUI_PaintContext paint, LCUI_Rect *box, LCUI_BoxShadow *s ) { int i; LCUI_Graph canvas; LCUI_Rect rsd, rb, rects[4]; rb.x = BoxShadow_GetBoxX( s ); rb.y = BoxShadow_GetBoxY( s ); rb.w = BoxShadow_GetBoxWidth( s, box->w ); rb.h = BoxShadow_GetBoxHeight( s, box->h ); rsd.x = BoxShadow_GetX( s ) + BLUR_WIDTH(s); rsd.y = BoxShadow_GetY( s ) + BLUR_WIDTH(s); rsd.w = rb.w + INNER_SHADOW_WIDTH(s)*2; rsd.h = rb.h + INNER_SHADOW_WIDTH(s)*2; /* 截取出与内容区重叠的区域 */ if( LCUIRect_GetOverlayRect(&rb, &rsd, &rb) ) { LCUIRect_CutFourRect( &rb, &rsd, rects ); /* 从阴影区域中排除部件占用的区域 */ for( i=0; i<4; ++i ) { if( !LCUIRect_GetOverlayRect( &paint->rect, &rects[i],&rects[i]) ) { continue; } rects[i].x -= paint->rect.x; rects[i].y -= paint->rect.y; Graph_Quote( &canvas, &paint->canvas, &rects[i] ); Graph_FillRect( &canvas, s->color, NULL, TRUE ); } return; } /* 不重叠则直接填充 */ if( LCUIRect_GetOverlayRect(&paint->rect, &rsd, &rb) ) { rb.x -= paint->rect.x; rb.y -= paint->rect.y; Graph_Quote( &canvas, &paint->canvas, &rb ); Graph_FillRect( &canvas, s->color, NULL, TRUE ); } }
int test_string_render( void ) { int ret; LCUI_Graph img; LCUI_Pos pos = {0, 80}; LCUI_Rect area = {0, 0, 320, 240}; LCUI_TextLayer txt = TextLayer_New(); LCUI_TextStyleRec txtstyle; /* 初始化字体处理功能 */ LCUI_InitFontLibrary(); /* 创建一个图像,并使用灰色填充 */ Graph_Init( &img ); Graph_Create( &img, 320, 240 ); Graph_FillRect( &img, RGB( 240, 240, 240 ), NULL, FALSE ); /* 设置文本的字体大小 */ TextStyle_Init( &txtstyle ); txtstyle.pixel_size = 24; txtstyle.has_pixel_size = TRUE; /* 设置文本图层的固定尺寸、文本样式、文本内容、对齐方式 */ TextLayer_SetFixedSize( txt, 320, 240 ); TextLayer_SetTextStyle( txt, &txtstyle ); TextLayer_SetTextAlign( txt, SV_CENTER ); TextLayer_SetTextW( txt, L"这是一段测试文本\nHello, World!", NULL ); TextLayer_Update( txt, NULL ); /* 将文本图层绘制到图像中,然后将图像写入至 png 文件中 */ TextLayer_DrawToGraph( txt, area, pos, &img ); ret = LCUI_WritePNGFile( "test_string_render.png", &img ); Graph_Free( &img ); /* 释放字体处理功能相关资源 */ LCUI_FreeFontLibrary(); return ret; }
LCUI_API int Graph_FillColor( LCUI_Graph *graph, LCUI_RGB color ) { return Graph_FillRect( graph, color, Rect(0,0,graph->w, graph->h) ); }
void Graph_DrawBackground( LCUI_PaintContext paint, const LCUI_Rect *box, LCUI_Background *bg ) { float scale; LCUI_Graph graph; LCUI_BOOL with_alpha; LCUI_Rect read_rect, paint_rect; int image_x, image_y, image_w, image_h; /* 计算背景图应有的尺寸 */ if( bg->size.using_value ) { switch( bg->size.value ) { case SV_CONTAIN: image_w = box->width; scale = 1.0 * bg->image.width / image_w; image_h = 1.0 * bg->image.height / scale; if( image_h > box->height ) { image_h = box->height; scale = 1.0 * bg->image.height / box->height; image_w = (int)(1.0 * bg->image.width / scale); } break; case SV_COVER: image_w = box->width; scale = 1.0 * bg->image.width / image_w; image_h = 1.0 * bg->image.height / scale; if( image_h < box->height ) { image_h = box->height; scale = 1.0 * bg->image.height / image_h; image_w = (int)(1.0 * bg->image.width / scale); } break; case SV_AUTO: default: image_w = bg->image.width; image_h = bg->image.height; break; } } else { switch( bg->size.w.type ) { case SVT_SCALE: image_w = box->w * bg->size.w.scale; break; case SVT_PX: image_w = bg->size.w.px; break; default: image_w = bg->image.width; break; } switch( bg->size.h.type ) { case SVT_SCALE: image_h = box->h * bg->size.h.scale; break; case SVT_PX: image_h = bg->size.h.px; break; default: image_h = bg->image.height; break; } } /* 计算背景图的像素坐标 */ if( bg->position.using_value ) { switch( bg->position.value ) { case SV_TOP: case SV_TOP_CENTER: image_x = (box->w - image_w) / 2; image_y = 0; break; case SV_TOP_RIGHT: image_x = box->w - image_w; image_y = 0; break; case SV_CENTER_LEFT: image_x = 0; image_y = (box->h - image_h) / 2; break; case SV_CENTER: case SV_CENTER_CENTER: image_x = (box->w - image_w) / 2; image_y = (box->h - image_h) / 2; break; case SV_CENTER_RIGHT: image_x = box->w - image_w; image_y = (box->h - image_h) / 2; break; case SV_BOTTOM_LEFT: image_x = 0; image_y = box->h - image_h; break; case SV_BOTTOM_CENTER: image_x = (box->w - image_w) / 2; image_y = box->h - image_h; break; case SV_BOTTOM_RIGHT: image_x = box->w - image_w; image_y = box->h - image_h; break; case SV_TOP_LEFT: default:image_x = image_y = 0; break; } } else { switch( bg->position.x.type ) { case SVT_SCALE: image_x = box->w - image_w; image_x *= bg->position.x.scale; break; case SVT_PX: image_x = bg->position.x.px; break; default:image_x = 0; break; } switch( bg->position.y.type ) { case SVT_SCALE: image_y = box->h - image_h; image_y *= bg->position.y.scale; break; case SVT_PX: image_y = bg->position.y.px; break; default:image_y = 0; break; } } /* 获取当前绘制区域与背景内容框的重叠区域 */ if( !LCUIRect_GetOverlayRect( box, &paint->rect, &paint_rect ) ) { return; } with_alpha = bg->color.alpha < 255; paint_rect.x -= paint->rect.x; paint_rect.y -= paint->rect.y; Graph_Quote( &graph, &paint->canvas, &paint_rect ); Graph_FillRect( &graph, bg->color, NULL, TRUE ); /* 将坐标转换为相对于背景内容框 */ paint_rect.x += paint->rect.x - box->x; paint_rect.y += paint->rect.y - box->y; /* 保存背景图像区域 */ read_rect.x = image_x; read_rect.y = image_y; read_rect.width = image_w; read_rect.height = image_h; /* 获取当前绘制区域与背景图像的重叠区域 */ if( !LCUIRect_GetOverlayRect( &read_rect, &paint_rect, &read_rect ) ) { return; } /* 转换成相对于图像的坐标 */ read_rect.x -= image_x; read_rect.y -= image_y; /* 如果尺寸没有变化则直接引用 */ if( image_w == bg->image.w && image_h == bg->image.h ) { Graph_Quote( &graph, &bg->image, &read_rect ); /* 转换成相对于当前绘制区域的坐标 */ image_x = image_x + box->x - paint->rect.x; image_y = image_y + box->y - paint->rect.y; image_x += read_rect.x; image_y += read_rect.y; Graph_Mix( &paint->canvas, &graph, image_x, image_y, with_alpha ); } else { float scale; LCUI_Graph buffer; LCUI_Rect quote_rect; Graph_Init( &buffer ); quote_rect = read_rect; /* 根据宽高的缩放比例,计算实际需要引用的区域 */ if( image_w != bg->image.w ) { scale = 1.0 * bg->image.width / image_w; quote_rect.x *= scale; quote_rect.width *= scale; } if( image_h != bg->image.h ) { scale = 1.0 * bg->image.height / image_h; quote_rect.y *= scale; quote_rect.height *= scale; } /* 引用源背景图像的一块区域 */ Graph_Quote( &graph, &bg->image, "e_rect ); image_w = read_rect.width; image_h = read_rect.height; /* 计算相对于绘制区域的坐标 */ image_x = read_rect.x + image_x; image_x = image_x + box->x - paint->rect.x; image_y = read_rect.y + image_y; image_y = image_y + box->y - paint->rect.y; /* 按比例进行缩放 */ Graph_Zoom( &graph, &buffer, FALSE, image_w, image_h ); Graph_Mix( &paint->canvas, &buffer, image_x, image_y, with_alpha ); Graph_Free( &buffer ); } }