private ArrayList<Shape> getSelectedTextBounds() {
   Page currentPage = pageViewComponent.getPage();
   ArrayList<Shape> highlightBounds = null;
   if (currentPage != null && currentPage.isInitiated()) {
     try {
       PageText pageText = currentPage.getViewText();
       if (pageText != null) {
         // get page transformation
         AffineTransform pageTransform =
             currentPage.getPageTransform(
                 documentViewModel.getPageBoundary(),
                 documentViewModel.getViewRotation(),
                 documentViewModel.getViewZoom());
         // paint the sprites
         GeneralPath textPath;
         ArrayList<LineText> pageLines = pageText.getPageLines();
         if (pageLines != null) {
           for (LineText lineText : pageLines) {
             java.util.List<WordText> words = lineText.getWords();
             if (words != null) {
               for (WordText wordText : words) {
                 // paint whole word
                 if (wordText.isSelected() || wordText.isHighlighted()) {
                   textPath = new GeneralPath(wordText.getBounds());
                   textPath.transform(pageTransform);
                   // paint highlight over any selected
                   if (wordText.isSelected()) {
                     if (highlightBounds == null) {
                       highlightBounds = new ArrayList<Shape>();
                     }
                     highlightBounds.add(textPath.getBounds2D());
                   }
                 }
                 // check children
                 else {
                   for (GlyphText glyph : wordText.getGlyphs()) {
                     if (glyph.isSelected()) {
                       textPath = new GeneralPath(glyph.getBounds());
                       textPath.transform(pageTransform);
                       if (highlightBounds == null) {
                         highlightBounds = new ArrayList<Shape>();
                       }
                       highlightBounds.add(textPath.getBounds2D());
                     }
                   }
                 }
               }
             }
           }
         }
       }
     } catch (InterruptedException e) {
       Thread.currentThread().interrupt();
       logger.fine("HighLightAnnotation selected text bounds calculation interrupted.");
     }
   }
   return highlightBounds;
 }
  public void testSetPath() {
    XMLSlideShow ppt = new XMLSlideShow();
    XSLFSlide slide = ppt.createSlide();
    XSLFFreeformShape shape1 = slide.createFreeform();
    // comples path consisting of a rectangle and an ellipse inside it
    GeneralPath path1 = new GeneralPath(new Rectangle(150, 150, 300, 300));
    path1.append(new Ellipse2D.Double(200, 200, 100, 50), false);
    shape1.setPath(path1);

    GeneralPath path2 = shape1.getPath();

    // YK: how to compare the original path1 and the value returned by XSLFFreeformShape.getPath() ?
    // one way is to create another XSLFFreeformShape from path2 and compare the resulting xml
    assertEquals(path1.getBounds2D(), path2.getBounds2D());

    XSLFFreeformShape shape2 = slide.createFreeform();
    shape2.setPath(path2);

    assertEquals(
        shape1.getSpPr().getCustGeom().toString(), shape2.getSpPr().getCustGeom().toString());
  }
  private BufferedImage create_SMALL_POINTER_Image(final int WIDTH) {
    if (WIDTH <= 0) {
      return null;
    }

    final BufferedImage IMAGE = UTIL.createImage(WIDTH, WIDTH, Transparency.TRANSLUCENT);
    final Graphics2D G2 = IMAGE.createGraphics();
    G2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    G2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    // G2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
    // RenderingHints.VALUE_STROKE_NORMALIZE);

    final int IMAGE_WIDTH = IMAGE.getWidth();
    final int IMAGE_HEIGHT = IMAGE.getHeight();

    final GeneralPath STOPWATCHPOINTERSMALL = new GeneralPath();
    STOPWATCHPOINTERSMALL.setWindingRule(Path2D.WIND_EVEN_ODD);
    STOPWATCHPOINTERSMALL.moveTo(
        IMAGE_WIDTH * 0.4766355140186916, IMAGE_HEIGHT * 0.3130841121495327);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.4766355140186916,
        IMAGE_HEIGHT * 0.32242990654205606,
        IMAGE_WIDTH * 0.48598130841121495,
        IMAGE_HEIGHT * 0.3317757009345794,
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.3364485981308411);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.3364485981308411,
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.35046728971962615,
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.35046728971962615);
    STOPWATCHPOINTERSMALL.lineTo(
        IMAGE_WIDTH * 0.5046728971962616, IMAGE_HEIGHT * 0.35046728971962615);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.5046728971962616,
        IMAGE_HEIGHT * 0.35046728971962615,
        IMAGE_WIDTH * 0.5046728971962616,
        IMAGE_HEIGHT * 0.3364485981308411,
        IMAGE_WIDTH * 0.5046728971962616,
        IMAGE_HEIGHT * 0.3364485981308411);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.514018691588785,
        IMAGE_HEIGHT * 0.3317757009345794,
        IMAGE_WIDTH * 0.5233644859813084,
        IMAGE_HEIGHT * 0.32242990654205606,
        IMAGE_WIDTH * 0.5233644859813084,
        IMAGE_HEIGHT * 0.3130841121495327);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.5233644859813084,
        IMAGE_HEIGHT * 0.3037383177570093,
        IMAGE_WIDTH * 0.514018691588785,
        IMAGE_HEIGHT * 0.29439252336448596,
        IMAGE_WIDTH * 0.5046728971962616,
        IMAGE_HEIGHT * 0.2897196261682243);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.5046728971962616,
        IMAGE_HEIGHT * 0.2897196261682243,
        IMAGE_WIDTH * 0.5,
        IMAGE_HEIGHT * 0.20093457943925233,
        IMAGE_WIDTH * 0.5,
        IMAGE_HEIGHT * 0.20093457943925233);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.5,
        IMAGE_HEIGHT * 0.20093457943925233,
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.2897196261682243,
        IMAGE_WIDTH * 0.4953271028037383,
        IMAGE_HEIGHT * 0.2897196261682243);
    STOPWATCHPOINTERSMALL.curveTo(
        IMAGE_WIDTH * 0.48598130841121495,
        IMAGE_HEIGHT * 0.29439252336448596,
        IMAGE_WIDTH * 0.4766355140186916,
        IMAGE_HEIGHT * 0.3037383177570093,
        IMAGE_WIDTH * 0.4766355140186916,
        IMAGE_HEIGHT * 0.3130841121495327);
    STOPWATCHPOINTERSMALL.closePath();
    if (flatNeedle) {
      G2.setColor(getPointerColor().MEDIUM);
      G2.fill(STOPWATCHPOINTERSMALL);
    } else {
      final Point2D POINTER_START =
          new Point2D.Double(STOPWATCHPOINTERSMALL.getBounds2D().getMinX(), 0);
      final Point2D POINTER_STOP =
          new Point2D.Double(STOPWATCHPOINTERSMALL.getBounds2D().getMaxX(), 0);
      final float[] POINTER_FRACTIONS = {0.0f, 0.3888888889f, 0.5f, 0.6111111111f, 1.0f};
      final Color[] POINTER_COLORS = {
        getPointerColor().MEDIUM,
        getPointerColor().MEDIUM,
        getPointerColor().LIGHT,
        getPointerColor().MEDIUM,
        getPointerColor().MEDIUM
      };
      final LinearGradientPaint GRADIENT =
          new LinearGradientPaint(POINTER_START, POINTER_STOP, POINTER_FRACTIONS, POINTER_COLORS);
      G2.setPaint(GRADIENT);
      G2.fill(STOPWATCHPOINTERSMALL);
      G2.setPaint(getPointerColor().DARK);
      G2.draw(STOPWATCHPOINTERSMALL);
    }

    final Ellipse2D SWBRASSRINGSMALL =
        new Ellipse2D.Double(
            IMAGE_WIDTH * 0.4813084006309509,
            IMAGE_HEIGHT * 0.29439252614974976,
            IMAGE_WIDTH * 0.037383198738098145,
            IMAGE_HEIGHT * 0.03738316893577576);
    G2.setColor(new Color(0xC48200));
    G2.fill(SWBRASSRINGSMALL);

    final Ellipse2D SWRING1SMALL =
        new Ellipse2D.Double(
            IMAGE_WIDTH * 0.4859813153743744,
            IMAGE_HEIGHT * 0.29906541109085083,
            IMAGE_WIDTH * 0.02803739905357361,
            IMAGE_HEIGHT * 0.02803739905357361);
    G2.setColor(new Color(0x999999));
    G2.fill(SWRING1SMALL);

    final Ellipse2D SWRING1SMALL0 =
        new Ellipse2D.Double(
            IMAGE_WIDTH * 0.49065420031547546,
            IMAGE_HEIGHT * 0.3037383258342743,
            IMAGE_WIDTH * 0.018691569566726685,
            IMAGE_HEIGHT * 0.018691569566726685);
    G2.setColor(Color.BLACK);
    G2.fill(SWRING1SMALL0);

    G2.dispose();

    return IMAGE;
  }
  /**
   * Draws a range marker.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param axis the value axis.
   * @param marker the marker.
   * @param dataArea the area for plotting data (not including 3D effect).
   */
  public void drawRangeMarker(
      Graphics2D g2, CategoryPlot plot, ValueAxis axis, Marker marker, Rectangle2D dataArea) {

    Rectangle2D adjusted =
        new Rectangle2D.Double(
            dataArea.getX(),
            dataArea.getY() + getYOffset(),
            dataArea.getWidth() - getXOffset(),
            dataArea.getHeight() - getYOffset());
    if (marker instanceof ValueMarker) {
      ValueMarker vm = (ValueMarker) marker;
      double value = vm.getValue();
      Range range = axis.getRange();
      if (!range.contains(value)) {
        return;
      }

      GeneralPath path = null;
      PlotOrientation orientation = plot.getOrientation();
      if (orientation == PlotOrientation.HORIZONTAL) {
        float x = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float y = (float) adjusted.getMaxY();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo((float) (x + getXOffset()), y - (float) getYOffset());
        path.lineTo((float) (x + getXOffset()), (float) (adjusted.getMinY() - getYOffset()));
        path.lineTo(x, (float) adjusted.getMinY());
        path.closePath();
      } else if (orientation == PlotOrientation.VERTICAL) {
        float y = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float x = (float) dataArea.getX();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo(x + (float) this.xOffset, y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX() + this.xOffset), y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX()), y);
        path.closePath();
      }
      g2.setPaint(marker.getPaint());
      g2.fill(path);
      g2.setPaint(marker.getOutlinePaint());
      g2.draw(path);

      String label = marker.getLabel();
      RectangleAnchor anchor = marker.getLabelAnchor();
      if (label != null) {
        Font labelFont = marker.getLabelFont();
        g2.setFont(labelFont);
        g2.setPaint(marker.getLabelPaint());
        Point2D coordinates =
            calculateRangeMarkerTextAnchorPoint(
                g2,
                orientation,
                dataArea,
                path.getBounds2D(),
                marker.getLabelOffset(),
                LengthAdjustmentType.EXPAND,
                anchor);
        TextUtilities.drawAlignedString(
            label,
            g2,
            (float) coordinates.getX(),
            (float) coordinates.getY(),
            marker.getLabelTextAnchor());
      }

    } else {
      super.drawRangeMarker(g2, plot, axis, marker, adjusted);
      // TODO: draw the interval marker with a 3D effect
    }
  }
  private BufferedImage create_MAIN_POINTER_Image(final int WIDTH) {
    if (WIDTH <= 0) {
      return null;
    }

    final BufferedImage IMAGE = UTIL.createImage(WIDTH, WIDTH, Transparency.TRANSLUCENT);
    final Graphics2D G2 = IMAGE.createGraphics();
    G2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    G2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    // G2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
    // RenderingHints.VALUE_STROKE_NORMALIZE);

    final int IMAGE_WIDTH = IMAGE.getWidth();
    final int IMAGE_HEIGHT = IMAGE.getHeight();

    final GeneralPath STOPWATCHPOINTER = new GeneralPath();
    STOPWATCHPOINTER.setWindingRule(Path2D.WIND_EVEN_ODD);
    STOPWATCHPOINTER.moveTo(IMAGE_WIDTH * 0.5093457943925234, IMAGE_HEIGHT * 0.45794392523364486);
    STOPWATCHPOINTER.lineTo(IMAGE_WIDTH * 0.5, IMAGE_HEIGHT * 0.102803738317757);
    STOPWATCHPOINTER.lineTo(IMAGE_WIDTH * 0.49065420560747663, IMAGE_HEIGHT * 0.45794392523364486);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.45794392523364486,
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.45794392523364486,
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.45794392523364486);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.4719626168224299,
        IMAGE_HEIGHT * 0.46261682242990654,
        IMAGE_WIDTH * 0.45794392523364486,
        IMAGE_HEIGHT * 0.48130841121495327,
        IMAGE_WIDTH * 0.45794392523364486,
        IMAGE_HEIGHT * 0.5);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.45794392523364486,
        IMAGE_HEIGHT * 0.5186915887850467,
        IMAGE_WIDTH * 0.4719626168224299,
        IMAGE_HEIGHT * 0.5373831775700935,
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.5420560747663551);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.5420560747663551,
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.5420560747663551,
        IMAGE_WIDTH * 0.49065420560747663,
        IMAGE_HEIGHT * 0.5420560747663551);
    STOPWATCHPOINTER.lineTo(IMAGE_WIDTH * 0.49065420560747663, IMAGE_HEIGHT * 0.6214953271028038);
    STOPWATCHPOINTER.lineTo(IMAGE_WIDTH * 0.5093457943925234, IMAGE_HEIGHT * 0.6214953271028038);
    STOPWATCHPOINTER.lineTo(IMAGE_WIDTH * 0.5093457943925234, IMAGE_HEIGHT * 0.5420560747663551);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.5420560747663551,
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.5420560747663551,
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.5420560747663551);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.5280373831775701,
        IMAGE_HEIGHT * 0.5373831775700935,
        IMAGE_WIDTH * 0.5420560747663551,
        IMAGE_HEIGHT * 0.5186915887850467,
        IMAGE_WIDTH * 0.5420560747663551,
        IMAGE_HEIGHT * 0.5);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.5420560747663551,
        IMAGE_HEIGHT * 0.48130841121495327,
        IMAGE_WIDTH * 0.5280373831775701,
        IMAGE_HEIGHT * 0.46261682242990654,
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.45794392523364486);
    STOPWATCHPOINTER.curveTo(
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.45794392523364486,
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.45794392523364486,
        IMAGE_WIDTH * 0.5093457943925234,
        IMAGE_HEIGHT * 0.45794392523364486);
    STOPWATCHPOINTER.closePath();
    if (flatNeedle) {
      G2.setColor(getPointerColor().MEDIUM);
      G2.fill(STOPWATCHPOINTER);
    } else {
      final Point2D POINTER_START = new Point2D.Double(STOPWATCHPOINTER.getBounds2D().getMinX(), 0);
      final Point2D POINTER_STOP = new Point2D.Double(STOPWATCHPOINTER.getBounds2D().getMaxX(), 0);
      final float[] POINTER_FRACTIONS = {0.0f, 0.3888888889f, 0.5f, 0.6111111111f, 1.0f};
      final Color[] POINTER_COLORS = {
        getPointerColor().MEDIUM,
        getPointerColor().MEDIUM,
        getPointerColor().LIGHT,
        getPointerColor().MEDIUM,
        getPointerColor().MEDIUM
      };
      final LinearGradientPaint GRADIENT =
          new LinearGradientPaint(POINTER_START, POINTER_STOP, POINTER_FRACTIONS, POINTER_COLORS);
      G2.setPaint(GRADIENT);
      G2.fill(STOPWATCHPOINTER);
      G2.setPaint(getPointerColor().DARK);
      G2.draw(STOPWATCHPOINTER);
    }

    final Ellipse2D SWBRASSRING =
        new Ellipse2D.Double(
            IMAGE_WIDTH * 0.4672897160053253,
            IMAGE_HEIGHT * 0.4672897160053253,
            IMAGE_WIDTH * 0.06542053818702698,
            IMAGE_HEIGHT * 0.06542053818702698);
    final Point2D SWBRASSRING_START = new Point2D.Double(0, SWBRASSRING.getBounds2D().getMaxY());
    final Point2D SWBRASSRING_STOP = new Point2D.Double(0, SWBRASSRING.getBounds2D().getMinY());
    final float[] SWBRASSRING_FRACTIONS = {0.0f, 0.01f, 0.99f, 1.0f};
    final Color[] SWBRASSRING_COLORS = {
      new Color(230, 179, 92, 255),
      new Color(230, 179, 92, 255),
      new Color(196, 130, 0, 255),
      new Color(196, 130, 0, 255)
    };
    final LinearGradientPaint SWBRASSRING_GRADIENT =
        new LinearGradientPaint(
            SWBRASSRING_START, SWBRASSRING_STOP, SWBRASSRING_FRACTIONS, SWBRASSRING_COLORS);
    G2.setPaint(SWBRASSRING_GRADIENT);
    G2.fill(SWBRASSRING);

    final Ellipse2D SWRING1 =
        new Ellipse2D.Double(
            IMAGE_WIDTH * 0.47663551568984985,
            IMAGE_HEIGHT * 0.47663551568984985,
            IMAGE_WIDTH * 0.04672896862030029,
            IMAGE_HEIGHT * 0.04672896862030029);
    final Point2D SWRING1_CENTER = new Point2D.Double((0.5 * IMAGE_WIDTH), (0.5 * IMAGE_HEIGHT));
    final float[] SWRING1_FRACTIONS = {0.0f, 0.19f, 0.22f, 0.8f, 0.99f, 1.0f};
    final Color[] SWRING1_COLORS = {
      new Color(197, 197, 197, 255),
      new Color(197, 197, 197, 255),
      new Color(0, 0, 0, 255),
      new Color(0, 0, 0, 255),
      new Color(112, 112, 112, 255),
      new Color(112, 112, 112, 255)
    };
    final RadialGradientPaint SWRING1_GRADIENT =
        new RadialGradientPaint(
            SWRING1_CENTER,
            (float) (0.02336448598130841 * IMAGE_WIDTH),
            SWRING1_FRACTIONS,
            SWRING1_COLORS);
    G2.setPaint(SWRING1_GRADIENT);
    G2.fill(SWRING1);

    G2.dispose();

    return IMAGE;
  }