rpms/openoffice.org/F-7 workspace.glyphadv.patch, NONE, 1.1 openoffice.org.spec, 1.1186, 1.1187 openoffice.org-2.2.1.ooo78895.sw.overlappingpdf.patch, 1.1, NONE

Caolan McNamara (caolanm) fedora-extras-commits at redhat.com
Wed Jun 27 08:53:21 UTC 2007


Author: caolanm

Update of /cvs/pkgs/rpms/openoffice.org/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv19495

Modified Files:
	openoffice.org.spec 
Added Files:
	workspace.glyphadv.patch 
Removed Files:
	openoffice.org-2.2.1.ooo78895.sw.overlappingpdf.patch 
Log Message:
workspace.glyphadv.patch

workspace.glyphadv.patch:

--- NEW FILE workspace.glyphadv.patch ---
Index: gsl/psprint/inc/psprint/fontmanager.hxx
diff -u gsl/psprint/inc/psprint/fontmanager.hxx:1.31 gsl/psprint/inc/psprint/fontmanager.hxx:1.31.72.1
--- gsl/psprint/inc/psprint/fontmanager.hxx:1.31	Mon Jun 19 03:23:01 2006
+++ gsl/psprint/inc/psprint/fontmanager.hxx	Wed Feb 28 05:59:08 2007
@@ -651,6 +651,11 @@
                            int nGlyphs,
                            bool bVertical = false
                            );
+    void getGlyphWidths( fontID nFont,
+                         bool bVertical,
+                         std::vector< sal_Int32 >& rWidths,
+                         std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
+
 
     // font administration functions
 
Index: gsl/psprint/source/fontmanager/fontmanager.cxx
diff -u gsl/psprint/source/fontmanager/fontmanager.cxx:1.73 gsl/psprint/source/fontmanager/fontmanager.cxx:1.73.46.2
--- gsl/psprint/source/fontmanager/fontmanager.cxx:1.73	Sat Sep 16 05:34:04 2006
+++ gsl/psprint/source/fontmanager/fontmanager.cxx	Mon Mar  5 07:13:28 2007
@@ -3146,11 +3146,11 @@
             effectiveCode |= bVertical ? 1 << 16 : 0;
             ::std::hash_map< int, CharacterMetric >::const_iterator it =
                   pFont->m_pMetrics->m_aMetrics.find( effectiveCode );
-	    // if no vertical metrics are available assume rotated horizontal metrics
-	    if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) )
-                  it = pFont->m_pMetrics->m_aMetrics.find( code );
-	    // the character metrics are in it->second
-	    if( it != pFont->m_pMetrics->m_aMetrics.end() )
+            // if no vertical metrics are available assume rotated horizontal metrics
+            if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) )
+                it = pFont->m_pMetrics->m_aMetrics.find( code );
+            // the character metrics are in it->second
+            if( it != pFont->m_pMetrics->m_aMetrics.end() )
                 pArray[ code - minCharacter ] = it->second;
         }
     }
@@ -3639,7 +3639,7 @@
         }
         else
         {
-            DBG_ASSERT( !(pGlyphIDs[i] & 0xffff0000), "overlong glyph id" );
+            DBG_ASSERT( !(pGlyphIDs[i] & 0x007f0000), "overlong glyph id" );
             DBG_ASSERT( (int)pNewEncoding[i] < nGlyphs, "encoding wrong" );
             DBG_ASSERT( pEnc[pNewEncoding[i]] == 0 && pGID[pNewEncoding[i]] == 0, "duplicate encoded glyph" );
             pEnc[ pNewEncoding[i] ] = pNewEncoding[i];
@@ -3687,6 +3687,66 @@
     return bSuccess;
 }
 
+void PrintFontManager::getGlyphWidths( fontID nFont,
+                                       bool bVertical,
+                                       std::vector< sal_Int32 >& rWidths,
+                                       std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc )
+{
+    PrintFont* pFont = getFont( nFont );
+    if( !pFont ||
+        (pFont->m_eType != fonttype::TrueType && pFont->m_eType != fonttype::Type1) )
+        return;
+    if( pFont->m_eType == fonttype::TrueType )
+    {
+        TrueTypeFont* pTTFont = NULL;
+        TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont);
+        ByteString aFromFile = getFontFile( pFont );
+        if( OpenTTFont( aFromFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) != SF_OK )
+            return;
+        int nGlyphs = GetTTGlyphCount( pTTFont );
+        if( nGlyphs > 0 )
+        {
+            rWidths.resize(nGlyphs);
+            std::vector<sal_uInt16> aGlyphIds(nGlyphs);
+            for( int i = 0; i < nGlyphs; i++ )
+                aGlyphIds[i] = sal_uInt16(i);
+            TTSimpleGlyphMetrics* pMetrics = GetTTSimpleGlyphMetrics( pTTFont,
+                                                                      &aGlyphIds[0],
+                                                                      nGlyphs,
+                                                                      bVertical ? 1 : 0 );
+            if( pMetrics )
+            {
+                for( int i = 0; i< nGlyphs; i++ )
+                    rWidths[i] = pMetrics[i].adv;
+                free( pMetrics );
+                rUnicodeEnc.clear();
+            }
+        }
+        CloseTTFont( pTTFont );
+    }
+    else if( pFont->m_eType == fonttype::Type1 )
+    {
+        if( ! pFont->m_aEncodingVector.size() )
+            pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, true, true );
+        if( pFont->m_pMetrics )
+        {
+            rUnicodeEnc.clear();
+            rWidths.clear();
+            rWidths.reserve( pFont->m_pMetrics->m_aMetrics.size() );
+            for( std::hash_map< int, CharacterMetric >::const_iterator it = 
+                 pFont->m_pMetrics->m_aMetrics.begin();
+                 it != pFont->m_pMetrics->m_aMetrics.end(); ++it )
+            {
+                if( (it->first & 0x00010000) == 0 || bVertical )
+                {
+                    rUnicodeEnc[ sal_Unicode(it->first & 0x0000ffff) ] = sal_uInt32(rWidths.size());
+                    rWidths.push_back( it->second.width );
+                }
+            }
+        }
+    }
+}
+
 // -------------------------------------------------------------------------
 
 const std::map< sal_Unicode, sal_Int32 >* PrintFontManager::getEncodingMap( fontID nFont, const std::map< sal_Unicode, rtl::OString >** pNonEncoded ) const
Index: gsl/psprint/source/fontsubset/sft.c
diff -u gsl/psprint/source/fontsubset/sft.c:1.39 gsl/psprint/source/fontsubset/sft.c:1.39.40.1
--- gsl/psprint/source/fontsubset/sft.c:1.39	Fri Oct 13 01:28:20 2006
+++ gsl/psprint/source/fontsubset/sft.c	Wed Feb 28 05:59:09 2007
@@ -2553,6 +2553,11 @@
 
 #endif
 
