c++libharu

Libharu pdf creation : How to know the size of the printed text


I'm currently using the libharu library in order to render some pdf in a C++ program.

I have no idea whether it is possible or not to know the size needed in order to draw a specific text with a specific font.

The HPDF_Page_TextRect drawing method will return an HPDF_PAGE_INSUFFICIENT_SPACE message if the text can't fit in the rect provided, but I'd like to know if there is a way to calculate the minimum size in which a text will fit with a specific font.

In advace, thanks.


Solution

  • I found a workaround which consists in drawing the text outside the page while shrinking the rect width until the drawing fails. It's not subtil at all, but it works.

    HPDF_STATUS drawString_2(HPDF_Page pdfPage, CString texte, COLORREF textColor, HPDF_Font font, HPDF_REAL fontSize, HPDF_REAL left, HPDF_REAL right, HPDF_REAL top, 
                             HPDF_REAL bottom, HPDF_TextAlignment alignment, HPDF_REAL textRise = 0, HPDF_TextRenderingMode renderingMode = HPDF_FILL);
    
    
    HPDF_REAL calculateMaxWidthForTextInRect2(HPDF_Page pdfPage, CString texte, HPDF_REAL left, HPDF_REAL right, HPDF_REAL top, HPDF_REAL bottom, HPDF_Font font, HPDF_REAL fontSize);
    
    
    HPDF_STATUS drawString_2(HPDF_Page pdfPage, CString texte, COLORREF textColor, HPDF_Font font, HPDF_REAL fontSize, HPDF_REAL left, HPDF_REAL right, HPDF_REAL top, 
                             HPDF_REAL bottom, HPDF_TextAlignment alignment, HPDF_REAL textRise, HPDF_TextRenderingMode renderingMode)
    {
    #ifdef DEBUG
            assert(font != NULL);
    #else
            if (font == NULL)
                return 1;
    #endif
        HPDF_Page_SetFontAndSize(pdfPage, font, fontSize);
        HPDF_Page_SetTextRise(pdfPage, textRise);
        HPDF_Page_SetTextRenderingMode(pdfPage, renderingMode);
        HPDF_Page_SetRGBFill(pdfPage, GetRValue(textColor) / 255.f, GetGValue(textColor) / 255.f, GetBValue(textColor) / 255.f);
        HPDF_Page_BeginText(pdfPage);
        HPDF_STATUS returnValue = HPDF_Page_TextRect(pdfPage, left, top, right, bottom, (LPCSTR)texte, alignment, NULL);
        HPDF_Page_EndText(pdfPage);
    
        return returnValue;
    }
    
    HPDF_REAL calculateMaxWidthForTextInRect2(HPDF_Page pdfPage, CString texte, HPDF_REAL left, HPDF_REAL right, HPDF_REAL top, HPDF_REAL bottom, HPDF_Font font, HPDF_REAL fontSize)
    {
        // Let's draw outside the page size, so the text, even invisible, will not be selectionnable and copyable
        HPDF_REAL leftTmp           = -(right - left);
        HPDF_REAL rightTmp          = 0;
        HPDF_REAL topTmp            = -(bottom - top);
        HPDF_REAL bottomTmp         = 0;
    
        HPDF_Page_SetTextRenderingMode(pdfPage, HPDF_INVISIBLE);
    
        // Let's reduce horizontally the rect until the drawing fails
        while (drawString_2(pdfPage, texte, RGB(0, 0, 0), font, fontSize, leftTmp, rightTmp, topTmp, bottomTmp, HPDF_TALIGN_CENTER, 0, HPDF_INVISIBLE) == HPDF_OK)
        {
            leftTmp ++;
            rightTmp --;
        }   
    
        // If no drawing has be performed, the text cannot be rendered in the provided rect
        if (rightTmp == 0)
            return -1;
    
        // Let's decrement the shifting in order to get the latest correct value
        leftTmp --;
        rightTmp ++;
    
        return (rightTmp - leftTmp);
    }