std::string PdfVecObjects::GetNextSubsetPrefix()
{
	if ( m_sSubsetPrefix == "" )
	{
		m_sSubsetPrefix = "AAAAAA+";
	}
	else
	{
		PODOFO_ASSERT( m_sSubsetPrefix.length() == 7 );
		PODOFO_ASSERT( m_sSubsetPrefix[6] == '+' );
	
		for ( int i = 5; i >= 0; i-- )
		{
			if ( m_sSubsetPrefix[i] < 'Z' )
			{
				m_sSubsetPrefix[i]++;
				break;
			}
			m_sSubsetPrefix[i] = 'A';
		}
	}

	return m_sSubsetPrefix;
}
Example #2
0
PdfFont* PdfFontCache::GetDuplicateFontType1( PdfFont * pFont, const char* pszSuffix )
{
    TCISortedFontList it = m_vecFonts.begin();

	std::string id = pFont->GetIdentifier().GetName();
	id += pszSuffix;

    // Search if the object is a cached normal font
    while( it != m_vecFonts.end() )
    {
		if( (*it).m_pFont->GetIdentifier() == id ) 
            return (*it).m_pFont;

        ++it;
    }

    // Search if the object is a cached font subset
    it = m_vecFontSubsets.begin();
    while( it != m_vecFontSubsets.end() )
    {
        if( (*it).m_pFont->GetIdentifier() == id ) 
            return (*it).m_pFont;

        ++it;
    }

    // Create a copy of the font
	PODOFO_ASSERT( pFont->GetFontMetrics()->GetFontType() == ePdfFontType_Type1Pfb );
	PdfFontMetrics *pMetrics = new PdfFontMetrics( &m_ftLibrary, pFont->GetFontMetrics()->GetFilename() );
	PdfFont* newFont = new PdfFontType1( static_cast<PdfFontType1 *>(pFont), pMetrics, pszSuffix, m_pParent );
    if( newFont ) 
    {
		std::string name = newFont->GetFontMetrics()->GetFontname();
		name += pszSuffix;
        TFontCacheElement element;
        element.m_pFont     = newFont;
        element.m_bBold     = newFont->IsBold();
        element.m_bItalic   = newFont->IsItalic();
        element.m_sFontName = name;
        element.m_pEncoding = newFont->GetEncoding();
        m_vecFonts  .push_back( element );
        
        // Now sort the font list
        std::sort( m_vecFonts.begin(), m_vecFonts.end() );
    }

    return newFont;
}
Example #3
0
PdfFont* PdfFontCache::GetFont( const wchar_t* pszFontName, bool bBold, bool bItalic, 
                                bool bEmbedd, const PdfEncoding * const pEncoding )
{
    PODOFO_ASSERT( pEncoding );

    PdfFont*          pFont;
    std::pair<TISortedFontList,TCISortedFontList> it;

    it = std::equal_range( m_vecFonts.begin(), m_vecFonts.end(), 
			   TFontCacheElement( pszFontName, bBold, bItalic, pEncoding ) );
    if( it.first == it.second )
        return GetWin32Font( it.first, m_vecFonts, pszFontName, bBold, bItalic, bEmbedd, pEncoding );
    else
        pFont = (*it.first).m_pFont;
    
    return pFont;
}
Example #4
0
PdfFont* PdfFontCache::GetFont( const char* pszFontName, bool bBold, bool bItalic, 
                                bool bEmbedd, const PdfEncoding * const pEncoding, 
                                const char* pszFileName )
{
    PODOFO_ASSERT( pEncoding );

    PdfFont*          pFont;
    PdfFontMetrics*   pMetrics;
    std::pair<TISortedFontList,TCISortedFontList> it;

    it = std::equal_range( m_vecFonts.begin(), m_vecFonts.end(), 
			   TFontCacheElement( pszFontName, bBold, bItalic, pEncoding ) );
    if( it.first == it.second )
    {
        std::string sPath;
        if ( pszFileName == NULL )
            sPath = this->GetFontPath( pszFontName, bBold, bItalic );
        else
            sPath = pszFileName;
        
        if( sPath.empty() )
        {
#ifdef _WIN32
            return GetWin32Font( it.first, m_vecFonts, pszFontName, bBold, bItalic, bEmbedd, pEncoding );
#else
            PdfError::LogMessage( eLogSeverity_Critical, "No path was found for the specified fontname: %s\n", pszFontName );
            return NULL;
#endif // _WIN32
        }
        
        pMetrics = new PdfFontMetrics( &m_ftLibrary, sPath.c_str() );
        pFont    = this->CreateFontObject( it.first, m_vecFonts, pMetrics, 
					   bEmbedd, bBold, bItalic, pszFontName, pEncoding );
    }
    else
        pFont = (*it.first).m_pFont;
    
    return pFont;
}
PdfFontMetricsObject::PdfFontMetricsObject( PdfObject* pFont, PdfObject* pDescriptor, const PdfEncoding* const pEncoding )
    : PdfFontMetrics( ePdfFontType_Unknown, "", NULL ),
      m_pEncoding( pEncoding ), m_dDefWidth(0.0)
{
    if( !pDescriptor )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

	const PdfName & rSubType = pFont->GetDictionary().GetKey( PdfName::KeySubtype )->GetName();

    // OC 15.08.2010 BugFix: /FirstChar /LastChar /Widths are in the Font dictionary and not in the FontDescriptor
	if ( rSubType == PdfName("Type1") || rSubType == PdfName("TrueType") ) {
		m_sName        = pDescriptor->GetIndirectKey( "FontName" )->GetName();
		m_bbox         = pDescriptor->GetIndirectKey( "FontBBox" )->GetArray();
    m_nFirst       = static_cast<int>(pFont->GetDictionary().GetKeyAsLong( "FirstChar", 0L ));
    m_nLast        = static_cast<int>(pFont->GetDictionary().GetKeyAsLong( "LastChar", 0L ));
	 // OC 15.08.2010 BugFix: GetIndirectKey() instead of GetDictionary().GetKey() and "Widths" instead of "Width"
    PdfObject* widths = pFont->GetIndirectKey( "Widths" );
    if( widths != NULL )
    {
        m_width        = widths->GetArray();
        m_missingWidth = NULL;
    }
    else
    {
        widths = pDescriptor->GetDictionary().GetKey( "MissingWidth" );
        if( widths == NULL ) 
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_NoObject, "Font object defines neither Widths, nor MissingWidth values!" );
            m_missingWidth = widths;
        }
    }
	} else if ( rSubType == PdfName("CIDFontType0") || rSubType == PdfName("CIDFontType2") ) {
		PdfObject *pObj = pDescriptor->GetIndirectKey( "FontName" );
		if (pObj) {
			m_sName = pObj->GetName();
		}
		pObj = pDescriptor->GetIndirectKey( "FontBBox" );
		if (pObj) {
			m_bbox = pObj->GetArray();
		}
		m_nFirst = 0;
		m_nLast = 0;

		m_dDefWidth = static_cast<double>(pFont->GetDictionary().GetKeyAsLong( "DW", 1000L ));
		PdfVariant default_width(m_dDefWidth);
		PdfObject * pw = pFont->GetIndirectKey( "W" );

		for (int i = m_nFirst; i <= m_nLast; ++i) {
			m_width.push_back(default_width);
		}
		if (pw) {
			PdfArray w = pw->GetArray();
			int pos = 0;
			while (pos < static_cast<int>(w.GetSize())) {
				int start = static_cast<int>(w[pos++].GetNumber());
				PODOFO_ASSERT (start >= 0);
				if (w[pos].IsArray()) {
					PdfArray widths = w[pos++].GetArray();
					int length = start + static_cast<int>(widths.GetSize());
					PODOFO_ASSERT (length >= start);
					if (length > static_cast<int>(m_width.GetSize())) {
						m_width.resize(length, default_width);
					}
					for (int i = 0; i < static_cast<int>(widths.GetSize()); ++i) {
						m_width[start + i] = widths[i];
					}
				} else {
					int end = static_cast<int>(w[pos++].GetNumber());
					int length = start + end;
					PODOFO_ASSERT (length >= start);
					if (length > static_cast<int>(m_width.GetSize())) {
						m_width.resize(length, default_width);
					}
					pdf_int64 width = w[pos++].GetNumber();
					for (int i = start; i <= end; ++i)
						m_width[i] = PdfVariant(width);
				}
			}
		}
		m_nLast = m_width.GetSize() - 1;
	} else {
        PODOFO_RAISE_ERROR_INFO( ePdfError_UnsupportedFontFormat, rSubType.GetEscapedName().c_str() );
	}


    m_nWeight      = static_cast<unsigned int>(pDescriptor->GetDictionary().GetKeyAsLong( "FontWeight", 400L ));
    m_nItalicAngle = static_cast<int>(pDescriptor->GetDictionary().GetKeyAsLong( "ItalicAngle", 0L ));

    m_dPdfAscent   = pDescriptor->GetDictionary().GetKeyAsReal( "Ascent", 0.0 );
    m_dAscent      = m_dPdfAscent / 1000.0;
    m_dPdfDescent  = pDescriptor->GetDictionary().GetKeyAsReal( "Descent", 0.0 );
    m_dDescent     = m_dPdfDescent / 1000.0;
    m_dLineSpacing = m_dAscent + m_dDescent;
    
    // Try to fine some sensible values
    m_dUnderlineThickness = 1.0;
    m_dUnderlinePosition  = 0.0;
    m_dStrikeOutThickness = m_dUnderlinePosition;
    m_dStrikeOutPosition  = m_dAscent / 2.0;

    m_bSymbol = false; // TODO
}
Example #6
0
PdfFont* PdfFontCache::GetFontSubset( const char* pszFontName, bool bBold, bool bItalic, 
				      const PdfEncoding * const pEncoding,
				      const char* pszFileName )
{
    PdfFont*        pFont;
    PdfFontMetrics* pMetrics;
    std::pair<TISortedFontList,TCISortedFontList> it;

    // WARNING: The characters are completely ignored right now!

    it = std::equal_range( m_vecFontSubsets.begin(), m_vecFontSubsets.end(), 
			   TFontCacheElement( pszFontName, bBold, bItalic, pEncoding ) );
    if( it.first == it.second )
    {
	std::string sPath; 
	if( pszFileName == NULL ) 
	{
	    sPath = this->GetFontPath( pszFontName, bBold, bItalic );
	    if( sPath.empty() )
	    {
#ifdef _WIN32
		// TODO: GetWin32Font
		PODOFO_ASSERT( 0 );
#else	    
		PdfError::LogMessage( eLogSeverity_Critical, "No path was found for the specified fontname: %s\n", pszFontName );
		return NULL;
#endif // _WIN32
	    }
	}
	else
	    sPath = pszFileName;
	
	pMetrics = new PdfFontMetrics( &m_ftLibrary, sPath.c_str() );
	if( !(pMetrics && pMetrics->GetFontType() == ePdfFontType_TrueType ) )
	{
	    PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidFontFile, "Subsetting is only supported for TrueType fonts." );
	}
	
	PdfInputDevice          input( sPath.c_str() );
	PdfRefCountedBuffer     buffer;
	PdfOutputDevice         output( &buffer );
	
	PdfFontTTFSubset        subset( &input, pMetrics, PdfFontTTFSubset::eFontFileType_TTF );
	PdfEncoding::const_iterator itChar
	    = pEncoding->begin();
	while( itChar != pEncoding->end() )
	{
	    subset.AddCharacter( *itChar );
	    ++itChar;
	}
	subset.BuildFont( &output );

	// Delete metrics object, as it was only used so that PdfFontTTFSubset could
	// match unicode character points to glyph indeces
	delete pMetrics;
	// TODO: Do not hardcode unique basenames...
	pMetrics = new PdfFontMetrics( &m_ftLibrary, buffer, "ABCDEF+" );
	pFont = this->CreateFontObject( it.first, m_vecFontSubsets, pMetrics, 
					true, bBold, bItalic, pszFontName, pEncoding );
    }
    else
	pFont = (*it.first).m_pFont;


    return pFont;
}