+int GetTTGlyphCount( TrueTypeFont* ttf )
+{
+    return ttf->nglyphs;
+}
+
 TTSimpleGlyphMetrics *GetTTSimpleGlyphMetrics(TrueTypeFont *ttf, sal_uInt16 *glyphArray, int nGlyphs, int mode)
 {
     sal_uInt8* pTable;
Index: gsl/psprint/source/fontsubset/sft.h
diff -u gsl/psprint/source/fontsubset/sft.h:1.15 gsl/psprint/source/fontsubset/sft.h:1.15.72.1
--- gsl/psprint/source/fontsubset/sft.h:1.15	Mon Jun 19 03:25:17 2006
+++ gsl/psprint/source/fontsubset/sft.h	Wed Feb 28 05:59:10 2007
@@ -571,6 +571,11 @@
  */
     int CheckSymbolEncoding(TrueTypeFont* ttf);
     
+/**
+ * returns the number of glyphs in a font
+ */
+ int GetTTGlyphCount( TrueTypeFont* ttf );
+    
 /*- private definitions */ /*FOLD00*/
 
     struct _TrueTypeFont {
Index: gsl/vcl/inc/outfont.hxx
diff -u gsl/vcl/inc/outfont.hxx:1.23 gsl/vcl/inc/outfont.hxx:1.23.246.1
--- gsl/vcl/inc/outfont.hxx:1.23	Thu Jul 13 03:12:00 2006
+++ gsl/vcl/inc/outfont.hxx	Wed Feb 28 06:00:30 2007
@@ -152,7 +152,8 @@
 
     virtual int             GetHeight() const           { return mnHeight; }
     virtual int             GetWidth() const            { return mnWidth; }
-    virtual sal_IntPtr      GetFontId() const           { return 0; }
+    virtual sal_IntPtr      GetFontId() const = 0;
+    int                     GetFontMagic() const        { return mnMagic; }
     bool                    IsScalable() const          { return (mnHeight == 0); }
     bool                    CheckMagic( int n ) const   { return (n == mnMagic); }
     ImplFontData*           GetNextFace() const         { return mpNext; }
Index: gsl/vcl/inc/salgdi.hxx
diff -u gsl/vcl/inc/salgdi.hxx:1.36 gsl/vcl/inc/salgdi.hxx:1.36.94.1
--- gsl/vcl/inc/salgdi.hxx:1.36	Tue Nov 14 07:22:46 2006
+++ gsl/vcl/inc/salgdi.hxx	Wed Feb 28 06:00:30 2007
@@ -296,6 +296,15 @@
                                           long* pDataLen ) = 0;
     // frees the font data again
     virtual void			FreeEmbedFontData( const void* pData, long nDataLen ) = 0;
+    
+    // get the same widths as in CreateFontSubset and GetEmbedFontData
+    // in case of an embeddable font also fill the mapping
+    // between unicode and glyph id
+    // leave widths vector and mapping untouched in case of failure
+    virtual void            GetGlyphWidths( ImplFontData* pFont,
+                                            bool bVertical,
+                                            std::vector< sal_Int32 >& rWidths,
+                                            std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) = 0;
 
     virtual BOOL                    GetGlyphBoundRect( long nIndex, Rectangle& ) = 0;
     virtual BOOL                    GetGlyphOutline( long nIndex, basegfx::B2DPolyPolygon& ) = 0;
Index: gsl/vcl/source/gdi/makefile.mk
diff -u gsl/vcl/source/gdi/makefile.mk:1.29 gsl/vcl/source/gdi/makefile.mk:1.29.18.2
--- gsl/vcl/source/gdi/makefile.mk:1.29	Tue Feb  6 06:18:36 2007
+++ gsl/vcl/source/gdi/makefile.mk	Mon Mar  5 06:28:12 2007
@@ -108,6 +108,7 @@
 			$(SLO)$/base14.obj		\
 			$(SLO)$/pdfwriter.obj	\
 			$(SLO)$/pdfwriter_impl.obj	\
+            $(SLO)$/pdffontcache.obj\
 			$(SLO)$/sallayout.obj		\
 			$(SLO)$/salgdilayout.obj	\
 			$(SLO)$/extoutdevdata.obj	\
@@ -128,6 +129,7 @@
 					$(SLO)$/impgraph.obj	\
                     $(SLO)$/metric.obj		\
                     $(SLO)$/pdfwriter_impl.obj	\
+                    $(SLO)$/pdffontcache.obj\
                     $(SLO)$/fontcfg.obj		\
 					$(SLO)$/bmpconv.obj		\
 					$(SLO)$/pdfextoutdevdata.obj	\
Index: gsl/vcl/source/gdi/pdffontcache.cxx
diff -u /dev/null gsl/vcl/source/gdi/pdffontcache.cxx:1.1.2.3
--- /dev/null	Wed Jun 27 01:30:16 2007
+++ gsl/vcl/source/gdi/pdffontcache.cxx	Fri Mar  2 08:22:22 2007
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision$
+ *
+ *  last change: $Author$ $Date$
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include "precompiled_vcl.hxx"
+
+#include "pdffontcache.hxx"
+#include "salgdi.hxx"
+#include "outfont.hxx"
+#include "sallayout.hxx"
+
+using namespace vcl;
+
+PDFFontCache::FontIdentifier::FontIdentifier( ImplFontData* pFont, bool bVertical ) :
+    m_nFontId( pFont->GetFontId() ),
+    m_nMagic( pFont->GetFontMagic() ),
+    m_bVertical( bVertical )
+{
+}
+
+PDFFontCache::FontData& PDFFontCache::getFont( ImplFontData* pFont, bool bVertical )
+{
+    FontIdentifier aId( pFont, bVertical );
+    FontToIndexMap::iterator it = m_aFontToIndex.find( aId );
+    if( it != m_aFontToIndex.end() )
+        return m_aFonts[ it->second ];
+    m_aFontToIndex[ aId ] = sal_uInt32(m_aFonts.size());
+    m_aFonts.push_back( FontData() );
+    return m_aFonts.back();
+}
+
+sal_Int32 PDFFontCache::getGlyphWidth( ImplFontData* pFont, sal_uInt32 nGlyph, bool bVertical, SalGraphics* pGraphics )
+{
+    sal_Int32 nWidth = 0;
+    FontData& rFontData( getFont( pFont, bVertical ) );
+    if( rFontData.m_nWidths.empty() )
+    {
+        pGraphics->GetGlyphWidths( pFont, bVertical, rFontData.m_nWidths, rFontData.m_aGlyphIdToIndex );
+    }
+    if( ! rFontData.m_nWidths.empty() )
+    {
+        sal_uInt32 nIndex = nGlyph;
+        if( (nGlyph & GF_ISCHAR) != 0 )
+        {
+            std::map<sal_Unicode,sal_uInt32>::const_iterator it =
+                rFontData.m_aGlyphIdToIndex.find( sal_Unicode(nGlyph & GF_IDXMASK) );
+                nIndex = (it != rFontData.m_aGlyphIdToIndex.end()) ? it->second : 0;
+        }
+        nIndex &= GF_IDXMASK;
+        if( nIndex < rFontData.m_nWidths.size() )
+            nWidth = rFontData.m_nWidths[ nIndex ];
+    }
+    return nWidth;
+}
Index: gsl/vcl/source/gdi/pdffontcache.hxx
diff -u /dev/null gsl/vcl/source/gdi/pdffontcache.hxx:1.1.2.2
--- /dev/null	Wed Jun 27 01:30:16 2007
+++ gsl/vcl/source/gdi/pdffontcache.hxx	Mon Mar  5 06:28:12 2007
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile$
+ *
+ *  $Revision$
+ *
+ *  last change: $Author$ $Date$
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#ifndef VCL_PDFFONTCACHE_HXX
+#define VCL_PDFFONTCACHE_HXX
+
+#include <sal/types.h>
+
+#include <vector>
+#include <map>
+
+class ImplFontData;
+class SalGraphics;
+
+namespace vcl
+{
+    class PDFFontCache
+    {
+        struct FontIdentifier
+        {
+            sal_IntPtr      m_nFontId;
+            int             m_nMagic;
+            bool            m_bVertical;
+            
+            FontIdentifier( ImplFontData*, bool bVertical );
+            FontIdentifier() : m_nFontId(0), m_nMagic(0), m_bVertical( false ) {}
+            
+            bool operator==( const FontIdentifier& rRight ) const
+            {
+                return m_nFontId == rRight.m_nFontId &&
+                       m_nMagic == rRight.m_nMagic &&
+                       m_bVertical == rRight.m_bVertical;
+            }
+            bool operator<( const FontIdentifier& rRight ) const
+            {
+                return m_nFontId < rRight.m_nFontId ||
+                       m_nMagic < rRight.m_nMagic ||
+                       m_bVertical < rRight.m_bVertical;
+            }
+        };
+        struct FontData
+        {
+            std::vector< sal_Int32 >                m_nWidths;
+            std::map< sal_Unicode, sal_uInt32 >     m_aGlyphIdToIndex;
+        };
+        typedef std::map< FontIdentifier, sal_uInt32 > FontToIndexMap;
+        
+        std::vector< FontData >     m_aFonts;
+        FontToIndexMap              m_aFontToIndex;
+        
+        FontData& getFont( ImplFontData*, bool bVertical );
+        public:
+        PDFFontCache() {}
+        ~PDFFontCache() {}
+        
+        sal_Int32 getGlyphWidth( ImplFontData* pFont, sal_uInt32 nGlyphId, bool bVertical, SalGraphics* pGraphics );
+    };
+}
+
+#endif
Index: gsl/vcl/source/gdi/pdfwriter_impl.cxx
diff -u gsl/vcl/source/gdi/pdfwriter_impl.cxx:1.102 gsl/vcl/source/gdi/pdfwriter_impl.cxx:1.102.66.9
--- gsl/vcl/source/gdi/pdfwriter_impl.cxx:1.102	Thu Dec 21 04:03:14 2006
+++ gsl/vcl/source/gdi/pdfwriter_impl.cxx	Fri Mar  2 09:10:34 2007
@@ -718,7 +718,7 @@
 
     void append( PDFWriterImpl::PDFPage& rPage, OStringBuffer& rBuffer, Point* pBack = NULL );
 
-    Point transform( const Point& rPoint );
+    Point transform( const Point& rPoint ) const;
 };
 }
 
@@ -733,7 +733,7 @@
     f[5] = 0.0;
 }
 
-Point Matrix3::transform( const Point& rOrig )
+Point Matrix3::transform( const Point& rOrig ) const
 {
     double x = (double)rOrig.X(), y = (double)rOrig.Y();
     return Point( (int)(x*f[0] + y*f[2] + f[4]), (int)(x*f[1] + y*f[3] + f[5]) );
@@ -1751,6 +1751,7 @@
 
     virtual ImplFontData*               Clone() const { return new ImplPdfBuiltinFontData(*this); }
     virtual ImplFontEntry*              CreateFontInstance( ImplFontSelectData& ) const;
+    virtual sal_IntPtr                  GetFontId() const { return reinterpret_cast<sal_IntPtr>(&mrBuiltin); }
 };
 
 inline const ImplPdfBuiltinFontData* GetPdfFontData( const ImplFontData* pFontData )
@@ -2970,6 +2971,20 @@
         if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
             goto streamend;
     }
+    else
+    {
+        rtl::OStringBuffer aErrorComment( 256 );
+        aErrorComment.append( "GetEmbedFontData failed for font \"" );
+        aErrorComment.append( OUStringToOString( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ) );
+        aErrorComment.append( '\"' );
+        if( pFont->GetSlant() == ITALIC_NORMAL )
+            aErrorComment.append( " italic" );
+        else if( pFont->GetSlant() == ITALIC_OBLIQUE )
+            aErrorComment.append( " oblique" );
+        aErrorComment.append( " weight=" );
+        aErrorComment.append( sal_Int32(pFont->GetWeight()) );
+        emitComment( aErrorComment.getStr() );
+    }
 
     if( nStreamObject )
         // write font descriptor
@@ -3459,6 +3474,21 @@
 
                 aFontIDToObject[ lit->m_nFontID ] = nFontObject;
             }
+            else
+            {
+                const ImplFontData* pFont = it->first;
+                rtl::OStringBuffer aErrorComment( 256 );
+                aErrorComment.append( "CreateFontSubset failed for font \"" );
+                aErrorComment.append( OUStringToOString( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ) );
+                aErrorComment.append( '\"' );
+                if( pFont->GetSlant() == ITALIC_NORMAL )
+                    aErrorComment.append( " italic" );
+                else if( pFont->GetSlant() == ITALIC_OBLIQUE )
+                    aErrorComment.append( " oblique" );
+                aErrorComment.append( " weight=" );
+                aErrorComment.append( sal_Int32(pFont->GetWeight()) );
+                emitComment( aErrorComment.getStr() );
+            }
         }
     }
     osl_removeFile( aTmpName.pData );
