Program: 70021
Project: 70021
Buggy source:
/** 
 * Renders the legend block based on the legend rendering rules.
 * @param ipr
 * @param lg
 * @param htRenderers
 * @throws ChartException
 */
public void renderLegend(IPrimitiveRenderer ipr,Legend lg,Map<Series,LegendItemRenderingHints> htRenderers) throws ChartException {
  if (!lg.isVisible()) {
    return;
  }
  renderBlock(ipr,lg,StructureSource.createLegend(lg));
  final IDisplayServer xs=getDevice().getDisplayServer();
  final double dScale=getDeviceScale();
  Bounds bo=goFactory.scaleBounds(lg.getBounds(),dScale);
  Size sz=null;
  double dX, dY;
  if (lg.getPosition() != Position.INSIDE_LITERAL) {
    try {
      sz=lg.getPreferredSize(xs,cm,rtc);
    }
 catch (    Exception ex) {
      throw new ChartException(ChartEnginePlugin.ID,ChartException.RENDERING,ex);
    }
    sz.scale(dScale);
    dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
    dY=0;
    if (lg.isSetAnchor()) {
      int iAnchor=lg.getAnchor().getValue();
      if (isRightToLeft()) {
        if (iAnchor == Anchor.EAST) {
          iAnchor=Anchor.WEST;
        }
 else         if (iAnchor == Anchor.NORTH_EAST) {
          iAnchor=Anchor.NORTH_WEST;
        }
 else         if (iAnchor == Anchor.SOUTH_EAST) {
          iAnchor=Anchor.SOUTH_WEST;
        }
 else         if (iAnchor == Anchor.WEST) {
          iAnchor=Anchor.EAST;
        }
 else         if (iAnchor == Anchor.NORTH_WEST) {
          iAnchor=Anchor.NORTH_EAST;
        }
 else         if (iAnchor == Anchor.SOUTH_WEST) {
          iAnchor=Anchor.SOUTH_EAST;
        }
      }
switch (iAnchor) {
case Anchor.NORTH:
case Anchor.NORTH_EAST:
case Anchor.NORTH_WEST:
        dY=bo.getTop();
      break;
case Anchor.SOUTH:
case Anchor.SOUTH_EAST:
case Anchor.SOUTH_WEST:
    dY=bo.getTop() + bo.getHeight() - sz.getHeight();
  break;
default :
dY=bo.getTop() + (bo.getHeight() - sz.getHeight()) / 2;
break;
}
switch (iAnchor) {
case Anchor.WEST:
case Anchor.NORTH_WEST:
case Anchor.SOUTH_WEST:
dX=bo.getLeft();
break;
case Anchor.EAST:
case Anchor.SOUTH_EAST:
case Anchor.NORTH_EAST:
dX=bo.getLeft() + bo.getWidth() - sz.getWidth();
break;
default :
dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
break;
}
}
 else {
dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
dY=bo.getTop() + (bo.getHeight() - sz.getHeight()) / 2;
}
}
 else {
dX=bo.getLeft();
dY=bo.getTop();
sz=SizeImpl.create(bo.getWidth(),bo.getHeight());
}
final LegendLayoutHints lilh=rtc.getLegendLayoutHints();
if (lilh == null) {
throw new ChartException(ChartEnginePlugin.ID,ChartException.RENDERING,"String_Node_Str",Messages.getResourceBundle(rtc.getULocale()));
}
Label lgTitle=lg.getTitle();
double lgTitleWidth=0, lgTitleHeight=0;
double yOffset=0, xOffset=0, wOffset=0, hOffset=0;
final boolean bRenderLegendTitle=lgTitle != null && lgTitle.isSetVisible() && lgTitle.isVisible() && !lilh.getLaTitle().getCaption().getValue().equals("String_Node_Str");
int iTitlePos=Position.ABOVE;
if (bRenderLegendTitle) {
lgTitle=lilh.getLaTitle();
Size titleSize=lilh.getTitleSize();
lgTitleWidth=titleSize.getWidth();
lgTitleHeight=titleSize.getHeight();
iTitlePos=lg.getTitlePosition().getValue();
if (isRightToLeft()) {
if (iTitlePos == Position.LEFT) {
iTitlePos=Position.RIGHT;
}
 else if (iTitlePos == Position.RIGHT) {
iTitlePos=Position.LEFT;
}
}
switch (iTitlePos) {
case Position.ABOVE:
yOffset=lgTitleHeight;
hOffset=-yOffset;
break;
case Position.BELOW:
hOffset=-lgTitleHeight;
break;
case Position.LEFT:
xOffset=lgTitleWidth;
wOffset=-xOffset;
break;
case Position.RIGHT:
wOffset=-lgTitleWidth;
break;
}
}
final ClientArea ca=lg.getClientArea();
final Insets lgIns=goFactory.scaleInsets(lg.getInsets(),dScale);
LineAttributes lia=ca.getOutline();
bo=goFactory.createBounds(dX,dY,sz.getWidth(),sz.getHeight());
bo=goFactory.adjusteBounds(bo,lgIns);
dX=bo.getLeft();
dY=bo.getTop();
bo.delta(xOffset,yOffset,wOffset,hOffset);
dX=bo.getLeft();
dY=bo.getTop();
final double dBaseX=dX;
final double dBaseY=dY;
final RectangleRenderEvent rre=((EventObjectCache)ir).getEventObject(StructureSource.createLegend(lg),RectangleRenderEvent.class);
if (ca.getShadowColor() != null) {
rre.setBounds(goFactory.translateBounds(bo,3,3));
rre.setBackground(ca.getShadowColor());
ipr.fillRectangle(rre);
}
rre.setBounds(bo);
rre.setOutline(lia);
rre.setBackground(ca.getBackground());
ipr.fillRectangle(rre);
ipr.drawRectangle(rre);
lia=goFactory.copyOf(lia);
lia.setVisible(true);
final boolean bPaletteByCategory=(cm.getLegend().getItemType().getValue() == LegendItemType.CATEGORIES);
if (bPaletteByCategory) {
if (cm instanceof ChartWithAxes) {
final Axis axPrimaryBase=((ChartWithAxes)cm).getBaseAxes()[0];
if (axPrimaryBase.getSeriesDefinitions().isEmpty()) {
return;
}
}
 else if (cm instanceof ChartWithoutAxes) {
if (((ChartWithoutAxes)cm).getSeriesDefinitions().isEmpty()) {
return;
}
}
}
renderAllLegendItems(ipr,lg,lilh,htRenderers,bo,dBaseX,dBaseY);
if (bRenderLegendTitle) {
double lX=bo.getLeft();
double lY=bo.getTop();
switch (iTitlePos) {
case Position.ABOVE:
lX=bo.getLeft() + (bo.getWidth() - lgTitleWidth) / 2d;
lY=bo.getTop() - lgTitleHeight;
break;
case Position.BELOW:
lX=bo.getLeft() + (bo.getWidth() - lgTitleWidth) / 2d;
lY=bo.getTop() + bo.getHeight();
break;
case Position.LEFT:
lX=bo.getLeft() - lgTitleWidth;
lY=bo.getTop() + (bo.getHeight() - lgTitleHeight) / 2d;
break;
case Position.RIGHT:
lX=bo.getLeft() + bo.getWidth();
lY=bo.getTop() + (bo.getHeight() - lgTitleHeight) / 2d;
break;
}
final TextRenderEvent tre=((EventObjectCache)ir).getEventObject(WrappedStructureSource.createLegendTitle(lg,lgTitle),TextRenderEvent.class);
tre.setBlockBounds(goFactory.createBounds(lX,lY,lgTitleWidth,lgTitleHeight));
TextAlignment ta=TextAlignmentImpl.create();
ta.setHorizontalAlignment(HorizontalAlignment.CENTER_LITERAL);
ta.setVerticalAlignment(VerticalAlignment.CENTER_LITERAL);
tre.setBlockAlignment(ta);
tre.setLabel(lgTitle);
tre.setAction(TextRenderEvent.RENDER_TEXT_IN_BLOCK);
if (rtc.isRightToLeftText()) {
tre.setRtlCaption();
}
ipr.drawText(tre);
}
}

