2009-12-15 2 views
11

Java 6에서 내 스윙 GUI 응용 프로그램을 실행할 때 모든 글꼴에 대해 구성된 하위 픽셀 앤티 앨리어스 설정이 자동으로 사용됩니다. 결과는 표준 AA 옵션보다 훨씬 향상되었습니다.스윙과 같이 화면 텍스트에 페인팅 텍스트의 시스템 앤티 앨리어싱 설정을 상속하려면 어떻게해야합니까?

하지만 이미지를 칠할 때 그래픽 컨텍스트를 초기화하여 시스템의 AA 구성을 사용할 방법이 없습니다. 자바의 다른 AA 힌트를 가지고 놀러 다니는 것은 모든 사용자에게 서브 픽셀 방법이 적용되지 않기 때문에 잃어버린 원인입니다.

하나를 선택하고 명시 적으로 힌트를 설정하지 않고 주어진 그래픽 컨텍스트에 대해 시스템 AA 설정을 상속하는 방법이 있습니까? 현재 표준 AA가 제공하는 끔찍한 결과를 피하기 위해 GASP AA를 사용해야합니다. 나는 텍스트 AA에 대해 아무 것도 설정하지 않고 AA 힌트를 전혀 설정하지 않으려 고 노력했다.


업데이트 내가이 아래로 고정 있다고 생각 2010-01-05

; 서브 픽셀의 AA 힌트는, AWT 그래픽스 문맥에 직접 페인트 할 경우에만 존중되는 것처럼 보입니다. 이중 버퍼 이미지에 페인트 할 때 표준 AA 만 수행합니다. 하지만 더블 버퍼 이미지를 우회하면 서브 픽셀 AA가 완료됩니다.

그렇지 않으면 The_Fire의 대답은 Swing을 사용할 수있는 JVM (J2ME JVM이 아님)에서 작동합니다. AWT 컴퍼넌트를 사용하면, 새로운 JLabel() 대신에 새로운 Label()를 사용해 The_Fire의 대답이 기능하지 않는 것에주의 해주세요. 아마도, Component가 디스플레이에 구현 될 때까지는 FontRenderContext를 추출 할 수 없기 때문입니다. 내 목표 이미지의 그래픽 컨텍스트를 얻을


내 현재 코드는 현재 다음과 같습니다

try { 
    if((dbImage=dctRoot.createImage(wid,hgt,1))!=null) {   // if createImage returns null or throws an exception the component is not yet displayable 
     dbGraphics=(Graphics2D)dbImage.getGraphics(); 
     if(dctRoot.properties.getBoolean("Antialias",true)) { 
      try { 
       // set AA on overall 
       dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING  ,RenderingHints.VALUE_ANTIALIAS_ON); 
       // set text AA to platform/impl default 
       dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); 
       // try to override platform/impl AA with font-specified AA (Java 6+) 
       try { dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null)); } catch(Throwable thr) {;} // yes, ignore exception 
       } 
      catch(Throwable thr) { 
       dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+")."); 
       dctRoot.setProperty("Antialias","False");   // turn off AA for subsequent painting 
       } 
      } 
     } 
    } 
catch(Throwable thr) { 
    dbImage=null; 
    dbGraphics=null; 
    } 

이미지를 만들 수있는 코드가되는 배경을 형성하는 기본 AWT 구성 요소를 사용합니다 I 다른 모든 AWT 구성 요소와 잘 작동하도록 setFocusCycleRoot를 수행 할 수 있어야하므로 필자의 모든 페인팅을 수행합니다. 구성 요소는 Panel입니다. 이미지를 만드는 코드는 다음과 같습니다 스윙을 사용하여

