The DocInfo stream holds what the whole document shares: its
properties, the pictures it embeds, its fonts, border and fill definitions, character
shapes, tab stops, numbering, bullets, paragraph shapes and styles. Each is a
record; the paragraphs in
the sections refer to them by their position in their own list, counting from 0. This
page follows Hancom’s HWP 5.0 specification, revision 1.3 (8 November 2018), section
4.2, with its table numbers. Numbers are little-endian; lengths are in HWPUNIT,
1/7200 inch, unless stated.
Record order
| Tag | Name | Level | Size in the overview table | Contents |
|---|---|---|---|---|
0x10 | HWPTAG_DOCUMENT_PROPERTIES | 0 | 30 | Document properties |
0x11 | HWPTAG_ID_MAPPINGS | 0 | 32 | How many of each list follow |
0x12 | HWPTAG_BIN_DATA | 1 | varies | One picture or object |
0x13 | HWPTAG_FACE_NAME | 1 | varies | One font |
0x14 | HWPTAG_BORDER_FILL | 1 | varies | Borders and background |
0x15 | HWPTAG_CHAR_SHAPE | 1 | 72 | Character shape |
0x16 | HWPTAG_TAB_DEF | 1 | 14 | Tab stops |
0x17 | HWPTAG_NUMBERING | 1 | varies | Paragraph numbering |
0x18 | HWPTAG_BULLET | 1 | 10 | Bullet |
0x19 | HWPTAG_PARA_SHAPE | 1 | 54 | Paragraph shape |
0x1A | HWPTAG_STYLE | 1 | varies | Style |
0x5C | HWPTAG_MEMO_SHAPE | 1 | 22 | Memo shape |
0x61 | HWPTAG_TRACK_CHANGE_AUTHOR | 1 | varies | Author of tracked changes |
0x60 | HWPTAG_TRACK_CHANGE | 1 | varies | Tracked change contents and shape |
0x1B | HWPTAG_DOC_DATA | 0 | varies | Document data (parameter sets) |
0x5E | HWPTAG_FORBIDDEN_CHAR | 0 | varies | Line-breaking forbidden characters |
0x1E | HWPTAG_COMPATIBLE_DOCUMENT | 0 | 4 | Target program |
0x1F | HWPTAG_LAYOUT_COMPATIBILITY | 1 | 20 | Layout compatibility |
0x1C | HWPTAG_DISTRIBUTE_DOC_DATA | 0 | 256 | Distribution document data |
0x20 | HWPTAG_TRACKCHANGE | 1 | 1032 | Change tracking information |
The order is the specification’s table 4. Its sizes do not always match the field
tables further on (document properties 30 against 26, character shape 72 against 74,
bullet 10 against 20, tab definition 14 against 8 + 8 per tab), so a reader should go
by the size in each record header and ignore bytes at the end it does not know.
0x1D (HWPTAG_BEGIN + 13) is reserved.
HWPTAG_DOCUMENT_PROPERTIES
| Offset | Type | Field |
|---|---|---|
0 | UINT16 | Number of sections (the number of BodyText/Sectionn streams) |
2 | UINT16 | First page number |
4 | UINT16 | First footnote number |
6 | UINT16 | First endnote number |
8 | UINT16 | First picture number |
10 | UINT16 | First table number |
12 | UINT16 | First equation number |
14 | UINT32 | Caret position: list ID |
18 | UINT32 | Caret position: paragraph ID |
22 | UINT32 | Caret position: character position in the paragraph |
26 bytes (table 14).
HWPTAG_ID_MAPPINGS
An array of INT32 counts, 72 bytes for 18 entries; older documents have fewer, so the length depends on the document version (table 15). Each count says how many records of that kind follow, in this order (table 16):
| Index | Count of | Index | Count of |
|---|---|---|---|
| 0 | Binary data (BIN_DATA) | 9 | Character shapes |
| 1 | Korean (Hangul) fonts | 10 | Tab definitions |
| 2 | English fonts | 11 | Numberings |
| 3 | Hanja (Chinese character) fonts | 12 | Bullets |
| 4 | Japanese fonts | 13 | Paragraph shapes |
| 5 | Other fonts | 14 | Styles |
| 6 | Symbol fonts | 15 | Memo shapes (from version 5.0.2.1) |
| 7 | User fonts | 16 | Tracked changes (from 5.0.3.2) |
| 8 | Border and fill definitions | 17 | Tracked-change authors (from 5.0.3.2) |
The seven font lists follow one after another, so a character shape’s font ID for English is a position in the English list. pyhwp, the open-source reader, reads the memo shape count from version 5.0.1.7.
HWPTAG_BIN_DATA
| Type | Field | Present when |
|---|---|---|
| UINT16 | Properties (below) | Always |
| WORD + WCHAR[len1] | Absolute path of the linked file | Type is LINK |
| WORD + WCHAR[len2] | Relative path of the linked file | Type is LINK |
| UINT16 | ID of the data in the BinData storage | Type is EMBEDDING or STORAGE |
| WORD + WCHAR[len3] | Format, as an extension without the dot: jpg, bmp, gif for pictures, ole for OLE objects | Type is EMBEDDING |
| Bits | Value | Meaning (table 18) |
|---|---|---|
| 0–3 type | 0x0000 | LINK: a picture in an outside file |
0x0001 | EMBEDDING: a picture file inside the document | |
0x0002 | STORAGE: an embedded OLE object | |
| 4–5 compression | 0x0000 | As the storage’s default (the file header’s compression flag) |
0x0010 | Always compressed | |
0x0020 | Never compressed | |
| 8–9 state | 0x0000 | Not yet accessed |
0x0100 | Accessed and the file found | |
0x0200 | Access failed | |
0x0300 | Link access failed, and the failure ignored |
An embedded item is the stream BinData/BINxxxx.ext, with
the ID as four hexadecimal digits, for example BIN0001.jpg (the naming is
pyhwp’s; the specification only says each item is its own stream). The specification
puts the state in bits 8–9, which settles an older reading of bits 16–17.
HWPTAG_FACE_NAME
| Type | Field |
|---|---|
| BYTE | Properties: 0x80 an alternative font follows; 0x40 font type information follows; 0x20 a default font follows (table 20) |
| WORD + WCHAR[len1] | Font name |
| BYTE | Alternative font type: 0 unknown, 1 TrueType (TTF), 2 Hangul’s own font (HFT) (table 21) |
| WORD + WCHAR[len2] | Alternative font name |
| BYTE[10] | Font type information: family, serif style, weight, proportion, contrast, stroke variation, arm style, letterform, midline, x-height, one byte each (table 22; the same ten classes as PANOSE) |
| WORD + WCHAR[len3] | Default font name |
The alternative font, the type information and the default font are there only when their property bit is set. Up to 18 + 2 × (len1 + len2 + len3) bytes.
HWPTAG_BORDER_FILL
Used by table cells, paragraphs, pages and character borders. Table 23:
| Offset | Type | Field |
|---|---|---|
0 | UINT16 | Properties (below) |
2 | UINT8[4] | Line type of the four borders (line types) |
6 | UINT8[4] | Line width of the four borders (widths) |
10 | COLORREF[4] | Colour of the four borders |
26 | UINT8 | Diagonal type: 0 slash, 1 backslash, 2 crooked slash (table 27) |
27 | UINT8 | Diagonal width |
28 | COLORREF | Diagonal colour |
32 | bytes | Fill information |
The specification lists the four types, then the four widths, then the four colours. pyhwp, which is tested against real files, reads them side by side instead, five bytes per border (type, width, colour) for left, right, top and bottom, then the diagonal the same way; the 32 bytes are the same either way. The order of the four sides is not given in the specification.
| Bits | Meaning (table 24) |
|---|---|
| 0 | 3D effect |
| 1 | Shadow effect |
| 2–4 | Slash diagonals, one bit per line clockwise: 000 none, 010 slash, 011 top left to the bottom edge, 110 top left to the right edge, 111 top left to the bottom and right edges |
| 5–7 | Backslash diagonals, anticlockwise: 000 none, 010 backslash, 011 top right to the bottom edge, 110 top right to the left edge, 111 top right to the bottom and left edges |
| 8–9 | Slash diagonal is a bent line |
| 10 | Backslash diagonal is a bent line |
| 11 | Slash diagonal rotated 180° |
| 12 | Backslash diagonal rotated 180° |
| 13 | Centre line |
Line types
Table 25, also used for underlines, strikethroughs, tab leaders, footnote separators and column lines.
| Value | Line | Value | Line |
|---|---|---|---|
| 0 | Solid | 9 | Double: thick then thin |
| 1 | Long dashes | 10 | Triple: thin, thick, thin |
| 2 | Dots | 11 | Wave |
| 3 | Dash dot (-.-.-.-.) | 12 | Double wave |
| 4 | Dash dot dot (-..-..-..) | 13 | Thick 3D |
| 5 | Dashes longer than the dash | 14 | Thick 3D, light from the other side |
| 6 | Circles larger than the dot | 15 | 3D single line |
| 7 | Double | 16 | 3D single line, light from the other side |
| 8 | Double: thin then thick |
Line widths
| Value | Width | Value | Width |
|---|---|---|---|
| 0 | 0.1 mm | 8 | 0.6 mm |
| 1 | 0.12 mm | 9 | 0.7 mm |
| 2 | 0.15 mm | 10 | 1.0 mm |
| 3 | 0.2 mm | 11 | 1.5 mm |
| 4 | 0.25 mm | 12 | 2.0 mm |
| 5 | 0.3 mm | 13 | 3.0 mm |
| 6 | 0.4 mm | 14 | 4.0 mm |
| 7 | 0.5 mm | 15 | 5.0 mm |
Fill information
Table 28. Also used by drawing objects. A UINT32 fill type comes first; its bits say which of the parts below follow, in this order.
| Type | Field |
|---|---|
| UINT32 | Fill type: 0x00 none, 0x01 solid colour, 0x02 image, 0x04 gradient (bits can be combined) |
| Solid colour (bit 0x01) | |
| COLORREF | Background colour |
| COLORREF | Pattern colour |
| INT32 | Pattern: 1 horizontal lines, 2 vertical lines, 3 backslashes, 4 slashes, 5 crosses (+), 6 diagonal crosses (x) (table 29) |
| Gradient (bit 0x04) | |
| INT16 | Gradient type: 1 linear (stripes), 2 radial (circular), 3 conical, 4 square (table 30) |
| INT16 | Angle (start angle) |
| INT16 | Horizontal centre (X) |
| INT16 | Vertical centre (Y) |
| INT16 | Blur, 0–100 |
| INT16 | Number of colours, num (always 2 in Hangul Wordian, 2002 and SE) |
| INT32[num] | Positions where the colour changes; only when num > 2 |
| COLORREF[num] | Colours |
| Image (bit 0x02) | |
| BYTE | Image fill type |
| 5 bytes | Picture information |
| Then | |
| DWORD | Size of extra gradient data: 1 if the gradient bit is set, otherwise 0 |
| BYTE | Centre of the gradient blur, 0–100 (when that size is 1) |
| DWORD + bytes | Length and data of extra fill properties |
The tail of this table is unclear in the specification. pyhwp reads, after the three parts, a UINT32 and the blur-centre byte only when the gradient bit is set, and notes that the extra fill properties are present in some files and absent in others (seen in version 5.0.1.7).
Image fill types
| Value | Placement | Value | Placement |
|---|---|---|---|
| 0 | Tiled, everywhere | 8 | Bottom centre |
| 1 | Tiled across the top | 9 | Centre left |
| 2 | Tiled across the bottom | 10 | Top left |
| 3 | Tiled down the left | 11 | Bottom left |
| 4 | Tiled down the right | 12 | Centre right |
| 5 | Stretched to fit | 13 | Top right |
| 6 | Centred | 14 | Bottom right |
| 7 | Top centre | 15 | None |
Picture information
| Offset | Type | Field (table 32) |
|---|---|---|
0 | INT8 | Brightness |
1 | INT8 | Contrast |
2 | BYTE | Effect: 0 the real picture, 1 greyscale, 2 black and white, 4 8 × 8 pattern |
3 | UINT16 | ID of the BIN_DATA item (the picture) |
HWPTAG_CHAR_SHAPE
Seven-entry arrays hold one value per script, in the order Korean, English, Hanja, Japanese, other, symbol, user (table 34).
| Offset | Type | Field (table 33) |
|---|---|---|
0 | WORD[7] | Font ID per script: a position in that script’s font list |
14 | UINT8[7] | Width ratio per script, 50–200% |
21 | INT8[7] | Letter spacing per script, −50 to 50% |
28 | UINT8[7] | Relative size per script, 10–250% |
35 | INT8[7] | Vertical position per script, −100 to 100% |
42 | INT32 | Base size, 0 pt to 4096 pt |
46 | UINT32 | Properties (below) |
50 | INT8 | Shadow offset X, −100 to 100% |
51 | INT8 | Shadow offset Y, −100 to 100% |
52 | COLORREF | Text colour |
56 | COLORREF | Underline colour |
60 | COLORREF | Shade colour |
64 | COLORREF | Shadow colour |
68 | UINT16 | Character border and fill ID (from version 5.0.2.1) |
70 | COLORREF | Strikethrough colour (from 5.0.3.0) |
The fields add up to 74 bytes; the specification gives the total as 72. The base size
unit is not stated; Hangul’s unit HWPUNIT is 1/100 point, which fits the
4096-point limit. COLORREF is 0x00BBGGRR.
| Bits | Meaning (table 35) | Values |
|---|---|---|
| 0 | Italic | |
| 1 | Bold | |
| 2–3 | Underline position | 0 none, 1 below the text, 3 above the text |
| 4–7 | Underline line | A line type |
| 8–10 | Outline | 0 none, 1 solid, 2 dotted, 3 thick solid, 4 dashed (long dots), 5 dash dot, 6 dash dot dot |
| 11–12 | Shadow | 0 none, 1 separate (discontinuous), 2 continuous |
| 13 | Embossed | |
| 14 | Engraved | |
| 15 | Superscript | |
| 16 | Subscript | |
| 17 | Reserved | |
| 18–20 | Strikethrough | 0 none; other values not listed |
| 21–24 | Emphasis mark | 0 none, 1 filled dot above, 2 hollow circle above, 3 caron (ˇ), 4 tilde (˜), 5 middle dot (・), 6 colon (:) |
| 25 | Use the space width that suits the font | |
| 26–29 | Strikethrough line | A line type |
| 30 | Kerning |
pyhwp, from an earlier revision, names underline value 2 as a line through the text and reads bits 11–13 as the shadow; revision 1.3 has value 2 unlisted and the shadow in bits 11–12.
HWPTAG_TAB_DEF
| Offset | Type | Field (table 36) |
|---|---|---|
0 | UINT32 | Properties: bit 0 automatic tab at the left end of the paragraph (for hanging indents); bit 1 automatic tab at the right end (table 37) |
4 | 4 bytes | Number of tab stops, count |
| Then count times, 8 bytes each | ||
| +0 | HWPUNIT | Position |
| +4 | UINT8 | Kind: 0 left, 1 right, 2 centre, 3 decimal point |
| +5 | UINT8 | Leader: a line type |
| +6 | UINT16 | Reserved, to make 8 bytes |
The count is printed as INT16 but with a length of 4, and the total, 8 + 8 × count, needs 4 bytes; pyhwp reads it as a UINT32.
HWPTAG_NUMBERING
Outline and paragraph numbering for up to ten levels (table 38).
| Type | Field |
|---|---|
| Seven times, for levels 1–7 | |
| bytes | Paragraph head information |
| WORD + WCHAR[len] | Number format of the level (not used for bullets) |
| Then | |
| UINT16 | Start number |
| UINT32[7] | Start number of each level 1–7 (from version 5.0.2.5) |
| WORD + WCHAR[len], three times | Extended number formats of levels 8–10 |
| UINT32[3] | Start numbers of levels 8–10 (from 5.1.0.0) |
In a number format a caret before a character makes it a code: ^n shows
the path of levels (1.1.1.1.1.1.1) and ^N the same with a
full stop added at the end (1.1.1.1.1.1.1.). Other characters are shown
as they are.
Paragraph head information
| Offset | Type | Field (table 39) |
|---|---|---|
0 | UINT32 | Properties (below) |
4 | HWPUNIT16 | Width correction |
6 | HWPUNIT16 | Distance from the body text |
8 | UINT32 | Character shape ID of the number |
The specification gives the total as 8 bytes, but its fields take 12, and pyhwp reads 12.
| Bits | Meaning (table 40) | Values |
|---|---|---|
| 0–1 | Alignment of the number | 0 left, 1 centre, 2 right |
| 2 | Number width follows the width of the actual text | 0 no, 1 yes |
| 3 | Automatic hanging indent | 0 no, 1 yes |
| 4 | Kind of distance from the body text | 0 a ratio of the character size, 1 a value |
Number formats
Table 41 lists the number styles; the same codes are used for footnotes, endnotes and page numbers, which add more (see the footnote shape). The specification does not say which bits of this record hold them.
| Value | Style | Value | Style |
|---|---|---|---|
| 0 | 1, 2, 3 | 8 | 가, 나, 다 (Hangul syllables) |
| 1 | Circled 1, 2, 3 | 9 | Circled 가, 나, 다 |
| 2 | I, II, III | 10 | ㄱ, ㄴ, ㄷ (Hangul letters) |
| 3 | i, ii, iii | 11 | Circled ㄱ, ㄴ, ㄷ |
| 4 | A, B, C | 12 | 일, 이, 삼 (Korean number words) |
| 5 | a, b, c | 13 | 一, 二, 三 (Chinese numerals) |
| 6 | Circled A, B, C | 14 | Circled 一, 二, 三 |
| 7 | Circled a, b, c |
HWPTAG_BULLET
| Type | Field (table 42) |
|---|---|
| bytes | Paragraph head information |
| WCHAR | Bullet character |
| INT32 | Image bullet: 0 for a character bullet, otherwise the image’s ID |
| 4 bytes | Image bullet settings: contrast, brightness, effect and ID |
| WCHAR | Character of a check bullet |
The specification gives 20 bytes in all, counting the head information as 8; pyhwp notes that this table is incomplete and reads only the head information and the bullet character.
HWPTAG_PARA_SHAPE
| Offset | Type | Field (table 43) |
|---|---|---|
0 | UINT32 | Properties 1 (below) |
4 | INT32 | Left margin |
8 | INT32 | Right margin |
12 | INT32 | Indent (positive) or hanging indent (negative) |
16 | INT32 | Space above |
20 | INT32 | Space below |
24 | INT32 | Line spacing, used by Hangul 2007 and older (before version 5.0.2.5) |
28 | UINT16 | Tab definition ID |
30 | UINT16 | Numbering ID or bullet ID |
32 | UINT16 | Border and fill ID |
34 | INT16 | Paragraph border gap, left |
36 | INT16 | Paragraph border gap, right |
38 | INT16 | Paragraph border gap, top |
40 | INT16 | Paragraph border gap, bottom |
42 | UINT32 | Properties 2 (from version 5.0.1.7) |
46 | UINT32 | Properties 3 (from 5.0.2.5) |
50 | UINT32 | Line spacing (from 5.0.2.5) |
54 bytes. pyhwp notes that the four margins and spacings are stored at twice their value (in units of 1/14400 inch); the specification does not say so.
| Bits | Properties 1 (table 44) | Values |
|---|---|---|
| 0–1 | Line spacing kind (Hangul 2007 and older) | 0 by the characters (percent), 1 fixed, 2 margin only |
| 2–4 | Alignment | 0 justified, 1 left, 2 right, 3 centre, 4 distributed, 5 divided (spread at spaces only) |
| 5–6 | Line breaking of Latin text | 0 by word, 1 hyphenate, 2 by character |
| 7 | Line breaking of Korean text | 0 by word (eojeol), 1 by character |
| 8 | Snap to the page’s line grid | |
| 9–15 | Minimum space | 0–75% |
| 16 | Widow and orphan control | |
| 17 | Keep with the next paragraph | |
| 18 | Keep the paragraph together (paragraph protection) | |
| 19 | Always start a new page before the paragraph | |
| 20–21 | Vertical alignment | 0 by the font (baseline), 1 top, 2 centre, 3 bottom |
| 22 | Line height suits the font | |
| 23–24 | Paragraph head | 0 none, 1 outline, 2 number, 3 bullet |
| 25–27 | Paragraph level | Level 1–7 |
| 28 | Join the border with the neighbouring paragraphs | |
| 29 | Ignore the paragraph margins | |
| 30 | Paragraph tail shape |
| Bits | Properties 2 (table 45) |
|---|---|
| 0–1 | Single-line input |
| 2–3 | Reserved |
| 4 | Adjust the space between Korean and Latin text automatically |
| 5 | Adjust the space between Korean text and numbers automatically |
| Bits | Properties 3 (table 46) | Values |
|---|---|---|
| 0–4 | Line spacing kind | 0 by the characters, 1 fixed, 2 margin only, 3 at least |
HWPTAG_STYLE
| Type | Field (table 47) |
|---|---|
| WORD + WCHAR[len1] | Local name (on Korean Windows the Korean name) |
| WORD + WCHAR[len2] | English name |
| BYTE | Properties: bits 0–2 the kind, 0 paragraph style, 1 character style (table 48) |
| BYTE | ID of the next style (used for the paragraph after this one) |
| INT16 | Language ID |
| UINT16 | Paragraph shape ID; required for a paragraph style |
| UINT16 | Character shape ID; required for a character style |
12 + 2 × (len1 + len2) bytes. The language ID’s cross-reference in the specification points at the style kind table, and its values are not listed.
HWPTAG_DOC_DATA and parameter sets
Free-form document data, such as whether the document is a label document and the
print dialogue’s settings, stored as one parameter set (table 49). Control data
(HWPTAG_CTRL_DATA, for field names and hyperlinks) uses the same
structure.
| Type | Parameter set (table 50) |
|---|---|
| WORD | Parameter set ID |
| INT16 | Number of items, n |
| items | n parameter items |
| Type | Parameter item (table 51) |
|---|---|
| WORD | Item ID |
| WORD | Item type (below) |
| varies | Item data |
| Type value | Name | Stored as | Meaning (table 52) |
|---|---|---|---|
| 0 | PIT_NULL | UINT | Null |
| 1 | PIT_BSTR | WORD + WCHAR[len] | A string |
| 2 | PIT_I1 | UINT | INT8 |
| 3 | PIT_I2 | UINT | INT16 |
| 4 | PIT_I4 | UINT | INT32 |
| 5 | PIT_I | UINT | INT |
| 6 | PIT_UI1 | UINT | UINT8 |
| 7 | PIT_UI2 | UINT | UINT16 |
| 8 | PIT_UI4 | UINT | UINT32 |
| 9 | PIT_UI | UINT | UINT |
0x8000 | PIT_SET | Parameter set | A nested parameter set |
0x8001 | PIT_ARRAY | INT16 + parameter sets | A count, then that many parameter sets |
0x8002 | PIT_BINDATA | UINT16 | A binary data ID |
The parameter set and item IDs themselves are not listed in the specification.
HWPTAG_COMPATIBLE_DOCUMENT
A UINT32 target program (tables 54 and 55): 0 Hangul document (the current version), 1 compatible with Hangul 2007, 2 compatible with Microsoft Word.
HWPTAG_LAYOUT_COMPATIBILITY
Five UINT32 values, 20 bytes (table 56): character-level, paragraph-level, section-level, object-level and field-level formatting options. The meaning of their bits is not given.
Records without a layout
The specification names these records and their sizes but does not describe their
fields: HWPTAG_MEMO_SHAPE (22 bytes), HWPTAG_FORBIDDEN_CHAR
(the characters not allowed at the start or end of a line),
HWPTAG_TRACK_CHANGE, HWPTAG_TRACK_CHANGE_AUTHOR and
HWPTAG_TRACKCHANGE (1,032 bytes). Their contents are unknown here.
Sources
- Hangul document file format 5.0, revision 1.3 – Hancom’s specification (PDF, in Korean), section 4.2
- pyhwp – open-source reader whose models are cited where they differ from the specification (Python)