Program: 11438
Project: 11438
Buggy source:
@Override public void paint(final GL2 gl,final EventPlotInfo info,final GlimpseBounds bounds,final Axis1D timeAxis,final Collection<EventDrawInfo> events){
  final StackedTimePlot2D plot=info.getStackedTimePlot();
  final int height=bounds.getHeight();
  final int width=bounds.getWidth();
  final Orientation orient=plot.getOrientation();
  final int size=orient == Orientation.HORIZONTAL ? height : width;
  final int buffer=info.getEventPadding();
  List<IconDrawInfo> iconDrawList=Lists.newArrayList();
  List<TextDrawInfo> textDrawList=Lists.newArrayList();
  FloatBuffer fillBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 2);
  FloatBuffer borderBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 2);
  FloatBuffer fillColorBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 4);
  FloatBuffer borderColorBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 4);
  IntBuffer fillCounts=Buffers.newDirectIntBuffer(events.size());
  IntBuffer borderCounts=Buffers.newDirectIntBuffer(events.size());
  IntBuffer fillIndices=Buffers.newDirectIntBuffer(events.size());
  IntBuffer borderIndices=Buffers.newDirectIntBuffer(events.size());
  int fillIndex=0;
  int borderIndex=0;
  int fillCount=0;
  int borderCount=0;
  Object defaultIconId=info.getDefaultIconId();
  TextureAtlas atlas=info.getTextureAtlas();
  TextRenderer textRenderer=info.getTextRenderer();
  boolean horiz=plot.isTimeAxisHorizontal();
  for (  EventDrawInfo eventInfo : events) {
    int posMax=eventInfo.posMax;
    int posMin=eventInfo.posMin;
    Event event=eventInfo.event;
    Event nextEvent=eventInfo.nextEvent;
    int sizePerpPixels=posMax - posMin;
    double sizePerpCenter=posMin + sizePerpPixels / 2.0;
    int arrowSize=Math.min(sizePerpPixels,ARROW_SIZE);
    Epoch epoch=plot.getEpoch();
    double timeMin=epoch.fromTimeStamp(event.getStartTime());
    double timeMax=epoch.fromTimeStamp(event.getEndTime());
    double arrowBaseMin=timeMin;
    boolean offEdgeMin=false;
    if (timeAxis.getMin() > timeMin) {
      offEdgeMin=true;
      timeMin=timeAxis.getMin() + ARROW_TIP_BUFFER / timeAxis.getPixelsPerValue();
      arrowBaseMin=timeMin + arrowSize / timeAxis.getPixelsPerValue();
    }
    double arrowBaseMax=timeMax;
    boolean offEdgeMax=false;
    if (timeAxis.getMax() < timeMax) {
      offEdgeMax=true;
      timeMax=timeAxis.getMax() - ARROW_TIP_BUFFER / timeAxis.getPixelsPerValue();
      arrowBaseMax=timeMax - arrowSize / timeAxis.getPixelsPerValue();
    }
    arrowBaseMax=Math.max(timeMin,arrowBaseMax);
    arrowBaseMin=Math.min(timeMax,arrowBaseMin);
    double timeSpan=arrowBaseMax - arrowBaseMin;
    double remainingSpace=timeAxis.getPixelsPerValue() * timeSpan - buffer * 2;
    int pixel=buffer + (offEdgeMin ? arrowSize : 0) + Math.max(0,timeAxis.valueToScreenPixel(timeMin));
    double nextStartValue=nextEvent != null ? epoch.fromTimeStamp(nextEvent.getStartTime()) : timeAxis.getMax();
    int nextStartPixel=nextEvent != null ? timeAxis.valueToScreenPixel(nextStartValue) : size;
    EventSelectionHandler selectionHandler=info.getEventSelectionHandler();
    boolean highlightSelected=selectionHandler.isHighlightSelectedEvents();
    boolean isSelected=highlightSelected ? selectionHandler.isEventSelected(event) : false;
    EventBounds eventBounds=info.getEventBounds(event.getId());
    if (!offEdgeMin && !offEdgeMax) {
      if (event.isShowBackground()) {
        float[] color=getBackgroundColor(event,info,isSelected);
        fillIndex=addVerticesBox(fillCounts,fillIndices,fillIndex,fillBuffer,fillColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax);
        fillCount++;
      }
      if (event.isShowBorder()) {
        float[] color=getBorderColor(event,info,isSelected);
        borderIndex=addVerticesBox(borderCounts,borderIndices,borderIndex,borderBuffer,borderColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax);
        borderCount++;
      }
    }
 else {
      if (event.isShowBackground()) {
        float[] color=getBackgroundColor(event,info,isSelected);
        fillIndex=addVerticesArrow(fillCounts,fillIndices,fillIndex,fillBuffer,fillColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax,(float)arrowBaseMin,(float)arrowBaseMax,(float)sizePerpCenter);
        fillCount++;
      }
      if (event.isShowBorder()) {
        float[] color=getBorderColor(event,info,isSelected);
        borderIndex=addVerticesArrow(borderCounts,borderIndices,borderIndex,borderBuffer,borderColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax,(float)arrowBaseMin,(float)arrowBaseMax,(float)sizePerpCenter);
        borderCount++;
      }
    }
    int totalIconSizePerpPixels=getIconSizePerpPixels(event,info,sizePerpPixels);
    if (event.hasChildren()) {
      final int numChildren=event.getEventCount();
      final int numRows=maxIconRows;
      int iconSizePerpPixels=totalIconSizePerpPixels / numRows;
      int columnsByAvailableSpace=(int)Math.floor(remainingSpace / (double)iconSizePerpPixels);
      int columnsByNumberOfIcons=(int)Math.ceil(numChildren / (double)numRows);
      int numColumns=(int)Math.min(columnsByAvailableSpace,columnsByNumberOfIcons);
      double iconSizePerpValue=iconSizePerpPixels / timeAxis.getPixelsPerValue();
      int totalIconWidthPixels=iconSizePerpPixels * numColumns;
      eventBounds.setIconVisible(event.isShowIcon() && !isIconOverlapping(totalIconWidthPixels,0,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode()));
      if (eventBounds.isIconVisible()) {
        double value=timeAxis.screenPixelToValue(pixel);
        eventBounds.setIconStartTime(epoch.toTimeStamp(value));
        eventBounds.setIconEndTime(eventBounds.getIconStartTime().add(totalIconWidthPixels / timeAxis.getPixelsPerValue()));
        Iterator<Event> iter=event.iterator();
        outer:         for (int c=0; c < numColumns; c++) {
          for (int r=numRows - 1; r >= 0; r--) {
            if (iter.hasNext()) {
              Event child=iter.next();
              Object icon=child.getIconId();
              if (icon == null || !atlas.isImageLoaded(icon)) {
                GlimpseColor.glColor(gl,getBackgroundColor(child,info,isSelected),0.5f);
                icon=defaultIconId;
              }
 else {
                GlimpseColor.glColor(gl,GlimpseColor.getWhite());
              }
              if (atlas.isImageLoaded(icon)) {
                ImageData iconData=atlas.getImageData(icon);
                int iconSizePerp=horiz ? iconData.getHeight() : iconData.getWidth();
                double iconScale=iconSizePerpPixels / (double)iconSizePerp;
                double x=value + c * iconSizePerpValue;
                double startY=sizePerpCenter - totalIconSizePerpPixels / 2.0;
                double y=startY + r * iconSizePerpPixels;
                if (horiz) {
                  iconDrawList.add(new IconDrawInfo(icon,x,y,iconScale,iconScale,0,iconSizePerp,true));
                }
 else {
                  iconDrawList.add(new IconDrawInfo(icon,x,y,iconScale,iconScale,0,iconSizePerp,false));
                }
              }
            }
 else {
              break outer;
            }
          }
        }
        remainingSpace-=totalIconWidthPixels + buffer;
        pixel+=totalIconWidthPixels + buffer;
      }
    }
 else {
      boolean isOverlapping=isIconOverlapping(totalIconSizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode());
      eventBounds.setIconVisible(event.isShowIcon() && event.getIconId() != null && !isOverlapping);
      if (eventBounds.isIconVisible()) {
        Object icon=event.getIconId();
        if (icon == null || !atlas.isImageLoaded(icon)) {
          icon=defaultIconId;
        }
        if (atlas.isImageLoaded(icon)) {
          ImageData iconData=atlas.getImageData(icon);
          int iconSizePerp=horiz ? iconData.getHeight() : iconData.getWidth();
          int iconSizeTime=horiz ? iconData.getWidth() : iconData.getHeight();
          int iconSizePerpPixels=getIconSizePerpPixels(event,info,sizePerpPixels);
          double iconScale=iconSizePerpPixels / (double)iconSizePerp;
          double posTime=timeAxis.screenPixelToValue(pixel);
          eventBounds.setIconStartTime(epoch.toTimeStamp(posTime));
          double iconSizeTimeAxis=iconSizeTime / timeAxis.getPixelsPerValue();
          eventBounds.setIconEndTime(eventBounds.getIconStartTime().add(iconSizeTimeAxis));
          int iconSizeTimeScaledPixels=(int)(iconSizeTime * iconScale);
          double posPerp=sizePerpCenter - iconSizePerpPixels / 2.0;
          if (horiz) {
            iconDrawList.add(new IconDrawInfo(icon,posTime,posPerp,iconScale,iconScale,0,iconSizePerp,true));
          }
 else {
            iconDrawList.add(new IconDrawInfo(icon,posPerp,posTime,iconScale,iconScale,0,iconSizePerp,false));
          }
          remainingSpace-=iconSizeTimeScaledPixels + buffer;
          pixel+=iconSizeTimeScaledPixels + buffer;
        }
      }
    }
    if (event.isShowLabel() && event.getLabel() != null) {
      Rectangle2D labelBounds=textRenderer.getBounds(event.getLabel());
      boolean isTextOverfull=isTextOverfull(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,labelBounds,event.getOverlapRenderingMode());
      boolean isTextIntersecting=isTextIntersecting(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,labelBounds,event.getOverlapRenderingMode());
      boolean isTextOverlappingAndHidden=((isTextOverfull || isTextIntersecting) && event.getTextRenderingMode() == TextRenderingMode.HideAll);
      double availableSpace=getTextAvailableSpace(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode());
      eventBounds.setTextVisible(!isTextOverlappingAndHidden);
      if (eventBounds.isTextVisible()) {
        Rectangle2D displayBounds=labelBounds;
        String displayText=event.getLabel();
        if (labelBounds.getWidth() > availableSpace && event.getTextRenderingMode() != TextRenderingMode.ShowAll) {
          displayText=calculateDisplayText(textRenderer,displayText,availableSpace);
          displayBounds=textRenderer.getBounds(displayText);
        }
        double value=timeAxis.screenPixelToValue(pixel);
        eventBounds.setTextStartTime(epoch.toTimeStamp(value));
        eventBounds.setTextEndTime(eventBounds.getTextStartTime().add(displayBounds.getWidth() / timeAxis.getPixelsPerValue()));
        float[] color;
        if (event.getLabelColor() != null) {
          color=event.getLabelColor();
        }
 else         if (!info.isTextColorSet() && !event.isShowBackground()) {
          color=info.getTextColorNoBackground();
        }
 else {
          color=info.getTextColor();
        }
        if (horiz) {
          int pixelY=(int)(sizePerpPixels / 2.0 - labelBounds.getHeight() * 0.3 + posMin);
          textDrawList.add(new TextDrawInfo(displayText,color,pixel,pixelY,0,0));
          remainingSpace-=displayBounds.getWidth() + buffer;
          pixel+=displayBounds.getWidth() + buffer;
        }
 else {
          double shiftX=sizePerpPixels / 2.0 + posMin;
          int pixelX=(int)shiftX;
          double shiftY=pixel;
          int pixelY=(int)(pixel - labelBounds.getHeight() * 0.34);
          textDrawList.add(new TextDrawInfo(displayText,color,pixelX,pixelY,shiftX,shiftY));
          remainingSpace-=displayBounds.getWidth() + buffer;
          pixel+=displayBounds.getWidth() + buffer;
        }
      }
    }
  }
  if (fillCount > 0) {
    gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    fillBuffer.flip();
    fillColorBuffer.flip();
    fillIndices.flip();
    fillCounts.flip();
    gl.glVertexPointer(2,GL.GL_FLOAT,0,fillBuffer);
    gl.glColorPointer(4,GL.GL_FLOAT,0,fillColorBuffer);
    gl.glMultiDrawArrays(GL2.GL_LINE_LOOP,fillIndices,fillCounts,fillCount);
    gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
  }
  if (borderCount > 0) {
    gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    borderBuffer.flip();
    borderColorBuffer.flip();
    borderIndices.flip();
    borderCounts.flip();
    gl.glVertexPointer(2,GL.GL_FLOAT,0,borderBuffer);
    gl.glColorPointer(4,GL.GL_FLOAT,0,borderColorBuffer);
    gl.glMultiDrawArrays(GL2.GL_POLYGON,borderIndices,borderCounts,borderCount);
    gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
  }
  if (!iconDrawList.isEmpty()) {
    atlas.beginRendering();
    try {
      for (      IconDrawInfo iconInfo : iconDrawList) {
        if (iconInfo.isX()) {
          atlas.drawImageAxisX(gl,iconInfo.id,timeAxis,iconInfo.positionX,iconInfo.positionY,iconInfo.scaleX,iconInfo.scaleY,iconInfo.centerX,iconInfo.centerY);
        }
 else {
          atlas.drawImageAxisY(gl,iconInfo.id,timeAxis,iconInfo.positionX,iconInfo.positionY,iconInfo.scaleX,iconInfo.scaleY,iconInfo.centerX,iconInfo.centerY);
        }
      }
    }
  finally {
      atlas.endRendering();
    }
  }
  if (!textDrawList.isEmpty()) {
    textRenderer.beginRendering(width,height);
    try {
      for (      TextDrawInfo textInfo : textDrawList) {
        if (!horiz) {
          gl.glMatrixMode(GL2.GL_PROJECTION);
          gl.glTranslated(textInfo.getShiftX(),textInfo.getShiftY(),0);
          gl.glRotated(90,0,0,1.0f);
          gl.glTranslated(-textInfo.getShiftX(),-textInfo.getShiftY(),0);
        }
        GlimpseColor.setColor(textRenderer,textInfo.getColor());
        textRenderer.draw(textInfo.getText(),textInfo.getX(),textInfo.getY());
      }
    }
  finally {
      textRenderer.endRendering();
    }
  }
}