public DctImage createImage(int wid, int hgt, float accpty) { 
    GraphicsConfiguration    cfg=awtComponent.getGraphicsConfiguration(); 
    Image        img=null; 

    if(transparentImages) { 
     //y { img=new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB); }  // NB: J2ME CDC/PP 1.1 does not have the BufferedImage constructors (one day I may discover a way to create a BufferedImage via another API!!) 
     try { img=cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT); }// NB: J2ME CDC/PP 1.1 does not have this API, but prefer to use GraphicsConfiguration over new BufferImage(...) 
     catch(NoClassDefFoundError thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled 
     catch(NoSuchMethodError  thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled 
     catch(NoSuchFieldError  thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled 
     } 
    else { 
     img=cfg.createCompatibleImage(wid,hgt); 
     } 

    if(accpty>0 && SET_ACCELERATION_PRIORITY!=null) { 
     try { SET_ACCELERATION_PRIORITY.invoke(img,new Object[]{new Float(accpty)}); } catch(Throwable thr) {;} 
     } 

    return (img==null ? null : new DctImage(img)); 
    } 
+0

온 스크린 또는 오프 스크린과 관련이 없으므로 (답변이 아닌 주석이므로) 문자열의 특정 외국 문자가 스윙을 일으켜 TextLayout 글꼴 렌더링으로 다시 전환되는 것을 알고 있습니다 (안티 앨리어싱 된), 맞죠? – whybird

답변

7

여기에 몇 가지 요인이 있습니다.

첫째, 이미지는 기본 AWT 구성 요소에서 작성해야하고, 투명성없이 작성해야합니다 : 일부 설명 할 수없는 이유로,

cfg.createCompatibleImage(wid,hgt); 

대신

cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT); 

둘째, 기본 AA 설정 인 KEY_ANTIALIASING은 LCD 서브 픽셀 AA를 사용하려면 꺼야합니다.

마지막으로, 그리고 가장 중요한 힌트를 렌더링 바탕 화면 글꼴을 사용하여 쉽게 검색됩니다

java.awt.Toolkit.getDesktopProperty("awt.font.desktophints") 

업데이트 2010-01-05

을 자바 6.26에서 다시 테스트, 그것은 것 같아 텍스트 AA를 렌더링하기 위해 일반 AA를 해제해야하는 문제가 마침내 해결되었습니다 (오라클로가는 길 ... Sun은 몇 년 전인 10 년 후).

5

,이 같은 권리 텍스트 앤티 앨리어싱 힌트를 얻을 수 있어요 : 내 시스템에서

JLabel label = new JLabel(); 
FontMetrics fm = label.getFontMetrics(label.getFont()); 
Object aaHintValue = fm.getFontRenderContext().getAntiAliasingHint(); 

RenderingHits.VALUE_TEXT_ANTIALIAS_LCD_HRGB를 반환합니다.

+0

재미있는 생각입니다. J2ME/CDC/PP에서는 지원되지 않는 Swing을 사용할 수는 없지만 AWT 창에서 같은 것을 얻을 수는 있습니다. –

+0

직장에서 이것을 테스트해야하지만, getFontMetrics()가 Component 메소드이기 때문에, 필자는 내 컨텍스트에서이 함수가 제대로 작동 할 것으로 기대합니다. 이것을 가정하면 1 월에 이것을 받아 들일 수 있습니다. –

+0

올바른 AA 힌트를 얻으려고 노력하기 때문에 +1을줍니다. AWT (아마도 네이티브 구성 요소가 구현되지 않았기 때문에)에서는 작동하지 않으며, 지정된 LCD 힌트를 적용하더라도 서브 픽셀 AA를 수행하지 않아 문제가 해결되는 데 필요한 것입니다. –

1

잠깐, Windows JVM에서이 코드를 실행하고 있습니까? 필자는 ClearType이 Swing이 일부 원시 코드 (예 : Linux 또는 다른 비 Microsoft 플랫폼에서는 사용할 수 없음)를 통해 상속되는 Microsoft 기술이라고 생각했습니다. (

내가 한 번 데비안에서 실행 안티 앨리어싱 글꼴 JPG를 생성 서블릿을 작성하고, 이것은이 코드의 스윙에 의존하면 내가 기억 할 수

Font font = new Font("Komix", Font.PLAIN, 8); 
Graphics2D g2; 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
FontRenderContext frc = g2.getFontRenderContext(); 
g2.setFont(font); 
g2.setPaint(Color.black); 
g2.drawString(sMessage, xOffset, yOffset); 

즉석를 사용하는 코드였다 javax.swing을 가져 왔고 서블릿은 약 300 줄이므로 다른 것을 필요로한다고 생각할 수도 있습니다. Google의 빠른 검사는 AWT 공간 에서처럼 정교합니다. 희망이 도움이됩니다.

+0

그래, 나는 충분히 쉽게 금주 모임을 돌릴 수있다. 그러나 그것은 약 20pt 미만의 글꼴 크기에서 쓰레기 같이 보이는 표준 AA를 사용한다. GASP AA를 사용하면 더 잘 작동하지만 더 작은 글꼴 크기의 경우 AA를 꺼 버리는 경향이 있습니다. 서브 픽셀 AA를 사용하는 것이 가장 좋지만 하드웨어 픽셀 배열 (수직 또는 수평 및 RGB 또는 BGR)을 일치시켜야합니다. O/S가 사용하고있는 AA 설정을 상속하고 싶습니다. O/S가 올바른지, 아니면 사용자가 일반적으로 데스크탑에서보고있는 것과 동등 할 것이기 때문입니다. 진짜 문제는 표준 AA가 서브 픽셀 AA 옆에있는 쓰레기처럼 보입니다. –

+0

BTW는 ClearType이 Microsoft의 상표이며 관련 기술은 모든 주요 플랫폼에서 사용할 수있는 * sub-pixel * 앤티 앨리어싱입니다. –

2

적어도 특별한 vm 커맨드 라인 옵션을 사용하지 않으면 java.awt.Toolkit.getDesktopProperty ("awt.font.desktophints")는 리눅스에서 null로 보입니다. 아마 플랫폼 기본값이 무엇인지 알 수 없기 때문일 것입니다. 예를 들어 "-Dawt.useSystemAAFontSettings = lcd"를 추가하면이를 치료하는 것처럼 보이고 Graphics2D 인스턴스에 대한 힌트를 설정하면 서브 픽셀 렌더링이 가능해집니다.

+0

Toolkit.getDefaultToolkit(). getDesktopProperty ("awt.font.desktophints"); – Hanynowsky

관련 문제