package ij.gui;
import ij.*;
import ij.process.*;
import ij.util.*;
import ij.macro.Interpreter;
import ij.plugin.frame.Recorder;
import ij.plugin.Colors;
import java.awt.geom.*;
import java.awt.*;
/** This class is a rectangular ROI containing text. */
public class TextRoi extends Roi {
public static final int LEFT=0, CENTER=1, RIGHT=2;
static final int MAX_LINES = 50;
private static final String line1 = "Enter text, then press";
private static final String line2 = "ctrl+b to add to overlay";
private static final String line3 = "or ctrl+d to draw.";
private static final String line1a = "Enter text...";
private String[] theText = new String[MAX_LINES];
private static String name = "SansSerif";
private static int style = Font.PLAIN;
private static int size = 18;
private Font instanceFont;
private static boolean newFont = true;
private static boolean antialiasedText = true; // global flag used by text tool
private static int globalJustification;
private static Color defaultFillColor;
private int justification;
private boolean antialiased = antialiasedText;
private double previousMag;
private boolean firstChar = true;
private boolean firstMouseUp = true;
private int cline = 0;
private boolean drawStringMode;
private double angle; // degrees
private static double defaultAngle;
private static boolean firstTime = true;
/** Creates a TextRoi.*/
public TextRoi(int x, int y, String text) {
super(x, y, 1, 1);
init(text, null);
}
/** Use this constructor as a drop-in replacement for ImageProcessor.drawString(). */
public TextRoi(String text, double x, double y, Font font) {
super(x, y, 1, 1);
drawStringMode = true;
if (text!=null && text.contains("\n")) {
String[] lines = Tools.split(text, "\n");
int count = Math.min(lines.length, MAX_LINES);
for (int i=0; i1.0)
mag = 1.0;
if (size<(12/mag))
size = (int)(12/mag);
if (firstTime) {
theText[0] = line1;
theText[1] = line2;
theText[2] = line3;
firstTime = false;
} else
theText[0] = line1a;
if (previousRoi!=null && (previousRoi instanceof TextRoi)) {
firstMouseUp = false;
previousRoi = null;
}
instanceFont = new Font(name, style, size);
justification = globalJustification;
setStrokeColor(Toolbar.getForegroundColor());
if (WindowManager.getWindow("Fonts")!=null) {
setFillColor(defaultFillColor);
setAngle(defaultAngle);
}
}
/** This method is used by the text tool to add typed
characters to displayed text selections. */
public void addChar(char c) {
if (imp==null) return;
if (!(c>=' ' || c=='\b' || c=='\n')) return;
if (firstChar) {
cline = 0;
theText[cline] = new String("");
for (int i=1; i0)
theText[cline] = theText[cline].substring(0, theText[cline].length()-1);
else if (cline>0) {
theText[cline] = null;
cline--;
}
if (angle!=0.0)
imp.draw();
else
imp.draw(clipX, clipY, clipWidth, clipHeight);
firstChar = false;
return;
} else if ((int)c=='\n') {
// newline
if (cline<(MAX_LINES-1)) cline++;
theText[cline] = "";
updateBounds(null);
updateText();
} else {
char[] chr = {c};
theText[cline] += new String(chr);
updateBounds(null);
updateText();
firstChar = false;
return;
}
}
Font getScaledFont() {
if (nonScalable)
return instanceFont;
else {
if (instanceFont==null)
instanceFont = new Font(name, style, size);
double mag = getMagnification();
return instanceFont.deriveFont((float)(instanceFont.getSize()*mag));
}
}
/** Renders the text on the image. */
public void drawPixels(ImageProcessor ip) {
ip.setFont(instanceFont);
ip.setAntialiasedText(antialiased);
FontMetrics metrics = ip.getFontMetrics();
int fontHeight = metrics.getHeight();
int descent = metrics.getDescent();
int i = 0;
int yy = 0;
int xi = (int)Math.round(getXBase());
int yi = (int)Math.round(getYBase());
while (i0.0)
this.antialiased = true;
}
/** Returns the state of the 'antialiased' instance variable. */
public boolean getAntialiased() {
return antialiased;
}
/** Sets the 'justification' instance variable (must be LEFT, CENTER or RIGHT) */
public static void setGlobalJustification(int justification) {
if (justification<0 || justification>RIGHT)
justification = LEFT;
globalJustification = justification;
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) {
Roi roi = imp.getRoi();
if (roi instanceof TextRoi) {
((TextRoi)roi).setJustification(justification);
imp.draw();
}
}
}
/** Returns the global (default) justification (LEFT, CENTER or RIGHT). */
public static int getGlobalJustification() {
return globalJustification;
}
/** Sets the 'justification' instance variable (must be LEFT, CENTER or RIGHT) */
public void setJustification(int justification) {
if (justification<0 || justification>RIGHT)
justification = LEFT;
this.justification = justification;
}
/** Returns the value of the 'justification' instance variable (LEFT, CENTER or RIGHT). */
public int getJustification() {
return justification;
}
/** Sets the global font face, size and style that will be used by
TextROIs interactively created using the text tool. */
public static void setFont(String fontName, int fontSize, int fontStyle) {
setFont(fontName, fontSize, fontStyle, true);
}
/** Sets the font face, size, style and antialiasing mode that will
be used by TextROIs interactively created using the text tool. */
public static void setFont(String fontName, int fontSize, int fontStyle, boolean antialiased) {
name = fontName;
size = fontSize;
style = fontStyle;
globalJustification = LEFT;
antialiasedText = antialiased;
newFont = true;
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) {
Roi roi = imp.getRoi();
if (roi instanceof TextRoi) {
((TextRoi)roi).setAntialiased(antialiased);
((TextRoi)roi).setCurrentFont(new Font(name, style, size));
imp.draw();
}
}
}
/** Sets the default fill (background) color. */
public static void setDefaultFillColor(Color fillColor) {
defaultFillColor = fillColor;
}
/** Sets the default angle. */
public static void setDefaultAngle(double angle) {
defaultAngle = angle;
}
protected void handleMouseUp(int screenX, int screenY) {
super.handleMouseUp(screenX, screenY);
//if (widthnewWidth)
newWidth = w;
i++;
}
if (nullg) g.dispose();
newWidth += 2.0;
b.width = newWidth;
switch (justification) {
case LEFT:
if (xMax!=0 && x+newWidth>xMax && width!=1)
b.x = xMax-width;
break;
case CENTER:
b.x = oldX+oldWidth/2.0 - newWidth/2.0;
break;
case RIGHT:
b.x = oldX+oldWidth - newWidth;
break;
}
b.height = nLines*fontHeight+2;
if (yMax!=0) {
if (b.height>yMax)
b.height = yMax;
if (b.y+b.height>yMax)
b.y = yMax-height;
}
x=(int)b.x; y=(int)b.y;
width=(int)Math.ceil(b.width);
height=(int)Math.ceil(b.height);
//IJ.log("adjustSize2: "+theText[0]+" "+width+","+height);
}
void updateText() {
if (imp!=null) {
updateClipRect();
if (angle!=0.0)
imp.draw();
else
imp.draw(clipX, clipY, clipWidth, clipHeight);
}
}
double stringWidth(String s, FontMetrics metrics, Graphics g) {
java.awt.geom.Rectangle2D r = metrics.getStringBounds(s, g);
return r.getWidth();
}
/** Used by the Recorder for recording the text tool. */
public String getMacroCode(String cmd, ImagePlus imp) {
String code = "";
boolean script = Recorder.scriptMode();
boolean addSelection = cmd.startsWith("Add");
if (script && !addSelection)
code += "ip = imp.getProcessor();\n";
if (script) {
String str = "Font.PLAIN";
if (style==Font.BOLD)
str = "Font.BOLD";
else if (style==Font.ITALIC)
str = "Font.ITALIC";
code += "font = new Font(\""+name+"\", "+str+", "+size+");\n";
if (addSelection)
return getAddSelectionScript(code);
code += "ip.setFont(font);\n";
} else {
String options = "";
if (style==Font.BOLD)
options += "bold";
if (style==Font.ITALIC)
options += " italic";
if (antialiasedText)
options += " antialiased";
if (options.equals(""))
options = "plain";
code += "setFont(\""+name+"\", "+size+", \""+options+"\");\n";
}
ImageProcessor ip = imp.getProcessor();
ip.setFont(new Font(name, style, size));
FontMetrics metrics = ip.getFontMetrics();
int fontHeight = metrics.getHeight();
if (script)
code += "ip.setColor(new Color("+getColorArgs(getStrokeColor())+"));\n";
else
code += "setColor(\""+Colors.colorToString(getStrokeColor())+"\");\n";
if (addSelection) {
code += "Overlay.drawString(\""+text()+"\", "+x+", "+(y+fontHeight)+", "+getAngle()+");\n";
code += "Overlay.show();\n";
} else {
code += (script?"ip.":"")+"drawString(\""+text()+"\", "+x+", "+(y+fontHeight)+");\n";
if (script)
code += "imp.updateAndDraw();\n";
else
code += "//makeText(\""+text()+"\", "+x+", "+(y+fontHeight)+");\n";
}
return (code);
}
private String text() {
String text = "";
for (int i=0; iwidth)
width = w;
i++;
}
Rectangle r = ip.getRoi();
if (width>r.width) {
r.width = width;
ip.setRoi(r);
}
ip.fill();
}
}
/** Returns a copy of this TextRoi. */
public synchronized Object clone() {
TextRoi tr = (TextRoi)super.clone();
tr.theText = new String[MAX_LINES];
for (int i=0; i
Ads help maintain this website.