Program: 11369
Project: 11369
Buggy source:
@Override protected synchronized void doPaintTo(GlimpseContext context){
  GlimpseBounds bounds=getBounds(context);
  Axis2D axis=getAxis2D(context);
  GL3 gl=context.getGL().getGL3();
  int width=bounds.getWidth();
  int height=bounds.getHeight();
  if (axis == null && !drawInPixelCoords) {
    throw new AxisNotSetException(this,context);
  }
  double x=drawInPixelCoords ? this.x : axis.getAxisX().valueToScreenPixelUnits(this.x);
  double y=drawInPixelCoords ? bounds.getHeight() - this.y : axis.getAxisY().valueToScreenPixelUnits(this.y);
  if (icons == null) {
    loadIcons(context);
  }
  if (newFont != null) {
    updateTextRenderer();
  }
  if (text != null && textLayout == null && textRenderer != null) {
    updateTextLayout();
  }
  if (iconIds == null && lines == null)   return;
  GLUtils.enableStandardBlending(gl);
  try {
    double textHeight=0;
    if (lines != null) {
      textHeight=(textLayout.getLineHeight()) * lines.size() + lineSpacing * (lines.size() - 1);
    }
    float iconSize;
    if (iconIds == null || iconIds.isEmpty()) {
      iconSize=0;
    }
 else     if (iconSizeFixedToText && textHeight != 0) {
      iconSize=(float)textLayout.getLineHeight();
    }
 else {
      iconSize=this.iconSize;
    }
    double iconHeight=0;
    if (icons != null) {
      iconHeight=iconSize * icons.size() + iconSpacing * (icons.size() - 1);
    }
    int boundingHeight=(int)(borderSize * 2 + Math.max(iconHeight,textHeight));
    float textLength=0;
    if (lines != null) {
      for (int k=0; k < lines.size(); k++) {
        textLength=Math.max(textLength,lines.get(k).width);
      }
    }
    int boundingWidth=(int)(borderSize * 2 + iconSize + textLength);
    if (iconIds != null && !iconIds.isEmpty() && lines != null) {
      boundingWidth+=textIconSpacing;
    }
    int offsetX=this.offsetX + this.insets.left;
    int offsetY=this.offsetY - this.insets.top;
    double clampX=offsetX, clampY=offsetY;
    if (clampToScreenEdges) {
      if (x + boundingWidth + offsetX > bounds.getWidth())       clampX=bounds.getWidth() - boundingWidth - x;
      if (x + offsetX < 0)       clampX=-x;
      if (y + offsetY > bounds.getHeight())       clampY=bounds.getHeight() - y;
      if (boundingHeight > y + offsetY)       clampY=boundingHeight - y;
    }
    if (this.paintBackground || this.paintBorder) {
      if (paintBackground) {
        this.fillBuilder.clear();
        this.fillBuilder.addQuad2f(boundingHeight,boundingWidth,(float)(x + clampX),(float)(y + clampY));
        this.fillProg.begin(gl);
        try {
          this.fillProg.setPixelOrtho(gl,bounds);
          this.fillProg.draw(gl,this.fillBuilder,this.backgroundColor);
        }
  finally {
          this.fillProg.end(gl);
        }
      }
      if (paintBorder) {
        this.linePath.clear();
        this.linePath.addRectangle(boundingHeight,boundingWidth,(float)(x + clampX),(float)(y + clampY));
        this.lineProg.begin(gl);
        try {
          this.lineProg.setPixelOrtho(gl,bounds);
          this.lineProg.setViewport(gl,bounds);
          this.lineStyle.rgba=borderColor;
          this.lineProg.draw(gl,this.lineStyle,this.linePath);
        }
  finally {
          this.lineProg.end(gl);
        }
      }
    }
    gl.glDisable(GL2.GL_BLEND);
    if (lines != null && textRenderer != null) {
      GlimpseColor.setColor(textRenderer,textColor);
      textRenderer.beginRendering(width,height);
      try {
        double posX=x + iconSize + borderSize;
        if (iconIds != null && !iconIds.isEmpty()) {
          posX+=textIconSpacing;
        }
        double posY=y - borderSize - textLayout.getLineHeight();
        double iconPosY=Float.NEGATIVE_INFINITY;
        if (wrapTextAroundIcon && icons != null) {
          iconPosY=y - (iconSize * icons.size() + iconSpacing * (icons.size() - 1) + borderSize);
        }
        for (int i=0; i < lines.size(); i++) {
          if (posY + textLayout.getLineHeight() < iconPosY)           posX=x + borderSize;
          textRenderer.draw(lines.get(i).text,(int)(posX + clampX),(int)(posY + clampY));
          posY=posY - lineSpacing - (textLayout.getLineHeight());
        }
      }
  finally {
        textRenderer.endRendering();
      }
    }
    if (iconIds != null && !iconIds.isEmpty()) {
      atlas.beginRendering(context);
      try {
        double posY=y - borderSize - iconSize;
        for (int i=0; i < iconIds.size(); i++) {
          Object iconId=iconIds.get(i);
          ImageData iconData=icons.get(i);
          if (iconId != null && iconData != null) {
            double iconScale=iconSize / (double)iconData.getWidth();
            float[] color=defaultIconColor;
            if (iconColors != null && i < iconColors.size()) {
              float[] iconColor=iconColors.get(i);
              if (iconColor != null)               color=iconColor;
            }
            int scaleX=(int)(x + borderSize + clampX);
            int scaleY=(int)(posY + clampY);
            atlas.drawImage(gl,iconId,scaleX,scaleY,iconScale,iconScale,0,iconData.getHeight(),color);
            posY=posY - iconSize - iconSpacing;
          }
        }
      }
  finally {
        atlas.endRendering(context);
      }
    }
  }
  finally {
    GLUtils.disableBlending(gl);
  }
}

