2014-12-08 3 views
1

캔버스에서 텍스트 렌더링을 사용하는 응용 프로그램을 만들고 있는데 별난 문제가 있습니다. 많은 컴퓨터에서 테스트를 마쳤으며 Windows가 설치된 시스템에서만 발생합니다. 설명해 드리겠습니다 :Windows에서 캔버스의 버그 렌더링 텍스트

필자의 글꼴 크기, 채우기 색, 텍스트 획 및 기울임 체로 Times New Roman을 사용할 때 일부 문자에 선이 표시됩니다.

처음에는 캔버스에 사용하고 있던 라이브러리에 문제가 있다고 생각했지만 네이티브 캔버스로 테스트 해 보았습니다. http://jsfiddle.net/ekm3o977/1/ (단지 Windows에서 발생하는 기억)

<body> 
    <canvas id="myCanvas" width="1000" height="400"></canvas> 
    <script> 
     var canvas = document.getElementById('myCanvas'); 
     var context = canvas.getContext('2d'); 
     var x = 80; 
     var y = 110; 

     context.font = 'italic 70px Times New Roman'; 

     context.lineWidth = 1; 
     // stroke color 
     context.strokeStyle = 'red'; 
     context.fillStyle = 'blue'; 
     context.fillText('abcdefghijklmnñ', x, y); 
     context.strokeText('abcdefghijklmnñ', x, y); 
     context.fillText('opqrstuvwxyz', x, y+100); 
     context.strokeText('opqrstuvwxyz', x, y+100); 
    </script> 
</body> 

의 어떤 생각이 어떻게이 해결할 수 있습니다 여기에

는 jsfiddle입니까? 감사합니다

+0

Win8.1 IE11, Chrome39 & FF33에서 변위를 확인했습니다. 이 문제를 해결하려면 시스템 글꼴 대신 webfont Times New Roman을 사용할 수 있습니다. – markE

답변

1

이 서체 자체와 함께 (브라우저가 상호 작용하는) 서브 시스템의 내부 문제이므로이 문제의 주된 원인은 해결할 수 없습니다.

당신은하지만 접근 방식의 몇 가지를 시도 할 수 있습니다 :

코멘트에서 언급 한 바와 같이
  1. , 그것의 웹 폰트 버전 (: requires license 참고)를 사용하려고합니다. 캔버스의 경우 font-loader을 사용해야하므로 텍스트를 캔버스에 그리기 전에 글꼴이 제대로로드되었는지 알 수 있습니다.

  2. 문제가 100px 크기에서 사라지는 것을 확인했습니다. 이것을 사용하여 필요한 크기로 래퍼 함수를 ​​확장 할 수 있습니다. 베이스 라인과 정렬을 떨어 뜨리는 것과 같은 내 솔루션에서 몇 가지 타협점을 취했습니다. 그러나 필요한 경우 확장 할 수 있습니다.

    당신이 우리를 볼 수 있듯이

    var ctx = canvas.getContext("2d"); 
     
    
     
    ctx.fillStyle = "blue"; 
     
    ctx.strokeStyle = "red"; 
     
    ctx.lineWidth = 1; 
     
    ctx.font = "italic 70px Times New Roman"; 
     
    ctx.textBaseline = "top"; 
     
    ctx.fillText("This is native fillText/strokeText", 10, 10); 
     
    ctx.strokeText("This is native fillText/strokeText", 10, 10); 
     
    
     
    tnrWrapper(ctx, "This is wrapper function", 10, 80, 70, "italic"); 
     
    
     
    function tnrWrapper(ctx, txt, x, y, size, style) { 
     
    
     
        var width, hf = 1.1, // height factor 
     
         tcanvas = document.createElement("canvas"), 
     
         tctx = tcanvas.getContext("2d"); 
     
    
     
        style = style || ""; // italic, bold or nothing 
     
        
     
        tctx.font = style + " 100px Times New Roman"; // fixed at 100px here 
     
        width = tctx.measureText(txt).width; 
     
        
     
        tcanvas.width = width; // this will reset font, optionally set a fixed width 
     
        tcanvas.height = 100*hf; // todo: find a better proportional factor 
     
    
     
        tctx.font = style + " 100px Times New Roman"; // new width resets context 
     
        tctx.textBaseline = "top"; 
     
        tctx.textAlign = "start"; // rtl sensitive, or use left/right 
     
        
     
        tctx.lineWidth = ctx.lineWidth * (100/size); // scale line width 
     
        tctx.fillStyle = ctx.fillStyle; 
     
        tctx.strokeStyle = ctx.strokeStyle; 
     
    
     
        tctx.fillText(txt, 0, 0); 
     
        tctx.strokeText(txt, 0, 0); 
     
        
     
        ctx.drawImage(tcanvas, x, y, width * (size/100), 100*hf * (size/100)); 
     
    }
    <canvas id=canvas width=600 height=180></canvas>

지금 같은 크기지만 정렬 문제없이 대략적인 얻는다.

참고 1 : 글꼴의 크기가 선형으로 동작하지 않습니다. 그들은 개별 크기로 표시하기 위해 최적화되어 있습니다. 이것은 실제 너비 등에 영향을 미치므로 모든 크기에서 동일한 것으로 기대하지 마십시오. 그러나이 문제에 대한 해결책이있을 때까지는 작업 솔루션을 제공해야합니다 (Windows에서는 시스템 수준 인 것처럼 보입니다).

참고 2 : 글꼴이 두 번 설정됩니다. 우리가 그것을 측정하고 일치하도록 캔버스를 업데이트해야하기 때문입니다. 캔버스가 새로운 차원 컨텍스트를 가져 오면 설정된 글꼴을 잃어 버리게 재설정됩니다. 캔버스의 고정 너비를 설정하여이를 피할 수 있습니다.

희망이 도움이됩니다.