Program: 66276
Project: 66276
Buggy source:
/** 
 * @param dBlockY
 * @param dBlockHeight
 * @param aax
 * @param axPH
 * @param scY
 * @param iXLabelLocation
 * @param iYLabelLocation
 * @param iXTitleLocation
 * @param laYAxisLabels
 * @param iv
 * @param dXAxisLabelsThickness
 * @param dDecorationThickness
 * @param dXAxisTitleThickness
 * @param dHTotal
 * @param dY
 * @param dY1
 * @param dY2
 * @param bTicksAbove
 * @param bTicksBelow
 * @param bForwardScale
 * @return
 * @throws ChartException
 */
private double adjustVerticalWithValueOrigin(double dBlockY,double dBlockHeight,AllAxes aax,final OneAxis axPH,final AutoScale scY,final int iXLabelLocation,final int iYLabelLocation,final int iXTitleLocation,final Label laYAxisLabels,final IntersectionValue iv,double dXAxisLabelsThickness,double[] dDecorationThickness,double dXAxisTitleThickness,double dHTotal,double dY,double dY1,double dY2,final boolean bTicksAbove,final boolean bTicksBelow,final boolean bForwardScale) throws ChartException {
  double dDeltaY1=0, dDeltaY2=0;
  if (iXLabelLocation == ABOVE) {
    double dH1=(bTicksAbove ? getTickSize() : 0) + Math.max(dXAxisLabelsThickness,dDecorationThickness[0]);
    double dH2=(bTicksBelow ? getTickSize() : 0);
    if (dH1 + dH2 <= dHTotal) {
      dY1-=dH1;
      dY2+=dH2;
    }
 else {
      axPH.setShowLabels(false);
    }
    if (iXTitleLocation == ABOVE) {
      dY1-=dXAxisTitleThickness;
    }
 else     if (iXTitleLocation == BELOW) {
      dY2+=dXAxisTitleThickness;
    }
    dDeltaY1=dY - dY1;
    dDeltaY2=dY2 - dY;
    if (dY1 < dBlockY) {
      final Object[] oaMinMax=scY.getMinMax();
      boolean bForceBreak=false;
      do {
        scY.setEndPoints(scY.getStart() + scY.getStartShift(),scY.getEnd() - scY.getEndShift());
        scY.resetShifts();
        double[] da=scY.getEndPoints();
        double dT_RI=dBlockY - dY1;
        double dStart, dEnd;
        if (bForwardScale) {
          double dAMin_AMax=da[1] - da[0];
          double dAMin_RI=da[1] - dY;
          dEnd=da[1];
          dStart=(dT_RI / dAMin_RI) * dAMin_AMax + da[0];
          if (dStart < dBlockY) {
            dStart=dBlockY;
            bForceBreak=true;
          }
        }
 else {
          double dAMin_AMax=da[0] - da[1];
          double dAMin_RI=da[0] - dY;
          dStart=da[0];
          dEnd=(dT_RI / dAMin_RI) * dAMin_AMax + da[1];
          if (dEnd < dBlockY) {
            dEnd=dBlockY;
            bForceBreak=true;
          }
        }
        scY.setEndPoints(dStart,dEnd);
        scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
        if (!scY.isStepFixed()) {
          while (!scY.checkFit(ids,laYAxisLabels,iYLabelLocation)) {
            if (!scY.zoomOut()) {
              bForceBreak=true;
              break;
            }
            scY.updateAxisMinMax(oaMinMax[0],oaMinMax[1]);
            int tickCount=scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
            if (scY.getUnit() != null && asInteger(scY.getUnit()) == Calendar.YEAR && tickCount <= 3 || isSharedScale()) {
              bForceBreak=true;
              break;
            }
          }
        }
        dY=getLocation(scY,iv);
        dY1=dY - dDeltaY1;
        dY2=dY + dDeltaY2;
      }
 while (Math.abs(dY1 - dBlockY) > 1 && !bForceBreak);
    }
  }
 else   if (iXLabelLocation == BELOW) {
    double dH1=(bTicksAbove ? getTickSize() : 0);
    double dH2=(bTicksBelow ? getTickSize() : 0) + Math.max(dXAxisLabelsThickness,dDecorationThickness[1]);
    if (dH1 + dH2 <= dHTotal) {
      dY1-=dH1;
      dY2+=dH2;
    }
    if (iXTitleLocation == ABOVE) {
      dY1-=dXAxisTitleThickness;
    }
 else     if (iXTitleLocation == BELOW) {
      dY2+=dXAxisTitleThickness;
    }
    dDeltaY1=dY - dY1;
    dDeltaY2=dY2 - dY;
    if (dY2 > dBlockY + dBlockHeight) {
      final Object[] oaMinMax=scY.getMinMax();
      boolean bForceBreak=false;
      do {
        scY.setEndPoints(scY.getStart() + scY.getStartShift(),scY.getEnd() - scY.getEndShift());
        scY.resetShifts();
        double[] da=scY.getEndPoints();
        double dX2_X1=dY2 - (dBlockY + dBlockHeight);
        double dStart, dEnd;
        if (bForwardScale) {
          double dAMin_AMax=da[1] - da[0];
          double dX2_AMax=dY - da[0];
          dEnd=da[1] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dStart=da[0];
          if (dEnd > dBlockY + dBlockHeight) {
            dEnd=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
 else {
          double dAMin_AMax=da[0] - da[1];
          double dX2_AMax=dY - da[1];
          dStart=da[0] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dEnd=da[1];
          if (dStart > dBlockY + dBlockHeight) {
            dStart=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
        if (ChartUtil.mathEqual(Math.abs(dEnd - dStart),0)) {
          bForceBreak=true;
        }
        scY.setEndPoints(dStart,dEnd);
        scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
        if (!scY.isStepFixed()) {
          while (!scY.checkFit(ids,laYAxisLabels,iYLabelLocation)) {
            if (!scY.zoomOut()) {
              bForceBreak=true;
              break;
            }
            scY.updateAxisMinMax(oaMinMax[0],oaMinMax[1]);
            int tickCount=scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
            if (scY.getUnit() != null && asInteger(scY.getUnit()) == Calendar.YEAR && tickCount <= 3 || isSharedScale()) {
              bForceBreak=true;
              break;
            }
          }
        }
        dY=getLocation(scY,iv);
        dY2=dY + dDeltaY2;
        dY1=dY - dDeltaY1;
      }
 while (Math.abs(dY2 - (dBlockY + dBlockHeight)) > 1 && !bForceBreak);
    }
  }
  axPH.setTitleCoordinate((iXTitleLocation == ABOVE) ? dY1 - 1 : dY2 + 1 - dXAxisTitleThickness);
  return dY;
}

Fixed version (ground truth):
/** 
 * @param dBlockY
 * @param dBlockHeight
 * @param aax
 * @param axPH
 * @param scY
 * @param iXLabelLocation
 * @param iYLabelLocation
 * @param iXTitleLocation
 * @param laYAxisLabels
 * @param iv
 * @param dXAxisLabelsThickness
 * @param dDecorationThickness
 * @param dXAxisTitleThickness
 * @param dHTotal
 * @param dY
 * @param dY1
 * @param dY2
 * @param bTicksAbove
 * @param bTicksBelow
 * @param bForwardScale
 * @return
 * @throws ChartException
 */
private double adjustVerticalWithValueOrigin(double dBlockY,double dBlockHeight,AllAxes aax,final OneAxis axPH,final AutoScale scY,final int iXLabelLocation,final int iYLabelLocation,final int iXTitleLocation,final Label laYAxisLabels,final IntersectionValue iv,double dXAxisLabelsThickness,double[] dDecorationThickness,double dXAxisTitleThickness,double dHTotal,double dY,double dY1,double dY2,final boolean bTicksAbove,final boolean bTicksBelow,final boolean bForwardScale) throws ChartException {
  double dDeltaY1=0, dDeltaY2=0;
  if (iXLabelLocation == ABOVE) {
    double dH1=(bTicksAbove ? getTickSize() : 0) + Math.max(dXAxisLabelsThickness,dDecorationThickness[0]);
    double dH2=(bTicksBelow ? getTickSize() : 0);
    if (dH1 + dH2 <= dHTotal) {
      dY1-=dH1;
      dY2+=dH2;
    }
 else {
      axPH.setShowLabels(false);
    }
    if (iXTitleLocation == ABOVE) {
      dY1-=dXAxisTitleThickness;
    }
 else     if (iXTitleLocation == BELOW) {
      dY2+=dXAxisTitleThickness;
    }
    dDeltaY1=dY - dY1;
    dDeltaY2=dY2 - dY;
    if (dY1 < dBlockY) {
      final Object[] oaMinMax=scY.getMinMax();
      boolean bForceBreak=false;
      do {
        scY.setEndPoints(scY.getStart() + scY.getStartShift(),scY.getEnd() - scY.getEndShift());
        scY.resetShifts();
        double[] da=scY.getEndPoints();
        double dT_RI=dBlockY - dY1;
        double dStart, dEnd;
        if (bForwardScale) {
          double dAMin_AMax=da[1] - da[0];
          double dAMin_RI=da[1] - dY;
          dEnd=da[1];
          dStart=(dT_RI / dAMin_RI) * dAMin_AMax + da[0];
          if (dStart < dBlockY) {
            dStart=dBlockY;
            bForceBreak=true;
          }
        }
 else {
          double dAMin_AMax=da[0] - da[1];
          double dAMin_RI=da[0] - dY;
          dStart=da[0];
          dEnd=(dT_RI / dAMin_RI) * dAMin_AMax + da[1];
          if (dEnd < dBlockY) {
            dEnd=dBlockY;
            bForceBreak=true;
          }
        }
        scY.setEndPoints(dStart,dEnd);
        scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
        if (!scY.isStepFixed()) {
          while (!scY.checkFit(ids,laYAxisLabels,iYLabelLocation)) {
            if (!scY.zoomOut()) {
              bForceBreak=true;
              break;
            }
            scY.updateAxisMinMax(oaMinMax[0],oaMinMax[1]);
            int tickCount=scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
            if (scY.getUnit() != null && asInteger(scY.getUnit()) == Calendar.YEAR && tickCount <= 3 || isSharedScale()) {
              bForceBreak=true;
              break;
            }
          }
        }
        dY=getLocation(scY,iv);
        dY1=dY - dDeltaY1;
        dY2=dY + dDeltaY2;
      }
 while (Math.abs(dY1 - dBlockY) > 1 && !bForceBreak);
    }
 else     if (dY2 > dBlockY + dBlockHeight) {
      final Object[] oaMinMax=scY.getMinMax();
      boolean bForceBreak=false;
      do {
        scY.setEndPoints(scY.getStart() + scY.getStartShift(),scY.getEnd() - scY.getEndShift());
        scY.resetShifts();
        double[] da=scY.getEndPoints();
        double dX2_X1=dY2 - (dBlockY + dBlockHeight);
        double dStart, dEnd;
        if (bForwardScale) {
          double dAMin_AMax=da[1] - da[0];
          double dX2_AMax=dY - da[0];
          dEnd=da[1] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dStart=da[0];
          if (dEnd > dBlockY + dBlockHeight) {
            dEnd=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
 else {
          double dAMin_AMax=da[0] - da[1];
          double dX2_AMax=dY - da[1];
          dStart=da[0] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dEnd=da[1];
          if (dStart > dBlockY + dBlockHeight) {
            dStart=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
        if (ChartUtil.mathEqual(Math.abs(dEnd - dStart),0)) {
          bForceBreak=true;
        }
        scY.setEndPoints(dStart,dEnd);
        scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
        if (!scY.isStepFixed()) {
          while (!scY.checkFit(ids,laYAxisLabels,iYLabelLocation)) {
            if (!scY.zoomOut()) {
              bForceBreak=true;
              break;
            }
            scY.updateAxisMinMax(oaMinMax[0],oaMinMax[1]);
            int tickCount=scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
            if (scY.getUnit() != null && asInteger(scY.getUnit()) == Calendar.YEAR && tickCount <= 3 || isSharedScale()) {
              bForceBreak=true;
              break;
            }
          }
        }
        dY=getLocation(scY,iv);
        dY2=dY + dDeltaY2;
        dY1=dY - dDeltaY1;
      }
 while (Math.abs(dY2 - (dBlockY + dBlockHeight)) > 1 && !bForceBreak);
    }
  }
 else   if (iXLabelLocation == BELOW) {
    double dH1=(bTicksAbove ? getTickSize() : 0);
    double dH2=(bTicksBelow ? getTickSize() : 0) + Math.max(dXAxisLabelsThickness,dDecorationThickness[1]);
    if (dH1 + dH2 <= dHTotal) {
      dY1-=dH1;
      dY2+=dH2;
    }
    if (iXTitleLocation == ABOVE) {
      dY1-=dXAxisTitleThickness;
    }
 else     if (iXTitleLocation == BELOW) {
      dY2+=dXAxisTitleThickness;
    }
    dDeltaY1=dY - dY1;
    dDeltaY2=dY2 - dY;
    if (dY2 > dBlockY + dBlockHeight) {
      final Object[] oaMinMax=scY.getMinMax();
      boolean bForceBreak=false;
      do {
        scY.setEndPoints(scY.getStart() + scY.getStartShift(),scY.getEnd() - scY.getEndShift());
        scY.resetShifts();
        double[] da=scY.getEndPoints();
        double dX2_X1=dY2 - (dBlockY + dBlockHeight);
        double dStart, dEnd;
        if (bForwardScale) {
          double dAMin_AMax=da[1] - da[0];
          double dX2_AMax=dY - da[0];
          dEnd=da[1] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dStart=da[0];
          if (dEnd > dBlockY + dBlockHeight) {
            dEnd=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
 else {
          double dAMin_AMax=da[0] - da[1];
          double dX2_AMax=dY - da[1];
          dStart=da[0] - (dX2_X1 / dX2_AMax) * dAMin_AMax;
          dEnd=da[1];
          if (dStart > dBlockY + dBlockHeight) {
            dStart=dBlockY + dBlockHeight;
            bForceBreak=true;
          }
        }
        if (ChartUtil.mathEqual(Math.abs(dEnd - dStart),0)) {
          bForceBreak=true;
        }
        scY.setEndPoints(dStart,dEnd);
        scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
        if (!scY.isStepFixed()) {
          while (!scY.checkFit(ids,laYAxisLabels,iYLabelLocation)) {
            if (!scY.zoomOut()) {
              bForceBreak=true;
              break;
            }
            scY.updateAxisMinMax(oaMinMax[0],oaMinMax[1]);
            int tickCount=scY.computeTicks(ids,laYAxisLabels,iYLabelLocation,VERTICAL,dStart,dEnd,true,aax);
            if (scY.getUnit() != null && asInteger(scY.getUnit()) == Calendar.YEAR && tickCount <= 3 || isSharedScale()) {
              bForceBreak=true;
              break;
            }
          }
        }
        dY=getLocation(scY,iv);
        dY2=dY + dDeltaY2;
        dY1=dY - dDeltaY1;
      }
 while (Math.abs(dY2 - (dBlockY + dBlockHeight)) > 1 && !bForceBreak);
    }
  }
  axPH.setTitleCoordinate((iXTitleLocation == ABOVE) ? dY1 - 1 : dY2 + 1 - dXAxisTitleThickness);
  return dY;
}