% DrawHighQualityUnicodeTextDemo % % This demo shows how to draw high-quality, anti-aliased text, and some % japanese text encoded in Unicode. % % MacOS/X has text fonts with support for japanese characters preinstalled, % so this should just work out of the box. Have a look at the code of the % demo on how to select a suitable font, and how to read unicode text from % the filesystem. The (commented out) reading code for SHIFT_JIS -> Unicode % conversion would only work on recent Matlab releases. Older releases need % different approaches - also different wrt. PowerPC vs. IntelMac. That's % why we hard-coded the text in this demo -- Want to have it working even % on old Matlab 6... % % On MS-Windows you will need to install the special east-asian font % support kit in order to be able to draw japanese text. % How to do this? See... % % http://www.coscom.co.jp/japanesefont/index.html % % with some more info here: % http://www.alanwood.net/unicode/fonts_windows.html#japanese % % After that, text drawing seems to "just work" with our "Courier New" % font. If you don't install the font pack, you'll just see funny little % squares instead of nice japanese characters... % % On MacOS/X you have the choice between three different text % rendering/layouting methods, as selectable by the Screen preference % setting 'TextRenderer': The default is 1, which selects Apple's ATSU text % renderer. A setting of 0 would also select ATSU but would use a different % method for layout of text. Each method has its own weaknesses in that it % will have trouble drawing text in some special fonts correctly, so you % may have to choose the method based on the font to get best results. % Typical standard fonts are handled correctly by both methods. A setting % of 2 will use the Linux text rendering plugin (see "help DrawTextPlugin") % which in our experience handles all fonts well and is of superior % performance to the OSX ATSU renderer. However, given that historically % ATSU was used on OSX for many years and each layout and rendering method % will give slightly different text appearance, for reason of consistency % we leave the default setting for OSX on 1, instead of using the superior % setting 2. % % 11/26/07 mk Wrote it. Derived from Allens DrawSomeTextDemo. try % Choosing the display with the highest display number is % a best guess about where you want the stimulus displayed. screens=Screen('Screens'); screenNumber=max(screens); % These preference setting selects the high quality text renderer on % each operating system: It is not really needed, as the high quality % renderer is the default on all operating systems, so this is more of % a "better safe than sorry" setting. Screen('Preference', 'TextRenderer', 1); % This command uncoditionally enables text anti-aliasing for high % quality text. It is not strictly needed here, because the default % setting is to let the operating system decide what to use - which is % usually anti-aliased rendering. This here just to demonstrate the % switch. On WindowsXP or Vista, there also exists a setting of 2 for % especially hiqh quality anti-aliasing. However, i couldn't ever see % any perceptible difference in quality... Screen('Preference', 'TextAntiAliasing', 1); % This setting disables user defined alpha-blending for text - not % strictly needed, alpha blending is disabled by default. Screen('Preference', 'TextAlphaBlending', 0); % We want the y-position of the text cursor to define the vertical % position of the baseline of the text, as opposed to defining the top % of the bounding box of the text. This command enables that behaviour % by default. However, the Screen('DrawText') command provides an % optional flag to override the global default on a case by case basis: Screen('Preference', 'DefaultTextYPositionIsBaseline', 1); % Open an onscreen window, fullscreen with default 50% gray background: w=Screen('OpenWindow', screenNumber, 128); % Draw some yellow oval, just to make the scene more interesting... Screen('FillOval', w, [255 255 0], [0 0 400 400]); % Select 'Arial' as font, choose a text size of 48pts and a % default text style: Screen('TextFont',w, 'Arial'); Screen('TextSize',w, 48); Screen('TextStyle', w, 0); % The standard 'Hello World' message drawn with the low-level % Screen('DrawText') command. We start at x=300 and y=100. We draw in % Red+Blue color: Screen('DrawText', w, double('Hello '), 300, 100, [255, 0, 255]); % Add to the text, starting at the last text cursor position. This % should append the text to the previously drawn text... Screen('DrawText', w, double('World! Smooth & Funky')); % Now for some Unicode text rendering... % The following array of double values encodes some japanese text in % UTF-16 Unicode. Unicode text must be passed to Screens text drawing % functions as a row-vector of double type, i.e., a numeric row vector, % or - if it isn't one already - converted via the double() operator % etc... Standard text strings are always interpreted as standard 8 bit % ASCII text. % % According to the donor of this text snippet, it says "Thank you in % japanese" -- let's hope he didn't lie to me ;-) % unicodetext = [26085, 26412, 35486, 12391, 12354, 12426, 12364, 12392, 12358, 12372, 12374, 12356, ... 12414, 12375, 12383, 12290, 13, 10]; % The text above is hard-coded. The following *disabled* snippet of code % would have done the same, reading the text from a text file, encoded % in so called Shift_JIS encoding, then converting it from Shift_JIS % into Unicode UTF-16, then into a double matrix. However, this only % works on recent Matlab releases, e.g, R2007a (V7.4) and later. In % order to make this demo workable on older Matlabs, we just show you % the commented code: if 0 fid = fopen([PsychtoolboxRoot 'PsychDemos/japanese_shiftJIS.txt'], 'r', 'n','Shift_JIS'); unicodetext = native2unicode(fread(fid),'Shift_JIS'); %#ok fclose(fid); disp(unicodetext); unicodetext = double(transpose(unicodetext)); end % On MS-Windows you need to install the special east-asian font % support kit in order to be able to draw japanese text. % How to do this? See... % http://www.coscom.co.jp/japanesefont/index.html % % with some more info here: % http://www.alanwood.net/unicode/fonts_windows.html#japanese % % After that, text drawing seems to "just work" with our "Courier New" % font as selected above. % Under OS/X if the legacy text renderer type 0 is used ... if IsOSX % ... we must select a font that supports japanese characters... Screen('TextFont', w, 'Hiragino Mincho Pro'); end if Screen('Preference', 'TextRenderer') == 1 % We can auto-select fonts by their supported languages on the % default cross-platform text renderer plugin (type 1), e.g., we % simply require a font with... if 1 % ... support for the 'ja'panese language, whatever fits best: Screen('TextFont', w, '-:lang=ja'); else % ... support for the 'he'brew language, whatever fits best: Screen('TextFont', w, '-:lang=he'); % Of course we also need to supply a text string with some % hebrew characters (unicode code points) then: unicodetext = 1488:1514; end end % Let's draw the text once with the low-level Screen command at % location (20, 300) in color black (==0) ... y = 200; Screen('DrawText', w, unicodetext, 20, y, 0); % Draw some green line at the top of the letters and at the baseline of % the text, just to show how nicely 'DrawText' now obeys the text size % settings of 48 pts... Screen('DrawLine', w, [0 255 0], 100, y - 48, 1400, y - 48); Screen('DrawLine', w, [0 255 0], 100, y, 1400, y); % ...and once centered with the convenient high level DrawFormattedText % command... DrawFormattedText(w, unicodetext, 'center', 'center'); % Tell user how to exit the demo, this time in the font 'Times' at a % size of 86pts, in red color: Screen('TextFont',w, 'Times'); Screen('TextSize',w, 86); Screen('DrawText', w, 'Hit any key to continue.', 100, 600, [255, 0, 0]); % Show text slide: Screen('Flip',w); % Wait for keypress, then for key release: KbStrokeWait; % Some funny little animation loop. Text scrolls down from top to % bottom of screen - or until key press... vbl=Screen('Flip',w); tstart=vbl; count=-100; while ~KbCheck && count < 1200 % Test affine text transformations? doAffine = 0; if doAffine % Yes. Apply some rotation and some translation: angle = 2 * (GetSecs - tstart) / 360 * 2 * 3.141592654; delta = 10 * sin((GetSecs - tstart)); newmatrix = [ cos(angle), -sin(angle), delta ; ... sin(angle), cos(angle), delta ]; oldmatrix = Screen('TextTransform', w, newmatrix) Screen('TextBackgroundColor', w, [0 255 0 128]); end % Draw text baseline in green... Screen('DrawLine', w, [0 255 0], 100, count, 1400, count); % Compute texts bounding box... [normRect realRect, ~, xAdvance] = Screen('TextBounds', w, 'Hit any key to exit.', 100, count); % Draw the text... newX = Screen('DrawText', w, 'Hit any key to exit.', 100, count, [255, 0, 0, 255]); Screen('DrawText', w, 'This is yellow.', [], [], [255, 255, 0, 255]); % Visualize its bounding box: Screen('FrameRect', w, [255 0 255], realRect); % Visualize the horizontal advance to the next text string: realRect(1) = realRect(3); % This 100 + xAdvance aka oldX + xAdvance should be the same as newX after text drawing: if ~doAffine realRect(3) = 100 + xAdvance; Screen('FrameRect', w, [255 255 0], realRect); end % Update count and show frame... count=count+1; Screen('Flip',w); end Screen('Flip', w); % Some nice good bye message in blue and at 24 pts text size: Screen('TextSize',w, 24); DrawFormattedText(w, 'Hit any key to exit the demo. Bye!', 'center', 'center', [0 0 255]); Screen('Flip', w); % Wait for keypress, then flip a last time: KbStrokeWait; Screen('Flip', w); Screen('Preference', 'DefaultTextYPositionIsBaseline', 0); % Close the screen, we're done... sca; catch % This "catch" section executes in case of an error in the "try" section % above. Importantly, it closes the onscreen window if it's open. Screen('Preference', 'DefaultTextYPositionIsBaseline', 0); sca; psychrethrow(psychlasterror); end