*/
private boolean canClip = false;
+ /**
+ * Property to set text antialiasing method
+ */
+ private static final String TEXT_ANTIALIAS_METHOD = "TEXT_ANTIALIAS_METHOD";
+
+ private static final Object textAntialiasMethod;
+
+ static
+ {
+ final String textAntialiasMethodPref = Cache
+ .getDefault(TEXT_ANTIALIAS_METHOD, "GASP");
+ switch (textAntialiasMethodPref)
+ {
+ case "ON":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
+ break;
+ case "GASP":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_GASP;
+ break;
+ case "LCD_HBGR":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
+ break;
+ case "LCD_HRGB":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
+ break;
+ case "LCD_VBGR":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
+ break;
+ case "LCD_VRGB":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
+ break;
+ case "OFF":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
+ break;
+ case "DEFAULT":
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
+ break;
+ default:
+ jalview.bin.Console.warn(TEXT_ANTIALIAS_METHOD + " value '"
+ + textAntialiasMethodPref
+ + "' not recognised, defaulting to 'GASP'. See https://docs.oracle.com/javase/8/docs/api/java/awt/RenderingHints.html#KEY_TEXT_ANTIALIASING");
+ textAntialiasMethod = RenderingHints.VALUE_TEXT_ANTIALIAS_GASP;
+ }
+ }
+
public AnnotationRenderer()
{
this(false);
.getComplementConsensusAnnotation();
BitSet graphGroupDrawn = new BitSet();
- int charOffset = 0; // offset for a label
// \u03B2 \u03B1
// debug ints
int yfrom = 0, f_i = 0, yto = 0, f_to = 0;
if (validCharWidth && validRes && displayChar != null
&& (displayChar.length() > 0))
{
- // Graphics2D gg = (g);
- float fmWidth = fm.charsWidth(displayChar.toCharArray(), 0,
- displayChar.length());
+ float fmWidth = fm.stringWidth(displayChar);
/*
* shrink label width to fit in column, if that is
if (scaleColLabel && fmWidth > charWidth)
{
scaledToFit = true;
- fmScaling = charWidth;
- fmScaling /= fmWidth;
+ fmScaling = (float) charWidth / fmWidth;
// and update the label's width to reflect the scaling.
fmWidth = charWidth;
}
- charOffset = (int) ((charWidth - fmWidth) / 2f);
+ float charOffset = (charWidth - fmWidth) / 2f;
if (row_annotations[column].colour == null)
{
* draw the label, unless it is the same secondary structure
* symbol (excluding RNA Helix) as the previous column
*/
- final int xPos = (x * charWidth) + charOffset;
- final int yPos = y + iconOffset;
-
+ final float xPos = (x * charWidth) + charOffset;
+ final float yPos = y + iconOffset;
+
+ // Act on a copy of the Graphics2d object
+ Graphics2D g2dCopy = (Graphics2D) g2d.create();
+ // Clip to this annotation line (particularly width).
+ // This removes artifacts from text when side scrolling
+ // (particularly in wrap format), but can result in clipped
+ // characters until a full paint is drawn.
+ g2dCopy.setClip(0, (int) yPos - charHeight, imgWidth - 1,
+ charHeight);
/*
* translate to drawing position _before_ applying any scaling
*/
- g2d.translate(xPos, yPos);
+ g2dCopy.translate(xPos, yPos);
+ // narrow the clipping rectangle to the size of a character square
+ // or the character width
+ g2dCopy.clipRect(0, 0 - charHeight,
+ (int) Math.ceil(Math.max(charWidth, fmWidth)),
+ charHeight);
if (scaledToFit)
{
/*
* use a scaling transform to make the label narrower
* (JalviewJS doesn't have Font.deriveFont(AffineTransform))
*/
- g2d.transform(
+ g2dCopy.transform(
AffineTransform.getScaleInstance(fmScaling, 1.0));
}
- setAntialias(g);
+ setAntialias(g2dCopy, true);
if (column == 0 || row.graph > 0)
{
- g2d.drawString(displayChar, 0, 0);
+ g2dCopy.drawString(displayChar, 0, 0);
}
else if (row_annotations[column - 1] == null || (labelAllCols
|| !displayChar.equals(
|| (displayChar.length() < 2
&& row_annotations[column].secondaryStructure == ' ')))
{
- g2d.drawString(displayChar, 0, 0);
- }
- if (scaledToFit)
- {
- /*
- * undo scaling before translating back
- * (restoring saved transform does NOT work in JS PDFGraphics!)
- */
- g2d.transform(AffineTransform
- .getScaleInstance(1D / fmScaling, 1.0));
+ g2dCopy.drawString(displayChar, 0, 0);
}
- g2d.translate(-xPos, -yPos);
+ g2dCopy.dispose();
}
}
if (row.hasIcons)
private void setAntialias(Graphics g)
{
+ setAntialias(g, false);
+ }
+
+ private void setAntialias(Graphics g, boolean text)
+ {
if (isVectorRendering())
{
// no need to antialias vector drawings
if (Cache.getDefault("ANTI_ALIAS", true))
{
Graphics2D g2d = (Graphics2D) g;
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
+ if (text)
+ {
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ this.textAntialiasMethod);
+ }
+ else
+ {
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ }
}
}