[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 147 commits - android/Bootstrap android/experimental basegfx/source bin/get-bugzilla-attachments-by-mimetype bin/lo-all-static-libs chart2/source chart2/uiconfig cppcanvas/source cui/AllLangResTarget_cui.mk cui/source cui/uiconfig cui/UIConfig_cui.mk dbaccess/source desktop/source dictionaries extras/source filter/source forms/source fpicker/source framework/source helpcontent2 idlc/CustomTarget_parser_test.mk idlc/test include/filter include/oox include/sfx2 include/vcl include/xmloff instsetoo_native/util ios/CustomTarget_MobileLibreOffice_app.mk ios/Executable_LibreOffice.mk ios/lo.xcconfig.in lotuswordpro/source offapi/com offapi/type_reference oox/source psprint_config/configuration qadevOOo/runner qadevOOo/tests README.Android README.Code Repository.mk rsc/source sal/osl sal/qa sax/source sc/inc scp2/source sc/qa sc/source sd/qa sd/source setup_native/source sfx2/source sfx2/util solenv/bin solenv/gbuild st armath/source svgio/inc svl/source svx/source sw/inc sw/qa sw/source unoidl/source vcl/aqua vcl/generic vcl/inc vcl/source winaccessibility/inc winaccessibility/Library_uacccom.mk winaccessibility/Library_winaccessibility.mk winaccessibility/source wizards/com wizards/Pyuno_web.mk writerfilter/Library_writerfilter.mk writerfilter/source xmloff/dtd xmloff/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 25 08:54:04 PST 2013


Rebased ref, commits from common ancestor:
commit e00562d9835bd82d74ef0301ea7425ff769915df
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:57:40 2013 -0500

    Allow worker threads to use their own FastParser instances.
    
    To prevent deadlock during threaded sheet stream parsing.  It now
    deadlocks at a different place.
    
    Change-Id: I0ba0f2c9a257e71b0a340ab14e369b06d5fd8829

diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx
index 87234fb..76eb091 100644
--- a/include/oox/core/xmlfilterbase.hxx
+++ b/include/oox/core/xmlfilterbase.hxx
@@ -56,8 +56,7 @@ namespace oox {
 namespace core {
 
 class FragmentHandler;
-
-// ============================================================================
+class FastParser;
 
 struct TextField {
     com::sun::star::uno::Reference< com::sun::star::text::XText > xText;
@@ -107,7 +106,8 @@ public:
 
         @return  True, if the fragment could be imported.
      */
-    bool                importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler );
+    bool importFragment( const rtl::Reference<FragmentHandler>& rxHandler );
+    bool importFragment( const rtl::Reference<FragmentHandler>& rxHandler, FastParser& rParser );
 
     /** Imports a fragment into an xml::dom::XDocument.
 
@@ -231,6 +231,8 @@ public:
 
     void importDocumentProperties();
 
+    FastParser* createParser() const;
+
 protected:
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
         implGetInputStream( utl::MediaDescriptor& rMediaDesc ) const;
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index dddc29c..30f3848 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -143,6 +143,13 @@ struct NamespaceIds: public rtl::StaticWithInit<
     }
 };
 
+void registerNamespaces( FastParser& rParser )
+{
+    const Sequence< beans::Pair<OUString, sal_Int32> > ids = NamespaceIds::get();
+    for (sal_Int32 i = 0; i < ids.getLength(); ++i)
+        rParser.registerNamespace(ids[i].Second);
+}
+
 } // namespace
 
 struct XmlFilterBaseImpl
@@ -164,10 +171,7 @@ XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxCo
     maVmlSuffix( ".vml" )
 {
     // register XML namespaces
-    const Sequence< beans::Pair< OUString, sal_Int32 > > ids=
-        NamespaceIds::get();
-    for( sal_Int32 i=0; i<ids.getLength(); ++i )
-        maFastParser.registerNamespace( ids[i].Second );
+    registerNamespaces(maFastParser);
 }
 
 XmlFilterBase::XmlFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
@@ -203,13 +207,25 @@ void XmlFilterBase::importDocumentProperties()
     xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() );
 }
 
+FastParser* XmlFilterBase::createParser() const
+{
+    FastParser* pParser = new FastParser(getComponentContext());
+    registerNamespaces(*pParser);
+    return pParser;
+}
+
 OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType )
 {
     // importRelations() caches the relations map for subsequence calls
     return importRelations( OUString() )->getFragmentPathFromFirstType( rType );
 }
 
-bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+bool XmlFilterBase::importFragment( const rtl::Reference<FragmentHandler>& rxHandler )
+{
+    return importFragment(rxHandler, mxImpl->maFastParser);
+}
+
+bool XmlFilterBase::importFragment( const rtl::Reference<FragmentHandler>& rxHandler, FastParser& rParser )
 {
     OSL_ENSURE( rxHandler.is(), "XmlFilterBase::importFragment - missing fragment handler" );
     if( !rxHandler.is() )
@@ -263,8 +279,8 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r
         // own try/catch block for showing parser failure assertion with fragment path
         if( xInStrm.is() ) try
         {
-            mxImpl->maFastParser.setDocumentHandler( xDocHandler );
-            mxImpl->maFastParser.parseStream( xInStrm, aFragmentPath );
+            rParser.setDocumentHandler(xDocHandler);
+            rParser.parseStream(xInStrm, aFragmentPath);
             return true;
         }
         catch( Exception& )
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index abafb20..1f472c3 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -53,6 +53,7 @@ namespace oox { namespace core {
     class FilterBase;
     class FragmentHandler;
     class XmlFilterBase;
+    class FastParser;
 } }
 
 class ScDocument;
@@ -269,7 +270,10 @@ public:
 
     /** Imports a fragment using the passed fragment handler, which contains
         the full path to the fragment stream. */
-    bool                importOoxFragment( const ::rtl::Reference< ::oox::core::FragmentHandler >& rxHandler );
+    bool importOoxFragment( const rtl::Reference<oox::core::FragmentHandler>& rxHandler );
+
+    bool importOoxFragment( const rtl::Reference<oox::core::FragmentHandler>& rxHandler, oox::core::FastParser& rParser );
+
 
     // BIFF2-BIFF8 specific (MUST NOT be called in OOXML/BIFF12 filter) -------
 
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index e9471cb..81eb2ed 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -49,6 +49,7 @@
 #include "globstr.hrc"
 #include "calcconfig.hxx"
 
+#include <oox/core/fastparser.hxx>
 #include <comphelper/processfactory.hxx>
 #include <officecfg/Office/Calc.hxx>
 #include <salhelper/thread.hxx>
@@ -240,13 +241,17 @@ class WorkerThread : public salhelper::Thread
     WorkbookFragment& mrWorkbookHandler;
     size_t mnID;
     FragmentHandlerRef mxHandler;
+    boost::scoped_ptr<oox::core::FastParser> mxParser;
     osl::Mutex maMtxAction;
     osl::Condition maCondActionChanged;
     WorkerAction meAction;
 public:
     WorkerThread( WorkbookFragment& rWorkbookHandler, size_t nID ) :
         salhelper::Thread("sheet-import-worker-thread"),
-        mrWorkbookHandler(rWorkbookHandler), mnID(nID), meAction(None) {}
+        mrWorkbookHandler(rWorkbookHandler),
+        mnID(nID),
+        mxParser(rWorkbookHandler.getOoxFilter().createParser()),
+        meAction(None) {}
 
     virtual void execute()
     {
@@ -271,7 +276,7 @@ public:
 
 #if 0
             // TODO : This still deadlocks in the fast parser code.
-            mrWorkbookHandler.importOoxFragment(mxHandler);
+            mrWorkbookHandler.importOoxFragment(mxHandler, *mxParser);
 #else
             double val = rand() / static_cast<double>(RAND_MAX);
             val *= 1000000; // normalize to 1 second.
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 33270e5..66a51b4 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -961,11 +961,16 @@ XmlFilterBase& WorkbookHelper::getOoxFilter() const
     return mrBookGlob.getOoxFilter();
 }
 
-bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler )
 {
     return getOoxFilter().importFragment( rxHandler );
 }
 
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler, oox::core::FastParser& rParser )
+{
+    return getOoxFilter().importFragment(rxHandler, rParser);
+}
+
 // BIFF specific --------------------------------------------------------------
 
 BiffType WorkbookHelper::getBiff() const
commit 8e5fd4a15ae2c7d55842b1b768b7807a2d3a298e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:14:44 2013 -0500

    A bit of cleanup.
    
    Change-Id: I576a184ebc8422d760800c670f8d9070f66e9e78

diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 3416dc7..dddc29c 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -58,8 +58,6 @@ using ::com::sun::star::xml::dom::XDocumentBuilder;
 namespace oox {
 namespace core {
 
-// ============================================================================
-
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::container;
@@ -74,12 +72,6 @@ using utl::MediaDescriptor;
 using ::sax_fastparser::FSHelperPtr;
 using ::sax_fastparser::FastSerializerHelper;
 
-
-
-
-
-// ============================================================================
-
 namespace {
 
 bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
@@ -88,27 +80,6 @@ bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
     return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos );
 }
 
-} // namespace
-
-// ============================================================================
-
-struct XmlFilterBaseImpl
-{
-    typedef RefMap< OUString, Relations > RelationsMap;
-
-    FastParser                     maFastParser;
-    const OUString                 maBinSuffix;
-    const OUString                 maVmlSuffix;
-    RelationsMap                   maRelationsMap;
-    TextFieldStack                 maTextFieldStack;
-
-    explicit            XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
-};
-
-// ----------------------------------------------------------------------------
-
-namespace {
-
 struct NamespaceIds: public rtl::StaticWithInit<
     Sequence< beans::Pair< OUString, sal_Int32 > >,
     NamespaceIds>
@@ -172,9 +143,20 @@ struct NamespaceIds: public rtl::StaticWithInit<
     }
 };
 
-}
+} // namespace
 
-// ----------------------------------------------------------------------------
+struct XmlFilterBaseImpl
+{
+    typedef RefMap< OUString, Relations > RelationsMap;
+
+    FastParser                     maFastParser;
+    const OUString                 maBinSuffix;
+    const OUString                 maVmlSuffix;
+    RelationsMap                   maRelationsMap;
+    TextFieldStack                 maTextFieldStack;
+
+    explicit            XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
+};
 
 XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
     maFastParser( rxContext ),
commit 136d57e9eb2a106ac4c22712027cc48ed6e4ad8d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:12:41 2013 -0500

    No indent on namespaces.
    
    Change-Id: I2639a51c2faa19373a335c28b160862435cd6dbe

diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 98c8886..3416dc7 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -107,70 +107,71 @@ struct XmlFilterBaseImpl
 
 // ----------------------------------------------------------------------------
 