@@ -5166,13 +5196,13 @@
     return true;
 }
 
-void PDFWriterImpl::registerGlyphs(
-                                   int nGlyphs,
-                                   sal_Int32* pGlyphs,
-                                   sal_Unicode* pUnicodes,
-                                   sal_uInt8* pMappedGlyphs,
-                                   sal_Int32* pMappedFontObjects,
-                                   ImplFontData* pFallbackFonts[] )
+void PDFWriterImpl::registerGlyphs( int nGlyphs,
+                                    sal_Int32* pGlyphs,
+                                    sal_Int32* pGlyphWidths,
+                                    sal_Unicode* pUnicodes,
+                                    sal_uInt8* pMappedGlyphs,
+                                    sal_Int32* pMappedFontObjects,
+                                    ImplFontData* pFallbackFonts[] )
 {
     ImplFontData* pDevFont = m_pReferenceDevice->mpFontEntry->maFontSelData.mpFontData;
     for( int i = 0; i < nGlyphs; i++ )
@@ -5182,8 +5212,34 @@
 
         ImplFontData* pCurrentFont = pFallbackFonts[i] ? pFallbackFonts[i] : pDevFont;
 
-        if( pCurrentFont->mbSubsettable )
+        if( isBuiltinFont( pCurrentFont ) )
         {
+            sal_Int32 nFontID = 0;
+            FontEmbedData::iterator it = m_aEmbeddedFonts.find( pCurrentFont );
+            if( it != m_aEmbeddedFonts.end() )
+                nFontID = it->second.m_nNormalFontID;
+            else
+            {
+                nFontID = m_nNextFID++;
+                m_aEmbeddedFonts[ pCurrentFont ] = EmbedFont();
+                m_aEmbeddedFonts[ pCurrentFont ].m_nNormalFontID = nFontID;
+            }
+
+            pGlyphWidths[ i ] = 0;
+            pMappedGlyphs[ i ] = (sal_Int8)pUnicodes[i];
+            pMappedFontObjects[ i ] = nFontID;
+            const ImplPdfBuiltinFontData* pFD = GetPdfFontData( pCurrentFont );
+            if( pFD )
+            {
+                const BuiltinFont* pBuiltinFont = pFD->GetBuiltinFont();
+                pGlyphWidths[i] = pBuiltinFont->m_aWidths[ pUnicodes[i] & 0x00ff ];
+            }
+        }
+        else if( pCurrentFont->mbSubsettable )
+        {
+            #ifndef WNT
+            DBG_ASSERT( (pGlyphs[i] & GF_ISCHAR) == 0, "hdu promised this would only happen on Windows" );
+            #endif
 
             FontSubset& rSubset = m_aSubsets[ pCurrentFont ];
             // search for glyphID
@@ -5218,8 +5274,13 @@
                 rNewGlyph.m_nFontID = pMappedFontObjects[i];
                 rNewGlyph.m_nSubsetGlyphID = nNewId;
             }
+            getReferenceDevice()->ImplGetGraphics();
+            pGlyphWidths[i] = m_aFontCache.getGlyphWidth( pCurrentFont,
+                                                          pGlyphs[i],
+                                                          (pGlyphs[i] & GF_ROTMASK) != 0,
+                                                          m_pReferenceDevice->mpGraphics );
         }
-        else
+        else if( pCurrentFont->IsEmbeddable() )
         {
             sal_Int32 nFontID = 0;
             FontEmbedData::iterator it = m_aEmbeddedFonts.find( pCurrentFont );
@@ -5302,6 +5363,10 @@
             }
             pMappedGlyphs[ i ] = (sal_Int8)cChar;
             pMappedFontObjects[ i ] = nCurFontID;
+            pGlyphWidths[ i ] = m_aFontCache.getGlyphWidth( pCurrentFont,
+                                                            (pEncoding ? pUnicodes[i] : cChar) | GF_ISCHAR,
+                                                            false,
+                                                            m_pReferenceDevice->mpGraphics );
         }
     }
 }
@@ -5376,6 +5441,179 @@
     updateGraphicsState();
 }
 
