or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-api.mdconfiguration.mddocument-api.mdeditor-api.mdindex.mdrendering-api.mdtext-layer.mdxfa-api.md

text-layer.mddocs/

0

# Text Layer API

1

2

Text layer functionality for extracting, searching, and enabling text selection within PDF documents. The text layer renders transparent, selectable text elements over the PDF canvas.

3

4

## Capabilities

5

6

### Text Layer Rendering

7

8

Creates a selectable text layer that overlays the PDF page canvas, enabling text selection, copying, and searching.

9

10

```javascript { .api }

11

class TextLayer {

12

/**

13

* Constructor for text layer

14

* @param parameters - Text layer construction parameters

15

*/

16

constructor(parameters: TextLayerConstructorParameters);

17

18

/**

19

* Render text layer over PDF page

20

* @returns Promise that resolves when rendering is complete

21

*/

22

render(): Promise<void>;

23

24

/**

25

* Update existing text layer

26

* @param parameters - Text layer update parameters

27

*/

28

update(parameters: TextLayerUpdateParameters): void;

29

30

/**

31

* Cancel text layer rendering

32

*/

33

cancel(): void;

34

35

/** HTML elements that correspond to the text items */

36

get textDivs(): HTMLElement[];

37

}

38

```

39

40

### Text Layer Constructor Parameters

41

42

Configuration for creating a text layer instance.

43

44

```javascript { .api }

45

interface TextLayerConstructorParameters {

46

/** Text content source (from page.getTextContent()) */

47

textContentSource: ReadableStream | Promise<TextContent> | TextContent;

48

/** Container element for text layer */

49

container: HTMLElement;

50

/** Page viewport for positioning */

51

viewport: PageViewport;

52

}

53

```

54

55

**Usage Examples:**

56

57

```javascript

58

import { TextLayer } from "pdfjs-dist";

59

60

// Get text content from page

61

const textContent = await page.getTextContent();

62

63

// Create text layer container

64

const textLayerDiv = document.createElement("div");

65

textLayerDiv.className = "textLayer";

66

document.body.appendChild(textLayerDiv);

67

68

// Create and render text layer

69

const textLayer = new TextLayer({

70

textContentSource: textContent,

71

container: textLayerDiv,

72

viewport: viewport

73

});

74

75

await textLayer.render();

76

console.log("Text layer rendered");

77

```

78

79

80

### Text Layer Update Parameters

81

82

Configuration for updating an existing text layer.

83

84

```javascript { .api }

85

interface TextLayerUpdateParameters {

86

/** New viewport for repositioning */

87

viewport: PageViewport;

88

/** Callback invoked before the text layer is updated */

89

onBefore?: () => void;

90

}

91

```

92

93

**Usage Examples:**

94

95

```javascript

96

// Update text layer when viewport changes

97

const newViewport = page.getViewport({ scale: 2.0 });

98

99

textLayer.update({

100

viewport: newViewport,

101

onBefore: () => console.log("Updating text layer")

102

});

103

```

104

105

106

### Text Content Interfaces

107

108

Data structures for text content and positioning.

109

110

```javascript { .api }

111

interface TextContent {

112

/** Array of text items on the page */

113

items: TextItem[];

114

/** Font and style information */

115

styles: { [fontName: string]: TextStyle };

116

/** Page language */

117

lang?: string;

118

}

119

120

interface TextItem {

121

/** Text string content */

122

str: string;

123

/** Text direction (left-to-right, right-to-left, top-to-bottom) */

124

dir: "ltr" | "rtl" | "ttb";

125

/** Text width in user space units */

126

width: number;

127

/** Text height in user space units */

128

height: number;

129

/** Transformation matrix [a, b, c, d, e, f] */

130

transform: number[];

131

/** Font name reference */

132

fontName: string;

133

/** Whether text has end-of-line marker */

134

hasEOL?: boolean;

135

}

136

137

interface TextStyle {

138

/** Font ascent */

139

ascent: number;

140

/** Font descent */

141

descent: number;

142

/** Whether font is vertical */

143

vertical?: boolean;

144

/** CSS font family */

145

fontFamily: string;

146

}

147

```

148

149

### Text Layer Utilities

150

151

Helper functions for text layer management.

152

153

```javascript { .api }

154

/**

155

* Get text layer builder for custom text layer implementation

156

* @param options - Builder options

157

* @returns Text layer builder instance

158

*/

159

function getTextLayerBuilder(options: any): any;

160

161

/**

162

* Normalize Unicode text for better searching

163

* @param text - Input text

164

* @returns Normalized text

165

*/

166

function normalizeUnicode(text: string): string;

167

```

