Libharu pdf创建:如何知道打印文本的大小

时间:2015-12-03 14:18:14

标签: c++ libharu

我目前正在使用libharu库,以便在C ++程序中呈现一些pdf。

我不知道是否有可能知道为了使用特定字体绘制特定文本所需的大小。

HPDF_Page_TextRect绘图方法会返回HPDF_PAGE_INSUFFICIENT_SPACE消息,如果文字不适合所提供的矩形,但我想知道是否有办法计算最小尺寸哪个文本适合特定字体。

先生,谢谢。

2 个答案:

答案 0 :(得分:2)

另一种方法是使用HPDF_Page_TextWidth函数来获取当前fontsize,字符间距和字间距的文本宽度:

HPDF_STATUS FitText( 
                    HPDF_Page pdfPage, 
                    HPDF_Font pdfFont, 
                    HPDF_REAL pdfFontSize, 
                    HPDF_REAL rectProvidedLeft, 
                    HPDF_REAL rectProvidedRight, 
                    HPDF_REAL rectProvidedTop, 
                    char *pText )
{
    if ( pdfPage <= 0 || pdfFont <= 0 || pdfFontSize <= 0 )
        return HPDF_INVALID_PARAMETER;

    HPDF_Page_SetFontAndSize ( pdfPage, pdfFont, pdfFontSize );
    HPDF_REAL dTextExtent = HPDF_Page_TextWidth ( pdfPage, pText );

    // reduce font size until text fit in provided rectangle
    HPDF_REAL nReducedFontSize = pdfFontSize;
    while ( dTextExtent > (rectProvidedRight-rectProvidedLeft) && nReducedFontSize >= 0 )
    {
        HPDF_Page_SetFontAndSize ( pdfPage, pdfFont, --nReducedFontSize );
        dTextExtent         = HPDF_Page_TextWidth ( pdfPage, pText );
    }
    if ( nReducedFontSize == 0 )
        return HPDF_STRING_OUT_OF_RANGE;

    HPDF_Page_BeginText     ( pdfPage );
    HPDF_Page_MoveTextPos   ( pdfPage, rectProvidedLeft, rectProvidedTop );
    HPDF_STATUS pdfStatus   = HPDF_Page_ShowText    ( pdfPage, pText );
    HPDF_Page_EndText       ( pdfPage );

    return pdfStatus;
}

答案 1 :(得分:1)

我找到了一种解决方法,包括在缩小矩形宽度直到绘图失败时在页面外绘制文本。它根本没有下降,但它确实有效。

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);
}