Fixed version (ground truth):
@Override public void paint(final GL2 gl,final EventPlotInfo info,final GlimpseBounds bounds,final Axis1D timeAxis,final Collection<EventDrawInfo> events){
  final StackedTimePlot2D plot=info.getStackedTimePlot();
  final int height=bounds.getHeight();
  final int width=bounds.getWidth();
  final Orientation orient=plot.getOrientation();
  final int size=orient == Orientation.HORIZONTAL ? height : width;
  final int buffer=info.getEventPadding();
  List<IconDrawInfo> iconDrawList=Lists.newArrayList();
  List<TextDrawInfo> textDrawList=Lists.newArrayList();
  FloatBuffer fillBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 2);
  FloatBuffer borderBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 2);
  FloatBuffer fillColorBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 4);
  FloatBuffer borderColorBuffer=Buffers.newDirectFloatBuffer(events.size() * 6 * 4);
  IntBuffer fillCounts=Buffers.newDirectIntBuffer(events.size());
  IntBuffer borderCounts=Buffers.newDirectIntBuffer(events.size());
  IntBuffer fillIndices=Buffers.newDirectIntBuffer(events.size());
  IntBuffer borderIndices=Buffers.newDirectIntBuffer(events.size());
  int fillIndex=0;
  int borderIndex=0;
  int fillCount=0;
  int borderCount=0;
  Object defaultIconId=info.getDefaultIconId();
  TextureAtlas atlas=info.getTextureAtlas();
  TextRenderer textRenderer=info.getTextRenderer();
  boolean horiz=plot.isTimeAxisHorizontal();
  for (  EventDrawInfo eventInfo : events) {
    int posMax=eventInfo.posMax;
    int posMin=eventInfo.posMin;
    Event event=eventInfo.event;
    Event nextEvent=eventInfo.nextEvent;
    int sizePerpPixels=posMax - posMin;
    double sizePerpCenter=posMin + sizePerpPixels / 2.0;
    int arrowSize=Math.min(sizePerpPixels,ARROW_SIZE);
    Epoch epoch=plot.getEpoch();
    double timeMin=epoch.fromTimeStamp(event.getStartTime());
    double timeMax=epoch.fromTimeStamp(event.getEndTime());
    double arrowBaseMin=timeMin;
    boolean offEdgeMin=false;
    if (timeAxis.getMin() > timeMin) {
      offEdgeMin=true;
      timeMin=timeAxis.getMin() + ARROW_TIP_BUFFER / timeAxis.getPixelsPerValue();
      arrowBaseMin=timeMin + arrowSize / timeAxis.getPixelsPerValue();
    }
    double arrowBaseMax=timeMax;
    boolean offEdgeMax=false;
    if (timeAxis.getMax() < timeMax) {
      offEdgeMax=true;
      timeMax=timeAxis.getMax() - ARROW_TIP_BUFFER / timeAxis.getPixelsPerValue();
      arrowBaseMax=timeMax - arrowSize / timeAxis.getPixelsPerValue();
    }
    arrowBaseMax=Math.max(timeMin,arrowBaseMax);
    arrowBaseMin=Math.min(timeMax,arrowBaseMin);
    double timeSpan=arrowBaseMax - arrowBaseMin;
    double remainingSpace=timeAxis.getPixelsPerValue() * timeSpan - buffer * 2;
    int pixel=buffer + (offEdgeMin ? arrowSize : 0) + Math.max(0,timeAxis.valueToScreenPixel(timeMin));
    double nextStartValue=nextEvent != null ? epoch.fromTimeStamp(nextEvent.getStartTime()) : timeAxis.getMax();
    int nextStartPixel=nextEvent != null ? timeAxis.valueToScreenPixel(nextStartValue) : size;
    EventSelectionHandler selectionHandler=info.getEventSelectionHandler();
    boolean highlightSelected=selectionHandler.isHighlightSelectedEvents();
    boolean isSelected=highlightSelected ? selectionHandler.isEventSelected(event) : false;
    EventBounds eventBounds=info.getEventBounds(event.getId());
    if (!offEdgeMin && !offEdgeMax) {
      if (event.isShowBackground()) {
        float[] color=getBackgroundColor(event,info,isSelected);
        fillIndex=addVerticesBox(fillCounts,fillIndices,fillIndex,fillBuffer,fillColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax);
        fillCount++;
      }
      if (event.isShowBorder()) {
        float[] color=getBorderColor(event,info,isSelected);
        borderIndex=addVerticesBox(borderCounts,borderIndices,borderIndex,borderBuffer,borderColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax);
        borderCount++;
      }
    }
 else {
      if (event.isShowBackground()) {
        float[] color=getBackgroundColor(event,info,isSelected);
        fillIndex=addVerticesArrow(fillCounts,fillIndices,fillIndex,fillBuffer,fillColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax,(float)arrowBaseMin,(float)arrowBaseMax,(float)sizePerpCenter);
        fillCount++;
      }
      if (event.isShowBorder()) {
        float[] color=getBorderColor(event,info,isSelected);
        borderIndex=addVerticesArrow(borderCounts,borderIndices,borderIndex,borderBuffer,borderColorBuffer,horiz,color,(float)timeMin,(float)timeMax,(float)posMin,(float)posMax,(float)arrowBaseMin,(float)arrowBaseMax,(float)sizePerpCenter);
        borderCount++;
      }
    }
    int totalIconSizePerpPixels=getIconSizePerpPixels(event,info,sizePerpPixels);
    if (event.hasChildren()) {
      final int numChildren=event.getEventCount();
      final int numRows=maxIconRows;
      int iconSizePerpPixels=totalIconSizePerpPixels / numRows;
      int columnsByAvailableSpace=(int)Math.floor(remainingSpace / (double)iconSizePerpPixels);
      int columnsByNumberOfIcons=(int)Math.ceil(numChildren / (double)numRows);
      int numColumns=(int)Math.min(columnsByAvailableSpace,columnsByNumberOfIcons);
      double iconSizePerpValue=iconSizePerpPixels / timeAxis.getPixelsPerValue();
      int totalIconWidthPixels=iconSizePerpPixels * numColumns;
      eventBounds.setIconVisible(event.isShowIcon() && !isIconOverlapping(totalIconWidthPixels,0,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode()));
      if (eventBounds.isIconVisible()) {
        double value=timeAxis.screenPixelToValue(pixel);
        eventBounds.setIconStartTime(epoch.toTimeStamp(value));
        eventBounds.setIconEndTime(eventBounds.getIconStartTime().add(totalIconWidthPixels / timeAxis.getPixelsPerValue()));
        Iterator<Event> iter=event.iterator();
        outer:         for (int c=0; c < numColumns; c++) {
          for (int r=numRows - 1; r >= 0; r--) {
            if (iter.hasNext()) {
              Event child=iter.next();
              Object icon=child.getIconId();
              if (icon == null || !atlas.isImageLoaded(icon)) {
                GlimpseColor.glColor(gl,getBackgroundColor(child,info,isSelected),0.5f);
                icon=defaultIconId;
              }
 else {
                GlimpseColor.glColor(gl,GlimpseColor.getWhite());
              }
              if (atlas.isImageLoaded(icon)) {
                ImageData iconData=atlas.getImageData(icon);
                int iconSizePerp=horiz ? iconData.getHeight() : iconData.getWidth();
                double iconScale=iconSizePerpPixels / (double)iconSizePerp;
                double x=value + c * iconSizePerpValue;
                double startY=sizePerpCenter - totalIconSizePerpPixels / 2.0;
                double y=startY + r * iconSizePerpPixels;
                if (horiz) {
                  iconDrawList.add(new IconDrawInfo(icon,x,y,iconScale,iconScale,0,iconSizePerp,true));
                }
 else {
                  iconDrawList.add(new IconDrawInfo(icon,x,y,iconScale,iconScale,0,iconSizePerp,false));
                }
              }
            }
 else {
              break outer;
            }
          }
        }
        remainingSpace-=totalIconWidthPixels + buffer;
        pixel+=totalIconWidthPixels + buffer;
      }
    }
 else {
      boolean isOverlapping=isIconOverlapping(totalIconSizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode());
      eventBounds.setIconVisible(event.isShowIcon() && event.getIconId() != null && !isOverlapping);
      if (eventBounds.isIconVisible()) {
        Object icon=event.getIconId();
        if (icon == null || !atlas.isImageLoaded(icon)) {
          icon=defaultIconId;
        }
        if (atlas.isImageLoaded(icon)) {
          ImageData iconData=atlas.getImageData(icon);
          int iconSizePerp=horiz ? iconData.getHeight() : iconData.getWidth();
          int iconSizeTime=horiz ? iconData.getWidth() : iconData.getHeight();
          int iconSizePerpPixels=getIconSizePerpPixels(event,info,sizePerpPixels);
          double iconScale=iconSizePerpPixels / (double)iconSizePerp;
          double posTime=timeAxis.screenPixelToValue(pixel);
          eventBounds.setIconStartTime(epoch.toTimeStamp(posTime));
          double iconSizeTimeAxis=iconSizeTime / timeAxis.getPixelsPerValue();
          eventBounds.setIconEndTime(eventBounds.getIconStartTime().add(iconSizeTimeAxis));
          int iconSizeTimeScaledPixels=(int)(iconSizeTime * iconScale);
          double posPerp=sizePerpCenter - iconSizePerpPixels / 2.0;
          if (horiz) {
            iconDrawList.add(new IconDrawInfo(icon,posTime,posPerp,iconScale,iconScale,0,iconSizePerp,true));
          }
 else {
            iconDrawList.add(new IconDrawInfo(icon,posPerp,posTime,iconScale,iconScale,0,iconSizePerp,false));
          }
          remainingSpace-=iconSizeTimeScaledPixels + buffer;
          pixel+=iconSizeTimeScaledPixels + buffer;
        }
      }
    }
    if (event.isShowLabel() && event.getLabel() != null) {
      Rectangle2D labelBounds=textRenderer.getBounds(event.getLabel());
      boolean isTextOverfull=isTextOverfull(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,labelBounds,event.getOverlapRenderingMode());
      boolean isTextIntersecting=isTextIntersecting(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,labelBounds,event.getOverlapRenderingMode());
      boolean isTextOverlappingAndHidden=((isTextOverfull || isTextIntersecting) && event.getTextRenderingMode() == TextRenderingMode.HideAll);
      double availableSpace=getTextAvailableSpace(sizePerpPixels,buffer,remainingSpace,pixel,nextStartPixel,event.getOverlapRenderingMode());
      eventBounds.setTextVisible(!isTextOverlappingAndHidden);
      if (eventBounds.isTextVisible()) {
        Rectangle2D displayBounds=labelBounds;
        String displayText=event.getLabel();
        if (labelBounds.getWidth() > availableSpace && event.getTextRenderingMode() != TextRenderingMode.ShowAll) {
          displayText=calculateDisplayText(textRenderer,displayText,availableSpace);
          displayBounds=textRenderer.getBounds(displayText);
        }
        double value=timeAxis.screenPixelToValue(pixel);
        eventBounds.setTextStartTime(epoch.toTimeStamp(value));
        eventBounds.setTextEndTime(eventBounds.getTextStartTime().add(displayBounds.getWidth() / timeAxis.getPixelsPerValue()));
        float[] color;
        if (event.getLabelColor() != null) {
          color=event.getLabelColor();
        }
 else         if (!info.isTextColorSet() && !event.isShowBackground()) {
          color=info.getTextColorNoBackground();
        }
 else {
          color=info.getTextColor();
        }
        if (horiz) {
          int pixelY=(int)(sizePerpPixels / 2.0 - labelBounds.getHeight() * 0.3 + posMin);
          textDrawList.add(new TextDrawInfo(displayText,color,pixel,pixelY,0,0));
          remainingSpace-=displayBounds.getWidth() + buffer;
          pixel+=displayBounds.getWidth() + buffer;
        }
 else {
          double shiftX=sizePerpPixels / 2.0 + posMin;
          int pixelX=(int)shiftX;
          double shiftY=pixel;
          int pixelY=(int)(pixel - labelBounds.getHeight() * 0.34);
          textDrawList.add(new TextDrawInfo(displayText,color,pixelX,pixelY,shiftX,shiftY));
          remainingSpace-=displayBounds.getWidth() + buffer;
          pixel+=displayBounds.getWidth() + buffer;
        }
      }
    }
  }
  if (fillCount > 0) {
    gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    fillBuffer.flip();
    fillColorBuffer.flip();
    fillIndices.flip();
    fillCounts.flip();
    gl.glVertexPointer(2,GL.GL_FLOAT,0,fillBuffer);
    gl.glColorPointer(4,GL.GL_FLOAT,0,fillColorBuffer);
    gl.glMultiDrawArrays(GL2.GL_POLYGON,fillIndices,fillCounts,fillCount);
    gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
  }
  if (borderCount > 0) {
    gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    borderBuffer.flip();
    borderColorBuffer.flip();
    borderIndices.flip();
    borderCounts.flip();
    gl.glVertexPointer(2,GL.GL_FLOAT,0,borderBuffer);
    gl.glColorPointer(4,GL.GL_FLOAT,0,borderColorBuffer);
    gl.glMultiDrawArrays(GL2.GL_LINE_LOOP,borderIndices,borderCounts,borderCount);
    gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
  }
  if (!iconDrawList.isEmpty()) {
    atlas.beginRendering();
    try {
      for (      IconDrawInfo iconInfo : iconDrawList) {
        if (iconInfo.isX()) {
          atlas.drawImageAxisX(gl,iconInfo.id,timeAxis,iconInfo.positionX,iconInfo.positionY,iconInfo.scaleX,iconInfo.scaleY,iconInfo.centerX,iconInfo.centerY);
        }
 else {
          atlas.drawImageAxisY(gl,iconInfo.id,timeAxis,iconInfo.positionX,iconInfo.positionY,iconInfo.scaleX,iconInfo.scaleY,iconInfo.centerX,iconInfo.centerY);
        }
      }
    }
  finally {
      atlas.endRendering();
    }
  }
  if (!textDrawList.isEmpty()) {
    textRenderer.beginRendering(width,height);
    try {
      for (      TextDrawInfo textInfo : textDrawList) {
        if (!horiz) {
          gl.glMatrixMode(GL2.GL_PROJECTION);
          gl.glTranslated(textInfo.getShiftX(),textInfo.getShiftY(),0);
          gl.glRotated(90,0,0,1.0f);
          gl.glTranslated(-textInfo.getShiftX(),-textInfo.getShiftY(),0);
        }
        GlimpseColor.setColor(textRenderer,textInfo.getColor());
        textRenderer.draw(textInfo.getText(),textInfo.getX(),textInfo.getY());
      }
    }
  finally {
      textRenderer.endRendering();
    }
  }
}