168

169

**Usage Examples:**

170

171

```javascript

172

// Extract plain text from text content

173

function extractPlainText(textContent) {

174

return textContent.items

175

.map(item => item.str + (item.hasEOL ? '\n' : ''))

176

.join('');

177

}

178

179

// Find text positions for highlighting

180

function findTextPositions(textContent, searchTerm) {

181

const positions = [];

182

let currentIndex = 0;

183

184

textContent.items.forEach((item, index) => {

185

if (item.str.toLowerCase().includes(searchTerm.toLowerCase())) {

186

positions.push({

187

index: index,

188

item: item,

189

coordinates: {

190

x: item.transform[4],

191

y: item.transform[5],

192

width: item.width,

193

height: item.height

194

}

195

});

196

}

197

});

198

199

return positions;

200

}

201

202

// Create searchable text layer with highlighting

203

async function createSearchableTextLayer(page, container, viewport) {

204

const textContent = await page.getTextContent({

205

normalizeWhitespace: true

206

});

207

208

const textLayer = new TextLayer({

209

textContentSource: textContent,

210

container: container,

211

viewport: viewport

212

});

213

214

await textLayer.render();

215

216

// Enable text search

217

return {

218

textContent: textContent,

219

search: (term) => findTextPositions(textContent, term),

220

extractText: () => extractPlainText(textContent)

221

};

222

}

223

```

224

225

### CSS Styling

226

227

The text layer requires CSS styling for proper positioning and appearance:

228

229

```css

230

.textLayer {

231

position: absolute;

232

left: 0;

233

top: 0;

234

right: 0;

235

bottom: 0;

236

overflow: hidden;

237

opacity: 0.2;

238

line-height: 1.0;

239

}

240

241

.textLayer > span {

242

color: transparent;

243

position: absolute;

244

white-space: pre;

245

cursor: text;

246

transform-origin: 0% 0%;

247

}

248

249

.textLayer .highlight {

250

background-color: rgba(180, 0, 170, 0.2);

251

}

252

253

.textLayer .highlight.appended {

254

background-color: rgba(0, 100, 0, 0.2);

255

}

256

257

.textLayer .highlight.begin {

258

background-color: rgba(255, 255, 0, 0.2);

259

}

260

261

.textLayer .highlight.end {

262

background-color: rgba(255, 0, 0, 0.2);

263

}

264

265

.textLayer .highlight.middle {

266

background-color: rgba(255, 255, 0, 0.2);

267

}

268

269

.textLayer .highlight.selected {

270

background-color: rgba(0, 100, 0, 0.2);

271

}

272

```

273

274

### Advanced Text Layer Features

275

276

```javascript { .api }

277

/**

278

* Enhanced text layer with search and highlight capabilities

279

*/

280

interface EnhancedTextLayer {

281

/** Highlight text matching search term */

282

highlightText(searchTerm: string, className?: string): void;

283

284

/** Clear all highlights */

285

clearHighlights(): void;

286

287

/** Get text in selection */

288

getSelectedText(): string;

289

290

/** Get all text content as string */

291

getAllText(): string;

292

293

/** Find and scroll to text */

294

findAndScrollTo(searchTerm: string): boolean;

295

}

296

```

297

298

**Usage Examples:**

299

300

```javascript

301

// Complete text layer implementation with search

302

class SearchableTextLayer {

303

constructor(page, container, viewport) {

304

this.page = page;

305

this.container = container;

306

this.viewport = viewport;

307

this.textContent = null;

308

this.textDivs = [];

309

}

310

311

async render() {

312

this.textContent = await this.page.getTextContent({

313

normalizeWhitespace: true

314

});

315

316

this.textLayer = new TextLayer({

317

textContentSource: this.textContent,

318

container: this.container,

319

viewport: this.viewport

320

});

321

322

await this.textLayer.render();

323

this.textDivs = this.textLayer.textDivs;

324

}

325

326

search(term) {

327

this.clearHighlights();

328

329

const normalizedTerm = term.toLowerCase();

330

let matches = [];

331

332

this.textContent.items.forEach((item, index) => {

333

const normalizedText = item.str.toLowerCase();

334

if (normalizedText.includes(normalizedTerm)) {

335

matches.push(index);

336

if (this.textDivs[index]) {

337

this.textDivs[index].classList.add('highlight');

338

}

339

}

340

});

341

342

return matches;

343

}

344

345

clearHighlights() {

346

this.textDivs.forEach(div => {

347

div.classList.remove('highlight');

348

});

349

}

350

}

351

```