% TextBug % Demonstrates an off-by-one bug in Screen('Drawtext'). The rendered text % is drawn +1 pixel to the right of where it should be. This leaves the % leftmost pixel unused, and clips off the rightmost pixel of the string. % The bug is demonstrated here by drawing a letter twice, first in green as % part of a string that has a space added (so no clipping occurs) and is % then overwritten in black, without the added space. A green right edge is % apparent in many rendered characters, at least in the Sloan font whose % characters have no built-in spacing. The program also finds the bounding % box of each character. For Sloan, the top bound is always zero, which is % correct, but the left bound is always 1, which should also be zero. % % Denis Pelli March 21, 2007 % denis.pelli@... % The Sloan font may be downloaded from here: % http://psych.nyu.edu/pelli/software.html % 3/21/07 dgp Wrote it, based on allen ingling's DrawSomeTextDemo.m alphabet='CDHKNORSVZ'; font='Sloan'; fontSize=640; try w=Screen('OpenWindow',0); Screen('TextFont',w,font); Screen('TextSize',w,fontSize); Screen('DrawText',w,'X'); fprintf('\n\nFont is %s at size %d.\n',Screen('TextFont',w),Screen('TextSize',w)); black=BlackIndex(w); white=WhiteIndex(w); green=[0 255 0]; rect=1.5*[0 0 fontSize fontSize]; screenRect=Screen('Rect',w); rect=ClipRect(rect,screenRect); for a=alphabet Screen('FillRect',w,white); Screen('DrawText',w,[a ' '],0,0,green); Screen('DrawText',w,a,0,0,black); Screen('Flip',w); m=Screen('GetImage',w,rect); b=m(:,:,2)==black(1); % convert to binary bitmap vMargin=zeros(1,size(b,1)); for i=1:size(b,1) vMargin(i)=any(b(i,:)); end hMargin=zeros(1,size(b,2)); for j=1:size(b,2) hMargin(j)=any(b(:,j)); end vList=[nan find(vMargin)]; hList=[nan find(hMargin)]; bounds=[min(hList)-1 min(vList)-1 max(hList) max(vList)]; width=RectWidth(bounds); height=RectHeight(bounds); fprintf('"%s" is %3.0f wide %3.0f high, with bounding rect [%3d %3d %3d %3d].',a,width,height,bounds); g=(m(:,:,1)==green(1)) & (m(:,:,2)==green(2)); ghMargin=zeros(1,size(g,2)); for j=1:size(g,2) ghMargin(j)=any(g(:,j)); end gList=find(ghMargin); if ~isempty(gList) fprintf(' Clipped cols:'); fprintf(' %d',gList); fprintf(' %d.\n',sum(g(:))); else fprintf('\n'); end end Screen('CloseAll'); catch Screen('CloseAll'); psychrethrow(psychlasterror); end