# Can fitText be used to set only height? If not, is there an alternative

**URL:** <https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896>\
**Category:** Technical Support\
**Created:** [July 22, 2021, 9:02pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896 "2021-07-22T21:02:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![licenses](https://avatars.discourse-cdn.com/v4/letter/l/848f3c/32.png) [@licenses](https://pdfjs.community/u/licenses)\
**Post date:** [July 22, 2021, 9:02pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/1 "2021-07-22T21:02:48Z")

</div>

**PDF.js Express Version**

 (index) Value

| | |
| --- | --- |
| UI version | “7.3.0” |
| Core version | “7.3.2” |
| Build | “My8yMi8yMDIxfDQwM2IyMDFjNg==” |
| WebViewer Server | false |
| Full API | false |

**Detailed description of issue**  
I’m creating a list of freeTextannotations by using the last’s annotation bottom coordinate as the new Y coordinate for the next one. As far as I could find in the documentation, (and by a lot of experimentation), fitText seems to be the only method that can provide me with an rectangle adjusted to the size of the content. The only problem is that it adjusts the width by setting the page width as it’s X2 position. This means that the annotation occupies the rest of the width of the page, no matter where it is placed on the document.

**Expected behaviour**  
{What I would like to do is have the annotation only adjust in height. Can that be done?}

**Does your issue happen with every document, or just one?**  
{Every}

**Link to document**  
{Provide a link to the document in question if possible}

**Code snippet**  
{Provide a relevant code snippet}

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex031/uploads/pdfjscommunity/original/1X/ffbcd25c7d423db8d5acd5db201c272f4db306dd.png) [@system](https://pdfjs.community/u/system)\
**Post date:** [July 22, 2021, 9:02pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/2 "2021-07-22T21:02:53Z")

</div>

**Hello, I’m Ron, an automated tech support bot 🤖**

While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:

Guides:
- [Rich text](https://pdfjs.express/documentation/annotation/rich-text)
- [Create custom annotation styles](https://pdfjs.express/documentation/annotation/customizing-default-annotation-styles)
- [Create free text annotations in PDF.js Express](https://pdfjs.express/documentation/annotation/create-annotation-free-text)

APIs:
- [Annotations.WidgetAnnotation - setRect(rect)](https://pdfjs.express/api/Annotations.WidgetAnnotation.html#setRect__anchor)
- [CoreControls.EditBoxManager](https://pdfjs.express/api/CoreControls.EditBoxManager.html#__anchor)
- [Annotations.FreeTextAnnotation - setRect(rect)](https://pdfjs.express/api/Annotations.FreeTextAnnotation.html#setRect__anchor)

Forums:
- [Freetext Annotation Text padding](https://pdfjs.community/t/freetext-annotation-text-padding/315/2)
- [How to rotate/flip Annotations by 180 degrees?](https://pdfjs.community/t/how-to-rotate-flip-annotations-by-180-degrees/244/2)
- [Unable to save the transparency to fillColor](https://pdfjs.community/t/unable-to-save-the-transparency-to-fillcolor/242/1)

---

<div class="post-metadata">

**Author:** ![Logan](https://yyz1.discourse-cdn.com/flex031/user_avatar/pdfjs.community/logan/32/13_2.png) [@Logan](https://pdfjs.community/u/Logan)\
**Post date:** [July 27, 2021, 2:22pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/3 "2021-07-27T14:22:11Z")

</div>

Hi!

Can you please send me a code snippet showing how you are adding these annotations. A code snippet will help me find a solution for you much faster.

Thanks!  
Logan

---

<div class="post-metadata">

**Author:** ![licenses](https://avatars.discourse-cdn.com/v4/letter/l/848f3c/32.png) [@licenses](https://pdfjs.community/u/licenses)\
**Post date:** [July 27, 2021, 3:52pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/4 "2021-07-27T15:52:16Z")

</div>

Hey Logan, here you go.  
I adjust the line (meaning, Y position of each group of elements that compose a line), by readjusting the largest box with fitText. So, again, fitText adjusts the box, but it formats it to take the remaining width of the page. I don’t want that. I want the box to adjust given a width constraint. I would also be satisfied with a different method for building tables on a PDF. Thanks

```javascript
function addIssues(annotations, pageHeight: number, docViewer, annotationList: Annotations.WidgetAnnotation[]) {
    const result: any[] = [];
    
    const doc = docViewer.getDocument();
    const pageNumber = 1;
    const pageInfo = doc.getPageInfo(pageNumber);
    const pageMatrix = doc.getPageMatrix(pageNumber);
    const pageRotation = doc.getPageRotation(pageNumber);
    const maxIter = props.state?.length ?? 0;

    // Issue item widgets
    const issueProperties = ["description", "locationCode", "itemCode", "deficiencyCode", "statusCode", "isSiteCompleted", "completedDate"];
    const fieldNames = ["description", "location", "item", "deficiency", "status", "site-done", "complete-date"];
    const freeTextDict: { [key: string]: any } = {};
    const filteredWidgetsDict: { [key: string]: any[] } = {};
    fieldNames.forEach(prop => filteredWidgetsDict[prop] = annotationList.filter(el => el.fieldName?.includes(prop)));

    // Define bottom and page correction factor
    let bottom: number = filteredWidgetsDict["description"]?.[0].getBottom();
    let pageCorr = filteredWidgetsDict["description"]?.[0].getPageNumber() - 1;

    // Create freetext annotations for each property in each issue, 
    // MaxIter is the length of the issues list 
    for (let i = 0; i < maxIter; ++i) {
        fieldNames.forEach(prop => freeTextDict[prop] = new annotations.FreeTextAnnotation());

        for (let index = 0; index < fieldNames.length; ++index) {
            const property = issueProperties[index];
            const fieldName = fieldNames[index];
            
            // Place them on the page, items are placed using the bottom of the last description widget as the initial Y position
            if (property === "description") {
                if (i === 0) {
                    placeCustomWidgets(filteredWidgetsDict[fieldName][pageCorr], freeTextDict[fieldName])
                } else {
                    placeCustomWidgets(filteredWidgetsDict[fieldName][pageCorr], freeTextDict[fieldName], 0, bottom);
                }
            } else {
                if (i === 0) {
                    placeCustomWidgets(filteredWidgetsDict[fieldName][pageCorr], freeTextDict[fieldName], filteredWidgetsDict[fieldName][pageCorr].X, filteredWidgetsDict[fieldName][pageCorr].Y)
                } else {
                    placeCustomWidgets(filteredWidgetsDict[fieldName][pageCorr], freeTextDict[fieldName], filteredWidgetsDict[fieldName][pageCorr].X, bottom)
                }
            }
        }
        
        const pageFraction = freeTextDict["description"].getBottom() / pageHeight;

        for (let fi = 0; fi < fieldNames.length; ++fi) {

            const content = props.state?.[i]?.[issueProperties[fi]];
            const fieldName = fieldNames[fi];
            const padding = new annotations.Rect(0, 0, 0, 0);
            const textColor = new annotations.Color(0, 0, 0);
            const strokeColor = new annotations.Color(255, 255, 255);
            const fontSize = '8pt';
            formulateTextWidget(freeTextDict[fieldName], fieldName, content, padding, textColor, strokeColor, fontSize);

        }
        
        // Adjust the largest box
        freeTextDict["description"].fitText(pageInfo, pageMatrix, pageRotation);

        bottom = freeTextDict["description"].getBottom();
        if (pageFraction > 0.95) {
            // console.log("Turning page");
            pageCorr += 1;
            bottom = filteredWidgetsDict["description"]?.[pageCorr].Y;
        }
        // console.log(`The bottom is at ${bottom}`);
        Object.keys(freeTextDict).forEach(k => result.push(freeTextDict[k]));
    }
    return result;
}

export function placeCustomWidgets(templateWidget: Annotations.WidgetAnnotation, newWidget: Annotations.WidgetAnnotation, x?: number, y?: number) {
    const pageNumber = templateWidget.getPageNumber();
    const newX = x ? x : templateWidget.X;
    const newY = y ? y : templateWidget.Y;
    newWidget.setPageNumber(pageNumber);

    newWidget.X = newX;
    newWidget.Y = newY;

    // console.log("PageNumber placing issues");
    // console.log(pageNumber)
    newWidget.Width = templateWidget.Width;
    newWidget.Height = templateWidget.Height;

    return newWidget;
}

```

---

<div class="post-metadata">

**Author:** ![Logan](https://yyz1.discourse-cdn.com/flex031/user_avatar/pdfjs.community/logan/32/13_2.png) [@Logan](https://pdfjs.community/u/Logan)\
**Post date:** [July 29, 2021, 8:07pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/5 "2021-07-29T20:07:21Z")

</div>

Hi there!

We have an API for this coming in version 8.0 (will be released soon), but for now I found a little trick that should work for you.

The `pageInfo` object you pass in contains the width and height of the document, and the `fitText` function uses that width to know how far over to the right it is allowed to expand before it needs to break to the next line. By altering `pageInfo.width` we can trick the function into breaking into a new line before it actually needs to:

```javascript
const freeTextAnnot = new Annotations.FreeTextAnnotation();
freeTextAnnot.X = 100;
freeTextAnnot.Width = 100;
// ... other annot config

const pageInfo = doc.getPageInfo(pageNumber);
pageInfo.width = freeTextAnnot.X + freeTextAnnot.Width;
freeTextAnnot.fitText(pageInfo, pageMatrix, pageRotation);

```

This code will make sure the freeTextAnnot always maintains the width you set it to.

Let me know this goes!

Thanks,  
Logan

---

<div class="post-metadata">

**Author:** ![licenses](https://avatars.discourse-cdn.com/v4/letter/l/848f3c/32.png) [@licenses](https://pdfjs.community/u/licenses)\
**Post date:** [July 29, 2021, 9:10pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/6 "2021-07-29T21:10:49Z")

</div>

Hi Logan,  
I liked your trick, worked like a charm.

Can I suggest something for version 8. If you guys could include more examples of usage, with type annotations for typescript, in the documentation, that would be very helpful.  
Other than that.  
Great job.

Thanks

---

<div class="post-metadata">

**Author:** ![Logan](https://yyz1.discourse-cdn.com/flex031/user_avatar/pdfjs.community/logan/32/13_2.png) [@Logan](https://pdfjs.community/u/Logan)\
**Post date:** [July 29, 2021, 9:27pm UTC](https://pdfjs.community/t/can-fittext-be-used-to-set-only-height-if-not-is-there-an-alternative/896/7 "2021-07-29T21:27:29Z")

</div>

Glad it worked!

Yeah we plan on ramping up our documentation soon. For something like this an example probably wouldn’t have helped because this is such a unique use case, but we definitely will be adding more.

Unfortunately we do not plan on on shipping TypeScript definitions any time soon.

Thanks!  
Logan
