Index: PdfPainter.cpp
===================================================================
--- PdfPainter.cpp	(revision 1767)
+++ PdfPainter.cpp	(working copy)
@@ -925,7 +925,7 @@
 void PdfPainter::DrawMultiLineText( double dX, double dY, double dWidth, double dHeight, const PdfString & rsText, 
                                     EPdfAlignment eAlignment, EPdfVerticalAlignment eVertical, bool bClip )
 {
-    PODOFO_RAISE_LOGIC_IF( !m_pCanvas, "Call SetPage() first before doing drawing operations." );
+     PODOFO_RAISE_LOGIC_IF( !m_pCanvas, "Call SetPage() first before doing drawing operations." );
 
     if( !m_pFont || !m_pPage || !rsText.IsValid() )
     {
@@ -947,7 +947,7 @@
     PdfString   sString  = this->ExpandTabs( rsText, rsText.GetCharacterLength() );
 
 	std::vector<PdfString> vecLines = GetMultiLineTextAsLines(dWidth, sString);
-
+	double dLineGap = m_pFont->GetFontMetrics()->GetLineSpacing() - m_pFont->GetFontMetrics()->GetAscent() + m_pFont->GetFontMetrics()->GetDescent();
     // Do vertical alignment
     switch( eVertical ) 
     {
@@ -961,145 +961,168 @@
                    ((dHeight - (m_pFont->GetFontMetrics()->GetLineSpacing() * vecLines.size()))/2.0)); 
             break;
     }
+	
+	dY -= (m_pFont->GetFontMetrics()->GetAscent() + dLineGap / (2.0));
 
     std::vector<PdfString>::const_iterator it = vecLines.begin();
     while( it != vecLines.end() )
     {
+		
         if( (*it).GetCharacterLength() )
-            this->DrawTextAligned( dX, dY - m_pFont->GetFontMetrics()->GetAscent(), dWidth, *it, eAlignment );
+            this->DrawTextAligned( dX, dY, dWidth, *it, eAlignment );
         dY -= m_pFont->GetFontMetrics()->GetLineSpacing();
-       
         ++it;
     }
     this->Restore();
 }
 
-std::vector<PdfString> PdfPainter::GetMultiLineTextAsLines( double dWidth, const PdfString & rsText)
+std::vector<PdfString> PdfPainter::GetMultiLineTextAsLines(double dWidth, const PdfString & rsText)
 {
-    PODOFO_RAISE_LOGIC_IF( !m_pCanvas, "Call SetPage() first before doing drawing operations." );
+	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 );
-    }
-     
-    if( dWidth <= 0.0 ) // nonsense arguments
-	    return std::vector<PdfString>();
-    
-    if( rsText.GetCharacterLength() == 0 ) // empty string
-        return std::vector<PdfString>(1, rsText);
-	        
-    // We will work with utf16 encoded string because it allows us 
-    // fast and easy individual characters access    
-    const std::string& stringUtf8 = rsText.GetStringUtf8();
-    std::vector<pdf_utf16be> stringUtf16(stringUtf8.length() + 1, 0);
-	assert(stringUtf16.size() > 0);	
-    const pdf_long converted = PdfString::ConvertUTF8toUTF16(
-	    reinterpret_cast<const pdf_utf8*>(stringUtf8.c_str()), &stringUtf16[0], stringUtf16.size());
+	if (!m_pFont || !m_pPage || !rsText.IsValid())
+	{
+		PODOFO_RAISE_ERROR(ePdfError_InvalidHandle);
+	}
+
+	if (dWidth <= 0.0) // nonsense arguments
+		return std::vector<PdfString>();
+
+	if (rsText.GetCharacterLength() == 0) // empty string
+		return std::vector<PdfString>(1, rsText);
+
+	// We will work with utf16 encoded string because it allows us 
+	// fast and easy individual characters access    
+	const std::string& stringUtf8 = rsText.GetStringUtf8();
+	std::vector<pdf_utf16be> stringUtf16(stringUtf8.length() + 1, 0);
+	assert(stringUtf16.size() > 0);
+	const pdf_long converted = PdfString::ConvertUTF8toUTF16(
+		reinterpret_cast<const pdf_utf8*>(stringUtf8.c_str()), &stringUtf16[0], stringUtf16.size());
 	//const pdf_long len = rsText.GetCharacterLength();
-    assert( converted == (rsText.GetCharacterLength() + 1) );
+	assert(converted == (rsText.GetCharacterLength() + 1));
 
 	const pdf_utf16be* const stringUtf16Begin = &stringUtf16[0];