-namespace
+namespace {
+
+struct NamespaceIds: public rtl::StaticWithInit<
+    Sequence< beans::Pair< OUString, sal_Int32 > >,
+    NamespaceIds>
 {
-    struct NamespaceIds: public rtl::StaticWithInit<
-        Sequence< beans::Pair< OUString, sal_Int32 > >,
-        NamespaceIds>
+    Sequence< beans::Pair< OUString, sal_Int32 > > operator()()
     {
-        Sequence< beans::Pair< OUString, sal_Int32 > > operator()()
-        {
-            static const char* const namespaceURIs[] = {
-                "http://www.w3.org/XML/1998/namespace",
-                "http://schemas.openxmlformats.org/package/2006/relationships",
-                "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
-                "http://schemas.openxmlformats.org/drawingml/2006/main",
-                "http://schemas.openxmlformats.org/drawingml/2006/diagram",
-                "http://schemas.openxmlformats.org/drawingml/2006/chart",
-                "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
-                "urn:schemas-microsoft-com:vml",
-                "urn:schemas-microsoft-com:office:office",
-                "urn:schemas-microsoft-com:office:word",
-                "urn:schemas-microsoft-com:office:excel",
-                "urn:schemas-microsoft-com:office:powerpoint",
-                "http://schemas.microsoft.com/office/2006/activeX",
-                "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
-                "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
-                "http://schemas.microsoft.com/office/excel/2006/main",
-                "http://schemas.openxmlformats.org/presentationml/2006/main",
-                "http://schemas.openxmlformats.org/markup-compatibility/2006",
-                "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
-                "http://schemas.microsoft.com/office/drawing/2008/diagram",
-                "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
-            };
-
-            static const sal_Int32 namespaceIds[] = {
-                NMSP_xml,
-                NMSP_packageRel,
-                NMSP_officeRel,
-                NMSP_dml,
-                NMSP_dmlDiagram,
-                NMSP_dmlChart,
-                NMSP_dmlChartDr,
-                NMSP_dmlSpreadDr,
-                NMSP_vml,
-                NMSP_vmlOffice,
-                NMSP_vmlWord,
-                NMSP_vmlExcel,
-                NMSP_vmlPowerpoint,
-                NMSP_xls,
-                NMSP_ppt,
-                NMSP_ax,
-                NMSP_xm,
-                NMSP_mce,
-                NMSP_mceTest,
-                NMSP_dsp,
-                NMSP_xlsExtLst
-            };
-
-            Sequence< beans::Pair< OUString, sal_Int32 > > aRet(STATIC_ARRAY_SIZE(namespaceIds));
-            for( sal_Int32 i=0; i<aRet.getLength(); ++i )
-                aRet[i] = make_Pair(
-                    OUString::createFromAscii(namespaceURIs[i]),
-                    namespaceIds[i]);
-            return aRet;
-        }
-    };
+        static const char* const namespaceURIs[] = {
+            "http://www.w3.org/XML/1998/namespace",
+            "http://schemas.openxmlformats.org/package/2006/relationships",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+            "http://schemas.openxmlformats.org/drawingml/2006/main",
+            "http://schemas.openxmlformats.org/drawingml/2006/diagram",
+            "http://schemas.openxmlformats.org/drawingml/2006/chart",
+            "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
+            "urn:schemas-microsoft-com:vml",
+            "urn:schemas-microsoft-com:office:office",
+            "urn:schemas-microsoft-com:office:word",
+            "urn:schemas-microsoft-com:office:excel",
+            "urn:schemas-microsoft-com:office:powerpoint",
+            "http://schemas.microsoft.com/office/2006/activeX",
+            "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+            "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
+            "http://schemas.microsoft.com/office/excel/2006/main",
+            "http://schemas.openxmlformats.org/presentationml/2006/main",
+            "http://schemas.openxmlformats.org/markup-compatibility/2006",
+            "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
+            "http://schemas.microsoft.com/office/drawing/2008/diagram",
+            "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
+        };
+
+        static const sal_Int32 namespaceIds[] = {
+            NMSP_xml,
+            NMSP_packageRel,
+            NMSP_officeRel,
+            NMSP_dml,
+            NMSP_dmlDiagram,
+            NMSP_dmlChart,
+            NMSP_dmlChartDr,
+            NMSP_dmlSpreadDr,
+            NMSP_vml,
+            NMSP_vmlOffice,
+            NMSP_vmlWord,
+            NMSP_vmlExcel,
+            NMSP_vmlPowerpoint,
+            NMSP_xls,
+            NMSP_ppt,
+            NMSP_ax,
+            NMSP_xm,
+            NMSP_mce,
+            NMSP_mceTest,
+            NMSP_dsp,
+            NMSP_xlsExtLst
+        };
+
+        Sequence< beans::Pair< OUString, sal_Int32 > > aRet(STATIC_ARRAY_SIZE(namespaceIds));
+        for( sal_Int32 i=0; i<aRet.getLength(); ++i )
+            aRet[i] = make_Pair(
+                OUString::createFromAscii(namespaceURIs[i]),
+                namespaceIds[i]);
+        return aRet;
+    }
+};
+
 }
 
 // ----------------------------------------------------------------------------
commit 0da598c5d7f2bedc8113567bccade3d2a9f8a0b1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 18:28:26 2013 -0500

    Add hook to optionally enable threaded sheet stream parsing.
    
    Threaded version still not working as the fast parser deadlocks during
    threaded parsing.
    
    Change-Id: I3d402a22a394d7d0d7edf96590ae039506928fde

diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 30f0f34..e9471cb 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -51,6 +51,12 @@
 
 #include <comphelper/processfactory.hxx>
 #include <officecfg/Office/Calc.hxx>
+#include <salhelper/thread.hxx>
+#include <osl/conditn.hxx>
+
+#include <queue>
+#include <boost/scoped_ptr.hpp>
+
 #include "oox/ole/vbaproject.hxx"
 
 namespace oox {
@@ -194,6 +200,189 @@ const RecordInfo* WorkbookFragment::getRecordInfos() const
     return spRecInfos;
 }
 
+namespace {
+
+class WorkerThread;
+
+typedef std::pair<WorksheetGlobalsRef, FragmentHandlerRef> SheetFragmentHandler;
+typedef std::vector<SheetFragmentHandler> SheetFragmentVector;
+typedef rtl::Reference<WorkerThread> WorkerThreadRef;
+
+struct WorkerThreadData
+{
+    osl::Mutex maMtx;
+    std::vector<WorkerThreadRef> maThreads;
+};
+
+struct IdleWorkerThreadData
+{
+    osl::Mutex maMtx;
+    osl::Condition maCondAdded;
+    std::queue<WorkerThread*> maThreads;
+};
+
+struct
+{
+    boost::scoped_ptr<WorkerThreadData> mpWorkerThreads;
+    boost::scoped_ptr<IdleWorkerThreadData> mpIdleThreads;
+
+} aThreadGlobals;
+
+enum WorkerAction
+{
+    None = 0,
+    TerminateThread,
+    Work
+};
+
+class WorkerThread : public salhelper::Thread
+{
+    WorkbookFragment& mrWorkbookHandler;
+    size_t mnID;
+    FragmentHandlerRef mxHandler;
+    osl::Mutex maMtxAction;
+    osl::Condition maCondActionChanged;
+    WorkerAction meAction;
+public:
+    WorkerThread( WorkbookFragment& rWorkbookHandler, size_t nID ) :
+        salhelper::Thread("sheet-import-worker-thread"),
+        mrWorkbookHandler(rWorkbookHandler), mnID(nID), meAction(None) {}
+
+    virtual void execute()
+    {
+        announceIdle();
+
+        // Keep looping until the terminate request is set.
+        for (maCondActionChanged.wait(); true; maCondActionChanged.wait())
+        {
+            osl::MutexGuard aGuard(maMtxAction);
+            if (!maCondActionChanged.check())
+                // Wait again.
+                continue;
+
+            maCondActionChanged.reset();
+
+            if (meAction == TerminateThread)
+                // End the thread.
+                return;
+
+            if (meAction != Work)
+                continue;
+
+#if 0
+            // TODO : This still deadlocks in the fast parser code.
+            mrWorkbookHandler.importOoxFragment(mxHandler);
+#else
+            double val = rand() / static_cast<double>(RAND_MAX);
+            val *= 1000000; // normalize to 1 second.
+            val *= 1.5; // inflate it a bit.
+            usleep(val); // pretend to be working while asleep.
+#endif
+            announceIdle();
+        }
+    }
+
+    void announceIdle()
+    {
+        // Set itself idle to receive a new task from the main thread.
+        osl::MutexGuard aGuard(aThreadGlobals.mpIdleThreads->maMtx);
+        aThreadGlobals.mpIdleThreads->maThreads.push(this);
+        aThreadGlobals.mpIdleThreads->maCondAdded.set();
+    }
+
+    void terminate()
+    {
+        osl::MutexGuard aGuard(maMtxAction);
+        meAction = TerminateThread;
+        maCondActionChanged.set();
+    }
+
+    void assign( const FragmentHandlerRef& rHandler )
+    {
+        osl::MutexGuard aGuard(maMtxAction);
+        mxHandler = rHandler;
+        meAction = Work;
+        maCondActionChanged.set();
+    }
+};
+
+void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
+{
+#if 0 // threaded version
+    size_t nThreadCount = 3;
+    if (nThreadCount > rSheets.size())
+        nThreadCount = rSheets.size();
+
+    // Create new thread globals.
+    aThreadGlobals.mpWorkerThreads.reset(new WorkerThreadData);
+    aThreadGlobals.mpIdleThreads.reset(new IdleWorkerThreadData);
+
+    SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end();
+
+    {
+        // Initialize worker threads.
+        osl::MutexGuard aGuard(aThreadGlobals.mpWorkerThreads->maMtx);
+        for (size_t i = 0; i < nThreadCount; ++i)
+        {
+            WorkerThreadRef pThread(new WorkerThread(rWorkbookHandler, i));
+            aThreadGlobals.mpWorkerThreads->maThreads.push_back(pThread);
+            pThread->launch();
+        }
+    }
+
+    for (aThreadGlobals.mpIdleThreads->maCondAdded.wait(); true; aThreadGlobals.mpIdleThreads->maCondAdded.wait())
+    {
+        osl::MutexGuard aGuard(aThreadGlobals.mpIdleThreads->maMtx);
+        if (!aThreadGlobals.mpIdleThreads->maCondAdded.check())
+            // Wait again.
+            continue;
+
+        aThreadGlobals.mpIdleThreads->maCondAdded.reset();
+
+        // Assign work to all idle threads.
+        while (!aThreadGlobals.mpIdleThreads->maThreads.empty())
+        {
+            if (it == itEnd)
+                break;
+
+            WorkerThread* p = aThreadGlobals.mpIdleThreads->maThreads.front();
+            aThreadGlobals.mpIdleThreads->maThreads.pop();
+            p->assign(it->second);
+            ++it;
+        }
+
+        if (it == itEnd)
+            // Finished!  Exit the loop.
+            break;
+    }
+
+    {
+        // Terminate all worker threads.
+        osl::MutexGuard aGuard(aThreadGlobals.mpWorkerThreads->maMtx);
+        for (size_t i = 0, n = aThreadGlobals.mpWorkerThreads->maThreads.size(); i < n; ++i)
+        {
+            WorkerThreadRef pWorker = aThreadGlobals.mpWorkerThreads->maThreads[i];
+            pWorker->terminate();
+            if (pWorker.is())
+                pWorker->join();
+        }
+    }
+
+    // Delete all thread globals.
+    aThreadGlobals.mpWorkerThreads.reset();
+    aThreadGlobals.mpIdleThreads.reset();
+
+#else // non-threaded version
+    for( SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end(); it != itEnd; ++it)
+    {
+        // import the sheet fragment
+        rWorkbookHandler.importOoxFragment(it->second);
+    }
+#endif
+}
+
+}
+
 void WorkbookFragment::finalizeImport()
 {
     ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
@@ -229,8 +418,6 @@ void WorkbookFragment::finalizeImport()
         fragments for all sheets that are needed before the cell formulas are
         loaded. Additionally, the instances of the WorkbookGlobals structures
         have to be stored for every sheet. */
-    typedef ::std::pair< WorksheetGlobalsRef, FragmentHandlerRef > SheetFragmentHandler;
-    typedef ::std::vector< SheetFragmentHandler > SheetFragmentVector;
     SheetFragmentVector aSheetFragments;
     std::vector<WorksheetHelper*> maHelpers;
     WorksheetBuffer& rWorksheets = getWorksheets();
@@ -315,11 +502,7 @@ void WorkbookFragment::finalizeImport()
     }
 
     // load all worksheets
