Program: 18187
Project: 18187
Buggy source:
@Override public void drawValues(Canvas c){
  MPPointF center=mChart.getCenterCircleBox();
  float radius=mChart.getRadius();
  float rotationAngle=mChart.getRotationAngle();
  float[] drawAngles=mChart.getDrawAngles();
  float[] absoluteAngles=mChart.getAbsoluteAngles();
  float phaseX=mAnimator.getPhaseX();
  float phaseY=mAnimator.getPhaseY();
  final float holeRadiusPercent=mChart.getHoleRadius() / 100.f;
  float labelRadiusOffset=radius / 10f * 3.6f;
  if (mChart.isDrawHoleEnabled()) {
    labelRadiusOffset=(radius - (radius * holeRadiusPercent)) / 2f;
  }
  final float labelRadius=radius - labelRadiusOffset;
  PieData data=mChart.getData();
  List<IPieDataSet> dataSets=data.getDataSets();
  float yValueSum=data.getYValueSum();
  boolean drawEntryLabels=mChart.isDrawEntryLabelsEnabled();
  float angle;
  int xIndex=0;
  c.save();
  for (int i=0; i < dataSets.size(); i++) {
    IPieDataSet dataSet=dataSets.get(i);
    final boolean drawValues=dataSet.isDrawValuesEnabled();
    if (!drawValues && !drawEntryLabels)     continue;
    final PieDataSet.ValuePosition xValuePosition=dataSet.getXValuePosition();
    final PieDataSet.ValuePosition yValuePosition=dataSet.getYValuePosition();
    applyValueTextStyle(dataSet);
    float lineHeight=Utils.calcTextHeight(mValuePaint,"String_Node_Str") + Utils.convertDpToPixel(4f);
    IValueFormatter formatter=dataSet.getValueFormatter();
    int entryCount=dataSet.getEntryCount();
    mValueLinePaint.setColor(dataSet.getValueLineColor());
    mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
    float offset=Utils.convertDpToPixel(5.f);
    final float sliceSpace=getSliceSpace(dataSet);
    for (int j=0; j < entryCount; j++) {
      PieEntry entry=dataSet.getEntryForIndex(j);
      if (xIndex == 0)       angle=0.f;
 else       angle=absoluteAngles[xIndex - 1] * phaseX;
      final float sliceAngle=drawAngles[xIndex];
      final float sliceSpaceMiddleAngle=sliceSpace / (Utils.FDEG2RAD * labelRadius);
      final float angleOffset=(sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
      angle=angle + angleOffset;
      final float transformedAngle=rotationAngle + angle * phaseY;
      float value=mChart.isUsePercentValuesEnabled() ? entry.getY() / yValueSum * 100f : entry.getY();
      final float sliceXBase=(float)Math.cos(transformedAngle * Utils.FDEG2RAD);
      final float sliceYBase=(float)Math.sin(transformedAngle * Utils.FDEG2RAD);
      final boolean drawXOutside=drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
      final boolean drawYOutside=drawValues && yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
      final boolean drawXInside=drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
      final boolean drawYInside=drawValues && yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
      if (drawXOutside || drawYOutside) {
        final float valueLineLength1=dataSet.getValueLinePart1Length();
        final float valueLineLength2=dataSet.getValueLinePart2Length();
        final float valueLinePart1OffsetPercentage=dataSet.getValueLinePart1OffsetPercentage() / 100.f;
        float pt2x, pt2y;
        float labelPtx, labelPty;
        float line1Radius;
        if (mChart.isDrawHoleEnabled())         line1Radius=(radius - (radius * holeRadiusPercent)) * valueLinePart1OffsetPercentage + (radius * holeRadiusPercent);
 else         line1Radius=radius * valueLinePart1OffsetPercentage;
        final float polyline2Width=dataSet.isValueLineVariableLength() ? labelRadius * valueLineLength2 * (float)Math.abs(Math.sin(transformedAngle * Utils.FDEG2RAD)) : labelRadius * valueLineLength2;
        final float pt0x=line1Radius * sliceXBase + center.x;
        final float pt0y=line1Radius * sliceYBase + center.y;
        final float pt1x=labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
        final float pt1y=labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
        if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {
          pt2x=pt1x - polyline2Width;
          pt2y=pt1y;
          mValuePaint.setTextAlign(Align.RIGHT);
          labelPtx=pt2x - offset;
          labelPty=pt2y;
        }
 else {
          pt2x=pt1x + polyline2Width;
          pt2y=pt1y;
          mValuePaint.setTextAlign(Align.LEFT);
          labelPtx=pt2x + offset;
          labelPty=pt2y;
        }
        if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
          c.drawLine(pt0x,pt0y,pt1x,pt1y,mValueLinePaint);
          c.drawLine(pt1x,pt1y,pt2x,pt2y,mValueLinePaint);
        }
        if (drawXOutside && drawYOutside) {
          drawValue(c,formatter,value,entry,0,labelPtx,labelPty,dataSet.getValueTextColor(j));
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),labelPtx,labelPty + lineHeight);
          }
        }
 else         if (drawXOutside) {
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),labelPtx,labelPty + lineHeight / 2.f);
          }
        }
 else         if (drawYOutside) {
          drawValue(c,formatter,value,entry,0,labelPtx,labelPty + lineHeight / 2.f,dataSet.getValueTextColor(j));
        }
      }
      if (drawXInside || drawYInside) {
        float x=labelRadius * sliceXBase + center.x;
        float y=labelRadius * sliceYBase + center.y;
        mValuePaint.setTextAlign(Align.CENTER);
        if (drawXInside && drawYInside) {
          drawValue(c,formatter,value,entry,0,x,y,dataSet.getValueTextColor(j));
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),x,y + lineHeight);
          }
        }
 else         if (drawXInside) {
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),x,y + lineHeight / 2f);
          }
        }
 else         if (drawYInside) {
          drawValue(c,formatter,value,entry,0,x,y + lineHeight / 2f,dataSet.getValueTextColor(j));
        }
      }
      xIndex++;
    }
  }
  MPPointF.recycleInstance(center);
  c.restore();
}

