// File: /workspace/github_cpp_makefile_star2_O3/thierry7100[P]CutOptim/src/SvgDoc.cpp
// Function: SvgDoc::SimplifyPath(NSVGpath*, double)
void SvgDoc::SimplifyPath(NSVGpath *path, double max_error)
{
NSVGPathElt *Elt, *Elt2, *oldElt = NULL;
float x, y;
float xmin, xmax, ymin, ymax;

    //  Now walk through all path elements to delete vertices if they are aligned
    x = path->StartX;
    y = path->StartY;
    xmin = x;
    xmax = x;
    ymin = y;
    ymax = y;
    Elt = path->PathElts;
    while ( Elt != NULL )
    {
        Elt2 = Elt->next;
        if ( Elt2 != NULL )
        {
            //  Build segment x,y --> Elt2->EndX, EndY
            //  Compute parameters of the line segment between Start and End
            double b = Elt2->EndX - x;
            double a = y - Elt2->EndY;
            double c = x * Elt2->EndY - Elt2->EndX*y;
            //  Compute distance between Elt->EndX, EndY and the segment
            // Distance between point and line is (a * p.x + b * p.y + c)*(a * p.x + b * p.y + c)/(a*a + b*b)
            double d1 = a * Elt->EndX + b * Elt->EndY + c;
            d1 *= d1;
            d1 /= a*a + b*b;
            if ( d1 < max_error )
            {
                //  remove Elt
                if ( oldElt == NULL)
                    path->PathElts = Elt2;
                else
                    oldElt->next = Elt2;
                path->nElts--;
                Elt = Elt2;
                continue;
            }
            else
            {
                x = Elt->EndX;
                y = Elt->EndY;
                xmin = fmin(xmin, x);
                xmax = fmax(xmax, x);
                ymin = fmin(ymin, y);
                ymax = fmax(ymax, y);
                //  Then next element
                oldElt = Elt;
                Elt = Elt2;
                continue;
            }
        }
        break;
    }
    path->PolyLine->bounds[0] = xmin;
    path->PolyLine->bounds[1] = ymin;
    path->PolyLine->bounds[2] = xmax;
    path->PolyLine->bounds[3] = ymax;
}

// Assembly:
movupd (%rsi), %xmm1
cvtpd2ps %xmm1, %xmm1
movq 0x10(%rsi), %rcx
testq %rcx, %rcx
je 0x2c6f5
movq 0x38(%rcx), %r8
testq %r8, %r8
je 0x2c6f5
leaq 0x10(%rsi), %rax
xorl %edx, %edx
movapd 0x11ac2(%rip), %xmm3    # 0x3e0c0
movapd %xmm1, %xmm2
movapd %xmm1, %xmm4
movq %r8, %rdi
xorps %xmm7, %xmm7
cvtss2sd %xmm4, %xmm7
movsd 0x8(%r8), %xmm8
movsd 0x10(%r8), %xmm9
movapd %xmm8, %xmm5
subsd %xmm7, %xmm5
movaps %xmm4, %xmm6
shufps $0x55, %xmm4, %xmm6     # xmm6 = xmm6[1,1],xmm4[1,1]
xorps %xmm10, %xmm10
cvtss2sd %xmm6, %xmm10
movaps %xmm10, %xmm11
subsd %xmm9, %xmm11
xorpd %xmm3, %xmm8
movupd 0x8(%rcx), %xmm6
movlhps %xmm5, %xmm10           # xmm10 = xmm10[0],xmm5[0]
shufpd $0x2, %xmm6, %xmm8      # xmm8 = xmm8[0],xmm6[1]
mulpd %xmm10, %xmm8
unpcklpd %xmm11, %xmm7           # xmm7 = xmm7[0],xmm11[0]
unpcklpd %xmm6, %xmm9            # xmm9 = xmm9[0],xmm6[0]
mulpd %xmm7, %xmm9
addpd %xmm8, %xmm9
movapd %xmm9, %xmm7
unpckhpd %xmm9, %xmm7            # xmm7 = xmm7[1],xmm9[1]
addsd %xmm9, %xmm7
mulsd %xmm7, %xmm7
mulsd %xmm5, %xmm5
mulsd %xmm11, %xmm11
addsd %xmm5, %xmm11
divsd %xmm11, %xmm7
ucomisd %xmm7, %xmm0
jbe 0x2c6aa
leaq 0x38(%rdx), %rcx
testq %rdx, %rdx
cmoveq %rax, %rcx
movq %rdi, (%rcx)
decl 0x18(%rsi)
jmp 0x2c6e3
cvtpd2ps %xmm6, %xmm4
movapd %xmm4, %xmm5
minps %xmm1, %xmm5
cmpunordps %xmm1, %xmm1
movapd %xmm4, %xmm6
andpd %xmm1, %xmm6
andnps %xmm5, %xmm1
orps %xmm6, %xmm1
movapd %xmm4, %xmm5
maxps %xmm2, %xmm5
cmpunordps %xmm2, %xmm2
movapd %xmm4, %xmm6
andpd %xmm2, %xmm6
andnps %xmm5, %xmm2
orps %xmm6, %xmm2
movq %rcx, %rdx
movq 0x38(%rdi), %r8
movq %rdi, %rcx
testq %r8, %r8
jne 0x2c606
jmp 0x2c6f8
movaps %xmm1, %xmm2
cvtps2pd %xmm1, %xmm0
movq 0x50(%rsi), %rax
movups %xmm0, 0x28(%rax)
cvtps2pd %xmm2, %xmm0
movups %xmm0, 0x38(%rax)
retq
nop