// File: /workspace/github_cpp_makefile_star2_O2/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
leaq 0x10(%rsi), %rax
movq 0x10(%rsi), %rdx
xorl %ecx, %ecx
movapd 0xeb18(%rip), %xmm3     # 0x360c0
movapd %xmm1, %xmm2
movapd %xmm1, %xmm5
cvtss2sd %xmm5, %xmm4
shufps $0x55, %xmm5, %xmm5     # xmm5 = xmm5[1,1,1,1]
cvtss2sd %xmm5, %xmm5
leaq 0x38(%rcx), %rdi
testq %rcx, %rcx
cmoveq %rax, %rdi
movq %rdx, %rcx
testq %rdx, %rdx
je 0x276a5
movq 0x38(%rcx), %rdx
testq %rdx, %rdx
je 0x276a5
movsd 0x8(%rdx), %xmm7
movsd 0x10(%rdx), %xmm8
movapd %xmm7, %xmm9
subsd %xmm4, %xmm9
movaps %xmm5, %xmm10
subsd %xmm8, %xmm10
xorpd %xmm3, %xmm7
movupd 0x8(%rcx), %xmm6
movaps %xmm5, %xmm11
movlhps %xmm9, %xmm11           # xmm11 = xmm11[0],xmm9[0]
shufpd $0x2, %xmm6, %xmm7      # xmm7 = xmm7[0],xmm6[1]
mulpd %xmm11, %xmm7
movapd %xmm4, %xmm11
unpcklpd %xmm10, %xmm11          # xmm11 = xmm11[0],xmm10[0]
unpcklpd %xmm6, %xmm8            # xmm8 = xmm8[0],xmm6[0]
mulpd %xmm11, %xmm8
addpd %xmm7, %xmm8
movapd %xmm8, %xmm7
unpckhpd %xmm8, %xmm7            # xmm7 = xmm7[1],xmm8[1]
addsd %xmm8, %xmm7
mulsd %xmm7, %xmm7
mulsd %xmm9, %xmm9
mulsd %xmm10, %xmm10
addsd %xmm9, %xmm10
divsd %xmm10, %xmm7
ucomisd %xmm7, %xmm0
jbe 0x2766a
movq %rdx, (%rdi)
decl 0x18(%rsi)
jmp 0x275c7
cvtpd2ps %xmm6, %xmm5
movapd %xmm5, %xmm4
minps %xmm1, %xmm4
cmpunordps %xmm1, %xmm1
movapd %xmm5, %xmm6
andpd %xmm1, %xmm6
andnps %xmm4, %xmm1
orps %xmm6, %xmm1
movapd %xmm5, %xmm4
maxps %xmm2, %xmm4
cmpunordps %xmm2, %xmm2
movapd %xmm5, %xmm6
andpd %xmm2, %xmm6
andnps %xmm4, %xmm2
orps %xmm6, %xmm2
jmp 0x275b0
cvtps2pd %xmm1, %xmm0
movq 0x50(%rsi), %rax
movups %xmm0, 0x28(%rax)
cvtps2pd %xmm2, %xmm0
movups %xmm0, 0x38(%rax)
retq