-    for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt )
-    {
-        // import the sheet fragment
-        importOoxFragment( aIt->second );
-    }
+    importSheetFragments(*this, aSheetFragments);
 
     for( std::vector<WorksheetHelper*>::iterator aIt = maHelpers.begin(), aEnd = maHelpers.end(); aIt != aEnd; ++aIt )
     {
commit e79af02bb0e8de14c881f5071a519f6fadedc828
Author: Herbert Dürr <hdu at apache.org>
Date:   Mon Nov 25 13:29:47 2013 +0000

    Resolves: #i123747# allow treating Window's SEH events as C++ exceptions
    
    The crash reporter facility can provide much better details about crashes.
    But if that facility is disabled then handling SEH events such as div-by-zero
    as C++ exceptions is a worthwhile alternative. It can provide a few interesting
    details and it allows a graceful shutdown of the application.
    
    (cherry picked from commit c9d10b167b37a9cb0bb310cafc8e80b6cce8ea7a)
    
    Conflicts:
    	sal/osl/w32/signal.cxx
    
    Change-Id: I25324d6e02ab8acd8fd2b036b77039aac87cf262

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index ee3b4d5..79fdc50 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1488,11 +1488,8 @@ int Desktop::Main()
 
         // set static variable to enabled/disable crash reporter
         retrieveCrashReporterState();
-        if ( !isCrashReporterEnabled() )
-        {
-            osl_setErrorReporting( sal_False );
-            // disable stack trace feature
-        }
+        const bool bCrashReporterEnabled = isCrashReporterEnabled();
+        osl_setErrorReporting( !bCrashReporterEnabled );
 
         // create title string
         LanguageTag aLocale( LANGUAGE_SYSTEM);
diff --git a/sal/osl/w32/signal.cxx b/sal/osl/w32/signal.cxx
index f13a78a..51e08bc 100644
--- a/sal/osl/w32/signal.cxx
+++ b/sal/osl/w32/signal.cxx
@@ -33,6 +33,8 @@
 #include <errorrep.h>
 #include <systools/win32/uwinapi.h>
 #include <sal/macros.h>
+#include <eh.h>
+#include <stdexcept>
 
 typedef struct _oslSignalHandlerImpl
 {
@@ -398,11 +400,50 @@ oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
 /*****************************************************************************/
 /* osl_setErrorReporting */
 /*****************************************************************************/
+
+void win_seh_translator( unsigned nSEHCode, _EXCEPTION_POINTERS* pExcPtrs)
+{
+    const char* pSEHName = NULL;
+    switch( nSEHCode) {
+        case EXCEPTION_ACCESS_VIOLATION:         pSEHName = "SEH Exception: ACCESS VIOLATION"; break;
+        case EXCEPTION_DATATYPE_MISALIGNMENT:    pSEHName = "SEH Exception: DATATYPE MISALIGNMENT"; break;
+//      case EXCEPTION_BREAKPOINT:               pSEHName = "SEH Exception: BREAKPOINT"; break;
+//      case EXCEPTION_SINGLE_STEP:              pSEHName = "SEH Exception: SINGLE STEP"; break;
+        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:    pSEHName = "SEH Exception: ARRAY BOUNDS EXCEEDED"; break;
+        case EXCEPTION_FLT_DENORMAL_OPERAND:     pSEHName = "SEH Exception: DENORMAL FLOAT OPERAND"; break;
+        case EXCEPTION_FLT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: FLOAT DIVIDE_BY_ZERO"; break;
+        case EXCEPTION_FLT_INEXACT_RESULT:       pSEHName = "SEH Exception: FLOAT INEXACT RESULT"; break;
+        case EXCEPTION_FLT_INVALID_OPERATION:    pSEHName = "SEH Exception: INVALID FLOAT OPERATION"; break;
+        case EXCEPTION_FLT_OVERFLOW:             pSEHName = "SEH Exception: FLOAT OVERFLOW"; break;
+        case EXCEPTION_FLT_STACK_CHECK:          pSEHName = "SEH Exception: FLOAT STACK_CHECK"; break;
+        case EXCEPTION_FLT_UNDERFLOW:            pSEHName = "SEH Exception: FLOAT UNDERFLOW"; break;
+        case EXCEPTION_INT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: INTEGER DIVIDE_BY_ZERO"; break;
+        case EXCEPTION_INT_OVERFLOW:             pSEHName = "SEH Exception: INTEGER OVERFLOW"; break;
+        case EXCEPTION_PRIV_INSTRUCTION:         pSEHName = "SEH Exception: PRIVILEDGED INSTRUCTION"; break;
+        case EXCEPTION_IN_PAGE_ERROR:            pSEHName = "SEH Exception: IN_PAGE_ERROR"; break;
+        case EXCEPTION_ILLEGAL_INSTRUCTION:      pSEHName = "SEH Exception: ILLEGAL INSTRUCTION"; break;
+        case EXCEPTION_NONCONTINUABLE_EXCEPTION: pSEHName = "SEH Exception: NONCONTINUABLE EXCEPTION"; break;
+        case EXCEPTION_STACK_OVERFLOW:           pSEHName = "SEH Exception: STACK OVERFLOW"; break;
+        case EXCEPTION_INVALID_DISPOSITION:      pSEHName = "SEH Exception: INVALID DISPOSITION"; break;
+        case EXCEPTION_GUARD_PAGE:               pSEHName = "SEH Exception: GUARD PAGE"; break;
+        case EXCEPTION_INVALID_HANDLE:           pSEHName = "SEH Exception: INVALID HANDLE"; break;
+//      case EXCEPTION_POSSIBLE_DEADLOCK:        pSEHName = "SEH Exception: POSSIBLE DEADLOCK"; break;
+        default:                                 pSEHName = "Unknown SEH Exception"; break;
+    }
+    throw std::runtime_error( pSEHName);
+}
+
 sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
 {
     sal_Bool bOld = bErrorReportingEnabled;
     bErrorReportingEnabled = bEnable;
 
+    if( !bEnable) // if the crash reporter is disabled
+    {
+        // fall back to handle Window's SEH events as C++ exceptions
+        _set_se_translator( win_seh_translator);
+    }
+
     return bOld;
 }
 
commit 871d8e0f278dab646e1877a505577edc730a26cf
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Nov 25 14:13:40 2013 +0000

    Resolves: rhbz#188467 default to Type42
    
    Change-Id: Ifea55c532784accd218ad359349708f48aee7bb5

diff --git a/psprint_config/configuration/ppds/SGENPRT.PS b/psprint_config/configuration/ppds/SGENPRT.PS
index 0446757..177e2c4 100644
--- a/psprint_config/configuration/ppds/SGENPRT.PS
+++ b/psprint_config/configuration/ppds/SGENPRT.PS
@@ -42,6 +42,7 @@
 *ColorDevice: True
 *DefaultColorSpace: RGB
 *LanguageLevel: "2"
+*TTRasterizer: Type42
 
 *% --- For None Color or old PostScript(R) printers use following lines ---
 *% *ColorDevice: False
commit 79c0027c88fb64ffa7bbefcab2e291852733c223
Author: Steve Yin <steve_y at apache.org>
Date:   Mon Nov 25 13:15:27 2013 +0000

    Integrate branch of IAccessible2
    
    Change-Id: I8c2fea0367ebfa53ce5e109ef48fd661cbfb78b3

diff --git a/include/vcl/combobox.hxx b/include/vcl/combobox.hxx
index 6f9c534..76533ab 100644
--- a/include/vcl/combobox.hxx
+++ b/include/vcl/combobox.hxx
@@ -74,6 +74,7 @@ private:
     DECL_DLLPRIVATE_LINK(   ImplSelectionChangedHdl, void* );
     DECL_DLLPRIVATE_LINK(   ImplUserDrawHdl, UserDrawEvent* );
     DECL_DLLPRIVATE_LINK(   ImplAutocompleteHdl, Edit* );
+    DECL_DLLPRIVATE_LINK( ImplListItemSelectHdl , void* );
 
 protected:
     using Window::ImplInit;
@@ -178,8 +179,8 @@ public:
     void            SetMRUEntries( const OUString& rEntries, sal_Unicode cSep = ';' );
     OUString        GetMRUEntries( sal_Unicode cSep = ';' ) const;
     void            SetMaxMRUCount( sal_uInt16 n );
-    sal_uInt16          GetMaxMRUCount() const;
-
+    sal_uInt16      GetMaxMRUCount() const;
+    sal_uInt16      GetMRUCount() const;
     void            SetEntryData( sal_uInt16 nPos, void* pNewData );
     void*           GetEntryData( sal_uInt16 nPos ) const;
 
diff --git a/include/vcl/lstbox.hxx b/include/vcl/lstbox.hxx
index 6b3ab8c..cc63c2f 100644
--- a/include/vcl/lstbox.hxx
+++ b/include/vcl/lstbox.hxx
@@ -63,7 +63,8 @@ private:
     DECL_DLLPRIVATE_LINK(  ImplPopupModeEndHdl, void* );
     DECL_DLLPRIVATE_LINK(  ImplSelectionChangedHdl, void* );
     DECL_DLLPRIVATE_LINK(  ImplUserDrawHdl, UserDrawEvent* );
-
+    DECL_DLLPRIVATE_LINK(  ImplFocusHdl, void* );
+    DECL_DLLPRIVATE_LINK(  ImplListItemSelectHdl, void* );
 protected:
     using Window::ImplInit;
     SAL_DLLPRIVATE void    ImplInit( Window* pParent, WinBits nStyle );
@@ -198,6 +199,7 @@ public:
     Size                CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
     void                GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
 
+    sal_uInt16          GetMRUCount() const;
     sal_uInt16          GetDisplayLineCount() const;
 
     void                EnableMirroring();
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 637c701..5131872 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -134,6 +134,8 @@ private:
     sal_uInt16          nDefaultItem;       // Id of default item
     sal_uInt16          nSelectedId;
 
+    sal_uInt16          nHighlightedItem;
+
     // for output:
     sal_uInt16          nImgOrChkPos;
     sal_uInt16          nTextPos;
@@ -234,6 +236,13 @@ public:
     sal_uInt16          GetCurItemId() const;
     OString             GetCurItemIdent() const;
 
+    void                SetHightlightItem(sal_uInt16 nHighlightedItem);
+    sal_uInt16          GetHighlightItem() const;
+
+    OUString            GetItemAccKeyStrFromPos(sal_uInt16 nPos) const;
+
+    sal_Bool            IsTemporaryItemFromPos(sal_uInt16 nPos) const;
+
     void                SetDefaultItem( sal_uInt16 nItemId )    { nDefaultItem = nItemId; }
     sal_uInt16              GetDefaultItem() const              { return nDefaultItem; }
 
diff --git a/vcl/inc/ilstbox.hxx b/vcl/inc/ilstbox.hxx
index 315f4ce..18dfee8 100644
--- a/vcl/inc/ilstbox.hxx
+++ b/vcl/inc/ilstbox.hxx
@@ -253,6 +253,8 @@ private:
     Link            maDoubleClickHdl;
     Link            maUserDrawHdl;
     Link            maMRUChangedHdl;
+    Link            maFocusHdl;
+    Link            maListItemSelectHdl;
 
     ::vcl::QuickSelectionEngine maQuickSelectionEngine;
 
@@ -266,7 +268,7 @@ protected:
     virtual void    GetFocus();
     virtual void    LoseFocus();
 
-    sal_Bool            SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift = sal_False, sal_Bool bCtrl = sal_False );
+    sal_Bool        SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift = sal_False, sal_Bool bCtrl = sal_False, sal_Bool bSelectPosChange = sal_False );
     void            ImplPaint( sal_uInt16 nPos, sal_Bool bErase = sal_False, bool bLayout = false );
     void            ImplDoPaint( const Rectangle& rRect, bool bLayout = false );
     void            ImplCalcMetrics();
@@ -363,9 +365,13 @@ public:
     const Link&     GetUserDrawHdl() const              { return maUserDrawHdl; }
     void            SetMRUChangedHdl( const Link& rLink )   { maMRUChangedHdl = rLink; }
     const Link&     GetMRUChangedHdl() const                { return maMRUChangedHdl; }
+    void            SetFocusHdl( const Link& rLink )    { maFocusHdl = rLink ; }
+    const Link&     GetFocusHdl() const             { return maFocusHdl; }
 
+    void            SetListItemSelectHdl( const Link& rLink )   { maListItemSelectHdl = rLink ; }
+    const Link&     GetListItemSelectHdl() const                { return maListItemSelectHdl; }
     bool            IsSelectionChanged() const { return mbSelectionChanged; }
-    sal_uInt16          GetSelectModifier() const { return mnSelectModifier; }
+    sal_uInt16      GetSelectModifier() const { return mnSelectModifier; }
 
     void            EnableSort( bool b ) { mbSort = b; }
 
@@ -499,6 +505,10 @@ public:
     void            SetUserDrawHdl( const Link& rLink ) { maLBWindow.SetUserDrawHdl( rLink ); }
     const Link&     GetUserDrawHdl() const              { return maLBWindow.GetUserDrawHdl(); }
 
