提交 0621f30e 编写于 作者: B bernard.xiong@gmail.com

move rtgui_win to branches.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1346 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 0e93e680
Import('env')
Import('rtconfig')
Import('RTT_ROOT')
Import('projects')
common_src = Split("""
common/color.c
common/region.c
common/rtgui_object.c
common/rtgui_system.c
common/rtgui_theme.c
common/rtgui_xml.c
common/dc.c
common/dc_buffer.c
common/dc_hw.c
common/filerw.c
common/image.c
common/image_xpm.c
common/image_hdc.c
common/font.c
common/font_hz_file.c
common/font_hz_bmp.c
common/asc12font.c
common/asc16font.c
common/hz12font.c
common/hz16font.c
""")
server_src = Split("""
server/driver.c
server/mouse.c
server/panel.c
server/server.c
server/topwin.c
""")
widgets_src = Split("""
widgets/button.c
widgets/checkbox.c
widgets/container.c
widgets/iconbox.c
widgets/label.c
widgets/progressbar.c
widgets/radiobox.c
widgets/slider.c
widgets/staticline.c
widgets/textbox.c
widgets/listbox.c
widgets/view.c
widgets/list_view.c
widgets/filelist_view.c
widgets/widget.c
widgets/window.c
widgets/combobox.c
widgets/scrollbar.c
""")
# The set of source files associated with this SConscript file.
src_local = common_src + server_src + widgets_src
path = [RTT_ROOT + '/components/rtgui/include',
RTT_ROOT + '/components/rgtui/common',
RTT_ROOT + '/components/rtgui/server',
RTT_ROOT + '/components/rtgui/widgets']
# group definitions
group = {}
group['name'] = 'GUI'
group['src'] = File(src_local)
group['CCFLAGS'] = ''
group['CPPPATH'] = path
group['CPPDEFINES'] = ''
group['LINKFLAGS'] = ''
# add group to project list
projects.append(group)
env.Append(CCFLAGS = group['CCFLAGS'])
env.Append(CPPPATH = group['CPPPATH'])
env.Append(CPPDEFINES = group['CPPDEFINES'])
env.Append(LINKFLAGS = group['LINKFLAGS'])
objs = env.Object(group['src'])
Return('objs')
/*
* File : asc16font.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/font.h>
const unsigned char asc12_font[] =
{//Tahoma
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//հ
0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00,//!
0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//"
0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00,0x00,//#
0x00,0x00,0x20,0x78,0xA0,0x60,0x30,0x28,0xF0,0x20,0x00,0x00,//$
0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00,//%
0x00,0x00,0x00,0x60,0x90,0x90,0x60,0xA8,0x90,0x68,0x00,0x00,//&
0x00,0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//'
0x00,0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,//(
0x00,0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,//)
0x00,0x00,0x00,0x20,0xA8,0x70,0xA8,0x20,0x00,0x00,0x00,0x00,//*
0x00,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00,//+
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40,0x00,//,
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,//-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,//.
0x00,0x00,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x00,///
0x00,0x00,0x00,0x70,0x88,0x98,0xA8,0xC8,0x88,0x70,0x00,0x00,//0
0x00,0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00,//1
0x00,0x00,0x00,0x70,0x88,0x88,0x30,0x40,0x80,0xF8,0x00,0x00,//2
0x00,0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,0x00,//3
0x00,0x00,0x00,0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00,0x00,//4
0x00,0x00,0x00,0xF8,0x80,0x80,0x70,0x08,0x88,0x70,0x00,0x00,//5
0x00,0x00,0x00,0x70,0x88,0x80,0xF0,0x88,0x88,0x70,0x00,0x00,//6
0x00,0x00,0x00,0xF8,0x08,0x10,0x20,0x20,0x40,0x40,0x00,0x00,//7
0x00,0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x00,//8
0x00,0x00,0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00,0x00,//9
0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00,//:
0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x20,0x20,0x40,0x00,0x00,//;
0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,//<
0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00,0x00,//=
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,//>
0x00,0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x00,0x20,0x00,0x00,//?
0x00,0x00,0x78,0x84,0xB4,0xD4,0xD4,0xB8,0x80,0x78,0x00,0x00,//@
0x00,0x00,0x00,0x30,0x30,0x48,0x48,0x78,0x84,0x84,0x00,0x00,//A
0x00,0x00,0x00,0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00,0x00,//B
0x00,0x00,0x00,0x38,0x40,0x80,0x80,0x80,0x40,0x38,0x00,0x00,//C
0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0x88,0x90,0xE0,0x00,0x00,//D
0x00,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00,//E
0x00,0x00,0x00,0xF8,0x80,0x80,0xF8,0x80,0x80,0x80,0x00,0x00,//F
0x00,0x00,0x00,0x78,0x80,0x80,0xB8,0x88,0x88,0x78,0x00,0x00,//G
0x00,0x00,0x00,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0x00,//H
0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,//I
0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00,//J
0x00,0x00,0x00,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00,0x00,//K
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00,//L
0x00,0x00,0x00,0x88,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x00,0x00,//M
0x00,0x00,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00,0x00,//N
0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,//O
0x00,0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x00,0x00,//P
0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xA8,0x70,0x08,0x00,//Q
0x00,0x00,0x00,0xE0,0x90,0x90,0xE0,0xA0,0x90,0x88,0x00,0x00,//R
0x00,0x00,0x00,0x78,0x80,0x80,0x70,0x08,0x08,0xF0,0x00,0x00,//S
0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,//T
0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,//U
0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x00,0x00,//V
0x00,0x00,0x00,0xA8,0xA8,0xA8,0xA8,0x50,0x50,0x50,0x00,0x00,//W
0x00,0x00,0x00,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0x00,0x00,//X
0x00,0x00,0x00,0x88,0x50,0x50,0x20,0x20,0x20,0x20,0x00,0x00,//Y
0x00,0x00,0x00,0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x00,//Z
0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00,//[
0x00,0x00,0x40,0x40,0x40,0x20,0x20,0x20,0x10,0x10,0x10,0x00,//\
0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00,//]
0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00,//]
0x00,0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,//^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,//_
0x00,0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//`
0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0x00,//a
0x00,0x00,0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0xF0,0x00,0x00,//b
0x00,0x00,0x00,0x00,0x00,0x78,0x80,0x80,0x80,0x78,0x00,0x00,//c
0x00,0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00,0x00,//d
0x00,0x00,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x78,0x00,0x00,//e
0x00,0x00,0x18,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x00,0x00,//f
0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x78,0x08,0x70,//g
0x00,0x00,0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0x00,0x00,//h
0x00,0x00,0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00,//i
0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x60,//j
0x00,0x00,0x40,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00,//k
0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x30,0x00,0x00,//l
0x00,0x00,0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00,0x00,//m
0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x48,0x00,0x00,//n
0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00,//o
0x00,0x00,0x00,0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,//p
0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x78,0x08,0x08,//q
0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x00,0x00,//r
0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x30,0x08,0x70,0x00,0x00,//s
0x00,0x00,0x00,0x20,0x20,0x78,0x20,0x20,0x20,0x18,0x00,0x00,//t
0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x00,0x00,//u
0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x00,0x00,//v
0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0xA8,0x50,0x50,0x00,0x00,//w
0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,//x
0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x20,0xC0,//y
0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00,0x00,//z
0x00,0x00,0x08,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x08,0x00,//{
0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,//|
0x00,0x00,0x40,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x40,0x00,//}
0x00,0x00,0x00,0x00,0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,//~
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//
};
const struct rtgui_font_bitmap asc12 =
{
(const rt_uint8_t*)asc12_font, /* bmp */
RT_NULL,
RT_NULL,
6, /* width */
12, /* height */
0, /* first char */
127 /* last char */
};
rtgui_font_t rtgui_font_asc12 =
{
"asc", /* family */
12, /* height */
1, /* refer count */
&bmp_font_engine, /* font engine */
(void *)&asc12, /* font private data */
};
/* size = 4096 bytes */
此差异已折叠。
#include <rtgui/rtgui.h>
#include <rtgui/blit.h>
/* 2 bpp to 1 bpp */
static void rtgui_blit_line_2_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
/* 3 bpp to 1 bpp */
static void rtgui_blit_line_3_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 3;
while (line)
{
*dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
((*(src_ptr + 1) & 0x0000E000)>>11) |
((*(src_ptr + 2) & 0x000000C0)>>6));
src_ptr += 3;
dst_ptr ++;
line --;
}
return;
}
/* 4 bpp to 1 bpp */
static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
struct _color {rt_uint8_t r, g, b, a;} *c;
c = (struct _color*)src_ptr;
while (line-- > 0)
{
*dst_ptr = (c->r & 0xe0) | (c->g & 0xc0) >> 3 | (c->b & 0xe0) >> 5 ;
c ++;
dst_ptr ++;
}
}
/* 1 bpp to 2 bpp */
static void rtgui_blit_line_1_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
/* 3 bpp to 2 bpp */
static void rtgui_blit_line_3_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t* dst;
dst = (rt_uint16_t*)dst_ptr;
line = line / 3;
while (line)
{
*dst = (((*(src_ptr + 0) << 8) & 0x0000F800) |
((*(src_ptr + 1) << 3) & 0x000007E0) |
((*(src_ptr + 2) >> 3) & 0x0000001F));
src_ptr += 3;
dst ++;
line --;
}
return;
}
/* 4 bpp to 2 bpp */
static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
struct _color {rt_uint8_t r, g, b, a;} *c;
rt_uint16_t* ptr;
c = (struct _color*)src_ptr;
ptr = (rt_uint16_t*)dst_ptr;
line = line / 4;
while (line-- > 0)
{
*ptr = ((c->r & 0xf8) << 8) | ((c->g & 0xfc) << 3) | (c->b >> 3);
c ++;
ptr ++;
}
}
static void rtgui_blit_line_1_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
#define HI 1
#define LO 0
/* Special optimized blit for RTGUI_RGB 5-6-5 --> RGBA 8-8-8-8 */
static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
{
0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
};
static void rtgui_blit_line_2_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t *src;
rt_uint32_t *dst;
src = (rt_uint16_t*)src_ptr;
dst = (rt_uint32_t*)dst_ptr;
line = line / 2;
while (line)
{
*dst++ = RGB565_RGBA8888_LUT[src[LO]*2] + RGB565_RGBA8888_LUT[src[HI]*2+1];
line--;
src ++;
}
}
void rtgui_blit_line_direct(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_memcpy(dst_ptr, src_ptr, line);
}
/* convert 4bpp to 3bpp */
static void rtgui_blit_line_4_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 4;
while (line)
{
*dst_ptr++ = *src_ptr++;
*dst_ptr++ = *src_ptr++;
*dst_ptr++ = *src_ptr++;
src_ptr ++;
line --;
}
}
static void rtgui_blit_line_1_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
}
static void rtgui_blit_line_2_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
}
/* convert 3bpp to 4bpp */
static void rtgui_blit_line_3_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 4;
while (line)
{
*dst_ptr++ = *src_ptr++;
*dst_ptr++ = *src_ptr++;
*dst_ptr++ = *src_ptr++;
*dst_ptr++ = 0;
line --;
}
}
static const rtgui_blit_line_func _blit_table[5][5] =
{
/* 0_0, 1_0, 2_0, 3_0, 4_0 */
{RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
/* 0_1, 1_1, 2_1, 3_1, 4_1 */
{RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
/* 0_2, 1_2, 2_2, 3_2, 4_2 */
{RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 },
/* 0_3, 1_3, 2_3, 3_3, 4_3 */
{RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
/* 0_4, 1_4, 2_4, 3_4, 4_4 */
{RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
};
rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
{
RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
RT_ASSERT(src_bpp>0 && src_bpp < 5);
return _blit_table[dst_bpp][src_bpp];
}
/*
* File : color.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/color.h>
const rtgui_color_t red = RTGUI_RGB(0xff, 0x00, 0x00);
const rtgui_color_t green = RTGUI_RGB(0x00, 0xff, 0x00);
const rtgui_color_t blue = RTGUI_RGB(0x00, 0x00, 0xff);
const rtgui_color_t black = RTGUI_RGB(0x00, 0x00, 0x00);
const rtgui_color_t white = RTGUI_RGB(0xff, 0xff, 0xff);
const rtgui_color_t yellow = RTGUI_RGB(0xff, 0xff, 0x00);
const rtgui_color_t cyan = RTGUI_RGB(0x00, 80, 80); /*ɫ*/
const rtgui_color_t purple = RTGUI_RGB(0xff, 0x00, 0xff); /*ɫ*/
const rtgui_color_t high_light = RTGUI_RGB(0xff, 0xff, 0xff);
const rtgui_color_t dark = RTGUI_RGB(0x40, 0x40, 0x40);
const rtgui_color_t dark_grey = RTGUI_RGB(0x7f, 0x7f, 0x7f);
const rtgui_color_t light_grey = RTGUI_RGB(0xc0, 0xc0, 0xc0);
const rtgui_color_t selected_color = RTGUI_RGB(10, 36, 106);
此差异已折叠。
/*
* File : dc_buffer.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/rtgui.h>
#include <rtgui/dc.h>
#include <rtgui/blit.h>
#include <rtgui/dc_hw.h>
#include <rtgui/color.h>
#include <rtgui/rtgui_system.h>
#define hw_driver (rtgui_graphic_driver_get_default())
struct rtgui_dc_buffer
{
struct rtgui_dc parent;
/* graphic context */
rtgui_gc_t gc;
/* width and height */
rt_uint16_t width, height;
rt_uint16_t pitch;
/* blit info */
rtgui_region_t clip;
/* pixel data */
rt_uint8_t* pixel;
};
static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc* dc);
static void rtgui_dc_buffer_draw_point(struct rtgui_dc* dc, int x, int y);
static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
static void rtgui_dc_buffer_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
static void rtgui_dc_buffer_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
static void rtgui_dc_buffer_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
static void rtgui_dc_buffer_blit_line(struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_point,
struct rtgui_dc* dest, rtgui_rect_t* rect);
static void rtgui_dc_buffer_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
static rtgui_gc_t* rtgui_dc_buffer_get_gc(struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_buffer_get_visible(struct rtgui_dc* dc);
static void rtgui_dc_buffer_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
const static struct rtgui_dc_engine dc_buffer_engine =
{
rtgui_dc_buffer_draw_point,
rtgui_dc_buffer_draw_color_point,
rtgui_dc_buffer_draw_vline,
rtgui_dc_buffer_draw_hline,
rtgui_dc_buffer_fill_rect,
rtgui_dc_buffer_blit_line,
rtgui_dc_buffer_blit,
rtgui_dc_buffer_set_gc,
rtgui_dc_buffer_get_gc,
rtgui_dc_buffer_get_visible,
rtgui_dc_buffer_get_rect,
rtgui_dc_buffer_fini,
};
struct rtgui_dc* rtgui_dc_buffer_create(int w, int h)
{
struct rtgui_dc_buffer* dc;
dc = (struct rtgui_dc_buffer*)rtgui_malloc(sizeof(struct rtgui_dc_buffer));
dc->parent.type = RTGUI_DC_BUFFER;
dc->parent.engine = &dc_buffer_engine;
dc->gc.foreground = default_foreground;
dc->gc.background = default_background;
dc->gc.font = rtgui_font_default();
dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
dc->width = w;
dc->height = h;
dc->pitch = w * sizeof(rtgui_color_t);
rtgui_region_init(&(dc->clip));
dc->pixel = rtgui_malloc(h * dc->pitch);
rt_memset(dc->pixel, 0, h * dc->pitch);
return &(dc->parent);
}
rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc)
{
struct rtgui_dc_buffer* dc_buffer;
dc_buffer = (struct rtgui_dc_buffer*)dc;
return dc_buffer->pixel;
}
static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc* dc)
{
struct rtgui_dc_buffer* buffer = (struct rtgui_dc_buffer*)dc;
if (dc->type != RTGUI_DC_BUFFER) return RT_FALSE;
rtgui_free(buffer->pixel);
buffer->pixel = RT_NULL;
return RT_TRUE;
}
static void rtgui_dc_buffer_draw_point(struct rtgui_dc* self, int x, int y)
{
rtgui_color_t* ptr;
struct rtgui_dc_buffer* dc;
dc = (struct rtgui_dc_buffer*)self;
/* note: there is no parameter check in this function */
ptr = (rtgui_color_t*)(dc->pixel + y * dc->pitch + x * sizeof(rtgui_color_t));
*ptr = dc->gc.foreground;
}
static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color)
{
rtgui_color_t* ptr;
struct rtgui_dc_buffer* dc;
dc = (struct rtgui_dc_buffer*)self;
/* note: there is no parameter check in this function */
ptr = (rtgui_color_t*)(dc->pixel + y * dc->pitch + x * sizeof(rtgui_color_t));
*ptr = color;
}
static void rtgui_dc_buffer_draw_vline(struct rtgui_dc* self, int x, int y1, int y2)
{
rtgui_color_t* ptr;
register rt_base_t index;
struct rtgui_dc_buffer* dc;
dc = (struct rtgui_dc_buffer*)self;
if (x >= dc->width) return;
if (y1 > dc->height) y1 = dc->height;
if (y2 > dc->height) y2 = dc->height;
ptr = (rtgui_color_t*)(dc->pixel + y1 * dc->pitch + x * sizeof(rtgui_color_t));
for (index = y1; index < y2; index ++)
{
/* draw this point */
*ptr = dc->gc.foreground;
ptr += dc->width;
}
}
static void rtgui_dc_buffer_draw_hline(struct rtgui_dc* self, int x1, int x2, int y)
{
rtgui_color_t* ptr;
register rt_base_t index;
struct rtgui_dc_buffer* dc;
dc = (struct rtgui_dc_buffer*)self;
if (y >= dc->height) return;
if (x1 > dc->width) x1 = dc->width;
if (x2 > dc->width) x2 = dc->width;
ptr = (rtgui_color_t*)(dc->pixel + y * dc->pitch + x1 * sizeof(rtgui_color_t));
for (index = x1; index < x2; index ++)
{
/* draw this point */
*ptr++ = dc->gc.foreground;
}
}
static void rtgui_dc_buffer_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect)
{
rtgui_rect_t r;
struct rtgui_dc_buffer* dc;
r = *rect;
dc = (struct rtgui_dc_buffer*)self;
if (r.x1 > dc->width) r.x1 = dc->width;
if (r.x2 > dc->width) r.x2 = dc->width;
if (r.y1 > dc->height) r.y1 = dc->height;
if (r.y2 > dc->height) r.y2 = dc->height;
/* fill first line */
rtgui_dc_buffer_draw_hline(&(dc->parent), r.x1, r.x2, r.y1);
/* memory copy other lines */
if (r.y2 > r.y1)
{
register rt_base_t index;
for (index = r.y1 + 1; index < r.y2; index ++)
{
rt_memcpy(dc->pixel + index * dc->pitch,
dc->pixel + r.y1 * dc->pitch,
(r.x2 - r.x1) * sizeof(rtgui_color_t));
}
}
}
/* blit a dc to a hardware dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
{
struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
if (dc_point == RT_NULL) dc_point = &rtgui_empty_point;
if (rtgui_dc_get_visible(dest) == RT_FALSE) return;
if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
{
rt_uint8_t *line_ptr, *pixels;
rt_uint16_t rect_width, rect_height, index, pitch;
rtgui_blit_line_func blit_line;
/* calculate correct width and height */
if (rtgui_rect_width(*rect) > (dc->width - dc_point->x))
rect_width = dc->width - dc_point->x;
else
rect_width = rtgui_rect_width(*rect);
if (rtgui_rect_height(*rect) > (dc->height - dc_point->y))
rect_height = dc->height - dc_point->y;
else
rect_height = rtgui_rect_height(*rect);
/* prepare pixel line */
pixels = dc->pixel + dc_point->y * dc->pitch + dc_point->x * sizeof(rtgui_color_t);
if (hw_driver->byte_per_pixel == sizeof(rtgui_color_t))
{
/* it's the same byte per pixel, draw it directly */
for (index = rect->y1; index < rect->y1 + rect_height; index++)
{
dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, pixels);
pixels += dc->width * sizeof(rtgui_color_t);
}
}
else
{
/* get blit line function */
blit_line = rtgui_blit_line_get(hw_driver->byte_per_pixel, 4);
/* calculate pitch */
pitch = rect_width * sizeof(rtgui_color_t);
/* create line buffer */
line_ptr = (rt_uint8_t*) rtgui_malloc(rect_width * hw_driver->byte_per_pixel);
/* draw each line */
for (index = rect->y1; index < rect->y1 + rect_height; index ++)
{
/* blit on line buffer */
blit_line(line_ptr, (rt_uint8_t*)pixels, pitch);
pixels += dc->width * sizeof(rtgui_color_t);
/* draw on hardware dc */
dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, line_ptr);
}
/* release line buffer */
rtgui_free(line_ptr);
}
}
}
static void rtgui_dc_buffer_blit_line(struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
{
rtgui_color_t* color_ptr;
struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
RT_ASSERT(dc != RT_NULL);
RT_ASSERT(line_data != RT_NULL);
/* out of range */
if ((x1 > dc->width) || (y > dc->height)) return;
/* check range */
if (x2 > dc->width) x2 = dc->width;
color_ptr = (rtgui_color_t*)(dc->pixel + y * dc->pitch + x1 * sizeof(rtgui_color_t));
rt_memcpy(color_ptr, line_data, (x2 - x1) * sizeof(rtgui_color_t));
}
static void rtgui_dc_buffer_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
{
struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
dc->gc = *gc;
}
static rtgui_gc_t *rtgui_dc_buffer_get_gc(struct rtgui_dc* self)
{
struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
return &dc->gc;
}
static rt_bool_t rtgui_dc_buffer_get_visible(struct rtgui_dc* dc)
{
return RT_TRUE;
}
static void rtgui_dc_buffer_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
{
struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
rect->x1 = rect->y1 = 0;
rect->x2 = dc->width;
rect->y2 = dc->height;
}
/*
* File : dc_client.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
* 2010-08-09 Bernard rename hardware dc to client dc
* 2010-09-13 Bernard fix rtgui_dc_client_blit_line issue, which found
* by appele
* 2010-09-14 Bernard fix vline and hline coordinate issue
*/
#include <rtgui/dc.h>
#include <rtgui/dc_hw.h>
#include <rtgui/dc_client.h>
#include <rtgui/driver.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/window.h>
#include <panel.h>
static void rtgui_dc_client_draw_point(struct rtgui_dc* dc, int x, int y);
static void rtgui_dc_client_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
static void rtgui_dc_client_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
static void rtgui_dc_client_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
static void rtgui_dc_client_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
static void rtgui_dc_client_blit (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
static void rtgui_dc_client_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
static rtgui_gc_t *rtgui_dc_client_get_gc (struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_client_get_visible(struct rtgui_dc* dc);
static void rtgui_dc_client_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
#define hw_driver (rtgui_graphic_driver_get_default())
#define dc_set_foreground(c) dc->gc.foreground = c
#define dc_set_background(c) dc->gc.background = c
#define _int_swap(x, y) do {x ^= y; y ^= x; x ^= y;} while (0)
struct rtgui_dc* rtgui_dc_begin_drawing(PVOID wdt)
{
rtgui_widget_t *owner = (rtgui_widget_t*)wdt;
RT_ASSERT(owner != RT_NULL);
if ((rtgui_region_is_flat(&owner->clip) == RT_EOK) &&
rtgui_rect_is_equal(&(owner->extent), &(owner->clip.extents)) == RT_EOK)
{
/* use hardware DC */
return rtgui_dc_hw_create(owner);
}
return rtgui_dc_client_create(owner);
}
void rtgui_dc_end_drawing(struct rtgui_dc* dc)
{
dc->engine->fini(dc);
}
const struct rtgui_dc_engine dc_client_engine =
{
rtgui_dc_client_draw_point,
rtgui_dc_client_draw_color_point,
rtgui_dc_client_draw_vline,
rtgui_dc_client_draw_hline,
rtgui_dc_client_fill_rect,
rtgui_dc_client_blit_line,
rtgui_dc_client_blit,
rtgui_dc_client_set_gc,
rtgui_dc_client_get_gc,
rtgui_dc_client_get_visible,
rtgui_dc_client_get_rect,
rtgui_dc_client_fini,
};
void rtgui_dc_client_init(rtgui_widget_t* owner)
{
struct rtgui_dc* dc;
RT_ASSERT(owner != RT_NULL);
dc = RTGUI_WIDGET_DC(owner);
dc->type = RTGUI_DC_CLIENT;
dc->engine = &dc_client_engine;
}
extern struct rt_mutex cursor_mutex;
extern void rtgui_mouse_show_cursor(void);
extern void rtgui_mouse_hide_cursor(void);
struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
{
struct rtgui_dc* dc;
rtgui_widget_t* widget;
/* adjudge owner */
if(owner == RT_NULL)return RT_NULL;
dc = RTGUI_WIDGET_DC(owner);
/* set init visible as true */
RTGUI_WIDGET_DC_SET_VISIBLE(owner);
/* check widget visible */
widget = owner;
while (widget != RT_NULL)
{
if (RTGUI_WIDGET_IS_HIDE(widget))
{
RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
break;
}
widget = widget->parent;
}
return dc;
}
static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
{
// rtgui_widget_t* owner;
//
// if (dc == RT_NULL || dc->type != RTGUI_DC_CLIENT) return RT_FALSE;
//
// /* get owner */
// owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
// if(RTGUI_WIDGET_IS_DC_VISIBLE(owner))
// {
// /* send to server to end drawing */
// rtgui_event_update_t eupdate;
// RTGUI_EVENT_UPDATE_INIT(&(eupdate));
// eupdate.rect = owner->extent;
//
// rtgui_thread_send(rtgui_thread_get_server(), (struct rtgui_event*)&eupdate, sizeof(eupdate));
// }
return RT_TRUE;
}
/*
* draw a logic point on device
*/
static void rtgui_dc_client_draw_point(struct rtgui_dc* self, int x, int y)
{
rtgui_rect_t rect;
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;
y = y + owner->extent.y1;
if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK)
{
/* draw this point */
hw_driver->set_pixel(&(owner->gc.foreground), x, y);
}
}
static void rtgui_dc_client_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color)
{
rtgui_rect_t rect;
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;
y = y + owner->extent.y1;
if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK)
{
/* draw this point */
hw_driver->set_pixel(&color, x, y);
}
}
/*
* 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->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->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2);
}
}
/*
* 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->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->draw_hline(&(owner->gc.foreground), draw_x1, draw_x2, y);
}
}
static void rtgui_dc_client_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect)
{
rtgui_color_t foreground;
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;
/* save foreground color */
foreground = owner->gc.foreground;
/* set background color as foreground color */
owner->gc.foreground = owner->gc.background;
/* fill rect */
for (index = rect->y1; index < rect->y2; index ++)
{
rtgui_dc_client_draw_hline(self, rect->x1, rect->x2, index);
}
/* restore foreground color */
owner->gc.foreground = foreground;
}
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;
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->draw_raw_hline(line_data, 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->draw_raw_hline(line_data + (draw_x1 - x1) * hw_driver->byte_per_pixel, draw_x1, draw_x2, y);
}
}
static void rtgui_dc_client_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
{
/* not blit in hardware dc */
return ;
}
static void rtgui_dc_client_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
{
rtgui_widget_t *owner;
if (self == RT_NULL) return;
/* get owner */
owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
owner->gc = *gc;
}
static rtgui_gc_t* rtgui_dc_client_get_gc(struct rtgui_dc* self)
{
rtgui_widget_t *owner;
RT_ASSERT(self != RT_NULL);
/* get owner */
owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
return &(owner->gc);
}
static rt_bool_t rtgui_dc_client_get_visible(struct rtgui_dc* self)
{
rtgui_widget_t *owner;
if (self == RT_NULL) return RT_FALSE;
/* get owner */
owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return RT_FALSE;
return RT_TRUE;
}
static void rtgui_dc_client_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
{
rtgui_widget_t *owner;
if (self == RT_NULL) return;
/* get owner */
owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
rtgui_widget_get_rect(owner, rect);
}
/*
* File : dc_hw.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/dc.h>
#include <rtgui/dc_hw.h>
#include <rtgui/driver.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/window.h>
static void rtgui_dc_hw_draw_point(struct rtgui_dc* dc, int x, int y);
static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
static void rtgui_dc_hw_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
static void rtgui_dc_hw_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
static void rtgui_dc_hw_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
static void rtgui_dc_hw_blit (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
static void rtgui_dc_hw_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
static rtgui_gc_t *rtgui_dc_hw_get_gc (struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc* dc);
static void rtgui_dc_hw_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
struct rtgui_dc_hw
{
struct rtgui_dc parent;
rtgui_widget_t *owner;
const struct rtgui_graphic_driver* hw_driver;
};
const struct rtgui_dc_engine dc_hw_engine =
{
rtgui_dc_hw_draw_point,
rtgui_dc_hw_draw_color_point,
rtgui_dc_hw_draw_vline,
rtgui_dc_hw_draw_hline,
rtgui_dc_hw_fill_rect,
rtgui_dc_hw_blit_line,
rtgui_dc_hw_blit,
rtgui_dc_hw_set_gc,
rtgui_dc_hw_get_gc,
rtgui_dc_hw_get_visible,
rtgui_dc_hw_get_rect,
rtgui_dc_hw_fini,
};
extern struct rt_mutex cursor_mutex;
extern void rtgui_mouse_show_cursor(void);
extern void rtgui_mouse_hide_cursor(void);
struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
{
struct rtgui_dc_hw* dc;
rtgui_widget_t* widget;
/* adjudge owner */
if (owner == RT_NULL) return RT_NULL;
/* set init visible as true */
RTGUI_WIDGET_DC_SET_VISIBLE(owner);
/* check widget visible */
widget = owner;
while (widget != RT_NULL)
{
if (RTGUI_WIDGET_IS_HIDE(widget))
{
RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
break;
}
widget = widget->parent;
}
if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return RT_NULL;
/* create DC */
dc = (struct rtgui_dc_hw*) rtgui_malloc(sizeof(struct rtgui_dc_hw));
if(dc == RT_NULL)return RT_NULL;
dc->parent.type = RTGUI_DC_HW;
dc->parent.engine = &dc_hw_engine;
dc->owner = owner;
dc->hw_driver = rtgui_graphic_driver_get_default();
return &(dc->parent);
}
static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
{
struct rtgui_dc_hw* self;
if (dc == RT_NULL || dc->type != RTGUI_DC_HW) return RT_FALSE;
self = (struct rtgui_dc_hw*)dc;
/* release hardware dc */
rtgui_free(self);
return RT_TRUE;
}
/*
* draw a logic point on device
*/
static void rtgui_dc_hw_draw_point(struct rtgui_dc* self, int x, int y)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
x = x + dc->owner->extent.x1;
y = y + dc->owner->extent.y1;
/* draw this point */
dc->hw_driver->set_pixel(&(dc->owner->gc.foreground), x, y);
}
static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
x = x + dc->owner->extent.x1;
y = y + dc->owner->extent.y1;
/* draw this point */
dc->hw_driver->set_pixel(&color, x, y);
}
/*
* draw a logic vertical line on device
*/
static void rtgui_dc_hw_draw_vline(struct rtgui_dc* self, int x, int y1, int y2)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
x = x + dc->owner->extent.x1;
y1 = y1 + dc->owner->extent.y1;
y2 = y2 + dc->owner->extent.y1;
/* draw vline */
dc->hw_driver->draw_vline(&(dc->owner->gc.foreground), x, y1, y2);
}
/*
* draw a logic horizontal line on device
*/
static void rtgui_dc_hw_draw_hline(struct rtgui_dc* self, int x1, int x2, int y)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
/* convert logic to device */
x1 = x1 + dc->owner->extent.x1;
x2 = x2 + dc->owner->extent.x1;
y = y + dc->owner->extent.y1;
/* draw hline */
dc->hw_driver->draw_hline(&(dc->owner->gc.foreground), x1, x2, y);
}
static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect)
{
rtgui_color_t color;
register rt_base_t index, x1, x2;
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
/* get background color */
color = dc->owner->gc.background;
/* convert logic to device */
x1 = rect->x1 + dc->owner->extent.x1;
x2 = rect->x2 + dc->owner->extent.x1;
/* fill rect */
for (index = dc->owner->extent.y1 + rect->y1; index < dc->owner->extent.y1 + rect->y2; index ++)
{
dc->hw_driver->draw_hline(&color, x1, x2, index);
}
}
static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
/* convert logic to device */
x1 = x1 + dc->owner->extent.x1;
x2 = x2 + dc->owner->extent.x1;
y = y + dc->owner->extent.y1;
dc->hw_driver->draw_raw_hline(line_data, x1, x2, y);
}
static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
{
/* not blit in hardware dc */
return ;
}
static void rtgui_dc_hw_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
/* set gc */
dc->owner->gc = *gc;
}
static rtgui_gc_t* rtgui_dc_hw_get_gc(struct rtgui_dc* self)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
return &(dc->owner->gc);
}
static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc* self)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
if (!RTGUI_WIDGET_IS_DC_VISIBLE(dc->owner)) return RT_FALSE;
return RT_TRUE;
}
static void rtgui_dc_hw_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
{
struct rtgui_dc_hw* dc;
RT_ASSERT(self != RT_NULL);
dc = (struct rtgui_dc_hw*) self;
/* get owner */
rtgui_widget_get_rect(dc->owner, rect);
}
/*
* File : filerw.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/filerw.h>
#include <rtgui/rtgui_system.h>
#ifdef RTGUI_USING_DFS_FILERW
#include <dfs_posix.h>
/* standard file read/write */
struct rtgui_filerw_stdio
{
/* inherit from rtgui_filerw */
struct rtgui_filerw parent;
int fd;
rt_bool_t eof;
};
static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
{
return -1;
}
return lseek(stdio_filerw->fd, offset, stdio_whence[whence]);
}
static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
{
int result;
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
/* end of file */
if (stdio_filerw->eof == RT_TRUE) return -1;
result = read(stdio_filerw->fd, ptr, size * maxnum);
if (result == 0) stdio_filerw->eof = RT_TRUE;
return result;
}
static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
return write(stdio_filerw->fd, (char*)ptr, size * num);
}
static int stdio_tell(struct rtgui_filerw* context)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
return lseek(stdio_filerw->fd, 0, SEEK_CUR);
}
static int stdio_eof(struct rtgui_filerw* context)
{
int result;
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
if (stdio_filerw->eof == RT_TRUE) result = 1;
else result = -1;
return result;
}
static int stdio_close(struct rtgui_filerw *context)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
if (stdio_filerw)
{
close(stdio_filerw->fd);
rtgui_free(stdio_filerw);
return 0;
}
return -1;
}
#elif defined(RTGUI_USING_STDIO_FILERW)
#include <stdio.h>
/* standard file read/write */
struct rtgui_filerw_stdio
{
/* inherit from rtgui_filerw */
struct rtgui_filerw parent;
FILE* fp;
};
static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
{
return -1;
}
if (fseek(stdio_filerw->fp, offset, stdio_whence[whence]) == 0)
{
return ftell(stdio_filerw->fp);
}
return -1;
}
static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
{
size_t nread;
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
nread = fread(ptr, size, maxnum, stdio_filerw->fp);
if (nread == 0 && ferror(stdio_filerw->fp))
{
return -1;
}
return nread;
}
static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
{
size_t nwrote;
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
nwrote = fwrite(ptr, size, num, stdio_filerw->fp);
if ( nwrote == 0 && ferror(stdio_filerw->fp) )
{
return -1;
}
return nwrote;
}
static int stdio_tell(struct rtgui_filerw* context)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
return ftell(stdio_filerw->fp);
}
static int stdio_eof(struct rtgui_filerw* context)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
return feof(stdio_filerw->fp);
}
static int stdio_close(struct rtgui_filerw *context)
{
struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
if (stdio_filerw)
{
fclose(stdio_filerw->fp);
rtgui_free(stdio_filerw);
return 0;
}
return -1;
}
#endif
/* memory file read/write */
struct rtgui_filerw_mem
{
/* inherit from rtgui_filerw */
struct rtgui_filerw parent;
const rt_uint8_t *mem_base, *mem_position, *mem_end;
};
static int mem_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
{
const rt_uint8_t* newpos;
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
RT_ASSERT(mem != RT_NULL);
switch (whence) {
case RTGUI_FILE_SEEK_SET:
newpos = mem->mem_base + offset;
break;
case RTGUI_FILE_SEEK_CUR:
newpos = mem->mem_position + offset;
break;
case RTGUI_FILE_SEEK_END:
newpos = mem->mem_end + offset;
break;
default:
return -1;
}
if ( newpos < mem->mem_base )
newpos = mem->mem_base;
if ( newpos > mem->mem_end )
newpos = mem->mem_end;
mem->mem_position = newpos;
return mem->mem_position- mem->mem_base;
}
static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
{
int total_bytes;
int mem_available;
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
total_bytes = (maxnum * size);
if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) )
{
return -1;
}
mem_available = mem->mem_end - mem->mem_position;
if (total_bytes > mem_available)
total_bytes = mem_available;
rt_memcpy(ptr, mem->mem_position, total_bytes);
mem->mem_position += total_bytes;
return (total_bytes / size);
}
static int mem_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
{
#if 0
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
if ((mem->mem_position + (num * size)) > mem->mem_end)
{
num = (mem->mem_end - mem->mem_position)/size;
}
rt_memcpy(mem->mem_position, ptr, num*size);
mem->mem_position += num*size;
return num;
#else
return 0; /* not support memory write */
#endif
}
static int mem_tell(struct rtgui_filerw* context)
{
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
return mem->mem_position - mem->mem_base;
}
static int mem_eof(struct rtgui_filerw* context)
{
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
return mem->mem_position >= mem->mem_end;
}
static int mem_close(struct rtgui_filerw *context)
{
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
if (mem != RT_NULL)
{
rtgui_free(mem);
return 0;
}
return -1;
}
const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context)
{
struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
/* check whether it's a memory filerw */
if (mem->parent.read != mem_read) return RT_NULL;
return mem->mem_base;
}
/* file read/write public interface */
#ifdef RTGUI_USING_DFS_FILERW
static int parse_mode(const char *mode)
{
int f=0;
for (;;)
{
switch (*mode)
{
case 0: return f;
case 'b': break;
case 'r': f=O_RDONLY; break;
case 'w': f=O_WRONLY|O_CREAT|O_TRUNC; break;
case 'a': f=O_WRONLY|O_CREAT|O_APPEND; break;
case '+': f=(f&(~O_WRONLY))|O_RDWR; break;
}
++mode;
}
}
struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
{
int fd;
struct rtgui_filerw_stdio *rw;
RT_ASSERT(filename != RT_NULL);
rw = RT_NULL;
fd = open(filename, parse_mode(mode), 0);
if ( fd >= 0 )
{
rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
if (rw != RT_NULL)
{
rw->parent.seek = stdio_seek;
rw->parent.read = stdio_read;
rw->parent.write = stdio_write;
rw->parent.tell = stdio_tell;
rw->parent.close = stdio_close;
rw->parent.eof = stdio_eof;
rw->fd = fd;
rw->eof = RT_FALSE;
}
}
return &(rw->parent);
}
#elif defined(RTGUI_USING_STDIO_FILERW)
struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
{
FILE *fp;
struct rtgui_filerw_stdio *rw;
RT_ASSERT(filename != RT_NULL);
rw = RT_NULL;
fp = fopen(filename, mode);
if ( fp != RT_NULL )
{
rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
if (rw != RT_NULL)
{
rw->parent.seek = stdio_seek;
rw->parent.read = stdio_read;
rw->parent.write = stdio_write;
rw->parent.tell = stdio_tell;
rw->parent.close = stdio_close;
rw->parent.eof = stdio_eof;
rw->fp = fp;
}
}
return &(rw->parent);
}
#endif
struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size)
{
struct rtgui_filerw_mem* rw;
RT_ASSERT(mem != RT_NULL);
rw = (struct rtgui_filerw_mem*) rtgui_malloc(sizeof(struct rtgui_filerw_mem));
if (rw != RT_NULL)
{
rw->parent.seek = mem_seek;
rw->parent.read = mem_read;
rw->parent.write = mem_write;
rw->parent.tell = mem_tell;
rw->parent.eof = mem_eof;
rw->parent.close = mem_close;
rw->mem_base = mem;
rw->mem_position = mem;
rw->mem_end = mem + size;
}
return &(rw->parent);
}
int rtgui_filerw_seek(struct rtgui_filerw* context, rt_off_t offset, int whence)
{
RT_ASSERT(context != RT_NULL);
return context->seek(context, offset, whence);
}
int rtgui_filerw_read(struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count)
{
RT_ASSERT(context != RT_NULL);
return context->read(context, buffer, size, count);
}
int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count)
{
RT_ASSERT(context != RT_NULL);
return context->write(context, buffer, size, count);
}
int rtgui_filerw_eof (struct rtgui_filerw* context)
{
RT_ASSERT(context != RT_NULL);
return context->eof(context);
}
int rtgui_filerw_tell(struct rtgui_filerw* context)
{
RT_ASSERT(context != RT_NULL);
return context->tell(context);
}
int rtgui_filerw_close(struct rtgui_filerw* context)
{
int result;
RT_ASSERT(context != RT_NULL);
/* close context */
result = context->close(context);
if (result != 0)
{
/* close file failed */
return -1;
}
return 0;
}
/*
* File : font.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtgui/font.h>
#include <rtgui/dc.h>
static rtgui_list_t _rtgui_font_list;
static rtgui_font_t* rtgui_default_font;
extern rtgui_font_t rtgui_font_asc12;
extern rtgui_font_t rtgui_font_asc16;
/* extern rtgui_font_t rtgui_font_arial16; */
/* extern rtgui_font_t rtgui_font_arial12; */
#ifdef RTGUI_USING_FONTHZ
extern rtgui_font_t rtgui_font_hz16;
extern rtgui_font_t rtgui_font_hz12;
#endif
void rtgui_font_system_init()
{
rtgui_list_init(&(_rtgui_font_list));
/* set default font to RT_NULL */
rtgui_default_font = RT_NULL;
#ifdef RTGUI_USING_FONT16
rtgui_font_system_add_font(&rtgui_font_asc16);
#ifdef RTGUI_USING_FONTHZ
rtgui_font_system_add_font(&rtgui_font_hz16);
#endif
#endif
#ifdef RTGUI_USING_FONT12
rtgui_font_system_add_font(&rtgui_font_asc12);
#ifdef RTGUI_USING_FONTHZ
rtgui_font_system_add_font(&rtgui_font_hz12);
#endif
#endif
#ifdef RTGUI_USING_FONT12
if (rtgui_default_font == RT_NULL)
rtgui_font_set_defaut(&rtgui_font_asc12);
#endif
#ifdef RTGUI_USING_FONT16
if (rtgui_default_font == RT_NULL)
rtgui_font_set_defaut(&rtgui_font_asc16);
#endif
}
void rtgui_font_system_add_font(rtgui_font_t* font)
{
rtgui_list_init(&(font->list));
rtgui_list_append(&_rtgui_font_list, &(font->list));
/* init font */
if(font->engine->font_init != RT_NULL)
font->engine->font_init(font);
/* first refer, load it */
if(font->engine->font_load != RT_NULL)
font->engine->font_load(font);
}
void rtgui_font_system_remove_font(rtgui_font_t* font)
{
rtgui_list_remove(&_rtgui_font_list, &(font->list));
}
rtgui_font_t* rtgui_font_default(void)
{
return rtgui_default_font;
}
void rtgui_font_set_defaut(rtgui_font_t* font)
{
rtgui_default_font = font;
}
rtgui_font_t* rtgui_font_refer(const rt_uint8_t* family, rt_uint16_t height)
{
/* search font */
rtgui_list_t* node;
rtgui_font_t* font;
rtgui_list_foreach(node, &_rtgui_font_list)
{
font = rtgui_list_entry(node, rtgui_font_t, list);
if((rt_strncmp((const char*)font->family, (const char*)family, RTGUI_NAME_MAX) == 0) &&
font->height == height)
{
font->refer_count ++;
return font;
}
}
return RT_NULL;
}
void rtgui_font_derefer(rtgui_font_t* font)
{
RT_ASSERT(font != RT_NULL);
font->refer_count --;
/* no refer, remove font */
if(font->refer_count == 0)
{
rtgui_font_system_remove_font(font);
}
}
/* draw a text */
void rtgui_font_draw(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect)
{
RT_ASSERT(font != RT_NULL);
if(font->engine != RT_NULL && font->engine->font_draw_text != RT_NULL)
{
font->engine->font_draw_text(font, dc, text, len, rect);
}
}
int rtgui_font_get_string_width(rtgui_font_t *font, const char* text)
{
rtgui_rect_t rect;
/* get metrics */
rtgui_font_get_string_rect(font, text, &rect);
return rect.x2 - rect.x1;
}
int rtgui_font_get_font_width(rtgui_font_t* font)
{
rtgui_rect_t rect;
char *text = "H";
/* get metrics */
rtgui_font_get_string_rect(font, text, &rect);
return rect.x2 - rect.x1;
}
int rtgui_font_get_font_height(rtgui_font_t* font)
{
rtgui_rect_t rect;
char *text = "H";
/* get metrics */
rtgui_font_get_string_rect(font, text, &rect);
return rect.y2 - rect.y1;
}
void rtgui_font_get_string_rect(rtgui_font_t* font, const char* text, rtgui_rect_t* rect)
{
RT_ASSERT(font != RT_NULL);
if(font->engine != RT_NULL && font->engine->font_get_metrics != RT_NULL)
{
font->engine->font_get_metrics(font, text, rect);
}
else
{
/* no font engine found, set rect to zero */
rt_memset(rect, 0, sizeof(rtgui_rect_t));
}
}
void rtgui_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect)
{
RT_ASSERT(font != RT_NULL);
if (font->engine != RT_NULL &&
font->engine->font_get_metrics != RT_NULL)
{
font->engine->font_get_metrics(font, text, rect);
}
else
{
/* no font engine found, set rect to zero */
rt_memset(rect, 0, sizeof(rtgui_rect_t));
}
}
static void rtgui_bitmap_font_draw_text(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect);
static void rtgui_bitmap_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect);
const struct rtgui_font_engine bmp_font_engine =
{
RT_NULL,
RT_NULL,
rtgui_bitmap_font_draw_text,
rtgui_bitmap_font_get_metrics
};
void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, rtgui_dc_t *dc, const char ch, rtgui_rect_t* rect)
{
const rt_uint8_t* font_ptr;
rt_uint16_t x, y, h;
register rt_int32_t i, j, k, word_bytes;
/* check first and last char */
if(ch < font->first_char || ch > font->last_char) return;
x = rect->x1;
y = rect->y1;
/* get width */
if (font->char_width == RT_NULL)
{
word_bytes = (((font->width - 1) / 8) + 1);
font_ptr = font->bmp + (ch - font->first_char) * word_bytes * font->height;
}
else
{
word_bytes = ((font->char_width[ch - font->first_char] - 1)/8) + 1;
font_ptr = font->bmp + font->offset[ch - font->first_char];
}
h = (font->height + y > rect->y2) ? rect->y2 - rect->y1 : font->height;
for(i = 0; i < h; i++)
{
for(j = 0; j < word_bytes; j++)
{
for(k = 0; k < 8; k++)
{
if(((font_ptr[i * word_bytes + j] >> (7 - k)) & 0x01) != 0)
{
/* draw a pixel */
rtgui_dc_draw_point(dc,k + 8 * j + x, i + y);
}
}
}
}
}
static void rtgui_bitmap_font_draw_text(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect)
{
rt_uint32_t length;
struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
#ifdef RTGUI_USING_FONTHZ
struct rtgui_font* hz_font;
RT_ASSERT(bmp_font != RT_NULL);
hz_font = rtgui_font_refer("hz", font->height);
while ((rect->x1 < rect->x2) && len)
{
length = 0;
while ((rt_uint8_t)*(text + length) >= 0x80) length ++; /* it's not a ascii character */
if (length > 0)
{
if (hz_font != RT_NULL)
rtgui_font_draw(hz_font, dc, text, length, rect);
text += length;
len -= length;
}
length = 0;
while (((rt_uint8_t)*(text + length) < 0x80) && *(text + length)) length ++;
if (length > 0)
{
len -= length;
while (length-- && rect->x1 < rect->x2)
{
rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
/* move x to next character */
if (bmp_font->char_width == RT_NULL)
rect->x1 += bmp_font->width;
else
rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
text ++;
}
}
}
rtgui_font_derefer(hz_font);
#else
while ((rect->x1 < rect->x2) && len)
{
while (((rt_uint8_t)*(text + length) < 0x80) && *(text + length)) length ++;
if (length > 0)
{
len -= length;
while (length-- && rect->x1 < rect->x2)
{
rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
/* move x to next character */
if (bmp_font->char_width == RT_NULL)
rect->x1 += bmp_font->width;
else
rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
text ++;
}
}
}
#endif
}
static void rtgui_bitmap_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect)
{
rt_uint32_t length;
struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
RT_ASSERT(bmp_font != RT_NULL);
/* set init metrics rect */
rect->x1 = rect->y1 = 0;rect->x2 = 0;
rect->y2 = bmp_font->height;
while (*text)
{
length = 0;
while (*(text + length) >= 0x80) length ++; /* it's not a ascii character */
rect->x2 += (font->height/2) * length;
text += length;
length = 0;
while ((*(text + length) < 0x80) && *(text + length)) length ++;
if (bmp_font->char_width != RT_NULL)
{
/* get width for each character */
while (*text && (*text < 0x80))
{
rect->x2 += bmp_font->char_width[*text - bmp_font->first_char];
text ++;
}
}
else
{
/* set metrics rect */
rect->x2 += bmp_font->width * length;
text += length;
}
}
}
#include <rtgui/font_freetype.h>
#ifdef RTGUI_USING_TTF
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect);
static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect);
struct rtgui_font_engine freetype_font_engine =
{
RT_NULL,
RT_NULL,
rtgui_freetype_font_draw_text,
rtgui_freetype_font_get_metrics
};
struct rtgui_freetype_font
{
int bold;
int italic;
FT_Face face;
FT_Library library;
};
static void gbk_to_unicode(rt_uint16_t *unicode, const unsigned char *text, int len)
{
int i;
unsigned short wch;
extern unsigned short ff_convert(unsigned short wch, int direction);
for (i = 0; i < len; )
{
if (*text < 0x80)
{
wch = *text;
*unicode = ff_convert(wch, 1);
text ++;
i ++;
}
else
{
wch = wch = *(text + 1) | (*text << 8);
*unicode = ff_convert(wch, 1);
text += 2;
i += 2;
}
unicode ++;
}
*unicode = '\0';
}
static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect)
{
int index = 0;
FT_Error err = 0;
rt_uint16_t *text_short, *text_ptr;
struct rtgui_freetype_font* freetype;
RT_ASSERT(font != RT_NULL);
freetype = (struct rtgui_freetype_font*) font->data;
RT_ASSERT(freetype != RT_NULL);
/* allocate unicode buffer */
text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
if (text_short == RT_NULL) return ; /* out of memory */
/* convert gbk to unicode */
gbk_to_unicode(text_short, text, len);
text_ptr = text_short;
while (*text_ptr)
{
index = FT_Get_Char_Index(freetype->face, *text_ptr);
err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT|FT_LOAD_RENDER);
if (err == 0)
{
int rows, x;
rt_uint8_t* ptr;
/* render font */
ptr = (rt_uint8_t*)freetype->face->glyph->bitmap.buffer;
for (rows = 0; rows < freetype->face->glyph->bitmap.rows; rows ++)
for (x = 0; x < freetype->face->glyph->bitmap.width; x++)
{
if (*ptr > 0)
rtgui_dc_draw_color_point(dc, rect->x1 + x, rect->y1 + rows, RTGUI_RGB(0xff - *ptr, 0xff - *ptr, 0xff - *ptr));
ptr ++;
}
}
text_ptr ++;
rect->x1 += freetype->face->glyph->bitmap.width;
}
/* release unicode buffer */
rtgui_free(text_short);
}
static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect)
{
int index = 0, len;
FT_Error err = 0;
rt_uint16_t w = 0, h = 0;
rt_uint16_t *text_short, *text_ptr;
struct rtgui_freetype_font* freetype;
RT_ASSERT(font != RT_NULL);
RT_ASSERT(rect != RT_NULL);
freetype = (struct rtgui_freetype_font*) font->data;
RT_ASSERT(freetype != RT_NULL);
len = strlen(text);
memset(rect, 0, sizeof(struct rtgui_rect));
/* allocate unicode buffer */
text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
if (text_short == RT_NULL) return ; /* out of memory */
/* convert gbk to unicode */
gbk_to_unicode(text_short, text, len);
text_ptr = text_short;
while (*text_ptr)
{
index = FT_Get_Char_Index(freetype->face, *text_ptr);
err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT);
if (err == 0)
{
w += freetype->face->glyph->bitmap.width;
if (freetype->face->glyph->bitmap.rows > h)
{
h = freetype->face->glyph->bitmap.rows;
}
}
text_ptr ++;
}
rect->x1 = 0; rect->y1 = 0;
rect->x2 = w; rect->y2 = h;
/* release unicode buffer */
rtgui_free(text_short);
}
rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int italic, rt_size_t size)
{
FT_Error err = 0;
struct rtgui_font* font;
font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font));
if (font != RT_NULL)
{
struct rtgui_freetype_font* freetype;
freetype = (struct rtgui_freetype_font*) rtgui_malloc (sizeof(struct rtgui_freetype_font));
if (freetype == RT_NULL)
{
rt_free(font);
font = RT_NULL;
}
else
{
err = FT_Init_FreeType(&freetype->library);
if((err = FT_New_Face(freetype->library, filename, 0, &freetype->face)))
{
FT_Done_FreeType(freetype->library);
rt_free(font);
font = RT_NULL;
}
else
{
err = FT_Select_Charmap(freetype->face, ft_encoding_unicode);
if(err)
{
err = FT_Select_Charmap(freetype->face, ft_encoding_latin_1 );
}
err = FT_Set_Pixel_Sizes(freetype->face, 0, size);
if (err != 0)
{
rtgui_free(font);
font = RT_NULL;
FT_Done_FreeType(freetype->library);
rtgui_free(freetype);
return RT_NULL;
}
freetype->bold = bold;
freetype->italic = italic;
rt_kprintf("fonfile:%s\n", filename);
rt_kprintf("font family_name:%s\n", freetype->face->family_name);
rt_kprintf("font style_name:%s\n", freetype->face->style_name);
/* set user data */
font->data = freetype;
font->family = rt_strdup(freetype->face->family_name);
font->height = (rt_uint16_t)size;
font->refer_count = 0;
font->engine = &freetype_font_engine;
/* add to system */
rtgui_font_system_add_font(font);
}
}
}
return font;
}
void rtgui_freetype_font_destroy(rtgui_font_t* font)
{
struct rtgui_freetype_font* freetype;
RT_ASSERT(font != RT_NULL);
freetype = (struct rtgui_freetype_font*) font->data;
RT_ASSERT(freetype != RT_NULL);
rtgui_font_system_remove_font(font);
FT_Done_Face (freetype->face);
FT_Done_FreeType(freetype->library);
rtgui_free(freetype);
rtgui_free(font);
}
#endif
#include <rtgui/dc.h>
#include <rtgui/font.h>
#ifdef RTGUI_USING_HZ_BMP
static void rtgui_hz_bitmap_font_draw_text(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect);
static void rtgui_hz_bitmap_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect);
const struct rtgui_font_engine hz_bmp_font_engine =
{
RT_NULL,
RT_NULL,
rtgui_hz_bitmap_font_draw_text,
rtgui_hz_bitmap_font_get_metrics
};
static void _rtgui_hz_bitmap_font_draw_text(struct rtgui_font_bitmap* bmp_font, rtgui_dc_t *dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect)
{
register rt_base_t h, word_bytes;
rt_uint8_t* str;
RT_ASSERT(bmp_font != RT_NULL);
/* drawing height */
h = (bmp_font->height + rect->y1 > rect->y2)? rect->y2 - rect->y1 : bmp_font->height;
word_bytes = (bmp_font->width + 7)/8;
str = (rt_uint8_t*)text;
while (len > 0 && rect->x1 < rect->x2)
{
const rt_uint8_t* font_ptr;
rt_ubase_t sect, index;
register rt_base_t i, j, k;
/* calculate section and index */
sect = *str - 0xA0;
index = *(str+1) - 0xA0;
/* get font pixel data */
font_ptr = bmp_font->bmp + ( 94*(sect-1) + (index-1) )*(bmp_font->width + bmp_font->height);
/* draw word */
for (i=0; i < h; i ++)
{
for (j=0; j < word_bytes; j++)
for (k=0; k < 8; k++)
{
if ( ((font_ptr[i*2 + j] >> (7-k)) & 0x01) != 0 &&
(rect->x1 + 8 * j + k < rect->x2))
{
rtgui_dc_draw_point(dc, rect->x1 + 8*j + k, rect->y1 + i);
}
}
}
/* move x to next character */
rect->x1 += bmp_font->width;
str += 2;
len -= 2;
}
}
static void rtgui_hz_bitmap_font_draw_text (struct rtgui_font* font, rtgui_dc_t *dc, const char* text, rt_ubase_t length, struct rtgui_rect* rect)
{
rt_uint32_t len;
struct rtgui_font *efont;
struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
RT_ASSERT(dc != RT_NULL);
/* get English font */
efont = rtgui_font_refer("asc", bmp_font->height);
if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */
while (length > 0)
{
len = 0;
while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++;
/* draw text with English font */
if (len > 0)
{
rtgui_font_draw(efont, dc, text, len, rect);
text += len;
length -= len;
}
len = 0;
while (((rt_uint8_t)*(text + len)) >= 0x80) len ++;
if (len > 0)
{
_rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect);
text += len;
length -= len;
}
}
rtgui_font_derefer(efont);
}
static void rtgui_hz_bitmap_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect)
{
struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
RT_ASSERT(bmp_font != RT_NULL);
/* set metrics rect */
rect->x1 = rect->y1 = 0;
rect->x2 = (rt_int16_t)(bmp_font->width * rt_strlen((const char*)text));
rect->y2 = bmp_font->height;
}
#endif
/*
* Cached HZ font engine
*/
#include <rtgui/dc.h>
#include <rtgui/font.h>
#include <rtgui/tree.h>
#include <rtgui/rtgui_system.h>
#ifdef RTGUI_USING_HZ_FILE
#include <dfs_posix.h>
#define HZ_CACHE_MAX 64
static int _font_cache_compare(struct hz_cache* node1, struct hz_cache* node2);
static void rtgui_hz_file_font_load(rtgui_font_t* font);
static void rtgui_hz_file_font_draw_text(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect);
static void rtgui_hz_file_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect);
const struct rtgui_font_engine rtgui_hz_file_font_engine =
{
RT_NULL,
rtgui_hz_file_font_load,
rtgui_hz_file_font_draw_text,
rtgui_hz_file_font_get_metrics
};
SPLAY_PROTOTYPE(cache_tree, hz_cache, hz_node, _font_cache_compare);
SPLAY_GENERATE (cache_tree, hz_cache, hz_node, _font_cache_compare);
static int _font_cache_compare(struct hz_cache* cache_1, struct hz_cache* cache_2)
{
if(cache_1->hz_id > cache_2->hz_id) return 1;
if(cache_1->hz_id < cache_2->hz_id) return -1;
return 0;
}
static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t hz_id)
{
rt_uint32_t seek;
struct hz_cache *cache, search;
search.hz_id = hz_id;
cache = SPLAY_FIND(cache_tree, &(font->cache_root), &search);
if(cache != RT_NULL)
{
/* find it */
return (rt_uint8_t*)(cache + 1);
}
/* can not find it, load to cache */
cache = (struct hz_cache*) rt_malloc(sizeof(struct hz_cache) + font->font_data_size);
if(cache == RT_NULL) return RT_NULL; /* no memory yet */
cache->hz_id = hz_id;
seek = 94 * (((hz_id & 0xff) - 0xA0) - 1) + ((hz_id >> 8) - 0xA0) - 1;
seek *= font->font_data_size;
/* read hz font data */
if((lseek(font->fd, seek, SEEK_SET) < 0) ||
read(font->fd, (char*)(cache + 1), font->font_data_size) !=
font->font_data_size)
{
rt_free(cache);
return RT_NULL;
}
/* insert to cache */
SPLAY_INSERT(cache_tree, &(font->cache_root), cache);
font->cache_size ++;
if(font->cache_size > HZ_CACHE_MAX)
{
/* remove a cache */
struct hz_cache* left;
left = font->cache_root.sph_root;
while(SPLAY_LEFT(left, hz_node) != RT_NULL) left = SPLAY_LEFT(left, hz_node);
/* remove the left node */
SPLAY_REMOVE(cache_tree, &(font->cache_root), left);
font->cache_size --;
}
return (rt_uint8_t*)(cache + 1);
}
static void rtgui_hz_file_font_load(rtgui_font_t* font)
{
struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data;
RT_ASSERT(hz_file_font != RT_NULL);
hz_file_font->fd = open(hz_file_font->font_fn, O_RDONLY, 0);
}
static void rtgui_hz_file_font_draw_text(rtgui_font_t* font, rtgui_dc_t *dc, const char* text, rt_uint32_t len, rtgui_rect_t* rect)
{
register rt_int32_t h, word_bytes;
rt_uint8_t* str;
struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data;
RT_ASSERT(hz_file_font != RT_NULL);
/* drawing height */
h = (hz_file_font->font_size + rect->y1 > rect->y2)?
rect->y2 - rect->y1 : hz_file_font->font_size;
word_bytes = (hz_file_font->font_size + 7) / 8;
str = (rt_uint8_t*)text;
while(len > 0 && rect->x1 < rect->x2)
{
const rt_uint8_t* font_ptr;
register rt_int32_t i, j, k;
/* get font pixel data */
font_ptr = _font_cache_get(hz_file_font, *str | (*(str+1) << 8));
/* draw word */
for(i=0; i < h; i ++)
{
for(j=0; j < word_bytes; j++)
for(k=0; k < 8; k++)
{
if( ((font_ptr[i*2 + j] >> (7-k)) & 0x01) != 0 &&
(rect->x1 + 8 * j + k < rect->x2))
{
rtgui_dc_draw_color_point(dc, rect->x1 + 8*j + k, rect->y1 + i, color);
}
}
}
/* move x to next character */
rect->x1 += hz_file_font->font_size;
str += 2;
len -= 2;
}
}
static void rtgui_hz_file_font_get_metrics(rtgui_font_t* font, const char* text, rtgui_rect_t* rect)
{
struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data;
RT_ASSERT(hz_file_font != RT_NULL);
/* set metrics rect */
rect->x1 = rect->y1 = 0;
rect->x2 = (rt_int16_t)(hz_file_font->font_size/2 * rt_strlen((const char*)text));
rect->y2 = hz_file_font->font_size;
}
#endif
此差异已折叠。
此差异已折叠。
/*
* File : image.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
*/
#include <rtthread.h>
#include <rtgui/image.h>
#include <rtgui/image_xpm.h>
#include <rtgui/image_hdc.h>
#include <rtgui/rtgui_system.h>
#include <string.h>
#ifdef RTGUI_IMAGE_BMP
#include <rtgui/image_bmp.h>
#endif
#ifdef RTGUI_IMAGE_JPEG
#include <rtgui/image_jpeg.h>
#endif
#ifdef RTGUI_IMAGE_PNG
#include <rtgui/image_png.h>
#endif
static rtgui_list_t _rtgui_system_image_list = {RT_NULL};
/* init rtgui image system */
void rtgui_system_image_init(void)
{
/* always support XPM image */
rtgui_image_xpm_init();
rtgui_image_hdc_init();
#ifdef RTGUI_IMAGE_BMP
rtgui_image_bmp_init();
#endif
#ifdef RTGUI_IMAGE_JPEG
rtgui_image_jpeg_init();
#endif
#ifdef RTGUI_IMAGE_PNG
rtgui_image_png_init();
#endif
}
static struct rtgui_image_engine* rtgui_image_get_engine(const char* type)
{
rtgui_list_t *node;
struct rtgui_image_engine *engine;
rtgui_list_foreach(node, &_rtgui_system_image_list)
{
engine = rtgui_list_entry(node, struct rtgui_image_engine, list);
if(strncasecmp(engine->name, type, strlen(engine->name)) ==0)
return engine;
}
return RT_NULL;
}
#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
rtgui_image_t* rtgui_image_create_from_file(const char* type, const char* filename, rt_bool_t load)
{
struct rtgui_filerw* file;
struct rtgui_image_engine* engine;
rtgui_image_t* image = RT_NULL;
/* create filerw context */
file = rtgui_filerw_create_file(filename, "rb");
if(file == RT_NULL) return RT_NULL;
/* get image engine */
engine = rtgui_image_get_engine(type);
if(engine == RT_NULL)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
if(engine->image_check(file) == RT_TRUE)
{
image = (rtgui_image_t*) rt_malloc(sizeof(rtgui_image_t));
if(image == RT_NULL)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
if(engine->image_load(image, file, load) != RT_TRUE)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
/* set image engine */
image->engine = engine;
}
else
{
rtgui_filerw_close(file);
}
return image;
}
#endif
rtgui_image_t* rtgui_image_create_from_mem(const char* type, const rt_uint8_t* data, rt_size_t length, rt_bool_t load)
{
struct rtgui_filerw* file;
struct rtgui_image_engine* engine;
rtgui_image_t* image = RT_NULL;
/* create filerw context */
file = rtgui_filerw_create_mem(data, length);
if(file == RT_NULL) return RT_NULL;
/* ȡͼget image engine */
engine = rtgui_image_get_engine(type);
if(engine == RT_NULL)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
if(engine->image_check(file) == RT_TRUE)
{
image = (rtgui_image_t*)rt_malloc(sizeof(rtgui_image_t));
if(image == RT_NULL)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
if(engine->image_load(image, file, load) != RT_TRUE)
{
/* close filerw context */
rtgui_filerw_close(file);
return RT_NULL;
}
/* set image engine */
image->engine = engine;
}
else
{
rtgui_filerw_close(file);
}
return image;
}
void rtgui_image_destroy(rtgui_image_t* image)
{
RT_ASSERT(image != RT_NULL);
image->engine->image_unload(image);
rt_free(image);
}
/* register an image engine */
void rtgui_image_register_engine(struct rtgui_image_engine* engine)
{
RT_ASSERT(engine!= RT_NULL);
rtgui_list_append(&_rtgui_system_image_list, &(engine->list));
}
void rtgui_image_blit(rtgui_image_t *image, rtgui_dc_t *dc, rtgui_rect_t *rect)
{
RT_ASSERT(rect != RT_NULL);
if(image != RT_NULL && image->engine != RT_NULL)
{
/* use image engine to blit */
image->engine->image_blit(image, dc, rect);
}
}
void rtgui_image_paste(rtgui_image_t *image, rtgui_dc_t *dc, rtgui_rect_t *rect, rtgui_color_t shield_color)
{
RT_ASSERT(rect != RT_NULL);
if(image != RT_NULL && image->engine != RT_NULL)
{
/* use image engine to blit */
image->engine->image_paste(image, dc, rect, shield_color);
}
}
struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors)
{
struct rtgui_image_palette* palette = RT_NULL;
if (ncolors > 0)
{
palette = (struct rtgui_image_palette*) rt_malloc(sizeof(struct rtgui_image_palette) + sizeof(rtgui_color_t) * ncolors);
if (palette != RT_NULL) palette->colors = (rtgui_color_t*)(palette + 1);
}
return palette;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* File : rtgui_object.c
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-04 Bernard first version
*/
#include <rtgui/rtgui_object.h>
#include <rtgui/rtgui_system.h>
static void _rtgui_object_constructor(rtgui_object_t *object)
{
if (!object) return;
object->is_static = RT_FALSE;
}
/* Destroys the object */
static void _rtgui_object_destructor(rtgui_object_t *object)
{
/* nothing */
}
rtgui_type_t *rtgui_type_create(const char *type_name, rtgui_type_t *parent_type,
int type_size, rtgui_constructor_t constructor,
rtgui_destructor_t destructor)
{
rtgui_type_t *new_type;
if (!type_name)
return RT_NULL;
new_type = rtgui_malloc(sizeof(rtgui_type_t));
new_type->name = rt_strdup(type_name);
new_type->size = type_size;
new_type->constructor = constructor;
new_type->destructor = destructor;
if (!parent_type)
{
new_type->hierarchy_depth = 0;
new_type->hierarchy = RT_NULL;
}
else
{
/* Build the type hierarchy */
new_type->hierarchy_depth = parent_type->hierarchy_depth + 1;
new_type->hierarchy = rtgui_malloc(sizeof(rtgui_type_t *) * new_type->hierarchy_depth);
new_type->hierarchy[0] = parent_type;
rt_memcpy(new_type->hierarchy + 1, parent_type->hierarchy,
parent_type->hierarchy_depth * sizeof(rtgui_type_t *));
}
return new_type;
}
void rtgui_type_destroy(rtgui_type_t *type)
{
if (!type) return;
if (type->hierarchy) rtgui_free(type->hierarchy);
rtgui_free(type->name);
rtgui_free(type);
}
void rtgui_type_object_construct(rtgui_type_t *type, rtgui_object_t *object)
{
int i;
if (!type || !object) return;
/* Call the constructors */
for (i = type->hierarchy_depth - 1; i >= 0; i--)
{
if (type->hierarchy[i]->constructor)
type->hierarchy[i]->constructor(object);
}
if (type->constructor) type->constructor(object);
}
void rtgui_type_destructors_call(rtgui_type_t *type, rtgui_object_t *object)
{
int i;
if (!type || !object) return;
if (type->destructor) type->destructor(object);
for (i = 0; i < type->hierarchy_depth; i++)
{
if (type->hierarchy[i]->destructor)
type->hierarchy[i]->destructor(object);
}
}
rt_bool_t rtgui_type_inherits_from(rtgui_type_t *type, rtgui_type_t *parent)
{
int i;
if (!type || !parent) return RT_FALSE;
if (type == parent) return RT_TRUE;
for (i = 0; i < type->hierarchy_depth; i++)
{
if (type->hierarchy[i] == parent) return RT_TRUE;
}
return RT_FALSE;
}
rtgui_type_t *rtgui_type_parent_type_get(rtgui_type_t *type)
{
if (!type || !type->hierarchy) return RT_NULL;
return type->hierarchy[0];
}
const char *rtgui_type_name_get(rtgui_type_t *type)
{
if (!type) return RT_NULL;
return type->name;
}
struct rtgui_object_information
{
rt_uint32_t objs_number;
rt_uint32_t allocated_size;
rt_uint32_t max_allocated;
};
struct rtgui_object_information obj_info = {0, 0, 0};
/**
* @brief Creates a new object: it calls the corresponding constructors (from the constructor of the base class to the
* constructor of the more derived class) and then sets the values of the given properties
* @param object_type the type of object to create
* @return Returns the new Etk_Object of type @a object_type
*/
rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type)
{
rtgui_object_t *new_object;
if (!object_type)
return RT_NULL;
new_object = rtgui_malloc(object_type->size);
if (new_object == RT_NULL) return RT_NULL;
obj_info.objs_number ++;
obj_info.allocated_size += object_type->size;
if (obj_info.allocated_size > obj_info.max_allocated)
obj_info.max_allocated = obj_info.allocated_size;
new_object->type = object_type;
new_object->is_static = RT_FALSE;
rtgui_type_object_construct(object_type, new_object);
return new_object;
}
/**
* @brief Destroys the object: it first sets the weak-pointers to RT_NULL, emits the "destroyed" signal, and then
* queues the object in the list of objects to free. Thus, the destructors will only be called at the beginning of the
* next main loop iteration (from the destructor of the more derived class to the destructor of the ultimate base class).
* @param object the object to destroy
* @warning You should not assume that this function will call directly the destructors of the object!
*/
void rtgui_object_destroy(rtgui_object_t *object)
{
if (!object || object->is_static == RT_TRUE) return;
obj_info.objs_number --;
obj_info.allocated_size -= object->type->size;
/* call destructor */
RT_ASSERT(object->type != RT_NULL);
rtgui_type_destructors_call(object->type, object);
/* release object */
rtgui_free(object);
}
/**
* @internal
* @brief Gets the type of a rtgui_object
* @return Returns the type of a rtgui_object
*/
rtgui_type_t *rtgui_object_type_get(void)
{
static rtgui_type_t *object_type = RT_NULL;
if (!object_type)
{
object_type = rtgui_type_create("object", RT_NULL,
sizeof(rtgui_object_t), RTGUI_CONSTRUCTOR(_rtgui_object_constructor),
RTGUI_DESTRUCTOR(_rtgui_object_destructor));
}
return object_type;
}
/**
* @brief Checks if @a object can be cast to @a type.
* If @a object doesn't inherit from @a type, a warning is displayed in the console but the object is returned anyway.
* @param object the object to cast
* @param type the type to which we cast the object
* @return Returns the object
* @note You usually do not need to call this function, use specific macros instead (ETK_IS_WIDGET() for example)
*/
rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *object, rtgui_type_t *type)
{
if (!object) return RT_NULL;
if (!rtgui_type_inherits_from(object->type, type))
{
rt_kprintf("Invalid cast from \"%s\" to \"%s\"\n", rtgui_type_name_get(object->type), rtgui_type_name_get(type));
}
return object;
}
/**
* @brief Gets the type of the object
* @param object an object
* @return Returns the type of @a object (RT_NULL on failure)
*/
rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object)
{
if (!object) return RT_NULL;
return object->type;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
#ifndef __RTGUI_BLIT_H__
#define __RTGUI_BLIT_H__
#include <rtgui/rtgui.h>
typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line);
rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
#ifndef __RTGUI_IMAGE_JPEG_H__
#define __RTGUI_IMAGE_JPEG_H__
#include <image.h>
void rtgui_image_jpeg_init(void);
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册