Fixed version (ground truth):
/** 
 * Renders the legend block based on the legend rendering rules.
 * @param ipr
 * @param lg
 * @param htRenderers
 * @throws ChartException
 */
public void renderLegend(IPrimitiveRenderer ipr,Legend lg,Map<Series,LegendItemRenderingHints> htRenderers) throws ChartException {
  if (!lg.isVisible()) {
    return;
  }
  renderBlock(ipr,lg,StructureSource.createLegend(lg));
  final IDisplayServer xs=getDevice().getDisplayServer();
  final double dScale=getDeviceScale();
  Bounds bo=goFactory.scaleBounds(lg.getBounds(),dScale);
  Size sz=null;
  double dX, dY;
  if (lg.getPosition() != Position.INSIDE_LITERAL) {
    try {
      sz=lg.getPreferredSize(xs,cm,rtc);
    }
 catch (    Exception ex) {
      throw new ChartException(ChartEnginePlugin.ID,ChartException.RENDERING,ex);
    }
    sz.scale(dScale);
    dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
    dY=0;
    if (lg.isSetAnchor()) {
      int iAnchor=lg.getAnchor().getValue();
      if (isRightToLeft()) {
        if (iAnchor == Anchor.EAST) {
          iAnchor=Anchor.WEST;
        }
 else         if (iAnchor == Anchor.NORTH_EAST) {
          iAnchor=Anchor.NORTH_WEST;
        }
 else         if (iAnchor == Anchor.SOUTH_EAST) {
          iAnchor=Anchor.SOUTH_WEST;
        }
 else         if (iAnchor == Anchor.WEST) {
          iAnchor=Anchor.EAST;
        }
 else         if (iAnchor == Anchor.NORTH_WEST) {
          iAnchor=Anchor.NORTH_EAST;
        }
 else         if (iAnchor == Anchor.SOUTH_WEST) {
          iAnchor=Anchor.SOUTH_EAST;
        }
      }
switch (iAnchor) {
case Anchor.NORTH:
case Anchor.NORTH_EAST:
case Anchor.NORTH_WEST:
        dY=bo.getTop();
      break;
case Anchor.SOUTH:
case Anchor.SOUTH_EAST:
case Anchor.SOUTH_WEST:
    dY=bo.getTop() + bo.getHeight() - sz.getHeight();
  break;
default :
dY=bo.getTop() + (bo.getHeight() - sz.getHeight()) / 2;
break;
}
switch (iAnchor) {
case Anchor.WEST:
case Anchor.NORTH_WEST:
case Anchor.SOUTH_WEST:
dX=bo.getLeft();
break;
case Anchor.EAST:
case Anchor.SOUTH_EAST:
case Anchor.NORTH_EAST:
dX=bo.getLeft() + bo.getWidth() - sz.getWidth();
break;
default :
dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
break;
}
}
 else {
dX=bo.getLeft() + (bo.getWidth() - sz.getWidth()) / 2;
dY=bo.getTop() + (bo.getHeight() - sz.getHeight()) / 2;
}
}
 else {
dX=bo.getLeft();
dY=bo.getTop();
sz=SizeImpl.create(bo.getWidth(),bo.getHeight());
}
final LegendLayoutHints lilh=rtc.getLegendLayoutHints();
if (lilh == null) {
throw new ChartException(ChartEnginePlugin.ID,ChartException.RENDERING,"String_Node_Str",Messages.getResourceBundle(rtc.getULocale()));
}
Label lgTitle=lg.getTitle();
double lgTitleWidth=0, lgTitleHeight=0;
double yOffset=0, xOffset=0, wOffset=0, hOffset=0;
final boolean bRenderLegendTitle=lgTitle != null && lgTitle.isVisible() && !lilh.getLaTitle().getCaption().getValue().equals("String_Node_Str");
int iTitlePos=Position.ABOVE;
if (bRenderLegendTitle) {
lgTitle=lilh.getLaTitle();
Size titleSize=lilh.getTitleSize();
lgTitleWidth=titleSize.getWidth();
lgTitleHeight=titleSize.getHeight();
iTitlePos=lg.getTitlePosition().getValue();
if (isRightToLeft()) {
if (iTitlePos == Position.LEFT) {
iTitlePos=Position.RIGHT;
}
 else if (iTitlePos == Position.RIGHT) {
iTitlePos=Position.LEFT;
}
}
switch (iTitlePos) {
case Position.ABOVE:
yOffset=lgTitleHeight;
hOffset=-yOffset;
break;
case Position.BELOW:
hOffset=-lgTitleHeight;
break;
case Position.LEFT:
xOffset=lgTitleWidth;
wOffset=-xOffset;
break;
case Position.RIGHT:
wOffset=-lgTitleWidth;
break;
}
}
final ClientArea ca=lg.getClientArea();
final Insets lgIns=goFactory.scaleInsets(lg.getInsets(),dScale);
LineAttributes lia=ca.getOutline();
bo=goFactory.createBounds(dX,dY,sz.getWidth(),sz.getHeight());
bo=goFactory.adjusteBounds(bo,lgIns);
dX=bo.getLeft();
dY=bo.getTop();
bo.delta(xOffset,yOffset,wOffset,hOffset);
dX=bo.getLeft();
dY=bo.getTop();
final double dBaseX=dX;
final double dBaseY=dY;
final RectangleRenderEvent rre=((EventObjectCache)ir).getEventObject(StructureSource.createLegend(lg),RectangleRenderEvent.class);
if (ca.getShadowColor() != null) {
rre.setBounds(goFactory.translateBounds(bo,3,3));
rre.setBackground(ca.getShadowColor());
ipr.fillRectangle(rre);
}
rre.setBounds(bo);
rre.setOutline(lia);
rre.setBackground(ca.getBackground());
ipr.fillRectangle(rre);
ipr.drawRectangle(rre);
lia=goFactory.copyOf(lia);
lia.setVisible(true);
final boolean bPaletteByCategory=(cm.getLegend().getItemType().getValue() == LegendItemType.CATEGORIES);
if (bPaletteByCategory) {
if (cm instanceof ChartWithAxes) {
final Axis axPrimaryBase=((ChartWithAxes)cm).getBaseAxes()[0];
if (axPrimaryBase.getSeriesDefinitions().isEmpty()) {
return;
}
}
 else if (cm instanceof ChartWithoutAxes) {
if (((ChartWithoutAxes)cm).getSeriesDefinitions().isEmpty()) {
return;
}
}
}
renderAllLegendItems(ipr,lg,lilh,htRenderers,bo,dBaseX,dBaseY);
if (bRenderLegendTitle) {
double lX=bo.getLeft();
double lY=bo.getTop();
switch (iTitlePos) {
case Position.ABOVE:
lX=bo.getLeft() + (bo.getWidth() - lgTitleWidth) / 2d;
lY=bo.getTop() - lgTitleHeight;
break;
case Position.BELOW:
lX=bo.getLeft() + (bo.getWidth() - lgTitleWidth) / 2d;
lY=bo.getTop() + bo.getHeight();
break;
case Position.LEFT:
lX=bo.getLeft() - lgTitleWidth;
lY=bo.getTop() + (bo.getHeight() - lgTitleHeight) / 2d;
break;
case Position.RIGHT:
lX=bo.getLeft() + bo.getWidth();
lY=bo.getTop() + (bo.getHeight() - lgTitleHeight) / 2d;
break;
}
final TextRenderEvent tre=((EventObjectCache)ir).getEventObject(WrappedStructureSource.createLegendTitle(lg,lgTitle),TextRenderEvent.class);
tre.setBlockBounds(goFactory.createBounds(lX,lY,lgTitleWidth,lgTitleHeight));
TextAlignment ta=TextAlignmentImpl.create();
ta.setHorizontalAlignment(HorizontalAlignment.CENTER_LITERAL);
ta.setVerticalAlignment(VerticalAlignment.CENTER_LITERAL);
tre.setBlockAlignment(ta);
tre.setLabel(lgTitle);
tre.setAction(TextRenderEvent.RENDER_TEXT_IN_BLOCK);
if (rtc.isRightToLeftText()) {
tre.setRtlCaption();
}
ipr.drawText(tre);
}
}