+    void            SetFocusHdl( const Link& rLink )    { maLBWindow.SetFocusHdl( rLink ); }
+    const Link&     GetFocusHdl() const             { return maLBWindow.GetFocusHdl(); }
+    void            SetListItemSelectHdl( const Link& rLink )   { maLBWindow.SetListItemSelectHdl( rLink ); }
+    const Link&     GetListItemSelectHdl() const    { return maLBWindow.GetListItemSelectHdl(); }
     void            SetSelectionChangedHdl( const Link& rLnk )  { maLBWindow.GetEntryList()->SetSelectionChangedHdl( rLnk ); }
     void            SetCallSelectionChangedHdl( sal_Bool bCall )    { maLBWindow.GetEntryList()->SetCallSelectionChangedHdl( bCall ); }
     sal_Bool            IsSelectionChanged() const                  { return maLBWindow.IsSelectionChanged(); }
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index bb304b1..214bbf5 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -205,6 +205,7 @@ void ComboBox::ImplInit( Window* pParent, WinBits nStyle )
     mpImplLB->SetDoubleClickHdl( LINK( this, ComboBox, ImplDoubleClickHdl ) );
     mpImplLB->SetUserDrawHdl( LINK( this, ComboBox, ImplUserDrawHdl ) );
     mpImplLB->SetSelectionChangedHdl( LINK( this, ComboBox, ImplSelectionChangedHdl ) );
+    mpImplLB->SetListItemSelectHdl( LINK( this, ComboBox, ImplListItemSelectHdl ) );
     mpImplLB->Show();
 
     if ( mpFloatWin )
@@ -460,7 +461,11 @@ IMPL_LINK_NOARG(ComboBox, ImplSelectHdl)
     return 0;
 }
 
-// -----------------------------------------------------------------------
+IMPL_LINK( ComboBox, ImplListItemSelectHdl,  void*, EMPTYARG )
+{
+    ImplCallEventListeners( VCLEVENT_LISTBOX_SELECT );
+    return 1;
+}
 
 IMPL_LINK_NOARG(ComboBox, ImplCancelHdl)
 {
@@ -1364,6 +1369,11 @@ sal_uInt16 ComboBox::GetMaxMRUCount() const
     return mpImplLB->GetMaxMRUCount();
 }
 
+sal_uInt16 ComboBox::GetMRUCount() const
+{
+    return mpImplLB->GetEntryList()->GetMRUCount();
+}
+
 // -----------------------------------------------------------------------
 
 sal_uInt16 ComboBox::GetDisplayLineCount() const
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index 98edce1..904a502 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -2491,8 +2491,7 @@ void Edit::Modify()
             return;
 
         // #i13677# notify edit listeners about caret position change
-        ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED );
-
+        ImplCallEventListeners( VCLEVENT_EDIT_CARETCHANGED );
         // FIXME: this is currently only on aqua
         // check for other platforms that need similar handling
         if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
@@ -2647,15 +2646,35 @@ void Edit::ImplSetSelection( const Selection& rSelection, sal_Bool bPaint )
             if ( aNew != maSelection )
             {
                 ImplClearLayoutData();
+                Selection aTemp = maSelection;
                 maSelection = aNew;
 
                 if ( bPaint && ( aOld.Len() || aNew.Len() || IsPaintTransparent() ) )
                     ImplInvalidateOrRepaint( 0, maText.getLength() );
                 ImplShowCursor();
-                if ( mbIsSubEdit )
-                    ((Edit*)GetParent())->ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED );
-                else
-                    ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED );
+
+                sal_Bool bCaret = sal_False, bSelection = sal_False;
+                long nB=aNew.Max(), nA=aNew.Min(),oB=aTemp.Max(), oA=aTemp.Min();
+                long nGap = nB-nA, oGap = oB-oA;
+                if (nB != oB)
+                    bCaret = sal_True;
+                if (nGap != 0 || oGap != 0)
+                    bSelection = sal_True;
+                if (bCaret)
+                {
+                    if ( mbIsSubEdit )
+                        ((Edit*)GetParent())->ImplCallEventListeners( VCLEVENT_EDIT_CARETCHANGED );
+                    else
+                        ImplCallEventListeners( VCLEVENT_EDIT_CARETCHANGED );
+                }
+                if (bSelection)
+                {
+                    if ( mbIsSubEdit )
+                        ((Edit*)GetParent())->ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED );
+                    else
+                        ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED );
+                }
+
                 // #103511# notify combobox listeners of deselection
                 if( !maSelection && GetParent() && GetParent()->GetType() == WINDOW_COMBOBOX )
                     ((Edit*)GetParent())->ImplCallEventListeners( VCLEVENT_COMBOBOX_DESELECT );
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index fa9c277..e15898d 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -929,7 +929,8 @@ void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
 
                 mnCurrentPos = nSelect;
                 mbTrackingSelect = true;
-                SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() );
+                sal_Bool bCurPosChange = (mnCurrentPos != nSelect);
+                SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ,bCurPosChange);
                 mbTrackingSelect = false;
                 if ( mbGrabFocus )
                     GrabFocus();
@@ -1000,6 +1001,12 @@ void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
                             ImplCallSelect();
                             mbTravelSelect = false;
                         }
+                        // When list box selection change by mouse move, notity
+                        // VCLEVENT_LISTBOX_SELECT vcl event.
+                        else
+                        {
+                            maListItemSelectHdl.Call(NULL);
+                        }
                     }
                     mbTrackingSelect = false;
                 }
@@ -1087,7 +1094,7 @@ void ImplListBoxWindow::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
 
 // -----------------------------------------------------------------------
 
-sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl )
+sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl, sal_Bool bSelectPosChange /*=FALSE*/ )
 {
     bool bFocusChanged = false;
     sal_Bool bSelectionChanged = sal_False;
@@ -1232,6 +1239,10 @@ sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLE
             maFocusRect.SetSize( aSz );
             if( HasFocus() )
                 ImplShowFocusRect();
+            if (bSelectPosChange)
+            {
+                maFocusHdl.Call(reinterpret_cast<void*>(nSelect));
+            }
         }
         ImplClearLayoutData();
     }
@@ -1690,8 +1701,9 @@ sal_Bool ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
         DBG_ASSERT( !mpEntryList->IsEntryPosSelected( nSelect ) || mbMulti, "ImplListBox: Selecting same Entry" );
         if( nSelect >= mpEntryList->GetEntryCount() )
             nSelect = mpEntryList->GetEntryCount()-1;
+        sal_Bool bCurPosChange = (mnCurrentPos != nSelect);
         mnCurrentPos = nSelect;
-        if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) )
+        if(SelectEntries( nSelect, eLET, bShift, bCtrl, bCurPosChange))
         {
             mbTravelSelect = true;
             mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
@@ -2159,12 +2171,11 @@ Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_uInt16 nItem ) const
 {
     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
     Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
-    long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() );
+    long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) + GetEntryList()->GetMRUCount()*GetEntryHeight();
     Rectangle aRect( Point( 0, nY ), aSz );
     return aRect;
 }
 
-
 // -----------------------------------------------------------------------
 
 void ImplListBoxWindow::StateChanged( StateChangedType nType )
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index b1e5df0..fe358ae 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -162,6 +162,8 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle )
     mpImplLB->SetCancelHdl( LINK( this, ListBox, ImplCancelHdl ) );
     mpImplLB->SetDoubleClickHdl( LINK( this, ListBox, ImplDoubleClickHdl ) );
     mpImplLB->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) );
+    mpImplLB->SetFocusHdl( LINK( this, ListBox, ImplFocusHdl ) );
+    mpImplLB->SetListItemSelectHdl( LINK( this, ListBox, ImplListItemSelectHdl ) );
     mpImplLB->SetPosPixel( Point() );
     mpImplLB->SetEdgeBlending(GetEdgeBlending());
     mpImplLB->Show();
@@ -239,6 +241,18 @@ IMPL_LINK_NOARG(ListBox, ImplSelectHdl)
     return 1;
 }
 
+IMPL_LINK( ListBox, ImplFocusHdl, void *, nPos )
+{
+    ImplCallEventListeners( VCLEVENT_LISTBOX_FOCUS , nPos);
+    return 1;
+}
+
+IMPL_LINK( ListBox, ImplListItemSelectHdl, void*, EMPTYARG )
+{
+    ImplCallEventListeners( VCLEVENT_LISTBOX_SELECT );
+    return 1;
+}
+
 
 IMPL_LINK_NOARG(ListBox, ImplScrollHdl)
 {
@@ -1013,6 +1027,7 @@ void ListBox::SetNoSelection()
         mpImplWin->SetImage( aImage );
         mpImplWin->Invalidate();
     }
+    ImplCallEventListeners(VCLEVENT_LISTBOX_STATEUPDATE);
 }
 
 
@@ -1131,7 +1146,20 @@ void ListBox::SelectEntry( const OUString& rStr, sal_Bool bSelect )
 void ListBox::SelectEntryPos( sal_uInt16 nPos, sal_Bool bSelect )
 {
     if ( nPos < mpImplLB->GetEntryList()->GetEntryCount() )
+    {
+        sal_uInt16 oldSelectCount = GetSelectEntryCount(), newSelectCount = 0, nCurrentPos = mpImplLB->GetCurrentPos();
         mpImplLB->SelectEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), bSelect );
+        newSelectCount = GetSelectEntryCount();
+        if (oldSelectCount == 0 && newSelectCount > 0)
+            ImplCallEventListeners(VCLEVENT_LISTBOX_STATEUPDATE);
+        //Only when bSelect == true, send both Selection & Focus events
+        if (nCurrentPos != nPos && bSelect)
+        {
+            ImplCallEventListeners( VCLEVENT_LISTBOX_SELECT, reinterpret_cast<void*>(nPos));
+            if (HasFocus())
+                ImplCallEventListeners( VCLEVENT_LISTBOX_FOCUS, reinterpret_cast<void*>(nPos));
+        }
+    }
 }
 
 
@@ -1538,6 +1566,11 @@ void ListBox::SetEdgeBlending(bool bNew)
     }
 }
 
+sal_uInt16 ListBox::GetMRUCount() const
+{
+    return mpImplLB->GetEntryList()->GetMRUCount();
+}
+
 // =======================================================================
 MultiListBox::MultiListBox( Window* pParent, WinBits nStyle ) :
     ListBox( WINDOW_MULTILISTBOX )
diff --git a/vcl/source/control/morebtn.cxx b/vcl/source/control/morebtn.cxx
index 0e69776..c1cc320 100644
--- a/vcl/source/control/morebtn.cxx
+++ b/vcl/source/control/morebtn.cxx
@@ -127,9 +127,6 @@ void MoreButton::Click()
     mbState = !mbState;
     ShowState();
 
-    // Call Click handler here, so that we can initialize the Controls
-    PushButton::Click();
-
     // Update the windows according to the status
     if ( mbState )
     {
@@ -170,6 +167,8 @@ void MoreButton::Click()
             }
         }
     }
+    // Call Click handler here, so that we can initialize the Controls
+    PushButton::Click();
 }
 
 void MoreButton::AddWindow( Window* pWindow )
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 93ee0cd..640af54 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -702,6 +702,7 @@ void TabControl::ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId )
         }
 
         pPage->ActivatePage();
+        pPage->Show();
 
         if ( pOldPage && pOldPage->HasChildPathFocus() )
         {
@@ -712,8 +713,6 @@ void TabControl::ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId )
             else
                 GrabFocus();
         }
-
-        pPage->Show();
     }
 
     if ( pOldPage )
