/usr/share/psychtoolbox-3/PsychDemos/DrawMirroredTextDemo.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | function DrawMirroredTextDemo(upsideDown)
% DrawMirroredTextDemo([upsideDown=0])
% _______________________________________________________
%
% Trivial example of drawing mirrored text. This demonstrates how to use
% low-level OpenGL API functions to apply geometric transformations to
% the drawn objects.
%
% Will draw a text string, once in normal orientation, and once mirrored.
% The mirrored text is either mirrored left<->right, or upside down if you
% set the optional 'upsideDown' flag to 1. At each key press, the text
% will be redrawn at an increasing size, until after a couple of redraws
% the demo will end.
%
% The demo also draws a bounding box around the text string to demonstrate
% how you can find out about the bounds of a text string via
% Screen('TextBounds').
%
% The mirroring is implemented by first defining a geomtric transformation
% which will apply to all further drawn shapes and text strings. Then the
% text string is drawn via Screen('DrawText') -- thereby affected by the
% geometric transform. Then the transform is undone to "normal".
%
% How does this work?
%
% 1. The command Screen('glPushMatrix'); makes a "backup copy" of the
% current transformation state -- the default way of drawing.
%
% 2. The command Screen('glTranslate', w, xc, yc, 0); translates the
% origin of the coordinate system (which is normally located at the
% upper-left corner of the screen) into the geometric center of the
% location of the text string. We find the center xc,yc by retrieving the
% bounding box of the text string Screen('TextBounds'), then calculating
% the center of that box [xc, yc].
%
% 3. The Screen('glScale', w, x, y, z); will scale all further drawn
% objects by a factor 'x' in x-direction (horizontal), 'y' in y-direction
% (vertical), 'z' in z-direction (depths). Scaling happen with respect to
% the current origin. As we just set the origin to be the center of the
% text string in step 2, the object will "scale" around that point. A
% value of -1 effectively switches the direction along the 'x' axis for a
% horizontal flip, or along the 'y' axis for an upside down vertical flip.
% Values with a magnitude other than 1 would scale the whole text up or
% down in size.
%
% 4. The command Screen('glTranslate', w, -xc, -yc, 0); translates the
% origin of the coordinate system back to the upper-left corner of the
% screen. This to make sure that all coordinates provided later on are
% wrt. to the usual reference frame.
%
% Steps 2,3 and 4 are internally merged to one mathematical transformation:
% The flipping of all drawn shapes and objects around the screen position
% [xc,yc] -- the center of the text string.
%
% 5. We Screen('DrawText') the text string --> The flipping applies.
%
% 6. We undo the whole transformation via Screen('glPopMatrix') thereby
% restoring the original "do nothing" transformation from the backup copy
% which was created in step 1. All further drawing is therbey unaffected
% by the flipping, so we can draw the second copy of the text and the
% bounding box.
%
% Besides the scaling and translation transform for moving, rescaling and
% flipping drawn objects and shapes, there is also the Screen('glRotate')
% transform to apply rotation around axis.
%
% This transformations apply to any drawing command, not only text strings!
% _________________________________________________________________________
%
% see also: PsychDemos
% 3/8/04 awi Wrote it.
% 7/13/04 awi Added comments section.
% 9/8/04 awi Added Try/Catch, cosmetic changes to documentation.
% 11/1/05 mk Derived from DrawSomeTextOSX.
if nargin < 1
upsideDown = [];
end
if isempty(upsideDown)
upsideDown = 0;
end
text = 'Hello World! QqPpYyGgJj Press key multiple times to exit.';
x = 100;
y = 100;
try
% Choosing the display with the highest dislay number is
% a best guess about where you want the stimulus displayed.
screens=Screen('Screens');
screenNumber=max(screens);
w=Screen('OpenWindow', screenNumber,0,[],32,2);
Screen('FillRect', w, [0, 0, 0]);
Screen('TextFont',w, 'Courier New');
Screen('TextStyle', w, 1);
% Loop through all text sized from 20 to 80 pixels...
for mysize=20:5:80
% Setup text size:
Screen('TextSize',w, mysize);
% Draw text 'normal'
Screen('DrawText', w, text, x, y + 100, [255, 255, 255]);
% Paint a green frame around it, just to demonstrate the
% 'TextBounds' command:
textbox = Screen('TextBounds', w, text);
textbox = OffsetRect(textbox, x, y);
Screen('FrameRect', w, [0, 255, 0, 255], textbox);
% Setup mirror transformation for horizontal flipping:
% xc, yc is the geometric center of the text.
[xc, yc] = RectCenter(textbox);
% Make a backup copy of the current transformation matrix for later
% use/restoration of default state:
Screen('glPushMatrix', w);
% Translate origin into the geometric center of text:
Screen('glTranslate', w, xc, yc, 0);
% Apple a scaling transform which flips the diretion of x-Axis,
% thereby mirroring the drawn text horizontally:
if upsideDown
Screen('glScale', w, 1, -1, 1);
else
Screen('glScale', w, -1, 1, 1);
end
% We need to undo the translations...
Screen('glTranslate', w, -xc, -yc, 0);
% The transformation is ready for mirrored drawing of text:
% Draw text again, this time mirrored as it is affected by the
% mirror transform that has been setup above:
Screen('DrawText', w, text, x, y, [255, 255, 0]);
% Restore to non-mirror mode, aka the default transformation
% that you've stored on the matrix stack:
Screen('glPopMatrix', w);
% Now all transformations are back to normal and we can proceed
% ordinarily...
% Flip the display:
Screen('Flip',w);
% Wait for keypress:
KbStrokeWait;
% Next iteration...
end;
% Done!
Screen('CloseAll');
catch
%this "catch" section executes in case of an error in the "try" section
%above. Importantly, it closes the onscreen window if its open.
Screen('CloseAll');
psychrethrow(psychlasterror);
end % try..catch
|