Fixed version (ground truth):
@Override protected synchronized void doPaintTo(GlimpseContext context){
  GlimpseBounds bounds=getBounds(context);
  Axis2D axis=getAxis2D(context);
  GL3 gl=context.getGL().getGL3();
  int width=bounds.getWidth();
  int height=bounds.getHeight();
  if (axis == null && !drawInPixelCoords) {
    throw new AxisNotSetException(this,context);
  }
  double x=drawInPixelCoords ? this.x : axis.getAxisX().valueToScreenPixelUnits(this.x);
  double y=drawInPixelCoords ? bounds.getHeight() - this.y : axis.getAxisY().valueToScreenPixelUnits(this.y);
  if (icons == null) {
    loadIcons(context);
  }
  if (newFont != null) {
    updateTextRenderer();
  }
  if (text != null && textLayout == null && textRenderer != null) {
    updateTextLayout();
  }
  if (iconIds == null && lines == null)   return;
  GLUtils.enableStandardBlending(gl);
  try {
    double textHeight=0;
    if (lines != null) {
      textHeight=(textLayout.getLineHeight()) * lines.size() + lineSpacing * (lines.size() - 1);
    }
    float iconSize;
    if (iconIds == null || iconIds.isEmpty()) {
      iconSize=0;
    }
 else     if (iconSizeFixedToText && textHeight != 0) {
      iconSize=(float)textLayout.getLineHeight();
    }
 else {
      iconSize=this.iconSize;
    }
    double iconHeight=0;
    if (icons != null) {
      iconHeight=iconSize * icons.size() + iconSpacing * (icons.size() - 1);
    }
    int boundingHeight=(int)(borderSize * 2 + Math.max(iconHeight,textHeight));
    float textLength=0;
    if (lines != null) {
      for (int k=0; k < lines.size(); k++) {
        textLength=Math.max(textLength,lines.get(k).width);
      }
    }
    int boundingWidth=(int)(borderSize * 2 + iconSize + textLength);
    if (iconIds != null && !iconIds.isEmpty() && lines != null) {
      boundingWidth+=textIconSpacing;
    }
    int offsetX=this.offsetX + this.insets.left;
    int offsetY=this.offsetY - this.insets.top;
    double clampX=offsetX, clampY=offsetY;
    if (clampToScreenEdges) {
      if (x + boundingWidth + offsetX > bounds.getWidth())       clampX=bounds.getWidth() - boundingWidth - x;
      if (x + offsetX < 0)       clampX=-x;
      if (y + offsetY > bounds.getHeight())       clampY=bounds.getHeight() - y;
      if (boundingHeight > y + offsetY)       clampY=boundingHeight - y;
    }
    if (this.paintBackground || this.paintBorder) {
      if (paintBackground) {
        this.fillBuilder.clear();
        this.fillBuilder.addQuad2f(boundingHeight,boundingWidth,(float)(x + clampX),(float)(y + clampY));
        this.fillProg.begin(gl);
        try {
          this.fillProg.setPixelOrtho(gl,bounds);
          this.fillProg.draw(gl,this.fillBuilder,this.backgroundColor);
        }
  finally {
          this.fillProg.end(gl);
        }
      }
      if (paintBorder) {
        this.linePath.clear();
        this.linePath.addRectangle(boundingHeight,boundingWidth,(float)(x + clampX),(float)(y + clampY));
        this.lineProg.begin(gl);
        try {
          this.lineProg.setPixelOrtho(gl,bounds);
          this.lineProg.setViewport(gl,bounds);
          this.lineStyle.rgba=borderColor;
          this.lineProg.draw(gl,this.lineStyle,this.linePath);
        }
  finally {
          this.lineProg.end(gl);
        }
      }
    }
    gl.glDisable(GL2.GL_BLEND);
    if (lines != null && textRenderer != null) {
      GlimpseColor.setColor(textRenderer,textColor);
      textRenderer.beginRendering(width,height);
      try {
        double posX=x + iconSize + borderSize;
        if (iconIds != null && !iconIds.isEmpty()) {
          posX+=textIconSpacing;
        }
        double posY=y - borderSize - textLayout.getLineHeight();
        double iconPosY=Float.NEGATIVE_INFINITY;
        if (wrapTextAroundIcon && icons != null) {
          iconPosY=y - (iconSize * icons.size() + iconSpacing * (icons.size() - 1) + borderSize);
        }
        for (int i=0; i < lines.size(); i++) {
          if (posY + textLayout.getLineHeight() < iconPosY)           posX=x + borderSize;
          textRenderer.draw(lines.get(i).text,(int)(posX + clampX),(int)(posY + clampY));
          posY=posY - lineSpacing - (textLayout.getLineHeight());
        }
      }
  finally {
        textRenderer.endRendering();
      }
    }
    if (iconIds != null && !iconIds.isEmpty()) {
      atlas.beginRendering(context);
      try {
        double posY=y - borderSize - iconSize;
        for (int i=0; i < iconIds.size(); i++) {
          Object iconId=iconIds.get(i);
          ImageData iconData=icons.get(i);
          if (iconId != null && iconData != null) {
            double iconScale=iconSize / (double)iconData.getWidth();
            float[] color=defaultIconColor;
            if (iconColors != null && i < iconColors.size()) {
              float[] iconColor=iconColors.get(i);
              if (iconColor != null)               color=iconColor;
            }
            int scaleX=(int)(x + borderSize + clampX);
            int scaleY=(int)(posY + clampY);
            atlas.drawImage(context,iconId,scaleX,scaleY,iconScale,iconScale,0,iconData.getHeight(),color);
            posY=posY - iconSize - iconSpacing;
          }
        }
      }
  finally {
        atlas.endRendering(context);
      }
    }
  }
  finally {
    GLUtils.disableBlending(gl);
  }
}