Пример #1
0
void PdfParser::FindToken( const char* pszToken, const long lRange )
{
    m_device.Device()->Seek( 0, std::ios_base::end );

    std::streamoff nFileSize = m_device.Device()->Tell();
    if (nFileSize == -1)
    {
        PODOFO_RAISE_ERROR_INFO(
                ePdfError_NoXRef,
                "Failed to seek to EOF when looking for xref");
    }

    pdf_long lXRefBuf  = PDF_MIN( nFileSize, lRange );
    size_t   nTokenLen = strlen( pszToken );

    m_device.Device()->Seek( -lXRefBuf, std::ios_base::cur );
    if( m_device.Device()->Read( m_buffer.GetBuffer(), lXRefBuf ) != lXRefBuf && !m_device.Device()->Eof() )
    {
        PODOFO_RAISE_ERROR( ePdfError_NoXRef );
    }

    m_buffer.GetBuffer()[lXRefBuf] = '\0';

    int i; // Do not make this unsigned, this will cause infinte loops in files without trailer

    // search backwards in the buffer in case the buffer contains null bytes
    // because it is right after a stream (can't use strstr for this reason)
    for( i = lXRefBuf - nTokenLen; i >= 0; i-- )
    {
        if( strncmp( m_buffer.GetBuffer()+i, pszToken, nTokenLen ) == 0 )
        {
            break;
        }
    }

    if( !i )
    {
        PODOFO_RAISE_ERROR( ePdfError_InternalLogic );
    }

    m_device.Device()->Seek( (lXRefBuf-i)*-1, std::ios_base::end );
}
Пример #2
0
void PdfFontCID::CreateWidth( PdfObject* pFontDict ) const
{
    const int cAbsoluteMax = 0xffff;
    int nFirstChar = m_pEncoding->GetFirstChar();
    int nLastChar  = m_pEncoding->GetLastChar();

    int  i;

    // Allocate an initialize an array, large enough to 
    // hold a width value for every possible glyph index
    double* pdWidth = static_cast<double*>(malloc( sizeof(double) * cAbsoluteMax ) );
    if( !pdWidth )
    {
        PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
    }

    for( i=0;i<cAbsoluteMax;i++ )
        pdWidth[i] = 0.0;

    // Load the width of all requested glyph indeces
    int nMin       = 0xffff;
    int nMax       = 0;

    long    lGlyph = 0;

    for( i=nFirstChar;i<=nLastChar;i++ )
    {
        lGlyph = m_pMetrics->GetGlyphId( i );
        if( lGlyph )
        {
            nMin = PDF_MIN( static_cast<long>(nMin), lGlyph );
            nMax = PDF_MAX( static_cast<long>(nMax), lGlyph );
            nMax = PDF_MIN( nMax, cAbsoluteMax );

            if( lGlyph < cAbsoluteMax )
                pdWidth[lGlyph] = m_pMetrics->GetGlyphWidth( lGlyph );

        }
    }

	if (nMax >= nMin) {
        // Now compact the array
        std::ostringstream oss;
        PdfArray array;
        array.reserve( nMax - nMin + 1 );

        i = nMin;
        double    dCurWidth  = pdWidth[i];
        pdf_int64 lCurIndex  = i++;
        pdf_int64 lCurLength = 1L;
        
        for( ;i<=nMax;i++ )
        {
            if( static_cast<int>(pdWidth[i] - dCurWidth) == 0 )
                ++lCurLength;
            else
            {
                if( lCurLength > 1 ) 
                {
                    array.push_back( lCurIndex );
                    pdf_int64 temp = lCurIndex + lCurLength - 1;
                    array.push_back( temp ); 
                    array.push_back( dCurWidth ); 
                }
                else
                {
                    if( array.size() && array.back().IsArray() ) 
                    {
                        array.back().GetArray().push_back( dCurWidth );
                    }
                    else
                    {
                        PdfArray tmp;
                        tmp.push_back( dCurWidth );
                        
                        array.push_back( lCurIndex );
                        array.push_back( tmp );
                    }
                }
                
                lCurIndex  = i;
                lCurLength = 1L;
                dCurWidth  = pdWidth[i];
            }
        }

        if (array.size() == 0) 
        {
            array.push_back( lCurIndex = nMin );
            array.push_back( lCurIndex = nMax );
            array.push_back( dCurWidth ); 
        }
        
        pFontDict->GetDictionary().AddKey( PdfName("W"), array ); 
    }

    free( pdWidth );
}
Пример #3
0
void PdfTable::Draw( double dX, double dY, PdfPainter* pPainter, const PdfRect & rClipRect,
                     double* pdLastX, double* pdLastY )
{
    if( !pPainter ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    //RG: TODO Should dCurY variable be initialised with 0? (line 257 may fall through without initialisation!)
    int i = 0;
    int j = 0;
    double  dCurX = 0.0;
    double  dCurY = 0.0;

    double  dWidth = 0.0;
    double  dHeight = 0.0;
    double  dVertical = 0.0;
    double* pdColWidths  = new double[this->GetCols()];
    double* pdRowHeights = new double[this->GetRows()];

	bool bBorders = !m_pModel || (m_pModel && m_pModel->HasBorders() );

    // Calculate all necessary sizes
    this->CalculateTableSize( dX, dY, pPainter->GetPage(), 
                              pdColWidths, pdRowHeights,
                              &dWidth, &dHeight );
 
    if( !(!static_cast<int>(rClipRect.GetBottom()) && 
          !static_cast<int>(rClipRect.GetLeft()) &&
          !static_cast<int>(rClipRect.GetWidth()) && 
          !static_cast<int>(rClipRect.GetWidth())) ) 
        m_curClipRect = rClipRect;
    else
    {
        m_curClipRect = PdfRect( 0.0, dX, 
                                 pPainter->GetPage()->GetPageSize().GetWidth() - dX,
                                 dY );
    }

    // Draw the table
    pPainter->Save();
    PdfFont* pDefaultFont = pPainter->GetFont(); // get the default font
    PdfFont* pFont;

    // draw contents
    if( m_pModel ) 
    {
		pPainter->SetStrokeWidth( m_pModel->GetBorderWidth() );

		if( bBorders ) // draw top border
            this->DrawHorizontalBorders( 0, dX, dY, pPainter, pdColWidths );

        for( j=0;j<m_nRows;j++ )
        {
			if( this->CheckForNewPage( &dY, &dCurY, pdRowHeights[j], pPainter ) && bBorders )
                // draw top border on new page
                this->DrawHorizontalBorders( j, dX, dY, pPainter, pdColWidths );
    
			dCurX  = 0.0;	
			dCurY += pdRowHeights[j];

            for( i=0;i<m_nCols;i++ ) 
            {
	            // set a clipping rectangle
                pPainter->Save();
                pPainter->SetClipRect( dX + dCurX, dY - dCurY, pdColWidths[i], pdRowHeights[j] );

                // Draw background
				double dBorder = bBorders ? m_pModel->GetBorderWidth()/2.0 : 0.0;
                if( m_pModel->HasBackgroundColor( i, j ) ) 
                {
                    pPainter->Save();
                    pPainter->SetColor( m_pModel->GetBackgroundColor( i, j ) );
					// Make sure that FillRect only fills inside the border
					// rectangle and not over the border. This is necessary
					// because we draw the border first and than the contents.
                    pPainter->FillRect( dX + dCurX + dBorder, dY - dCurY + dBorder, 
						                pdColWidths[i] - 2.0 * dBorder, 
										pdRowHeights[j] - 2.0 * dBorder );
                    pPainter->Restore();
                }

                // draw an image
                PdfImage* pImage = m_pModel->GetImage( i, j );
                double dImageWidth = 0.0;
                if( m_pModel->HasImage( i, j ) && pImage )
                {
                    double dScaleX = (pdColWidths[i])  / pImage->GetPageSize().GetWidth();
                    double dScaleY = (pdRowHeights[j] - 2.0 * dBorder) / pImage->GetPageSize().GetHeight();
                    double dScale  = PDF_MIN( dScaleX, dScaleY );

                    dImageWidth = pImage->GetPageSize().GetWidth() * dScale;

                    pPainter->DrawImage( dX + dCurX, dY - dCurY + dBorder, pImage, dScale, dScale );
                }

                // Set the correct font
                pFont = m_pModel->GetFont( i, j );
                pFont = pFont ? pFont : pDefaultFont;
                pPainter->SetFont( pFont );
				pPainter->SetColor( m_pModel->GetForegroundColor( i, j ) );

                // draw text
				if( m_pModel->HasWordWrap( i, j ) )
				{
					// Make sure we have at least 1 dot free space at each side of the rectangle
					pPainter->DrawMultiLineText( dX + dCurX + 1.0 + dImageWidth, dY - dCurY, 
                                                 pdColWidths[i] - 2.0 - dImageWidth, pdRowHeights[j],
												 m_pModel->GetText( i, j ), m_pModel->GetAlignment( i, j ),
												 m_pModel->GetVerticalAlignment( i, j ) );
				}
				else
				{
					// calculate vertical alignment
					switch( m_pModel->GetVerticalAlignment( i, j ) ) 
					{
						default:
						case ePdfVerticalAlignment_Top:
							dVertical = 0.0;
							break;
						case ePdfVerticalAlignment_Center:
							dVertical = (pdRowHeights[j] - pFont->GetFontMetrics()->GetLineSpacing()) / 2.0;
							break;
						case ePdfVerticalAlignment_Bottom:
							dVertical = (pdRowHeights[j] - pFont->GetFontMetrics()->GetLineSpacing());
							break;
					}

					// Make sure we have at least 1 dot free space at each side of the rectangle
					pPainter->DrawTextAligned( dX + dCurX + 1 + dImageWidth, dY - dCurY + dVertical, 
                                               pdColWidths[i] - 2.0 - dImageWidth, m_pModel->GetText( i, j ), m_pModel->GetAlignment( i, j ) );
				}
                
                pPainter->Restore();
				if( bBorders ) // draw left x border
                {
                    // use always the border color of the left to the current cell
                    pPainter->SetStrokingColor( m_pModel->GetBorderColor( i>0 ? i-1 : i, j ) );
					pPainter->DrawLine( dX + dCurX, dY - dCurY, dX + dCurX, dY - dCurY + pdRowHeights[j] );
                }

		        dCurX += pdColWidths[i];    
            }

			if( bBorders ) 
			{
				// Draw last X border
                if( i > 0 )
                {
                    pPainter->SetStrokingColor( m_pModel->GetBorderColor( i-1, j ) );
				    pPainter->DrawLine( dX + dCurX, dY - dCurY, dX + dCurX, dY - dCurY + pdRowHeights[j] );
                }

                // draw border below row    
                this->DrawHorizontalBorders( j, dX, dY - dCurY, pPainter, pdColWidths );
    		}
		}    
	}
    pPainter->Restore();

    if( pdLastX )
        *pdLastX = dX + dWidth;

    if( pdLastY )
        *pdLastY = dY - dCurY;

    // Free allocated memory
    delete [] pdColWidths;
    delete [] pdRowHeights;
}