mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-01 19:58:14 +08:00
add meshgradient & sweepgradient
This commit is contained in:
parent
2101e09ce9
commit
0c9b56f33b
9
cmake/common_functions.cmake
Normal file → Executable file
9
cmake/common_functions.cmake
Normal file → Executable file
@ -1,12 +1,13 @@
|
||||
|
||||
function(CreatePAK ResourceDIR PakPath)
|
||||
execute_process(COMMAND zip -r -0 ${PakPath} ./ -i *
|
||||
function(CreatePAK ResourceDIR PakPath projectname)
|
||||
add_custom_command(TARGET ${projectname} PRE_BUILD
|
||||
COMMAND zip -r -0 ${PakPath} ./
|
||||
WORKING_DIRECTORY ${ResourceDIR})
|
||||
message("Package ${ResourceDIR} to:${PakPath}")
|
||||
endfunction()
|
||||
|
||||
function(CreatePO SourceDIR POPath)
|
||||
execute_process(
|
||||
function(CreatePO SourceDIR POPath projectname)
|
||||
add_custom_command(TARGET ${projectname} PRE_BUILD
|
||||
COMMAND touch ${POPath}
|
||||
COMMAND xgettext -d ntvplus -j -c -p${PROJECT_BINARY_DIR} -kTEXT ${SRCS_NTV_PLUS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
@ -52,7 +52,7 @@ add_custom_target(systempak
|
||||
COMMENT "package system resource"
|
||||
)
|
||||
|
||||
CreatePAK(${PROJECT_SOURCE_DIR}/res ${CMAKE_CURRENT_BINARY_DIR}/cdroid.pak)
|
||||
CreatePAK(${PROJECT_SOURCE_DIR}/res ${CMAKE_CURRENT_BINARY_DIR}/cdroid.pak gui)
|
||||
set_target_properties(gui_static PROPERTIES OUTPUT_NAME "gui")
|
||||
|
||||
file(GLOB_RECURSE allfiles RELATIVE "${PROJECT_SOURCE_DIR}/" "*.h")
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <cairomm/pattern.h>
|
||||
#include <cairomm/private.h>
|
||||
#include <cairomm/matrix.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace Cairo
|
||||
{
|
||||
@ -287,6 +288,122 @@ RadialGradient::~RadialGradient()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MeshPattern::MeshPattern(){
|
||||
m_cobject=cairo_pattern_create_mesh();
|
||||
check_object_status_and_throw_exception(*this);
|
||||
}
|
||||
|
||||
MeshPattern::MeshPattern(cairo_pattern_t* cobject, bool has_reference)
|
||||
:Pattern(cobject,has_reference){
|
||||
}
|
||||
|
||||
void MeshPattern::begin_patch(){
|
||||
cairo_mesh_pattern_begin_patch(m_cobject);
|
||||
}
|
||||
|
||||
void MeshPattern::end_patch(){
|
||||
cairo_mesh_pattern_end_patch(m_cobject);
|
||||
}
|
||||
|
||||
void MeshPattern::line_to(double x,double y){
|
||||
cairo_mesh_pattern_line_to(m_cobject,x,y);
|
||||
}
|
||||
|
||||
void MeshPattern::move_to(double x,double y){
|
||||
cairo_mesh_pattern_move_to(m_cobject,x,y);
|
||||
}
|
||||
|
||||
void MeshPattern::curve_to(double x1,double y1,double x2,double y2,double x3,double y3){
|
||||
cairo_mesh_pattern_curve_to(m_cobject,x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
void MeshPattern::set_control_point(uint32_t point_num,double x,double y){
|
||||
cairo_mesh_pattern_set_control_point(m_cobject,point_num,x,y);
|
||||
}
|
||||
|
||||
void MeshPattern::set_corner_color_rgb(uint32_t corner_num,double red,double green,double blue){
|
||||
cairo_mesh_pattern_set_corner_color_rgb(m_cobject,corner_num,red,green,blue);
|
||||
}
|
||||
|
||||
void MeshPattern::set_corner_color_rgba(uint32_t corner_num,double red,double green,double blue,double alpha){
|
||||
cairo_mesh_pattern_set_corner_color_rgba(m_cobject,corner_num,red,green,blue,alpha);
|
||||
}
|
||||
|
||||
int MeshPattern::get_corner_color_rgba(uint32_t patch_num,uint32_t corner_num,double& red,double& green,double& blue,double&alpha){
|
||||
return cairo_mesh_pattern_get_corner_color_rgba(m_cobject,patch_num,corner_num,&red,&green,&blue,&alpha);
|
||||
}
|
||||
|
||||
int MeshPattern::get_control_point(uint32_t patch_num,uint32_t corner_num,double&x,double&y){
|
||||
return cairo_mesh_pattern_get_control_point(m_cobject,patch_num,corner_num,&x,&y);
|
||||
}
|
||||
|
||||
RefPtr<MeshPattern>MeshPattern::create(){
|
||||
cairo_pattern_t*p=cairo_pattern_create_mesh();
|
||||
return make_refptr_for_instance<MeshPattern>(new MeshPattern());
|
||||
}
|
||||
|
||||
SweepGradient::SweepGradient(double cx,double cy,double radius)
|
||||
:MeshPattern(){
|
||||
m_cx=cx;
|
||||
m_cy=cy;
|
||||
m_radius=radius;
|
||||
printf("(%.2f,%.2f:%.2f):%p %p\r\n",m_cx,m_cy,m_radius,this,m_cobject);
|
||||
}
|
||||
|
||||
SweepGradient::SweepGradient(cairo_pattern_t* cobject, bool has_reference)
|
||||
:MeshPattern(cobject, has_reference){
|
||||
}
|
||||
|
||||
RefPtr<SweepGradient>SweepGradient::create(double cx,double cy,double radius){
|
||||
return make_refptr_for_instance<SweepGradient>(new SweepGradient(cx,cy,radius));
|
||||
}
|
||||
|
||||
void SweepGradient::add_sector_patch( double angle_A,double A_r, double A_g, double A_b,double A_a,
|
||||
double angle_B,double B_r, double B_g, double B_b,double B_a){
|
||||
double r_sin_A, r_cos_A;
|
||||
double r_sin_B, r_cos_B;
|
||||
double h;
|
||||
r_sin_A = m_radius * sin (angle_A);
|
||||
r_cos_A = m_radius * cos (angle_A);
|
||||
r_sin_B = m_radius * sin (angle_B);
|
||||
r_cos_B = m_radius * cos (angle_B);
|
||||
|
||||
h = 4.0/3.0 * tan ((angle_B - angle_A)/4.0);
|
||||
|
||||
begin_patch();
|
||||
|
||||
move_to (m_cx, m_cy);
|
||||
line_to (m_cx + r_cos_A, m_cy + r_sin_A);
|
||||
|
||||
curve_to(m_cx + r_cos_A - h * r_sin_A, m_cy + r_sin_A + h * r_cos_A,
|
||||
m_cx + r_cos_B + h * r_sin_B, m_cy + r_sin_B - h * r_cos_B,
|
||||
m_cx + r_cos_B, m_cy + r_sin_B);
|
||||
|
||||
set_corner_color_rgba (0, 1, 1, 1,A_a);
|
||||
set_corner_color_rgba (1, A_r, A_g, A_b,A_a);
|
||||
set_corner_color_rgba (2, B_r, B_g, B_b,B_a);
|
||||
end_patch ();
|
||||
}
|
||||
|
||||
void SweepGradient::add_sector_patch( double angle_A,double A_r, double A_g, double A_b,
|
||||
double angle_B,double B_r, double B_g, double B_b){
|
||||
add_sector_patch(angle_A,A_r,A_g,A_b,1.f,angle_B,B_r,B_g,B_b,1.f);
|
||||
}
|
||||
|
||||
static void color2rgba(uint32_t c,float&r,float&g,float&b,float&a){
|
||||
a=(c>>24)/255.;
|
||||
r=((c>>16)&0xFF)/255.;
|
||||
g=((c>>8)&0xFF)/255.;
|
||||
b=(c&0xFF)/255;
|
||||
}
|
||||
void SweepGradient::add_sector_patch(double angleA,uint32_t colorA,double angleB, uint32_t colorB){
|
||||
float r1,g1,b1,a1,r2,g2,b2,a2;
|
||||
color2rgba(colorA,r1,g1,b1,a1);
|
||||
color2rgba(colorB,r2,g2,b2,a2);
|
||||
add_sector_patch(angleA,r1,g1,b1,a1,angleB,r2,g2,b2,a2);
|
||||
}
|
||||
|
||||
} //namespace Cairo
|
||||
|
||||
|
@ -79,7 +79,8 @@ public:
|
||||
/**
|
||||
* The pattern is a radial gradient.
|
||||
*/
|
||||
RADIAL = CAIRO_PATTERN_TYPE_RADIAL
|
||||
RADIAL = CAIRO_PATTERN_TYPE_RADIAL,
|
||||
MESH = CAIRO_PATTERN_TYPE_MESH /*added by zhhou*/
|
||||
};
|
||||
|
||||
/**
|
||||
@ -543,6 +544,43 @@ public:
|
||||
static RefPtr<RadialGradient> create(double cx0, double cy0, double radius0, double cx1, double cy1, double radius1);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////added by zhhou////////////////////////////////////////////////
|
||||
|
||||
class CAIROMM_API MeshPattern:public Pattern{
|
||||
protected:
|
||||
MeshPattern();
|
||||
public:
|
||||
explicit MeshPattern(cairo_pattern_t* cobject, bool has_reference = false);
|
||||
void begin_patch();
|
||||
void end_patch();
|
||||
void line_to(double x,double y);
|
||||
void move_to(double x,double y);
|
||||
void curve_to(double,double,double,double,double,double);
|
||||
void set_control_point(uint32_t point_num,double x,double y);
|
||||
void set_corner_color_rgb(uint32_t corner_num,double red,double green,double blue);
|
||||
void set_corner_color_rgba(uint32_t corner_num,double red,double green,double blue,double alpha);
|
||||
int get_patch_count()const;
|
||||
int get_corner_color_rgba(uint32_t patch_num,uint32_t corner_num,double& red,double& green,double& blue,double&alpha);
|
||||
int get_control_point(uint32_t patch_num,uint32_t corner_num,double&x,double&y);
|
||||
static RefPtr<MeshPattern>create();
|
||||
};
|
||||
|
||||
class CAIROMM_API SweepGradient : public MeshPattern{
|
||||
private:
|
||||
double m_cx;
|
||||
double m_cy;
|
||||
double m_radius;
|
||||
protected:
|
||||
SweepGradient(double,double,double);
|
||||
public:
|
||||
explicit SweepGradient(cairo_pattern_t* cobject, bool has_reference = false);
|
||||
void add_sector_patch( double angle_A,double A_r, double A_g, double A_b,double A_a,
|
||||
double angle_B,double B_r, double B_g, double B_b,double B_a);
|
||||
void add_sector_patch( double angle_A,double A_r, double A_g, double A_b,
|
||||
double angle_B,double B_r, double B_g, double B_b);
|
||||
void add_sector_patch(double angleA,uint32_t colorA,double angleB,uint32_t colorB);
|
||||
static RefPtr<SweepGradient> create(double cx,double cy,double r);
|
||||
};
|
||||
} // namespace Cairo
|
||||
|
||||
#endif //__CAIROMM_PATTERN_H
|
||||
|
@ -33,7 +33,6 @@ bool AnimationDrawable::setVisible(bool visible,bool restart){
|
||||
|
||||
void AnimationDrawable::start(){
|
||||
mAnimating = true;
|
||||
LOGD("mRunning=%d",mRunning);
|
||||
if(!isRunning())
|
||||
setFrame(0,false,mAnimationState->getChildCount()>1||!mAnimationState->mOneShot);
|
||||
}
|
||||
|
@ -356,15 +356,6 @@ static void parseShapeGradient(Shape*shape,const AttributeSet&atts){
|
||||
{"sweep",Shape::Gradient::SWEEP}},Shape::Gradient::LINEAR));
|
||||
if(atts.hasAttribute("gradientRadius"))
|
||||
shape->setGradientRadius(atts.getDimensionPixelSize("gradientRadius"));
|
||||
|
||||
std::string type=atts.getString("type");
|
||||
if(!type.empty()){
|
||||
switch(type[0]){
|
||||
case 'l': shape->setGradientType(Shape::Gradient::LINEAR); break; //linear gradient
|
||||
case 'r': shape->setGradientType(Shape::Gradient::RADIAL); break; //radial gradient
|
||||
case 's': shape->setGradientType(Shape::Gradient::SWEEP); break; //sweep gradient(not support)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parseCorners(Shape*shape,const AttributeSet&atts){
|
||||
@ -515,7 +506,7 @@ Drawable*Drawable::fromStream(Context*ctx,std::istream&stream,const std::string&
|
||||
} while(rdlen);
|
||||
XML_ParserFree(parser);
|
||||
|
||||
LOGD("parsed drawable [%p] from %s",pd.drawable,resname.c_str());
|
||||
LOGV("parsed drawable [%p] from %s",pd.drawable,resname.c_str());
|
||||
return pd.drawable;
|
||||
}
|
||||
|
||||
|
@ -103,22 +103,36 @@ void Shape::applyGradients(){
|
||||
cls.resize(mGradientColors.size());
|
||||
for(int i=0;i<mGradientColors.size();i++){
|
||||
cls[i]=Color(mGradientColors[i]);
|
||||
LOGV("gradient.colors[%d]=%x",i,mGradientColors[i]);
|
||||
LOGV("gradient.colors[%d/%d]=%x",i,mGradientColors.size(),cls[i].toArgb());
|
||||
}
|
||||
RefPtr<Cairo::Gradient> g=std::make_shared<Cairo::Gradient>(mPaint->cobj());
|
||||
switch(mGradientColors.size()){
|
||||
case 2:
|
||||
g->add_color_stop_rgba(.0f,cls[0].red(),cls[0].green(),cls[0].blue(),cls[0].alpha());
|
||||
g->add_color_stop_rgba(1.f,cls[1].red(),cls[1].green(),cls[1].blue(),cls[1].alpha());
|
||||
break;
|
||||
case 3:
|
||||
g->add_color_stop_rgba(.0f,cls[0].red(),cls[0].green(),cls[0].blue(),cls[0].alpha());
|
||||
g->add_color_stop_rgba(.5f,cls[1].red(),cls[1].green(),cls[1].blue(),cls[1].alpha());
|
||||
g->add_color_stop_rgba(1.f,cls[2].red(),cls[2].green(),cls[2].blue(),cls[2].alpha());
|
||||
if(mPaint->get_type()!=Pattern::Type::MESH){
|
||||
RefPtr<Cairo::Gradient>pat=std::make_shared<Cairo::Gradient>(mPaint->cobj(),false);
|
||||
switch(mGradientColors.size()){
|
||||
case 2:
|
||||
pat->add_color_stop_rgba(.0f,cls[0].red(),cls[0].green(),cls[0].blue(),cls[0].alpha());
|
||||
pat->add_color_stop_rgba(1.f,cls[1].red(),cls[1].green(),cls[1].blue(),cls[1].alpha());
|
||||
break;
|
||||
case 3:
|
||||
pat->add_color_stop_rgba(.0f,cls[0].red(),cls[0].green(),cls[0].blue(),cls[0].alpha());
|
||||
pat->add_color_stop_rgba(.5f,cls[1].red(),cls[1].green(),cls[1].blue(),cls[1].alpha());
|
||||
pat->add_color_stop_rgba(1.f,cls[2].red(),cls[2].green(),cls[2].blue(),cls[2].alpha());
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
RefPtr<Cairo::SweepGradient>swp=std::dynamic_pointer_cast<Cairo::SweepGradient>(mPaint);
|
||||
const uint32_t*cc=mGradientColors.data();
|
||||
const size_t ccnum=mGradientColors.size();
|
||||
double angle=0;
|
||||
for(int i=0;i<ccnum;i++){
|
||||
swp->add_sector_patch(angle,mGradientColors[i],angle+M_PI*2./ccnum,mGradientColors[(i+1)%ccnum]);
|
||||
LOGV("add_sector_patch(%.2f) color:%x->%x",angle,mGradientColors[i],mGradientColors[(i+1)%ccnum]);
|
||||
angle+=M_PI*2./ccnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shape::rebuildPattern(int x,int y){
|
||||
const float cx=mGradientCenterX*mWidth+x;
|
||||
const float cy=mGradientCenterY*mHeight+y;
|
||||
switch(mGradientType){
|
||||
case Gradient::SOLID:{
|
||||
const Color c(mGradientColors[0]);
|
||||
@ -128,26 +142,29 @@ void Shape::rebuildPattern(int x,int y){
|
||||
const int angleIndex=mGradientAngle/45;
|
||||
const int wh=std::max(mWidth,mHeight);
|
||||
switch(angleIndex%8){
|
||||
case 0: mPaint=LinearGradient::create(0,0,wh,0) ; break;
|
||||
case 0: mPaint=LinearGradient::create(0,0,mWidth,0) ; break;
|
||||
case 1: mPaint=LinearGradient::create(0,wh,wh,0); break;
|
||||
case 2: mPaint=LinearGradient::create(0,wh,0,0) ; break;
|
||||
case 2: mPaint=LinearGradient::create(0,mHeight,0,0) ; break;
|
||||
case 3: mPaint=LinearGradient::create(wh,wh,0,0); break;
|
||||
case 4: mPaint=LinearGradient::create(wh,0,0,0) ; break;
|
||||
case 4: mPaint=LinearGradient::create(mWidth,0,0,0) ; break;
|
||||
case 5: mPaint=LinearGradient::create(wh,0,0,wh); break;
|
||||
case 6: mPaint=LinearGradient::create(0,0,0,wh) ; break;
|
||||
case 6: mPaint=LinearGradient::create(0,0,0,mHeight) ; break;
|
||||
case 7: mPaint=LinearGradient::create(0,0,wh,wh); break;
|
||||
}
|
||||
LOGV("angleIndex=%d size=%dx%d %d colors",angleIndex,mWidth,mHeight,mGradientColors.size());
|
||||
applyGradients();
|
||||
}break;
|
||||
case Gradient::RADIAL:{
|
||||
const float cx=mGradientCenterX*mWidth+x;
|
||||
const float cy=mGradientCenterY*mHeight+y;
|
||||
const float pd=mGradientAngle*M_PI/180.f;
|
||||
LOGV("center=%.2f,%.2f cx,cy=%.2f,%.2f mRadius=%f mAngle=%.2f xy=%d,%d",mGradientCenterX,mGradientCenterY,cx,cy,mGradientRadius,mGradientAngle,x,y);
|
||||
mPaint=RadialGradient::create(cx,cy,0,cx,cy,mGradientRadius);
|
||||
applyGradients();
|
||||
}break;
|
||||
case Gradient::SWEEP:
|
||||
case Gradient::SWEEP:{
|
||||
mPaint=SweepGradient::create(mGradientCenterX*mWidth,mGradientCenterY*mHeight,mGradientRadius);
|
||||
LOGV("SWEEP(%.2f,%.2f:%.2f",mGradientCenterX*mWidth,mGradientCenterY*mHeight,mGradientRadius);
|
||||
applyGradients();
|
||||
}break;
|
||||
default:
|
||||
LOGE("unsupported gradient type %d",mGradientType);
|
||||
break;
|
||||
@ -158,7 +175,8 @@ void Shape::fill_stroke(Canvas&canvas,int x,int y){
|
||||
const bool bstroke=(mStrokeWidth>0) && (mStrokeColor&0x80000000);
|
||||
if(mGradientColors.size()){
|
||||
rebuildPattern(x,y);
|
||||
mPaint->set_matrix(canvas.get_matrix());
|
||||
if(mGradientType==Shape::Gradient::RADIAL)
|
||||
mPaint->set_matrix(canvas.get_matrix());
|
||||
canvas.set_source(mPaint);
|
||||
if(bstroke)
|
||||
canvas.fill_preserve();
|
||||
@ -202,7 +220,7 @@ void RectShape::onResize(int width,int height){
|
||||
}
|
||||
|
||||
void RectShape::draw(Canvas&canvas,int x,int y){
|
||||
if(mPaint)canvas.set_source(mPaint);
|
||||
rebuildPattern(x,y);
|
||||
canvas.rectangle(0,0,mWidth,mHeight);
|
||||
fill_stroke(canvas,x,y);
|
||||
}
|
||||
@ -292,8 +310,8 @@ void OvalShape::draw(Canvas&canvas,int x,int y){
|
||||
canvas.scale(1.f/ratio,1.f);
|
||||
canvas.set_fill_rule(Cairo::Context::FillRule::EVEN_ODD);
|
||||
}
|
||||
fill_stroke(canvas,x,y);
|
||||
canvas.translate(-mWidth/2,-mHeight/2);
|
||||
fill_stroke(canvas,x,y);
|
||||
}
|
||||
|
||||
RoundRectShape::RoundRectShape():RectShape(){
|
||||
@ -345,6 +363,7 @@ void RoundRectShape::drawRound(Canvas&canvas,const Rect&r,const std::vector<floa
|
||||
void RoundRectShape::draw(Canvas&canvas,int x,int y){
|
||||
Rect r={0,0,mWidth,mHeight};
|
||||
drawRound(canvas,r,mOuterRadii);
|
||||
canvas.set_fill_rule(Cairo::Context::FillRule::WINDING);
|
||||
if(mInnerRadii.size()){
|
||||
drawRound(canvas,r,mInnerRadii);
|
||||
canvas.set_fill_rule(Cairo::Context::FillRule::EVEN_ODD);
|
||||
|
@ -196,7 +196,11 @@ Drawable*ShapeDrawable::inflate(Context*ctx,const AttributeSet&atts){
|
||||
oval->setThicknessRatio(atts.getFloat("thicknessRatio",.0f));
|
||||
oval->setInnerRadius(atts.getInt("innerRadius",0));
|
||||
oval->setInnerRadiusRatio(atts.getFloat("innerRadiusRatio",.0f));
|
||||
}else if(type.compare( "arc")==0) shape = new ArcShape(0,0);
|
||||
}else if(type.compare( "arc")==0){
|
||||
const float start=atts.getFloat("startAngle",0);
|
||||
const float end =atts.getFloat("endAngle",360);
|
||||
shape= new ArcShape(start,end);
|
||||
}
|
||||
ShapeDrawable*d=new ShapeDrawable();
|
||||
d->setShape(shape);
|
||||
return d;
|
||||
|
@ -171,6 +171,26 @@ TEST_F(DRAWABLE,rectshape){
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DRAWABLE,roundrect){
|
||||
RECT rect={2,2,2,2};
|
||||
std::vector<float>out={40,30,50,30};
|
||||
std::vector<float>in={};//{30,20,30,20};
|
||||
RoundRectShape*rs=new RoundRectShape(out,rect,in);
|
||||
rs->setStrokeColor(0xFFFF0000);
|
||||
rs->setGradientColors(std::vector<uint32_t>{0xFFFF0000,0xFF00FF00});//,0xFF0000FF});
|
||||
rs->setGradientType(Shape::Gradient::SWEEP);
|
||||
rs->setGradientAngle(270);
|
||||
rs->setStrokeSize(5);
|
||||
rs->setGradientCenterX(.5f);
|
||||
rs->setGradientCenterY(.5f);
|
||||
rs->setGradientRadius(250);
|
||||
rs->resize(500,500);
|
||||
ctx->set_color(0xFF00FF00);
|
||||
rs->draw(*ctx,50,50);
|
||||
postCompose();
|
||||
sleep(10);
|
||||
}
|
||||
|
||||
TEST_F(DRAWABLE,roundrectshape){
|
||||
RECT rect={2,2,2,2};
|
||||
std::vector<float>out={40,30,50,30};
|
||||
|
Loading…
Reference in New Issue
Block a user