001/* ============ 002 * FXGraphics2D 003 * ============ 004 * 005 * (C)opyright 2014-2020, by Object Refinery Limited. 006 * 007 * http://www.jfree.org/fxgraphics2d/index.html 008 * 009 * The FXGraphics2D class has been developed by Object Refinery Limited for 010 * use in Orson Charts (http://www.object-refinery.com/orsoncharts) and 011 * JFreeChart (http://www.jfree.org/jfreechart). It may be useful for other 012 * code that uses the Graphics2D API provided by Java2D. 013 * 014 * Redistribution and use in source and binary forms, with or without 015 * modification, are permitted provided that the following conditions are met: 016 * - Redistributions of source code must retain the above copyright 017 * notice, this list of conditions and the following disclaimer. 018 * - Redistributions in binary form must reproduce the above copyright 019 * notice, this list of conditions and the following disclaimer in the 020 * documentation and/or other materials provided with the distribution. 021 * - Neither the name of the Object Refinery Limited nor the 022 * names of its contributors may be used to endorse or promote products 023 * derived from this software without specific prior written permission. 024 * 025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 028 * ARE DISCLAIMED. IN NO EVENT SHALL OBJECT REFINERY LIMITED BE LIABLE FOR ANY 029 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 030 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 031 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 032 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 033 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 034 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 035 * 036 */ 037 038package org.jfree.fx; 039 040import java.awt.Font; 041import java.awt.FontMetrics; 042import java.awt.Graphics; 043import java.awt.Graphics2D; 044import java.awt.geom.Rectangle2D; 045import java.text.CharacterIterator; 046import javafx.geometry.Bounds; 047import javafx.scene.text.FontPosture; 048import javafx.scene.text.FontWeight; 049import javafx.scene.text.Text; 050 051/** 052 * A font metrics implementation for JavaFX. This uses the JavaFX APIs to 053 * get font measurements, which is more exact than relying on the equivalent 054 * Java2D APIs. 055 * 056 * @since 1.5 057 */ 058public class FXFontMetrics extends FontMetrics { 059 060 private Graphics2D g2; 061 062 /** 063 * Creates a new instance. 064 * 065 * @param font the font ({@code null} not permitted). 066 * @param g2 the graphics target ({@code null} not permitted). 067 */ 068 public FXFontMetrics(Font font, Graphics2D g2) { 069 super(font); 070 this.g2 = g2; 071 } 072 073 @Override 074 public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex, 075 int limit, Graphics context) { 076 char[] arr = new char[limit - beginIndex]; 077 ci.setIndex(beginIndex); 078 for(int idx = 0; idx < arr.length; idx++) { 079 arr[idx] = ci.current(); 080 ci.next(); 081 } 082 return getStringBounds(arr, beginIndex, limit, context); 083 } 084 085 @Override 086 public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit, 087 Graphics context) { 088 String str = new String(chars, beginIndex, limit - beginIndex); 089 return getStringBounds(str, context); 090 } 091 092 @Override 093 public Rectangle2D getStringBounds(String str, int beginIndex, int limit, 094 Graphics context) { 095 String substr = str.substring(beginIndex, limit); 096 return super.getStringBounds(substr, context); 097 } 098 099 @Override 100 public Rectangle2D getStringBounds(String str, Graphics context) { 101 Text text = new Text(str); 102 FontWeight weight = font.isBold() ? FontWeight.BOLD : FontWeight.NORMAL; 103 FontPosture posture = font.isItalic() 104 ? FontPosture.ITALIC : FontPosture.REGULAR; 105 javafx.scene.text.Font jfxfont = javafx.scene.text.Font.font( 106 font.getFamily(), weight, posture, font.getSize()); 107 text.setFont(jfxfont); 108 Bounds b = text.getLayoutBounds(); 109 return new Rectangle2D.Double(b.getMinX(), b.getMinY(), b.getWidth(), 110 b.getHeight()); 111 } 112 113 @Override 114 public int stringWidth(String str) { 115 return (int) getStringBounds(str, this.g2).getWidth(); 116 } 117 118}