or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

attributed-string.mddecoration-script.mdengines.mdindex.mdlayout-engine.md

decoration-script.mddocs/

0

# Text Decoration & Script Processing

1

2

Utilities for text decoration (underlines, strike-through) and Unicode script processing for proper text rendering across different writing systems.

3

4

## Capabilities

5

6

### Text Decoration Engine

7

8

Generates decoration lines for text including underlines and strike-through effects. Calculates proper positioning, thickness, and styling for decorations based on font metrics.

9

10

```typescript { .api }

11

/**

12

* Creates a text decoration engine for generating underlines and strike-through

13

* @returns Function that adds decoration lines to attributed string lines

14

*/

15

function textDecoration(): (line: AttributedString) => AttributedString;

16

```

17

18

**Usage Example:**

19

20

```typescript

21

import { textDecoration } from "@react-pdf/textkit";

22

23

// Create decoration engine

24

const decorationEngine = textDecoration();

25

26

// Apply decorations to a line with underline and strike attributes

27

const decoratedLine = decorationEngine(line);

28

29

// The engine will add decorationLines to the AttributedString

30

console.log(decoratedLine.decorationLines);

31

```

32

33

The text decoration engine processes runs with the following attributes:

34

- `underline`: Creates underline decoration

35

- `underlineColor`: Sets underline color (default: "black")

36

- `underlineStyle`: Sets underline style (default: "solid")

37

- `strike`: Creates strike-through decoration

38

- `strikeColor`: Sets strike-through color (default: "black")

39

- `strikeStyle`: Sets strike-through style (default: "solid")

40

41

### Script Itemization Engine

42

43

Performs Unicode script itemization by analyzing text and grouping consecutive characters with the same script. This is essential for proper text shaping and rendering, especially for complex scripts and mixed-language text.

44

45

```typescript { .api }

46

/**

47

* Creates a script itemization engine for Unicode script analysis

48

* @returns Function that groups attributed string characters by Unicode script

49

*/

50

function scriptItemizer(): (attributedString: AttributedString) => AttributedString;

51

```

52

53

**Usage Example:**

54

55

```typescript

56

import { scriptItemizer } from "@react-pdf/textkit";

57

58

// Create script itemizer

59

const scriptEngine = scriptItemizer();

60

61

// Process mixed-script text

62

const mixedText = fromFragments([

63

{ string: "Hello مرحبا" } // Latin + Arabic

64

]);

65

66

const itemizedString = scriptEngine(mixedText);

67

68

// Results in runs grouped by script:

69

// Run 1: "Hello " (script: "Latin")

70

// Run 2: "مرحبا" (script: "Arabic")

71

```

72

73

The script itemizer:

74

- Analyzes each character's Unicode script property

75

- Groups consecutive characters with the same script into runs

76

- Ignores "Common", "Inherited", and "Unknown" scripts

77

- Creates runs with `script` attribute set to the detected script name

78

79

### Word Hyphenation Engine

80

81

Provides word hyphenation functionality using the hyphen library with English (US) patterns. Splits words into syllable parts for line breaking purposes.

82

83

```typescript { .api }

84

/**

85

* Creates a word hyphenation engine using English hyphenation patterns

86

* @returns Function that splits words into hyphenation syllables

87

*/

88

function wordHyphenation(): (word: string | null) => string[];

89

```

90

91

**Usage Example:**

92

93

```typescript

94

import { wordHyphenation } from "@react-pdf/textkit";

95

96

// Create hyphenation engine

97

const hyphenationEngine = wordHyphenation();

98

99

// Hyphenate words

100

const syllables1 = hyphenationEngine("hyphenation");

101

// Result: ["hy", "phen", "ation"]

102

103

const syllables2 = hyphenationEngine("beautiful");

104

// Result: ["beau", "ti", "ful"]

105

106

const syllables3 = hyphenationEngine("cat");

107

// Result: ["cat"] (single syllable)

108

109

// Handles null input

110

const syllables4 = hyphenationEngine(null);

111

// Result: []

112

```

113

114

The hyphenation engine:

115

- Uses cached results for performance

116

- Supports soft hyphen (`\u00ad`) in input words

117

- Returns array of syllable parts

118

- Returns empty array for null input

119

- Uses English (US) hyphenation patterns by default

120

121

## Text Decoration Types

122

123

```typescript { .api }

124

interface DecorationLine {

125

rect: Rect;

126

opacity: number;

127

color: string;

128

style: string;

129

}

130

131

interface Rect {

132

x: number;

133

y: number;

134

width: number;

135

height: number;

136

}

137

```

138

139

## Decoration Calculation

140

141

The text decoration engine calculates decoration properties as follows:

142

143

### Underline Positioning

144

- **Y Position**: `ascent(line) + thickness * 2`

145

- **Thickness**: `Math.max(0.5, Math.floor(fontSize / 12))`

146

- **Width**: Constrained by line width and overflow settings

147

148

### Strike-through Positioning

149

- **Y Position**: `ascent(line) - runAscent(run) / 3`

150

- **Thickness**: Same as underline

151

- **Width**: Same as underline

152

153

### Color and Style

154

- Uses `underlineColor`/`strikeColor` attributes or defaults to "black"

155

- Uses `underlineStyle`/`strikeStyle` attributes or defaults to "solid"

156

- Respects `opacity` attribute from run

157

158

## Script Processing

159

160

The script itemizer recognizes all Unicode scripts and creates appropriate groupings for:

161

162

- **Latin scripts**: English, European languages

163

- **Arabic scripts**: Arabic, Persian, Urdu

164

- **Cyrillic scripts**: Russian, Bulgarian, Serbian

165

- **CJK scripts**: Chinese, Japanese, Korean

166

- **Indic scripts**: Hindi, Tamil, Bengali

167

- **And many others**: As defined by Unicode properties

168

169

Scripts marked as "Common", "Inherited", or "Unknown" are ignored during itemization, allowing surrounding script context to determine grouping.