diff --git a/vcl/source/window/btndlg.cxx b/vcl/source/window/btndlg.cxx
index 84694be..212b5c6 100644
--- a/vcl/source/window/btndlg.cxx
+++ b/vcl/source/window/btndlg.cxx
@@ -231,11 +231,16 @@ void ButtonDialog::StateChanged( StateChangedType nType )
     if ( nType == STATE_CHANGE_INITSHOW )
     {
         ImplPosControls();
+        for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
+        {
+            if ( it->mpPushButton && it->mbOwnButton )
+                it->mpPushButton->SetZOrder(0, WINDOW_ZORDER_LAST);
+        }
 
         // Set focus on default button.
         if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
         {
-            for ( btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
+            for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
             {
                 if (it->mnId == mnFocusButtonId )
                 {
diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx
index 6da32aa..29f02ea 100644
--- a/vcl/source/window/dlgctrl.cxx
+++ b/vcl/source/window/dlgctrl.cxx
@@ -541,7 +541,13 @@ namespace
 {
     bool isSuitableDestination(Window *pWindow)
     {
-        return (pWindow && isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled());
+        return (pWindow && isVisibleInLayout(pWindow) &&
+                isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() &&
+                //Pure window shouldn't get window after controls such as
+                //buttons.
+                (pWindow->GetType() != WINDOW_WINDOW && pWindow->GetType() != WINDOW_SYSWINDOW &&
+                  pWindow->GetType() != WINDOW_WORKWINDOW && pWindow->GetType() != WINDOW_CONTROL)
+               );
     }
 
     bool focusNextInGroup(std::vector<RadioButton*>::iterator aStart, std::vector<RadioButton*> &rGroup)
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 4a3e784..2a83c97 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -1577,6 +1577,36 @@ MenuItemType Menu::GetItemType( sal_uInt16 nPos ) const
         return MENUITEM_DONTKNOW;
 }
 
+void Menu::SetHightlightItem( sal_uInt16 nItem )
+{
+    nHighlightedItem = nItem;
+}
+
+sal_uInt16 Menu::GetHighlightItem() const
+{
+    return nHighlightedItem;
+}
+
+OUString Menu::GetItemAccKeyStrFromPos(sal_uInt16 nPos) const
+{
+    MenuItemData* pData = pItemList->GetDataFromPos( nPos );
+    if (pData)
+    {
+        return pData->aAccelKey.GetName();
+    }
+    return OUString();
+}
+
+sal_Bool Menu::IsTemporaryItemFromPos(sal_uInt16 nPos ) const
+{
+    MenuItemData* pData = pItemList->GetDataFromPos( nPos );
+    if (pData)
+    {
+        return pData->bIsTemporary;
+    }
+    return sal_False;
+}
+
 sal_uInt16 Menu::GetCurItemId() const
 {
     return nSelectedId;
@@ -2981,12 +3011,12 @@ Menu* Menu::ImplGetStartMenu()
     return pStart;
 }
 
-void Menu::ImplCallHighlight( sal_uInt16 nHighlightedItem )
+void Menu::ImplCallHighlight(sal_uInt16 nItem)
 {
     ImplMenuDelData aDelData( this );
 
     nSelectedId = 0;
-    MenuItemData* pData = pItemList->GetDataFromPos( nHighlightedItem );
+    MenuItemData* pData = pItemList->GetDataFromPos(nItem);
     if ( pData )
         nSelectedId = pData->nId;
     ImplCallEventListeners( VCLEVENT_MENU_HIGHLIGHT, GetItemPos( GetCurItemId() ) );
@@ -3666,7 +3696,10 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong
             OUString aTmpEntryText( ResId( SV_RESID_STRING_NOSELECTIONPOSSIBLE, *pResMgr ) );
             MenuItemData* pData = pItemList->Insert(
                 0xFFFF, MENUITEM_STRING, 0, aTmpEntryText, Image(), NULL, 0xFFFF, OString() );
-                pData->bIsTemporary = true;
+            size_t nPos;
+            pData = pItemList->GetData( pData->nId, nPos );
+            pData->bIsTemporary = true;
+            ImplCallEventListeners(VCLEVENT_MENU_SUBMENUCHANGED, nPos);
         }
     }
     else if ( Application::GetSettings().GetStyleSettings().GetAutoMnemonic() && !( nMenuFlags & MENU_FLAG_NOAUTOMNEMONICS ) )
@@ -3978,7 +4011,7 @@ void MenuFloatingWindow::doShutdown()
         // otherwise the entry will not be read when the menu is opened again
         if( nHighlightedItem != ITEMPOS_INVALID )
             pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
-
+        pMenu->SetHightlightItem(ITEMPOS_INVALID);
         if( !bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->bIsMenuBar )
         {
             // #102461# remove highlight in parent
@@ -4631,6 +4664,7 @@ void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, sal_Bool bStartPopup
             }
         }
         HighlightItem( nHighlightedItem, sal_True );
+        pMenu->SetHightlightItem(nHighlightedItem);
         pMenu->ImplCallHighlight( nHighlightedItem );
     }
     else
@@ -4931,6 +4965,8 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
                     MenuFloatingWindow* pFloat = ((PopupMenu*)pMenu->pStartedFrom)->ImplGetFloatingWindow();
                     pFloat->GrabFocus();
                     pFloat->KillActivePopup();
+                    sal_uInt16 highlightItem = pFloat->GetHighlightedItem();
+                    pFloat->ChangeHighlightItem(highlightItem, sal_False);
                 }
             }
         }
@@ -5534,8 +5570,8 @@ void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, sal_Bool bSelectEntry, sa
         HighlightItem( nHighlightedItem, sal_True );
     else if ( nRolloveredItem != ITEMPOS_INVALID )
         HighlightItem( nRolloveredItem, sal_True );
-
-    pMenu->ImplCallHighlight( nHighlightedItem );
+    pMenu->SetHightlightItem(nHighlightedItem);
+    pMenu->ImplCallHighlight(nHighlightedItem);
 
     if( mbAutoPopup )
         ImplCreatePopup( bSelectEntry );
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index 7a3e0a4..4d555a3 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -5423,7 +5423,10 @@ void ToolBox::ImplChangeHighlight( ImplToolItem* pItem, sal_Bool bNoGrabFocus )
                 mnCurPos = aPos;
             ImplShowFocus();
 
-            ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
+            if( pItem->mpWindow )
+                pItem->mpWindow->GrabFocus();
+            if( pItem != pOldItem )
+                ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
         }
     }
     else
diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
index 62544c6..4d0de02 100644
--- a/vcl/source/window/toolbox2.cxx
+++ b/vcl/source/window/toolbox2.cxx
@@ -1691,7 +1691,8 @@ void ToolBox::SetItemState( sal_uInt16 nItemId, TriState eState )
             ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
 
             // Notify
-            ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK, reinterpret_cast< void* >( nPos ) );
+            //Solution:Call accessible listener to notify state_changed event
+            ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMUPDATED, reinterpret_cast< void* >(nPos) );
         }
     }
 }
commit 57917b0c136520b478299f581bcd99ad5610c203
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Nov 25 13:16:18 2013 +0000

    this is the same condition as isSuitableDestination
    
    Change-Id: I540108793c845c9eb52e59ac0655f7c51492766c

diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx
index 7a4946d..6da32aa 100644
--- a/vcl/source/window/dlgctrl.cxx
+++ b/vcl/source/window/dlgctrl.cxx
@@ -878,7 +878,7 @@ sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput )
 
                         nStyle = pWindow->GetStyle();
 
-                        if ( isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() )
+                        if (isSuitableDestination(pWindow))
                         {
                             if ( pWindow != pSWindow )
                                 pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
commit 7ad1c4356bfde3bf37830fa8e4b3267212473f79
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Nov 25 15:00:21 2013 +0100

    dbaccess: improve exception message when no driver found
    
    Change-Id: I1734034e05324eb0d66fd52444b0521d4143bc12

diff --git a/dbaccess/source/core/dataaccess/datasource.cxx b/dbaccess/source/core/dataaccess/datasource.cxx
index 83bb45e..cd349b7 100644
--- a/dbaccess/source/core/dataaccess/datasource.cxx
+++ b/dbaccess/source/core/dataaccess/datasource.cxx
@@ -735,7 +735,8 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
 
     if ( !xReturn.is() )
     {
-        OUString sMessage = DBACORE_RESSTRING( nExceptionMessageId );
+        OUString sMessage = DBACORE_RESSTRING( nExceptionMessageId )
+            .replaceAll("$name$", m_pImpl->m_sConnectURL);
 
         SQLContext aContext;
         aContext.Message = DBACORE_RESSTRING(RID_STR_CONNECTION_REQUEST).
diff --git a/dbaccess/source/core/resource/strings.src b/dbaccess/source/core/resource/strings.src
index a6eb1fe..a2099c1 100644
--- a/dbaccess/source/core/resource/strings.src
+++ b/dbaccess/source/core/resource/strings.src
@@ -47,7 +47,7 @@ String RID_STR_COULDNOTCONNECT_UNSPECIFIED
 
 String RID_STR_COULDNOTCONNECT_NODRIVER
 {
-    Text [ en-US ] = "The connection to the external data source could not be established. No SDBC driver was found for the given URL.";
+    Text [ en-US ] = "The connection to the external data source could not be established. No SDBC driver was found for the URL '$name$'.";
 };
 
 String RID_STR_COULDNOTLOAD_MANAGER
commit 32f700a683b7faa17c58e6d1aad85915ebd40a1a
Author: Muthu Subramanian <sumuthu at collabora.com>
Date:   Mon Nov 25 19:39:20 2013 +0530

    fdo#68594: Adding unit test.

diff --git a/sd/qa/unit/data/ppt/fdo68594.ppt b/sd/qa/unit/data/ppt/fdo68594.ppt
new file mode 100644
index 0000000..83a95cd
Binary files /dev/null and b/sd/qa/unit/data/ppt/fdo68594.ppt differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 23ddec3..bd65a30 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -15,6 +15,8 @@
 #include <editeng/ulspitem.hxx>
 #include <editeng/fhgtitem.hxx>
 #include <editeng/escapementitem.hxx>
+#include <editeng/colritem.hxx>
+#include <rsc/rscsfx.hxx>
 
 #include <svx/svdotext.hxx>
 #include <animations/animationnodehelper.hxx>
@@ -47,6 +49,7 @@ public:
     void testFdo64512();
     void testFdo71075();
     void testN828390();
+    void testFdo68594();
 
     CPPUNIT_TEST_SUITE(SdFiltersTest);
     CPPUNIT_TEST(testDocumentLayout);
@@ -56,6 +59,7 @@ public:
     CPPUNIT_TEST(testFdo64512);
     CPPUNIT_TEST(testFdo71075);
     CPPUNIT_TEST(testN828390);
+    CPPUNIT_TEST(testFdo68594);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -240,6 +244,25 @@ void SdFiltersTest::testN778859()
     }
 }
 
+void SdFiltersTest::testFdo68594()
+{
+    ::sd::DrawDocShellRef xDocShRef = loadURL(getURLFromSrc("/sd/qa/unit/data/ppt/fdo68594.ppt"));
+    CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef.Is() );
+    CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef->IsInDestruction() );
+
+    SdDrawDocument *pDoc = xDocShRef->GetDoc();
+    CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != NULL );
+    const SdrPage *pPage = &(pDoc->GetPage (1)->TRG_GetMasterPage());
+    CPPUNIT_ASSERT_MESSAGE( "no page", pPage != NULL );
+    SdrObject *pObj = pPage->GetObj(1);
+    SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+    CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != NULL);
+    const SvxColorItem *pC = dynamic_cast<const SvxColorItem *>(&pTxtObj->GetMergedItem(EE_CHAR_COLOR));
+    CPPUNIT_ASSERT_MESSAGE( "no color item", pC != NULL);
+    // Color should be black
+    CPPUNIT_ASSERT_MESSAGE( "Placeholder color mismatch", pC->GetValue().GetColor() == 0);
+}
+
 void SdFiltersTest::testFdo64512()
 {
     ::sd::DrawDocShellRef xDocShRef = loadURL(getURLFromSrc("/sd/qa/unit/data/fdo64512.odp"));
commit 20f9413f17d397c7b097809d8c168a0a78e6c084
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Mon Nov 25 11:45:05 2013 +0100

    EMF+: Parse custom line cap data for start and end line caps.
    
    Change-Id: I3a5f79e22500f53c3c61c173e0827c250b2a8fd0

diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index ec5e739..69568d3 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -97,6 +97,12 @@ const sal_Int32 EmfPlusLineStyleDashDot = 0x00000003;
 const sal_Int32 EmfPlusLineStyleDashDotDot = 0x00000004;
 const sal_Int32 EmfPlusLineStyleCustom = 0x00000005;
 
+const sal_uInt32 EmfPlusCustomLineCapDataTypeDefault = 0x00000000;
+const sal_uInt32 EmfPlusCustomLineCapDataTypeAdjustableArrow = 0x00000001;
+
+const sal_uInt32 EmfPlusCustomLineCapDataFillPath = 0x00000001;
+const sal_uInt32 EmfPlusCustomLineCapDataLinePath = 0x00000002;
+
 using namespace ::com::sun::star;
 using namespace ::basegfx;
 
@@ -588,6 +594,94 @@ namespace cppcanvas
             }
         };
 
