Turns out I can't do high school calculus despite 4 years of Physics study.
The shading algorithm I envisioned has several rather hilarious
things wrong with it...
Although that 'j' does look damn good if you set the zoom *just* right...
{
return pair<Real,Real>(0, 1);
}
- Real a = (p1- p0 - 2*(p2-p1) + p3-p2);
- Real b = (p1-p0 - (p2-p1))*(p1-p0);
+ Real a = (3*(p1-p2) + p3 - p0);
+ Real b = 2*(p2 - 2*p1 + p0);
Real c = (p1-p0);
if (a == 0)
{
Debug("a, b, c are %f, %f, %f", Float(a), Float(b), Float(c));
if (b*b - 4*a*c < 0)
{
+ Debug("No real roots");
return pair<Real, Real>(0,1);
}
pair<Real, Real> tsols = SolveQuadratic(a, b, c);
inline std::pair<Real,Real> SolveQuadratic(const Real & a, const Real & b, const Real & c)
{
- Real x0((b + Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
- Real x1((b - Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
+ Real x0((-b + Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
+ Real x1((-b - Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
return std::pair<Real,Real>(x0,x1);
}
void Document::ParseSVGTransform(const string & s, SVGMatrix & transform)
{
- Debug("Parsing transform %s", s.c_str());
+ //Debug("Parsing transform %s", s.c_str());
string token;
string command;
unsigned i = 0;
else
return;
}
- Debug("Token is \"%s\"", command.c_str());
+ //Debug("Token is \"%s\"", command.c_str());
SVGMatrix delta = {1,0,0,0,1,0};
Warn("Unrecognised transform \"%s\", using identity", command.c_str());
}
- Debug("Old transform is {%f,%f,%f,%f,%f,%f}", transform.a, transform.b, transform.c, transform.d,transform.e,transform.f);
- Debug("Delta transform is {%f,%f,%f,%f,%f,%f}", delta.a, delta.b, delta.c, delta.d,delta.e,delta.f);
+ //Debug("Old transform is {%f,%f,%f,%f,%f,%f}", transform.a, transform.b, transform.c, transform.d,transform.e,transform.f);
+ //Debug("Delta transform is {%f,%f,%f,%f,%f,%f}", delta.a, delta.b, delta.c, delta.d,delta.e,delta.f);
SVGMatrix old(transform);
transform.a = old.a * delta.a + old.c * delta.b;
transform.d = old.b * delta.c + old.d * delta.d;
transform.f = old.b * delta.e + old.d * delta.f + old.f;
- Debug("New transform is {%f,%f,%f,%f,%f,%f}", transform.a, transform.b, transform.c, transform.d,transform.e,transform.f);
+ //Debug("New transform is {%f,%f,%f,%f,%f,%f}", transform.a, transform.b, transform.c, transform.d,transform.e,transform.f);
}
}
void Document::ParseSVGNode(pugi::xml_node & root, SVGMatrix & parent_transform)
{
- Debug("Parse node <%s>", root.name());
+ //Debug("Parse node <%s>", root.name());
for (pugi::xml_node child = root.first_child(); child; child = child.next_sibling())
int num_instructions = stbtt_GetGlyphShape(font, glyph_index, &instructions);
Real current_x(0), current_y(0);
-
+ unsigned start_index = m_count;
+ unsigned end_index = m_count;
for (int i = 0; i < num_instructions; ++i)
{
// TTF uses 16-bit signed ints for coordinates:
Real old_x(current_x), old_y(current_y);
current_x = inst_x;
current_y = inst_y;
- //unsigned bezier_index;
+
switch(instructions[i].type)
{
// Move To
break;
// Line To
case STBTT_vline:
- AddBezier(Bezier(old_x + x, old_y + y, old_x + x, old_y + y, current_x + x, current_y + y, current_x + x, current_y + y));
- //Add(BEZIER,Rect(0,0,1,1),bezier_index);
+ end_index = AddBezier(Bezier(old_x + x, old_y + y, old_x + x, old_y + y, current_x + x, current_y + y, current_x + x, current_y + y));
break;
// Quadratic Bezier To:
case STBTT_vcurve:
// - Endpoints are the same.
// - cubic1 = quad0+(2/3)*(quad1-quad0)
// - cubic2 = quad2+(2/3)*(quad1-quad2)
- AddBezier(Bezier(old_x + x, old_y + y, old_x + Real(2)*(inst_cx-old_x)/Real(3) + x, old_y + Real(2)*(inst_cy-old_y)/Real(3) + y,
+ end_index = AddBezier(Bezier(old_x + x, old_y + y, old_x + Real(2)*(inst_cx-old_x)/Real(3) + x, old_y + Real(2)*(inst_cy-old_y)/Real(3) + y,
current_x + Real(2)*(inst_cx-current_x)/Real(3) + x, current_y + Real(2)*(inst_cy-current_y)/Real(3) + y, current_x + x, current_y + y));
break;
}
}
+
+ if (start_index < m_count && end_index < m_count)
+ {
+ AddGroup(start_index, end_index);
+ }
stbtt_FreeShape(font, instructions);
}
Bezier control(objects.beziers[objects.data_indices[m_indexes[i]]].ToAbsolute(bounds),CPURenderBounds(Rect(0,0,1,1), view, target));
//Debug("%s -> %s via %s", objects.beziers[objects.data_indices[m_indexes[i]]].Str().c_str(), control.Str().c_str(), bounds.Str().c_str());
// Draw a rectangle around the bezier for debugging the bounds rectangle calculations
+ /*
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y, target, Colour(1,0,0,1));
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y+pix_bounds.h, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(0,1,0,1));
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x, pix_bounds.y+pix_bounds.h, target, Colour(1,0,0,1));
ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(0,1,0,1));
-
+ */
// Draw lines between the control points for debugging
//ObjectRenderer::RenderLineOnCPU((int64_t)control.x0, (int64_t)control.y0, (int64_t)control.x1, (int64_t)control.y1,target);
//ObjectRenderer::RenderLineOnCPU((int64_t)control.x1, (int64_t)control.y1, (int64_t)control.x2, (int64_t)control.y2,target);
if (m_indexes[i] < first_obj_id) continue;
if (m_indexes[i] >= last_obj_id) continue;
+
Rect bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
PixelBounds pix_bounds(bounds);
Colour c(0.5,0.5,1,1);
+ // make the bounds just a little bit bigger
+ pix_bounds.x--;
+ pix_bounds.w++;
+ pix_bounds.y--;
+ pix_bounds.h++;
+ /*
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y, target, c);
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y+pix_bounds.h, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, c);
ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x, pix_bounds.y+pix_bounds.h, target, c);
ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, c);
+ */
+ // Attempt to shade the region
+ // Assumes the outline has been drawn first...
+ for (int64_t y = max((int64_t)0, pix_bounds.y); y <= min(pix_bounds.y+pix_bounds.h, target.h-1); ++y)
+ {
+ bool inside = false;
+ bool online = false;
+ for (int64_t x = max((int64_t)0, pix_bounds.x); x <= min(pix_bounds.x+pix_bounds.w, target.w-1); ++x)
+ {
+ int64_t index = (x+target.w*y)*4;
+ if (target.pixels[index+0] == 0 && target.pixels[index+1] == 0 && target.pixels[index+2] == 0 && target.pixels[index+3] == 255)
+ {
+ online = true;
+ continue;
+ }
+ else if (online)
+ {
+ inside = !inside;
+ online = false;
+ }
+
+ if (inside)
+ {
+ target.pixels[index+0] = c.r*255;
+ target.pixels[index+1] = c.g*255;
+ target.pixels[index+2] = c.b*255;
+ target.pixels[index+3] = c.a*255;
+ }
+ }
+ }
}
GroupRenderer() : ObjectRenderer(GROUP, "shaders/rect_vert.glsl", "shaders/rect_frag.glsl", "shaders/rect_outline_geom.glsl") {}
virtual ~GroupRenderer() {}
virtual void RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target, unsigned first_obj_id, unsigned last_obj_id);
+ // do nothing on GPU
+ virtual void RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id) {}
};
}
{
// Don't print out gl Errors we generated.
if (source == GL_DEBUG_SOURCE_APPLICATION) return;
- Error("OpenGL Error (%d): %s", id, msg);
+ //Error("OpenGL Error (%d): %s", id, msg);
+ // Spams this message on fglrx, disabling for now because it's damn annoying.
+ // ERROR: opengl_debug_callback (screen.cpp:21) - OpenGL Error (1011): glObjectLabel failed because (depending on the operation) a referenced binding point is empty; a referenced name is not the name of an object; or the given name is otherwise not valid to this operation (GL_INVALID_VALUE)
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="580.2168"
+ height="628.40479"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="cubicbeziers.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="238.97518"
+ inkscape:cy="593.69099"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1366"
+ inkscape:window-height="692"
+ inkscape:window-x="1280"
+ inkscape:window-y="280"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-25.625,-34.073881)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 140,180.93361 C 12.857141,-46.209249 357.71463,165.18237 25.714285,112.36218"
+ id="path2985"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 380.35613,179.82644 c -137.24439,-190.777369 508.57143,-69.28571 70,2.14286"
+ id="path2985-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 140.72388,285.19636 C 1.0445869,95.551229 109.42999,427.06216 181.42946,261.07525"
+ id="path2985-1-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 347.85731,304.91858 C 431.42173,164.77092 446.8731,426.58132 536.04516,266.65533"
+ id="path2985-1-6-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 107.93659,486.26514 C 191.50101,346.11748 69.571636,281.64861 166.82491,472.24555"
+ id="path2985-1-6-2-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 425.12449,419.71135 c 83.56442,-140.14766 190.93968,60.04344 -50.20815,55.68094"
+ id="path2985-1-6-2-5-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 84.401896,615.05664 C 238.677,694.11208 24.823746,388.21676 226.12273,658.61575"
+ id="path2985-1-6-2-5-5-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 367.54579,602.1648 C 175.33857,815.57053 683.74439,370.27416 508.25647,614.40918"
+ id="path2985-1-6-2-5-5-5-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- These lines are comments to assist human readability -->
+<svg id="svg_example"
+xmlns="http://www.w3.org/2000/svg"
+version="1.1"
+width="104"
+height="186">
+<!-- The curved region -->
+<path id="curvedshape"
+d = "m 57,185 c 0,0 57,-13 32,-43 -25,-30 -53,2 -25,
+-30 28,-32 52,17 28,-32 -24,-50 -16,44 -35,12
+-19,-32 13,-64 13,-64 0,0 40,-50 -0,-14 -40,36
+-94,68 -59,109 35,41 45,62 45,62 z"
+style = "fill:#ff0000; fill-opacity:0.75;
+stroke:#000000;"/>
+</svg>