pub struct Values { /* private fields */ }
Expand description
Data structure for tracking values in DVI data.
The DVI format refers to seven runtime values that are modified based on operations in the data. These seven values are:
-
The current font, f.
-
The two coordinates of the current cursor position, (h,v).
-
The four values of the four variables
Var::W
,Var::X
,Var::Y
,Var::Z
.
This data structure provides a mechanism for calculating these values as DVI operations are run:
let mut values: dvi::Values = Default::default();
assert_eq!(values.y(), 0);
values.update(&dvi::Op::SetVar(dvi::Var::Y, 3));
assert_eq!(values.y(), 3);
values.update(&dvi::Op::Push);
values.update(&dvi::Op::SetVar(dvi::Var::Y, 5));
assert_eq!(values.y(), 5);
values.update(&dvi::Op::Pop);
assert_eq!(values.y(), 3);
Six of the values are just integers, which are simple to deal with.
The value of h is more complicated;
see the documentation on Values::h
for more information.
§Knuth’s description of the values
This text is from TeX.2021.584.
The DVI format is intended to be both compact and easily interpreted by a machine. Compactness is achieved by making most of the information implicit instead of explicit. When a DVI-reading program reads the commands for a page, it keeps track of several quantities:
-
The current font f is an integer; this value is changed only by
fnt
andfnt_num
commands (both commands are represented byOp::EnableFont
). -
The current position on the page is given by two numbers called the horizontal and vertical coordinates, h and v. Both coordinates are zero at the upper left corner of the page; moving to the right corresponds to increasing the horizontal coordinate, and moving down corresponds to increasing the vertical coordinate. Thus, the coordinates are essentially Cartesian, except that vertical directions are flipped; the Cartesian version of (h,v) would be (h,-v).
-
The current spacing amounts are given by four numbers w, x, y, and z, where w and x are used for horizontal spacing and where y and z are used for vertical spacing.
-
There is a stack containing (h,v,w,x,y,z) values; the DVI commands
push
(Op::Push
) andpop
(Op::Pop
) are used to change the current level of operation. Note that the current font f is not pushed and popped; the stack contains only information about positioning.
The values of h, v, w, x, y, and z are signed integers having up to 32 bits, including the sign. Since they represent physical distances, there is a small unit of measurement such that increasing h by 1 means moving a certain tiny distance to the right. The actual unit of measurement is variable, as explained below; TeX sets things up so that its DVI output is in sp units, i.e., scaled points, in agreement with all the scaled dimensions in TeX’s data structures.
Implementations§
source§impl Values
impl Values
sourcepub fn update(&mut self, op: &Op) -> bool
pub fn update(&mut self, op: &Op) -> bool
Update the values by applying the provided operation.
sourcepub fn f(&self) -> u32
pub fn f(&self) -> u32
Get the current value of the font, f.
Note that unlike every other value, the font is not affected by push and pop operations.
let mut values: dvi::Values = Default::default();
values.update(&dvi::Op::EnableFont(1));
assert_eq![values.f(), 1];
values.update(&dvi::Op::Push);
values.update(&dvi::Op::EnableFont(2));
assert_eq![values.f(), 2];
values.update(&dvi::Op::Pop);
assert_eq![values.f(), 2];
sourcepub fn h(&self) -> (i32, &[(u32, u32)])
pub fn h(&self) -> (i32, &[(u32, u32)])
Get the current value of the horizontal position, h.
The value of h is more complicated than other values.
The DVI format includes a set_char
command that typesets a character
and then increases h by the width of that character.
The problem is that without looking up the font metric file,
the data structure doesn’t know by how much to increase h.
Thus, the value of h in this data structure is an integer
plus a slice of characters whose widths should be added to
get the true value of h.
let mut values: dvi::Values = Default::default();
// move h 3 units to the right
values.update(&dvi::Op::Right(1));
// set the font
values.update(&dvi::Op::EnableFont(2));
// typeset DVI and move h each time
values.update(&dvi::Op::TypesetChar{char: 'D' as u32, move_h: true});
values.update(&dvi::Op::TypesetChar{char: 'V' as u32, move_h: true});
values.update(&dvi::Op::TypesetChar{char: 'I' as u32, move_h: true});
assert_eq![
values.h(),
(1_i32, [
('D' as u32, 2_u32),
('V' as u32, 2_u32),
('I' as u32, 2_u32),
].as_slice()),
];