com.actelion.research.gui.generic.GenericDepictor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
package com.actelion.research.gui.generic;
import com.actelion.research.chem.AbstractDepictor;
import com.actelion.research.chem.StereoMolecule;
public class GenericDepictor extends AbstractDepictor {
private int mTextSize;
private float mLineWidth;
public GenericDepictor(StereoMolecule mol) {
super(mol);
}
public GenericDepictor(StereoMolecule mol, int displayMode) {
super(mol, displayMode);
}
protected void init() {
super.init();
mLineWidth = 1.0f;
}
protected void drawBlackLine(DepictorLine theLine) {
mContext.drawLine(theLine.x1, theLine.y1, theLine.x2, theLine.y2);
}
protected void drawDottedLine(DepictorLine theLine) {
mContext.drawDottedLine(theLine.x1, theLine.y1, theLine.x2, theLine.y2);
}
protected void drawString(String theString, double x, double y) {
mContext.drawCenteredString(x, y, theString);
}
protected void drawPolygon(GenericPolygon p) {
mContext.fillPolygon(p);
}
protected void fillCircle(double x, double y, double d) {
mContext.fillCircle(x, y, d);
}
protected double getStringWidth(String theString) {
return mContext.getBounds(theString).getWidth();
}
protected void setTextSize(int theSize) {
mTextSize = theSize;
if (mContext != null)
mContext.setFont(theSize, false, false);
}
public int getTextSize() {
return mTextSize;
}
@Override
/**
* Draws a circular atom background that fades from center towards circle border
* @param argb if alpha < 1 then the background is mixed in accordingly
* @param radius <= 1.0; if null, then a default of 0.5 of the average bond length is used
*/
public void hiliteAtomBackgrounds(int[] atomARGB, float[] radius) {
double avbl = getTransformation().getScaling() * getMolecule().getAverageBondLength();
double maxRadius = (radius == null) ? 0.6 * avbl : 0.75 * avbl;
GenericRectangle rect = simpleCalculateBounds();
int imageX = (int)Math.floor(rect.x - maxRadius);
int imageY = (int)Math.floor(rect.y - maxRadius);
int imageW = (int)Math.ceil(rect.x + rect.width + maxRadius) - imageX + 1;
int imageH = (int)Math.ceil(rect.y + rect.height + maxRadius) - imageY + 1;
float[] imageARGB = new float[4 * imageW * imageH];
float[] pixelARGB = new float[4]; // pixel color buffer with changing alpha values
float[] background = getBackgroundColor().getRGBColorComponents(null);
for (int atom=0; atom>> 24) / 255f;
pixelARGB[1] = (float)((atomARGB[atom] & 0x00FF0000) >> 16) / 255f;
pixelARGB[2] = (float)((atomARGB[atom] & 0x0000FF00) >> 8) / 255f;
pixelARGB[3] = (float)(atomARGB[atom] & 0x000000FF) / 255f;
if (alpha != 1f) {
pixelARGB[1] = background[0]+alpha*(pixelARGB[1]-background[0]);
pixelARGB[2] = background[1]+alpha*(pixelARGB[2]-background[1]);
pixelARGB[3] = background[2]+alpha*(pixelARGB[3]-background[2]);
}
int atomRadius = (radius == null) ? (int)maxRadius : (int)(maxRadius * radius[atom]);
int atomSquare = atomRadius * atomRadius;
for (int rx=0; rx<=atomRadius; rx++) {
for (int ry=0; ry<=atomRadius; ry++) {
float squareDistance = rx*rx + ry*ry;
if (squareDistance <= atomSquare) {
pixelARGB[0] = 1f - (float)Math.sqrt(squareDistance) / atomRadius;
if (rx != 0 && ry != 0)
mixInColor(imageARGB, 4 * ((y0 - ry) * imageW + x0 - rx), pixelARGB);
if (ry != 0)
mixInColor(imageARGB, 4 * ((y0 - ry) * imageW + x0 + rx), pixelARGB);
if (rx != 0)
mixInColor(imageARGB, 4 * ((y0 + ry) * imageW + x0 - rx), pixelARGB);
mixInColor(imageARGB, 4 * ((y0 + ry) * imageW + x0 + rx), pixelARGB);
}
}
}
}
}
GenericImage image = mContext.createARGBImage(imageW, imageH);
int index = 0;
for (int y = 0; y 1f) {
float intensity = imageARGB[index++];
c = 0xFF000000;
c += ((int)(255f * imageARGB[index++] / intensity)) << 16;
c += ((int)(255f * imageARGB[index++] / intensity)) << 8;
c += ((int)(255f * imageARGB[index++] / intensity));
}
else {
c = ((int)(255f * imageARGB[index++])) << 24;
c += ((int)(255f * imageARGB[index++])) << 16;
c += ((int)(255f * imageARGB[index++])) << 8;
c += (int)(255f * imageARGB[index++]);
}
}
else {
index += 4;
}
image.setRGB(x, y, c);
}
}
mContext.drawImage(image, imageX, imageY);
}
private void mixInColor(float[] imageARGB, int index, float[] pixelARGB) {
if (imageARGB[index] == 0) { // if there is no previous color assigned
imageARGB[index++] = pixelARGB[0];
imageARGB[index++] = pixelARGB[1];
imageARGB[index++] = pixelARGB[2];
imageARGB[index++] = pixelARGB[3];
}
else { // we have to mix in the proper ratio
float oldIntensity = imageARGB[index];
float newIntensity = imageARGB[index] + pixelARGB[0];
imageARGB[index] = newIntensity;
index++;
imageARGB[index] = (imageARGB[index] * oldIntensity + pixelARGB[1] * pixelARGB[0]) / newIntensity;
index++;
imageARGB[index] = (imageARGB[index] * oldIntensity + pixelARGB[2] * pixelARGB[0]) / newIntensity;
index++;
imageARGB[index] = (imageARGB[index] * oldIntensity + pixelARGB[3] * pixelARGB[0]) / newIntensity;
}
}
protected double getLineWidth() {
return mLineWidth;
}
protected void setLineWidth(double lineWidth) {
mLineWidth = (float)lineWidth;
mContext.setLineWidth(mLineWidth);
}
protected void setRGB(int rgb) {
mContext.setRGB(rgb);
}
}