+void PDFWriterImpl::drawVerticalGlyphs(
+        const std::vector<PDFWriterImpl::PDFGlyph>& rGlyphs,
+        OStringBuffer& rLine,
+        const Point& rAlignOffset,
+        const Matrix3& rRotScale,
+        double fAngle,
+        double fXScale,
+        double fSkew,
+        sal_Int32 nFontHeight )
+{
+    long nXOffset = 0;
+    Point aCurPos( rGlyphs[0].m_aPos );
+    aCurPos = m_pReferenceDevice->PixelToLogic( aCurPos );
+    aCurPos += rAlignOffset;
+    for( size_t i = 0; i < rGlyphs.size(); i++ )
+    {
+        // have to emit each glyph on its own
+        double fDeltaAngle = 0.0;
+        double fYScale = 1.0;
+        double fTempXScale = fXScale;
+        double fSkewB = fSkew;
+        double fSkewA = 0.0;
+        
+        Point aDeltaPos;
+        if( ( rGlyphs[i].m_nGlyphId & GF_ROTMASK ) == GF_ROTL )
+        {
+            fDeltaAngle = M_PI/2.0;
+            aDeltaPos.X() = m_pReferenceDevice->GetFontMetric().GetAscent();
+            aDeltaPos.Y() = (int)((double)m_pReferenceDevice->GetFontMetric().GetDescent() * fXScale);
+            fYScale = fXScale;
+            fTempXScale = 1.0;
+            fSkewA = -fSkewB;
+            fSkewB = 0.0;
+        }
+        else if( ( rGlyphs[i].m_nGlyphId & GF_ROTMASK ) == GF_ROTR )
+        {
+            fDeltaAngle = -M_PI/2.0;
+            aDeltaPos.X() = (int)((double)m_pReferenceDevice->GetFontMetric().GetDescent()*fXScale);
+            aDeltaPos.Y() = -m_pReferenceDevice->GetFontMetric().GetAscent();
+            fYScale = fXScale;
+            fTempXScale = 1.0;
+            fSkewA = fSkewB;
+            fSkewB = 0.0;
+        }
+        aDeltaPos += (m_pReferenceDevice->PixelToLogic( Point( (int)((double)nXOffset/fXScale), 0 ) ) - m_pReferenceDevice->PixelToLogic( Point() ) );
+        if( i < rGlyphs.size()-1 )
+            nXOffset += rGlyphs[i+1].m_aPos.Y() - rGlyphs[i].m_aPos.Y();
+        if( ! rGlyphs[i].m_nGlyphId )
+            continue;
+        
+        
+        aDeltaPos = rRotScale.transform( aDeltaPos );
+        
+        Matrix3 aMat;
+        if( fSkewB != 0.0 || fSkewA != 0.0 )
+            aMat.skew( fSkewA, fSkewB );
+        aMat.scale( fTempXScale, fYScale );
+        aMat.rotate( fAngle+fDeltaAngle );
+        aMat.translate( aCurPos.X()+aDeltaPos.X(), aCurPos.Y()+aDeltaPos.Y() );
+        aMat.append( m_aPages.back(), rLine );
+        rLine.append( " Tm" );
+        if( i == 0 || rGlyphs[i-1].m_nMappedFontId != rGlyphs[i].m_nMappedFontId )
+        {
+            rLine.append( " /F" );
+            rLine.append( rGlyphs[i].m_nMappedFontId );
+            rLine.append( ' ' );
+            m_aPages.back().appendMappedLength( nFontHeight, rLine, true );
+            rLine.append( " Tf" );
+        }
+        rLine.append( "<" );
+        appendHex( rGlyphs[i].m_nMappedGlyphId, rLine );
+        rLine.append( ">Tj\n" );
+    }
+}
+
+void PDFWriterImpl::drawHorizontalGlyphs(
+        const std::vector<PDFWriterImpl::PDFGlyph>& rGlyphs,
+        OStringBuffer& rLine,
+        const Point& rAlignOffset,
+        double fAngle,
+        double fXScale,
+        double fSkew,
+        sal_Int32 nFontHeight,
+        sal_Int32 nPixelFontHeight
+        )
+{
+    // horizontal (= normal) case
+    
+    // fill in  run end indices
+    // end is marked by index of the first glyph of the next run
+    // a run is marked by same mapped font id and same Y position
+    std::vector< sal_uInt32 > aRunEnds;
+    aRunEnds.reserve( rGlyphs.size() );
+    for( size_t i = 1; i < rGlyphs.size(); i++ )
+    {
+        if( rGlyphs[i].m_nMappedFontId != rGlyphs[i-1].m_nMappedFontId ||
+            rGlyphs[i].m_aPos.Y() != rGlyphs[i-1].m_aPos.Y() )
+        {
+            aRunEnds.push_back(i);
+        }
+    }
+    // last run ends at last glyph
+    aRunEnds.push_back( rGlyphs.size() );
+
+    // loop over runs of the same font
+    sal_uInt32 nBeginRun = 0;
+    for( size_t nRun = 0; nRun < aRunEnds.size(); nRun++ )
+    {
+        // setup text matrix
+        Point aCurPos = rGlyphs[nBeginRun].m_aPos;
+        // back transformation to current coordinate system
+        aCurPos = m_pReferenceDevice->PixelToLogic( aCurPos );
+        aCurPos += rAlignOffset;
+        // the first run can be set with "Td" operator
+        // subsequent use of that operator would move
+        // the texline matrix relative to what was set before
+        // making use of that would drive us into rounding issues
+        if( nRun == 0 && fAngle == 0.0 && fXScale == 1.0 && fSkew == 0.0 )
+        {
+            m_aPages.back().appendPoint( aCurPos, rLine, false );
+            rLine.append( " Td " );
+        }
+        else
+        {
+            Matrix3 aMat;
+            if( fSkew != 0.0 )
+                aMat.skew( 0.0, fSkew );
+            aMat.scale( fXScale, 1.0 );
+            aMat.rotate( fAngle );
+            aMat.translate( aCurPos.X(), aCurPos.Y() );
+            aMat.append( m_aPages.back(), rLine );
+            rLine.append( " Tm\n" );
+        }
+        // set up correct font
+        rLine.append( "/F" );
+        rLine.append( rGlyphs[nBeginRun].m_nMappedFontId );
+        rLine.append( ' ' );
+        m_aPages.back().appendMappedLength( nFontHeight, rLine, true );
+        rLine.append( " Tf" );
+
+        // output glyphs using Tj or TJ
+        OStringBuffer aKernedLine( 256 ), aUnkernedLine( 256 );
+        aKernedLine.append( "[<" );
+        aUnkernedLine.append( '<' );
+        appendHex( rGlyphs[nBeginRun].m_nMappedGlyphId, aKernedLine );
+        appendHex( rGlyphs[nBeginRun].m_nMappedGlyphId, aUnkernedLine );
+
+        bool bNeedKern = false;
+        for( sal_uInt32 nPos = nBeginRun+1; nPos < aRunEnds[nRun]; nPos++ )
+        {
+            appendHex( rGlyphs[nPos].m_nMappedGlyphId, aUnkernedLine );
+            // check for adjustment
+            double fTheoreticalGlyphWidth = rGlyphs[nPos].m_aPos.X() - rGlyphs[nPos-1].m_aPos.X();
+            fTheoreticalGlyphWidth = 1000.0 * fTheoreticalGlyphWidth / fXScale / double(nPixelFontHeight);
+            sal_Int32 nAdjustment = rGlyphs[nPos-1].m_nNativeWidth - sal_Int32(fTheoreticalGlyphWidth+0.5);
+            if( nAdjustment != 0 )
+            {
+                bNeedKern = true;
+                aKernedLine.append( ">" );
+                aKernedLine.append( nAdjustment );
+                aKernedLine.append( "<" );
+            }
+            appendHex( rGlyphs[nPos].m_nMappedGlyphId, aKernedLine );
+        }
+        aKernedLine.append( ">]TJ\n" );
+        aUnkernedLine.append( ">Tj\n" );
+        rLine.append( bNeedKern ? aKernedLine : aUnkernedLine );
+        
+        // set beginning of next run
+        nBeginRun = aRunEnds[nRun];
+    }
+}
+
 void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bTextLines )
 {
     // relief takes precedence over shadow (see outdev3.cxx)
@@ -5392,27 +5630,25 @@
     const int nMaxGlyphs = 256;
 
     sal_Int32 pGlyphs[nMaxGlyphs];
+    sal_Int32 pGlyphWidths[nMaxGlyphs];
     sal_uInt8 pMappedGlyphs[nMaxGlyphs];
     sal_Int32 pMappedFontObjects[nMaxGlyphs];
     sal_Unicode pUnicodes[nMaxGlyphs];
     int pCharPosAry[nMaxGlyphs];
     sal_Int32 nAdvanceWidths[nMaxGlyphs];
     ImplFontData* pFallbackFonts[nMaxGlyphs];
-    sal_Int32 *pAdvanceWidths = m_aCurrentPDFState.m_aFont.IsVertical() ? nAdvanceWidths : NULL;
-    sal_Int32 nGlyphFlags[nMaxGlyphs];
+    bool bVertical = m_aCurrentPDFState.m_aFont.IsVertical();
     int nGlyphs;
     int nIndex = 0;
-    Point aCurPos, aLastPos(0, 0), aCumulativePos(0,0), aGlyphPos;
-    bool bFirst = true, bWasYChange = false;
     int nMinCharPos = 0, nMaxCharPos = rText.Len()-1;
     double fXScale = 1.0;
     double fSkew = 0.0;
-    sal_Int32 nFontHeight = m_pReferenceDevice->mpFontEntry->maFontSelData.mnHeight;
+    sal_Int32 nPixelFontHeight = m_pReferenceDevice->mpFontEntry->maFontSelData.mnHeight;
     TextAlign eAlign = m_aCurrentPDFState.m_aFont.GetAlign();
 
     // transform font height back to current units
     // note: the layout calculates in outdevs device pixel !!
-    nFontHeight = m_pReferenceDevice->ImplDevicePixelToLogicHeight( nFontHeight );
+    sal_Int32 nFontHeight = m_pReferenceDevice->ImplDevicePixelToLogicHeight( nPixelFontHeight );
     if( m_aCurrentPDFState.m_aFont.GetWidth() )
     {
         Font aFont( m_aCurrentPDFState.m_aFont );
@@ -5522,26 +5758,13 @@
 
     FontMetric aRefDevFontMetric = m_pReferenceDevice->GetFontMetric();
 
-    sal_Int32 nLastMappedFont = -1;
-    while( (nGlyphs = rLayout.GetNextGlyphs( nMaxGlyphs, pGlyphs, aCurPos, nIndex, pAdvanceWidths, pCharPosAry )) != 0 )
+    // collect the glyphs into a single array
+    std::vector< PDFGlyph > aGlyphs;
+    aGlyphs.reserve( nMaxGlyphs );
+    // first get all the glyphs and register them; coordinates still in Pixel
+    Point aGNGlyphPos;
+    while( (nGlyphs = rLayout.GetNextGlyphs( nMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, nAdvanceWidths, pCharPosAry )) != 0 )
     {
-        bWasYChange = (aGlyphPos.Y() != aCurPos.Y());
-        aGlyphPos = aCurPos;
-        // back transformation to current coordinate system
-        aCurPos = m_pReferenceDevice->PixelToLogic( aCurPos );
-
-        Point aOffset;
-        if ( eAlign == ALIGN_BOTTOM )
-            aOffset.Y() -= aRefDevFontMetric.GetDescent();
-        else if ( eAlign == ALIGN_TOP )
-            aOffset.Y() += aRefDevFontMetric.GetAscent();
-
-        if( aOffset.X() || aOffset.Y() )
-        {
-            aOffset = aRotScale.transform( aOffset );
-            aCurPos += aOffset;
-        }
-
         for( int i = 0; i < nGlyphs; i++ )
         {
             if( pGlyphs[i] & GF_FONTMASK )
@@ -5549,16 +5772,6 @@
             else
                 pFallbackFonts[i] = NULL;
 
-            nGlyphFlags[i] = (pGlyphs[i] & GF_FLAGMASK);
-#ifndef WNT
-            // #104930# workaround for Win32 bug: the glyph ids are actually
-            // Unicodes for vertical fonts because Win32 does not return
-            // the correct glyph ids; this is indicated by GF_ISCHAR which is
-            // needed in SalGraphics::CreateFontSubset to convert the Unicodes
-            // to vertical glyph ids. Doing this here on a per character
-            // basis would be a major performance hit.
-            pGlyphs[i] &= GF_IDXMASK;
-#endif
             if( pCharPosAry[i] >= nMinCharPos && pCharPosAry[i] <= nMaxCharPos )
                 pUnicodes[i] = rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]) );
             else
@@ -5568,159 +5781,34 @@
             // implementations set -1 then to indicate that no direct
             // mapping is possible
         }
