2012-08-28 7 views
1

저는 레이어를 사용하여 사용자가 PDF에 텍스트를 삽입 할 수있는 앱을 제작하고 있습니다.Swing과 iText 글꼴 렌더링의 차이점

PDF 페이지의 텍스트 위치는 JPanel 내부에서 ICEPdf을 사용하여 PDF를 렌더링하는 app를 사용하여 설정할 수 있습니다. 레이어의 위치와 크기를 선택한 후 앱에서 iText (버전 5.3.2)을 사용하여 PDF로 렌더링합니다.

내가 직면 한 문제는 스윙의 글꼴 렌더링이 PDF의 최종 결과와 현저하게 다릅니다.

스윙과 텍스트 렌더링 :

protected void paintComponent(Graphics g){ 
     //for each line... 
     g.drawString(text, b0, b1); 
     //b0 and b1 are computed from the selected bounding box for the text 
} 

나는이있다 :

Swing rendering

을 여기

같은 경계 상자 내부의 헬 베티 일반 글꼴을 사용하여 일부 스크린 샷, 모두

iText로 텍스트 렌더링 :

5,678,418,664,나는이 있습니다

PDF rendering

그래서 질문입니다 : 스윙과 iText를 정확히 동일한 방식으로 글꼴을 렌더링하기 위해 무엇을 할 수 있는가? Swing 또는 iText를 조정할 수 있으므로 어떤 코드가 수정 되더라도 사용자를 위해 WYSIWYG의 경험이 필요합니다.

다른 글꼴 및 유형으로 시도했지만 여전히 차이점이 있습니다. 몇 가지 구성이 누락 된 것 같습니다.

감사합니다.

+0

어떤 글꼴을 사용합니까? 글꼴을 PDF에 포함 할 수 있습니다. 또한 문자 쌍의 커닝을 확인하고 양쪽에서 사용자 정의 할 수 있습니다. – StanislavL

+0

양쪽에 Helvetica plain을 사용하고 있습니다. Helvetica는 핵심 글꼴 중 하나이므로 가져올 필요가 없습니다. 커닝이 문제 중 하나 일 수 있습니다. 스윙에서 어떻게 바꾸나요? –

+0

itext의 fontmapper를 사용하고 있습니까? 글꼴을 포함하고 있습니까? – djeikyb

답변

2

편집 : 자바에서

글꼴은 픽셀 단위로 측정하지만, iText를 측정 점에서, 우리는 72 포인트 인치당가 알고, 표준 윈도우 머신에 대한 인치/dpi의 당 96 개 픽셀이된다. 자바 글꼴 크기가 16 인 경우

difference = 72/dpi 
     0.75 = 72/96 

다음으로 우리는이 iText 글꼴 크기를 얻을 수있는 차이 자바 글꼴 크기를 곱할 수 :

먼저 우리는 점과 픽셀 사이의 차이를 찾을 필요 , 96dpi와 함께 사용하는 경우 iText 글꼴 크기는 12 여야합니다.

iTextFontSize = difference x javaFontSize 
      12 = 0.75 x 16 

Windows 컴퓨터에서 96dpi는 종종 표준이지만, 항상 그런 것은 아니므로 각각의 다른 컴퓨터에서 해결해야합니다.


포스트

원래 나는 차이가 힌트를 렌더링에 의해 발생합니다 생각합니다.

해결 방법 1 :

은 버퍼 이미지에 모든 것을 그리는 것이 가장 좋은 방법.그런 다음 버퍼링 된 이미지가 스윙 구성 요소에 그려지고 동일한 버퍼링 된 이미지가 PDF에 그려 지므로 두 이미지간에 차이가 없어야합니다.

대체 아이디어 :

잘 작동하지 않을 수 있습니다,하지만 기존의 코드와 더 잘 작동 할 것이다 또 다른 아이디어는 다음 PDF로 버퍼링 된 이미지를 그릴 직접 버퍼 이미지에 스윙 구성 요소의 내용을 그릴 것입니다 .

다음은 몇 가지 렌더링 힌트를 사용하여 JPanel의 내용을 버퍼링 된 이미지에 그려주는 빠른 예제입니다. 스윙과 iText를 정확히 동일한 방식으로 글꼴을 렌더링하기 위해 무엇을 할 수 있는지 :

public BufferedImage createImage(JPanel panel) 
{ 
    BufferedImage swingComponent = new BufferedImage(
      panel.getHeight(), panel.getWidth(), 
      BufferedImage.TYPE_INT_RGB); 

    Graphics2D g = swingComponent.createGraphics(); 

    g.setRenderingHint(RenderingHints.KEY_RENDERING, 
         RenderingHints.VALUE_RENDER_QUALITY); 

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
         RenderingHints.VALUE_ANTIALIAS_ON); 

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
         RenderingHints.VALUE_INTERPOLATION_BILINEAR); 

    g.dispose(); 
    return swingComponent; //print this to your PDF 
} 
+1

이 솔루션을 사용할 수는 있지만 최종 결과가 좋지 않을 수 있습니다. 텍스트 (이미지가 아님)를 렌더링하면 텍스트는 렌더링시 다른 PDF와 잘 맞습니다. 대신 이미지를 사용하면 사용자가 문서의 크기를 조절할 때 이미지가 [pixelated] (http://en.wikipedia.org/wiki/Pixelation) (주로 텍스트 포함)가 될 수 있습니다. 문제를 완화하려면 더 큰 이미지 (더 많은 dpi)를 사용해야하며 PDF 크기가 커집니다. –

+0

이봐, 그냥보고 싶을 때를 대비해서 : 나는 더 나은 해결책으로 내 게시물을 편집했다. – sorifiend

+0

그게 문제인지 나는 모른다. iTextFontSize를 어떤 값으로 줄이면 이전보다 더 큰 차이를 만들 수있다. –

0

그래서 질문은 (스윙 구성 요소에 맞게 힌트를 변경)?

정확히? 아주 작은. 두 가지 모두에 동일한 글꼴 특성을 제공한다고 가정하면 렌더링에 차이가있을 수 있습니다.

PDF 파일 (또는 실제로는 텍스트 문구)은 글꼴 정보 (가족, 크기, 스타일 등)를 보유하지만 텍스트를 장치로 렌더링하는 것은 PDF 판독기입니다. 사용하는 프로그램에 따라 플랫폼의 렌더러를 사용하거나 자체의 렌더러를 사용할 수 있습니다.

AFAIK, Java Swing은 기본 플랫폼의 렌더러와는 다른 자체 글꼴 렌더링 엔진을 사용합니다. 이렇게하면 여러 플랫폼에서 일관성있게 보일 수도 있지만 텍스트가 다른 프로그램과 동일한 방식으로 렌더링되지는 않습니다. 그것을 알고

는 옵션이 제한됩니다

  • 또한 스윙 글꼴 렌더링을 사용하는 PDF 리더를 사용합니다. 그것은 상당히 제한적인 해결책입니다.

  • 플랫폼의 렌더링 엔진을 사용하여 스윙을 그립니다. 그것은 마치 일하는 것처럼 들리며 SWT가 해결했을 것이라고 생각합니다. SWT 컴포넌트를 임베드 할 수 있습니까?