public static void updateIcons(JTree tree) { Font defaultFont = UIManager.getFont("Tree.font"); Font currentFont = tree.getFont(); double newScale = (double) currentFont.getSize2D() / defaultFont.getSize2D(); DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree.getCellRenderer(); renderer.setOpenIcon( scale(UIManager.getIcon("Tree.openIcon"), newScale, tree)); renderer.setClosedIcon( scale(UIManager.getIcon("Tree.closedIcon"), newScale, tree)); renderer.setLeafIcon( scale(UIManager.getIcon("Tree.leafIcon"), newScale, tree)); Collection<Integer> iconSizes = Arrays.asList( renderer.getOpenIcon().getIconHeight(), renderer.getClosedIcon().getIconHeight(), renderer.getLeafIcon().getIconHeight()); // Convert points to pixels Point2D p = new Point2D.Float(0, currentFont.getSize2D()); FontRenderContext context = tree.getFontMetrics(currentFont).getFontRenderContext(); context.getTransform().transform(p, p); int fontSizeInPixels = (int) Math.ceil(p.getY()); tree.setRowHeight( Math.max(fontSizeInPixels, Collections.max(iconSizes) + 2)); }
public static void main(String[] args) { Font defaultFont = new Font(null); FontRenderContext defaultFrc = new FontRenderContext(new AffineTransform(), true, true); GlyphVector gv = defaultFont.createGlyphVector(defaultFrc, "test"); //this causes the bounds to be cached //which is necessary to trigger the bug gv.getGlyphLogicalBounds(0); //this correctly gets the position of the overall advance Point2D glyphPosition = gv.getGlyphPosition(gv.getNumGlyphs()); // this sets the position of the overall advance, // but also incorrectly tries to clear the bounds cache // of a specific glyph indexed by the glyphIndex parameter // even if the glyphIndex represents the overall advance // (i.e. if glyphIndex == getNumGlyphs()) gv.setGlyphPosition(gv.getNumGlyphs(), glyphPosition); }
public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; FontRenderContext frc = new FontRenderContext(null, true, true); Font f = helvFont.deriveFont(Font.PLAIN, 40); System.out.println("font = " +f.getFontName()); GlyphVector gv = f.createGlyphVector(frc, codes); g.setFont(f); g.setColor(Color.white); g.fillRect(0,0,400,400); g.setColor(Color.black); g2.drawGlyphVector(gv, 5,200); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g2.drawString(str, 5, 250); }
static void test(int sz) { Font reg = new Font(name, Font.PLAIN, sz); Font bold = new Font(name, Font.BOLD, sz); //System.out.println("reg="+reg); //System.out.println("bold="+bold); FontRenderContext frc = new FontRenderContext(null, false, false); if (reg.getFontName(Locale.ENGLISH).equals(name) && bold.getFontName(Locale.ENGLISH).equals(name)) { Rectangle2D rb = reg.getStringBounds(" ", frc); Rectangle2D bb = bold.getStringBounds(" ", frc); if (bb.getWidth() > rb.getWidth() + 1.01f) { System.err.println("reg="+reg+" bds = " + rb); System.err.println("bold="+bold+" bds = " + bb); throw new RuntimeException("Advance difference too great."); } } else { System.out.println("Skipping test because fonts aren't as expected"); } }
/** * !!! not used currently, but might be by getPixelbounds? */ public void pixellate(FontRenderContext renderFRC, Point2D loc, Point pxResult) { if (renderFRC == null) { renderFRC = frc; } // it is a total pain that you have to copy the transform. AffineTransform at = renderFRC.getTransform(); at.transform(loc, loc); pxResult.x = (int)loc.getX(); // but must not behave oddly around zero pxResult.y = (int)loc.getY(); loc.setLocation(pxResult.x, pxResult.y); try { at.inverseTransform(loc, loc); } catch (NoninvertibleTransformException e) { throw new IllegalArgumentException("must be able to invert frc transform"); } }
public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv, float x, float y) { FontRenderContext frc = gv.getFontRenderContext(); FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc); if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) { SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y); return; } if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { double origin[] = {x, y}; sg2d.transform.transform(origin, 0, origin, 0, 1); x = (float) origin[0]; y = (float) origin[1]; } else { x += sg2d.transX; // don't use the glyph info origin, already in gv. y += sg2d.transY; } GlyphList gl = GlyphList.getInstance(); gl.setFromGlyphVector(info, gv, x, y); drawGlyphList(sg2d, gl, info.aaHint); gl.dispose(); }
static void measureText() { Font font = new Font(FONT, Font.PLAIN, 36); if (!font.getFamily(Locale.ENGLISH).equals(FONT)) { return; } FontRenderContext frc = new FontRenderContext(null, false, false); TextLayout tl1 = new TextLayout(STR1, font, frc); TextLayout tl2 = new TextLayout(STR2, font, frc); Rectangle r1 = tl1.getPixelBounds(frc, 0f, 0f); Rectangle r2 = tl2.getPixelBounds(frc, 0f, 0f); if (r1.height > r2.height) { System.out.println(font); System.out.println(r1); System.out.println(r2); throw new RuntimeException("BAD BOUNDS"); } }
BufferedImage drawText(boolean doGV) { int w = 400; int h = 50; BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); g.setColor(Color.white); g.fillRect(0,0,w,h); g.setColor(Color.black); Font f = helvFont.deriveFont(Font.PLAIN, 40); g.setFont(f); int x = 5; int y = h - 10; if (doGV) { FontRenderContext frc = new FontRenderContext(null, true, true); GlyphVector gv = f.createGlyphVector(frc, codes); g.drawGlyphVector(gv, 5, y); } else { g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g.drawString(str, x, y); } return bi; }
protected int getLineNumberWidth() { int newWidth = 0; EditorUI eui = editorUI; if (eui != null) { /* Insets insets = eui.getLineNumberMargin(); if (insets != null) { newWidth += insets.left + insets.right; } */ JTextComponent tc = eui.getComponent(); if (font != null && tc != null) { Graphics g; FontRenderContext frc; FontMetrics fm; if ((g = tc.getGraphics()) != null && (g instanceof Graphics2D) && (frc = ((Graphics2D)g).getFontRenderContext()) != null) { newWidth += new TextLayout(String.valueOf(highestLineNumber), font, frc).getAdvance(); } else if ((fm = getFontMetrics(font)) != null) { // Use FontMetrics.stringWidth() as best approximation newWidth += fm.stringWidth(String.valueOf(highestLineNumber)); } } } return newWidth; }
public static void main(String[] args) { Font font = new Font("Tahoma", Font.PLAIN, 12); String text = "\ude00"; FontRenderContext frc = new FontRenderContext(null, false, false); TextLayout layout = new TextLayout(text, font, frc); layout.getCaretShapes(0); }
private float getItalicAngle(FontRenderContext frc) { Object aa, fm; if (frc == null) { aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF; fm = RenderingHints.VALUE_FRACTIONALMETRICS_OFF; } else { aa = frc.getAntiAliasingHint(); fm = frc.getFractionalMetricsHint(); } return getFont2D().getItalicAngle(this, identityTx, aa, fm); }
/** * Initialize a factory to produce glyph arrays. * @param frc the FontRenderContext to use for the arrays to be produced. * @param text the text of the paragraph. * @param bidi the bidi information for the paragraph text, or null if the * entire text is left-to-right text. */ public TextLabelFactory(FontRenderContext frc, char[] text, Bidi bidi, int flags) { this.frc = frc; this.text = text.clone(); this.bidi = bidi; this.flags = flags; this.lineBidi = bidi; this.lineStart = 0; this.lineLimit = text.length; }
@Override protected void paintComponent(Graphics g) { atualizar(); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setFont(FONT); FontRenderContext frc = g2.getFontRenderContext(); TextLayout textLayout = new TextLayout(Integer.toString(value), FONT, frc); g2.setPaint(textColor); Shape outline = textLayout.getOutline(AffineTransform.getTranslateInstance(value < 10 ? 20 : type == SHIELD ? 10 : 14, 30)); g2.fill(outline); g2.setPaint(BLACK); g2.draw(outline); }
private void myDrawChars(Graphics g, /* OLD char buf[], */ Line l, int start, int howmany, int xoff, int baseline) { if (xferBuf.length < l.length()) { xferBuf = new char[l.length()]; } // OLD final char buf[] = l.XcharArray(); l.getChars(xferBuf); // Use rendering hints (antialiasing etc.) Map<?,?> hints = renderingHints; if ((hints != null) && (g instanceof Graphics2D)) { ((Graphics2D) g).setRenderingHints(hints); } if (metrics.isMultiCell()) { // slow way // This looks expensive but it is in fact a whole lot faster // than issuing a g.drawChars() _per_ character Graphics2D g2 = (Graphics2D) g; FontRenderContext frc = g2.getFontRenderContext(); // Gaaah, why doesn't createGlyphVector() take a (char[],offset,len) // triple? char[] tmp = new char[howmany]; System.arraycopy(xferBuf, start, tmp, 0, howmany); GlyphVector gv = getFont().createGlyphVector(frc, tmp); massage_glyphs(gv, start, howmany, l); g2.drawGlyphVector(gv, xoff, baseline); } else { // fast way g.drawChars(xferBuf, start, howmany, xoff, baseline); } }
/** * Returns the bounds for the character with the maximum * bounds as defined in the specified {@code FontRenderContext}. * <p>Note: The returned bounds is in baseline-relative coordinates * (see {@link java.awt.Font class notes}). * @param frc the specified {@code FontRenderContext} * @return a {@code Rectangle2D} that is the bounding box * for the character with the maximum bounds. */ public Rectangle2D getMaxCharBounds(FontRenderContext frc) { float [] metrics = new float[4]; getFont2D().getFontMetrics(this, frc, metrics); return new Rectangle2D.Float(0, -metrics[0], metrics[3], metrics[0] + metrics[1] + metrics[2]); }
public static void writeImage(File fontFile, File outputFile, String value) throws Exception { BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, image.getWidth(), image.getHeight()); g.setColor(Color.BLACK); Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile); font = font.deriveFont(Font.PLAIN, 72f); FontRenderContext frc = new FontRenderContext(null, false, false); GlyphVector gv = font.createGlyphVector(frc, value); g.drawGlyphVector(gv, 10, 80); g.fill(gv.getOutline(10, 180)); ImageIO.write(image, "png", outputFile); }
/** * Returns Cell's real size (this method considers Icon and name size) * * @param graph <code>JGraph</code> object to retrieve font dimension informations * @return cell's real size * * Bertoli Marco 4-giu-2005 */ public Dimension getSize(JGraph graph) { Dimension cellDimension = (Dimension) imageDimension.clone(); // Gets the graph font Font font = graph.getFont(); // Gets the graphical context Graphics2D g2D = (Graphics2D) graph.getGraphics(); // Gets the bounds of the cell name FontRenderContext frc = g2D.getFontRenderContext(); Rectangle r = font.getStringBounds(getUserObject().toString(), frc).getBounds(); // Sets the cell dimension cellDimension.height += r.height + 5; cellDimension.width = Math.max(cellDimension.width, r.width + 10); return cellDimension; }
public void runTest(Object ctx, int numReps) { TCContext tcctx = (TCContext)ctx; final Font font = tcctx.font; final CharacterIterator ci = tcctx.ci; final FontRenderContext frc = tcctx.frc; GlyphVector gv; do { gv = font.createGlyphVector(frc, ci); } while (--numReps >= 0); }
/** * Returns the logical bounds of the specified array of characters * in the specified {@code FontRenderContext}. The logical * bounds contains the origin, ascent, advance, and height, which * includes the leading. The logical bounds does not always enclose * all the text. For example, in some languages and in some fonts, * accent marks can be positioned above the ascent or below the * descent. To obtain a visual bounding box, which encloses all the * text, use the {@link TextLayout#getBounds() getBounds} method of * {@code TextLayout}. * <p>Note: The returned bounds is in baseline-relative coordinates * (see {@link java.awt.Font class notes}). * @param chars an array of characters * @param beginIndex the initial offset in the array of * characters * @param limit the end offset in the array of characters * @param frc the specified {@code FontRenderContext} * @return a {@code Rectangle2D} that is the bounding box of the * specified array of characters in the specified * {@code FontRenderContext}. * @throws IndexOutOfBoundsException if {@code beginIndex} is * less than zero, or {@code limit} is greater than the * length of {@code chars}, or {@code beginIndex} * is greater than {@code limit}. * @see FontRenderContext * @see Font#createGlyphVector * @since 1.2 */ public Rectangle2D getStringBounds(char [] chars, int beginIndex, int limit, FontRenderContext frc) { if (beginIndex < 0) { throw new IndexOutOfBoundsException("beginIndex: " + beginIndex); } if (limit > chars.length) { throw new IndexOutOfBoundsException("limit: " + limit); } if (beginIndex > limit) { throw new IndexOutOfBoundsException("range length: " + (limit - beginIndex)); } // this code should be in textlayout // quick check for simple text, assume GV ok to use if simple boolean simple = values == null || (values.getKerning() == 0 && values.getLigatures() == 0 && values.getBaselineTransform() == null); if (simple) { simple = ! FontUtilities.isComplexText(chars, beginIndex, limit); } if (simple) { GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex, limit - beginIndex, frc); return gv.getLogicalBounds(); } else { // need char array constructor on textlayout String str = new String(chars, beginIndex, limit - beginIndex); TextLayout tl = new TextLayout(str, this, frc); return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(), tl.getAscent() + tl.getDescent() + tl.getLeading()); } }
protected BufferedImage createImage(Color bgColor) { BufferedImage bufferedImage = new BufferedImage(END_X, END_Y, BufferedImage.TYPE_INT_RGB); // create graphics and graphics2d final Graphics graphics = bufferedImage.getGraphics(); final Graphics2D g2d = (Graphics2D) graphics; // set the background color g2d.setBackground(bgColor == null ? Color.gray : bgColor); g2d.clearRect(START_X, START_Y, END_X, END_Y); // create a pattern for the background createPattern(g2d); // set the fonts and font rendering hints Font font = new Font("Helvetica", Font.ITALIC, 30); g2d.setFont(font); FontRenderContext frc = g2d.getFontRenderContext(); g2d.translate(10, 24); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setStroke(new BasicStroke(3)); // sets the foreground color g2d.setPaint(Color.DARK_GRAY); GlyphVector gv = font.createGlyphVector(frc, message); int numGlyphs = gv.getNumGlyphs(); for (int ii = 0; ii < numGlyphs; ii++) { AffineTransform at; Point2D p = gv.getGlyphPosition(ii); at = AffineTransform.getTranslateInstance(p.getX(), p.getY()); at.rotate(Math.PI / 8); Shape shape = gv.getGlyphOutline(ii); Shape sss = at.createTransformedShape(shape); g2d.fill(sss); } return blurImage(bufferedImage); }
/** * Returns the logical bounds of the specified array of characters * in the specified <code>FontRenderContext</code>. The logical * bounds contains the origin, ascent, advance, and height, which * includes the leading. The logical bounds does not always enclose * all the text. For example, in some languages and in some fonts, * accent marks can be positioned above the ascent or below the * descent. To obtain a visual bounding box, which encloses all the * text, use the {@link TextLayout#getBounds() getBounds} method of * <code>TextLayout</code>. * <p>Note: The returned bounds is in baseline-relative coordinates * (see {@link java.awt.Font class notes}). * @param chars an array of characters * @param beginIndex the initial offset in the array of * characters * @param limit the end offset in the array of characters * @param frc the specified <code>FontRenderContext</code> * @return a <code>Rectangle2D</code> that is the bounding box of the * specified array of characters in the specified * <code>FontRenderContext</code>. * @throws IndexOutOfBoundsException if <code>beginIndex</code> is * less than zero, or <code>limit</code> is greater than the * length of <code>chars</code>, or <code>beginIndex</code> * is greater than <code>limit</code>. * @see FontRenderContext * @see Font#createGlyphVector * @since 1.2 */ public Rectangle2D getStringBounds(char [] chars, int beginIndex, int limit, FontRenderContext frc) { if (beginIndex < 0) { throw new IndexOutOfBoundsException("beginIndex: " + beginIndex); } if (limit > chars.length) { throw new IndexOutOfBoundsException("limit: " + limit); } if (beginIndex > limit) { throw new IndexOutOfBoundsException("range length: " + (limit - beginIndex)); } // this code should be in textlayout // quick check for simple text, assume GV ok to use if simple boolean simple = values == null || (values.getKerning() == 0 && values.getLigatures() == 0 && values.getBaselineTransform() == null); if (simple) { simple = ! FontUtilities.isComplexText(chars, beginIndex, limit); } if (simple) { GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex, limit - beginIndex, frc); return gv.getLogicalBounds(); } else { // need char array constructor on textlayout String str = new String(chars, beginIndex, limit - beginIndex); TextLayout tl = new TextLayout(str, this, frc); return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(), tl.getAscent() + tl.getDescent() + tl.getLeading()); } }
public Rectangle2D getBounds2D(String str, double x, double y, double dx, double dy, double scale) { if (isScaleInvariant()) { if (scale <= 0.d) { return new java.awt.geom.Rectangle2D.Double(x, y, 0, 0); } else { dx /= scale; dy /= scale; } } else { scale = 1; } // see http://forum.java.sun.com/thread.jspa?forumID=5&threadID=619854 // for an example of how to measure text size FontRenderContext frc = new FontRenderContext(null, true, false); GlyphVector gv = font.createGlyphVector(frc, str); Rectangle2D visualBounds = gv.getVisualBounds(); double voffset = visualBounds.getHeight() + visualBounds.getY(); Rectangle2D bounds = new Rectangle2D.Double(x + dx, y - voffset + dy, visualBounds.getWidth() * this.fontScale / scale, visualBounds.getHeight() * this.fontScale / scale); return bounds; }
protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int h = getHeight(); int width = getWidth(); Polygon arrow = new Polygon(); // Polygon leftArrow = new Polygon(); // g2.drawImage(closed, PAD, 0, h, h, this); g2.setFont(font); FontRenderContext frc = g2.getFontRenderContext(); LineMetrics lm = font.getLineMetrics(title, frc); float height = lm.getAscent() + lm.getDescent(); float x = OFFSET; float y = (h + height) / 2 - lm.getDescent(); g2.drawString(title, x, y); int th = ((int)height)-2; if (selected) { arrow.addPoint(width - 3*th/2 + 1, h/2 - th/4); arrow.addPoint(width - th/2 - 1, h/2 - th/4); arrow.addPoint(width - th, h/2 + th/4 ); g2.fillPolygon(arrow); } // g2.drawImage(open, PAD, 0, h, h, this); else { arrow.addPoint(width - 3*th/4, h/2 - (th-2)/2); arrow.addPoint(width - 3*th/4, h/2 + (th-2)/2); arrow.addPoint(width - 5*th/4, h /2); g2.fillPolygon(arrow); } }
public PhysicalStrike(Font font, FontFamily family, FontStyle style, FontRenderContext frc){ this.font = font; this.family = family; this.style = style; this.frc = frc; this.size2D = font.getNetFont().get_Size(); this.factor = size2D / family.GetEmHeight(style); }
public static void main(String a[]) { /* prepare blank image */ BufferedImage bi = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) bi.getGraphics(); g2.setColor(Color.WHITE); g2.fillRect(0, 0, 50, 50); /* draw outline somethere in the middle of the image */ FontRenderContext frc = new FontRenderContext(null, false, false); g2.setColor(Color.RED); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); GlyphVector gv = g2.getFont().createGlyphVector(frc, "test"); g2.fill(gv.getOutline(20, 20)); /* Check if anything was drawn. * If y direction is not correct then image is still blank and * test will fail. */ int bgcolor = Color.WHITE.getRGB(); for (int i=0; i<bi.getWidth(); i++) { for(int j=0; j<bi.getHeight(); j++) { if (bi.getRGB(i, j) != bgcolor) { System.out.println("Test passed."); return; } } } throw new RuntimeException("Outline was not detected"); }
/** * Constructs a <code>LineBreakMeasurer</code> for the specified text. * * @param text the text for which this <code>LineBreakMeasurer</code> * produces <code>TextLayout</code> objects; the text must contain * at least one character; if the text available through * <code>iter</code> changes, further calls to this * <code>LineBreakMeasurer</code> instance are undefined (except, * in some cases, when <code>insertChar</code> or * <code>deleteChar</code> are invoked afterward - see below) * @param breakIter the {@link BreakIterator} which defines line * breaks * @param frc contains information about a graphics device which is * needed to measure the text correctly; * text measurements can vary slightly depending on the * device resolution, and attributes such as antialiasing; this * parameter does not specify a translation between the * <code>LineBreakMeasurer</code> and user space * @throws IllegalArgumentException if the text has less than one character * @see LineBreakMeasurer#insertChar * @see LineBreakMeasurer#deleteChar */ public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc) { if (text.getEndIndex() - text.getBeginIndex() < 1) { throw new IllegalArgumentException("Text must contain at least one character."); } this.breakIter = breakIter; this.measurer = new TextMeasurer(text, frc); this.limit = text.getEndIndex(); this.pos = this.start = text.getBeginIndex(); charIter = new CharArrayIterator(measurer.getChars(), this.start); this.breakIter.setText(charIter); }
/** * Estimates the maximum tick label height. * * @param g2 the graphics device. * * @return The maximum height. */ protected double estimateMaximumTickLabelHeight(Graphics2D g2) { RectangleInsets tickLabelInsets = getTickLabelInsets(); double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom(); Font tickLabelFont = getTickLabelFont(); FontRenderContext frc = g2.getFontRenderContext(); result += tickLabelFont.getLineMetrics("123", frc).getHeight(); return result; }
/** * Returns an <mxRectangle> with the size (width and height in pixels) of the given string. * * @param text String whose size should be returned. * @param font Font to be used for the computation. */ public static mxRectangle getSizeForString(String text, Font font, double scale) { FontRenderContext frc = new FontRenderContext(null, false, false); font = font.deriveFont((float) (font.getSize2D() * scale)); FontMetrics metrics = null; if (fontGraphics != null) { metrics = fontGraphics.getFontMetrics(font); } double lineHeight = mxConstants.LINESPACING; if (metrics != null) { lineHeight += metrics.getHeight(); } else { lineHeight += font.getSize2D() * 1.27; } String[] lines = text.split("\n"); Rectangle2D boundingBox = null; if (lines.length == 0) { boundingBox = font.getStringBounds("", frc); } else { for (int i = 0; i < lines.length; i++) { Rectangle2D bounds = font.getStringBounds(lines[i], frc); if (boundingBox == null) { boundingBox = bounds; } else { boundingBox.setFrame(0, 0, Math.max(boundingBox.getWidth(), bounds.getWidth()), boundingBox.getHeight() + lineHeight); } } } return new mxRectangle(boundingBox); }
private void computeDimensions(Graphics g, Font font, FontMetrics fm) { String s = text; FontRenderContext frc = ((Graphics2D) g).getFontRenderContext(); width = fm.stringWidth(s); ascent = fm.getAscent(); descent = fm.getDescent(); int[] xs = new int[s.length()]; int[] ys = new int[s.length()]; for (int i = 0; i < xs.length; i++) { xs[i] = fm.stringWidth(s.substring(0, i + 1)); TextLayout lay = new TextLayout(s.substring(i, i + 1), font, frc); Rectangle2D rect = lay.getBounds(); int asc = (int) Math.ceil(-rect.getMinY()); int desc = (int) Math.ceil(rect.getMaxY()); if (asc < 0) asc = 0; if (asc > 0xFFFF) asc = 0xFFFF; if (desc < 0) desc = 0; if (desc > 0xFFFF) desc = 0xFFFF; ys[i] = (asc << 16) | desc; } charX = xs; charY = ys; dimsKnown = true; }
/** * The length of the metrics array must be >= 4. This method will * store the following elements in that array before returning: * metrics[0]: ascent * metrics[1]: descent * metrics[2]: leading * metrics[3]: max advance */ public void getFontMetrics(Font font, FontRenderContext frc, float metrics[]) { StrikeMetrics strikeMetrics = getStrike(font, frc).getFontMetrics(); metrics[0] = strikeMetrics.getAscent(); metrics[1] = strikeMetrics.getDescent(); metrics[2] = strikeMetrics.getLeading(); metrics[3] = strikeMetrics.getMaxAdvance(); }
/** * Constructs a {@code LineBreakMeasurer} for the specified text. * * @param text the text for which this {@code LineBreakMeasurer} * produces {@code TextLayout} objects; the text must contain * at least one character; if the text available through * {@code iter} changes, further calls to this * {@code LineBreakMeasurer} instance are undefined (except, * in some cases, when {@code insertChar} or * {@code deleteChar} are invoked afterward - see below) * @param breakIter the {@link BreakIterator} which defines line * breaks * @param frc contains information about a graphics device which is * needed to measure the text correctly; * text measurements can vary slightly depending on the * device resolution, and attributes such as antialiasing; this * parameter does not specify a translation between the * {@code LineBreakMeasurer} and user space * @throws IllegalArgumentException if the text has less than one character * @see LineBreakMeasurer#insertChar * @see LineBreakMeasurer#deleteChar */ public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc) { if (text.getEndIndex() - text.getBeginIndex() < 1) { throw new IllegalArgumentException("Text must contain at least one character."); } this.breakIter = breakIter; this.measurer = new TextMeasurer(text, frc); this.limit = text.getEndIndex(); this.pos = this.start = text.getBeginIndex(); charIter = new CharArrayIterator(measurer.getChars(), this.start); this.breakIter.setText(charIter); }
private static void testFontRenderingContext(Object aaHint) { JLabel label = new JLabel("Test"); label.putClientProperty(KEY_TEXT_ANTIALIASING, aaHint); FontRenderContext frc = label.getFontMetrics( label.getFont()).getFontRenderContext(); if (!aaHint.equals(frc.getAntiAliasingHint())) { throw new RuntimeException("Wrong aa hint in FontRenderContext"); } }
public void runTest(Object ctx, int numReps) { TCContext tcctx = (TCContext)ctx; final Font font = tcctx.font; final int[] glyphs = tcctx.glyphs; final FontRenderContext frc = tcctx.frc; GlyphVector gv; do { gv = font.createGlyphVector(frc, glyphs); } while (--numReps >= 0); }
private FontDesignMetrics(Font font, FontRenderContext frc) { super(font); this.font = font; this.frc = frc; this.isAntiAliased = frc.isAntiAliased(); this.usesFractionalMetrics = frc.usesFractionalMetrics(); frcTx = frc.getTransform(); matrix = new double[4]; initMatrixAndMetrics(); initAdvCache(); }
public StandardGlyphVector(Font font, FontRenderContext frc, int[] glyphs, float[] positions, int[] indices, int flags) { initGlyphVector(font, frc, glyphs, positions, indices, flags); // this code should go into layout float track = getTracking(font); if (track != 0) { track *= font.getSize2D(); Point2D.Float trackPt = new Point2D.Float(track, 0); // advance delta if (font.isTransformed()) { AffineTransform at = font.getTransform(); at.deltaTransform(trackPt, trackPt); } // how do we know its a base glyph // for now, it is if the natural advance of the glyph is non-zero Font2D f2d = FontUtilities.getFont2D(font); FontStrike strike = f2d.getStrike(font, frc); float[] deltas = { trackPt.x, trackPt.y }; for (int j = 0; j < deltas.length; ++j) { float inc = deltas[j]; if (inc != 0) { float delta = 0; for (int i = j, n = 0; n < glyphs.length; i += 2) { if (strike.getGlyphAdvance(glyphs[n++]) != 0) { // might be an inadequate test positions[i] += delta; delta += inc; } } positions[positions.length-2+j] += delta; } } } }
/** * Estimates the maximum width of the tick labels, assuming the specified * tick unit is used. * <P> * Rather than computing the string bounds of every tick on the axis, we * just look at two values: the lower bound and the upper bound for the * axis. These two values will usually be representative. * * @param g2 the graphics device. * @param unit the tick unit to use for calculation. * * @return The estimated maximum width of the tick labels. */ private double estimateMaximumTickLabelWidth(Graphics2D g2, DateTickUnit unit) { RectangleInsets tickLabelInsets = getTickLabelInsets(); double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight(); Font tickLabelFont = getTickLabelFont(); FontRenderContext frc = g2.getFontRenderContext(); LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc); if (isVerticalTickLabels()) { // all tick labels have the same width (equal to the height of // the font)... result += lm.getHeight(); } else { // look at lower and upper bounds... DateRange range = (DateRange) getRange(); Date lower = range.getLowerDate(); Date upper = range.getUpperDate(); String lowerStr = null; String upperStr = null; DateFormat formatter = getDateFormatOverride(); if (formatter != null) { lowerStr = formatter.format(lower); upperStr = formatter.format(upper); } else { lowerStr = unit.dateToString(lower); upperStr = unit.dateToString(upper); } FontMetrics fm = g2.getFontMetrics(tickLabelFont); double w1 = fm.stringWidth(lowerStr); double w2 = fm.stringWidth(upperStr); result += Math.max(w1, w2); } return result; }