def realizeSymbol(self, pp, grp, arp, symbol, annotation, onY2, clipPlotArea, clipDecoratedChart, drawMainSymbol, x, y, prevX, prevY, nextX, nextY):

        if not drawMainSymbol:
            return

        xPx = pp.xToPixel(x)
        yPx = pp.yToPixel(y, onY2)
        spacing = symbol.getFillSpacing()
        thickness = symbol.getFillThickness()
        r = symbol.getPieSliceRadius(pp, onY2)
        theta0 = symbol.getPieSliceTheta0()
        theta1 = symbol.getPieSliceTheta1()
        canvas = grp.getCanvas()
        if (Double.NaN==(xPx))  or  (Double.NaN==(yPx)):
            return; # undefined slice pivot point

        elif clipPlotArea  and  not self.intersects(xPx-r, yPx-r, xPx+r, yPx+r, 0, 0, pp.getXChartSize(), pp.getYChartSize()):
            return; # rect containing pie is off plot area

        elif clipDecoratedChart:
            yAxisWidth = pp.getYAxisEnsembleWidth()
            titleThickness = pp.chartTitleThickness()
            if not SymbolType.intersects(self, 0.0 - yAxisWidth,
                                         0.0 - titleThickness, 
                            pp.getXChartSizeDecoratedQuickly()-yAxisWidth, 
                            pp.getYChartSizeDecoratedQuickly()-titleThickness, 
                            xPx-r, yPx-r, xPx+r, yPx+r):
                return; # rect containing pie is off decorated chart


        # else bounding rectangle of pie containing the slice visible

        if 0 == spacing  and  None != canvas  and  thickness > 0:
            # continuous fill pie slice and canvas is available

            """
            * Solid fill pie slices implement the notion of internal vs
            * external borders a bit differently than rectangular
            * symbols.
            * <p>
            *
            * Internal borders are always drawn "centered",
            * that is, half internal, half external.  In part,
            * this is because that is how "stroke" of the
            * canvas API does it, so it's easier to implement.
            * But mainly it is because, when you assemble
            * several slices into a full pie, a centered
            * border, provided that each slice has the same
            * border color, is really the only choice that
            * looks right (this is a constraint of the
            * geometry how the slices fit together into a
            * pie).  <p>
            *
            * External borders (negative border width) are
            * drawn outside the slice proper by doubling the
            * thickness, and then over-filling the internal
            * part of the border by issuing the fill after,
            * instead of before, the border is drawn. Though
            * external borders don't look right within a pie
            * (because of how the slices occlude each other's
            * borders) they can be handy for making slice
            * selection borders that are drawn entirely
            * outside of the selected slice.
            *
            """
            borderWidth = symbol.getBorderWidth()
            if borderWidth >= 0:
                adjustedBorderWidth = borderWidth 
            else:
                adjustedBorderWidth = 2*abs(borderWidth)

            """
            * With incubator's <tt>GWTCanvas</tt>, IE7 & Chrome draw
            * 0 and 2*Pi slices incorrectly.  See issues #278
            * #282 for more information: <p>
            *
            * http:#code.google.com/p/google-web-toolkit-incubator/issues/detail?id=278
            * http:#code.google.com/p/google-web-toolkit-incubator/issues/detail?id=282
            * <p>
            *
            * Pies with > 1000 px radii are unlikely (tried
            * using 10000, but it didn't work in Chrome).
            *
            """
            MIN_DTHETA = 1./1000
            MAX_DTHETA = 2*math.pi - MIN_DTHETA

            # canvas measures angles clockwise from +x-axis
            # our angles are counter-clockwise from +x-axis
            dTheta = theta0 - theta1
            angleStart = 2*math.pi-theta0
            angleEnd = (angleStart +
                    max(MIN_DTHETA, min(dTheta, MAX_DTHETA)))

            if dTheta >= MIN_DTHETA  or  borderWidth < 0:
                canvas.beginPath()
                canvas.setLineWidth(adjustedBorderWidth)

                canvas.arc(xPx - grp.x0, yPx - grp.y0, r,
                            angleStart, angleEnd, False)
                if dTheta <= MAX_DTHETA:
                    canvas.lineTo(xPx - grp.x0, yPx- grp.y0)

                # else avoid "line to center" in full pies

                canvas.closePath()

                #canvas.translate(xPx - grp.x0, yPx - grp.y0)

                borderColor = symbol.getBorderColor()
                backgroundColor = symbol.getBackgroundColor()
                """
                * XXX: The approach to transparent border/fill
                * used below is to simply not stroke the border
                * or to not fill the inside of the path. This
                * isn't exactly right, because the region where
                * the border overlaps the filled area does not
                * always become transparent when it should.
                * These errors likely won't be noticed in most
                * usage scenarios, and without the ability to
                * replace filled/stroked regions with
                * transparent pixels (I don't think GWTCanvas
                * can do this?) there isn't an easy fix.
                *
                """

                # non-negative borders fill before stroking (thus
                # stroke overwrites internal half of border)
                # GWTCanvas thows an exception w "transparent"
                if (borderWidth >= 0  and  thickness > 0  and  
                    GChartConsts.TRANSPARENT_BORDER_COLOR != backgroundColor  and  
                    "transparent" != backgroundColor):
                    canvas.setFillStyle(backgroundColor)
                    canvas.fill()


                # stroke whenever a border is present
                if (borderWidth != 0  and  
                    GChartConsts.TRANSPARENT_BORDER_COLOR != borderColor  and  
                    "transparent" != borderColor):
                    canvas.setStrokeStyle(borderColor)
                    canvas.stroke()


                # negative borders fill AFTER stroking (thus zapping
                # the internal half of the stroked border).
                if (borderWidth < 0  and  
                    thickness > 0  and  
                    GChartConsts.TRANSPARENT_BORDER_COLOR != backgroundColor  and  
                    "transparent" != backgroundColor):
                    canvas.setFillStyle(backgroundColor)
                    canvas.fill()

            # else 0-sized slice, 0 or internal border, is just dropped

        else:
            if 0 == spacing:
                spacing = 1

            # if center point is on the chart, draw it:

            prevXPx = pp.xToPixel(prevX)
            prevYPx = pp.yToPixel(prevY, onY2)
            nextXPx = pp.xToPixel(nextX)
            nextYPx = pp.yToPixel(nextY, onY2)
            nBands = int ( round(r/spacing) )
            """ Holds positions at which the current vertical or
            * horizontal "gridline-like band" intersects the outter
            * perimeter of the current pie slice. These positions
            * are used to define the location and size of shading
            * bars required for each pie slice.
            *
            * Note: Although most pie slice perimeters are convex
            * and thus have perimeters that intersect a gridline
            * in at most two points, pie slices that take up more
            * than half of the entire pie have perimeters that
            * can (across their pacman-like mouth) intersect a
            * gridline at up to four points.
            *
            """
            MAX_PIE_SLICE_PERIMETER_INTERSECTIONS = 4
            p = [0.0, 0.0, 0.0, 0.0]
            EPS = 0.5
            sl = self.getSliceLimits(theta1, theta0)
            optimalIsVertical = (sl.yMax - sl.yMin) > (sl.xMax - sl.xMin)
            isFullPie = (symbol.getPieSliceSize() == 1.0)
            # perform any vertical shading that may be required:
            if (nBands > 0  and  
                 (self.verticallyShaded  or  
                      (self.optimallyShaded  and  
                           optimalIsVertical))):
                for i in range(int(round(nBands*sl.xMin)),
                               int(sl.xMax*nBands)):
                    nP = 0
                    dxPx = r*(i+0.5)/nBands
                    dyPx = math.sqrt(r*r - dxPx*dxPx)
                    # x of vertical line bisecting the shading band
                    xi = xPx + dxPx
                    # y-positions where this band crosses circle perimeter
                    c1 = yPx - dyPx
                    c2 = yPx + dyPx
                    # y-positions where this band crosses each slice edge
                    # (full pies don't have pie slice edges)
                    if isFullPie:
                        e1 = Double.NaN
                    else:
                        e1 = self.yWherePieEdgeIntersectsVerticalLine(
                                            xi,xPx,yPx,r,theta0)
                    if isFullPie:
                        e2 = Double.NaN
                    else:
                        e2 = self.yWherePieEdgeIntersectsVerticalLine(
                                            xi,xPx,yPx,r,theta1)
                    # Exclude circle perimeter intercepts outside of
                    # the slice.  Note: Pixel y coordinates used in
                    # browser increase going down, but cartesian y
                    # coordinates used in trig functions increase
                    # going up, hence the sign-flipping on second arg
                    # of angle function below.
                    if self.angleInRange(self.angle(xi-xPx,yPx-c1),theta0,theta1):
                        p[nP] = c1
                        nP += 1

                    # intersection points sorted by increasing y within p[]
                    if e1 < e2:
                        if not Double.NaN==(e1):
                            p[nP] = e1
                            nP += 1

                        if not Double.NaN==(e2):
                            p[nP] = e2
                            nP += 1


                    else:
                        if not Double.NaN==(e2):
                            p[nP] = e2
                            nP += 1

                        if not Double.NaN==(e1):
                            p[nP] = e1
                            nP += 1



                    if self.angleInRange(self.angle(xi-xPx, yPx-c2),theta0,theta1):
                        p[nP] = c2
                        nP += 1

                    for j in range(1, nP):
                        # logic below avoids drawing a line across the
                        # non-convex "pacman mouth" that occurs with any
                        # bigger-than-half-pie-sized slices, by
                        # requiring that a line drawn from the pie
                        # center to an interpolated point on each
                        # shading bar forms an angle in the slice's
                        # angular range. We use a point 30% rather than
                        # 50% of the way inbetween to avoid ever hitting the
                        # center of the pie (where angle is ambiguous).
                        #
                        # Note that, due to roundoff error, you cannot
                        # ALWAYS rely on the (mathematically correct)
                        # fact that problematic bars always connect p[1]
                        # and p[2].
                        if (abs(theta0-theta1) <= math.pi  or  
                            self.angleInRange(self.angle(xi-xPx,
                                                         yPx-(0.3*p[j]+0.7*p[j-1])),
                                              theta0,theta1)):
                            # widening of EPS pixels on either side fills in
                            # tiny intra-slice gaps (that can otherwise appear
                            # due to roundoff) by making each bar a tad bigger.
                            self.realizeOneImageOfSymbol(pp, grp, arp,
                                                    symbol, None,
                                                    onY2,
                                                    clipPlotArea,
                                                    clipDecoratedChart,
                                                    xi-0.5*
                                                    thickness,
                                                    p[j-1]-EPS,
                                                    prevXPx, prevYPx,
                                                    nextXPx, nextYPx,
                                                    thickness,
                                                    p[j] - p[j-1] +2*EPS)





            # Now do any required horizontal shading. This is
            # basically the same as the code for vertical shading
            # above (w appropriate transposition/adjustments).
            if (nBands > 0  and  (self.horizontallyShaded  or  
                    (self.optimallyShaded  and  
                     not optimalIsVertical))):
                for i in range( int ( round(-nBands*sl.yMax)),
                                int ( -nBands * sl.yMin) ):
                    nP = 0
                    dyPx = r*(i+0.5)/nBands
                    dxPx = math.sqrt(r*r - dyPx*dyPx)
                    # y of the horizontal line bisecting the shading band
                    yi = yPx + dyPx

                    # x-positions where this band crosses circle perimeter
                    c1 = xPx - dxPx
                    c2 = xPx + dxPx

                    # x-positions where this band crosses each slice edge
                    # (full pies don't have pie slice edges)
                    if isFullPie:
                        e1 = Double.NaN
                        e2 = Double.NaN
                    else:
                        e1 = self.xWherePieEdgeIntersectsHorizontalLine(
                                yi,xPx,yPx,r,theta0)
                        e2 = self.xWherePieEdgeIntersectsHorizontalLine(
                                yi,xPx,yPx,r,theta1)
                    # exclude circle perimeter intercepts outside of
                    # the slice
                    if self.angleInRange(self.angle(c1-xPx, yPx-yi),theta0,theta1):
                        p[nP] = c1
                        nP += 1


                    # intersection points sorted by increasing x within p[]
                    if e1 < e2:
                        if not Double.NaN==(e1):
                            p[nP] = e1
                            nP += 1

                        if not Double.NaN==(e2):
                            p[nP] = e2
                            nP += 1


                    else:
                        if not Double.NaN==(e2):
                            p[nP] = e2
                            nP += 1

                        if not Double.NaN==(e1):
                            p[nP] = e1
                            nP += 1



                    if self.angleInRange(self.angle(c2-xPx, yPx-yi),theta0,theta1):
                        p[nP] = c2
                        nP += 1


                    for j in range(1, nP):
                        # c.f. comment on corresponding vertical code above.
                        if abs(theta0-theta1) <= math.pi  or  self.angleInRange(self.angle((0.3*p[j]+0.7*p[j-1])-xPx, yPx-yi), theta0,theta1):
                            # widening of EPS pixels on either side fills in
                            # tiny intra-slice gaps that can sometimes appear
                            # by making slices just a tad bigger.
                            self.realizeOneImageOfSymbol(pp, grp, arp,
                                                    symbol, None,
                                                    onY2,
                                                    clipPlotArea,
                                                    clipDecoratedChart,
                                                    p[j-1]-EPS,
                                                    yi-0.5*
                                                    thickness,
                                                    prevXPx, prevYPx,
                                                    nextXPx, nextYPx,
                                                    p[j]-p[j-1] + 2*EPS,
                                                    thickness)






        # if the image has an attached label, realize that
        if annotation!=None  and  (annotation.getText() is not None  or  annotation.getWidget() is not None)  and  annotation.getVisible():

            # plus x-axis, for shifts, always corresponds to
            # outward pointing radius that bisects the slice,
            # with positive y axis, for shifts, at a 90 degree
            # counter-clockwise rotation from this x. Basic
            # trigonometry and this spec yeilds lines below.
            thetaMid = (theta0+theta1)/2.
            dX = annotation.getXShift()
            dY = annotation.getYShift()
            sinTheta = math.sin(thetaMid)
            cosTheta = math.cos(thetaMid)
            loc = annotation.getLocation()
            if None == loc:
                loc = self.defaultAnnotationLocation()

            # note: pixel Y increases down but yShift & "trig Y"
            # increase going up, which explains dY sign reversal
            arp.renderAnnotation(annotation,
                                loc.decodePieLocation(thetaMid),
                                xPx+(r+dX)*cosTheta - dY*sinTheta,
                                yPx-(r+dX)*sinTheta - dY*cosTheta,
                                0, 0,
                                symbol)


 # end of class PieSliceSymbolType
dataset/ETHPy150Open anandology/pyjamas/library/gwt/chart/SymbolType.py/PieSliceSymbolType.realizeSymbol/original