private LineBreakMeasurer[] getLineBreakMeasurers(Graphics2D g) { if (lbmTexto == null && (Texto != null && !Texto.equals(""))) { lbmTexto = new LineBreakMeasurer[Textos.length]; for (int i = 0; i < lbmTexto.length; i++) { String tmp = Textos[i].isEmpty()? " " : Textos[i]; AttributedString attribString = new AttributedString(tmp); attribString.addAttribute(TextAttribute.FONT, getFont()); //attribString.addAttribute(TextAttribute.FONT, getFont()); AttributedCharacterIterator attribCharIterator = attribString.getIterator(); //FontRenderContext frc = new FontRenderContext(null, true, false); FontRenderContext frc = g.getFontRenderContext(); lbmTexto[i] = new LineBreakMeasurer(attribCharIterator, frc); } } return lbmTexto; }
@Override public Dimension getPreferredSize(JComponent c) { String tipText = ((JToolTip)c).getTipText(); if (tipText == null || tipText.isEmpty()) { return new Dimension(0, 0); } float x = 0f; float y = 0f; for (String line : lineBreak.split(tipText)) { if (line.isEmpty()) { y += LEADING; continue; } AttributedCharacterIterator styledText = new AttributedString(line).getIterator(); LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc); while (measurer.getPosition() < styledText.getEndIndex()) { TextLayout layout = measurer.nextLayout(maximumWidth); x = Math.max(x, layout.getVisibleAdvance()); y += layout.getAscent() + layout.getDescent() + layout.getLeading(); } } return new Dimension((int) (x + 2 * margin), (int) (y + 2 * margin)); }
protected int measureExactLineBreakIndex(float width, int endLimit, boolean requireWord) { //FIXME would it be faster to create and cache a LineBreakMeasurer for the whole paragraph? Map<Attribute, Object> attributes = new HashMap<Attribute, Object>(); // we only need the font as it includes the size and style attributes.put(TextAttribute.FONT, fontInfo.fontInfo.font); String textLine = paragraphText.substring(paragraphPosition, endLimit); AttributedString attributedLine = new AttributedString(textLine, attributes); // we need a fresh iterator for the line BreakIterator breakIterator = paragraphTruncateAtChar ? BreakIterator.getCharacterInstance() : BreakIterator.getLineInstance(); LineBreakMeasurer breakMeasurer = new LineBreakMeasurer(attributedLine.getIterator(), breakIterator, context.getFontRenderContext()); int breakIndex = breakMeasurer.nextOffset(width, endLimit - paragraphPosition, requireWord) + paragraphPosition; if (logTrace) { log.trace("exact line break index measured at " + (paragraphOffset + breakIndex)); } return breakIndex; }
private static void drawTextInBoundedArea(Graphics2D g2d, int x1, int y1, int x2, int y2, String text) { float interline = 1; float width = x2 - x1; AttributedString as = new AttributedString(text); as.addAttribute(TextAttribute.FOREGROUND, g2d.getPaint()); as.addAttribute(TextAttribute.FONT, g2d.getFont()); AttributedCharacterIterator aci = as.getIterator(); FontRenderContext frc = new FontRenderContext(null, true, false); LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); while (lbm.getPosition() < text.length()) { TextLayout tl = lbm.nextLayout(width); y1 += tl.getAscent(); tl.draw(g2d, x1, y1); y1 += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl. getAscent(); if (y1 > y2) { break; } } }
private final static void pixelDataFromString(int width, int height, String str, java.awt.Font font, int[] pixels, LineBreakMeasurer measurer) { measurer.setPosition(0); g2d.clearRect(0, 0, width, height); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); float wrapping_width = width; float y = 0; int length = str.length(); while (measurer.getPosition() < length) { TextLayout layout = measurer.nextLayout(wrapping_width); y += (layout.getAscent()); float x = layout.isLeftToRight() ? 0 : (wrapping_width - layout.getAdvance()); layout.draw(g2d, x, y); y += layout.getDescent() + layout.getLeading(); } image.getRaster().getDataElements(0, 0, image.getWidth(), image.getHeight(), pixels); }
/** * @param wrappingWidth width of the layout * @param frCtx for possible new instance of LineBreakMeasurer * @return next TextLayout that is to be rendered */ private TextLayout nextLayout(float wrappingWidth, FontRenderContext frc) { TextLayout l; if (currentLayout == textLayouts.size()) { LineBreakMeasurer old = lineBreakMeasurer; LineBreakMeasurer measurer = getMeasurer(frc); if (measurer == null) { return null; } l = measurer.nextLayout(wrappingWidth); textLayouts.add(l); if (old != measurer) { // new line startLayouts.add(l); } } else { l = (TextLayout) textLayouts.get(currentLayout); } currentLayout++; // advance to next return l; }
private void drawText(Graphics2D g2, String text, float width) { FontRenderContext frc = g2.getFontRenderContext(); AttributedString styledText = new AttributedString(text); AttributedCharacterIterator aci = styledText.getIterator(); int start = aci.getBeginIndex(); int end = aci.getEndIndex(); LineBreakMeasurer measurer = new LineBreakMeasurer(aci, frc); measurer.setPosition(start); float x = 0, y = 0; while (measurer.getPosition() < end) { TextLayout layout = measurer.nextLayout(width); y += layout.getAscent(); float dx = layout.isLeftToRight() ? 0 : width - layout.getAdvance(); layout.draw(g2, x + dx, y); y += layout.getDescent() + layout.getLeading(); } }
private String wrapLines(String s, float wrappingWidth, FontRenderContext frc, String lineBreak) { AttributedCharacterIterator aci = new AttributedString(s).getIterator(); int end = aci.getEndIndex(); LineBreakMeasurer measurer = new LineBreakMeasurer(aci, frc); StringBuffer output = new StringBuffer(); int position = 0; int lastPosition = 0; do { measurer.nextLayout(wrappingWidth); position = measurer.getPosition(); output.append(s, lastPosition, position); output.append(lineBreak); lastPosition = position; } while (position < end); return output.toString(); }
@Override public void setFont(Font f) { super.setFont(f); atText.addAttribute(TextAttribute.FONT, usesSpecificFont() ? getFont() : getMainFont()); lbm = new LineBreakMeasurer(atText.getIterator(), DEFAULT_FRC); invalidate(); }
public Dimension getPreferredSize(JComponent c) { String tipText = ((JToolTip)c).getTipText(); if (tipText == null) { return new Dimension(0, 0); } float x = 0f; float y = 0f; for (String line : lineBreak.split(((JToolTip) c).getTipText())) { AttributedCharacterIterator styledText = new AttributedString(line).getIterator(); LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc); while (measurer.getPosition() < styledText.getEndIndex()) { TextLayout layout = measurer.nextLayout(maximumWidth); x = Math.max(x, layout.getVisibleAdvance()); y += layout.getAscent() + layout.getDescent() + layout.getLeading(); } } return new Dimension((int) (x + 2 * margin), (int) (y + 2 * margin)); }
private static int countLines(JTextArea textArea) { AttributedString text = new AttributedString(textArea.getText()); FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()).getFontRenderContext(); AttributedCharacterIterator charIt = text.getIterator(); LineBreakMeasurer lbm = new LineBreakMeasurer(charIt, frc); float formatWidth = (float) textArea.getSize().width; lbm.setPosition(charIt.getBeginIndex()); int numLines =0; while (lbm.getPosition()<charIt.getEndIndex()) { lbm.nextLayout(formatWidth); numLines++; } return numLines; }
private Dimension paintOrGetSize(Graphics2D g, int width) { Insets insets = getInsets(); width -= insets.left + insets.right + margin.left + margin.right; float w = insets.left + insets.right + margin.left + margin.right; float x = insets.left + margin.left, y = insets.top + margin.top; if (width > 0 && text != null && text.length() > 0) { AttributedString as = new AttributedString(getText()); as.addAttribute(TextAttribute.FONT, getFont()); AttributedCharacterIterator aci = as.getIterator(); LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); float max = 0; while (lbm.getPosition() < aci.getEndIndex()) { TextLayout textLayout = lbm.nextLayout(width); if (g != null && isJustified() && textLayout.getVisibleAdvance() > 0.80 * width) textLayout = textLayout.getJustifiedLayout(width); if (g != null) textLayout.draw(g, x, y + textLayout.getAscent()); y += textLayout.getDescent() + textLayout.getLeading() + textLayout.getAscent(); max = Math.max(max, textLayout.getVisibleAdvance()); } w += max; } return new Dimension((int)Math.ceil(w), (int)Math.ceil(y) + insets.bottom + margin.bottom); }
@Override public void render(final Graphics2D g) { if (this.displayedText == null || this.displayedText.isEmpty() || !Game.getRenderEngine().canRender(this.entity)) { return; } final Point2D location = Game.getCamera().getViewPortLocation(this.entity); RenderEngine.renderImage(g, this.bubble, new Point2D.Double(location.getX() + this.entity.getWidth() / 2.0 - this.textBoxWidth / 2.0 - PADDING, location.getY() - this.height - PADDING)); g.setColor(SPEAK_FONT_COLOR); final FontRenderContext frc = g.getFontRenderContext(); final String text = this.displayedText; final AttributedString styledText = new AttributedString(text); styledText.addAttribute(TextAttribute.FONT, this.font); final AttributedCharacterIterator iterator = styledText.getIterator(); final LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, frc); measurer.setPosition(0); final float x = (float) Game.getCamera().getViewPortLocation(this.entity).getX() + this.entity.getWidth() / 2.0f - this.textBoxWidth / 2.0f; float y = (float) Game.getCamera().getViewPortLocation(this.entity).getY() - this.height; while (measurer.getPosition() < text.length()) { final TextLayout layout = measurer.nextLayout(this.textBoxWidth); y += layout.getAscent(); final float dx = layout.isLeftToRight() ? 0 : this.textBoxWidth - layout.getAdvance(); layout.draw(g, x + dx, y); y += layout.getDescent() + layout.getLeading(); } }
@Override public void paint(Graphics g, JComponent c) { if (c.isOpaque()) { ImageLibrary.drawTiledImage("image.background.FreeColToolTip", g, c, null); } g.setColor(Color.BLACK); // FIXME: find out why this is necessary Graphics2D graphics = (Graphics2D)g; float x = margin; float y = margin; for (String line : lineBreak.split(((JToolTip) c).getTipText())) { if (line.isEmpty()) { y += LEADING; continue; } AttributedCharacterIterator styledText = new AttributedString(line).getIterator(); LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc); while (measurer.getPosition() < styledText.getEndIndex()) { TextLayout layout = measurer.nextLayout(maximumWidth); y += (layout.getAscent()); float dx = layout.isLeftToRight() ? 0 : (maximumWidth - layout.getAdvance()); layout.draw(graphics, x + dx, y); y += layout.getDescent() + layout.getLeading(); } } }
public void test() { // construct a paragraph as follows: MIXED + [SPACING + WORD] + ... StringBuffer text = new StringBuffer(MIXED); for (int i=0; i < NUM_WORDS; i++) { text.append(SPACING); text.append(WORD); } AttributedString attrString = new AttributedString(text.toString()); attrString.addAttribute(TextAttribute.SIZE, new Float(24.0)); LineBreakMeasurer measurer = new LineBreakMeasurer(attrString.getIterator(), DEFAULT_FRC); // get width of a space-word sequence, in context int sequenceLength = WORD.length()+SPACING.length(); measurer.setPosition(text.length() - sequenceLength); TextLayout layout = measurer.nextLayout(10000.0f); if (layout.getCharacterCount() != sequenceLength) { throw new Error("layout length is incorrect!"); } final float sequenceAdvance = layout.getVisibleAdvance(); float wrappingWidth = sequenceAdvance * 2; // now run test with a variety of widths while (wrappingWidth < (sequenceAdvance*NUM_WORDS)) { measurer.setPosition(0); checkMeasurer(measurer, wrappingWidth, sequenceAdvance, text.length()); wrappingWidth += sequenceAdvance / 5; } }
/** * Iterate through measurer and check that every line is * not too long and not too short, but just right. */ private void checkMeasurer(LineBreakMeasurer measurer, float wrappingWidth, float sequenceAdvance, int endPosition) { do { TextLayout layout = measurer.nextLayout(wrappingWidth); float visAdvance = layout.getVisibleAdvance(); // Check that wrappingWidth-sequenceAdvance < visAdvance // Also, if we're not at the end of the paragraph, // check that visAdvance <= wrappingWidth if (visAdvance > wrappingWidth) { // line is too long for given wrapping width throw new Error("layout is too long"); } if (measurer.getPosition() < endPosition) { if (visAdvance <= wrappingWidth - sequenceAdvance) { // line is too short for given wrapping width; // another word would have fit throw new Error("room for more words on line. diff=" + (wrappingWidth - sequenceAdvance - visAdvance)); } } } while (measurer.getPosition() != endPosition); }
private static void drawString(Graphics2D g, Font font, String value, float x, float y) { AttributedString str = new AttributedString(value); str.addAttribute(TextAttribute.FOREGROUND, Color.BLACK); str.addAttribute(TextAttribute.FONT, font); FontRenderContext frc = new FontRenderContext(null, true, true); TextLayout layout = new LineBreakMeasurer(str.getIterator(), frc).nextLayout(Integer.MAX_VALUE); layout.draw(g, x, y); }
public void setHorizontalLineBreakMeasurer(LineBreakMeasurer designatedHorizontalLineBreakMeasurer) throws IllegalArgumentException { if (designatedHorizontalLineBreakMeasurer!=null && verticalLineBreakMeasurer!=null) throw new IllegalArgumentException(NOT_BOTH_ERROR_MESSAGE); horizontalLineBreakMeasurer = designatedHorizontalLineBreakMeasurer; }
/** * Returns the {@link Dimension} for the given {@link JTextComponent} * subclass that will show the whole word wrapped text in the given width. * It won't work for styled text of varied size or style, it's assumed that * the whole text is rendered with the {@link JTextComponent}s font. * * @param textComponent the {@link JTextComponent} to calculate the {@link Dimension} for * @param width the width of the resulting {@link Dimension} * @param text the {@link String} which should be word wrapped * @return The calculated {@link Dimension} */ public static Dimension getWordWrappedTextDimension(JTextComponent textComponent, int width, String text) { if (textComponent == null) { throw new IllegalArgumentException("textComponent cannot be null"); } if (width < 1) { throw new IllegalArgumentException("width must be 1 or greater"); } if (text == null) { text = textComponent.getText(); } if (text.isEmpty()) { return new Dimension(width, 0); } FontMetrics metrics = textComponent.getFontMetrics(textComponent.getFont()); FontRenderContext rendererContext = metrics.getFontRenderContext(); float formatWidth = width - textComponent.getInsets().left - textComponent.getInsets().right; int lines = 0; String[] paragraphs = text.split("\n"); for (String paragraph : paragraphs) { if (paragraph.isEmpty()) { lines++; } else { AttributedString attributedText = new AttributedString(paragraph); attributedText.addAttribute(TextAttribute.FONT, textComponent.getFont()); AttributedCharacterIterator charIterator = attributedText.getIterator(); LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIterator, rendererContext); lineMeasurer.setPosition(charIterator.getBeginIndex()); while (lineMeasurer.getPosition() < charIterator.getEndIndex()) { lineMeasurer.nextLayout(formatWidth); lines++; } } } return new Dimension(width, metrics.getHeight() * lines + textComponent.getInsets().top + textComponent.getInsets().bottom); }
private ArrayList extractLineBreaks(final AttributedCharacterIterator itr, final LineBreakMeasurer measurer) { ArrayList breakList; breakList = new ArrayList(); while (measurer.getPosition() < itr.getEndIndex()) { if (constrainWidthToTextWidth) { measurer.nextLayout(Float.MAX_VALUE); } else { measurer.nextLayout((float) Math.ceil(getWidth() - insets.left - insets.right)); } breakList.add(new Integer(measurer.getPosition())); } return breakList; }
protected void startParagraph(AttributedCharacterIterator paragraph, boolean truncateAtChar) { this.paragraph = paragraph; BreakIterator breakIt = truncateAtChar ? BreakIterator.getCharacterInstance() : BreakIterator.getLineInstance(); lineMeasurer = new LineBreakMeasurer(paragraph, breakIt, context.getFontRenderContext()); }
@Override public TextLine baseTextLine(int index) { AttributedString tmpText = new AttributedString(paragraph, index, index + 1); LineBreakMeasurer lbm = new LineBreakMeasurer(tmpText.getIterator(), context.getFontRenderContext()); TextLayout tlyt = lbm.nextLayout(100);//FIXME what is this? why 100? return new TextLayoutLine(tlyt); }
@Override public void paint(Graphics g, JComponent c) { Graphics2D g2 = (Graphics2D)g.create(); try { if(icon!=null) { Dimension d = icon.getPreferredSize(c.getWidth()*3/4, c.getHeight()*3/4); icon.paintIcon(c, g2, c.getWidth()/2 - d.width/2, c.getHeight()/2 - d.height/2, d.width, d.height); } g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); if(attrString!=null) { float y = 0; for(int a = 0; a<attrString.length; a++) { LineBreakMeasurer lbm = new LineBreakMeasurer(attrString[a].getIterator(), g2.getFontRenderContext()); TextLayout tl = lbm.nextLayout(c.getWidth()); while(tl!=null) { y += tl.getAscent(); tl.draw(g2, 0, y); y += tl.getDescent() + tl.getLeading(); tl = lbm.nextLayout(c.getWidth()); } } } if(mouseInside) { g2.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10, new float[] {4, 4}, 0)); g2.draw(new Rectangle(0, 0, c.getWidth(), c.getHeight())); } } finally { g2.dispose(); } }
public TextBoxPaintable(String string,Font font,float maxWidth,float insets,Paint paint) { if(paint==null) paint = SystemColor.textText; this.insets = insets; this.text = string; this.paint = paint; List<String> lines = new ArrayList<String>(); Map<TextAttribute, Object> attributes = new HashMap<TextAttribute, Object>(); attributes.put( TextAttribute.FONT, font); AttributedString attrString = new AttributedString(string, attributes); LineBreakMeasurer lbm = new LineBreakMeasurer( attrString.getIterator(), frc); TextLayout tl = lbm.nextLayout(maxWidth); float dy = 0; GeneralPath path = new GeneralPath(); int startIndex = 0; while(tl!=null) { path.append( tl.getOutline( AffineTransform.getTranslateInstance(0, dy) ), false ); dy += tl.getAscent()+tl.getDescent()+tl.getLeading(); int charCount = tl.getCharacterCount(); lines.add( text.substring(startIndex, startIndex+charCount) ); startIndex += charCount; tl = lbm.nextLayout(maxWidth); } this.lines = lines.toArray(new String[lines.size()]); untransformedShape = path; Rectangle2D b = ShapeBounds.getBounds(untransformedShape); b.setFrame(b.getX(), b.getY(), b.getWidth() + 2*insets, b.getHeight() + 2*insets); untransformedBounds = b.getBounds(); }
public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) { float interline = 1.0f; // text if (text != null && text.length() > 0) { Paint originalPaint = g.getPaint(); Font originalFont = g.getFont(); g.setPaint(LABEL_COLOR); g.setFont(LABEL_FONT); int wrapWidth = 100; int textY = (int) graphicInfo.getY(); // TODO: use drawMultilineText() AttributedString as = new AttributedString(text); as.addAttribute(TextAttribute.FOREGROUND, g.getPaint()); as.addAttribute(TextAttribute.FONT, g.getFont()); AttributedCharacterIterator aci = as.getIterator(); FontRenderContext frc = new FontRenderContext(null, true, false); LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); while (lbm.getPosition() < text.length()) { TextLayout tl = lbm.nextLayout(wrapWidth); textY += tl.getAscent(); Rectangle2D bb = tl.getBounds(); double tX = graphicInfo.getX(); if (centered) { tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2); } tl.draw(g, (float) tX, textY); textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent(); } // restore originals g.setFont(originalFont); g.setPaint(originalPaint); } }
public static JavaTextLayout[] layoutText (JavaGraphics gfx, String text, TextFormat format, TextWrap wrap) { // normalize newlines in the text (Windows: CRLF -> LF, Mac OS pre-X: CR -> LF) text = normalizeEOL(text); // we do some fiddling to work around the fact that TextLayout chokes on the empty string String ltext = text.length() == 0 ? " " : text; // set up an attributed character iterator so that we can measure the text AttributedString astring = new AttributedString(ltext); if (format.font != null) { astring.addAttribute(TextAttribute.FONT, gfx.resolveFont(format.font)); } List<JavaTextLayout> layouts = new ArrayList<JavaTextLayout>(); FontRenderContext frc = format.antialias ? gfx.aaFontContext() : gfx.aFontContext(); LineBreakMeasurer measurer = new LineBreakMeasurer(astring.getIterator(), frc); int lastPos = ltext.length(), curPos = 0; char eol = '\n'; while (curPos < lastPos) { int nextRet = ltext.indexOf(eol, measurer.getPosition()+1); if (nextRet == -1) { nextRet = lastPos; } TextLayout layout = measurer.nextLayout(wrap.width, nextRet, false); int endPos = measurer.getPosition(); while (curPos < endPos && ltext.charAt(curPos) == eol) curPos += 1; // skip over EOLs layouts.add(new JavaTextLayout(ltext.substring(curPos, endPos), format, layout)); curPos = endPos; } return layouts.toArray(new JavaTextLayout[layouts.size()]); }
private int getStringWidth(AttributedCharacterIterator s) { FontRenderContext fontRenderContext = g.getFontRenderContext(); LineBreakMeasurer lbm = new LineBreakMeasurer(s, fontRenderContext); TextLayout textLayout = lbm.nextLayout(Integer.MAX_VALUE); if (textLayout == null) return 0; return (int) textLayout.getBounds().getWidth(); }
/** * Calculates the layout. * @param fontRenderContext the FontRenderContext * @param font the Font * @param text the text * @param layoutWidth the width of the layout area * @return the layout result */ public MultilineLayout calculateLayout(FontRenderContext fontRenderContext, Font font, String text, double layoutWidth) { // Layout multiline text MultilineLayout result = new MultilineLayout(); if (text == null || text.isEmpty()) return result; Map<TextAttribute, Object> styleMap = new HashMap<TextAttribute, Object>(); styleMap.put(TextAttribute.FONT, font); String[] textlines = text.split("\n"); double height = 0; for (String textline : textlines) { AttributedString attribText = new AttributedString(textline, styleMap); AttributedCharacterIterator iter = attribText.getIterator(); int textStart = iter.getBeginIndex(); int textEnd = iter.getEndIndex(); LineBreakMeasurer measurer = new LineBreakMeasurer(iter, fontRenderContext); measurer.setPosition(textStart); while (measurer.getPosition() < textEnd) { TextLayout line = measurer.nextLayout((float) layoutWidth); result.addLine(line); height += (line.getAscent() + line.getDescent() + line.getLeading()); } } result.setSize(layoutWidth, height); return result; }
double getWidthOfAttributedString(Graphics2D graphics2D, AttributedString attributedString) { AttributedCharacterIterator characterIterator = attributedString.getIterator(); FontRenderContext fontRenderContext = graphics2D.getFontRenderContext(); LineBreakMeasurer lbm = new LineBreakMeasurer(characterIterator, fontRenderContext); TextLayout textLayout = lbm.nextLayout(Integer.MAX_VALUE); return textLayout.getBounds().getWidth(); }
public MultilineText(String text) { super(text); atText = new AttributedString(text); atText.addAttribute(TextAttribute.FONT, usesSpecificFont() ? getFont() : getMainFont()); lbm = new LineBreakMeasurer(atText.getIterator(), DEFAULT_FRC); }
public void paint(Graphics g, JComponent c) { if (c.isOpaque()) { ImageLibrary.drawTiledImage("background.FreeColToolTip", g, c, null); } // TODO: find out why this is necessary g.setColor(Color.BLACK); Graphics2D graphics = (Graphics2D) g; float x = margin; float y = margin; for (String line : lineBreak.split(((JToolTip) c).getTipText())) { AttributedCharacterIterator styledText = new AttributedString(line).getIterator(); LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc); while (measurer.getPosition() < styledText.getEndIndex()) { TextLayout layout = measurer.nextLayout(maximumWidth); y += (layout.getAscent()); float dx = layout.isLeftToRight() ? 0 : (maximumWidth - layout.getAdvance()); layout.draw(graphics, x + dx, y); y += layout.getDescent() + layout.getLeading(); } } }
void rescale(double scale) { Rectangle bounds = getBounds(scale); HashMap settings = new HashMap(); settings.put(TextAttribute.FONT, new Font(style.getFontAttributes(scale))); AttributedCharacterIterator par = (new AttributedString(element.getAttribute("text"), settings)).getIterator(); LineBreakMeasurer lbm = new LineBreakMeasurer(par, new FontRenderContext(null, false, false)); ArrayList drawList = new ArrayList(); int parEnd = par.getEndIndex(); int positionX; int positionY = bounds.y; lbm.setPosition(par.getBeginIndex()); while (lbm.getPosition() < parEnd) { TextLayout layout = lbm.nextLayout(bounds.width); positionX = bounds.x; if (!layout.isLeftToRight()) { positionX += bounds.width - (int) layout.getAdvance(); } positionY += layout.getAscent(); if (positionY > bounds.y+bounds.height) break; drawList.add(new Point(positionX, positionY)); drawList.add(layout); positionY += layout.getDescent() + layout.getLeading(); } textPositions = new Point[drawList.size()/2]; textLines = new TextLayout[drawList.size()/2]; textScale = scale; for (int i = 0; i < textPositions.length; i++) { textPositions[i] = (Point) drawList.get(i*2); textLines[i] = (TextLayout) drawList.get(i*2+1); } }
void rescale(double scale) { Rectangle bounds = getBounds(scale); HashMap settings = new HashMap(); settings.put(TextAttribute.FONT, new Font(style.getFontAttributes(scale * Integer.parseInt(element.getAttribute("size"))))); AttributedCharacterIterator par = (new AttributedString(element.getAttribute("text"), settings)).getIterator(); LineBreakMeasurer lbm = new LineBreakMeasurer(par, new FontRenderContext(null, false, false)); ArrayList drawList = new ArrayList(); int parEnd = par.getEndIndex(); int positionX; int positionY = bounds.y; lbm.setPosition(par.getBeginIndex()); while (lbm.getPosition() < parEnd) { TextLayout layout = lbm.nextLayout(bounds.width); positionX = bounds.x; if (!layout.isLeftToRight()) { positionX += bounds.width - (int) layout.getAdvance(); } positionY += layout.getAscent(); if (positionY > bounds.y+bounds.height) break; drawList.add(new Point(positionX, positionY)); drawList.add(layout); positionY += layout.getDescent() + layout.getLeading(); } textPositions = new Point[drawList.size()/2]; textLines = new TextLayout[drawList.size()/2]; textScale = scale; for (int i = 0; i < textPositions.length; i++) { textPositions[i] = (Point) drawList.get(i*2); textLines[i] = (TextLayout) drawList.get(i*2+1); } }
private void createBubbleImage() { final BufferedImage img = ImageProcessing.getCompatibleImage(500, 500); final Graphics2D g = img.createGraphics(); g.setFont(this.font); final int stringWidth = g.getFontMetrics().stringWidth(this.currentText); if (stringWidth < this.textBoxWidth) { this.textBoxWidth = stringWidth; } final FontRenderContext frc = g.getFontRenderContext(); final AttributedString styledText = new AttributedString(this.currentText); styledText.addAttribute(TextAttribute.FONT, this.font); final AttributedCharacterIterator iterator = styledText.getIterator(); final LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, frc); measurer.setPosition(0); float y = 0; while (measurer.getPosition() < this.currentText.length()) { final TextLayout layout = measurer.nextLayout(this.textBoxWidth); y += layout.getAscent() + layout.getLeading() + 0.2; } final RoundRectangle2D bounds = new RoundRectangle2D.Double(0, 0, this.textBoxWidth + 2 * PADDING, y + 2 * PADDING, PADDING, PADDING); // Build a path final GeneralPath path = new GeneralPath(); path.moveTo(bounds.getWidth() / 2.0 - TRIANGLE_SIZE / 2.0, bounds.getHeight()); path.lineTo(bounds.getWidth() / 2.0, bounds.getHeight() + TRIANGLE_SIZE); path.lineTo(bounds.getWidth() / 2.0 + TRIANGLE_SIZE / 2.0, bounds.getHeight()); path.closePath(); final Area ar = new Area(bounds); ar.add(new Area(path)); int width = ar.getBounds().width; this.height = ar.getBounds().height; g.setColor(SPEAK_BACKGROUNDCOLOR); g.fill(ar); g.setColor(SPEAK_BORDERCOLOR); g.draw(ar); g.dispose(); this.bubble = ImageProcessing.crop(img, ImageProcessing.CROP_ALIGN_LEFT, ImageProcessing.CROP_VALIGN_TOP, width + 1, this.height + 1); }