RVF Specification

<< Click to display table of contents >>

RVF Specification

This topic contains thorough information about RichView file Format.

For the most of applications you need not to know about internals of RVF, all necessary information is in RVF Overview.

Syntax

{x}         zero or more repetitions of item x;

{x}+         one or more repetitions of item x;

[x]         item x is optional;

xy         item x is followed by item y;

x | y         item x or item y;

'c'         a literal;

<n>         a nonterminal.

Data Types in RVF

<int> an integer number, ['-']{<digit>}+;

<digit> ::= '0' | … | '9';

Integer number is either finished by ' ' (space character) or it is followed by the end of line; for the simplification, this space character will be omitted (i.e. it will be included in <int>).

<crlf> end of line characters; usually it is a CR+LF, CR or LF characters; before binary data or Unicode it is required to use both CR and LF characters (#13#10).

<string> string of ANSI characters (without CR, LF and #0 characters)

<Unicode string> string of Unicode characters. Last character in string must be a paragraph separator (code $2029).

<special string> string containing ANSI text if RVF version is 1.3 or lower, and UTF-8 text if RVF version is 1.3.1 and newer. In this string, character #1 represents character #13, character #2 represents character #10.

<special string 2> string containing ANSI text if RVF version is 1.3.1 or lower, and UTF-8 text if RVF version is 1.3.2 and newer. In this string, character #1 represents character #13, character #2 represents character #10.

<quoted string> <special string> enclosed in double quotes; double quotes inside the string are doubled.

RVF Structure

<RVF> ::= [<Version Info>]{<RVF Record>}

Version Info

<Version Info> := <Version Record Type><Version><SubVersion>[<SubSubVersion>]<crlf>

<Version Record Type> ::= '-8'

<Version> ::= <int>

<SubVersion> ::= <int>

<SubSubVersion> ::= <int>

Currently, <Version> = 1, <SubVersion> = 3, <SubSubVersion> = 2. In this version, item names, tags and string properties are stored as UTF-8.

Previously, <Version> = 1, <SubVersion> = 3.  <SubSubVersion> = 1 for Delphi 2009+, and omitted for older versions of Delphi. In this version, item names are saved as ANSI, tags and string properties are stored as UTF-8 if <SubSubVersion> = 1, or as ANSI if <SubSubVersion> = 0 or omitted.

If there is no <Version Info> in RVF, reader implies version 1.0 (no <Item Options> in <RVF Item>)

RVF Record Structure

RVF file consists of records. Most records represent items (one record = one item), but there are some special record types.

<RVF Record> ::= <Record Header><crlf>({<string><crlf>}|{<Unicode sting>})[<Binary Data>]

<Record Header> ::= <Record Type><Strings Count><Paragraph><Item Options><Query><Tag><Rest of Header>

<Record Type> ::= <int>

<Strings Count> ::= <int>

<Paragraph> ::= <int>

<Item Options>::=<int>

<Query> ::= '0' | '1' | '2' | '3'

<Tag> ::= <quoted string>

<Record Type> is a type of <RVF Record>

<Record Type>

Constant

Meaning

>=0

text; <Item Type> is an index in the collection of styles (RVStyle.TextStyles)

-1,-3..-6, -10..-12, -60, ...

rvs*** constants

non-text item

-2

rvsCheckpoint

invisible label ("checkpoint")

-7

rvsBack

background (image, color)

-8

rvsVersionInfo

RVF version (only in <Version Info>)

-9

rvsDocProperty

text, paragraph, list styles,layout information, DocProperties, DocParameters

<Strings Count> is a number of lines between this <Record Header> and the next <Record Header> (or the end of file). If RVF reader does not understand this record type it should skip this number of lines. <Binary Data> (if present) is counted as one of strings after the header..

<Paragraph> is an index in the collection of paragraph styles (RVStyle.ParaStyles) (if this item starts a paragraph) or -1 (if the record  represents item, and this item continues paragraph).

<Item Options> is a set of bits, converted to integer.

Bit Number

Meaning

0

Set if the item continues paragraph (<Paragraph>=-1); it's a redundant data;

1

Page break. Set if this item must start a new page (<Paragraph><>-1)

2

Set if the item should be displayed from the new line, but it does not start a new paragraph (in this case <Paragraph><>-1, but should be equal to the paragraph style of the previous non "-1" item)

3

Set if it is a text item containing Unicode.

<Tag>

<Tag> is a string associated with this item. TRichView saves this string in double quotes. Empty tags are saved as '0' (without quotes).  Tag strings are saved as UTF-8 in RVF 1.3.1 or newer, and as ANSI in older versions of RVF. On saving, #13 and #10 are changed to #1 and #2, on loading, there are restored back.

See also tags.

<Query> can be a digit in the range 0..3

<Query>

Meaning

0

The item content is saved in a text format (rvfoSaveBinary is excluded from RichView.RVFOptions)

1

The item is requested from program on loading, see below.

2

The item content is saved in a binary format (rvfoSaveBinary is in RichView.RVFOptions).

3

Special value for saving Unicode text as hexadecimal string

If <Query>=1, then the next line after the header is a name of item (picture or control).

Data is requested in events: OnRVFPictureNeeded, OnRVFControlNeeded.

The saving mode (to save full information about images or controls / to save only name and request it when reading) is determined by RichView.RVFOptions (for the request mode, rvfoSavePicturesBody and/or rvfoSaveControlsBody options should be cleared). You need to create control or image in this event and assign it to gr or ctrl parameters. For example:

procedure TMyForm.MyRichViewRVFControlNeeded(

  Sender: TCustomRichView; Name: TRVUnicodeString;

  Tag: TRVTagvar ctrl: TControl);

begin

  ctrl := TButton.Create(nil);

  TButton(ctrl).Caption := 'Demo';

  TButton(ctrl).OnClick := MyClickProcedure;

end;

<Rest of Header> varies for different item types. Some new parameters can be added in future to <Rest of Header>. RVF reader should ignore all parameters in header after last parameter it can understand.

If <Query> is equal to 1 then <Rest of Header> is empty.

The next section is for <Query>=0 | 2 | 3.

RVF Records

Checkpoints

<Record Type> = rvsCheckpoint

<Paragraph> is ignored.

<String Count> = 1

<Rest of Header> ::= <Raise Event>

<Raise Event> ::= '0' | '1'

If Raise Event is equal to '1' then OnCheckPointVisible event occurs when the checkpoint appears in visible area of RichView

Strings after the header:

<Checkpoint name>

<Checkpoint name> ::= <special string>

"Checkpoint" is not an item, but it's convenient to save it like an item. "Checkpoints" are saved before the associated items.

Text (Items)

<Record Type> >= 0

<Rest of Header> := [<Additional Properties>] [<Hint>]

<Hint> := <quoted string>, value of rvespHint property.

<Additional Properties> := +<quoted string>

<Strings Count> is a number of paragraphs in this item. All paragraphs will be of the given text and paragraph style. If <Paragraph>=-1 then this item continues the paragraph of the previous item.

Strings after the header are text lines (paragraphs). Stings can be in Unicode encoding (determined by <Item Options>). If <Query>=0, Unicode is saved as UTF-16 (WideString). If <Query>=3, Unicode is saved as hexadecimal string

<Additional Properties> are not stored by default. They can be used to store additional properties in subclassed TRVTextItemInfo.

Break (Item)

<Record Type> = rvsBreak

<Paragraph> is ignored

<Rest of Header> ::= <Break Color><Break Style><Break Width> [<Color Opacity>]

<Break Color> ::= <int>

<Break Style> ::= <int>

<Break Width> ::= <int>

<Break Color> is a color of horizontal line, TColor; if Break Color=clNone then line will be of color of the 0th text style. FMX version may also save <Color Opacity>, a value from 0 to 255.

<Break Style> is TRVBreakStyle value converted to integer.

<Break Width> is a width of line.

<String Count> >= 0.

Picture (Item)

<Record Type> = rvsPicture

<String Count> >= 3

<Rest of Header> = <Vertical Align>

<Vertical Align> ::=  <int>

<Vertical Align> is a vertical alignment of picture (TRVVAlign value converted to integer)

Strings after the header:

<Picture Name>

<Picture Delphi Type>

<Picture Data>

<Picture Name> ::= <special string 2>, it is an item text.

<Picture Delphi Type> is a name of picture class (such as 'TBitmap', 'TIcon', 'TMetafile', 'TJPEGImage').

<Picture Data> can be in text or binary format.

In text format, each byte is represented as two hexadecimal digits, so all data is encoded in one string.

In binary format, <crlf> after <Picture Delphi Type> must be CR+LF (both characters). Binary data consists of <Data Size> and <Data>. Data Size is a binary 4-byte number, the number of bytes in <Data>.

Note 1: [VCL and LCL] In order to load picture of the given class from RVF, its class must be registered with RegisterClasses procedure. You need not to register TBitmap, TIcon, TMetafile, because they are registered by RichView. For Delphi 3+ RichView also registers TJpegImage  (if the conditional define RVDONOTUSEJPEGIMAGE is not defined) In order to use third party graphics formats (descendants of TGraphic) in RVF you need to register them yourself with RegisterClasses procedure. If the class is not registered, TRichView allows to detect the image by format and choose the appropriate graphic class itself.

Note 2: Behavior of TRichView when loading unregistered graphics format is defined in RVFOptions property. If rvfoIgnoreUnknownPicFmt option is defined then this picture will be just skipped. If this option is not defined then the function returns False (reading failed). In both cases RVFWarnings property will contain rvfwUnknownPicFmt.

Control (Item)

<Record Type> = rvsComponent

See the previous section, adjusted for: rvfoIgnoreUnknownCtrls, rvfwUnknownCtrls.

Bullet (Item)

<Record Type> = rvsBullet

<String Count> >= 1

<Rest of Header> = <ImageList#><ImageIndex>

<ImageList#> ::= <int>

<ImageIndex> ::= <int>

Strings after the header:

<Bullet Name>

<Bullet Name> ::= <special string 2>, it is an item text.

<ImageList#> is the Tag property of the corresponding ImageList (do not confuse it with RichView item tags! It is TImageList.Tag property). On reading, OnRVFImageListNeeded occurs. You need to assign your imagelist to il parameter. Otherwise, the bullet will be skipped. The behavior of RichView when loading too large image index is defined in RVFOptions property. If rvfoConvLargeImageIdxToZero option is defined then index is set to 0. Otherwise the function returns False (reading failed). In both cases RVFWarnings property will contain rvfwConvLargeImageIdx.

Hotspot (Item)

<Record Type> = rvsHotspot

<String Count> >= 1

<Rest of Header> = <ImageList#><ImageIndex><HotImageIndex>

<ImageList#> ::= <int>

<ImageIndex> ::= <int>

<HotImageIndex> ::= <int>

Strings after the header:

<Hotspot Name>

<Hotspot Name> ::= <special string 2>, it is an item text.

See the previous section for details.

Collections of styles, layout, DocProperties

<Record Type> = rvsDocProperty

<Paragraph> is ignored

<Query> can be 0 (data will be saved as a hexadecimal text) or 2 (in a binary form)

<Rest of Header> ::= '1' | '2' | '3' | '4' | '5' | '6'|'7'|'8'|'9'|'10'|'11'|'12'

<Rest of Header>

Meaning

1

Collection of text styles (Style.TextStyles)

2

Collection of paragraph styles (Style.ParaStyles)

3

Layout (margins, BiDiMode, MaxTextWidth, MinTextWidth) of TRichView

4

Collection of list styles (Style.ListStyles)

5

DocProperties

6

Special information, written by TRVReportHelper when saving page

7

DocParameters

8

Subdocument (headers and footers for TSRichViewEdit)

9

RVStyle.Units

10

Collection of style templates (Style.StyleTemplates)

11

List of names of style templates

12

DocObjects

13

GetReadDocumentPixelsPerInch value

<String Count> = 2 for 1..4 and 6, 7, 10. The first line contains name of TRVStyle object for 1,2,4,10 or empty for 3,6,9,12. Hexadecimal text or binary data follow next.

When saving DocProperties, <String Count>=DocProperties.Count. Each item in DocProperties is saved as <special string>.

DocParameters are saved as lines like property=value (only for properties with non-default values).

For 7, the first line contains a name of a subdocument (such as 'header').

For 11, each style template is saved in two lines, so <String Count>=StyleTemplates.Count*2. The first line contains its name (<special string>), the second line contains its id.

For 12,  DocObjects are saved using a special TRVCollectionBuilder collection, to allow storing items of different classes.

For 13, the next line contains an integer value (as text).

Background

<Record Type> = rvsBackground

This item is similar to rvsPicture, but has differences:

<Rest of Header> is a background color and style, and optionally color opacity

there is no <Picture Name> line;

<Picture Delphi Type> is always TBitmap

<Query>=1 is not supported

<String Count> = 2 | 0

<Paragraph> and <Tag> are ignored (0).

<Rest of Header>=<Background Style><Color>

<Background Style>::= <int> (TRVBackgroundStyle value converted to integer)

<Color>::=<int> (background color)

If background style is bsNoBitmap (or background bitmap is empty), there are no strings after header  (and <Query>=0).

Strings after the header:

<Picture Delphi Type>

<Picture Data>

Background color is saved as TColor, even in FireMonkey version. FireMonkey version may also save color opacity (as an integer value from 0 to 255).

List Markers (Item)

<Record Type> = rvsMarker

<String Count> >= 0

<Rest of Header> ::= <List Index> <Level> <Start From> <Reset>

All items in <Rest of Header> are <int> (<Reset> is ord(boolean value))

Label (Item)

<Record Type> = rvsLabel

<String Count> >= 6

Strings after the header:

<Text>

<Text Style>

<Min Width>

<Alignment>

'protect' | 'no protect'

<Item Name>

<Text> ::= <special string>, it is Text property. <Text Style> ::= <int>, it is TextStyleNo property. <Min Width> ::= <int>, it is MinWidth property. <Alignment> ::= <int>, it is ord(Alignment). The next line depends on ProtectTextStyleNo. <Item Name> ::= <string>.

Sequence (Item)

<Record Type> = rvsSequence

<String Count> >= 10

Strings after the header:

<Sequence Id>

<Numbering Type>

<Reset>

<Start From>

<Text Style>

<Min Width>

<Alignment>

'protect' | 'no protect'

<Item Name>

<Formatting String>

<Sequence Id> ::= <special string>, it is SeqName property. <Numbering Type> ::= <int>, it is NumberType property. <Reset> ::= <int>, it is ord(Reset). <Start From> ::= <int>, it is Reset property. <Text Style>. The next five lines have the same meaning as for labels. <Formatting String> ::= <special string>, it is FormatString property.

Footnote and EndNote (Item)

<Record Type> = rvsFootnote | rvsEndnote

<String Count> >= 8

Strings after the header:

<Text Style>

<Min Width>

<Alignment>

'protect' | 'no protect'

<Reset>

<Start From>

<Item Name>

<Document>

The first seven lines have the same meaning as in sequences.

<Document> can be in text or binary format. It is Document saved in RVF format.

In text format, each byte is represented as two hexadecimal digits, so all data is encoded in one string.

In binary format, <crlf> after <Item Name> must be CR+LF (both characters). Binary data consist of <Data Size> and <Data>. Data Size is a binary 4-byte number, the number of bytes in <Data>.

Reference to Footnote or Endnote (Item)

<Record Type> = rvsNoteReference

<String Count> >= 5

Strings after the header:

<Text Style>

<Min Width>

<Alignment>

'protect' | 'no protect'

<Item Name>

Meanings of these lines are the same as for labels.

Extra Item Properties

Some items may contain extra integer and string properties. They are saved as lines after the header (one line per property) in the form:

name=value

If the property has the default value, it is not saved. The list of names can be found in RVItem.pas, arrays RVFExtraItemIntPropNames and RVFExtraItemStrPropNames.

Since TRichView v11, values are saved as <special string>

Note that all color properties are stored as TColor values, even in FireMonkey (where all color properties have TAlphaColor type). In addition to the color itself, FireMonkey version can store an additional color opacity property (with value from 0 to 255).


This specifications does not cover a case of saving style names instead of style indexes (this feature is deprecated)

Major Changes in RVF Format

RVF Version 1.2

Older programs are not able to read new RVF files, but programs compiled with new versions of RichView can read old RVF files.

The most significant change is adding <Item Options> in <RVF Item>.

There are two new record types: -7 (background) and -8 (version information)

RVF reader reads version number from version information. If there is no version information item, reader understand the file as RVF version 1.0

RVF version 1.3 (used in TRichView before v17.3 for Delphi 2007 or older):

allows saving space characters in tag strings (for Delphi 3+); tags strings are saved in double quotes;

in text mode, Unicode text is saved as a hexadecimal string (each byte is saved as two characters hexadecimal digits)

RVF version 1.3.1 (used in TRichView before v17.3 for Delphi 2009 or newer):

DocProperties, extra string properties, tag strings (if rvoTagsArePChars in Options; note: since TRichView v13.2 tags are always strings), style names (if rvfoUseStyleNames in RVFOptions) are saved as UTF-8 (with CR and LF characters changed to #1 and #2)

RVF version 1.3.2 (current version):

Item names are stored as UTF-8.

More Detailed Information about Changes in RVF

Changes in RichView version 1.3:

RVF now can contain Unicode text (for text items). Older versions will be unable to load files with Unicode. Version number in RVF header was not changed, because there are no changes in the specification (additions only).

Note: Unicode is used only for saving Unicode text items, so file contains a mix of ANSI and Unicode text. Such files must be considered as binary, do not edit them in text editors.

Changes in RichView version 1.4:

Added: tables (rvsTable). This is not a change in RVF, but an addition.

Tables are saved in binary or hexadecimal text form, similar to pictures or controls.

Changes in RichView version 1.5:

RVF now can contain text and paragraph styles (rvsDocProperty). This is not a change in RVF, but addition.

Styles are saved in binary or hexadecimal text form, similar to pictures or controls.

Changes in RichView version 1.7:

RVF now can contain layout information and collection of list styles (rvsDocProperty). This is not a change in RVF, but addition.

Changes in RichView version 1.8

RVF version number is changed to 1.3

Changes in RichView version 11

RVF version number is changed to 1.3.1 for Delphi 2009 and newer. Values of extra item properties are saved as <special string>, thus allowing them to contain line break characters.

Changes in RichView version 13

Saving measuring units. Sizes can be in twips.

Changes in RichView version 17.2

RVF version number is changed to 1.3.2. Item names are saved as <special string 2>, i.e. as UTF-8.