-    const pdf_utf16be* pszLineBegin = stringUtf16Begin;
-    const pdf_utf16be* pszCurrentCharacter = stringUtf16Begin;
-    const pdf_utf16be* pszStartOfCurrentWord  = stringUtf16Begin;
-    bool startOfWord = true;
-    double dCurWidthOfLine = 0.0;
+	const pdf_utf16be* pszLineBegin = stringUtf16Begin;
+	const pdf_utf16be* pszCurrentCharacter = stringUtf16Begin;
+	const pdf_utf16be* pszStartOfCurrentWord = stringUtf16Begin;
+	bool startOfWord = true;
+	double dCurWidthOfLine = 0.0;
 	std::vector<PdfString> vecLines;
 
-    // do simple word wrapping
-    while( *pszCurrentCharacter ) 
-    {
-        if( IsNewLineChar( *pszCurrentCharacter ) ) // hard-break! 
-        {
-            vecLines.push_back( PdfString( pszLineBegin, pszCurrentCharacter - pszLineBegin ) );
+	// do simple word wrapping
+	while (*pszCurrentCharacter)
+	{
+		if (IsNewLineChar(*pszCurrentCharacter)) // hard-break! 
+		{
+			vecLines.push_back(PdfString(pszLineBegin, pszCurrentCharacter - pszLineBegin));
 
-            pszLineBegin = pszCurrentCharacter+1;// skip the line feed
-            startOfWord = true;
-            dCurWidthOfLine = 0.0;
-        }
-        else if( IsSpaceChar( *pszCurrentCharacter ) )
-        {
-            if( dCurWidthOfLine > dWidth )
-            {
-                // The previous word does not fit in the current line.
-                // -> Move it to the next one.
-                vecLines.push_back( PdfString( pszLineBegin, pszStartOfCurrentWord - pszLineBegin ) );
-                pszLineBegin = pszStartOfCurrentWord;
+			pszLineBegin = pszCurrentCharacter + 1;// skip the line feed
+			startOfWord = true;
+			dCurWidthOfLine = 0.0;
+		}
+		else if (IsSpaceChar(*pszCurrentCharacter))
+		{
+			if (dCurWidthOfLine > dWidth)
+			{
+				// The previous word does not fit in the current line.
+				// -> Move it to the next one.
+				if (pszStartOfCurrentWord > pszLineBegin)
+					vecLines.push_back(PdfString(pszLineBegin, pszStartOfCurrentWord - pszLineBegin));
+				else
+				{
+					vecLines.push_back(PdfString(pszLineBegin, pszCurrentCharacter - pszLineBegin));
+					//Skip all spaces at the end of the line
+					while (IsSpaceChar(*(pszCurrentCharacter + 1)))
+						pszCurrentCharacter++;
 
-                if (!startOfWord)
-                {
-                    dCurWidthOfLine = m_pFont->GetFontMetrics()->StringWidth( 
-						pszStartOfCurrentWord, pszCurrentCharacter - pszStartOfCurrentWord );
-                }
-                else
-                {
-                    dCurWidthOfLine = 0.0;
-                }
-            }
-            else 
-            {           
-                dCurWidthOfLine += m_pFont->GetFontMetrics()->UnicodeCharWidth( SwapCharBytesIfRequired( *pszCurrentCharacter ) );
-            }
+					pszStartOfCurrentWord = pszCurrentCharacter + 1;
+				}
+				pszLineBegin = pszStartOfCurrentWord;
 
-            startOfWord = true;
-        }
-        else
-        {
-            if (startOfWord)
-            {
-                pszStartOfCurrentWord = pszCurrentCharacter;
-                startOfWord = false;
-            }
-            //else do nothing
+				if (!startOfWord)
+				{
+					dCurWidthOfLine = m_pFont->GetFontMetrics()->StringWidth(
+						pszStartOfCurrentWord, pszCurrentCharacter - pszStartOfCurrentWord);
+				}
+				else
+				{
+					dCurWidthOfLine = 0.0;
+				}
+			}
+			else
+			{
+				dCurWidthOfLine += m_pFont->GetFontMetrics()->UnicodeCharWidth(SwapCharBytesIfRequired(*pszCurrentCharacter));
+			}
 
-            if ((dCurWidthOfLine + m_pFont->GetFontMetrics()->UnicodeCharWidth( SwapCharBytesIfRequired( *pszCurrentCharacter ))) > dWidth)
-            {
-                if ( pszLineBegin == pszStartOfCurrentWord )
-                {
-                    // This word takes up the whole line.
-                    // Put as much as possible on this line.                    
-                    vecLines.push_back( PdfString( pszLineBegin, pszCurrentCharacter - pszLineBegin ) );
-                    pszLineBegin = pszCurrentCharacter;
-                    pszStartOfCurrentWord = pszCurrentCharacter;
-                    dCurWidthOfLine = m_pFont->GetFontMetrics()->UnicodeCharWidth( SwapCharBytesIfRequired( *pszCurrentCharacter ) );
-                }
-                else
-                {
-                    // The current word does not fit in the current line.
-                    // -> Move it to the next one.                    
-                    vecLines.push_back( PdfString( pszLineBegin, pszStartOfCurrentWord - pszLineBegin ) );
-                    pszLineBegin = pszStartOfCurrentWord;
-                    dCurWidthOfLine = m_pFont->GetFontMetrics()->StringWidth( pszStartOfCurrentWord, (pszCurrentCharacter-pszStartOfCurrentWord) + 1 );
-                }
-            }
-            else 
-            {
-                dCurWidthOfLine += m_pFont->GetFontMetrics()->UnicodeCharWidth( SwapCharBytesIfRequired( *pszCurrentCharacter ) );
-            }
-        }
-        ++pszCurrentCharacter;
-    }
+			startOfWord = true;
+		}
 
-    if( (pszCurrentCharacter - pszLineBegin) > 0 ) 
-    {
-        if( dCurWidthOfLine > dWidth )
-        {
-            // The previous word does not fit in the current line.
-            // -> Move it to the next one.
-            vecLines.push_back( PdfString( pszLineBegin, pszStartOfCurrentWord - pszLineBegin) );
-            pszLineBegin = pszStartOfCurrentWord;
-        }
-        //else do nothing
+		else
+		{
+			if (startOfWord)
+			{
+				pszStartOfCurrentWord = pszCurrentCharacter;
+				startOfWord = false;
+			}
+			//else do nothing
 
-        if( pszCurrentCharacter - pszLineBegin > 0 ) 
-        {
-            vecLines.push_back( PdfString( pszLineBegin, pszCurrentCharacter - pszLineBegin) );
-        }
-        //else do nothing
-    }
+			if ((dCurWidthOfLine + m_pFont->GetFontMetrics()->UnicodeCharWidth(SwapCharBytesIfRequired(*pszCurrentCharacter))) > dWidth)
+			{
+				if (pszLineBegin == pszStartOfCurrentWord)
+				{
+					// This word takes up the whole line.
+					// Put as much as possible on this line.         
+					if (pszLineBegin == pszCurrentCharacter)
+					{
+						vecLines.push_back(PdfString(pszCurrentCharacter, 1));
+						pszLineBegin = pszCurrentCharacter + 1;
+						pszStartOfCurrentWord = pszCurrentCharacter + 1;
+						dCurWidthOfLine = 0;
+					}
+					else
+					{
+						vecLines.push_back(PdfString(pszLineBegin, pszCurrentCharacter - pszLineBegin));
+						pszLineBegin = pszCurrentCharacter;
+						pszStartOfCurrentWord = pszCurrentCharacter;
+						dCurWidthOfLine = m_pFont->GetFontMetrics()->UnicodeCharWidth(SwapCharBytesIfRequired(*pszCurrentCharacter));
+					}
+				}
+				else
+				{
+					// The current word does not fit in the current line.
+					// -> Move it to the next one.                    
+					vecLines.push_back(PdfString(pszLineBegin, pszStartOfCurrentWord - pszLineBegin));
+					pszLineBegin = pszStartOfCurrentWord;
+					dCurWidthOfLine = m_pFont->GetFontMetrics()->StringWidth(pszStartOfCurrentWord, (pszCurrentCharacter - pszStartOfCurrentWord) + 1);
+				}
+			}
+			else
+			{
+				dCurWidthOfLine += m_pFont->GetFontMetrics()->UnicodeCharWidth(SwapCharBytesIfRequired(*pszCurrentCharacter));
+			}
+		}
+		++pszCurrentCharacter;
+	}
 
-    return vecLines;
+	if ((pszCurrentCharacter - pszLineBegin) > 0)
+	{
+		if (dCurWidthOfLine > dWidth &&pszStartOfCurrentWord > pszLineBegin)
+		{
+			// The previous word does not fit in the current line.
+			// -> Move it to the next one.
+			vecLines.push_back(PdfString(pszLineBegin, pszStartOfCurrentWord - pszLineBegin));
+			pszLineBegin = pszStartOfCurrentWord;
+		}
+		//else do nothing
+
+		if (pszCurrentCharacter - pszLineBegin > 0)
+		{
+			vecLines.push_back(PdfString(pszLineBegin, pszCurrentCharacter - pszLineBegin));
+		}
+		//else do nothing
+	}
+
+	return vecLines;
 }
 
 void PdfPainter::DrawTextAligned( double dX, double dY, double dWidth, const PdfString & rsText, EPdfAlignment eAlignment )
