# Snippet Helpers

## Content

The code samples throughout the documentation use a set of helper functions defined in a Util class. These utilities simplify the examples by handling common tasks such as loading files, saving output, displaying images, or arranging comparison images.
These helpers are **not part of the DsPdfJS API**. They are provided only to keep the documentation samples concise. Developers who want to run the examples locally may copy these utilities into their own projects.

>type=note
> **Note:** Some utilities rely on browser APIs such as `fetch`, `Blob`, `document`, and `URL.createObjectURL`. These helpers are intended primarily for browser‑based examples. Where applicable, alternative implementations for Node.js environments are provided.

## Environment Setup

The following utilities help initialize and manage the DsPdfJS runtime when running documentation samples.

#### connect()

Initializes the DsPdfJS WebAssembly module and applies the license key.

```javascript
static async connect() {
    // connect only if necessary
    if (!DsPdf.instance?.isConnected) {
        // set path to DsPdf.wasm
        DsPdfConfig.wasmUrl = '/node_modules/@mescius/ds-pdf/assets/DsPdf.wasm';
        // set the license key
        await DsPdfConfig.setLicenseKey("YOUR_LICENSE_KEY");
        // connect to DsPdf
        const connected = await connectDsPdf();
        if (!connected) {
            throw new Error("Unable to connect to DsPdfJS Wasm module.");
        }
    }
}
```

#### disconnect()

Disconnects from the DsPdfJS WebAssembly module and releases resources.

```javascript
static disconnect() {
    if (this.isConnected) {
        disconnectDsPdf();
    }
}
```

#### isConnected()

Indicates whether the DsPdfJS runtime is currently connected.

```javascript
static get isConnected() {
    if (DsPdf.instance) {
        return DsPdf.instance.isConnected;
    }
    return false;
}
```

#### dsApiVersion()

Returns the version of the DsPdfJS API currently in use.

```javascript
static get dsApiVersion() {
    const ds = DsPdf.instance;
    if (!ds || !ds.isConnected) {
        return "Unknown";
    }
    return ds.version;
}
```

## Loading and Saving Files

These utilities simplify loading input files and saving generated output when running documentation samples.

### Browser Environment

#### loadFile()

Loads a file using the browser `fetch()` API and returns its contents as a `Uint8Array`.
Parameters

* filePath - A string representing the URL or relative path of the file to load.

```javascript
static async loadFile(filePath) {
    const response = await fetch(filePath);
    if (!response.ok) {
        throw new Error(`Unable to load file: ${response.statusText}`);
    }
    return new Uint8Array(await response.arrayBuffer());
}
```

#### saveFile()

Saves binary data to a file in the browser by creating a downloadable object URL.
Parameters

* fileName - Name of the file to download.
* bytes - A Uint8Array containing the file data.
* mimeType - MIME type of the file being saved.

```javascript
static saveFile(fileName, bytes, mimeType) {
    const arr = bytes;
    if (!mimeType) {
        mimeType = "application/pdf";
    }
    const blob = new Blob([arr.buffer], { type: mimeType });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    console.log(`saved '${mimeType}' file as ${fileName}`);
}
```

### Node.js Environment

When running samples in a Node.js environment, file loading and saving can be implemented using the `fs` module.

#### loadFile()

```typescript
import * as fs from 'fs';
import * as path from 'path';

export async function loadFile(filePath) {
    const buffer = await fs.promises.readFile(path.join(process.cwd(), filePath));
    return new Uint8Array(buffer);
}
```

#### saveFile()

```typescript
export function saveFile(fileName, bytes) {
    const dirPath = path.join(process.cwd(), "output");

    if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath);
    }

    const resPath = path.join(dirPath, fileName);
    fs.writeFileSync(resPath, bytes);
}
```

## Displaying Images in Samples

These utilities display generated images directly in the documentation demo pages.

#### showImage()

Displays an [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) instance in the demo page.
Parameters

* image - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) object to display.

```javascript
static showImage(image) {
    const arr = image.save();
    const blob = new Blob([arr.buffer], {
        type: image.type === ImageType.PNG ? 'image/png' : 'image/jpeg'
    });
    const imageElement = document.getElementById('demoImage');
    imageElement.src = URL.createObjectURL(blob);
    imageElement.style.display = "block";
    imageElement.style.width = `${image.width}px`;
    imageElement.style.height = `${image.height}px`;
}
```

#### showBitmap()

Displays a [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) instance in the demo page.
Parameters

