pub enum Op {
Show 17 variants
TypesetChar {
char: u32,
move_h: bool,
},
TypesetRule {
height: i32,
width: i32,
move_h: bool,
},
NoOp,
BeginPage {
parameters: [i32; 10],
previous_begin_page: i32,
},
EndPage,
Push,
Pop,
Right(i32),
Move(Var),
SetVar(Var, i32),
Down(i32),
EnableFont(u32),
Extension(Vec<u8>),
DefineFont {
number: u32,
checksum: u32,
at_size: u32,
design_size: u32,
area: String,
name: String,
},
Preamble {
dvi_format: u8,
unit_numerator: u32,
unit_denominator: u32,
magnification: u32,
comment: String,
},
BeginPostamble {
final_begin_page: i32,
unit_numerator: u32,
unit_denominator: u32,
magnification: u32,
largest_height: u32,
largest_width: u32,
max_stack_depth: u16,
num_pages: u16,
},
EndPostamble {
postamble: i32,
dvi_format: u8,
num_223_bytes: usize,
},
}
Expand description
Operation that appears in DVI data.
The documentation for each variant is adapted from TeX.2021.585.
However the variants don’t map one-to-one on to commands as described
there. Instead, commands that are logically connected are represented
in the same variant. For example, set_char_0
, set1
and put1
are
all represented using the Op::TypesetChar
variant.
Variants§
TypesetChar
Typeset the specified character from the current font f such that the reference point of the character is at (h,v).
This op corresponds to the DVI commands set_char_N
, set_N
and put_N
.
Fields
move_h: bool
If true, after typesetting the character, increase h by the width of that character. Note that a character may have zero or negative width, so one cannot be sure that h will advance after this command; but h usually does increase.
This field is true for setX
commands and false for putX
commands.
TypesetRule
Typeset a solid black rectangle of the provided height and width, with its bottom left corner at (h,v).
If either the width or height is not positive, nothing should be typeset.
This op corresponds to the DVI commands set_rule
and put_rule
.
[TeX.2021.589] Sometimes it is desirable to make horizontal or vertical rules line up precisely with certain features in characters of a font. It is possible to guarantee the correct matching between DVI output and the characters generated by MetaFont by adhering to the following principles:
-
The MetaFont characters should be positioned so that a bottom edge or left edge that is supposed to line up with the bottom or left edge of a rule appears at the reference point, i.e., in row 0 and column 0 of the MetaFont raster. This ensures that the position of the rule will not be rounded differently when the pixel size is not a perfect multiple of the units of measurement in the DVI file.
-
A typeset rule of positive height and positive width should be equivalent to a MetaFont-generated character having black pixels in precisely those raster positions whose MeatFont coordinates satisfy 0≤x<wa and 0≤y<ha, where a is the number of pixels per DVI unit.
Fields
NoOp
No operation, do nothing.
This op corresponds to the DVI commands nop
.
BeginPage
Beginning of a page.
Set (h,v,w,x,y,z) equal to (0,0,0,0,0,0) and set the stack empty. Set the current font f to an undefined value.
This op corresponds to the DVI commands bop
.
Fields
parameters: [i32; 10]
The ten parameters.
In the output from TeX, these hold
the values of \count 0
…\count 9
at the time shipout was invoked for this page.
They can be used to identify pages,
if a user wants to print only part of a DVI file.
previous_begin_page: i32
Pointer to the previous Op::BeginPage
in the file,
or -1 if this is the first begin page op.
EndPage
End of page: Print what you have read since the
previous Op::BeginPage
.
At this point the stack should be empty.
The DVI-reading programs that drive most output devices will have kept a buffer of the material that appears on the page that has just ended. This material is largely, but not entirely, in order by v coordinate and (for fixed v) by h coordinate; so it usually needs to be sorted into some order that is appropriate for the device in question.
This op corresponds to the DVI commands eop
.
Push
Push the current values of (h,v,w,x,y,z) onto the top of the stack; do not change any of these values. Note that f is not pushed.
This op corresponds to the DVI commands push
.
Pop
Pop the top six values off of the stack and assign them respectively to (h,v,w,x,y,z). The number of pops should never exceed the number of pushes, since it would be highly embarrassing if the stack were empty at the time of a pop command.
This op corresponds to the DVI commands pop
.
Right(i32)
Move h right by the number in the payload. If the payload is negative, h moves left.
This op corresponds to the four DVI commands rightN
.
Move(Var)
Move h or v by the value of the variable in the payload.
If the variable is w or x, h is moved. If the variable is y or z, v is moved.
With luck, this parameterless command will usually suffice for moving h and v, because the same kind of motion will occur several times in succession.
This op corresponds to the four DVI commands w0
, x0
, y0
and z0
.
SetVar(Var, i32)
Set the value of the specified variable, and then move h or v based on the new value.
If the variable is w or x, h is moved. If the variable is y or z, v is moved.
This op corresponds to the four DVI commands wN
, xN
, yN
and zN
for N>0
.
Down(i32)
Move v down by the number in the payload. If the payload is negative, v moves up.
This op corresponds to the four DVI commands downN
.
EnableFont(u32)
Enable the specified font.
This font must have been previously defined by a Op::DefineFont
command.
This op corresponds to the DVI commands fnt_num_N
and fntN
.
Extension(Vec<u8>)
This command is undefined in
general; it functions as a (k+2)-byte Op::NoOp
,
where k is the number of bytes,
unless special DVI-reading
programs are being used.
It is recommended that the payload be a string having the form of a keyword followed by possible parameters relevant to that keyword.
This op corresponds to the DVI commands xxxN
.
DefineFont
Define a font.
This op corresponds to the DVI commands fnt_defN
.
The rest of the documentation on this variant comes from TeX.2021.588.
Font definitions must appear before the first use of a particular font number.
Once a font is defined with a specific number, it must not be defined again; however, we
definitions appear in the postamble as well as
in the pages, so in this sense each font number is defined exactly twice,
if at all. Like Op::NoOp
commands, font definitions can
appear before the first Op::BeginPage
,
or between an Op::EndPage
and a Op::BeginPage
.
Fields
checksum: u32
Check sum that TeX found in the TFM file for this font; this should match the check sum of the font found by programs that read this DVI file.
at_size: u32
A fixed-point scale factor that is applied to
the character widths this font; font dimensions in TFM files and
other font files are relative to this quantity, which is called the
“at size” elsewhere in this documentation. The value of the parameter is
always positive and less than 2^27
. It is given in the same units
as the other DVI dimensions, i.e., in sp when TeX has made the
file.
design_size: u32
Similar to the at size; it is the “design size,” and like the at size it is given in DVI units. Thus, this font is to be used at ms/(1000 d) times its normal size, where m is the magnification, s is the at size and d is the design size.
Preamble
The preamble. This must come at the very beginning of the file.
This op corresponds to the DVI command pre
.
The rest of the documentation on this variant comes from TeX.2021.587. The preamble contains basic information about the file as a whole.
Fields
dvi_format: u8
The DVI format; currently this byte is always set to 2. (The value 3 is currently used for an extended format that allows a mixture of right-to-left and left-to-right typesetting. Some day we will set the format to 4, when DVI format makes another incompatible change—perhaps in the year 2048.
unit_numerator: u32
The next two parameters are positive integers that define
the units of measurement; they are the numerator and denominator of a
fraction by which all dimensions in the DVI file could be multiplied
in order to get lengths in units of 10^(-7)
meters. Since 7227pt =
254cm, and since TeX works with scaled points where there are 2^16
sp in a point, TeX sets
the numerator to 254x10^5=25400000
and the denominator to
7227x2^16=473628672
.
magnification: u32
The magnification parameter is what TeX calls \mag
, i.e., 1000 times the
desired magnification. The actual fraction by which dimensions are
multiplied is therefore mn/(1000 d).
Note that if a TeX
source document does not call for any “true” dimensions, and if you
change it only by specifying a different \mag
setting, the DVI
file that TeX creates will be completely unchanged except for the value
of the maginification in the preamble and postamble.
(Fancy DVI-reading programs allow
users to override the magnificiation setting when a DVI file is being printed.)
BeginPostamble
The start of the postamble.
This op corresponds to the DVI command post
.
The rest of the documentation on this variant comes from TeX.2021.590.
This command introduces the postamble, which summarizes important facts that TeX has accumulated about the file, making it possible to print subsets of the data with reasonable efficiency. The postamble has the form:
Op::BeginPostamble
.- Multiple font definitions (
Op::DefineFont
). Op::EndPostamble
.
Fields
final_begin_page: i32
A pointer to the final Op::BeginPage
in the file.
unit_numerator: u32
Duplicate of the analagous parameter in Op::Preamble
unit_denominator: u32
Duplicate of the analagous parameter in Op::Preamble
magnification: u32
Duplicate of the analagous parameter in Op::Preamble
largest_height: u32
The height-plus-depth of the tallest page, in the same units as other dimensions of the file. This height, along with the next width parameter, might be used by a DVI-reading program to position individual “pages” on large sheets of film or paper; however, the standard convention for output on normal size paper is to position each page so that the upper left-hand corner is exactly one inch from the left and the top. Experience has shown that it is unwise to design DVI-to-printer software that attempts cleverly to center the output; a fixed position of the upper left corner is easiest for users to understand and to work with. Therefore this field and the next field are are often ignored.
num_pages: u16
The total number of pages (Op::BeginPage
commands) present.
EndPostamble
The end of the postamble.
This op corresponds to the DVI command post_post
.
The rest of the documentation on this variant comes from TeX.2021.591.
Fields
postamble: i32
A pointer to the
Op::BeginPostamble
command that started the postamble.
dvi_format: u8
Duplicate of the analagous parameter in Op::Preamble
num_223_bytes: usize
The DVI format byte is followed by four or more bytes that are all equal to the decimal number 223 (i.e., 0x337). TeX puts out four to seven of these trailing bytes, until the total length of the file is a multiple of four bytes, since this works out best on machines that pack four bytes per word; but any number of 223’s is allowed, as long as there are at least four of them. In effect, 223 is a sort of signature that is added at the very end.
This curious way to finish off a DVI file makes it feasible for
DVI-reading programs to find the postamble first, on most computers,
even though TeX wants to write the postamble last. Most operating
systems permit random access to individual words or bytes of a file, so
the DVI reader can start at the end and skip backwards over the 223’s
until finding the DVI identification byte. Then it can back up four bytes, read
the postamble pointer, and move to that byte of the file. This byte should, of course,
contain the value 248 (the op code for Op::BeginPostamble
);
now the postamble can be read, so the
DVI reader can discover all the information needed for typesetting the
pages. Note that it is also possible to skip through the DVI file at
reasonably high speed to locate a particular page, if that proves
desirable. This saves a lot of time, since DVI files used in production
jobs tend to be large.
Unfortunately, however, standard Pascal does not include the ability to access a random position in a file, or even to determine the length of a file. Almost all systems nowadays provide the necessary capabilities, so DVI format has been designed to work most efficiently with modern operating systems. But if DVI files have to be processed under the restrictions of standard Pascal, one can simply read them from front to back, since the necessary header information is present in the preamble and in the font definitions.
Implementations§
source§impl Op
impl Op
sourcepub fn deserialize(b: &[u8]) -> Result<Option<(Self, &[u8])>, InvalidDviData>
pub fn deserialize(b: &[u8]) -> Result<Option<(Self, &[u8])>, InvalidDviData>
Deserialize the next operation from the provided binary slice.
Note that in general it is easier to perform deserialization using the
Deserializer
iterator.
There are three possible return values from this method. If the deserialization succeeds, the return value contains the operation and the tail of the slice that was not consumed. This tail can be used to deserialize the next operation:
let data = vec![128, 4, 129, 1, 0];
let (op, tail) = dvi::Op::deserialize(&data).unwrap().unwrap();
assert_eq![op, dvi::Op::TypesetChar{char: 4, move_h: true}];
assert_eq![tail, &[129, 1, 0]];
let (op, tail) = dvi::Op::deserialize(&tail).unwrap().unwrap();
assert_eq![op, dvi::Op::TypesetChar{char: 256, move_h: true}];
assert_eq![tail, &[]];
If the slice is exhausted, the method returns None
:
let data = vec![];
assert_eq![dvi::Op::deserialize(&data), Ok(None)];
If the data is not valid DVI data, an error is returned:
let data_1 = vec![254];
assert_eq![
dvi::Op::deserialize(&data_1),
Err(dvi::InvalidDviData::InvalidOpCode(254)),
];
let data_2 = vec![129, 1];
assert_eq![
dvi::Op::deserialize(&data_2),
Err(dvi::InvalidDviData::Truncated(129)),
];
sourcepub fn serialize(&self, b: &mut Vec<u8>)
pub fn serialize(&self, b: &mut Vec<u8>)
Serialize this operation to bytes and append them to the provided vector.
Unless you want close control over allocations, it’s likely easier
to use the top-level serialize()
function.
let mut data = vec![];
let op = dvi::Op::Right(256);
op.serialize(&mut data);
assert_eq![data, vec![144, 1, 0]];
Trait Implementations§
impl Eq for Op
impl StructuralPartialEq for Op
Auto Trait Implementations§
impl Freeze for Op
impl RefUnwindSafe for Op
impl Send for Op
impl Sync for Op
impl Unpin for Op
impl UnwindSafe for Op
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)