protected void drawImageMap(final RenderableReplacedContentBox content) {
    if (version < '6') {
      return;
    }

    final ImageMap imageMap = RenderUtility.extractImageMap(content);
    // only generate a image map, if the user does not specify their own onw via the override.
    // Of course, they would have to provide the map by other means as well.

    if (imageMap == null) {
      return;
    }

    final ImageMapEntry[] imageMapEntries = imageMap.getMapEntries();
    for (int i = 0; i < imageMapEntries.length; i++) {
      final ImageMapEntry imageMapEntry = imageMapEntries[i];
      final String link = imageMapEntry.getAttribute(LibXmlInfo.XHTML_NAMESPACE, "href");
      final String tooltip = imageMapEntry.getAttribute(LibXmlInfo.XHTML_NAMESPACE, "title");
      if (StringUtils.isEmpty(tooltip)) {
        continue;
      }

      final AffineTransform affineTransform = getGraphics().getTransform();
      final float translateX = (float) affineTransform.getTranslateX();
      final int x = (int) (translateX + StrictGeomUtility.toExternalValue(content.getX()));
      final int y = (int) StrictGeomUtility.toExternalValue(content.getY());
      final float[] translatedCoords =
          translateCoordinates(imageMapEntry.getAreaCoordinates(), x, y);

      final PolygonAnnotation polygonAnnotation = new PolygonAnnotation(writer, translatedCoords);
      polygonAnnotation.put(PdfName.CONTENTS, new PdfString(tooltip, PdfObject.TEXT_UNICODE));
      writer.addAnnotation(polygonAnnotation);
    }
  }
  /**
   * Helperfunction to extract an image from an imagereference. If the image is contained as
   * java.awt.Image object only, the image is recoded into an PNG-Image.
   *
   * @param reference the image reference.
   * @return an image.
   * @throws com.lowagie.text.DocumentException if no PDFImageElement could be created using the
   *     given ImageReference.
   * @throws java.io.IOException if the image could not be read.
   */
  public Image getImage(final ImageContainer reference) throws DocumentException, IOException {
    if (reference == null) {
      throw new NullPointerException();
    }

    Object identity = null;
    java.awt.Image image = null;
    if (reference instanceof URLImageContainer) {
      final URLImageContainer urlImageContainer = (URLImageContainer) reference;
      final ResourceKey url = urlImageContainer.getResourceKey();
      if (url != null && urlImageContainer.isLoadable()) {
        identity = url;
        final Image cached = (Image) cachedImages.get(identity);
        if (cached != null) {
          return cached;
        }

        try {
          final ResourceData resourceData = resourceManager.load(url);
          final byte[] data = resourceData.getResource(resourceManager);
          final Image itextimage = Image.getInstance(data);
          cachedImages.put(identity, itextimage);
          return itextimage;
        } catch (ResourceException re) {
          RTFImageCache.logger.info("Caught illegal Image, will recode to PNG instead", re);
        } catch (BadElementException be) {
          RTFImageCache.logger.info("Caught illegal Image, will recode to PNG instead", be);
        } catch (IOException ioe) {
          RTFImageCache.logger.info(
              "Unable to read the raw-data, will try to recode image-data.", ioe);
        }

        try {
          final Resource resource = resourceManager.create(url, null, Image.class);
          image = (java.awt.Image) resource.getResource();
        } catch (ResourceException re) {
          RTFImageCache.logger.info("Caught illegal Image, will try to find local instance", re);
        }
      }
    }

    if (reference instanceof LocalImageContainer && image == null) {
      final LocalImageContainer localImageContainer = (LocalImageContainer) reference;
      image = localImageContainer.getImage();
      if (image != null) {
        // check, if the content was cached ...
        identity = localImageContainer.getIdentity();
        if (identity != null) {
          final Image cachedImage = (Image) cachedImages.get(identity);
          if (cachedImage != null) {
            return cachedImage;
          }
        }
      }
    }
    if (image == null) {
      return null;
    }

    final WaitingImageObserver obs = new WaitingImageObserver(image);
    obs.waitImageLoaded();

    try {
      final byte[] data = RenderUtility.encodeImage(image);
      final Image itextimage = Image.getInstance(data);
      if (identity != null) {
        cachedImages.put(identity, itextimage);
      }
      return itextimage;
    } catch (UnsupportedEncoderException uee) {
      logger.warn("Assertation-Failure: PNG encoding failed.", uee);
      return null;
    }
  }
  protected boolean drawImage(
      final RenderableReplacedContentBox content,
      final Image image,
      final com.lowagie.text.Image itextImage) {
    final StyleSheet layoutContext = content.getStyleSheet();
    final boolean shouldScale = layoutContext.getBooleanStyleProperty(ElementStyleKeys.SCALE);

    final int x = (int) StrictGeomUtility.toExternalValue(content.getX());
    final int y = (int) StrictGeomUtility.toExternalValue(content.getY());
    final int width = (int) StrictGeomUtility.toExternalValue(content.getWidth());
    final int height = (int) StrictGeomUtility.toExternalValue(content.getHeight());

    if (width == 0 || height == 0) {
      PdfLogicalPageDrawable.logger.debug("Error: Image area is empty: " + content);
      return false;
    }

    final WaitingImageObserver obs = new WaitingImageObserver(image);
    obs.waitImageLoaded();
    final int imageWidth = image.getWidth(obs);
    final int imageHeight = image.getHeight(obs);
    if (imageWidth < 1 || imageHeight < 1) {
      return false;
    }

    final Rectangle2D.Double drawAreaBounds = new Rectangle2D.Double(x, y, width, height);
    final AffineTransform scaleTransform;

    final Graphics2D g2;
    if (shouldScale == false) {
      double deviceScaleFactor = 1;
      final double devResolution =
          getMetaData().getNumericFeatureValue(OutputProcessorFeature.DEVICE_RESOLUTION);
      if (getMetaData().isFeatureSupported(OutputProcessorFeature.IMAGE_RESOLUTION_MAPPING)) {
        if (devResolution != 72.0 && devResolution > 0) {
          // Need to scale the device to its native resolution before attempting to draw the image..
          deviceScaleFactor = (72.0 / devResolution);
        }
      }

      final int clipWidth = Math.min(width, (int) Math.ceil(deviceScaleFactor * imageWidth));
      final int clipHeight = Math.min(height, (int) Math.ceil(deviceScaleFactor * imageHeight));
      final ElementAlignment horizontalAlignment =
          (ElementAlignment) layoutContext.getStyleProperty(ElementStyleKeys.ALIGNMENT);
      final ElementAlignment verticalAlignment =
          (ElementAlignment) layoutContext.getStyleProperty(ElementStyleKeys.VALIGNMENT);
      final int alignmentX =
          (int) RenderUtility.computeHorizontalAlignment(horizontalAlignment, width, clipWidth);
      final int alignmentY =
          (int) RenderUtility.computeVerticalAlignment(verticalAlignment, height, clipHeight);

      g2 = (Graphics2D) getGraphics().create();
      g2.clip(drawAreaBounds);
      g2.translate(x, y);
      g2.translate(alignmentX, alignmentY);
      g2.clip(new Rectangle2D.Float(0, 0, clipWidth, clipHeight));
      g2.scale(deviceScaleFactor, deviceScaleFactor);

      scaleTransform = null;
    } else {
      g2 = (Graphics2D) getGraphics().create();
      g2.clip(drawAreaBounds);
      g2.translate(x, y);
      g2.clip(new Rectangle2D.Float(0, 0, width, height));

      final double scaleX;
      final double scaleY;

      final boolean keepAspectRatio =
          layoutContext.getBooleanStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO);
      if (keepAspectRatio) {
        final double scaleFactor =
            Math.min(width / (double) imageWidth, height / (double) imageHeight);
        scaleX = scaleFactor;
        scaleY = scaleFactor;
      } else {
        scaleX = width / (double) imageWidth;
        scaleY = height / (double) imageHeight;
      }

      final int clipWidth = (int) (scaleX * imageWidth);
      final int clipHeight = (int) (scaleY * imageHeight);

      final ElementAlignment horizontalAlignment =
          (ElementAlignment) layoutContext.getStyleProperty(ElementStyleKeys.ALIGNMENT);
      final ElementAlignment verticalAlignment =
          (ElementAlignment) layoutContext.getStyleProperty(ElementStyleKeys.VALIGNMENT);
      final int alignmentX =
          (int) RenderUtility.computeHorizontalAlignment(horizontalAlignment, width, clipWidth);
      final int alignmentY =
          (int) RenderUtility.computeVerticalAlignment(verticalAlignment, height, clipHeight);

      g2.translate(alignmentX, alignmentY);
      scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY);
    }

    final PdfGraphics2D pdfGraphics2D = (PdfGraphics2D) g2;
    pdfGraphics2D.drawPdfImage(itextImage, image, scaleTransform, null);
    g2.dispose();
    return true;
  }