Exemplo n.º 1
0
  /** @see Graphics2D#drawString(String, float, float) */
  public void drawString(String s, float x, float y) {
    if (s.length() == 0) return;
    setFillPaint();
    if (onlyShapes) {
      drawGlyphVector(
          this.font.layoutGlyphVector(
              getFontRenderContext(),
              s.toCharArray(),
              0,
              s.length(),
              java.awt.Font.LAYOUT_LEFT_TO_RIGHT),
          x,
          y);
      //            Use the following line to compile in JDK 1.3
      //            drawGlyphVector(this.font.createGlyphVector(getFontRenderContext(), s), x, y);
    } else {
      boolean restoreTextRenderingMode = false;
      AffineTransform at = getTransform();
      AffineTransform at2 = getTransform();
      at2.translate(x, y);
      at2.concatenate(font.getTransform());
      setTransform(at2);
      AffineTransform inverse = this.normalizeMatrix();
      AffineTransform flipper = AffineTransform.getScaleInstance(1, -1);
      inverse.concatenate(flipper);
      double[] mx = new double[6];
      inverse.getMatrix(mx);
      cb.beginText();
      cb.setFontAndSize(baseFont, fontSize);
      // Check if we need to simulate an italic font.
      // When there are different fonts for italic, bold, italic bold
      // the font.getName() will be different from the font.getFontName()
      // value. When they are the same value then we are normally dealing
      // with a single font that has been made into an italic or bold
      // font.
      if (font.isItalic() && font.getFontName().equals(font.getName())) {
        float angle = baseFont.getFontDescriptor(BaseFont.ITALICANGLE, 1000);
        float angle2 = font.getItalicAngle();
        // We don't have an italic version of this font so we need
        // to set the font angle ourselves to produce an italic font.
        if (angle2 == 0) {
          // The JavaVM didn't have an angle setting for making
          // the font an italic font so use a default of
          // italic angle of 15 degrees.
          angle2 = 15.0f;
        } else {
          // This sign of the angle for Java and PDF seams
          // seams to be reversed.
          angle2 = -angle2;
        }
        if (angle == 0) {
          mx[2] = angle2 / 100.0f;
        }
      }
      cb.setTextMatrix(
          (float) mx[0], (float) mx[1], (float) mx[2], (float) mx[3], (float) mx[4], (float) mx[5]);
      Float fontTextAttributeWidth = (Float) font.getAttributes().get(TextAttribute.WIDTH);
      fontTextAttributeWidth =
          (fontTextAttributeWidth == null) ? TextAttribute.WIDTH_REGULAR : fontTextAttributeWidth;
      if (!TextAttribute.WIDTH_REGULAR.equals(fontTextAttributeWidth))
        cb.setHorizontalScaling(100.0f / fontTextAttributeWidth.floatValue());

      // Check if we need to simulate a bold font.
      // Do nothing if the BaseFont is already bold. This test is not foolproof but it will work
      // most of the times.
      if (baseFont.getPostscriptFontName().toLowerCase().indexOf("bold") < 0) {
        // Get the weight of the font so we can detect fonts with a weight
        // that makes them bold, but the Font.isBold() value is false.
        Float weight = (Float) font.getAttributes().get(TextAttribute.WEIGHT);
        if (weight == null) {
          weight = (font.isBold()) ? TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR;
        }
        if ((font.isBold() || (weight.floatValue() >= TextAttribute.WEIGHT_SEMIBOLD.floatValue()))
            && (font.getFontName().equals(font.getName()))) {
          // Simulate a bold font.
          float strokeWidth =
              font.getSize2D()
                  * (weight.floatValue() - TextAttribute.WEIGHT_REGULAR.floatValue())
                  / 30f;
          if (strokeWidth != 1) {
            if (realPaint instanceof Color) {
              cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
              cb.setLineWidth(strokeWidth);
              Color color = (Color) realPaint;
              int alpha = color.getAlpha();
              if (alpha != currentStrokeGState) {
                currentStrokeGState = alpha;
                PdfGState gs = strokeGState[alpha];
                if (gs == null) {
                  gs = new PdfGState();
                  gs.setStrokeOpacity(alpha / 255f);
                  strokeGState[alpha] = gs;
                }
                cb.setGState(gs);
              }
              cb.setColorStroke(color);
              restoreTextRenderingMode = true;
            }
          }
        }
      }

      double width = 0;
      if (font.getSize2D() > 0) {
        float scale = 1000 / font.getSize2D();
        Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
        width = derivedFont.getStringBounds(s, getFontRenderContext()).getWidth();
        if (derivedFont.isTransformed()) width /= scale;
      }
      // if the hyperlink flag is set add an action to the text
      Object url = getRenderingHint(HyperLinkKey.KEY_INSTANCE);
      if (url != null && !url.equals(HyperLinkKey.VALUE_HYPERLINKKEY_OFF)) {
        float scale = 1000 / font.getSize2D();
        Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
        double height = derivedFont.getStringBounds(s, getFontRenderContext()).getHeight();
        if (derivedFont.isTransformed()) height /= scale;
        double leftX = cb.getXTLM();
        double leftY = cb.getYTLM();
        PdfAction action = new PdfAction(url.toString());
        cb.setAction(
            action,
            (float) leftX,
            (float) leftY,
            (float) (leftX + width),
            (float) (leftY + height));
      }
      if (s.length() > 1) {
        float adv = ((float) width - baseFont.getWidthPoint(s, fontSize)) / (s.length() - 1);
        cb.setCharacterSpacing(adv);
      }
      cb.showText(s);
      if (s.length() > 1) {
        cb.setCharacterSpacing(0);
      }
      if (!TextAttribute.WIDTH_REGULAR.equals(fontTextAttributeWidth)) cb.setHorizontalScaling(100);

      // Restore the original TextRenderingMode if needed.
      if (restoreTextRenderingMode) {
        cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
      }

      cb.endText();
      setTransform(at);
      if (underline) {
        // These two are supposed to be taken from the .AFM file
        // int UnderlinePosition = -100;
        int UnderlineThickness = 50;
        //
        double d = asPoints(UnderlineThickness, (int) fontSize);
        Stroke savedStroke = originalStroke;
        setStroke(new BasicStroke((float) d));
        y = (float) (y + asPoints(UnderlineThickness, (int) fontSize));
        Line2D line = new Line2D.Double(x, y, width + x, y);
        draw(line);
        setStroke(savedStroke);
      }
    }
  }