Skip to content

Commit

Permalink
Merge pull request #1959 from arturoc/feature-ofPathRefactorRectRound
Browse files Browse the repository at this point in the history
ofPath refactor + ofRectRound +  fixes
  • Loading branch information
arturoc committed May 23, 2013
2 parents 2d98467 + f39ad36 commit bf2170f
Show file tree
Hide file tree
Showing 8 changed files with 614 additions and 428 deletions.
154 changes: 70 additions & 84 deletions libs/openFrameworks/graphics/ofCairoRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,6 @@
#include "ofImage.h"
#include "of3dPrimitives.h"

//-----------------------------------------------------------------------------------
//static void helper_quadratic_to (cairo_t *cr,
// double x1, double y1,
// double x2, double y2)
//{
// double x0, y0;
// cairo_get_current_point (cr, &x0, &y0);
// cairo_curve_to (cr,
// 2.0 / 3.0 * x1 + 1.0 / 3.0 * x0,
// 2.0 / 3.0 * y1 + 1.0 / 3.0 * y0,
// 2.0 / 3.0 * x1 + 1.0 / 3.0 * x2,
// 2.0 / 3.0 * y1 + 1.0 / 3.0 * y2,
// y1, y2);
//}

_cairo_status ofCairoRenderer::stream_function(void *closure,const unsigned char *data, unsigned int length){
((ofCairoRenderer*)closure)->streamBuffer.append((const char*)data,length);
Expand Down Expand Up @@ -184,9 +170,9 @@ void ofCairoRenderer::setStyle(const ofStyle & style){

void ofCairoRenderer::draw(ofPath & shape){
cairo_new_path(cr);
vector<ofSubPath> & paths = shape.getSubPaths();
for(int i=0;i<(int)paths.size();i++){
draw(paths[i]);
vector<ofPath::Command> & commands = shape.getCommands();
for(int i=0;i<(int)commands.size();i++){
draw(commands[i]);
}

cairo_fill_rule_t cairo_poly_mode;
Expand Down Expand Up @@ -229,7 +215,6 @@ void ofCairoRenderer::draw(ofPath & shape){
if(shape.getUseShapeColor()){
setColor(prevColor);
}
ofPopStyle();
}

void ofCairoRenderer::draw(ofPolyline & poly){
Expand Down Expand Up @@ -411,88 +396,89 @@ void ofCairoRenderer::draw( of3dPrimitive& model, ofPolyRenderMode renderType )

}

void ofCairoRenderer::draw(ofSubPath & path){
void ofCairoRenderer::draw(ofPath::Command & command){
if(!surface || !cr) return;
const vector<ofSubPath::Command> & commands = path.getCommands();
cairo_new_sub_path(cr);
for(int i=0; i<(int)commands.size(); i++){
switch(commands[i].type){
case ofSubPath::Command::lineTo:
curvePoints.clear();
cairo_line_to(cr,commands[i].to.x,commands[i].to.y);
break;
switch(command.type){
case ofPath::Command::moveTo:
curvePoints.clear();
cairo_new_sub_path(cr);
break;

case ofPath::Command::lineTo:
curvePoints.clear();
cairo_line_to(cr,command.to.x,command.to.y);
break;

case ofSubPath::Command::curveTo:
curvePoints.push_back(commands[i].to);

//code adapted from ofxVectorGraphics to convert catmull rom to bezier
if(curvePoints.size()==4){
ofPoint p1=curvePoints[0];
ofPoint p2=curvePoints[1];
ofPoint p3=curvePoints[2];
ofPoint p4=curvePoints[3];
case ofPath::Command::curveTo:
curvePoints.push_back(command.to);

//SUPER WEIRD MAGIC CONSTANT = 1/6 (this works 100% can someone explain it?)
ofPoint cp1 = p2 + ( p3 - p1 ) * (1.0/6);
ofPoint cp2 = p3 + ( p2 - p4 ) * (1.0/6);
//code adapted from ofxVectorGraphics to convert catmull rom to bezier
if(curvePoints.size()==4){
ofPoint p1=curvePoints[0];
ofPoint p2=curvePoints[1];
ofPoint p3=curvePoints[2];
ofPoint p4=curvePoints[3];

cairo_curve_to( cr, cp1.x, cp1.y, cp2.x, cp2.y, p3.x, p3.y );
curvePoints.pop_front();
}
break;
//SUPER WEIRD MAGIC CONSTANT = 1/6 (this works 100% can someone explain it?)
ofPoint cp1 = p2 + ( p3 - p1 ) * (1.0/6);
ofPoint cp2 = p3 + ( p2 - p4 ) * (1.0/6);

cairo_curve_to( cr, cp1.x, cp1.y, cp2.x, cp2.y, p3.x, p3.y );
curvePoints.pop_front();
}
break;

case ofSubPath::Command::bezierTo:
curvePoints.clear();
cairo_curve_to(cr,commands[i].cp1.x,commands[i].cp1.y,commands[i].cp2.x,commands[i].cp2.y,commands[i].to.x,commands[i].to.y);
break;

case ofSubPath::Command::quadBezierTo:
curvePoints.clear();
cairo_curve_to(cr,commands[i].cp1.x,commands[i].cp1.y,commands[i].cp2.x,commands[i].cp2.y,commands[i].to.x,commands[i].to.y);
break;
case ofPath::Command::bezierTo:
curvePoints.clear();
cairo_curve_to(cr,command.cp1.x,command.cp1.y,command.cp2.x,command.cp2.y,command.to.x,command.to.y);
break;

case ofPath::Command::quadBezierTo:
curvePoints.clear();
cairo_curve_to(cr,command.cp1.x,command.cp1.y,command.cp2.x,command.cp2.y,command.to.x,command.to.y);
break;

case ofSubPath::Command::arc:
curvePoints.clear();
// elliptic arcs not directly supported in cairo, lets scale y
if(commands[i].radiusX!=commands[i].radiusY){
float ellipse_ratio = commands[i].radiusY/commands[i].radiusX;
pushMatrix();
translate(0,-commands[i].to.y*ellipse_ratio);
scale(1,ellipse_ratio);
translate(0,commands[i].to.y/ellipse_ratio);
cairo_arc(cr,commands[i].to.x,commands[i].to.y,commands[i].radiusX,commands[i].angleBegin*DEG_TO_RAD,commands[i].angleEnd*DEG_TO_RAD);
//cairo_set_matrix(cr,&stored_matrix);
popMatrix();
}else{
cairo_arc(cr,commands[i].to.x,commands[i].to.y,commands[i].radiusX,commands[i].angleBegin*DEG_TO_RAD,commands[i].angleEnd*DEG_TO_RAD);
}
break;

case ofSubPath::Command::arcNegative:
curvePoints.clear();
// elliptic arcs not directly supported in cairo, lets scale y
if(commands[i].radiusX!=commands[i].radiusY){
float ellipse_ratio = commands[i].radiusY/commands[i].radiusX;
pushMatrix();
translate(0,-commands[i].to.y*ellipse_ratio);
scale(1,ellipse_ratio);
translate(0,commands[i].to.y/ellipse_ratio);
cairo_arc_negative(cr,commands[i].to.x,commands[i].to.y,commands[i].radiusX,commands[i].angleBegin*DEG_TO_RAD,commands[i].angleEnd*DEG_TO_RAD);
//cairo_set_matrix(cr,&stored_matrix);
popMatrix();
}else{
cairo_arc_negative(cr,commands[i].to.x,commands[i].to.y,commands[i].radiusX,commands[i].angleBegin*DEG_TO_RAD,commands[i].angleEnd*DEG_TO_RAD);
}
break;
case ofPath::Command::arc:
curvePoints.clear();
// elliptic arcs not directly supported in cairo, lets scale y
if(command.radiusX!=command.radiusY){
float ellipse_ratio = command.radiusY/command.radiusX;
pushMatrix();
translate(0,-command.to.y*ellipse_ratio);
scale(1,ellipse_ratio);
translate(0,command.to.y/ellipse_ratio);
cairo_arc(cr,command.to.x,command.to.y,command.radiusX,command.angleBegin*DEG_TO_RAD,command.angleEnd*DEG_TO_RAD);
//cairo_set_matrix(cr,&stored_matrix);
popMatrix();
}else{
cairo_arc(cr,command.to.x,command.to.y,command.radiusX,command.angleBegin*DEG_TO_RAD,command.angleEnd*DEG_TO_RAD);
}
break;

case ofPath::Command::arcNegative:
curvePoints.clear();
// elliptic arcs not directly supported in cairo, lets scale y
if(command.radiusX!=command.radiusY){
float ellipse_ratio = command.radiusY/command.radiusX;
pushMatrix();
translate(0,-command.to.y*ellipse_ratio);
scale(1,ellipse_ratio);
translate(0,command.to.y/ellipse_ratio);
cairo_arc_negative(cr,command.to.x,command.to.y,command.radiusX,command.angleBegin*DEG_TO_RAD,command.angleEnd*DEG_TO_RAD);
//cairo_set_matrix(cr,&stored_matrix);
popMatrix();
}else{
cairo_arc_negative(cr,command.to.x,command.to.y,command.radiusX,command.angleBegin*DEG_TO_RAD,command.angleEnd*DEG_TO_RAD);
}
}
break;

if(path.isClosed()){
case ofPath::Command::close:
cairo_close_path(cr);
break;

}


Expand Down
2 changes: 1 addition & 1 deletion libs/openFrameworks/graphics/ofCairoRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ofCairoRenderer: public ofBaseRenderer{
void update();

void draw(ofPath & shape);
void draw(ofSubPath & path);
void draw(ofPath::Command & path);
void draw(ofPolyline & poly);
void draw(ofMesh & vertexData, bool useColors=true, bool useTextures=true, bool useNormals=true);
void draw(ofMesh & vertexData, ofPolyRenderMode mode, bool useColors = false, bool useTextures = false, bool useNormals = false);
Expand Down
Loading

0 comments on commit bf2170f

Please sign in to comment.