Hi,

I have improved DrawMultiLineText of PdfPainter little bit and the output is 
better. Here is my updated version:

void PdfPainter::DrawMultiLineText( double dX, double dY, double dWidth, double 
dHeight, const PdfString & rsText, 
                                    EPdfAlignment eAlignment, 
EPdfVerticalAlignment eVertical )
{
    PODOFO_RAISE_LOGIC_IF( !m_pCanvas, "Call SetPage() first before doing 
drawing operations." );

    if( !m_pFont || !m_pPage || !rsText.IsValid() )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    // Peter Petrov 25 September 2008
    m_pFont->EmbedFont();
    
    if( dWidth <= 0.0 || dHeight <= 0.0 ) // nonsense arguments
        return;
    
    TLineElement              tLine;
    std::vector<TLineElement> vecLines;
    this->Save();
    this->SetClipRect( dX, dY, dWidth, dHeight );
    
    PdfString   sString  = this->ExpandTabs( rsText, 
rsText.GetCharacterLength() );
    tLine.pszStart       = sString.GetString();
    const char* pszEnd   = tLine.pszStart;
    const char* pszWord  = tLine.pszStart;
    
    double dCurWidth = 0.0;

    // do simple word wrapping
    // TODO: Use better algorithm!
    while( *pszEnd ) 
    {
        dCurWidth += m_pFont->GetFontMetrics()->CharWidth( *pszEnd );
        
        if( *pszEnd == '\n' ) // hard-break!
        {
            ++pszEnd; // skip the line feed
            
            tLine.lLen = pszEnd - tLine.pszStart;
            vecLines.push_back( tLine );
            
            tLine.pszStart = pszEnd;
            dCurWidth = 0.0;
        }
        else if( isspace( static_cast<unsigned int>(static_cast<unsigned 
char>(*pszEnd)) ) || 
                 ispunct( static_cast<unsigned int>(static_cast<unsigned 
char>(*pszEnd)) ))
            pszWord = pszEnd;
        
        if( dCurWidth > dWidth ) 
        {
            // The last word does not fit anymore in the current line.
            // -> Move it to the next one.
                        
            // skip leading whitespaces!
            while( *tLine.pszStart && isspace( static_cast<unsigned 
int>(static_cast<unsigned char>(*tLine.pszStart)) ) )
                ++tLine.pszStart;

            tLine.lLen = /*pszEnd*/pszWord - tLine.pszStart + 1;
            vecLines.push_back( tLine );
            tLine.pszStart = pszWord + 1;

            dCurWidth = pszEnd-pszWord > 0 ? 
                m_pFont->GetFontMetrics()->StringWidth( pszWord+1, 
pszEnd-pszWord-1 ) : 0.0;
        }
        ++pszEnd;
    }

    if( pszEnd-tLine.pszStart > 0 ) 
    {
        tLine.lLen = pszEnd - tLine.pszStart;
        vecLines.push_back( tLine );
    }

    // Do vertical alignment
    switch( eVertical ) 
    {
        default:
        case ePdfVerticalAlignment_Top:
            dY += dHeight; break;
        case ePdfVerticalAlignment_Bottom:
            dY += m_pFont->GetFontMetrics()->GetLineSpacing() * 
vecLines.size(); break;
        case ePdfVerticalAlignment_Center:
            dY += (dHeight - 
                   ((dHeight - (m_pFont->GetFontMetrics()->GetLineSpacing() * 
vecLines.size()))/2.0)); 
            break;
    }

    std::vector<TLineElement>::const_iterator it = vecLines.begin();
    while( it != vecLines.end() )
    {
        dY -= m_pFont->GetFontMetrics()->GetLineSpacing();
        if( (*it).pszStart )
            this->DrawTextAligned( dX, dY, dWidth, PdfString( (*it).pszStart, 
(*it).lLen ), eAlignment );

        ++it;
    }
    this->Restore();
}



      

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to