-        registerGlyphs( nGlyphs, pGlyphs, pUnicodes, pMappedGlyphs, pMappedFontObjects, pFallbackFonts );
-
-        if( pAdvanceWidths )
+        registerGlyphs( nGlyphs, pGlyphs, pGlyphWidths, pUnicodes, pMappedGlyphs, pMappedFontObjects, pFallbackFonts );
+        for( int i = 0; i < nGlyphs; i++)
         {
-            // have to emit each glyph on its own
-            long nXOffset = 0;
-            for( int n = 0; n < nGlyphs; n++ )
-            {
-                double fDeltaAngle = 0.0;
-                double fYScale = 1.0;
-                double fTempXScale = fXScale;
-                double fSkewB = fSkew;
-                double fSkewA = 0.0;
-
-                Point aDeltaPos;
-                if( ( nGlyphFlags[n] & GF_ROTMASK ) == GF_ROTL )
-                {
-                    fDeltaAngle = M_PI/2.0;
-                    aDeltaPos.X() = aRefDevFontMetric.GetAscent();
-                    aDeltaPos.Y() = (int)((double)m_pReferenceDevice->GetFontMetric().GetDescent() * fXScale);
-                    fYScale = fXScale;
-                    fTempXScale = 1.0;
-                    fSkewA = -fSkewB;
-                    fSkewB = 0.0;
-                }
-                else if( ( nGlyphFlags[n] & GF_ROTMASK ) == GF_ROTR )
-                {
-                    fDeltaAngle = -M_PI/2.0;
-                    aDeltaPos.X() = (int)((double)aRefDevFontMetric.GetDescent()*fXScale);
-                    aDeltaPos.Y() = -aRefDevFontMetric.GetAscent();
-                    fYScale = fXScale;
-                    fTempXScale = 1.0;
-                    fSkewA = fSkewB;
-                    fSkewB = 0.0;
-                }
-                aDeltaPos += (m_pReferenceDevice->PixelToLogic( Point( (int)((double)nXOffset/fXScale)/rLayout.GetUnitsPerPixel(), 0 ) ) - m_pReferenceDevice->PixelToLogic( Point() ) );
-                nXOffset += pAdvanceWidths[n];
-                if( ! pGlyphs[n] )
-                    continue;
-
-
-                aDeltaPos = aRotScale.transform( aDeltaPos );
-
-                Matrix3 aMat;
-                if( fSkewB != 0.0 || fSkewA != 0.0 )
-                    aMat.skew( fSkewA, fSkewB );
-                aMat.scale( fTempXScale, fYScale );
-                aMat.rotate( fAngle+fDeltaAngle );
-                aMat.translate( aCurPos.X()+aDeltaPos.X(), aCurPos.Y()+aDeltaPos.Y() );
-                aMat.append( m_aPages.back(), aLine );
-                aLine.append( " Tm" );
-                if( nLastMappedFont != pMappedFontObjects[n] )
-                {
-                    nLastMappedFont = pMappedFontObjects[n];
-                    aLine.append( " /F" );
-                    aLine.append( pMappedFontObjects[n] );
-                    aLine.append( ' ' );
-                    m_aPages.back().appendMappedLength( nFontHeight, aLine, true );
-                    aLine.append( " Tf" );
-                }
-                aLine.append( " <" );
-                appendHex( (sal_Int8)pMappedGlyphs[n], aLine );
-                aLine.append( "> Tj\n" );
-            }
-        }
-        else // normal case
-        {
-            // optimize use of Td vs. Tm
-            if( fAngle == 0.0 && fXScale == 1.0 && ( !bFirst || fSkew == 0.0 ) )
-            {
-                if( bFirst )
-                {
-                    m_aPages.back().appendPoint( aCurPos, aLine, false, &aCumulativePos );
-                    bFirst = false;
-                    aLastPos = aCurPos;
-                }
-                else
-                {
-                    sal_Int32 nDiffL = 0;
-                    Point aDiff = aCurPos - aLastPos;
-                    m_aPages.back().appendMappedLength( (sal_Int32)aDiff.X(), aLine, false, &nDiffL );
-                    aCumulativePos.X() += nDiffL;
-                    aLine.append( ' ' );
-                    if( bWasYChange )
-                    {
-                        m_aPages.back().appendMappedLength( (sal_Int32)-aDiff.Y(), aLine, true, &nDiffL );
-                        aCumulativePos.Y() -= nDiffL;
-                    }
-                    else
-                    {
-                        aLine.append( '0' );
-                    }
-                    // back project last position to catch rounding errors
-                    Point aBackPos = lcl_convert( m_aMapMode,
-                                                  m_aGraphicsStack.front().m_aMapMode,
-                                                  getReferenceDevice(),
-                                                  aCumulativePos
-                                                  );
-                    // catch rounding error in back projection on Y axis;
-                    // else the back projection can produce a sinuous text baseline
-                    if( ! bWasYChange )
-                        aBackPos.Y() = aLastPos.Y();
-                    aLastPos = aBackPos;
-                }
-                aLine.append( " Td " );
-            }
+            aGlyphs.push_back( PDFGlyph( aGNGlyphPos,
+                                         pGlyphWidths[i],
+                                         pGlyphs[i],
+                                         pMappedFontObjects[i],
+                                         pMappedGlyphs[i] ) );
+            if( bVertical )
+                aGNGlyphPos.Y() += nAdvanceWidths[i]/rLayout.GetUnitsPerPixel();
             else
-            {
-                Matrix3 aMat;
-                if( fSkew != 0.0 )
-                    aMat.skew( 0.0, fSkew );
-                aMat.scale( fXScale, 1.0 );
-                aMat.rotate( fAngle );
-                aMat.translate( aCurPos.X(), aCurPos.Y() );
-                aMat.append( m_aPages.back(), aLine, &aCumulativePos );
-                aLine.append( " Tm\n" );
-                aLastPos = aCurPos;
-                bFirst = false;
-            }
-            int nLast = 0;
-            while( nLast < nGlyphs )
-            {
-                while( ! pGlyphs[nLast] && nLast < nGlyphs )
-                    nLast++;
-                if( nLast >= nGlyphs )
-                    break;
-
-                int nNext = nLast+1;
-                while( nNext < nGlyphs && pMappedFontObjects[ nNext ] == pMappedFontObjects[nLast] && pGlyphs[nNext] )
-                    nNext++;
-                if( nLastMappedFont != pMappedFontObjects[nLast] )
-                {
-                    aLine.append( "/F" );
-                    aLine.append( pMappedFontObjects[nLast] );
-                    aLine.append( ' ' );
-                    m_aPages.back().appendMappedLength( nFontHeight, aLine, true );
-                    aLine.append( " Tf " );
-                    nLastMappedFont = pMappedFontObjects[nLast];
-                }
-                aLine.append( "<" );
-                for( int i = nLast; i < nNext; i++ )
-                {
-                    appendHex( (sal_Int8)pMappedGlyphs[i], aLine );
-                    if( i && (i % 35) == 0 )
-                        aLine.append( "\n" );
-                }
-                aLine.append( "> Tj\n" );
-
-                nLast = nNext;
-            }
+                aGNGlyphPos.X() += nAdvanceWidths[i]/rLayout.GetUnitsPerPixel();
         }
     }
+    
+    Point aAlignOffset;
+    if ( eAlign == ALIGN_BOTTOM )
+        aAlignOffset.Y() -= aRefDevFontMetric.GetDescent();
+    else if ( eAlign == ALIGN_TOP )
+        aAlignOffset.Y() += aRefDevFontMetric.GetAscent();
+    if( aAlignOffset.X() || aAlignOffset.Y() )
+        aAlignOffset = aRotScale.transform( aAlignOffset );
 
+    if( bVertical )
+        drawVerticalGlyphs( aGlyphs, aLine, aAlignOffset, aRotScale, fAngle, fXScale, fSkew, nFontHeight );
+    else
+        drawHorizontalGlyphs( aGlyphs, aLine, aAlignOffset, fAngle, fXScale, fSkew, nFontHeight, nPixelFontHeight );
+    
     // end textobject
     aLine.append( "ET\n" );
     if( bPop )
Index: gsl/vcl/source/gdi/pdfwriter_impl.hxx
diff -u gsl/vcl/source/gdi/pdfwriter_impl.hxx:1.42 gsl/vcl/source/gdi/pdfwriter_impl.hxx:1.42.78.2
--- gsl/vcl/source/gdi/pdfwriter_impl.hxx:1.42	Mon Dec  4 00:32:37 2006
+++ gsl/vcl/source/gdi/pdfwriter_impl.hxx	Thu Mar  1 04:26:56 2007
@@ -79,6 +79,9 @@
 #include <rtl/digest.h>
 #endif
 
+#include "pdffontcache.hxx"
+
+
 #include <vector>
 #include <map>
 #include <hash_map>
@@ -106,6 +109,7 @@
 {
 
 class PDFSalLayout;
+class Matrix3;
 
 class PDFWriterImpl
 {
@@ -512,6 +516,26 @@
         }
 
     };
+    
+    // helper structure for drawLayout and friends
+    struct PDFGlyph
+    {
+        Point       m_aPos;
+        sal_Int32   m_nNativeWidth;
+        sal_Int32   m_nGlyphId;
+        sal_Int32   m_nMappedFontId;
+        sal_uInt8   m_nMappedGlyphId;
+        
+        PDFGlyph( const Point& rPos,
+                  sal_Int32 nNativeWidth,
+                  sal_Int32 nGlyphId,
+                  sal_Int32 nFontId,
+                  sal_uInt8 nMappedGlyphId )
+        : m_aPos( rPos ), m_nNativeWidth( nNativeWidth ), m_nGlyphId( nGlyphId ),
+          m_nMappedFontId( nFontId ), m_nMappedGlyphId( nMappedGlyphId )
+        {}
+    };
+
 
     static const sal_Char* getStructureTag( PDFWriter::StructElement );
     static const sal_Char* getAttributeTag( PDFWriter::StructAttribute eAtr );
@@ -589,6 +613,7 @@
     FontSubsetData						m_aSubsets;
     FontEmbedData						m_aEmbeddedFonts;
     sal_Int32							m_nNextFID;
+    PDFFontCache                        m_aFontCache;
 
     sal_Int32							m_nInheritedPageWidth;  // in inch/72
     sal_Int32							m_nInheritedPageHeight; // in inch/72
@@ -816,10 +841,12 @@
 	void appendLiteralStringEncrypt( rtl::OStringBuffer& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer );
 
     /* creates fonts and subsets that will be emitted later */
-    void registerGlyphs( int nGlyphs, sal_Int32* pGlyphs, sal_Unicode* pUnicodes, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, ImplFontData* pFallbackFonts[] );
+    void registerGlyphs( int nGlyphs, sal_Int32* pGlyphs, sal_Int32* pGlpyhWidths, sal_Unicode* pUnicodes, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, ImplFontData* pFallbackFonts[] );
 
     /*  emits a text object according to the passed layout */
     /* TODO: remove rText as soon as SalLayout will change so that rText is not necessary anymore */
+    void drawVerticalGlyphs( const std::vector<PDFGlyph>& rGlyphs, rtl::OStringBuffer& rLine, const Point& rAlignOffset, const Matrix3& rRotScale, double fAngle, double fXScale, double fSkew, sal_Int32 nFontHeight );
+    void drawHorizontalGlyphs( const std::vector<PDFGlyph>& rGlyphs, rtl::OStringBuffer& rLine, const Point& rAlignOffset, double fAngle, double fXScale, double fSkew, sal_Int32 nFontHeight, sal_Int32 nPixelFontHeight );
     void drawLayout( SalLayout& rLayout, const String& rText, bool bTextLines );
     void drawRelief( SalLayout& rLayout, const String& rText, bool bTextLines );
     void drawShadow( SalLayout& rLayout, const String& rText, bool bTextLines );
