[comp.lang.pascal] Reading characters in graphics mode

stone@cunixb.cc.columbia.edu (Glenn Stone) (06/14/91)

There must an easy way to do this but I seem to have a mental block.  
I'm writing a graphics mode equivalent of READLN(StringVariable) in
TP 5.5.  This loop reads characters and tacks them onto a string
called T.  The problem is in dealing with the backspace; I want the
pointer to back up and erase the last character, but the ' ' in
graphics mode doesn't do this.  I need the equivalent of ClrEol.
How do you do it?  Thanks in advance...

   done := false;
   t := '';
   repeat
      c := ReadKey;
      case c of
         #13 : done := true;                             { CR }
         #8  : begin                                     { backspace }
               OutTextXY(GetX-TextWidth(t[length(t)]),GetY,' ');
               delete(t,length(t),1);                       ^----here
               end;                                                
         else begin                                    { append char }
            t := t + c;
            MoveTo(x,y);
            OutText(t);
            end;
         end;
   until done;

-------------------------------------------------------------------------
  Glenn Stone                                      BITNET: stone@cunixc
  Columbia University            INTERNET: stone@cunixb.cc.columbia.edu
-------------------------------------------------------------------------

tswingle@oucsace.cs.OHIOU.EDU (Tom Swingle) (06/18/91)

In article <1991Jun14.150309.5126@cunixf.cc.columbia.edu> stone@cunixb.cc.columbia.edu (Glenn Stone) writes:
>There must an easy way to do this but I seem to have a mental block.  
>I'm writing a graphics mode equivalent of READLN(StringVariable) in
>TP 5.5.  This loop reads characters and tacks them onto a string
>called T.  The problem is in dealing with the backspace; I want the
>pointer to back up and erase the last character, but the ' ' in
>graphics mode doesn't do this.  I need the equivalent of ClrEol.
>How do you do it?  Thanks in advance...
>
>   done := false;
>   t := '';
>   repeat
>      c := ReadKey;
>      case c of
>         #13 : done := true;                             { CR }
>         #8  : begin                                     { backspace }
>               OutTextXY(GetX-TextWidth(t[length(t)]),GetY,' ');
                 ^                                            ^
                 |--- Replace this line as described below ---|

>               delete(t,length(t),1);
>               end;                                                
>         else begin                                    { append char }
>            t := t + c;
>            MoveTo(x,y);
>            OutText(t);
>            end;
>         end;
>   until done;

How about, before each character is added to the string and printed on the 
screen, using GetImage to save a piece of screen of width TextWidth(c) and
height TextHeight(c) right under where the character is to go.  Then, rather
than an OutTextXY call to delete a character, use a call to PutImage to put
back the area that was saved.  What you will probably need is an array of tiny
buffers large enough to hold a screen image the size of the largest character
that could be printed.  Then, as you read characters, store the characters in
the string, and at the same time, store the corresponding screen images in
the array of buffers.  The array of buffers would need to contain the same
number of buffers as the maximum length of the string to be read.

Of course, if you know that the screen under the character to be printed will
be blank, all you need is a call to Bar with the drawing color set to the
current background color.  The width of the bar should be TextWidth(c), and the
height should be TextHeight(c).

If you're not familiar with these procedures, mail me and I will provide more
details.  It's too late at night right now to come up with good explanations
of the procedures, but I assume you would be familiar with them since you are
creating a graphics application.  I hope I have been clear enough with this
explanation.  It's late and I really should be in bed.
-- 
"The problem you are experiencing is  |  "To be sure of hitting the target, 
not with the network nor with the     |  shoot first and, whatever you hit, 
station.  Please adjust your set."    |  call it the target." 

campbell@cutmcvax.cs.curtin.edu.au (Trevor George Campbell CC361) (06/19/91)

stone@cunixb.cc.columbia.edu (Glenn Stone) writes:

>There must an easy way to do this but I seem to have a mental block.  
>I'm writing a graphics mode equivalent of READLN(StringVariable) in
>TP 5.5.  This loop reads characters and tacks them onto a string
>called T.  The problem is in dealing with the backspace; I want the
>pointer to back up and erase the last character, but the ' ' in
>graphics mode doesn't do this.  I need the equivalent of ClrEol.
>How do you do it?  Thanks in advance...

>         #8  : begin                                     { backspace }
>               OutTextXY(GetX-TextWidth(t[length(t)]),GetY,' ');
>               delete(t,length(t),1);                       ^----here
>               end;                                                

I had a similar problem, the only way that i could think to solve it was to
rewrite the character in the background colour. Unfortunately this wont work if
you don't know the background colour, or the colour varies from the start to end
of the input string. The only other possability that i can think of is if you 
can XOR the original character onto the screen, and then XOR the character
again to remove it from the screen.

One further point that may speed up the program (a minute amount) would be
to replace the delete(t,...) above with:   t[0] := CHR(ORD(t[0]) - 1) as turbo
just stores the length of a STRING in position 0. This is a useful hint if you
need to use the LENGTH of a string a lot (just look at position 0 of the String)
BUT unfortunately this is only in a character form (not a byte or integer)



--
Trevor          alias  <**<TOMCAT>**>

tuo em tel esaelP ,lanimret siht edisni kcuts m`I pleH



(
for all of you out there who can't read backwards.....
Help i'm stuck inside this terminal, Please let me out
)

J_SCHULL@acc.haverford.edu (Jonathan Schull) (06/20/91)

How to erase characters when backspaced?

I wrote a Clear routine which erases a particular area of the screen
(The Bar command can be used for this purpose).  So the backspace
tells you to rease from CursorPos to CursorPos-TextWidth('o');

.

ts@uwasa.fi (Timo Salmi) (06/20/91)

In article <1991Jun14.150309.5126@cunixf.cc.columbia.edu> stone@cunixb.cc.columbia.edu (Glenn Stone) writes:
>There must an easy way to do this but I seem to have a mental block.  
>I'm writing a graphics mode equivalent of READLN(StringVariable) in
:

This is only a partial help since the source code is not available,
but it sometimes helps to take a look at a program that has had the
same problem solved.  I have a turbdemo.exe in /pc/ts/tsdemo14.arc
which demonstrates various texthandling tricks in Turbo Pascal
graphics mode. 

"The wares are available by anonymous ftp from garbo.uwasa.fi,
Vaasa, Finland, 128.214.12.37, or by using our mail server (use the
latter if, and only if you don't have anonymous ftp).  If you are
not familiar with anonymous ftp or mail servers, I am prepared to
send prerecorded instructions on request.  (If you don't get the
instructions from me within a few days, it will mean that your email
address cannot be reached by a simple email reply.  It that case,
contact your system manager for devicing a proper mail path for you,
because unless you do, you wouldn't be able to utilize the mail
server anyway.  If you are in North America first consider using an
ftp site near you to spare the overseas load.)"

...................................................................
Prof. Timo Salmi
Moderating at garbo.uwasa.fi anonymous ftp archives 128.214.12.37
School of Business Studies, University of Vaasa, SF-65101, Finland
Internet: ts@chyde.uwasa.fi Funet: gado::salmi Bitnet: salmi@finfun