* bitmap - A [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object to display.

```javascript
static showBitmap(bitmap) {
    const arr = bitmap.saveAsPng();
    const blob = new Blob([arr.buffer], { type: 'image/png' });
    const imageElement = document.getElementById('demoImage');
    imageElement.src = URL.createObjectURL(blob);
    imageElement.style.display = "block";
    imageElement.style.width = `${bitmap.width}px`;
    imageElement.style.height = `${bitmap.height}px`;
}
```

## Image Comparison Helpers

These helpers generate composite images used in the documentation to visually compare results.

#### combineTwoImages()

Creates a comparison image showing two images side‑by‑side.
Parameters

* img1 - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) or [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object displayed in the first column.
* text1 - A string caption displayed above the first image.
* img2 - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) or [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object displayed in the second column.
* text2 - A string caption displayed above the second image.

```javascript
static async combineTwoImages(img1, text1, img2, text2) {

    const om = getCurrentObjectManager();
    pushObjectManager();

    const img1W = img1.width;
    const img1H = img1.height;
    const img2W = img2.width;
    const img2H = img2.height;

    const margin = 10;
    const m2 = margin * 2;
    const header = 40;
    const lw = 1;

    const fmt = new Format({
        font: Font.load(await Util.loadFile("fonts/segoeuib.ttf")),
        fontSize: 16
    });

    const tl1 = new Layout({ runs: [{ text: text1, format: fmt }] });
    const tl2 = new Layout({ runs: [{ text: text2, format: fmt }] });
    tl1.performLayout();
    tl2.performLayout();

    const txt1W = tl1.contentWidth;
    const txt2W = tl2.contentWidth;
    const max1W = img1W > txt1W ? img1W : txt1W;
    const max2W = img2W > txt2W ? img2W : txt2W;
    const maxH = img1H > img2H ? img1H : img2H;

    const ctx = new BmpContext(om, max1W + max2W + lw * 3 + m2 * 2, maxH + m2 + lw * 3 + header, 1, "DarkGray");

    let x1 = lw;
    let x2 = x1 + m2 + max1W + lw;
    let y1 = header + lw * 2;

    ctx.drawRect(x1, lw, max1W + m2, header, { fillColor: "LightGray" });
    ctx.drawRect(x2, lw, max2W + m2, header, { fillColor: "LightGray" });

    ctx.drawRect(x1, y1, max1W + m2, maxH + m2, { fillColor: "GhostWhite" });
    ctx.drawRect(x2, y1, max2W + m2, maxH + m2, { fillColor: "GhostWhite" });

    x1 += margin;
    x2 += margin;
    y1 += margin;

    ctx.drawImage(img1, x1, y1 + (maxH - img1H) / 2, img1W, img1H);
    ctx.drawImage(img2, x2, y1 + (maxH - img2H) / 2, img2W, img2H);

    const y0 = 10;
    ctx.drawLayout(tl1, x1, y0);
    ctx.drawLayout(tl2, x2, y0);

    popObjectManager();
    return ctx.bitmap;
}
```

#### combineThreeImages()

Creates a comparison image showing three images side‑by‑side.
Parameters

* img1 - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) or [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object displayed in the first column.
* text1 - A string caption displayed above the first image.
* img2 - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) or [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object displayed in the second column.
* text2 - A string caption displayed above the second image.
* img3 - An [Image](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Image) or [Bitmap](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/Bitmap) object displayed in the third column.
* text3 - A string caption displayed above the third image.

```javascript
static async combineThreeImages(img1, text1, img2, text2, img3, text3) {

    const om = getCurrentObjectManager();
    pushObjectManager();

    const img1W = img1.width;
    const img1H = img1.height;
    const img2W = img2.width;
    const img2H = img2.height;
    const img3W = img3.width;
    const img3H = img3.height;

    const margin = 10;
    const m2 = margin * 2;
    const header = 40;
    const lw = 1;

    const fmt = new Format({
        font: Font.load(await Util.loadFile("fonts/segoeuib.ttf")),
        fontSize: 16
    });

    const tl1 = new Layout({ runs: [{ text: text1, format: fmt }] });
    const tl2 = new Layout({ runs: [{ text: text2, format: fmt }] });
    const tl3 = new Layout({ runs: [{ text: text3, format: fmt }] });
    tl1.performLayout();
    tl2.performLayout();
    tl3.performLayout();

    const txt1W = tl1.contentWidth;
    const txt2W = tl2.contentWidth;
    const txt3W = tl3.contentWidth;
    const max1W = img1W > txt1W ? img1W : txt1W;
    const max2W = img2W > txt2W ? img2W : txt2W;
    const max3W = img3W > txt3W ? img3W : txt3W;
    let maxH = img1H;
    if (maxH < img2H) maxH = img2H;
    if (maxH < img3H) maxH = img3H;

    const ctx = new BmpContext(om, max1W + max2W + max3W + lw * 4 + m2 * 3, maxH + m2 + lw * 3 + header, 1, "DarkGray");

    let x1 = lw;
    let x2 = x1 + m2 + max1W + lw;
    let x3 = x2 + m2 + max2W + lw;
    let y1 = header + lw * 2;

    ctx.drawRect(x1, lw, max1W + m2, header, { fillColor: "LightGray" });
    ctx.drawRect(x2, lw, max2W + m2, header, { fillColor: "LightGray" });
    ctx.drawRect(x3, lw, max3W + m2, header, { fillColor: "LightGray" });

    ctx.drawRect(x1, y1, max1W + m2, maxH + m2, { fillColor: "GhostWhite" });
    ctx.drawRect(x2, y1, max2W + m2, maxH + m2, { fillColor: "GhostWhite" });
    ctx.drawRect(x3, y1, max3W + m2, maxH + m2, { fillColor: "GhostWhite" });

    x1 += margin;
    x2 += margin;
    x3 += margin;
    y1 += margin;

    ctx.drawImage(img1, x1, y1 + (maxH - img1H) / 2, img1W, img1H);
    ctx.drawImage(img2, x2, y1 + (maxH - img2H) / 2, img2W, img2H);
    ctx.drawImage(img3, x3, y1 + (maxH - img3H) / 2, img3W, img3H);

    const y0 = 10;
    ctx.drawLayout(tl1, x1, y0);
    ctx.drawLayout(tl2, x2, y0);
    ctx.drawLayout(tl3, x3, y0);

    popObjectManager();
    return ctx.bitmap;
}
```

#### addNote()

Draws a highlighted note box on a PDF page used in certain examples.
Parameters

* text - A string containing the note content.
* page - A [PdfPage](https://developer.mescius.com/document-solutions/javascript-pdf-api/api/classes/PdfPage) object where the note will be rendered.

```javascript
static addNote(text, page) {
    const g = page.context;
    const margin = g.resolution;
    const pad = margin / 8;
    const bounds = {
        x: margin,
        y: margin,
        width: g.width - margin * 2,
        height: g.height - margin * 2
    };

    var fmtDefault = new Format({
        font: Font.getPdfFont(StandardPdfFont.Helvetica),
        fontSize: 12
    });
    let tl = new Layout({
        defaultFormat: fmtDefault,
        maxWidth: bounds.width,
        maxHeight: bounds.height,
        marginAll: pad
    });
    tl.append({ text: text });
    tl.performLayout();

    let rect = tl.contentRect;
    rect.x += bounds.x - pad;
    rect.y += bounds.y - pad;
    rect.width += pad * 2;
    rect.height += pad * 2;

    g.drawRect(rect, { fillColor: [213, 221, 240], lineColor: [59, 92, 170], lineWidth: 0.5 });
    g.drawLayout(tl, bounds.x, bounds.y);
    return rect;
}
```

## Geometry Helpers

These utilities perform small geometry calculations used by some examples.

#### inflate()

Creates a new rectangle by expanding the original rectangle outward in all directions.
Parameters

* rect - A rectangle object that defines the position and size of a rectangular area using { x, y, width, height }. Example structure:

```javascript
{ x: number, y: number, width: number, height: number }
```

* x - The amount to inflate horizontally.
* y - The amount to inflate vertically.

```javascript
static inflate(rect, x, y) {
    const result = {
        x: rect.x - x,
        y: rect.y - y,
        width: rect.width + x * 2,
        height: rect.height + y * 2
    };
    return result;
}
```

#### quadrilateralToRect()

Converts a quadrilateral structure into a bounding rectangle.
Parameters:

* quadrilateral - A quadrilateral object containing four points (a, b, c, d). Each point represents a vertex of the shape and is defined using { x, y } coordinates. Example shape:

```javascript
{
  a: { x: number, y: number },
  b: { x: number, y: number },
  c: { x: number, y: number },
  d: { x: number, y: number }
}
```

```javascript
static quadrilateralToRect(quadrilateral) {
    const l = Math.min(quadrilateral.a.x, quadrilateral.b.x, quadrilateral.c.x, quadrilateral.d.x);
    const t = Math.min(quadrilateral.a.y, quadrilateral.b.y, quadrilateral.c.y, quadrilateral.d.y);
    const r = Math.max(quadrilateral.a.x, quadrilateral.b.x, quadrilateral.c.x, quadrilateral.d.x);
    const b = Math.max(quadrilateral.a.y, quadrilateral.b.y, quadrilateral.c.y, quadrilateral.d.y);

    return { x: l, y: t, width: r - l, height: b - t };
}
```