This document defines version 1 of the binary structure of the EPAR (Electronic Permissions and Recommendations) table, the content of which is specified on the EEULAA web site.
In general the table follows the principles that are common for other OpenType tables. Which are:
Strings are encoded with the UTF-16BE encoding scheme. String length is stored in appropriate structures. Strings are not zero-ended.
String values may be supplied in many languages. However, every string must have a US English version and must always come first. In version 1, only US English is permitted.
The language of a string is specified using the Language IDs as defined in the Windows Language IDs (platform ID = 3) list of the Naming Table definition.
The EPAR table contains the following primary parts in the specified order.
All parts except the header are optional.
The Table Header is organized as follows:
Type | Name | Description |
USHORT | version | Table version number (0). |
USHORT | headerLength | Length of the table header (in bytes). |
USHORT | numPermissions | Number of permission records. |
USHORT | numRecommendations | Number of recommendation records. |
USHORT | numEula | Number of EULA information records. |
USHORT | numStringRecords | Number of string records. |
USHORT | numContentRecords | Number of content records. |
ULONG | stringOffset | Offset from the beginning of the table to the string storage. A value of zero means that there is no string data. |
There may be zero or more permission records. Each permission record has the following structure:
Type | Name | Description |
USHORT | permissionID | Identifies the kind of permission. |
USHORT | value1 | First value of the record. |
ULONG | value2 | Second value of the record. |
USHORT | StringIndex | Zero-based index of the string storage entry related to the record. |
The meanings of the value1, value2 and StringIndex fields depend on the permission ID (see the list below).
There could be more than one permission record with the same permissionID. If the meaning of the record is exclusive, then the most restrictive value is applied. Some records, like Licensing Units are "additive" so every following record adds some information. If a record is "additive", but some values are exclusive (like there is "not allowed" record and some permission is granted in another record), then the most restrictive value is applied.
If there is no record for a specific permissionID, there is no implied or default meaning.
The permissions are:
ID | Name | Description | value1 | value2 | StringIndex |
1 | Bundle | The license may be tied to use or sale with specific fonts, software or hardware. | ALLOWED_COND | NO_VALUE | When value1 is ALLOWED_COND, the string defines one bundle by name or description. Otherwise, NO_STRING |
2 | Compression | The license may allow compression of the font file. | NONE | NO_VALUE | When value1 is ALLOWED_COND or DISALLOWED_COND the string defines one kind of compression. Otherwise, NO_STRING |
3 | Conversion | The license may allow conversion of the font file. | NONE | NO_VALUE | When value1 is ALLOWED_COND or DISALLOWED_COND the string defines one kind of conversion. Otherwise, NO_STRING |
4 | Licensing Units | The license may tie the font to something physical. | UNIT_USERS | UNLIMITED 1..64000 | NO_STRING |
5 | Link | The license may allow the use of a font in the display of a website or to be served as a licensed asset. | LINK_SOURCE | When value1 is LINK_SOURCE, value2 may be LINK_SOURCE_SAME_ORIGIN, LINK_SOURCE_ROOT_STRING, or LINK_SOURCE_SUB_LICENSE. When value1 is LINK_TYPE, value2 may be LINK_TYPE_DISPLAY_PRINT or LINK_TYPE_EDIT_PRINT. When value1 is LINK_METHOD, value2 may be LINK_METHOD_ACCESSIBLE or LINK_METHOD_PROTECTED | NO_STRING |
6 | Site | The license may be tied to specific physical locations. | SITE_ADDRESS | NO_VALUE | The string defines the site. |
7 | Meter | The license may be or event-limited or time-limited. | METER_USE METER_USE and METER_DOWNLOAD may occur once each. Only one of METER_HOUR, METER_DAY or METER_YEAR may occur. | When value1 is METER_USE or METER_DOWNLOAD the range is 1..99,000,000. When value1 is METER_HOUR, METER_DAY or METER_YEAR, the range is 1..100. | NO_STRING |
8 | Document Embedding | The license may permit the font to be incorporated in a document, so the font travels with the document. | NONE | NO_VALUE | NO_STRING |
9 | Video Embedding | The license may permit the font to be incorporated in a video, so the font travels with the video. | NONE | NO_VALUE | NO_STRING |
10 | Application Embedding | The license may permit the font to be incorporated in a computer program/application, so the font travels with the computer program/application. | NONE | NO_VALUE | NO_STRING |
11 | Modifications | The license may permit font users to add to or modify a font (other than conversion, compression and subsetting, which are covered elsewhere). | NONE | NO_VALUE | When value1 is ALLOWED_COND or DISALLOWED_COND the string defines an addition or modification. Otherwise, NO_STRING |
12 | License Transfer | The license may permit the font to be transferred to a third party. | NONE | NO_VALUE | If value1 is ALLOWED_COND or DISALLOWED_COND the string defines the license transfer conditions. Otherwise, NO_STRING |
13 | Sharing | The license may permit the font to be shared with a service bureau. | NONE | NO_VALUE | If value1 is ALLOWED_COND or DISALLOWED_COND the string defines the sharing conditions. Otherwise, NO_STRING |
ALL == 1
NONE == 2
ALLOWED_COND == 3
DISALLOWED_COND == 4
EMBED_DISPLAY == 5
EMBED_EDITABLE == 6
EMBED_INSTALLABLE == 7
EMBED_PRINT_AND_DISPLAY == 8
EMBED_PRINT_AND_REVIEW == 9
LINK_METHOD == 10
LINK_SOURCE == 11
LINK_TYPE == 12
METER_DAY == 14
METER_DOWNLOAD == 16
METER_HOUR == 13
METER_USE == 17
METER_YEAR == 15
SITE_ADDRESS == 18
SITE_BACKUP == 19
SITE_COUNTRY == 20
SITE_LAN == 21
SITE_ORGANIZATION == 22
SITE_WAN == 23
SITE_WWW == 24
UNIT_DEVICES == 25
UNIT_PRINTERS == 26
UNIT_SERVERS == 27
UNIT_USERS == 28
UNIT_WORKSTATIONS == 29
UNLIMITED == 0xFFFFFFFF
NO_VALUE == 0
LINK_METHOD_ACCESSIBLE == 1
LINK_METHOD_PROTECTED == 2
LINK_SOURCE_ROOT_STRING == 2
LINK_SOURCE_SAME_ORIGIN == 1
LINK_SOURCE_SUB_LICENSE == 3
LINK_TYPE_DISPLAY_PRINT == 1
LINK_TYPE_EDIT_PRINT == 2
NO_STRING == 0xFFFF
There may be zero or more recommendation records. Each recommendation record has the following structure:
Type | Name | Description |
USHORT | recommendationID | Identifies the kind of recommendation |
USHORT | value1 | First value of the record. |
FIXED | value2 | Second value of the record. |
USHORT | StringIndex | Zero-based index of the string storage entry related to the record. |
The meaning of the value1, value2 and fields depend on the recommendation record type (see the list below).
There could be more than one recommendation record with the same recommendationID. If two records with the same ID overlap, then the most restrictive value should be applied (for example, if there are two "maximum" records of 10 and 13, then 10 is used). Other records are additive. For example, one record with recommendation ID = 11 (scaling) may have value1 = 1 (optimal text size in points) and another, with the same ID will have value1 = 4, defining minimal recommended display size (in points). All other values will remain undefined.
The recommendations are:
ID | Name | Description | value1 | value2 | StringIndex |
1 | XY Scaling | Recommendation for use of the font when scaling x or y alone, expressed as % of default font proportions. | NOT_RECOMMENDED | If value1 is NOT_RECOMMENDED, NO_VALUE Otherwise the range is integers 0..100 | NO_STRING |
2 | Bold | Recommendation for bolding of the font expressed as a weight increase in % of em. | NOT_RECOMMENDED | If value1 is BOLD_MAXIMUM, the range is integers 0..20 Otherwise, NO_VALUE | NO_STRING |
3 | Curvebase | Recommendation for use of the font with curved baseline. | NOT_RECOMMENDED | NO_VALUE | If value1 is CURVEBASE, the string defines the recommendation. Otherwise, NO_STRING |
4 | Decontext | Recommendation for use of the font without feature tabregarding glyph substitution. | NOT_RECOMMENDED | NO_VALUE | If value1 is DECONTEXT, the string defines the recommendation. Otherwise, NO_STRING |
5 | Decompose | Recommendation for use of the font with decomposed glyphs. | NOT_RECOMMENDED, | NO_VALUE | If value1 is DECOMPOSE, the string defines the recommendation. Otherwise, NO_STRING |
6 | Justify | Recommendation regarding the addition of inter-letter space to fit a line to a column width. | NOT_RECOMMENDED | If value1 is JUSTIFY, the range is FALSE or TRUE. Otherwise, NO_VALUE | NO_STRING |
7 | Hyphen | Recommendation regarding text-hyphenation at line ends. | NOT_RECOMMENDED | If value1 is HYPHEN, the range is FALSE or TRUE. Otherwise, NO_VALUE | NO_STRING |
8 | Letter Space | Recommendation for adding or removing space between letters specified as a % of em. | NOT_RECOMMENDED | If value1 is LTRSPACE_MINIMUM, the range is integers -50..0. If value1 is LTRSPACE_MAXIMUM, the range is integers 0..200. Otherwise, NO_VALUE | NO_STRING |
9 | Oblique Angle | Recommendation for artificial slanting of the font, specified in degrees from the vertical. | NOT_RECOMMENDED | Specified in degrees from vertical. If value1 is OBLIQUE_LEFT_MAX, the range is integers --90..0. If value1 is OBLIQUE_RIGHT_MAX, the range is | NO_STRING |
10 | Overscale | Recommendation for minimal scaling of the font. | NOT_RECOMMENDED | If value1 is NOT_RECOMMENDED, NO_VALUE. If value1 is OVERSCALE_CRITICAL_PART_MINIMUM, the range is integers -50..0 [percent of em] If value1 is OVERSCALE_UPM_PER_PIXEL_MAXIMUM, the range is If value1 is OVERSCALE_X_HT_PIXELS_MINIMUM, the range is | NO_STRING |
11 | Scaling | Recommendation for optimal scaling of the font. | SCALING_DISPLAY_PIXELS_MINIMAL | SCALING_TEXT_POINTS_OPTIMAL range integers 4..18 SCALING_TEXT_POINTS_MINIMAL range integers 4..18 SCALING_DISPLAY_POINTS_MINIMAL range integers 14..144 SCALING_DISPLAY_POINTS_OPTIMAL range integers 14..144 SCALING_TEXT_PIXELS_OPTIMAL range integers 6..2048 SCALING_TEXT_PIXELS_MINIMAL range integers 6..256 SCALING_DISPLAY_PIXELS_OPTIMAL range integers 10..2048 SCALING_DISPLAY_PIXELS_MINIMAL range integers 10..256 | NO_STRING |
12 | Strike | Recommendation for an automatically generated stroke through the glyph. | NOT_RECOMMENDED | If value1 is STRIKE, the range is FALSE or TRUE. Otherwise, NO_VALUE | NO_STRING |
13 | Stroke | Recommendation for definition of the font’s contours as other than zero stroke width, specified as the maximum recommended width in % of UPM. | NOT_RECOMMENDED | If value1 is STROKE, the range is fixed (1 digit) 0.1..100 Otherwise, NO_VALUE | NO_STRING |
14 | Textset | Recommendation for the ideal length of a line of text, specified in maximum number of words. | NOT_RECOMMENDED | If value1 is TEXTSET, the range is integer 1..2048. Otherwise, NO_VALUE | NO_STRING |
15 | Uninstruct | Recommendation for the use of the glyph table’s TrueType instructions, specified as the minimum pixels per em. | NOT_RECOMMENDED | Range is integer 0..32767 Otherwise, NO_VALUE | NO_STRING |
16 | Unkern | Recommendation for pair kerning. | NOT_RECOMMENDED | If value1 is UNKERN_BELOW_PERCENT_OF_EM, the range is integer -100..1000. Otherwise, NO_VALUE | NO_STRING |
17 | Underscore | Recommendation for an automatically generated stroke below the glyph. | NOT_RECOMMENDED | If value1 is UNDERSCORE, the range is FALSE or TRUE. Otherwise, NO_VALUE | If value1 is UNDERSCORE, the string defines the recommendation. Otherwise, NO_STRING |
NOT_RECOMMENDED == 1
BLINKING == 2
BOLD_MAXIMUM == 3
CURVEBASE == 4
DECOMPOSE == 5
DECONTEXT == 6
HYPHEN == 7
JUSTIFY == 8
LTRSPACE_MAXIMUM == 9
LTRSPACE_MINIMUM == 10
OBLIQUE_LEFT_MAXIMUM == 11
OBLIQUE_RIGHT_MAXIMUM == 12
OVERSCALE_CRITICAL_PART_MINIMUM == 13
OVERSCALE_UPM_PER_PIXEL_MAXIMUM == 14
OVERSCALE_XHT_PIXELS_MINIMUM == 15
SCALING_DISPLAY_PIXELS_MINIMAL == 16
SCALING_DISPLAY_PIXELS_OPTIMAL == 17
SCALING_DISPLAY_POINTS_MINIMAL == 18
SCALING_DISPLAY_POINTS_OPTIMAL == 19
SCALING_TEXT_PIXELS_MINIMAL == 20
SCALING_TEXT_PIXELS_OPTIMAL == 21
SCALING_TEXT_POINTS_MINIMAL == 22
SCALING_TEXT_POINTS_OPTIMAL == 23
STRIKE == 24
STROKE_MAXIMUM == 25
TEXTSET == 26
UNDERSCORE == 27
UNINSTRUCT_NO_INSTRUCTIONS == 28
UNINSTRUCT_NO_X_INSTRUCTIONS == 29
UNINSTRUCT_NO_Y_INSTRUCTIONS == 30
UNKERN_BELOW_14_POINTS == 31
UNKERN_BELOW_67_POINTS == 32
UNKERN_BELOW_PERCENT_OF_EM == 33
XY_SCALING_X_MAXIMUM == 34
XY_SCALING_X_MINIMUM == 35
XY_SCALING_Y_MAXIMUM == 36
XY_SCALING_Y_MINIMUM == 37
NO_VALUE == 0
NO_STRING == 0xFFFF
Reference to the externally defined full-text information related to the content of the EPAR table can be stored as several EULA Information records:
Type | Name | Description |
USHORT | informationID | ID of the information record (see the list below) |
USHORT | StringIndex | Zero-based index of the string storage entry related to the record. URL for the record. The languageID for this record is relevant to the linked content, not to the URL itself. |
The EULA information that can be specified is::
ID | Name | Description |
1 | Full EULA URL | The EPAR can only give a summary of the most important parts of a EULA. In order to give the licensee access to the complete (and legally binding) EULA text the EULA should be accessible on the Internet. This field is for the URL where the full EULA is located. |
2 | Remote EPAR URL | The EPAR can also be accessed on a remote server. This field is for the URL/file where the remote EPAR is located. This is particularly useful for large license where many copies would need to be updated if there was a license change. Rather than read the EPAR data from the local table the application would read it from the remote EPAR file maintained by the vendor. Any values in the local EPAR are overridden by values in the remote EPAR. |
3 | License upgrade URL | If a licensee finds that their license is inadequate for their purposes then they should have a way to contact the vendor and arrange for a license upgrade (e.g. more users, more locations, more embedding, etc.) that will allow them to use the font as needed. This field is for the URL of the license upgrade web page or equivalent. |
String storage is organized into three parts (in the following order):
Each fixed-length multi-language string record represents a list of strings in different languages (the first of which must be US English). The StringIndex in a permission or recommendation record is a zero-based index into this list.
Each multi-language string record has the following structure:
Type | Name | Description |
USHORT | entriesCount | Number of language entries for the string record. |
USHORT | contentIndex | Zero-based index of the first language entry in the content list |
The content list has one record for each individual string.
In version 1 of the EPAR Table, the only languageID used is 0x0409, English – United States.
Each content record has the following structure:
Type | Name | Description |
USHORT | languageID | Language ID for this content entry. Corresponds to the LCID from the Windows Language IDs (platform ID = 3) list of the Naming Table definition. |
USHORT | length | Number of bytes in the referenced UTF-16BE encoded string. |
ULONG | stringOffset | Offset from the beginning of the string data. US English entry is required for any String and must come first in the content table for the string. |
A sequence of variable-length strings, each of which is encoded according to the UTF-16BE encoding scheme.