📄 textrender.java
字号:
/**
* $Id:TextRender.java $
*
* Copyright 2004 ~ 2005 JingFei International Cooperation LTD. All rights reserved. *
*/
package com.jfimagine.jfgraph.shape.decorate;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.util.Hashtable;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
import com.jfimagine.jfgraph.geom.Rect;
import com.jfimagine.utils.commonutil.CommonUtil;
import com.jfimagine.jfgraph.shape.rectangle.JFText;
/**
* TextRender class. TextRender is a class to encapsulate text processing.
*
* @author CookieMaker
*
* @version $Revision: 1.00 $
*/
public class TextRender {
// The LineBreakMeasurer used to line-break the paragraph.
private LineBreakMeasurer lineMeasurer;
// The index in the LineBreakMeasurer of the first character
// in the paragraph.
private int paragraphStart;
// The index in the LineBreakMeasurer of the first character
// after the end of the paragraph.
private int paragraphEnd;
//occurrence position of a new line char.
int[] lineLocations = new int[0];
/**
* Initialize render string.
* @param g The graphics context to draw string
* @param lines The string lines.
* @param fontFormat the specified font format.
*/
private void initRender(Graphics g, String lines, FontFormat fontFormat){
if (lines==null || lines.length()==0) lines=" ";
//if the first letter of the text is just a NewLine character,
//append a space at the head of this text, to avoid text drawing error.
if (lines.charAt(0)==CommonUtil.newLine())
lines =' '+lines;
//set rendering text font by current graphics context's font.
Hashtable map = new Hashtable();
map.put(TextAttribute.FONT,fontFormat.getZoomedFont());
AttributedString aString = new AttributedString(lines,map);
AttributedCharacterIterator paragraph=aString.getIterator();
//FontRenderContext frc = getDefaultFontRenderContext();
Graphics2D g2 =(Graphics2D)g;
FontRenderContext frc = g2.getFontRenderContext();
paragraphStart = paragraph.getBeginIndex();
paragraphEnd = paragraph.getEndIndex();
// Create a new LineBreakMeasurer from the paragraph.
lineMeasurer = new LineBreakMeasurer(paragraph,frc);
// create a line break(broken by new line char)position array
int lineCount =CommonUtil.getCharCount(lines,CommonUtil.newLine());
lineLocations = new int[lineCount+1];
int i=0;
if (lineCount>0){
for (char c = paragraph.first(); c != paragraph.DONE; c = paragraph.next()) {
if (c == CommonUtil.newLine()) {
lineLocations[i] = paragraph.getIndex();
i++;
}
}
}
lineLocations[lineCount] = paragraph.getEndIndex();
}
/**
* Draw multiple lines string in a rectangle.
* @param g A graphics context.
* @param rect A rectangle used to specify the position and size of lines.
* @param lines String lines to be drawn.
* @param fontFormat the specified font format for text rendering.
* @param textAlignment the alignment type
*/
public void drawMultiLines(Graphics g, Rect rect, String lines,FontFormat fontFormat,int textAlignment) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
//initialize render text.
initRender(g,lines,fontFormat);
// Set formatting width and height to rectangle.
float formatX = (float) rect.getX();
float formatY = (float) rect.getY();
float formatWidth = (float) rect.getWidth();
float formatHeight = (float) rect.getHeight();
float drawPosY = formatY;
lineMeasurer.setPosition(paragraphStart);
int currentLine = 0;
// Get lines from lineMeasurer until the entire
// paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// lineContainsText is true after first segment is drawn
boolean lineContainsText = false;
TextLayout layout;
while (true) {
// Retrieve next layout.
try{
layout = lineMeasurer.nextLayout(formatWidth,
lineLocations[currentLine],
lineContainsText);
}catch(Exception e){
//System.out.println("error at "+currentLine+" "+e.getMessage());
return;
}
// layout can be null if lineContainsText is true
if (layout != null) {
float height =(float)layout.getBounds().getHeight();
float width =(float)layout.getBounds().getWidth();
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
if (drawPosY - formatY>formatHeight)
break;
// Compute pen x position. If the paragraph is
// right-to-left, we want to align the TextLayouts
// to the right edge of the panel.
float drawPosX = formatX;
switch (textAlignment){
case JFText.TEXTALIGNMENT_LEFT:
drawPosX += 0;
break;
case JFText.TEXTALIGNMENT_RIGHT:
drawPosX += (float)(formatWidth - width);
break;
case JFText.TEXTALIGNMENT_MIDDLE:
drawPosX += (float)((formatWidth - width)/2);
break;
}
if (fontFormat.isUseStrokeAndFill()){
AffineTransform textAt = new AffineTransform();
textAt.translate(0, height);
java.awt.Shape shape = layout.getOutline(textAt);
drawTextShape(g,shape,drawPosX,(float)(drawPosY-height),fontFormat);
}else{
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2, drawPosX, drawPosY);
}
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}else{
break;
}
lineContainsText = true;
if (lineMeasurer.getPosition() == paragraphEnd)
break;
if (lineMeasurer.getPosition() == lineLocations[currentLine])
currentLine++;
if (currentLine>lineLocations.length-1)
break;
}
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
/***
* Draw a stroke and fill text according to the font format
*
* @param g The graphics context
* @param s The text to be drawn
* @param x,y The position to draw the string
* @param fontFormat The font format of the text
* @param zoomScale Current zoom scale
*/
public static void drawStrokeAndFillText(Graphics g, String s, float x, float y, FontFormat fontFormat, double zoomScale){
if (g==null || s==null || s.length()==0 || fontFormat==null || !fontFormat.isUseStrokeAndFill())
return;
TextLayout textTl = new TextLayout(s, fontFormat.getZoomedFont(), new FontRenderContext(null, false, false));
AffineTransform textAt = new AffineTransform();
textAt.translate(0, (float)textTl.getBounds().getHeight());
java.awt.Shape shape = textTl.getOutline(textAt);
drawTextShape(g,shape,x,y,fontFormat);
}
/***
* Draw a shape made by a text layout.
*
* @param g The graphics context
* @param s The shape to be drawn
* @param x,y The position to draw the string
* @param fontFormat The font format of the text
*/
private static void drawTextShape(Graphics g, java.awt.Shape s, float x, float y, FontFormat fontFormat){
Graphics2D g2 =(Graphics2D)g;
Rectangle2D rect2D =s.getBounds2D();
Rect rect =new Rect(rect2D.getX(),rect2D.getY(),rect2D.getWidth(),rect2D.getHeight());
//rect.moveBy(x,y);
g2.translate(x,y);
GeneralPath path =new GeneralPath(s);
fontFormat.getLineFormat().draw(g,path);
fontFormat.getFillFormat().draw(g,path,rect);
g2.translate(-x,-y);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -