Esempio n. 1
0
void PdfAnnotation::SetColor( double r, double g, double b ) {
  PdfArray c;
  c.push_back( PdfVariant( r ) );
  c.push_back( PdfVariant( g ) );
  c.push_back( PdfVariant( b ) );
  m_pObject->GetDictionary().AddKey( "C", c );
}
void PdfFontMetricsFreetype::GetWidthArray( PdfVariant & var, unsigned int nFirst, unsigned int nLast ) const
{
    unsigned int  i;
    PdfArray  list;

    if( !m_pFace ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    for( i=nFirst;i<=nLast;i++ )
    {
        if( i < PODOFO_WIDTH_CACHE_SIZE )
            list.push_back( PdfVariant( m_vecWidth[i] ) );
        else
        {
            if( !FT_Load_Char( m_pFace, i, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) )  // | FT_LOAD_NO_RENDER
            {
                //PODOFO_RAISE_ERROR( ePdfError_FreeType );
                list.push_back( PdfVariant( 0.0 ) );
                continue;
            }

            list.push_back( PdfVariant( m_pFace->glyph->metrics.horiAdvance * 1000.0 / m_pFace->units_per_EM ) );
        }
    }

    var = PdfVariant( list );
}
Esempio n. 3
0
void PagesTreeTest::CreateTestTreeCustom( PoDoFo::PdfMemDocument & rDoc )
{
    const int COUNT = PODOFO_TEST_NUM_PAGES / 10;
    PdfObject* pRoot = rDoc.GetPagesTree()->GetObject();
    PdfArray rootKids;
    

    for(int z=0; z<COUNT; z++) 
    {
        PdfObject* pNode = rDoc.GetObjects().CreateObject("Pages");
        PdfArray nodeKids;

        for(int i=0; i<COUNT; i++) 
        {
            PdfPage* pPage = new PdfPage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ),
                                          &(rDoc.GetObjects()) );
            pPage->GetObject()->GetDictionary().AddKey( PODOFO_TEST_PAGE_KEY, 
                                                        static_cast<long long>(z * COUNT + i) );

            //printf("Creating page %i z=%i i=%i\n", z * COUNT + i, z, i );
            nodeKids.push_back( pPage->GetObject()->Reference() );
        }

        pNode->GetDictionary().AddKey( PdfName("Kids"), nodeKids );
        pNode->GetDictionary().AddKey( PdfName("Count"), static_cast<long long>(COUNT) );
        rootKids.push_back( pNode->Reference() );
    }

    pRoot->GetDictionary().AddKey( PdfName("Kids"), rootKids );
    pRoot->GetDictionary().AddKey( PdfName("Count"), static_cast<long long>(PODOFO_TEST_NUM_PAGES) );
}
void PdfSignOutputDevice::AdjustByteRange()
{
    if(!m_bBeaconFound) {
        PODOFO_RAISE_ERROR( ePdfError_InternalLogic );
    }

    // Get final position
    size_t sFileEnd = GetLength();
    PdfArray arr;
    arr.push_back( PdfVariant(static_cast<pdf_int64>(0)) );
    arr.push_back( PdfVariant(static_cast<pdf_int64>(m_sBeaconPos)) );
    arr.push_back( PdfVariant(static_cast<pdf_int64>(m_sBeaconPos+m_pSignatureBeacon->data().size()+2) ) );
    arr.push_back( PdfVariant(static_cast<pdf_int64>(sFileEnd-(m_sBeaconPos+m_pSignatureBeacon->data().size()+2)) ) );
    std::string sPosition;
    PdfVariant(arr).ToString(sPosition, ePdfWriteMode_Compact);
    // Fill padding
    unsigned int sPosSize = sizeof("[ 0 1234567890 1234567890 1234567890]")-1;
    if(sPosition.size()<sPosSize)
    {
        // drop last ']'
        sPosition.resize(sPosition.size()-1);
        while(sPosition.size()<(sPosSize-1)) {
            sPosition+=' ';
        }
        sPosition+=']';
    }

    m_pRealDevice->Seek(m_sBeaconPos-sPosition.size()-9);
    m_pRealDevice->Write(sPosition.c_str(), sPosition.size());
}
Esempio n. 5
0
void PdfAnnotation::SetColor( double C, double M, double Y, double K ) {
  PdfArray c;
  c.push_back( PdfVariant( C ) );
  c.push_back( PdfVariant( M ) );
  c.push_back( PdfVariant( Y ) );
  c.push_back( PdfVariant( K ) );
  m_pObject->GetDictionary().AddKey( "C", c );
}
Esempio n. 6
0
void PdfPagesTree::InsertPagesIntoNode( PdfObject* pParent, const PdfObjectList & rlstParents, 
                                       int nIndex, const std::vector<PdfObject*>& vecPages )
{
    if( !pParent || !vecPages.size() ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    // 1. Add the reference of the new page to the kids array of pParent
    // 2. Increase count of every node in lstParents (which also includes pParent)
    // 3. Add Parent key to the page

    // 1. Add reference
    const PdfArray oldKids = pParent->GetDictionary().GetKey( PdfName("Kids") )->GetArray();
    PdfArray newKids;
    newKids.reserve( oldKids.GetSize() + vecPages.size() );

    bool bIsPushedIn = false;
    int i=0;
    for (PdfArray::const_iterator it=oldKids.begin(); it!=oldKids.end(); ++it, ++i ) 
    {
        if ( !bIsPushedIn && (nIndex < i) )    // Pushing before
        {
            for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
            {
                newKids.push_back( (*itPages)->Reference() );    // Push all new kids at once
            }
            bIsPushedIn = true;
        }
        newKids.push_back( *it );    // Push in the old kids
    }

    // If new kids are still not pushed in then they may be appending to the end
    if ( !bIsPushedIn && ( (nIndex + 1) == static_cast<int>(oldKids.size())) ) 
    {
        for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
        {
            newKids.push_back( (*itPages)->Reference() );    // Push all new kids at once
        }
        bIsPushedIn = true;
    }

    pParent->GetDictionary().AddKey( PdfName("Kids"), newKids );
 

    // 2. increase count
    for ( PdfObjectList::const_reverse_iterator itParents = rlstParents.rbegin(); itParents != rlstParents.rend(); ++itParents )
    {
        this->ChangePagesCount( *itParents, vecPages.size() );
    } 

    // 3. add parent key to each of the pages
    for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
    {
        (*itPages)->GetDictionary().AddKey( PdfName("Parent"), pParent->Reference() );
    }
}
Esempio n. 7
0
void PdfOutlineItem::SetTextColor( double r, double g, double b )
{
    PdfArray color;
    color.push_back( r );
    color.push_back( g );
    color.push_back( b );

    m_pObject->GetDictionary().AddKey( "C", color );
}
Esempio n. 8
0
void PdfPagesTree::InsertPageIntoNode( PdfObject* pParent, const PdfObjectList & rlstParents, 
                                       int nIndex, PdfObject* pPage )
{
    if( !pParent || !pPage ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    // 1. Add the reference of the new page to the kids array of pParent
    // 2. Increase count of every node in lstParents (which also includes pParent)
    // 3. Add Parent key to the page

    // 1. Add reference
    const PdfArray oldKids = pParent->GetDictionary().GetKey( PdfName("Kids") )->GetArray();
    PdfArray::const_iterator it = oldKids.begin();
    PdfArray newKids;

    newKids.reserve( oldKids.GetSize() + 1 );

    if( nIndex < 0 ) 
    {
        newKids.push_back( pPage->Reference() );
    }

    int i = 0;
    while( it != oldKids.end() ) 
    {
        newKids.push_back( *it );

        if( i == nIndex ) 
            newKids.push_back( pPage->Reference() );

        ++i;
        ++it;
    }

    /*
    PdfVariant var2( newKids );
    std::string str2;
    var2.ToString(str2);
    printf("newKids= %s\n", str2.c_str() );
    */

    pParent->GetDictionary().AddKey( PdfName("Kids"), newKids );
 
    // 2. increase count
    PdfObjectList::const_reverse_iterator itParents = rlstParents.rbegin();
    while( itParents != rlstParents.rend() )
    {
        this->ChangePagesCount( *itParents, 1 );

        ++itParents;
    } 

    // 3. add parent key to the page
    pPage->GetDictionary().AddKey( PdfName("Parent"), pParent->Reference() );
}
void PdfFontMetricsFreetype::GetBoundingBox( PdfArray & array ) const
{
    if( !m_pFace ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    array.Clear();
    array.push_back( PdfVariant( m_pFace->bbox.xMin * 1000.0 / m_pFace->units_per_EM ) );
    array.push_back( PdfVariant( m_pFace->bbox.yMin  * 1000.0 / m_pFace->units_per_EM ) );
    array.push_back( PdfVariant( m_pFace->bbox.xMax  * 1000.0 / m_pFace->units_per_EM ) );
    array.push_back( PdfVariant( m_pFace->bbox.yMax  * 1000.0 / m_pFace->units_per_EM ) );
}
Esempio n. 10
0
void PdfAnnotation::SetBorderStyle( double dHCorner, double dVCorner, double dWidth, const PdfArray & rStrokeStyle )
{
    // TODO : Support for Border style for PDF Vers > 1.0
    PdfArray aValues;

    aValues.push_back(dHCorner);
    aValues.push_back(dVCorner);
    aValues.push_back(dWidth);
    if( rStrokeStyle.size() )
        aValues.push_back(rStrokeStyle);

    m_pObject->GetDictionary().AddKey( "Border", aValues );
}
Esempio n. 11
0
PdfXObject::PdfXObject( const PdfMemDocument & rDoc, int nPage, PdfDocument* pParent )
    : PdfElement( "XObject", pParent ), PdfCanvas()
{
    m_rRect = PdfRect();

    InitXObject( m_rRect, "XObInd" );

    // Implementation note: source document must be different from distination
    if ( pParent == reinterpret_cast<const PdfDocument*>(&rDoc) )
    {
        PODOFO_RAISE_ERROR( ePdfError_InternalLogic );
    }
    // After filling set correct BBox
    m_rRect = pParent->FillXObjectFromDocumentPage( this, rDoc, nPage );

    PdfVariant    var;
    m_rRect.ToVariant( var );
    m_pObject->GetDictionary().AddKey( "BBox", var );

    PdfArray      matrix;
    matrix.push_back( PdfVariant( 1LL ) );
    matrix.push_back( PdfVariant( 0LL ) );
    matrix.push_back( PdfVariant( 0LL ) );
    matrix.push_back( PdfVariant( 1LL ) );
	if( m_rRect.GetLeft() != 0 )
	    matrix.push_back( PdfVariant( m_rRect.GetLeft() * (-1.0) ) );
	else
	    matrix.push_back( PdfVariant( 0LL ) );
	if( m_rRect.GetBottom() != 0 )
	    matrix.push_back( PdfVariant( m_rRect.GetBottom() * (-1.0) ) );
	else
	    matrix.push_back( PdfVariant( 0LL ) );
    m_pObject->GetDictionary().AddKey( "Matrix", matrix );
}
Esempio n. 12
0
void PdfStitchingFunction::Init( const PdfFunction::List & rlstFunctions, const PdfArray & rBounds, const PdfArray & rEncode )
{
    PdfArray                          functions;
    PdfFunction::List::const_iterator it = rlstFunctions.begin();

    functions.reserve( rlstFunctions.size() );

    while( it != rlstFunctions.end() )
    {
        functions.push_back( (*it).GetObject()->Reference() );
        ++it;
    }
    
    this->GetObject()->GetDictionary().AddKey( PdfName("Functions"), functions );
    this->GetObject()->GetDictionary().AddKey( PdfName("Bounds"), rBounds );
    this->GetObject()->GetDictionary().AddKey( PdfName("Encode"), rEncode );
}
Esempio n. 13
0
void PdfSampledFunction::Init( const PdfArray & rDomain,  const PdfArray & rRange, const PdfFunction::Sample & rlstSamples )
{
	PdfArray Size;
	for( unsigned i = 0; i < rDomain.GetSize() / 2; i++ )
		Size.push_back( PdfObject( (long long) (rDomain.GetSize()) / 2L ) );

    this->GetObject()->GetDictionary().AddKey( PdfName("Domain"), rDomain );
    this->GetObject()->GetDictionary().AddKey( PdfName("Range"), rRange );
    this->GetObject()->GetDictionary().AddKey( PdfName("Size"), Size );
    this->GetObject()->GetDictionary().AddKey( PdfName("Order"), PdfObject( 1LL ) );
    this->GetObject()->GetDictionary().AddKey( PdfName("BitsPerSample"), PdfObject( 8LL ) );

    this->GetObject()->GetStream()->BeginAppend();
    PdfFunction::Sample::const_iterator it = rlstSamples.begin();
    while( it != rlstSamples.end() )
    {
        this->GetObject()->GetStream()->Append( & ( *it ), 1 );
        ++it;
    }
    this->GetObject()->GetStream()->EndAppend();
}
Esempio n. 14
0
void PdfFontCID::Init( bool bEmbed )
{
    PdfObject* pDescriptor;
    PdfObject* pDescendantFonts;
    PdfObject* pCIDSystemInfo;
    PdfObject* pUnicode;

    PdfVariant var;
    PdfArray   array;

    // The descendant font is a CIDFont:
    pDescendantFonts = this->GetObject()->GetOwner()->CreateObject("Font");
    pCIDSystemInfo   = this->GetObject()->GetOwner()->CreateObject();
    pDescriptor      = this->GetObject()->GetOwner()->CreateObject("FontDescriptor");
    pUnicode         = this->GetObject()->GetOwner()->CreateObject(); // The ToUnicode CMap

    // Now setting each of the entries of the font
    this->GetObject()->GetDictionary().AddKey( PdfName::KeySubtype, PdfName("Type0") );
    this->GetObject()->GetDictionary().AddKey( "BaseFont", this->GetBaseFont() );
    this->GetObject()->GetDictionary().AddKey( "ToUnicode", pUnicode->Reference() );

    // The encoding is here usually a (Predefined) CMap from PdfIdentityEncoding:
    m_pEncoding->AddToDictionary( this->GetObject()->GetDictionary() );

    // The DecendantFonts, should be an indirect object:
    array.push_back( pDescendantFonts->Reference() );
    this->GetObject()->GetDictionary().AddKey( "DescendantFonts", array );

    // Setting the DescendantFonts paras
    // This is a type2 CIDFont, which is also known as TrueType:
    pDescendantFonts->GetDictionary().AddKey( PdfName::KeySubtype, PdfName("CIDFontType2") );

    // Same base font as the owner font:
    pDescendantFonts->GetDictionary().AddKey( "BaseFont", this->GetBaseFont() );

    // The CIDSystemInfo, should be an indirect object:
    pDescendantFonts->GetDictionary().AddKey( "CIDSystemInfo", pCIDSystemInfo->Reference() );

    // The FontDescriptor, should be an indirect object:
    pDescendantFonts->GetDictionary().AddKey( "FontDescriptor", pDescriptor->Reference() );
    pDescendantFonts->GetDictionary().AddKey( "CIDToGIDMap", PdfName("Identity") );

    // Add the width keys
    this->CreateWidth( pDescendantFonts );

    // Create the ToUnicode CMap
    this->CreateCMap( pUnicode );

    // Setting the CIDSystemInfo paras:
    pCIDSystemInfo->GetDictionary().AddKey( "Registry", PdfString("Adobe") );
    pCIDSystemInfo->GetDictionary().AddKey( "Ordering", PdfString("Identity") );
    pCIDSystemInfo->GetDictionary().AddKey( "Supplement", PdfVariant(static_cast<pdf_int64>(0LL)) );


    // Setting the FontDescriptor paras:
    array.Clear();
    m_pMetrics->GetBoundingBox( array );

    pDescriptor->GetDictionary().AddKey( "FontName", this->GetBaseFont() );
    pDescriptor->GetDictionary().AddKey( PdfName::KeyFlags, PdfVariant( static_cast<pdf_int64>(32LL) ) ); // TODO: 0 ????
    pDescriptor->GetDictionary().AddKey( "FontBBox", array );
    pDescriptor->GetDictionary().AddKey( "ItalicAngle", PdfVariant( static_cast<pdf_int64>(m_pMetrics->GetItalicAngle()) ) );
    pDescriptor->GetDictionary().AddKey( "Ascent", m_pMetrics->GetPdfAscent() );
    pDescriptor->GetDictionary().AddKey( "Descent", m_pMetrics->GetPdfDescent() );
    pDescriptor->GetDictionary().AddKey( "CapHeight", m_pMetrics->GetPdfAscent() ); // m_pMetrics->CapHeight() );
    pDescriptor->GetDictionary().AddKey( "StemV", PdfVariant( static_cast<pdf_int64>(1LL) ) );               // m_pMetrics->StemV() );

    // Peter Petrov 24 September 2008
    m_pDescriptor = pDescriptor;
    
    if( bEmbed )
    {
        this->EmbedFont( pDescriptor );
        m_bWasEmbedded = true;
    }
}
Esempio n. 15
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 );
}
Esempio n. 16
0
void PdfAnnotation::SetColor( double gray )
{
    PdfArray c;
    c.push_back( PdfVariant( gray ) );
    this->GetObject()->GetDictionary().AddKey( "C", c );
}
Esempio n. 17
0
void PdfTilingPattern::Init( EPdfTilingPatternType eTilingType,
		 double strokeR, double strokeG, double strokeB,
		 bool doFill, double fillR, double fillG, double fillB,
		 double offsetX, double offsetY,
		 PdfImage *pImage)
{
	if (eTilingType == ePdfTilingPatternType_Image && pImage == NULL) {
		PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
	}

	if (eTilingType != ePdfTilingPatternType_Image && pImage != NULL) {
		PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
	}

	PdfRect rRect;
	rRect.SetLeft(0);
	rRect.SetBottom(0);

	if (pImage) {
		rRect.SetWidth(pImage->GetWidth());
		rRect.SetHeight(-pImage->GetHeight());
	} else {
		rRect.SetWidth(8);
		rRect.SetHeight(8);
	}

	PdfVariant var;
   rRect.ToVariant( var );

	this->GetObject()->GetDictionary().AddKey( PdfName("PatternType"), static_cast<pdf_int64>(1L) ); // Tiling pattern
	this->GetObject()->GetDictionary().AddKey( PdfName("PaintType"), static_cast<pdf_int64>(1L) ); // Colored
	this->GetObject()->GetDictionary().AddKey( PdfName("TilingType"), static_cast<pdf_int64>(1L) ); // Constant spacing
	this->GetObject()->GetDictionary().AddKey( PdfName("BBox"), var );
	this->GetObject()->GetDictionary().AddKey( PdfName("XStep"), static_cast<pdf_int64>(rRect.GetWidth()) );
	this->GetObject()->GetDictionary().AddKey( PdfName("YStep"), static_cast<pdf_int64>(rRect.GetHeight()) );
	this->GetObject()->GetDictionary().AddKey( PdfName("Resources"), PdfObject( PdfDictionary() ) );

	if (offsetX < -1e-9 || offsetX > 1e-9 || offsetY < -1e-9 || offsetY > 1e-9) {
		PdfArray array;

		array.push_back (static_cast<pdf_int64>(1));
		array.push_back (static_cast<pdf_int64>(0));
		array.push_back (static_cast<pdf_int64>(0));
		array.push_back (static_cast<pdf_int64>(1));
		array.push_back (offsetX);
		array.push_back (offsetY);

		this->GetObject()->GetDictionary().AddKey( PdfName("Matrix"), array );
	}

   std::ostringstream out;
   out.flags( std::ios_base::fixed );
   out.precision( 1L /* clPainterDefaultPrecision */ );
   PdfLocaleImbue(out);

	if (pImage) {
		AddToResources(pImage->GetIdentifier(), pImage->GetObjectReference(), PdfName("XObject"));

      out << rRect.GetWidth() << " 0 0 "
          << rRect.GetHeight() << " "
          << rRect.GetLeft() << " " 
          << rRect.GetBottom() << " cm" << std::endl;
		out << "/" << pImage->GetIdentifier().GetName() << " Do" << std::endl;
	} else {
		if (doFill) {
			out << fillR << " " << fillG << " " << fillB << " rg" << " ";
			out << rRect.GetLeft() << " " << rRect.GetBottom() << " " << rRect.GetWidth() << " " << rRect.GetHeight() << " re" << " ";
			out << "f" <<  " "; //fill rect
		}

		out << strokeR << " " << strokeG << " " << strokeB << " RG" << " ";
		out << "2 J" << " "; // line capability style
		out << "0.5 w" <<  " "; //line width

		double left, bottom, right, top, whalf, hhalf;
		left = rRect.GetLeft();
		bottom = rRect.GetBottom();
		right = left + rRect.GetWidth();
		top = bottom + rRect.GetHeight();
		whalf = rRect.GetWidth() / 2;
		hhalf = rRect.GetHeight() / 2;

		switch (eTilingType) {
		case ePdfTilingPatternType_BDiagonal:
			out << left          << " " << bottom         << " m " << right         << " " << top            << " l ";
			out << left - whalf  << " " << top - hhalf    << " m " << left + whalf  << " " << top + hhalf    << " l ";
			out << right - whalf << " " << bottom - hhalf << " m " << right + whalf << " " << bottom + hhalf << " l" << std::endl;
			break;
		case ePdfTilingPatternType_Cross:
			out << left          << " " << bottom + hhalf << " m " << right         << " " << bottom + hhalf << " l ";
			out << left + whalf  << " " << bottom         << " m " << left + whalf  << " " << top            << " l" << std::endl;
			break;
		case ePdfTilingPatternType_DiagCross:
			out << left          << " " << bottom         << " m " << right         << " " << top            << " l ";
			out << left          << " " << top            << " m " << right         << " " << bottom         << " l" << std::endl;
			break;
		case ePdfTilingPatternType_FDiagonal:
			out << left          << " " << top            << " m " << right         << " " << bottom         << " l ";
			out << left - whalf  << " " << bottom + hhalf << " m " << left + whalf  << " " << bottom - hhalf << " l ";
			out << right - whalf << " " << top + hhalf    << " m " << right + whalf << " " << top - hhalf    << " l" << std::endl;
			break;
		case ePdfTilingPatternType_Horizontal:
			out << left          << " " << bottom + hhalf << " m " << right         << " " << bottom + hhalf << " l ";
			break;
		case ePdfTilingPatternType_Vertical:
			out << left + whalf  << " " << bottom         << " m " << left + whalf  << " " << top            << " l" << std::endl;
			break;
		case ePdfTilingPatternType_Image:
			/* This is handled above, based on the 'pImage' variable */
		default:
			PODOFO_RAISE_ERROR (ePdfError_InvalidEnumValue);
			break;

		}

		out << "S"; //stroke path
	}

	TVecFilters vecFlate;
	vecFlate.push_back( ePdfFilter_FlateDecode );

	std::string str = out.str();
	PdfMemoryInputStream stream(str.c_str(), str.length());

	this->GetObject()->GetStream()->Set(&stream, vecFlate);
}
void PdfMemStream::FlateCompress()
{
    PdfObject*        pObj;
    PdfVariant        vFilter( PdfName("FlateDecode" ) );
    PdfVariant        vFilterList;
    PdfArray          tFilters;

    PdfArray::const_iterator tciFilters;
    
    if( !m_lLength )
        return; // ePdfError_ErrOk

    // TODO: Handle DecodeParms
    if( m_pParent->GetDictionary().HasKey( "Filter" ) )
    {
        pObj = m_pParent->GetIndirectKey( "Filter" );

        if( pObj->IsName() )
        {
            if( pObj->GetName() != "DCTDecode" && pObj->GetName() != "FlateDecode" )
            {
                tFilters.push_back( vFilter );
                tFilters.push_back( *pObj );
            }
        }
        else if( pObj->IsArray() )
        {
            tciFilters = pObj->GetArray().begin();

            while( tciFilters != pObj->GetArray().end() )
            {
                if( (*tciFilters).IsName() )
                {
                    // do not compress DCTDecoded are already FlateDecoded streams again
                    if( (*tciFilters).GetName() == "DCTDecode" || (*tciFilters).GetName() == "FlateDecode" )
                    {
                        return;
                    }
                }

                ++tciFilters;
            }

            tFilters.push_back( vFilter );

            tciFilters = pObj->GetArray().begin();

            while( tciFilters != pObj->GetArray().end() )
            {
                tFilters.push_back( (*tciFilters) );
                
                ++tciFilters;
            }
        }
        else
            return;

        vFilterList = PdfVariant( tFilters );
        m_pParent->GetDictionary().AddKey( "Filter", vFilterList );

        FlateCompressStreamData(); // throws an exception on error
    }
    else
    {
        m_pParent->GetDictionary().AddKey( "Filter", PdfName( "FlateDecode" ) );
        FlateCompressStreamData();
    }
}