'This function calculates the appropriate label rotation given
the linecontour coordinates in screen units, the index of the
label location and the label width.
It will also break contour and calculate inlining if *lc* is
not empty (lc defaults to the empty list if None).  *spacing*
is the space around the label in pixels to leave empty.
Do both of these tasks at once to avoid calling mlab.path_length
multiple times, which is relatively costly.
The method used here involves calculating the path length
along the contour in pixel coordinates and then looking
approximately label width / 2 away from central point to
determine rotation and then to break contour if desired.'

def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):

    if (lc is None):
        lc = []
    hlw = (lw / 2.0)
    closed = mlab.is_closed_polygon(slc)
    if closed:
        slc = np.r_[(slc[ind:(-1)], slc[:(ind + 1)])]
        if len(lc):
            lc = np.r_[(lc[ind:(-1)], lc[:(ind + 1)])]
        ind = 0
    pl = mlab.path_length(slc)
    pl = (pl - pl[ind])
    xi = np.array([(- hlw), hlw])
    if closed:
        dp = np.array([pl[(-1)], 0])
    else:
        dp = np.zeros_like(xi)
    ll = mlab.less_simple_linear_interpolation(pl, slc, (dp + xi), extrap=True)
    dd = np.diff(ll, axis=0).ravel()
    if np.all((dd == 0)):
        rotation = 0.0
    else:
        rotation = np.rad2deg(np.arctan2(dd[1], dd[0]))
    if self.rightside_up:
        if (rotation > 90):
            rotation = (rotation - 180.0)
        if (rotation < (-90)):
            rotation = (180.0 + rotation)
    nlc = []
    if len(lc):
        xi = ((dp + xi) + np.array([(- spacing), spacing]))
        I = mlab.less_simple_linear_interpolation(pl, np.arange(len(pl)), xi, extrap=False)
        if ((not np.isnan(I[0])) and (int(I[0]) != I[0])):
            xy1 = mlab.less_simple_linear_interpolation(pl, lc, [xi[0]])
        if ((not np.isnan(I[1])) and (int(I[1]) != I[1])):
            xy2 = mlab.less_simple_linear_interpolation(pl, lc, [xi[1]])
        with np.errstate(invalid=u'ignore'):
            I = [np.floor(I[0]), np.ceil(I[1])]
        if closed:
            if np.all((~ np.isnan(I))):
                nlc.append(np.r_[(xy2, lc[int(I[1]):(int(I[0]) + 1)], xy1)])
        else:
            if (not np.isnan(I[0])):
                nlc.append(np.r_[(lc[:(int(I[0]) + 1)], xy1)])
            if (not np.isnan(I[1])):
                nlc.append(np.r_[(xy2, lc[int(I[1]):])])
    return (rotation, nlc)