+        struct EMFPCustomLineCap : public EMFPObject
+        {
+            sal_uInt32 type;
+
+        public:
+            EMFPCustomLineCap() : EMFPObject()
+            {
+            }
+
+            ~EMFPCustomLineCap()
+            {
+            }
+
+            void Read (SvStream& s, ImplRenderer& rR)
+            {
+                sal_uInt32 header;
+
+                s >> header >> type;
+
+                SAL_INFO("cppcanvas.emf", "EMF+\t\tcustom cap");
+                SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << header << " type: " << type << std::dec);
+
+                if (type == EmfPlusCustomLineCapDataTypeDefault)
+                {
+                    sal_Int32 customLineCapDataFlags, baseCap, baseInset;
+                    sal_Int32 strokeStartCap, strokeEndCap, strokeJoin;
+                    sal_Int32 strokeMiterLimit, widthScale;
+                    float fillHotSpotX, fillHotSpotY, strokeHotSpotX, strokeHotSpotY;
+
+                    s >> customLineCapDataFlags >> baseCap >> baseInset
+                      >> strokeStartCap >> strokeEndCap >> strokeJoin
+                      >> strokeMiterLimit >> widthScale
+                      >> fillHotSpotX >> fillHotSpotY >> strokeHotSpotX >> strokeHotSpotY;
+
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomLinCapDataFlags: 0x" << std::hex << customLineCapDataFlags);
+
+                    if (customLineCapDataFlags & EmfPlusCustomLineCapDataFillPath)
+                    {
+                        sal_Int32 pathLength;
+                        s >> pathLength;
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\tpath length: " << pathLength);
+
+                        sal_uInt32 pathHeader;
+                        sal_Int32 pathPoints, pathFlags;
+                        s >> pathHeader >> pathPoints >> pathFlags;
+
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\tpath (custom cap fill path)");
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec );
+
+                        EMFPPath path(pathPoints);
+                        path.Read(s, pathFlags, rR);
+                    }
+
+                    if (customLineCapDataFlags & EmfPlusCustomLineCapDataLinePath)
+                    {
+                        sal_Int32 pathLength;
+                        s >> pathLength;
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\tpath length: " << pathLength);
+
+                        sal_uInt32 pathHeader;
+                        sal_Int32 pathPoints, pathFlags;
+                        s >> pathHeader >> pathPoints >> pathFlags;
+
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\tpath (custom cap line path)");
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec );
+
+                        EMFPPath path(pathPoints);
+                        path.Read(s, pathFlags, rR);
+                    }
+                }
+                else if (type == EmfPlusCustomLineCapDataTypeAdjustableArrow)
+                {
+                    // TODO only reads the data, does not use them [I've had
+                    // no test document to be able to implement it]
+
+                    sal_Int32 width, height, middleInset, fillState, lineStartCap;
+                    sal_Int32 lineEndCap, lineJoin, lineMiterLimit, widthScale;
+                    float fillHotSpotX, fillHotSpotY, lineHotSpotX, lineHotSpotY;
+
+                    s >> width >> height >> middleInset >> fillState >> lineStartCap
+                      >> lineEndCap >> lineJoin >> lineMiterLimit >> widthScale
+                      >> fillHotSpotX >> fillHotSpotY >> lineHotSpotX >> lineHotSpotY;
+
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tTODO - actually read EmfPlusCustomLineCapArrowData object (section 2.2.2.12)");
+                }
+            }
+        };
+
         struct EMFPPen : public EMFPBrush
         {
             XForm transformation;
@@ -605,9 +699,9 @@ namespace cppcanvas
             sal_Int32 compoundArrayLen;
             float *compoundArray;
             sal_Int32 customStartCapLen;
-            sal_uInt8 *customStartCap;
+            EMFPCustomLineCap *customStartCap;
             sal_Int32 customEndCapLen;
-            sal_uInt8 *customEndCap;
+            EMFPCustomLineCap *customEndCap;
 
         public:
             EMFPPen () : EMFPBrush ()
@@ -622,8 +716,8 @@ namespace cppcanvas
             {
                 delete[] dashPattern;
                 delete[] compoundArray;
-                delete[] customStartCap;
-                delete[] customEndCap;
+                delete customStartCap;
+                delete customEndCap;
             }
 
             void SetStrokeWidth(rendering::StrokeAttributes& rStrokeAttributes, ImplRenderer& rR, const OutDevState& rState)
@@ -762,15 +856,13 @@ namespace cppcanvas
                 {
                     s >> customStartCapLen;
                     SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomStartCapLen: " << customStartCapLen);
+                    sal_uInt32 pos = s.Tell();
 
-                    if( customStartCapLen<0 )
-                        customStartCapLen=0;
-                    customStartCap = new sal_uInt8 [customStartCapLen];
-                    for (i = 0; i < customStartCapLen; i++)
-                    {
-                        s >> customStartCap [i];
-                        SAL_INFO("cppcanvas.emf", "EMF+\t\t\tcustomStartCap[" << i << "]: 0x" << std::hex << int(customStartCap[i]));
-                    }
+                    customStartCap = new EMFPCustomLineCap();
+                    customStartCap->Read(s, rR);
+
+                    // maybe we don't read everything yet, play it safe ;-)
+                    s.Seek(pos + customStartCapLen);
                 }
                 else
                     customStartCapLen = 0;
@@ -779,15 +871,13 @@ namespace cppcanvas
                 {
                     s >> customEndCapLen;
                     SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomEndCapLen: " << customEndCapLen);
+                    sal_uInt32 pos = s.Tell();
 
-                    if( customEndCapLen<0 )
-                        customEndCapLen=0;
-                    customEndCap = new sal_uInt8 [customEndCapLen];
-                    for (i = 0; i < customEndCapLen; i++)
-                    {
-                        s >> customEndCap [i];
-                        SAL_INFO("cppcanvas.emf", "EMF+\t\t\tcustomEndCap[" << i << "]: 0x" << std::hex << int(customEndCap[i]));
-                    }
+                    customEndCap = new EMFPCustomLineCap();
+                    customEndCap->Read(s, rR);
+
+                    // maybe we don't read everything yet, play it safe ;-)
+                    s.Seek(pos + customEndCapLen);
                 }
                 else
                     customEndCapLen = 0;
commit 172acd5bea74e3f5889833437410538008bcf89a
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Nov 22 17:06:10 2013 +0100

    EMF+: Small cleanup & more logging in preparation for line starts & ends.
    
    Change-Id: I584f8a1680c6aa7b51b948a00213c285387b77c3

diff --git a/cppcanvas/source/inc/implrenderer.hxx b/cppcanvas/source/inc/implrenderer.hxx
index c70bf54..02fc003 100644
--- a/cppcanvas/source/inc/implrenderer.hxx
+++ b/cppcanvas/source/inc/implrenderer.hxx
@@ -280,7 +280,7 @@ static float GetSwapFloat( SvStream& rSt )
             /* EMF+ */
             void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
             double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
-            void EMFPPlusDrawPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex);
+            void EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex);
             void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
 
             ActionVector maActions;
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 9dc50d7..ec5e739 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -28,6 +28,7 @@
 #include <basegfx/vector/b2dsize.hxx>
 #include <basegfx/range/b2drange.hxx>
 #include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
@@ -625,7 +626,7 @@ namespace cppcanvas
                 delete[] customEndCap;
             }
 
-            void SetStrokeAttributes (rendering::StrokeAttributes& rStrokeAttributes, ImplRenderer& rR, const OutDevState& rState)
+            void SetStrokeWidth(rendering::StrokeAttributes& rStrokeAttributes, ImplRenderer& rR, const OutDevState& rState)
             {
 #if OSL_DEBUG_LEVEL > 1
                 if (width == 0.0) {
@@ -633,8 +634,10 @@ namespace cppcanvas
                 }
 #endif
                 rStrokeAttributes.StrokeWidth = fabs((rState.mapModeTransform * rR.MapSize (width == 0.0 ? 0.05 : width, 0)).getX());
+            }
 
-                // set dashing
+            void SetStrokeDashing(rendering::StrokeAttributes& rStrokeAttributes)
+            {
                 if (dashStyle != EmfPlusLineStyleSolid)
                 {
                     const float dash[] = {3, 3};
@@ -678,12 +681,18 @@ namespace cppcanvas
                     s >> transformation;
 
                 if (penFlags & 2)
+                {
                     s >> startCap;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tstartCap: 0x" << std::hex << startCap);
+                }
                 else
                     startCap = 0;
 
                 if (penFlags & 4)
+                {
                     s >> endCap;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tendCap: 0x" << std::hex << endCap);
+                }
                 else
                     endCap = 0;
 
@@ -749,24 +758,38 @@ namespace cppcanvas
                 } else
                     compoundArrayLen = 0;
 
-                if (penFlags & 2048) {
+                if (penFlags & 2048)
+                {
                     s >> customStartCapLen;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomStartCapLen: " << customStartCapLen);
+
                     if( customStartCapLen<0 )
                         customStartCapLen=0;
                     customStartCap = new sal_uInt8 [customStartCapLen];
                     for (i = 0; i < customStartCapLen; i++)
+                    {
                         s >> customStartCap [i];
-                } else
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\t\tcustomStartCap[" << i << "]: 0x" << std::hex << int(customStartCap[i]));
+                    }
+                }
+                else
                     customStartCapLen = 0;
 
-                if (penFlags & 4096) {
+                if (penFlags & 4096)
+                {
                     s >> customEndCapLen;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomEndCapLen: " << customEndCapLen);
+
                     if( customEndCapLen<0 )
                         customEndCapLen=0;
                     customEndCap = new sal_uInt8 [customEndCapLen];
                     for (i = 0; i < customEndCapLen; i++)
+                    {
                         s >> customEndCap [i];
-                } else
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\t\tcustomEndCap[" << i << "]: 0x" << std::hex << int(customEndCap[i]));
+                    }
+                }
+                else
                     customEndCapLen = 0;
 
                 EMFPBrush::Read (s, rR);
@@ -1151,7 +1174,7 @@ namespace cppcanvas
             }
         }
 
-        void ImplRenderer::EMFPPlusDrawPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
+        void ImplRenderer::EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
                                                 OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex)
         {
             EMFPPen* pen = (EMFPPen*) aObjects [penIndex & 0xff];
@@ -1165,22 +1188,24 @@ namespace cppcanvas
                 rState.lineColor = ::vcl::unotools::colorToDoubleSequence (pen->GetColor (),
                                                                            rCanvas->getUNOCanvas ()->getDevice()->getDeviceColorSpace());
 
-                polygon.transform( rState.mapModeTransform );
-                rendering::StrokeAttributes aStrokeAttributes;
+                basegfx::B2DPolyPolygon aPolyPolygon(polygon);
+                aPolyPolygon.transform(rState.mapModeTransform);
+                rendering::StrokeAttributes aCommonAttributes;
 
-                pen->SetStrokeAttributes (aStrokeAttributes, *this, rState);
+                // some attributes are common for the polygon, and the line
+                // starts & ends - like the stroke width
+                pen->SetStrokeWidth(aCommonAttributes, *this, rState);
 
-                ActionSharedPtr pPolyAction(
-                                            internal::PolyPolyActionFactory::createPolyPolyAction(
-                                                                                                  polygon, rParms.mrCanvas, rState, aStrokeAttributes ) );
+                // but eg. dashing has to be additionally set only on the
+                // polygon
+                rendering::StrokeAttributes aPolygonAttributes(aCommonAttributes);
+                pen->SetStrokeDashing(aPolygonAttributes);
 
+                // render the polygon
+                ActionSharedPtr pPolyAction(internal::PolyPolyActionFactory::createPolyPolyAction(aPolyPolygon, rParms.mrCanvas, rState, aPolygonAttributes));
                 if( pPolyAction )
                 {
-                    maActions.push_back(
-                                        MtfAction(
-                                                  pPolyAction,
-                                                  rParms.mrCurrActionIndex ) );
-
+                    maActions.push_back(MtfAction(pPolyAction, rParms.mrCurrActionIndex));
                     rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
                 }
             }
