package ij.text;
import ij.util.Java2;
import java.awt.*;
import java.awt.event.*;
class TextCanvas extends Canvas {
TextPanel tp;
Font fFont;
FontMetrics fMetrics;
Graphics gImage;
Image iImage;
boolean antialiased;
TextCanvas(TextPanel tp) {
this.tp = tp;
addMouseListener(tp);
addMouseMotionListener(tp);
addKeyListener(tp);
addMouseWheelListener(tp);
}
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
tp.adjustVScroll();
tp.adjustHScroll();
iImage = null;
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if (tp==null || g==null) return;
Dimension d = getSize();
int iWidth = d.width;
int iHeight = d.height;
if (iWidth<=0 || iHeight<=0) return;
g.setColor(Color.lightGray);
if (iImage==null)
makeImage(iWidth,iHeight);
if (tp.iRowHeight==0 || (tp.iColWidth.length>0 && tp.iColWidth[0]==0&&tp.iRowCount>0)) {
tp.iRowHeight=fMetrics.getHeight()+2;
for (int i=0; i<tp.iColCount; i++)
calcAutoWidth(i);
tp.adjustHScroll();
tp.adjustVScroll();
}
gImage.setColor(Color.white);
gImage.fillRect(0,0,iWidth,iHeight);
if (tp.headings)
drawColumnLabels(iWidth);
int y=tp.iRowHeight+1-tp.iY;
int j=0;
while (y<tp.iRowHeight+1) {
j++;
y+=tp.iRowHeight;
}
tp.iFirstRow=j;
y=tp.iRowHeight+1;
for (;y<iHeight && j<tp.iRowCount; j++,y+=tp.iRowHeight) {
int x=-tp.iX;
for (int i=0;i<tp.iColCount;i++) {
if (i>=tp.iColWidth.length) break;
int w = tp.iColWidth[i];
Color b=Color.white,t=Color.black;
if (j>=tp.selStart && j<=tp.selEnd) {
int w2 = w;
if (tp.iColCount==1)
w2 = iWidth;
b=Color.black;
t=Color.white;
gImage.setColor(b);
gImage.fillRect(x,y,w2-1,tp.iRowHeight);
}
gImage.setColor(t);
char[] chars = getChars(i,j);
if (chars!=null)
gImage.drawChars(chars,0,chars.length,x+2,y+tp.iRowHeight-5);
x+=w;
}
}
if (iImage!=null)
g.drawImage(iImage,0,0,null);
}
void makeImage(int iWidth, int iHeight) {
iImage=createImage(iWidth, iHeight);
if (gImage!=null)
gImage.dispose();
gImage=iImage.getGraphics();
gImage.setFont(fFont);
Java2.setAntialiasedText(gImage, antialiased);
if(fMetrics==null)
fMetrics=gImage.getFontMetrics();
}
void drawColumnLabels(int iWidth) {
gImage.setColor(Color.darkGray);
gImage.drawLine(0,tp.iRowHeight,iWidth,tp.iRowHeight);
int x=-tp.iX;
for (int i=0; i<tp.iColCount; i++) {
int w=tp.iColWidth[i];
gImage.setColor(Color.lightGray);
gImage.fillRect(x+1,0,w,tp.iRowHeight);
gImage.setColor(Color.black);
if (tp.sColHead[i]!=null)
gImage.drawString(tp.sColHead[i],x+2,tp.iRowHeight-5);
if (tp.iColCount>0) {
gImage.setColor(Color.darkGray);
gImage.drawLine(x+w-1,0,x+w-1,tp.iRowHeight-1);
gImage.setColor(Color.white);
gImage.drawLine(x+w,0,x+w,tp.iRowHeight-1);
}
x+=w;
}
gImage.setColor(Color.lightGray);
gImage.fillRect(0,0,1,tp.iRowHeight);
gImage.fillRect(x+1,0,iWidth-x,tp.iRowHeight);
gImage.setColor(Color.darkGray);
gImage.drawLine(0,0,iWidth,0);
}
synchronized char[] getChars(int column, int row) {
if (tp==null || tp.vData==null)
return null;
if (row>=tp.vData.size())
return null;
char[] chars = row<tp.vData.size()?(char[])(tp.vData.elementAt(row)):null;
if (chars==null || chars.length==0)
return null;
if (tp.iColCount==1)
return chars;
int start = 0;
int tabs = 0;
int length = chars.length;
while (column>tabs) {
if (chars[start]=='\t')
tabs++;
start++;
if (start>=length)
return null;
};
if (start<0 || start>=chars.length) {
System.out.println("start="+start+", chars.length="+chars.length);
return null;
}
if (chars[start]=='\t')
return null;
int end = start;
while (chars[end]!='\t' && end<(length-1))
end++;
if (chars[end]=='\t')
end--;
char[] chars2 = new char[end-start+1];
for (int i=0,j=start; i<chars2.length; i++,j++) {
chars2[i] = chars[j];
}
return chars2;
}
void calcAutoWidth(int column) {
if (tp.sColHead==null || column>=tp.iColWidth.length || gImage==null)
return;
if (fMetrics==null)
fMetrics=gImage.getFontMetrics();
int w=15;
int maxRows = 20;
if (column==0 && tp.sColHead[0].equals(" "))
w += 5;
else {
char[] chars = tp.sColHead[column].toCharArray();
w = Math.max(w,fMetrics.charsWidth(chars,0,chars.length));
}
int rowCount = Math.min(tp.iRowCount, maxRows);
for (int row=0; row<rowCount; row++) {
char[] chars = getChars(column,row);
if (chars!=null)
w = Math.max(w,fMetrics.charsWidth(chars,0,chars.length));
}
char[] chars = tp.iRowCount>0?getChars(column, tp.iRowCount-1):null;
if (chars!=null)
w = Math.max(w,fMetrics.charsWidth(chars,0,chars.length));
if (column<tp.iColWidth.length)
tp.iColWidth[column] = w+15;
}
}