2010-12-22 7 views
10

He descubierto que, al representar texto opaco en Java (última versión 6u23), el AA de subpíxeles está bien, pero el texto translúcido no.¿Puede Java renderizar texto translúcido utilizando sub-píxel AA?

Sub-pixel AA:

alt textalt text

El mismo texto para el que sólo el color se ha cambiado de 0xFFFFFFFF a 0xBFFFFFFF:

alt textalt text

Como se puede ver, el texto translúcido es claramente estándar AA y en lugar de una representación translúcida limpia, tiene esa horrible apariencia de "90" araña ".

¿Esto se debe a una limitación técnica para el AA subpíxel en general, o un error en Java, o simplemente porque Java ni siquiera prueba el texto translúcido, o me he perdido algo?


Gráficos de inicialización

dbGraphics=(Graphics2D)dbImage.getGraphics(); 
if(dctRoot.properties.getBoolean("Antialias",true)) { 
    try { 
     Map hnts=(Map)(dctRoot.awtComponent.getToolkit().getDesktopProperty("awt.font.desktophints")); 

     // SET AA ON OVERALL (NOTE: GENERAL AA MUST BE OFF FOR SUBPIXEL AA TO BE HONORED - TEXT WIDGETS MUST DO THIS THEMSELVES) 
     dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); 

     if(hnts!=null) { 
      // SET FONT RENDERING HINTS FROM DESKTOP 
      dbGraphics.addRenderingHints(hnts); 
      } 
     else { 
      try { 
       // SET TEXT AA TO FONT-SPECIFIED GASP AA (JAVA 6+) 
       dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null)); 
       } 
      catch(Throwable thr3) { 
       // SET TEXT AA TO DEFAULT 
       dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
       } 
      } 
     } 
    catch(Throwable thr) { 
     dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+")."); 
     dctRoot.setProperty("Antialias","False");   // turn off AA for subsequent painting 
     } 
    } 
else { 
    try { 
     dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); 
     dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); 
     } 
    catch(Throwable thr) {;}        // ignore exception 
    } 

representación de texto

Object oaa=disableGeneralAA(gc); 
... 
gc.drawString(tl,xx,(ty+(xa*met.getHeight()))); 
restoreGeneralAA(gc,oaa); 

... 


static private volatile boolean   hasRenderingHints=true; 

// ***************************************************************************** 
// STATIC INIT & MAIN 
// ***************************************************************************** 

// ***************************************************************************** 
// STATIC METHODS 
// ***************************************************************************** 

/** 
* Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON. 
* <p> 
* This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel 
* AA, so general AA has to be turned off before rendering text and turned back on when done. This method abstracts that work and deals 
* with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs. 
*/ 
static public Object disableGeneralAA(Graphics2D gc) { 
    Object        old=null; 

    if(hasRenderingHints) { 
     try { 
      old=gc.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 
      gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); 
      } 
     catch(NoClassDefFoundError thr) { hasRenderingHints=false; } 
     catch(NoSuchFieldError  thr) { hasRenderingHints=false; } 
     catch(NoSuchMethodError thr) { hasRenderingHints=false; } 
     } 
    return old; 
    } 

/** 
* Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON. 
* <p> 
* This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel 
* AA, so general AA has to be turned off before rendering text and turned back on when done. This method abstracts that work and deals 
* with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs. 
*/ 
static public void restoreGeneralAA(Graphics2D gc, Object val) { 
    Object        old=null; 

    if(hasRenderingHints && val!=null) { 
     try { gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,val); } 
     catch(NoClassDefFoundError thr) { hasRenderingHints=false; } 
     catch(NoSuchFieldError  thr) { hasRenderingHints=false; } 
     catch(NoSuchMethodError thr) { hasRenderingHints=false; } 
     } 
    } 
+0

¿Ha intentado renderizar texto antialias en un 'BufferedImage' luego usando' AlphaComposite' para dibujar la imagen translúcidamente en la pantalla? (Desgraciadamente, será más lento) – finnw

+0

@finnw: toda la pintura se realiza en una imagen oculta externa, y esa imagen se copia en el contexto gráfico de la pantalla subyacente en cada 'pintura (Graphics agc)' usando un simple 'gc.drawImage' . Espero que la imagen en el búfer fuera de pantalla sea la imagen final; Hago mucha pintura translúcida, y el único problema es que la representación de texto parece ser un AA estándar cuando el color del texto es translúcido. –

+0

Parece que esto ha sido un problema por un tiempo http://forums.java.net/node/676951 – z5h

Respuesta

0

Creo que es debido a que su uso GASP que se lleva los puntos del estilo de fuente. ¿Has intentado utilizar VALUE_TEXT_ANTIALIAS_DEFAULT y VALUE_ALPHA_INTERPOLATION_DEFAULT? vale la pena un tiro.

http://download.oracle.com/javase/6/docs/api/java/awt/RenderingHints.html

+0

No, estoy usando AA sub-píxel; GASP es solo una alternativa en caso de que no se devuelvan los consejos de renderizado de escritorio. Esto se demuestra con las capturas de pantalla: la * única * diferencia entre los dos es el color utilizado para la representación. –

0

What Jav una versión estás usando? No lo dices. Pero parece que esto se ha fijado como de cualquiera de Java 6 Update 12 (J6u12) o JDK7 b43

Ver aquí: http://bugs.sun.com/view_bug.do?bug_id=6749060

Si su prueba de nuevo con Java = o mayor que J6u12 sin dejar de ver el error, hay Es un RFE donde puedes comentar en la base de datos de errores de Sun.

La manera de arreglar las cosas en la plataforma Java, es ya sea:

  1. votación sobre el informe de error en Sun's bugParade, para aumentar su prioridad, y esperar hasta que los programadores de Sun/Oracle consiguen o
  2. Ahora que Java es de código abierto, arréglalo tú mismo. (únete a la lista de correo en ho.io/jkp5 :-)

El informe bugParade desea votar o comentar en está aquí (en caso de que una prueba con j6u12 Está todavía presentes) es url: ho.io/jkp2

Si desea implementar una solución alternativa conocida para que el texto se ve bien incluso en los JRE mayores una solución alternativa que aquí se proporciona

url: ho.io/jkpy

"parece que la solución que i' m usar para emular la translucidez mezclando el color de primer plano requerido con el color de fondo del componente t sigue siendo el camino a seguir para asegurarse de que se utiliza el rasterizador nativo ".

¡Buena suerte!

+0

Ciertamente no se solucionó a partir de 6.23; Estoy ejecutando la última JVM y JDK. Observo que esto habla de que el destino no es opaco, y estoy usando una fuente translúcida, pero sospecho que el problema es cuando ocurre cualquier mezcla alfa. –

+0

Y hacer la translucidez yo mismo está fuera de la cuestión ya que el fondo sobre el que se realiza la prueba varía, a menudo es una imagen, logotipo o gradiente, no hay un color que funcione para todos los píxeles. –

Cuestiones relacionadas