/**
  * Returns the bounds for the character with the maximum bounds in the specified <code>Graphics
  * </code> context.
  *
  * @param context the specified <code>Graphics</code> context
  * @return a <code>Rectangle2D</code> that is the bounding box for the character with the maximum
  *     bounds.
  * @see java.awt.Font#getMaxCharBounds(java.awt.font.FontRenderContext)
  */
 public Rectangle2D getMaxCharBounds(final Graphics context) {
   final Font baseFont = getFont();
   final String name = baseFont.getName();
   final org.pentaho.reporting.libraries.fonts.registry.FontMetrics fontMetrics =
       metaData.getFontMetrics(
           name,
           baseFont.getSize2D(),
           baseFont.isBold(),
           baseFont.isItalic(),
           "UTF-8",
           false,
           false);
   return new Rectangle2D.Double(
       0,
       -StrictGeomUtility.toExternalValue(fontMetrics.getMaxAscent()),
       StrictGeomUtility.toExternalValue(fontMetrics.getMaxCharAdvance()),
       StrictGeomUtility.toExternalValue(
           fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent() + fontMetrics.getLeading()));
 }
  public ScalableTrueTypeFontMetrics(final TrueTypeFont font) throws IOException {
    if (font == null) {
      throw new NullPointerException("The font must not be null");
    }
    this.font = font;
    final FontHeaderTable head = (FontHeaderTable) font.getTable(FontHeaderTable.TABLE_ID);
    if (head == null) {
      throw new IllegalStateException("Font has no HEAD table and is not a usable font.");
    }
    final int unitsPerEm = head.getUnitsPerEm();
    final long strictScaleFactor = StrictGeomUtility.toInternalValue(1);
    maxAscent = (strictScaleFactor * head.getyMax()) / unitsPerEm;
    maxDescent = (strictScaleFactor * -head.getyMin()) / unitsPerEm;
    // prefer the mac table, as at least for the old version of Arial
    // I use, the mac table is consistent with the Java-Font-Metrics
    final HorizontalHeaderTable hhea =
        (HorizontalHeaderTable) font.getTable(HorizontalHeaderTable.TABLE_ID);
    if (hhea == null) {
      throw new IllegalStateException("The font has no HHEA table and is not a valid font.");
    }
    // Mac metrics must always be present..
    createMacMetrics(hhea, unitsPerEm, strictScaleFactor);

    final OS2Table table = (OS2Table) font.getTable(OS2Table.TABLE_ID);
    if (table != null) {
      computeWindowsMetrics(table, unitsPerEm, strictScaleFactor);
    }

    final PostscriptInformationTable postTable =
        (PostscriptInformationTable) font.getTable(PostscriptInformationTable.TABLE_ID);
    if (postTable != null) {
      this.italicAngle = StrictGeomUtility.toInternalValue(postTable.getItalicAngle());
      this.underlinePosition =
          getAscent()
              + (strictScaleFactor
                      * (-postTable.getUnderlinePosition()
                          + (postTable.getUnderlineThickness() / 2)))
                  / unitsPerEm;
    }

    font.dispose();
  }
 private void createMacMetrics(
     final HorizontalHeaderTable hhea, final int unitsPerEm, final long scaleFactor) {
   this.maxCharAdvance = (scaleFactor * hhea.getMaxAdvanceWidth()) / unitsPerEm;
   this.ascent = (scaleFactor * hhea.getAscender()) / unitsPerEm;
   this.descent = (scaleFactor * -hhea.getDescender()) / unitsPerEm;
   this.leading = (scaleFactor * hhea.getLineGap()) / unitsPerEm;
   this.xHeight =
       (long)
           (ascent * LibFontsDefaults.DEFAULT_XHEIGHT_SIZE / LibFontsDefaults.DEFAULT_ASCENT_SIZE);
   this.strikethroughPosition =
       getMaxAscent() - (long) (this.xHeight * LibFontsDefaults.DEFAULT_STRIKETHROUGH_POSITION);
   this.italicAngle =
       StrictGeomUtility.toInternalValue(
           -StrictMath.atan2(hhea.getCaretSlopeRun(), hhea.getCaretSlopeRise()) * 180 / Math.PI);
 }
 static {
   final long value = StrictGeomUtility.toInternalValue(1);
   conversionFactor =
       value / org.pentaho.reporting.libraries.fonts.tools.StrictGeomUtility.toInternalValue(1);
 }