Index: gsl/vcl/unx/inc/pspgraphics.h
diff -u gsl/vcl/unx/inc/pspgraphics.h:1.12 gsl/vcl/unx/inc/pspgraphics.h:1.12.94.1
--- gsl/vcl/unx/inc/pspgraphics.h:1.12	Tue Nov 14 07:24:00 2006
+++ gsl/vcl/unx/inc/pspgraphics.h	Wed Feb 28 06:00:32 2007
@@ -91,6 +91,11 @@
     static const void* DoGetEmbedFontData( psp::fontID aFont, const sal_Unicode* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen );
     static void DoFreeEmbedFontData( const void* pData, long nLen );
     static const std::map< sal_Unicode, sal_Int32 >* DoGetFontEncodingVector( psp::fontID aFont, const std::map< sal_Unicode, rtl::OString >** pNonEncoded );
+    static void DoGetGlyphWidths( psp::fontID aFont,
+                                  bool bVertical,
+                                  std::vector< sal_Int32 >& rWidths,
+                                  std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
+
     static ImplDevFontAttributes Info2DevFontAttributes( const psp::FastPrintFontInfo& );
     static void AnnounceFonts( ImplDevFontList*, const psp::FastPrintFontInfo& );
     static FontWidth	ToFontWidth (psp::width::type eWidth);
@@ -141,6 +146,10 @@
                                           FontSubsetInfo& rInfo,
                                           long* pDataLen );
     virtual void			FreeEmbedFontData( const void* pData, long nDataLen );
+    virtual void            GetGlyphWidths( ImplFontData* pFont,
+                                            bool bVertical,
+                                            std::vector< sal_Int32 >& rWidths,
+                                            std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
     virtual BOOL			GetGlyphBoundRect( long nIndex, Rectangle& );
     virtual BOOL			GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& );
     virtual SalLayout*		GetTextLayout( ImplLayoutArgs&, int nFallbackLevel );
Index: gsl/vcl/unx/inc/salgdi.h
diff -u gsl/vcl/unx/inc/salgdi.h:1.39 gsl/vcl/unx/inc/salgdi.h:1.39.94.1
--- gsl/vcl/unx/inc/salgdi.h:1.39	Tue Nov 14 07:24:32 2006
+++ gsl/vcl/unx/inc/salgdi.h	Wed Feb 28 06:00:32 2007
@@ -268,6 +268,10 @@
                                           FontSubsetInfo& rInfo,
                                           long* pDataLen );
     virtual void			FreeEmbedFontData( const void* pData, long nDataLen );
+    virtual void            GetGlyphWidths( ImplFontData* pFont,
+                                            bool bVertical,
+                                            std::vector< sal_Int32 >& rWidths,
+                                            std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
     virtual BOOL			GetGlyphBoundRect( long nIndex, Rectangle& );
     virtual BOOL			GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& );
     virtual SalLayout*		GetTextLayout( ImplLayoutArgs&, int nFallbackLevel );
Index: gsl/vcl/unx/source/gdi/pspgraphics.cxx
diff -u gsl/vcl/unx/source/gdi/pspgraphics.cxx:1.22 gsl/vcl/unx/source/gdi/pspgraphics.cxx:1.22.94.1
--- gsl/vcl/unx/source/gdi/pspgraphics.cxx:1.22	Tue Nov 14 07:25:26 2006
+++ gsl/vcl/unx/source/gdi/pspgraphics.cxx	Wed Feb 28 06:00:33 2007
@@ -1009,6 +1009,22 @@
     return PspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
 }
 
+//--------------------------------------------------------------------------
+
+void PspGraphics::GetGlyphWidths( ImplFontData* pFont,
+                                  bool bVertical,
+                                  std::vector< sal_Int32 >& rWidths,
+                                  std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the ImplFontData pFont
+    psp::fontID aFont = pFont->GetFontId();
+    PspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+}
+
 
 // static helpers of PspGraphics
 
@@ -1135,6 +1151,14 @@
     return rMgr.getEncodingMap( aFont, pNonEncoded );
 }
 
+void PspGraphics::DoGetGlyphWidths( psp::fontID aFont,
+                                    bool bVertical,
+                                    std::vector< sal_Int32 >& rWidths,
+                                    std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc )
+{
+    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+    rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+}
 // ----------------------------------------------------------------------------
 
 FontWidth PspGraphics::ToFontWidth (psp::width::type eWidth)
Index: gsl/vcl/unx/source/gdi/salgdi3.cxx
diff -u gsl/vcl/unx/source/gdi/salgdi3.cxx:1.143 gsl/vcl/unx/source/gdi/salgdi3.cxx:1.143.68.1
--- gsl/vcl/unx/source/gdi/salgdi3.cxx:1.143	Thu Dec 21 04:05:00 2006
+++ gsl/vcl/unx/source/gdi/salgdi3.cxx	Wed Feb 28 06:00:33 2007
@@ -1468,4 +1468,20 @@
 #endif
 }
 
+//--------------------------------------------------------------------------
+
+void X11SalGraphics::GetGlyphWidths( ImplFontData* pFont,
+                                   bool bVertical,
+                                   std::vector< sal_Int32 >& rWidths,
+                                   std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the ImplFontData pFont
+    psp::fontID aFont = pFont->GetFontId();
+    PspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+}
+
 // ===========================================================================
Index: gsl/vcl/unx/source/gdi/xlfd_extd.cxx
diff -u gsl/vcl/unx/source/gdi/xlfd_extd.cxx:1.28 gsl/vcl/unx/source/gdi/xlfd_extd.cxx:1.28.172.1
--- gsl/vcl/unx/source/gdi/xlfd_extd.cxx:1.28	Sun Sep 17 05:40:37 2006
+++ gsl/vcl/unx/source/gdi/xlfd_extd.cxx	Wed Feb 28 06:00:33 2007
@@ -78,6 +78,11 @@
     return pEntry;
 }
 
+sal_IntPtr ImplX11FontData::GetFontId() const
+{
+    return reinterpret_cast<sal_IntPtr>(&mrXlfd);
+}
+
 // --------------------------------------------------------------------------
 //
 //  classes for Xlfd handling that contain more than a single encoding.
Index: gsl/vcl/unx/source/gdi/xlfd_extd.hxx
diff -u gsl/vcl/unx/source/gdi/xlfd_extd.hxx:1.14 gsl/vcl/unx/source/gdi/xlfd_extd.hxx:1.14.538.1
--- gsl/vcl/unx/source/gdi/xlfd_extd.hxx:1.14	Fri Sep  9 06:09:55 2005
+++ gsl/vcl/unx/source/gdi/xlfd_extd.hxx	Wed Feb 28 06:00:33 2007
@@ -274,6 +274,7 @@
     const ExtendedXlfd&     GetExtendedXlfd() const { return mrXlfd; }
     virtual ImplFontData*   Clone() const           { return new ImplX11FontData( *this ); }
     virtual ImplFontEntry*  CreateFontInstance( ImplFontSelectData& ) const;
+    virtual sal_IntPtr      GetFontId() const;
 
     static bool             CheckFontData( const ImplFontData& r ) { return r.CheckMagic( X11IFD_MAGIC ); }
 };
Index: gsl/vcl/win/inc/salgdi.h
diff -u gsl/vcl/win/inc/salgdi.h:1.24 gsl/vcl/win/inc/salgdi.h:1.24.80.1
--- gsl/vcl/win/inc/salgdi.h:1.24	Mon Dec  4 08:40:48 2006
+++ gsl/vcl/win/inc/salgdi.h	Fri Mar  2 07:36:01 2007
@@ -82,6 +82,8 @@
 
     virtual ImplFontData*   Clone() const;
     virtual ImplFontEntry*  CreateFontInstance( ImplFontSelectData& ) const;
+    virtual sal_IntPtr      GetFontId() const;
+    void                    SetFontId( sal_IntPtr nId ) { mnId = nId; }
     void                    UpdateFromHDC( HDC );
 
     bool                    HasChar( sal_uInt32 cChar ) const;
@@ -95,8 +97,15 @@
     bool                    AliasSymbolsLow() const     { return mbAliasSymbolsLow; }
 
     ImplFontCharMap*        GetImplFontCharMap();
-
+    std::map< sal_Unicode,sal_Int32>* GetEncodingVector() const { return mpEncodingVector; }
+    void SetEncodingVector( std::map< sal_Unicode,sal_Int32>* pNewVec )
+    {
+        if( mpEncodingVector )
+            delete mpEncodingVector;
+        mpEncodingVector = pNewVec;
+    }
 private:
+    sal_IntPtr              mnId;
     bool                    mbDisableGlyphApi;
     bool                    mbHasKoreanRange;
     bool                    mbHasCJKSupport;
@@ -110,7 +119,7 @@
     WIN_BYTE                mnPitchAndFamily;
     bool                    mbAliasSymbolsHigh;
     bool                    mbAliasSymbolsLow;
-
+    std::map< sal_Unicode,sal_Int32>* mpEncodingVector;
 private:
     void                    ReadCmapTable( HDC );
     void                    ReadOs2Table( HDC );
@@ -171,6 +180,8 @@
 	BOOL					mbWindow;			// is Window
 	BOOL					mbScreen;			// is Screen compatible
 	BOOL					mbXORMode;			// _every_ output with RasterOp XOR
+    
+    HFONT                   ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFontScale, HFONT& o_rOldFont );
 
 public:
     WinSalGraphics();
@@ -332,6 +343,10 @@
                                           long* pDataLen );
     // frees the font data again
     virtual void			FreeEmbedFontData( const void* pData, long nDataLen );
+    virtual void            GetGlyphWidths( ImplFontData* pFont,
+                                            bool bVertical,
+                                            std::vector< sal_Int32 >& rWidths,
+                                            std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
 
     virtual BOOL                    GetGlyphBoundRect( long nIndex, Rectangle& );
     virtual BOOL                    GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& );
