|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 26234 (0x667a)
Types: TextFile
Names: »B«
└─⟦85b835f43⟧ Bits:30000549 8mm tape, Rational 1000, Xlib rev 6.00
└─⟦0c20f784e⟧ »DATA«
└─⟦1abbe589f⟧
└─⟦059497ac5⟧
└─⟦this⟧
with Xlbt_Arithmetic;
use Xlbt_Arithmetic;
with Xlbt_Basic;
use Xlbt_Basic;
with Xlbt_Font;
use Xlbt_Font;
with Xlbt_Misc;
use Xlbt_Misc;
with Xlbt_Reply;
use Xlbt_Reply;
with Xlbt_Request;
use Xlbt_Request;
with Xlbt_String16;
use Xlbt_String16;
with Xlbt_Text;
use Xlbt_Text;
with Xlbp_Font;
use Xlbp_Font;
with Xlbp_Gc;
use Xlbp_Gc;
with Xlbip_Get_Reply;
use Xlbip_Get_Reply;
with Xlbip_Internal;
use Xlbip_Internal;
with Xlbip_Put_Request;
use Xlbip_Put_Request;
package body Xlbp_Text16 is
------------------------------------------------------------------------------
-- X Library Text - 16-bit characters
--
-- Xlbp_Text16 - Handle drawing of 16-bit characters
------------------------------------------------------------------------------
-- Copyright 1989 - 1991 by Rational, Santa Clara, California.
-- Copyright 1987 - 1989 by Digital Equipment Corporation, Maynard, Mass.
-- Copyright 1987 - 1989 by Massachusetts Institute of Technology,
-- Cambridge, Massachusetts.
--
-- All Rights Reserved.
--
-- Permission to use, copy, modify, and distribute this software and its
-- documentation for any purpose and without fee is hereby granted,
-- provided that the above copyright notice(s) appear in all copies and that
-- both that copyright notice(s) and this permission notice appear in
-- supporting documentation, and that the names of Digital, MIT, or Rational
-- not be used in advertising or publicity pertaining to distribution of
-- the software without specific, written prior permission.
--
-- Digital, MIT, and Rational disclaim all warranties with regard to this
-- software, including all implied warranties of merchantability and fitness,
-- in no event shall Digital, MIT, or Rational be liable for any special,
-- indirect or consequential damages or any damages whatsoever resulting from
-- loss of use, data or profits, whether in an action of contract, negligence
-- or other tortious action, arising out of or in connection with the use or
-- performance of this software.
------------------------------------------------------------------------------
--\f
procedure X_Draw_String16 (Display : X_Display;
Drawable : X_Drawable;
Gc : X_Gc;
X : S_Short;
Y : S_Short;
Text : X_String16) is
------------------------------------------------------------------------------
-- X_Draw_String16
------------------------------------------------------------------------------
Str_Length : S_Natural := Text'Length;
Datalength : S_Natural;
Partial_N_Chars : S_Natural := Text'Length;
Elt : X_Text_Elt;
Character_Offset : S_Natural := Text'First;
begin
----Do nothing for an empty string.
if Str_Length <= 0 then
return;
end if;
----Lock the display and flush changes to the GC we are about to use.
Lock_Display (Display);
begin
Private_X_Flush_Gc (Display, Gc);
----Send the request header; figure out the actual request length. The length
-- is that of the header plus the text plus the number of sub-headers we need
-- to describe all of the up-to 254 character sub-blocks we are sending.
Datalength := X_Text_Elt'Size / 8 * ((Str_Length + 253) / 254) +
(Str_Length * 2);
Put_X_Poly_Text16_Request
(Display,
(Kind => Poly_Text16,
Length => X_Poly_Text16_Request'Size / 32 +
U_Short ((Datalength + 3) / 4),
Pad => 0,
Drawable => Drawable,
Gc => Gc.Gid,
X => X,
Y => Y),
Datalength);
----Send as many full 254 character blocks as we can.
Elt := (Deltaa => 0,
Length => 254);
while Partial_N_Chars > 254 loop
Put_X_Text_Elt_Unaligned (Display, Elt);
Put_X_String16_Unaligned
(Display,
Text (Character_Offset .. Character_Offset + 253));
Partial_N_Chars := Partial_N_Chars - 254;
Character_Offset := Character_Offset + 254;
end loop;
----Send the last not-full character block if there is one.
if Partial_N_Chars /= 0 then
Elt := (Deltaa => 0,
Length => U_Char (Partial_N_Chars));
Put_X_Text_Elt_Unaligned (Display, Elt);
Put_X_String16_Unaligned (Display,
Text (Character_Offset .. Text'Last));
end if;
-- Pad request out to a 32-bit boundary
if Datalength rem 4 /= 0 then
Put_U_Char_Array_Unaligned (Display,
(1 .. 4 - Datalength rem 4 => 0));
end if;
----Catch unexpected exceptions.
exception
when others =>
Unlock_Display (Display);
raise;
end;
----Unlock; sync; and return.
Unlock_Display (Display);
Sync_Handle (Display);
end X_Draw_String16;
--\f
procedure X_Draw_Image_String16 (Display : X_Display;
Drawable : X_Drawable;
Gc : X_Gc;
X : S_Short;
Y : S_Short;
Text : X_String16) is
------------------------------------------------------------------------------
-- X_Draw_Image_String16
------------------------------------------------------------------------------
Character_Offset : S_Natural := Text'First;
First_Time_Through : Boolean := True;
Cur_X : S_Short := X;
Last_X : S_Short := 0;
Cur_Length : S_Natural := Text'Length;
Unit : S_Natural;
begin
----Lock the display and flush changes to the GC we are about to use.
Lock_Display (Display);
begin
Private_X_Flush_Gc (Display, Gc);
----Loop until all of the characters are done.
while Cur_Length > 0 loop
----Figure out how many characters to do this pass.
if Cur_Length > 255 then
Unit := 255;
else
Unit := Cur_Length;
end if;
----If we just did a group then we must figure out how wide it was before we
-- can do the next group.
if First_Time_Through then
First_Time_Through := False;
else
declare
Direction : X_Font_Direction;
Ascent : S_Short;
Descent : S_Short;
Overall : X_Char_Struct;
Font : X_Font_Struct;
begin
----Unlock; get the font we're using; check the extent of the last 255
-- characters; and lock up again.
Unlock_Display (Display);
Font := X_Query_Font (Display, (Id => Gc.Gid.Id));
if Font = None_X_Font_Struct then
return;
end if;
X_Text_Extents16 (Font,
Text (Character_Offset - 255 ..
Character_Offset - 1),
Direction,
Ascent,
Descent,
Overall);
Free_X_Font_Struct (Font);
Lock_Display (Display);
Cur_X := Last_X + S_Short (Overall.Width);
end;
end if;
----Send out a request for this group of characters.
Last_X := Cur_X;
Put_X_Image_Text16_Request
(Display,
(Kind => Image_Text16,
Length => X_Image_Text16_Request'Size / 32 +
U_Short ((Unit * 2 + 3) / 4),
N_Chars => U_Char (Unit),
Drawable => Drawable,
Gc => Gc.Gid,
X => Last_X,
Y => Y),
Unit);
----Put out the characters for this group.
Put_X_String16
(Display,
Text (Character_Offset .. Character_Offset + Unit - 1));
Character_Offset := Character_Offset + Unit;
Cur_Length := Cur_Length - Unit;
end loop;
----Catch unexpected exceptions.
exception
when others =>
Unlock_Display (Display);
raise;
end;
----Unlock; sync; and return.
Unlock_Display (Display);
Sync_Handle (Display);
end X_Draw_Image_String16;
--\f
procedure X_Draw_Text16 (Display : X_Display;
Drawable : X_Drawable;
Gc : X_Gc;
X : S_Short;
Y : S_Short;
Items : X_Text_Item16_Array) is
------------------------------------------------------------------------------
-- X_Draw_Text16
------------------------------------------------------------------------------
Length : S_Natural := 0;
Font : U_Char_Array (1 .. 5);
Partial_N_Chars : S_Natural;
Partial_Delta : S_Short;
Elt : X_Text_Elt;
First_Time_Through : Boolean;
Character_Offset : S_Natural;
Chars : X_String16_Pointer;
begin
----Lock the display and flush changes to the GC we are about to use.
Lock_Display (Display);
begin
Private_X_Flush_Gc (Display, Gc);
----Process each of the Items in turn. Calculate the total size of the extra
-- data in this request.
for I in Items'Range loop
----Font changes are 5 bytes; a 255 byte, plus size of Font id.
if Items (I).Font /= None_X_Font then
Length := Length + 1 + X_Font'Size / 8;
end if;
----If there's a Delta then we will send one Text_Elt for each 128 of the
-- Delta amount.
if Items (I).Deltaa /= 0 then
if Items (I).Deltaa > 0 then
Length :=
Length + X_Text_Elt'Size / 8 *
S_Natural
((Items (I).Deltaa + 126) / 127);
else
Length :=
Length +
X_Text_Elt'Size / 8 *
S_Natural
((abs (Items (I).Deltaa) + 127) / 128);
end if;
end if;
----If there are characters then they will be sent in 254 character chunks with
-- a Text_Elt header for each chunk.
Chars := Items (I).Chars;
if Chars'Length > 0 then
Length := Length +
X_Text_Elt'Size / 8 *
S_Natural ((Chars'Length + 253) / 254 - 1);
if Items (I).Deltaa = 0 then
----We share with the last Delta if possible.
Length := Length + X_Text_Elt'Size / 8;
end if;
Length := Length + S_Natural (Chars'Length) * 2 ** 1;
end if;
end loop;
----Send the request header.
Put_X_Poly_Text16_Request
(Display,
(Kind => Poly_Text16,
Length => X_Poly_Text16_Request'Size / 32 +
U_Short ((Length + 3) / 4),
Pad => 0,
Drawable => Drawable,
Gc => Gc.Gid,
X => X,
Y => Y),
Length);
----Process each of the Items in turn. Put them into the Display buffer.
for I in Items'Range loop
----If this guy is doing a font change then put him out. To mark a font shift,
-- write a 255 byte followed by the 4 bytes of font ID, big-end (most
-- significant bits) first. Update our local GC with the new font.
if Items (I).Font /= None_X_Font then
Font (1) := 255;
Font (2) := U_Char (Items (I).Font.Id.Number / 2 ** 24);
Font (3) := U_Char (Items (I).Font.Id.Number /
2 ** 16 rem 16#100#);
Font (4) := U_Char (Items (I).Font.Id.Number /
2 ** 8 rem 16#100#);
Font (5) := U_Char (Items (I).Font.Id.Number rem 16#100#);
Put_U_Char_Array_Unaligned (Display, Font);
Gc.Values.Font := Items (I).Font;
end if;
----If there's a Delta then process that.
Partial_Delta := Items (I).Deltaa;
if Partial_Delta /= 0 then
while Partial_Delta < -128 or else Partial_Delta > 127 loop
if Partial_Delta > 0 then
Elt := (Deltaa => 127,
Length => 0);
Partial_Delta := Partial_Delta - 127;
else
Elt := (Deltaa => -128,
Length => 0);
Partial_Delta := Partial_Delta + 128;
end if;
Put_X_Text_Elt_Unaligned (Display, Elt);
end loop;
if Partial_Delta /= 0 and then
Items (I).Chars'Length = 0 then
Elt := (Deltaa => S_Char (Partial_Delta),
Length => 0);
Put_X_Text_Elt_Unaligned (Display, Elt);
end if;
end if;
----If there are characters then process them.
Chars := Items (I).Chars;
Partial_N_Chars := Chars'Last;
First_Time_Through := True;
Character_Offset := Chars'First;
----Do them in lumps of 254 at a time to begin with.
while Partial_N_Chars > 254 loop
if First_Time_Through then
First_Time_Through := False;
Elt := (Deltaa => S_Char (Partial_Delta),
Length => 254);
Put_X_Text_Elt_Unaligned (Display, Elt);
Partial_Delta := 0;
else
Elt := (Deltaa => 0,
Length => 254);
Put_X_Text_Elt_Unaligned (Display, Elt);
end if;
Put_X_String16_Unaligned
(Display,
Chars (Character_Offset .. Character_Offset + 253));
Partial_N_Chars := Partial_N_Chars - 254;
Character_Offset := Character_Offset + 254;
end loop;
----Finish off the last few characters; if any.
if Partial_N_Chars /= 0 then
Elt := (Deltaa => S_Char (Partial_Delta),
Length => U_Char (Partial_N_Chars));
Put_X_Text_Elt_Unaligned (Display, Elt);
Put_X_String16_Unaligned
(Display,
Chars (Character_Offset .. Chars'Last));
end if;
end loop;
----Pad request out to a 32-bit (4 byte) boundary.
Length := Length rem 4;
if Length /= 0 then
Put_U_Char_Array_Unaligned (Display, (1 .. 4 - Length => 0));
end if;
----Catch unexpected exceptions.
exception
when others =>
Unlock_Display (Display);
raise;
end;
----Unlock; sync; and return;
Unlock_Display (Display);
Sync_Handle (Display);
end X_Draw_Text16;
--\f
procedure X_Query_Text_Extents16 (Display : X_Display;
Font : X_Font;
Text : X_String16;
Direction : out X_Font_Direction;
Font_Ascent : out S_Short;
Font_Descent : out S_Short;
Overall : out X_Char_Struct) is
------------------------------------------------------------------------------
-- X_Query_Text_Extents16
------------------------------------------------------------------------------
Str_Length : constant S_Natural := Text'Length;
Rep : X_Reply_Contents;
Succ : X_Status;
begin
----Lock the display and flush changes to the gc we are about to use.
Lock_Display (Display);
begin
----Send the request.
Put_X_Query_Text_Extents_Request
(Display, (Kind => Query_Text_Extents,
Length => X_Query_Text_Extents_Request'Size / 32 +
U_Short ((Str_Length + 1) /
2), -- Yes, 2; not 4.
Font => Font,
Odd_Length =>
From_Boolean ((Str_Length rem 2) /= 0)));
----Send the string.
declare
Buf : U_Char_Array (1 .. Str_Length * 2);
begin
for I in reverse 0 .. Str_Length - 1 loop
Buf (I * 2 + 1) := U_Char (Text (Text'First + I).Char1);
Buf (I * 2 + 2) := U_Char (Text (Text'First + I).Char2);
end loop;
Put_U_Char_Array (Display, Buf);
end;
----Read the reply.
Get_Reply (Display => Display,
Code => Query_Text_Extents,
Reply => Rep,
Extra => 0,
Discard => True,
Status => Succ);
----If we got failure then return that.
if Succ = Failed then
Direction := Font_Left_To_Right;
Font_Ascent := 0;
Font_Descent := 0;
Overall := None_X_Char_Struct;
return;
end if;
----Return the results.
Direction := Rep.Query_Text_Extents.Draw_Direction;
Font_Ascent := Rep.Query_Text_Extents.Font_Ascent;
Font_Descent := Rep.Query_Text_Extents.Font_Descent;
Overall :=
(Ascent => Rep.Query_Text_Extents.Overall_Ascent,
Descent => Rep.Query_Text_Extents.Overall_Descent,
Width => S_Short (Rep.Query_Text_Extents.Overall_Width),
Lbearing => S_Short (Rep.Query_Text_Extents.Overall_Left),
Rbearing => S_Short (Rep.Query_Text_Extents.Overall_Right),
Attributes => (others => False));
----Catch unexpected exceptions.
exception
when others =>
Unlock_Display (Display);
raise;
end;
----Unlock; sync; and return success.
Unlock_Display (Display);
Sync_Handle (Display);
end X_Query_Text_Extents16;
--\f
procedure Ci_Get_Char_Info_2d (Fs : X_Font_Struct;
Char : X_Character16;
Cs : in out X_Char_Struct;
Found : out Boolean) is
begin
if Fs.Per_Char = None_X_Char_Struct_List_2d then
Cs := Fs.Min_Bounds;
Found := True;
--/ if not TeleGen2_2d_Bug then
elsif Char.Char1 in Fs.Per_Char'Range (1) and then
Char.Char2 in Fs.Per_Char'Range (2) then
Cs := Fs.Per_Char (Char.Char1, Char.Char2);
--/ else
--// elsif TeleGen2_2d_Bug(Char.Char1) in Fs.Per_Char'Range (1) and then
--// Char.Char2 in Fs.Per_Char'Range (2) then
--// Cs := Fs.Per_Char (TeleGen2_2d_Bug(Char.Char1), Char.Char2);
--/ end if;
if Ci_Non_Exist_Char (Cs) then
Found := False;
else
Found := True;
end if;
else
Found := False;
end if;
end Ci_Get_Char_Info_2d;
--\f
procedure Ci_Get_Default_Info_2d (Fs : X_Font_Struct;
Cs : in out X_Char_Struct;
Found : out Boolean) is
begin
Ci_Get_Char_Info_2d (Fs,
Fs.Default_Char,
Cs,
Found);
end Ci_Get_Default_Info_2d;
--\f
procedure X_Text_Extents16 (Font : X_Font_Struct;
Text : X_String16;
Direction : out X_Font_Direction;
Font_Ascent : out S_Short;
Font_Descent : out S_Short;
Overall : out X_Char_Struct) is
------------------------------------------------------------------------------
-- X_Text_Extents16
------------------------------------------------------------------------------
N_Found : S_Natural := 0; -- number of characters found
Def : X_Char_Struct; -- info about default char
Cs : X_Char_Struct;
Have_Def : Boolean;
Found : Boolean;
Ovrall : X_Char_Struct;
begin
Ci_Get_Default_Info_2d (Font, Def, Have_Def);
Direction := Font.Direction;
Font_Ascent := Font.Ascent;
Font_Descent := Font.Descent;
-- Iterate over the input string getting the appropriate * char struct.
-- The default (which may be null if there is no def_char) will be returned
-- if the character doesn't exist. On the first time * through the loop,
-- assign the values to overall; otherwise, compute * the new values.
for I in Text'Range loop
Ci_Get_Char_Info_2d (Font, Text (I), Cs, Found);
if not Found then
if Have_Def then
Cs := Def;
else
goto Continue;
end if;
end if;
if N_Found = 0 then
Overall := Cs;
else
Ovrall.Ascent := Max (Ovrall.Ascent, Cs.Ascent);
Ovrall.Descent := Max (Ovrall.Descent, Cs.Descent);
Ovrall.Lbearing := Min (Ovrall.Lbearing,
Ovrall.Width + Cs.Lbearing);
Ovrall.Rbearing := Max (Ovrall.Rbearing,
Ovrall.Width + Cs.Rbearing);
Ovrall.Width := Ovrall.Width + Cs.Width;
end if;
N_Found := N_Found + 1;
<<Continue>> null;
end loop;
----If there were no characters, then set everything to 0.
if N_Found = 0 then
Overall := None_X_Char_Struct;
else
Overall := Ovrall;
end if;
end X_Text_Extents16;
--\f
function X_Text_Width16 (Font : X_Font_Struct;
Text : X_String16) return S_Long is
------------------------------------------------------------------------------
-- X_Text_Width16
------------------------------------------------------------------------------
Def : X_Char_Struct; -- info about default char
Cs : X_Char_Struct;
Have_Def : Boolean;
Found : Boolean;
Width : S_Long;
begin
Ci_Get_Default_Info_2d (Font, Def, Have_Def);
-- Iterate over the input string getting the appropriate * char struct.
-- The default (which may be null if there is no def_char) will be returned
-- if the character doesn't exist. On the first time * through the loop,
-- assign the values to overall; otherwise, compute * the new values.
Width := 0;
for I in Text'Range loop
Ci_Get_Char_Info_2d (Font, Text (I), Cs, Found);
if not Found then
if Have_Def then
Width := Width + S_Long (Def.Width);
end if;
else
Width := Width + S_Long (Cs.Width);
end if;
end loop;
return Width;
end X_Text_Width16;
--\f
end Xlbp_Text16;