commit 40977516a515e21bc809a4d05f71be7dd481b1f7
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Nov 22 12:01:15 2013 +0100

    EMF+: Implement line dashing.
    
    Change-Id: I9eb21c0a8b5baa5b0080845f61b12fc65034d959

diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index be2bfbd..9dc50d7 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -89,6 +89,13 @@
 
 #define EmfPlusRegionInitialStateInfinite 0x10000003
 
+const sal_Int32 EmfPlusLineStyleSolid = 0x00000000;
+const sal_Int32 EmfPlusLineStyleDash = 0x00000001;
+const sal_Int32 EmfPlusLineStyleDot = 0x00000002;
+const sal_Int32 EmfPlusLineStyleDashDot = 0x00000003;
+const sal_Int32 EmfPlusLineStyleDashDotDot = 0x00000004;
+const sal_Int32 EmfPlusLineStyleCustom = 0x00000005;
+
 using namespace ::com::sun::star;
 using namespace ::basegfx;
 
@@ -626,6 +633,34 @@ namespace cppcanvas
                 }
 #endif
                 rStrokeAttributes.StrokeWidth = fabs((rState.mapModeTransform * rR.MapSize (width == 0.0 ? 0.05 : width, 0)).getX());
+
+                // set dashing
+                if (dashStyle != EmfPlusLineStyleSolid)
+                {
+                    const float dash[] = {3, 3};
+                    const float dot[] = {1, 3};
+                    const float dashdot[] = {3, 3, 1, 3};
+                    const float dashdotdot[] = {3, 3, 1, 3, 1, 3};
+
+                    sal_Int32 nLen = 0;
+                    const float *pPattern;
+                    switch (dashStyle)
+                    {
+                        case EmfPlusLineStyleDash:       nLen = SAL_N_ELEMENTS(dash); pPattern = dash; break;
+                        case EmfPlusLineStyleDot:        nLen = SAL_N_ELEMENTS(dot); pPattern = dot; break;
+                        case EmfPlusLineStyleDashDot:    nLen = SAL_N_ELEMENTS(dashdot); pPattern = dashdot; break;
+                        case EmfPlusLineStyleDashDotDot: nLen = SAL_N_ELEMENTS(dashdotdot); pPattern = dashdotdot; break;
+                        case EmfPlusLineStyleCustom:     nLen = dashPatternLen; pPattern = dashPattern; break;
+                    }
+                    if (nLen > 0)
+                    {
+                        uno::Sequence<double> aDashArray(nLen);
+                        for (int i = 0; i < nLen; ++i)
+                            aDashArray[i] = pPattern[i];
+
+                        rStrokeAttributes.DashArray = aDashArray;
+                    }
+                }
             }
 
             void Read (SvStream& s, ImplRenderer& rR, sal_Int32, sal_Int32 )
@@ -663,7 +698,10 @@ namespace cppcanvas
                     mitterLimit = 0;
 
                 if (penFlags & 32)
+                {
                     s >> dashStyle;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tdashStyle: 0x" << std::hex << dashStyle);
+                }
                 else
                     dashStyle = 0;
 
@@ -677,14 +715,23 @@ namespace cppcanvas
                 else
                     dashOffset = 0;
 
-                if (penFlags & 256) {
+                if (penFlags & 256)
+                {
+                    dashStyle = EmfPlusLineStyleCustom;
+
                     s >> dashPatternLen;
+                    SAL_INFO("cppcanvas.emf", "EMF+\t\tdashPatternLen: " << dashPatternLen);
+
                     if( dashPatternLen<0 || sal_uInt32(dashPatternLen)>SAL_MAX_INT32/sizeof(float) )
                         dashPatternLen = SAL_MAX_INT32/sizeof(float);
                     dashPattern = new float [dashPatternLen];
                     for (i = 0; i < dashPatternLen; i++)
+                    {
                         s >> dashPattern [i];
-                } else
+                        SAL_INFO("cppcanvas.emf", "EMF+\t\t\tdashPattern[" << i << "]: " << dashPattern[i]);
+                    }
+                }
+                else
                     dashPatternLen = 0;
 
                 if (penFlags & 512)
commit 4ba2b2ae62276ab7b40ba5730d631ad4b3fd6ac8
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Thu Nov 21 16:28:32 2013 +0100

    fdo#61272: Do the mapping correctly both for WMF and EMF.
    
    Turns out that for the WMF, we already had everything set up correctly, we
    were just overwriting the right settings with default data again :-) - fix
    that.
    
    Change-Id: I14b0c12b10f58eb7031f9da712dee76344c75159

diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index 54dca14..dd3b3b6 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -1972,7 +1972,7 @@ void WinMtfOutput::SetRefMill( const Size& rSize )
 void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
 {
     mnMapMode = nMapMode;
-    if ( nMapMode == MM_TEXT )
+    if ( nMapMode == MM_TEXT && !mbIsMapWinSet )
     {
         mnWinExtX = mnDevWidth;
         mnWinExtY = mnDevHeight;
commit 9d3c0aa1e64ae97ddc305df3873f977051f0b317
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Nov 20 21:17:50 2013 +0100

    Related fdo#61272: Revert "wmf-mm-text.diff: Fix WMF rendering, n#417818"
    
    This approach to WMF breaks EMF reading, need to revert it, and fix a
    different way.
    
    This reverts commit db1b08d217ebbdd1b0296e1da260bf314a77acf5.
    
    Conflicts:
    	vcl/source/filter/wmf/winmtf.cxx
    	vcl/source/filter/wmf/winmtf.hxx
    
    Change-Id: I8f779791153f2e1faa086c91b82b3e8b93304f3b

diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index e40809827..54dca14 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -340,14 +340,6 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
         {
             switch( mnMapMode )
             {
-                case MM_TEXT:
-                    fX2 -= mnWinOrgX;
-                    fY2 -= mnWinOrgY;
-                    fX2 *= 2540.0/mnUnitsPerInch;
-                    fY2 *= 2540.0/mnUnitsPerInch;
-                    fX2 += mnDevOrgX;
-                    fY2 += mnDevOrgY;
-                    break;
                 case MM_LOENGLISH :
                 {
                     fX2 -= mnWinOrgX;
@@ -433,10 +425,6 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
         {
             switch( mnMapMode )
             {
-                case MM_TEXT:
-                    fWidth *= 2540.0/mnUnitsPerInch;
-                    fHeight*= 2540.0/mnUnitsPerInch;
-                break;
                 case MM_LOENGLISH :
                 {
                     fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
@@ -873,7 +861,6 @@ WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
     mbComplexClip       ( false ),
     mnGfxMode           ( GM_COMPATIBLE ),
     mnMapMode           ( MM_TEXT ),
-    mnUnitsPerInch ( 96 ),
     mnDevOrgX           ( 0 ),
     mnDevOrgY           ( 0 ),
     mnDevWidth          ( 1 ),
@@ -1999,14 +1986,6 @@ void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
 
 
 
-void WinMtfOutput::SetUnitsPerInch( sal_uInt16 nUnitsPerInch )
-{
-    if( nUnitsPerInch != 0 )
-    mnUnitsPerInch = nUnitsPerInch;
-}
-
-
-
 void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
 {
     maXForm.eM11 = rXForm.eM11;
diff --git a/vcl/source/filter/wmf/winmtf.hxx b/vcl/source/filter/wmf/winmtf.hxx
index 163c9fc..9db9245 100644
--- a/vcl/source/filter/wmf/winmtf.hxx
+++ b/vcl/source/filter/wmf/winmtf.hxx
@@ -575,7 +575,6 @@ struct GDIObj
 
 class WinMtfOutput
 {
-
     WinMtfPathObj       aPathObj;
     WinMtfClipPath      aClipPath;
 
@@ -612,7 +611,6 @@ class WinMtfOutput
 
     sal_uInt32          mnGfxMode;
     sal_uInt32          mnMapMode;
-    sal_uInt16          mnUnitsPerInch;
 
     XForm               maXForm;
     sal_Int32           mnDevOrgX, mnDevOrgY;
@@ -666,7 +664,6 @@ public:
 
     sal_uInt32          GetMapMode() const { return mnMapMode; };
     void                SetMapMode( sal_uInt32 mnMapMode );
-    void                SetUnitsPerInch( sal_uInt16 nUnitsPerInch );
     void                SetWorldTransform( const XForm& rXForm );
     const XForm&        GetWorldTransform() const { return maXForm; }
     void                ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode );
diff --git a/vcl/source/filter/wmf/winwmf.cxx b/vcl/source/filter/wmf/winwmf.cxx
index ff97d10..f3cfaf2 100644
--- a/vcl/source/filter/wmf/winwmf.cxx
+++ b/vcl/source/filter/wmf/winwmf.cxx
@@ -1109,7 +1109,6 @@ sal_Bool WMFReader::ReadHeader()
         }
     }
 
-    pOut->SetUnitsPerInch( nUnitsPerInch );
     pOut->SetWinOrg( aPlaceableBound.TopLeft() );
     Size aWMFSize( labs( aPlaceableBound.GetWidth() ), labs( aPlaceableBound.GetHeight() ) );
     pOut->SetWinExt( aWMFSize );
commit 198b17dc5e182dfb2e5c930458764c7b3e6c914f
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Nov 20 21:11:24 2013 +0100

    Related fdo#61272: Revert "wmf-mm-text-1.diff: Fix WMF rendering, n#417818"
    
    This approach to WMF breaks EMF reading, need to revert it, and fix a
    different way.
    
    This reverts commit 16eaa5e7c1208034bb3244fea9e6d9491ccb5501.
    
    Conflicts:
    	vcl/source/filter/wmf/winmtf.cxx
    
    Change-Id: I59076d0a65d91ba3a1f3ebb48d8f7a542859d351

diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index 4a0d027..e40809827 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -343,15 +343,10 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
                 case MM_TEXT:
                     fX2 -= mnWinOrgX;
                     fY2 -= mnWinOrgY;
-                    if( mnDevWidth != 1 || mnDevHeight != 1 ) {
-                        fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
-                        fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
-                    }
+                    fX2 *= 2540.0/mnUnitsPerInch;
+                    fY2 *= 2540.0/mnUnitsPerInch;
                     fX2 += mnDevOrgX;
                     fY2 += mnDevOrgY;
-                    fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
-                    fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
-
                     break;
                 case MM_LOENGLISH :
                 {
@@ -439,13 +434,8 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
             switch( mnMapMode )
             {
                 case MM_TEXT:
-                if( mnDevWidth != 1 && mnDevHeight != 1 ) {
-                    fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
-                    fHeight*= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
-                } else {
-                    fWidth *= (double)mnMillX * 100 / (double)mnPixX;
-                    fHeight *= (double)mnMillY * 100 / (double)mnPixY;
-                }
+                    fWidth *= 2540.0/mnUnitsPerInch;
+                    fHeight*= 2540.0/mnUnitsPerInch;
                 break;
                 case MM_LOENGLISH :
                 {
commit 5854f6c4e1fe0ddb64f74722222b2ddbceaad9d0
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Nov 19 11:36:23 2013 +0100

    EMF: More useful debugging output.
    
    Change-Id: I2aa0e97878db62275d794be43a7d351e5ae25f1c

diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
index 2e79081..3ad4481 100644
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ b/vcl/source/filter/wmf/enhwmf.cxx
@@ -1378,57 +1378,57 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
                 }
                 break;
 
-                default :                           WinMtfAssertHandler( "Unknown Meta Action" );       break;
-                case EMR_MASKBLT :                  WinMtfAssertHandler( "MaskBlt" );                   break;
-                case EMR_PLGBLT :                   WinMtfAssertHandler( "PlgBlt" );                    break;
-                case EMR_SETDIBITSTODEVICE :        WinMtfAssertHandler( "SetDIBitsToDevice" );         break;
-                case EMR_FRAMERGN :                 WinMtfAssertHandler( "FrameRgn" );                  break;
-                case EMR_INVERTRGN :                WinMtfAssertHandler( "InvertRgn" );                 break;
-                case EMR_PAINTRGN :                 WinMtfAssertHandler( "PaintRgn" );                  break;
-                case EMR_FLATTENPATH :              WinMtfAssertHandler( "FlattenPath" );               break;
-                case EMR_WIDENPATH :                WinMtfAssertHandler( "WidenPath" );                 break;
-                case EMR_POLYDRAW :                 WinMtfAssertHandler( "Polydraw" );                  break;
-                case EMR_SETARCDIRECTION :          WinMtfAssertHandler( "SetArcDirection" );           break;
-                case EMR_SETPALETTEENTRIES :        WinMtfAssertHandler( "SetPaletteEntries" );         break;
-                case EMR_RESIZEPALETTE :            WinMtfAssertHandler( "ResizePalette" );             break;
-                case EMR_EXTFLOODFILL :             WinMtfAssertHandler( "ExtFloodFill" );              break;
-                case EMR_ANGLEARC :                 WinMtfAssertHandler( "AngleArc" );                  break;
-                case EMR_SETCOLORADJUSTMENT :       WinMtfAssertHandler( "SetColorAdjustment" );        break;
-                case EMR_POLYDRAW16 :               WinMtfAssertHandler( "PolyDraw16" );                break;
-                case EMR_POLYTEXTOUTA :             WinMtfAssertHandler( "PolyTextOutA" );              break;
-                case EMR_POLYTEXTOUTW :             WinMtfAssertHandler( "PolyTextOutW" );              break;
-                case EMR_CREATECOLORSPACE :         WinMtfAssertHandler( "CreateColorSpace" );          break;
-                case EMR_SETCOLORSPACE :            WinMtfAssertHandler( "SetColorSpace" );             break;
-                case EMR_DELETECOLORSPACE :         WinMtfAssertHandler( "DeleteColorSpace" );          break;
-                case EMR_GLSRECORD :                WinMtfAssertHandler( "GlsRecord" );                 break;
-                case EMR_GLSBOUNDEDRECORD :         WinMtfAssertHandler( "GlsBoundRecord" );            break;
-                case EMR_PIXELFORMAT :              WinMtfAssertHandler( "PixelFormat" );               break;
-                case EMR_DRAWESCAPE :               WinMtfAssertHandler( "DrawEscape" );                break;
-                case EMR_EXTESCAPE :                WinMtfAssertHandler( "ExtEscape" );                 break;
-                case EMR_STARTDOC :                 WinMtfAssertHandler( "StartDoc" );                  break;
-                case EMR_SMALLTEXTOUT :             WinMtfAssertHandler( "SmallTextOut" );              break;
-                case EMR_FORCEUFIMAPPING :          WinMtfAssertHandler( "ForceUFIMapping" );           break;
-                case EMR_NAMEDESCAPE :              WinMtfAssertHandler( "NamedEscape" );               break;
-                case EMR_COLORCORRECTPALETTE :      WinMtfAssertHandler( "ColorCorrectPalette" );       break;
-                case EMR_SETICMPROFILEA :           WinMtfAssertHandler( "SetICMProfileA" );            break;
-                case EMR_SETICMPROFILEW :           WinMtfAssertHandler( "SetICMProfileW" );            break;
-                case EMR_TRANSPARENTBLT :           WinMtfAssertHandler( "TransparenBlt" );             break;
-                case EMR_TRANSPARENTDIB :           WinMtfAssertHandler( "TransparenDib" );             break;
-                case EMR_GRADIENTFILL :             WinMtfAssertHandler( "GradientFill" );              break;
-                case EMR_SETLINKEDUFIS :            WinMtfAssertHandler( "SetLinkedUFIS" );             break;
-
-                case EMR_SETMAPPERFLAGS :           WinMtfAssertHandler( "SetMapperFlags", 0 );         break;
-                case EMR_SETICMMODE :               WinMtfAssertHandler( "SetICMMode", 0 );             break;
-                case EMR_CREATEMONOBRUSH :          WinMtfAssertHandler( "CreateMonoBrush", 0 );        break;
-                case EMR_SETBRUSHORGEX :            WinMtfAssertHandler( "SetBrushOrgEx", 0 );          break;
-                case EMR_SETMETARGN :               WinMtfAssertHandler( "SetMetArgn", 0 );             break;
-                case EMR_SETMITERLIMIT :            WinMtfAssertHandler( "SetMiterLimit", 0 );          break;
-                case EMR_EXCLUDECLIPRECT :          WinMtfAssertHandler( "ExcludeClipRect", 0 );        break;
-                case EMR_REALIZEPALETTE :           WinMtfAssertHandler( "RealizePalette", 0 );         break;
-                case EMR_SELECTPALETTE :            WinMtfAssertHandler( "SelectPalette", 0 );          break;
-                case EMR_CREATEPALETTE :            WinMtfAssertHandler( "CreatePalette", 0 );          break;
-                case EMR_ALPHADIBBLEND :            WinMtfAssertHandler( "AlphaDibBlend", 0 );          break;
-                case EMR_SETTEXTJUSTIFICATION :     WinMtfAssertHandler( "SetTextJustification", 0 );   break;
+                default :                           SAL_INFO("vcl.emf", "Unknown Meta Action");                                     break;
+                case EMR_MASKBLT :                  SAL_INFO("vcl.emf", "not implemented '" << "MaskBlt" << "'");                   break;
+                case EMR_PLGBLT :                   SAL_INFO("vcl.emf", "not implemented '" << "PlgBlt" << "'");                    break;
+                case EMR_SETDIBITSTODEVICE :        SAL_INFO("vcl.emf", "not implemented '" << "SetDIBitsToDevice" << "'");         break;
+                case EMR_FRAMERGN :                 SAL_INFO("vcl.emf", "not implemented '" << "FrameRgn" << "'");                  break;
+                case EMR_INVERTRGN :                SAL_INFO("vcl.emf", "not implemented '" << "InvertRgn" << "'");                 break;
+                case EMR_PAINTRGN :                 SAL_INFO("vcl.emf", "not implemented '" << "PaintRgn" << "'");                  break;
+                case EMR_FLATTENPATH :              SAL_INFO("vcl.emf", "not implemented '" << "FlattenPath" << "'");               break;
+                case EMR_WIDENPATH :                SAL_INFO("vcl.emf", "not implemented '" << "WidenPath" << "'");                 break;
+                case EMR_POLYDRAW :                 SAL_INFO("vcl.emf", "not implemented '" << "Polydraw" << "'");                  break;
+                case EMR_SETARCDIRECTION :          SAL_INFO("vcl.emf", "not implemented '" << "SetArcDirection" << "'");           break;
+                case EMR_SETPALETTEENTRIES :        SAL_INFO("vcl.emf", "not implemented '" << "SetPaletteEntries" << "'");         break;
+                case EMR_RESIZEPALETTE :            SAL_INFO("vcl.emf", "not implemented '" << "ResizePalette" << "'");             break;
+                case EMR_EXTFLOODFILL :             SAL_INFO("vcl.emf", "not implemented '" << "ExtFloodFill" << "'");              break;
+                case EMR_ANGLEARC :                 SAL_INFO("vcl.emf", "not implemented '" << "AngleArc" << "'");                  break;
+                case EMR_SETCOLORADJUSTMENT :       SAL_INFO("vcl.emf", "not implemented '" << "SetColorAdjustment" << "'");        break;
+                case EMR_POLYDRAW16 :               SAL_INFO("vcl.emf", "not implemented '" << "PolyDraw16" << "'");                break;
+                case EMR_POLYTEXTOUTA :             SAL_INFO("vcl.emf", "not implemented '" << "PolyTextOutA" << "'");              break;
+                case EMR_POLYTEXTOUTW :             SAL_INFO("vcl.emf", "not implemented '" << "PolyTextOutW" << "'");              break;
+                case EMR_CREATECOLORSPACE :         SAL_INFO("vcl.emf", "not implemented '" << "CreateColorSpace" << "'");          break;
+                case EMR_SETCOLORSPACE :            SAL_INFO("vcl.emf", "not implemented '" << "SetColorSpace" << "'");             break;
+                case EMR_DELETECOLORSPACE :         SAL_INFO("vcl.emf", "not implemented '" << "DeleteColorSpace" << "'");          break;
+                case EMR_GLSRECORD :                SAL_INFO("vcl.emf", "not implemented '" << "GlsRecord" << "'");                 break;
+                case EMR_GLSBOUNDEDRECORD :         SAL_INFO("vcl.emf", "not implemented '" << "GlsBoundRecord" << "'");            break;
+                case EMR_PIXELFORMAT :              SAL_INFO("vcl.emf", "not implemented '" << "PixelFormat" << "'");               break;
+                case EMR_DRAWESCAPE :               SAL_INFO("vcl.emf", "not implemented '" << "DrawEscape" << "'");                break;
+                case EMR_EXTESCAPE :                SAL_INFO("vcl.emf", "not implemented '" << "ExtEscape" << "'");                 break;
+                case EMR_STARTDOC :                 SAL_INFO("vcl.emf", "not implemented '" << "StartDoc" << "'");                  break;
+                case EMR_SMALLTEXTOUT :             SAL_INFO("vcl.emf", "not implemented '" << "SmallTextOut" << "'");              break;
+                case EMR_FORCEUFIMAPPING :          SAL_INFO("vcl.emf", "not implemented '" << "ForceUFIMapping" << "'");           break;
+                case EMR_NAMEDESCAPE :              SAL_INFO("vcl.emf", "not implemented '" << "NamedEscape" << "'");               break;
+                case EMR_COLORCORRECTPALETTE :      SAL_INFO("vcl.emf", "not implemented '" << "ColorCorrectPalette" << "'");       break;
+                case EMR_SETICMPROFILEA :           SAL_INFO("vcl.emf", "not implemented '" << "SetICMProfileA" << "'");            break;
+                case EMR_SETICMPROFILEW :           SAL_INFO("vcl.emf", "not implemented '" << "SetICMProfileW" << "'");            break;
+                case EMR_TRANSPARENTBLT :           SAL_INFO("vcl.emf", "not implemented '" << "TransparenBlt" << "'");             break;
+                case EMR_TRANSPARENTDIB :           SAL_INFO("vcl.emf", "not implemented '" << "TransparenDib" << "'");             break;
+                case EMR_GRADIENTFILL :             SAL_INFO("vcl.emf", "not implemented '" << "GradientFill" << "'");              break;
+                case EMR_SETLINKEDUFIS :            SAL_INFO("vcl.emf", "not implemented '" << "SetLinkedUFIS" << "'");             break;
+
+                case EMR_SETMAPPERFLAGS :           SAL_INFO("vcl.emf", "not implemented '" << "SetMapperFlags" << "'");            break;
+                case EMR_SETICMMODE :               SAL_INFO("vcl.emf", "not implemented '" << "SetICMMode" << "'");                break;
+                case EMR_CREATEMONOBRUSH :          SAL_INFO("vcl.emf", "not implemented '" << "CreateMonoBrush" << "'");           break;
+                case EMR_SETBRUSHORGEX :            SAL_INFO("vcl.emf", "not implemented '" << "SetBrushOrgEx" << "'");             break;
+                case EMR_SETMETARGN :               SAL_INFO("vcl.emf", "not implemented '" << "SetMetArgn" << "'");                break;
+                case EMR_SETMITERLIMIT :            SAL_INFO("vcl.emf", "not implemented '" << "SetMiterLimit" << "'");             break;
+                case EMR_EXCLUDECLIPRECT :          SAL_INFO("vcl.emf", "not implemented '" << "ExcludeClipRect" << "'");           break;
+                case EMR_REALIZEPALETTE :           SAL_INFO("vcl.emf", "not implemented '" << "RealizePalette" << "'");            break;
+                case EMR_SELECTPALETTE :            SAL_INFO("vcl.emf", "not implemented '" << "SelectPalette" << "'");             break;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list