Index: gsl/vcl/win/source/gdi/salgdi3.cxx
diff -u gsl/vcl/win/source/gdi/salgdi3.cxx:1.85 gsl/vcl/win/source/gdi/salgdi3.cxx:1.85.32.1
--- gsl/vcl/win/source/gdi/salgdi3.cxx:1.85	Thu Jan 25 03:26:50 2007
+++ gsl/vcl/win/source/gdi/salgdi3.cxx	Fri Mar  2 07:36:02 2007
@@ -299,6 +299,7 @@
     bool                mbImplSalCourierScalable;
     bool                mbImplSalCourierNew;
     bool                mbPrinter;
+    int                 mnFontCount;
 };
 
 // =======================================================================
@@ -654,7 +655,7 @@
 
 // -----------------------------------------------------------------------
 
-static ImplFontData* ImplLogMetricToDevFontDataA( const ENUMLOGFONTEXA* pLogFont,
+static ImplWinFontData* ImplLogMetricToDevFontDataA( const ENUMLOGFONTEXA* pLogFont,
                                          const NEWTEXTMETRICA* pMetric,
                                          DWORD nFontType )
 {
@@ -662,7 +663,7 @@
     if ( nFontType & RASTER_FONTTYPE )
         nHeight = pMetric->tmHeight - pMetric->tmInternalLeading;
 
-    ImplFontData* pData = new ImplWinFontData(
+    ImplWinFontData* pData = new ImplWinFontData(
         WinFont2DevFontAttributes(*pLogFont, *pMetric, nFontType),
         nHeight,
         pLogFont->elfLogFont.lfCharSet,
@@ -673,7 +674,7 @@
 
 // -----------------------------------------------------------------------
 
-static ImplFontData* ImplLogMetricToDevFontDataW( const ENUMLOGFONTEXW* pLogFont,
+static ImplWinFontData* ImplLogMetricToDevFontDataW( const ENUMLOGFONTEXW* pLogFont,
                                          const NEWTEXTMETRICW* pMetric,
                                          DWORD nFontType )
 {
@@ -681,7 +682,7 @@
     if ( nFontType & RASTER_FONTTYPE )
         nHeight = pMetric->tmHeight - pMetric->tmInternalLeading;
 
-    ImplFontData* pData = new ImplWinFontData(
+    ImplWinFontData* pData = new ImplWinFontData(
         WinFont2DevFontAttributes(*pLogFont, *pMetric, nFontType),
         nHeight,
         pLogFont->elfLogFont.lfCharSet,
@@ -782,7 +783,9 @@
     mbHasKoreanRange( false ),
     mbHasCJKSupport( false ),
     mbAliasSymbolsLow( false ),
-    mbAliasSymbolsHigh( false )
+    mbAliasSymbolsHigh( false ),
+    mnId( 0 ),
+    mpEncodingVector( NULL )
 {
     SetBitmapSize( 0, nHeight );
 
@@ -816,6 +819,14 @@
 
     if( mpUnicodeMap )
         mpUnicodeMap->DeReference();
+    delete mpEncodingVector;
+}
+
+// -----------------------------------------------------------------------
+
+sal_IntPtr ImplWinFontData::GetFontId() const
+{
+    return mnId;
 }
 
 // -----------------------------------------------------------------------
@@ -1221,31 +1232,9 @@
 
 // -----------------------------------------------------------------------
 
-USHORT WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel )
+HFONT WinSalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFontScale, HFONT& o_rOldFont )
 {
-    // return early if there is no new font
-    if( !pFont )
-    {
-        // deselect still active font
-        if( mhDefFont )
-            ::SelectFont( mhDC, mhDefFont );
-        // release no longer referenced font handles
-        for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
-        {
-            if( mhFonts[i] )
-                ::DeleteFont( mhFonts[i] );
-            mhFonts[ i ] = 0;
-        }
-        mhDefFont = 0;
-        return 0;
-    }
-
-    DBG_ASSERT( pFont->mpFontData, "WinSalGraphics mpFontData==NULL");
-    mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast<ImplWinFontEntry*>( pFont->mpFontEntry );
-    mpWinFontData[ nFallbackLevel ] = static_cast<ImplWinFontData*>( pFont->mpFontData );
-
     HFONT hNewFont = 0;
-    HFONT hOldFont;
 
     HDC hdcScreen = 0;
     if( mbVirDev )
@@ -1255,15 +1244,15 @@
     if( aSalShlData.mbWNT )
     {
         LOGFONTW aLogFont;
-        ImplGetLogFontFromFontSelect( mhDC, pFont, aLogFont, true );
+        ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true );
 
         // on the display we prefer Courier New when Courier is a
         // bitmap only font and we need to stretch or rotate it
         if( mbScreen
-        &&  (pFont->mnWidth != 0
-          || pFont->mnOrientation != 0
-          || pFont->mpFontData == NULL
-          || (pFont->mpFontData->GetHeight() != pFont->mnHeight))
+        &&  (i_pFont->mnWidth != 0
+          || i_pFont->mnOrientation != 0
+          || i_pFont->mpFontData == NULL
+          || (i_pFont->mpFontData->GetHeight() != i_pFont->mnHeight))
         && !bImplSalCourierScalable
         && bImplSalCourierNew
         && (ImplSalWICompareAscii( aLogFont.lfFaceName, "Courier" ) == 0) )
@@ -1272,12 +1261,12 @@
         // limit font requests to MAXFONTHEIGHT
         // TODO: share MAXFONTHEIGHT font instance
         if( -aLogFont.lfHeight <= MAXFONTHEIGHT )
-            mfFontScale = 1.0;
+            o_rFontScale = 1.0;
         else
         {
-            mfFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT;
+            o_rFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT;
             aLogFont.lfHeight = -MAXFONTHEIGHT;
-            aLogFont.lfWidth = static_cast<LONG>( aLogFont.lfWidth / mfFontScale );
+            aLogFont.lfWidth = static_cast<LONG>( aLogFont.lfWidth / o_rFontScale );
         }
 
         hNewFont = ::CreateFontIndirectW( &aLogFont );
@@ -1288,7 +1277,7 @@
             // "PRB: Fonts Not Drawn Antialiased on Device Context for DirectDraw Surface"
             SelectFont( hdcScreen, SelectFont( hdcScreen , hNewFont ) );
         }
-        hOldFont = ::SelectFont( mhDC, hNewFont );
+        o_rOldFont = ::SelectFont( mhDC, hNewFont );
 
         TEXTMETRICW aTextMetricW;
         if( !::GetTextMetricsW( mhDC, &aTextMetricW ) )
@@ -1310,15 +1299,15 @@
              // TODO: get them from somewhere else
             mpLogFont = new LOGFONTA;
         LOGFONTA& aLogFont = *mpLogFont;
-        ImplGetLogFontFromFontSelect( mhDC, pFont, aLogFont, true );
+        ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true );
 
         // on the display we prefer Courier New when Courier is a
         // bitmap only font and we need to stretch or rotate it
         if( mbScreen
-        &&  (pFont->mnWidth != 0
-          || pFont->mnOrientation != 0
-          || pFont->mpFontData == NULL
-          || (pFont->mpFontData->GetHeight() != pFont->mnHeight))
+        &&  (i_pFont->mnWidth != 0
+          || i_pFont->mnOrientation != 0
+          || i_pFont->mpFontData == NULL
+          || (i_pFont->mpFontData->GetHeight() != i_pFont->mnHeight))
         && !bImplSalCourierScalable
         && bImplSalCourierNew
         && (stricmp( aLogFont.lfFaceName, "Courier" ) == 0) )
@@ -1327,12 +1316,12 @@
         // limit font requests to MAXFONTHEIGHT to work around driver problems
         // TODO: share MAXFONTHEIGHT font instance
         if( -aLogFont.lfHeight <= MAXFONTHEIGHT )
-            mfFontScale = 1.0;
+            o_rFontScale = 1.0;
         else
         {
-            mfFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT;
+            o_rFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT;
             aLogFont.lfHeight = -MAXFONTHEIGHT;
-            aLogFont.lfWidth = static_cast<LONG>( aLogFont.lfWidth / mfFontScale );
+            aLogFont.lfWidth = static_cast<LONG>( aLogFont.lfWidth / o_rFontScale );
         }
 
         hNewFont = ::CreateFontIndirectA( &aLogFont );
@@ -1343,7 +1332,7 @@
             // "PRB: Fonts Not Drawn Antialiased on Device Context for DirectDraw Surface"
             ::SelectFont( hdcScreen, ::SelectFont( hdcScreen , hNewFont ) );
         }
-        hOldFont = ::SelectFont( mhDC, hNewFont );
+        o_rOldFont = ::SelectFont( mhDC, hNewFont );
 
         TEXTMETRICA aTextMetricA;
         // when the font doesn't work try a replacement
@@ -1363,6 +1352,35 @@
 
     if( hdcScreen )
         ::ReleaseDC( NULL, hdcScreen );
+    
+    return hNewFont;
+}
+
+USHORT WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel )
+{
+    // return early if there is no new font
+    if( !pFont )
+    {
+        // deselect still active font
+        if( mhDefFont )
+            ::SelectFont( mhDC, mhDefFont );
+        // release no longer referenced font handles
+        for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
+        {
+            if( mhFonts[i] )
+                ::DeleteFont( mhFonts[i] );
+            mhFonts[ i ] = 0;
+        }
+        mhDefFont = 0;
+        return 0;
+    }
+
+    DBG_ASSERT( pFont->mpFontData, "WinSalGraphics mpFontData==NULL");
+    mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast<ImplWinFontEntry*>( pFont->mpFontEntry );
+    mpWinFontData[ nFallbackLevel ] = static_cast<ImplWinFontData*>( pFont->mpFontData );
+
+    HFONT hOldFont = 0;
+    HFONT hNewFont = ImplDoSetFont( pFont, mfFontScale, hOldFont );
 
     if( !mhDefFont )
     {
@@ -1747,7 +1765,8 @@
             if( (nFontType & RASTER_FONTTYPE) && !(nFontType & DEVICE_FONTTYPE) )
                 return 1;
 
-        ImplFontData* pData = ImplLogMetricToDevFontDataA( pLogFont, &(pMetric->ntmTm), nFontType );
+        ImplWinFontData* pData = ImplLogMetricToDevFontDataA( pLogFont, &(pMetric->ntmTm), nFontType );
+        pData->SetFontId( sal_IntPtr( pInfo->mnFontCount++ ) );
 
         // prefer the system character set, so that we get as much as
         // possible important characters. In the other case we could only
@@ -1802,7 +1821,8 @@
             if( (nFontType & RASTER_FONTTYPE) && !(nFontType & DEVICE_FONTTYPE) )
                 return 1;
 
-        ImplFontData* pData = ImplLogMetricToDevFontDataW( pLogFont, &(pMetric->ntmTm), nFontType );
+        ImplWinFontData* pData = ImplLogMetricToDevFontDataW( pLogFont, &(pMetric->ntmTm), nFontType );
+        pData->SetFontId( sal_IntPtr( pInfo->mnFontCount++ ) );
 
         // knowing Courier to be scalable is nice
         if( pInfo->mbCourier )
@@ -2070,9 +2090,10 @@
         aDFS.maMapName = aFontName;
     */
 
-    ImplFontData* pFontData = new ImplWinFontData( aDFA, 0,
+    ImplWinFontData* pFontData = new ImplWinFontData( aDFA, 0,
         sal::static_int_cast<WIN_BYTE>(nPreferedCharSet),
         sal::static_int_cast<WIN_BYTE>(TMPF_VECTOR|TMPF_TRUETYPE) );
+    pFontData->SetFontId( reinterpret_cast<sal_IntPtr>(pFontData) );
     pFontList->Add( pFontData );
     return true;
 }
@@ -2136,6 +2157,7 @@
     aInfo.mpLogFontW    = NULL;
     aInfo.mbCourier     = false;
     aInfo.mbPrinter     = mbPrinter;
+    aInfo.mnFontCount   = 0;
     if ( !mbPrinter )
     {
         aInfo.mbImplSalCourierScalable  = false;
@@ -2505,7 +2527,9 @@
 
     // TODO: much better solution: move SetFont and restoration of old font to caller
     ScopedFont aOldFont(*this);
-    SetFont( &aIFSD, 0 );
+    float fScale = 0.0;
+    HFONT hOldFont = 0;
+    ImplDoSetFont( &aIFSD, fScale, hOldFont );
 
 #if OSL_DEBUG_LEVEL > 1
     // get font metrics
@@ -2691,22 +2715,123 @@
         return NULL;
 
     // fill the encoding vector
-    typedef std::map< sal_Unicode,sal_Int32> Code2Int;
-    Code2Int& rMap = *new Code2Int;
-#if 0
-    // TODO: get correct encoding vector
-    ImplWinFontData* pWinFontData = reinterpret_cast<ImplWinFontData*>(pFont);
-    GLYPHSET aGlyphSet;
-    aGlyphSet.cbThis = sizeof(aGlyphSet);
-    DWORD aW = ::GetFontUnicodeRanges( mhDC, &aGlyphSet);
-#else
-    for( sal_Unicode i = 32; i < 256; ++i )
-        rMap[i] = i;
+    // currently no nonencoded vector
     if( pNonEncoded )
         *pNonEncoded = NULL;
-#endif
 
-    return &rMap;
+    ImplWinFontData* pWinFontData = static_cast<ImplWinFontData*>(pFont);
+    std::map< sal_Unicode,sal_Int32>* pEncoding = pWinFontData->GetEncodingVector();
+    if( pEncoding == NULL )
+    {
+        pEncoding = new std::map< sal_Unicode,sal_Int32>();
+        pWinFontData->SetEncodingVector( pEncoding );
+        #if 0
+        // TODO: get correct encoding vector
+        GLYPHSET aGlyphSet;
+        aGlyphSet.cbThis = sizeof(aGlyphSet);
+        DWORD aW = ::GetFontUnicodeRanges( mhDC, &aGlyphSet);
+        #else
+        for( sal_Unicode i = 32; i < 256; ++i )
+            (*pEncoding)[i] = i;
+        #endif
+    }
+
+    return pEncoding;
+}
+
+//--------------------------------------------------------------------------
+
+void WinSalGraphics::GetGlyphWidths( ImplFontData* pFont,
+                                     bool bVertical,
+                                     std::vector< sal_Int32 >& rWidths,
+                                     std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc )
+{
+    // create matching ImplFontSelectData
+    // we need just enough to get to the font file data
+    ImplFontSelectData aIFSD( *pFont, Size(0,1000), 0, false );
+
+    // TODO: much better solution: move SetFont and restoration of old font to caller
+    ScopedFont aOldFont(*this);
+    
+    float fScale = 0.0;
+    HFONT hOldFont = 0;
+    ImplDoSetFont( &aIFSD, fScale, hOldFont );
+    
+    if( pFont->IsSubsettable() )
+    {
+        // get raw font file data
+        DWORD nFontSize1 = ::GetFontData( mhDC, 0, 0, NULL, 0 );
+        if( nFontSize1 == GDI_ERROR )
+            return;
+        ScopedCharArray xRawFontData(new char[ nFontSize1 ]);
+        DWORD nFontSize2 = ::GetFontData( mhDC, 0, 0, (void*)xRawFontData.get(), nFontSize1 );
+        if( nFontSize1 != nFontSize2 )
+            return;
+
+        // open font file
+        sal_uInt32 nFaceNum = 0;
+        if( !*xRawFontData.get() )  // TTC candidate
+            nFaceNum = ~0U;  // indicate "TTC font extracts only"
+    
+        ScopedTrueTypeFont aSftTTF;
+        int nRC = aSftTTF.open( xRawFontData.get(), nFontSize1, nFaceNum );
+        if( nRC != SF_OK )
+            return;
+    
+        int nGlyphs = GetTTGlyphCount( aSftTTF.get() );
+        if( nGlyphs > 0 )
+        {
+            rWidths.resize(nGlyphs);
+            std::vector<sal_uInt16> aGlyphIds(nGlyphs);
+            for( int i = 0; i < nGlyphs; i++ )
+                aGlyphIds[i] = sal_uInt16(i);
+            TTSimpleGlyphMetrics* pMetrics = ::GetTTSimpleGlyphMetrics( aSftTTF.get(),
+                                                                        &aGlyphIds[0],
+                                                                        nGlyphs,
+                                                                        bVertical ? 1 : 0 );
+            if( pMetrics )
+            {
+                for( int i = 0; i< nGlyphs; i++ )
+                    rWidths[i] = pMetrics[i].adv;
+                free( pMetrics );
+                rUnicodeEnc.clear();
+            }
+            ImplWinFontData* pWinFont = static_cast<ImplWinFontData*>(pFont);
+            ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap();
+			DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" );
+
+			int nCharCount = pMap->GetCharCount();
+            sal_uInt32 nChar = pMap->GetFirstChar();
+			for( int i = 0; i < nCharCount; i++ )
+            {
+                if( nChar < 0x00010000 )
+                {
+                    sal_uInt16 nGlyph = ::MapChar( aSftTTF.get(),
+                                                   static_cast<sal_uInt16>(nChar),
+                                                   bVertical ? 1 : 0 );
+                    if( nGlyph )
+                        rUnicodeEnc[ static_cast<sal_Unicode>(nChar) ] = nGlyph;
+                }
+				nChar = pMap->GetNextChar( nChar );
+            }
+        }
+    }
+    else if( pFont->IsEmbeddable() )
+    {
+        // get individual character widths
+        rWidths.clear();
+        rUnicodeEnc.clear();
+        rWidths.reserve( 224 );
+        for( sal_Unicode i = 32; i < 256; ++i )
+        {
+            int nCharWidth = 0;
+            if( ::GetCharWidth32W( mhDC, i, i, &nCharWidth ) )
+            {
+                rUnicodeEnc[ i ] = rWidths.size();
+                rWidths.push_back( nCharWidth );
+            }
+        }
+    }    
 }
 
 //--------------------------------------------------------------------------


Index: openoffice.org.spec
===================================================================
RCS file: /cvs/pkgs/rpms/openoffice.org/F-7/openoffice.org.spec,v
retrieving revision 1.1186
retrieving revision 1.1187
diff -u -r1.1186 -r1.1187
--- openoffice.org.spec	27 Jun 2007 08:24:32 -0000	1.1186
+++ openoffice.org.spec	27 Jun 2007 08:52:38 -0000	1.1187
@@ -139,7 +139,7 @@
 Patch80: openoffice.org-2.2.1.ooo78383.vcl.printxerror.patch
 Patch81: openoffice.org-2.2.1.ooo78392.sixtyfour.tools.patch
 Patch82: openoffice.org-2.2.1.oooXXXXX.xmloff.outofrange.patch
-Patch83: openoffice.org-2.2.1.ooo78895.sw.overlappingpdf.patch
+Patch83: workspace.glyphadv.patch
 Patch84: openoffice.org-2.2.1.ooo78921.sw.embedded.patch
 
 %define instdir %{_libdir}/openoffice.org
@@ -1073,7 +1073,7 @@
 %patch80 -p1 -b .ooo78383.vcl.printxerror.patch
 %patch81 -p1 -b .ooo78392.sixtyfour.tools.patch
 %patch82 -p1 -b .oooXXXXX.xmloff.outofrange.patch
-%patch83 -p1 -b .ooo78895.sw.overlappingpdf.patch
+%patch83 -p1 -b .workspace.glyphadv.patch
 %patch84 -p1 -b .ooo78921.sw.embedded.patch
 
 cp %{SOURCE1} extras/source/database/evolocal.odb


--- openoffice.org-2.2.1.ooo78895.sw.overlappingpdf.patch DELETED ---




More information about the fedora-extras-commits mailing list