Fixed version (ground truth):
@Override public void drawValues(Canvas c){
  MPPointF center=mChart.getCenterCircleBox();
  float radius=mChart.getRadius();
  float rotationAngle=mChart.getRotationAngle();
  float[] drawAngles=mChart.getDrawAngles();
  float[] absoluteAngles=mChart.getAbsoluteAngles();
  float phaseX=mAnimator.getPhaseX();
  float phaseY=mAnimator.getPhaseY();
  final float holeRadiusPercent=mChart.getHoleRadius() / 100.f;
  float labelRadiusOffset=radius / 10f * 3.6f;
  if (mChart.isDrawHoleEnabled()) {
    labelRadiusOffset=(radius - (radius * holeRadiusPercent)) / 2f;
  }
  final float labelRadius=radius - labelRadiusOffset;
  PieData data=mChart.getData();
  List<IPieDataSet> dataSets=data.getDataSets();
  float yValueSum=data.getYValueSum();
  boolean drawEntryLabels=mChart.isDrawEntryLabelsEnabled();
  float angle;
  int xIndex=0;
  c.save();
  float offset=Utils.convertDpToPixel(5.f);
  for (int i=0; i < dataSets.size(); i++) {
    IPieDataSet dataSet=dataSets.get(i);
    final boolean drawValues=dataSet.isDrawValuesEnabled();
    if (!drawValues && !drawEntryLabels)     continue;
    final PieDataSet.ValuePosition xValuePosition=dataSet.getXValuePosition();
    final PieDataSet.ValuePosition yValuePosition=dataSet.getYValuePosition();
    applyValueTextStyle(dataSet);
    float lineHeight=Utils.calcTextHeight(mValuePaint,"String_Node_Str") + Utils.convertDpToPixel(4f);
    IValueFormatter formatter=dataSet.getValueFormatter();
    int entryCount=dataSet.getEntryCount();
    mValueLinePaint.setColor(dataSet.getValueLineColor());
    mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
    final float sliceSpace=getSliceSpace(dataSet);
    for (int j=0; j < entryCount; j++) {
      PieEntry entry=dataSet.getEntryForIndex(j);
      if (xIndex == 0)       angle=0.f;
 else       angle=absoluteAngles[xIndex - 1] * phaseX;
      final float sliceAngle=drawAngles[xIndex];
      final float sliceSpaceMiddleAngle=sliceSpace / (Utils.FDEG2RAD * labelRadius);
      final float angleOffset=(sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
      angle=angle + angleOffset;
      final float transformedAngle=rotationAngle + angle * phaseY;
      float value=mChart.isUsePercentValuesEnabled() ? entry.getY() / yValueSum * 100f : entry.getY();
      final float sliceXBase=(float)Math.cos(transformedAngle * Utils.FDEG2RAD);
      final float sliceYBase=(float)Math.sin(transformedAngle * Utils.FDEG2RAD);
      final boolean drawXOutside=drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
      final boolean drawYOutside=drawValues && yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
      final boolean drawXInside=drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
      final boolean drawYInside=drawValues && yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
      if (drawXOutside || drawYOutside) {
        final float valueLineLength1=dataSet.getValueLinePart1Length();
        final float valueLineLength2=dataSet.getValueLinePart2Length();
        final float valueLinePart1OffsetPercentage=dataSet.getValueLinePart1OffsetPercentage() / 100.f;
        float pt2x, pt2y;
        float labelPtx, labelPty;
        float line1Radius;
        if (mChart.isDrawHoleEnabled())         line1Radius=(radius - (radius * holeRadiusPercent)) * valueLinePart1OffsetPercentage + (radius * holeRadiusPercent);
 else         line1Radius=radius * valueLinePart1OffsetPercentage;
        final float polyline2Width=dataSet.isValueLineVariableLength() ? labelRadius * valueLineLength2 * (float)Math.abs(Math.sin(transformedAngle * Utils.FDEG2RAD)) : labelRadius * valueLineLength2;
        final float pt0x=line1Radius * sliceXBase + center.x;
        final float pt0y=line1Radius * sliceYBase + center.y;
        final float pt1x=labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
        final float pt1y=labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
        if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {
          pt2x=pt1x - polyline2Width;
          pt2y=pt1y;
          mValuePaint.setTextAlign(Align.RIGHT);
          if (drawXOutside)           mEntryLabelsPaint.setTextAlign(Align.RIGHT);
          labelPtx=pt2x - offset;
          labelPty=pt2y;
        }
 else {
          pt2x=pt1x + polyline2Width;
          pt2y=pt1y;
          mValuePaint.setTextAlign(Align.LEFT);
          if (drawXOutside)           mEntryLabelsPaint.setTextAlign(Align.LEFT);
          labelPtx=pt2x + offset;
          labelPty=pt2y;
        }
        if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
          c.drawLine(pt0x,pt0y,pt1x,pt1y,mValueLinePaint);
          c.drawLine(pt1x,pt1y,pt2x,pt2y,mValueLinePaint);
        }
        if (drawXOutside && drawYOutside) {
          drawValue(c,formatter,value,entry,0,labelPtx,labelPty,dataSet.getValueTextColor(j));
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),labelPtx,labelPty + lineHeight);
          }
        }
 else         if (drawXOutside) {
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),labelPtx,labelPty + lineHeight / 2.f);
          }
        }
 else         if (drawYOutside) {
          drawValue(c,formatter,value,entry,0,labelPtx,labelPty + lineHeight / 2.f,dataSet.getValueTextColor(j));
        }
      }
      if (drawXInside || drawYInside) {
        float x=labelRadius * sliceXBase + center.x;
        float y=labelRadius * sliceYBase + center.y;
        mValuePaint.setTextAlign(Align.CENTER);
        if (drawXInside && drawYInside) {
          drawValue(c,formatter,value,entry,0,x,y,dataSet.getValueTextColor(j));
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),x,y + lineHeight);
          }
        }
 else         if (drawXInside) {
          if (j < data.getEntryCount() && entry.getLabel() != null) {
            drawEntryLabel(c,entry.getLabel(),x,y + lineHeight / 2f);
          }
        }
 else         if (drawYInside) {
          drawValue(c,formatter,value,entry,0,x,y + lineHeight / 2f,dataSet.getValueTextColor(j));
        }
      }
      xIndex++;
    }
  }
  MPPointF.recycleInstance(center);
  c.restore();
}