[Libreoffice-commits] core.git: 10 commits - basctl/source cppuhelper/source editeng/source include/vcl svl/source ucbhelper/source ucb/source vcl/inc vcl/quartz vcl/README vcl/source vcl/unx vcl/win xmlscript/source

Norbert Thiebaud nthiebaud at gmail.com
Thu Sep 11 16:47:32 PDT 2014


 basctl/source/basicide/baside2b.cxx                |   11 +
 cppuhelper/source/paths.cxx                        |   20 ++-
 editeng/source/outliner/outliner.cxx               |    2 
 include/vcl/outdev.hxx                             |    2 
 svl/source/numbers/zforscan.hxx                    |    2 
 ucb/source/ucp/webdav-neon/NeonSession.cxx         |    2 
 ucbhelper/source/client/proxydecider.cxx           |    4 
 vcl/README                                         |    8 +
 vcl/inc/graphite_layout.hxx                        |    2 
 vcl/inc/graphite_serverfont.hxx                    |    2 
 vcl/inc/sallayout.hxx                              |    6 -
 vcl/quartz/ctlayout.cxx                            |   10 -
 vcl/source/gdi/sallayout.cxx                       |   12 +-
 vcl/source/glyphs/graphite_layout.cxx              |    4 
 vcl/source/outdev/map.cxx                          |   25 ++++
 vcl/source/outdev/text.cxx                         |  117 +++++++++++++++++----
 vcl/source/window/builder.cxx                      |    6 -
 vcl/source/window/layout.cxx                       |    2 
 vcl/unx/generic/printer/ppdparser.cxx              |   12 +-
 vcl/win/source/gdi/winlayout.cxx                   |   22 +--
 xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx |    6 -
 21 files changed, 206 insertions(+), 71 deletions(-)

New commits:
commit f5d3114cc4b62f95bcd3ce3a5a1d859a69603269
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 19:05:19 2014 +0200

    vcl: protect against out-of-bound access of empty OUString
    
    Change-Id: If2671ba0547eb69fce7005f5427dcd175a5c29a2

diff --git a/vcl/unx/generic/printer/ppdparser.cxx b/vcl/unx/generic/printer/ppdparser.cxx
index 606fd55..e8e2a78 100644
--- a/vcl/unx/generic/printer/ppdparser.cxx
+++ b/vcl/unx/generic/printer/ppdparser.cxx
@@ -887,8 +887,14 @@ void PPDParser::parse( ::std::list< OString >& rLines )
         sal_Int32 nPos = aKey.indexOf('/');
         if (nPos != -1)
             aKey = aKey.copy(0, nPos);
-        aKey = aKey.copy(1); // remove the '*'
-
+        if(!aKey.isEmpty())
+        {
+            aKey = aKey.copy(1); // remove the '*'
+        }
+        if(aKey.isEmpty())
+        {
+            continue;
+        }
         if ((aKey == "CloseUI") ||
             (aKey == "JCLCloseUI") ||
             (aKey == "OpenGroup") ||
@@ -1245,7 +1251,7 @@ void PPDParser::parseConstraint( const OString& rLine )
     for( int i = 0; i < nTokens; i++ )
     {
         OUString aToken = GetCommandLineToken( i, aLine );
-        if( aToken[ 0 ] == '*' )
+        if( !aToken.isEmpty() && aToken[ 0 ] == '*' )
         {
             aToken = aToken.replaceAt( 0, 1, "" );
             if( aConstraint.m_pKey1 )
commit 5500c51e9bddcf3bb4356ac3e69f4df1043df6c9
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 19:00:14 2014 +0200

    harden access to OUString[0]
    
    Change-Id: Ibc2997f9974b8f6d561db0632642060ab95b80f0

diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 8db0652..8a36713 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -2807,7 +2807,7 @@ void VclBuilder::applyPackingProperty(Window *pCurrent,
 
             if (sKey == "expand")
             {
-                bool bTrue = (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1');
+                bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
                 if (pToolBoxParent)
                     pToolBoxParent->SetItemExpand(m_pParserState->m_nLastToolbarId, bTrue);
                 else
@@ -2820,12 +2820,12 @@ void VclBuilder::applyPackingProperty(Window *pCurrent,
 
             if (sKey == "fill")
             {
-                bool bTrue = (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1');
+                bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
                 pCurrent->set_fill(bTrue);
             }
             else if (sKey == "pack-type")
             {
-                VclPackType ePackType = (sValue[0] == 'e' || sValue[0] == 'E') ? VCL_PACK_END : VCL_PACK_START;
+                VclPackType ePackType = (!sValue.isEmpty() && (sValue[0] == 'e' || sValue[0] == 'E')) ? VCL_PACK_END : VCL_PACK_START;
                 pCurrent->set_pack_type(ePackType);
             }
             else if (sKey == "left-attach")
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index fb99034..d38c56b 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -1231,7 +1231,7 @@ void VclGrid::setAllocation(const Size& rAllocation)
 
 bool toBool(const OString &rValue)
 {
-    return (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1');
+    return (!rValue.isEmpty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
 }
 
 bool VclGrid::set_property(const OString &rKey, const OString &rValue)
commit 18fa868f1424c9f859181dac4b5212ed7cb7dd0f
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 18:47:08 2014 +0200

    svl: test lenght before access
    
    Change-Id: Ia0f41da43f150cd664dd9d4b5adef4e387253bf8

diff --git a/svl/source/numbers/zforscan.hxx b/svl/source/numbers/zforscan.hxx
index 914a553..a8492f0 100644
--- a/svl/source/numbers/zforscan.hxx
+++ b/svl/source/numbers/zforscan.hxx
@@ -236,7 +236,7 @@ private: // Private section
     bool InsertSymbol( sal_uInt16 & nPos, svt::NfSymbolType eType, const OUString& rStr );
 
     static inline bool StringEqualsChar( const OUString& rStr, sal_Unicode ch )
-        { return rStr[0] == ch && rStr.getLength() == 1; }
+        { return rStr.getLength() == 1 && rStr[0] == ch; }
         // Yes, for efficiency get the character first and then compare length
         // because in most places where this is used the string is one char.
 
commit 0439f66742b3b71e2a36c79a09e0943e51a37bde
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 18:44:37 2014 +0200

    xmlscript: avoid accessing [0] of an emptry string
    
    Change-Id: I2ad756b07418d3eb93f48374cd7de3bc3db9ce29

diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
index af40e4d..3aed222 100644
--- a/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
+++ b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
@@ -1064,7 +1064,11 @@ void TextFieldElement::endElement()
     if (getStringAttr( &aValue, "echochar", _xAttributes, _pImport->XMLNS_DIALOGS_UID ) && !aValue.isEmpty() )
     {
         SAL_WARN_IF( aValue.getLength() != 1, "xmlscript.xmldlg", "### more than one character given for echochar!" );
-        sal_Int16 nChar = (sal_Int16)aValue[ 0 ];
+        sal_Int16 nChar = 0;
+        if(!aValue.isEmpty())
+        {
+            nChar = (sal_Int16)aValue[ 0 ];
+        }
         xControlModel->setPropertyValue( "EchoChar", makeAny( nChar ) );
     }
 
commit 007864407b2aeb54ebd4c00eafae9f6e1adada39
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 18:34:52 2014 +0200

    ucb: prevent out of bound access in OUString
    
    Change-Id: I451bf13cbf39ec13152d083a6a6728cd043f9fbd

diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx
index ef073e0..f7c9811 100644
--- a/ucb/source/ucp/webdav-neon/NeonSession.cxx
+++ b/ucb/source/ucp/webdav-neon/NeonSession.cxx
@@ -2047,7 +2047,7 @@ OUString NeonSession::makeAbsoluteURL( OUString const & rURL ) const
     try
     {
         // Is URL relative or already absolute?
-        if ( rURL[ 0 ] != '/' )
+        if ( !rURL.isEmpty() && rURL[ 0 ] != '/' )
         {
             // absolute.
             return OUString( rURL );
commit 0db950ded89aa916fba40d27479a6722ec9a05c7
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 18:14:42 2014 +0200

    bug wrong order of test cause out of bound access.
    
    Change-Id: If9c497473bc163677175b0fda1f3a8975cceb3dd

diff --git a/ucbhelper/source/client/proxydecider.cxx b/ucbhelper/source/client/proxydecider.cxx
index 66ff406..f5e1b3e 100644
--- a/ucbhelper/source/client/proxydecider.cxx
+++ b/ucbhelper/source/client/proxydecider.cxx
@@ -496,8 +496,8 @@ const InternetProxyServer & InternetProxyDecider_Impl::getProxy(
 
         OUString aHost;
 
-        if ( ( rHost[ 0 ] == '[' ) &&
-             ( rHost.getLength() > 1 ) )
+        if ( ( rHost.getLength() > 1 ) &&
+             ( rHost[ 0 ] == '[' ))
         {
             // host is given as numeric IPv6 address. name resolution
             // functions need hostname without square brackets.
commit 0cac63da2347afcc358ef9e24f1906614b4d2606
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Sep 11 18:11:06 2014 +0200

    fix access to potentiellement empty string
    
    Change-Id: I84fc6b7e5528b677411163ee3c9d05d4f2e6feb2

diff --git a/cppuhelper/source/paths.cxx b/cppuhelper/source/paths.cxx
index e8aa042..c00d729 100644
--- a/cppuhelper/source/paths.cxx
+++ b/cppuhelper/source/paths.cxx
@@ -122,13 +122,21 @@ bool cppu::nextDirectoryItem(osl::Directory & directory, rtl::OUString * url) {
 void cppu::decodeRdbUri(rtl::OUString * uri, bool * optional, bool * directory)
 {
     assert(uri != 0 && optional != 0 && directory != 0);
-    *optional = (*uri)[0] == '?';
-    if (*optional) {
-        *uri = uri->copy(1);
+    if(!(uri->isEmpty()))
+    {
+        *optional = (*uri)[0] == '?';
+        if (*optional) {
+            *uri = uri->copy(1);
+        }
+        *directory = uri->startsWith("<") && uri->endsWith(">*");
+        if (*directory) {
+            *uri = uri->copy(1, uri->getLength() - 3);
+        }
     }
-    *directory = uri->startsWith("<") && uri->endsWith(">*");
-    if (*directory) {
-        *uri = uri->copy(1, uri->getLength() - 3);
+    else
+    {
+        *optional = false;
+        *directory = false;
     }
 }
 
commit 0836415ffd592ecf932a1208f2faba70c2d4988d
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Sep 8 09:35:58 2014 +0200

    coverity#703951 unchecked return value
    
    Change-Id: Id9a3c639bd778552b176c19b7574a9d9786ffebc

diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 311f88f..9791dcb 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -1273,7 +1273,7 @@ bool Outliner::ImpCanIndentSelectedPages( OutlinerView* pCurView )
         if ( nDepthChangedHdlPrevDepth == 1 )   // is the only page
             return false;
         else
-            pCurView->ImpCalcSelectedPages( false );  // without the first
+            (void)pCurView->ImpCalcSelectedPages( false );  // without the first
     }
     return IndentingPagesHdl( pCurView );
 }
commit ec1de2a4ff284f9f1d2e8147af91a8a1588652a1
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Sep 8 09:28:00 2014 +0200

    coverity#735600 Division by zero
    
    Change-Id: Ia936814ae37ae802fab36f7bde56de09338eb617

diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 2fadb71..7118989 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -1474,10 +1474,13 @@ void BreakPointWindow::MouseButtonDown( const MouseEvent& rMEvt )
     {
         Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
         long nLineHeight = GetTextHeight();
-        long nYPos = aMousePos.Y() + nCurYOffset;
-        long nLine = nYPos / nLineHeight + 1;
-        rModulWindow.ToggleBreakPoint( (sal_uLong)nLine );
-        Invalidate();
+        if(nLineHeight)
+        {
+            long nYPos = aMousePos.Y() + nCurYOffset;
+            long nLine = nYPos / nLineHeight + 1;
+            rModulWindow.ToggleBreakPoint( (sal_uLong)nLine );
+            Invalidate();
+        }
     }
 }
 
commit 1b42acdaeae134f94580d6e1eba89da16741d596
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Sat Sep 6 16:13:09 2014 +0200

    vcl: use DeviceCoordinate for GetCaretPositions in sallayout
    
    Change-Id: I5a959e1c3806da713e106c1b0fc8690a6578987b

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index df0cd27..b05edab 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1722,6 +1722,8 @@ public:
 
     SAL_DLLPRIVATE DeviceCoordinate LogicWidthToDeviceCoordinate( long nWidth ) const;
     SAL_DLLPRIVATE DeviceCoordinate LogicHeightToDeviceCoordinate( long nHeight ) const;
+    SAL_DLLPRIVATE long DeviceCoordinateToLogicWidth(DeviceCoordinate width) const;
+    SAL_DLLPRIVATE long DeviceCoordinateToLogicHeight(DeviceCoordinate height) const;
 
 private:
 
diff --git a/vcl/README b/vcl/README
index 65113a6..c00a3e1 100644
--- a/vcl/README
+++ b/vcl/README
@@ -188,3 +188,11 @@ other programs, use the "pdfunzip" tool:
 
 LD_LIBRARY_PATH=$PWD/instdir/ure/lib workdir/LinkTarget/Executable/pdfunzip input.pdf output.pdf
 
+=== DeviceCoordinate ===
+
+The type DeviceCoordinate is meant to represent coordinate in the native Device space
+The implementation is platform dependant. it is a scalar type, but can by int/long/float/double...
+Originally such coordinate was represented with int or long... DeviceCoordinate
+was introduced to allow for sub-point coordiante (iow float/double), which is
+quite important when dealing with HiDPI devices.
+
diff --git a/vcl/inc/graphite_layout.hxx b/vcl/inc/graphite_layout.hxx
index 3295468..11a9f6b 100644
--- a/vcl/inc/graphite_layout.hxx
+++ b/vcl/inc/graphite_layout.hxx
@@ -127,7 +127,7 @@ public:
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
     virtual void  ApplyDXArray(ImplLayoutArgs &rArgs, std::vector<int> & rDeltaWidth);
 
-    virtual void  GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
+    virtual void  GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const SAL_OVERRIDE;
 
     // methods using glyph indexing
     virtual int   GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&,
diff --git a/vcl/inc/graphite_serverfont.hxx b/vcl/inc/graphite_serverfont.hxx
index 0d533e0..00ebfb2 100644
--- a/vcl/inc/graphite_serverfont.hxx
+++ b/vcl/inc/graphite_serverfont.hxx
@@ -80,7 +80,7 @@ public:
         {
             return maImpl.GetTextBreak(max_width, extra, factor);
         }
-        virtual void    GetCaretPositions( int as, long* cxa ) const SAL_OVERRIDE
+        virtual void GetCaretPositions( int as, DeviceCoordinate* cxa ) const SAL_OVERRIDE
         {
             maImpl.GetCaretPositions(as, cxa);
         }
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 3a2061b..0138f8a 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -174,7 +174,7 @@ public:
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra=0, int nFactor=1) const = 0;
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const = 0;
     virtual DeviceCoordinate GetTextWidth() const { return FillDXArray( NULL ); }
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const = 0;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const = 0;
     virtual bool    IsKashidaPosValid ( int /*nCharPos*/ ) const { return true; } // i60594
 
     // methods using glyph indexing
@@ -231,7 +231,7 @@ public:
     virtual void    DrawText( SalGraphics& ) const SAL_OVERRIDE;
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const SAL_OVERRIDE;
     virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos,
                                    int&, DeviceCoordinate* pGlyphAdvAry, int* pCharPosAry,
                                    const PhysicalFontFace** pFallbackFonts ) const SAL_OVERRIDE;
@@ -332,7 +332,7 @@ public:
     virtual DeviceCoordinate GetTextWidth() const SAL_OVERRIDE;
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const SAL_OVERRIDE;
 
     // used by display layers
     virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos, int&,
diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx
index cd9771a..fb73b78 100644
--- a/vcl/quartz/ctlayout.cxx
+++ b/vcl/quartz/ctlayout.cxx
@@ -45,7 +45,7 @@ public:
     virtual DeviceCoordinate GetTextWidth() const SAL_OVERRIDE;
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const SAL_OVERRIDE;
     virtual bool    GetBoundRect( SalGraphics&, Rectangle& ) const SAL_OVERRIDE;
 
     virtual void    InitFont( void) const SAL_OVERRIDE;
@@ -840,7 +840,7 @@ sal_Int32 CTLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoordinate n
     return nIndex;
 }
 
-void CTLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) const
+void CTLayout::GetCaretPositions( int nMaxIndex, DeviceCoordinate* pCaretXArray ) const
 {
     DBG_ASSERT( ((nMaxIndex>0)&&!(nMaxIndex&1)),
         "CTLayout::GetCaretPositions() : invalid number of caret pairs requested");
@@ -848,7 +848,7 @@ void CTLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) const
     // initialize the caret positions
     for( int i = 0; i < nMaxIndex; ++i )
     {
-        pCaretXArray[ i ] = -1;
+        pCaretXArray[ i ] = (DeviceCoordinate)-1;
     }
     for( int n = 0; n <= mnCharCount; ++n )
     {
@@ -859,12 +859,12 @@ void CTLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) const
 
         // update previous trailing position
         if( n > 0 )
-            pCaretXArray[ 2*n-1 ] = lrint( fPos1 );
+            pCaretXArray[ 2*n-1 ] = (DeviceCoordinate) fPos1;
 
         // update current leading position
         if( 2*n >= nMaxIndex )
             break;
-        pCaretXArray[ 2*n+0 ] = lrint( fPos1 );
+        pCaretXArray[ 2*n+0 ] = (DeviceCoordinate) fPos1;
     }
 }
 
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index c30a99a..a3124c4 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -1247,7 +1247,7 @@ void GenericSalLayout::KashidaJustify( long nKashidaIndex, int nKashidaWidth )
     }
 }
 
-void GenericSalLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) const
+void GenericSalLayout::GetCaretPositions( int nMaxIndex, DeviceCoordinate* pCaretXArray ) const
 {
     // initialize result array
     long nXPos = -1;
@@ -1990,26 +1990,28 @@ DeviceCoordinate MultiSalLayout::FillDXArray( DeviceCoordinate* pCharWidths ) co
     return nMaxWidth;
 }
 
-void MultiSalLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) const
+void MultiSalLayout::GetCaretPositions( int nMaxIndex, DeviceCoordinate* pCaretXArray ) const
 {
     SalLayout& rLayout = *mpLayouts[ 0 ];
     rLayout.GetCaretPositions( nMaxIndex, pCaretXArray );
 
     if( mnLevel > 1 )
     {
-        long* pTempPos = (long*)alloca( nMaxIndex * sizeof(long) );
+        DeviceCoordinate* pTempPos = (DeviceCoordinate*)alloca( nMaxIndex * sizeof(DeviceCoordinate) );
         for( int n = 1; n < mnLevel; ++n )
         {
             mpLayouts[ n ]->GetCaretPositions( nMaxIndex, pTempPos );
             double fUnitMul = mnUnitsPerPixel;
             fUnitMul /= mpLayouts[n]->GetUnitsPerPixel();
             for( int i = 0; i < nMaxIndex; ++i )
+            {
                 if( pTempPos[i] >= 0 )
                 {
-                    long w = pTempPos[i];
-                    w = static_cast<long>(w*fUnitMul + 0.5);
+                    DeviceCoordinate w = pTempPos[i];
+                    w = (DeviceCoordinate)(w * fUnitMul + 0.5);
                     pCaretXArray[i] = w;
                 }
+            }
         }
     }
 }
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 6f7cbb2..508a0db 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -1090,14 +1090,14 @@ void GraphiteLayout::kashidaJustify(std::vector<int>& rDeltaWidths, sal_GlyphId
 
 }
 
-void GraphiteLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const
+void GraphiteLayout::GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const
 {
     // For each character except the last discover the caret positions
     // immediately before and after that character.
     // This is used for underlines in the GUI amongst other things.
     // It may be used from MultiSalLayout, in which case it must take into account
     // glyphs that have been moved.
-    std::fill(pCaretXArray, pCaretXArray + nArraySize, -1);
+    std::fill(pCaretXArray, pCaretXArray + nArraySize, (DeviceCoordinate)-1);
     // the layout method doesn't modify the layout even though it isn't
     // const in the interface
     bool bRtl = (mnLayoutFlags & SAL_LAYOUT_BIDI_RTL);//const_cast<GraphiteLayout*>(this)->maLayout.rightToLeft();
diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx
index 396a2c4..2cea0d3 100644
--- a/vcl/source/outdev/map.cxx
+++ b/vcl/source/outdev/map.cxx
@@ -2142,6 +2142,31 @@ long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
     return nY;
 }
 
+long OutputDevice::DeviceCoordinateToLogicWidth(DeviceCoordinate width) const
+{
+    if ( !mbMap )
+    {
+        return (long)width;
+    }
+#if VCL_FLOAT_DEVICE_PIXEL
+    return (long)(width / (maMapRes.mfScaleX * mnDPIX));
+#else
+    return ImplDevicePixelToLogicWidth(width);
+#endif
+}
+
+long OutputDevice::DeviceCoordinateToLogicHeight(DeviceCoordinate height) const
+{
+    if ( !mbMap )
+    {
+        return (long)height;
+    }
+#if VCL_FLOAT_DEVICE_PIXEL
+    return (long)(height / (maMapRes.mfScaleY * mnDPIY));
+#else
+    return ImplDevicePixelToLogicHeight(height);
+#endif
+}
 
 DeviceCoordinate OutputDevice::LogicWidthToDeviceCoordinate( long nWidth ) const
 {
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 51117fe..1dff2db 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -1014,6 +1014,7 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
     {
         pDXPixelArray = (DeviceCoordinate*)alloca(nLen * sizeof(DeviceCoordinate));
     }
+    long nWidthRes;
     DeviceCoordinate nWidth = pSalLayout->FillDXArray( pDXPixelArray );
     int nWidthFactor = pSalLayout->GetUnitsPerPixel();
     pSalLayout->Release();
@@ -1026,36 +1027,41 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
             pDXPixelArray[ i ] += pDXPixelArray[ i-1 ];
         }
     }
-    if( mbMap )
+    if( nWidthFactor > 1 )
     {
         if( pDXPixelArray )
         {
             for( int i = 0; i < nLen; ++i )
             {
-                pDXPixelArray[i] = ImplDevicePixelToLogicWidth( pDXPixelArray[i] );
+                pDXPixelArray[i] /= nWidthFactor;
             }
         }
-        nWidth = ImplDevicePixelToLogicWidth( nWidth );
+        nWidth /= nWidthFactor;
     }
-    if( nWidthFactor > 1 )
+    if( mbMap )
     {
         if( pDXPixelArray )
         {
             for( int i = 0; i < nLen; ++i )
             {
-                pDXPixelArray[i] /= nWidthFactor;
+                pDXAry[i] = DeviceCoordinateToLogicWidth( pDXPixelArray[i] );
             }
         }
-        nWidth /= nWidthFactor;
+        nWidthRes = DeviceCoordinateToLogicWidth( nWidth );
     }
-    if(pDXAry)
+    else
     {
-        for( int i = 0; i < nLen; ++i )
+        if( pDXPixelArray )
         {
-            pDXAry[i] = basegfx::fround(pDXPixelArray[i]);
+            for( int i = 0; i < nLen; ++i )
+            {
+                pDXAry[i] = (long)pDXPixelArray[i];
+            }
         }
+        nWidthRes = (long) nWidth;
     }
-    return basegfx::fround(nWidth);
+
+    return nWidth;
 
 #else /* ! VCL_FLOAT_DEVICE_PIXEL */
 
@@ -1091,7 +1097,7 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
 bool OutputDevice::GetCaretPositions( const OUString& rStr, long* pCaretXArray,
                                       sal_Int32 nIndex, sal_Int32 nLen,
                                       long* pDXAry, long nLayoutWidth,
-                                      bool bCellBreaking ) const
+                                      bool /* bCellBreaking */ ) const
 {
 
     if( nIndex >= rStr.getLength() )
@@ -1105,50 +1111,121 @@ bool OutputDevice::GetCaretPositions( const OUString& rStr, long* pCaretXArray,
     if( !pSalLayout )
         return false;
 
+#if VCL_FLOAT_DEVICE_PIXEL
+    int nWidthFactor = pSalLayout->GetUnitsPerPixel();
+    DeviceCoordinate* pDevCaretXArray = (DeviceCoordinate*)alloca(2 * nLen * sizeof(DeviceCoordinate));
+
+    pSalLayout->GetCaretPositions( 2*nLen, pDevCaretXArray );
+    DeviceCoordinate nWidth = pSalLayout->GetTextWidth();
+    pSalLayout->Release();
+
+    // fixup unknown caret positions
+    int i;
+    for( i = 0; i < 2 * nLen; ++i )
+    {
+        if( pDevCaretXArray[ i ] >= 0 )
+        {
+            break;
+        }
+    }
+    DeviceCoordinate nXPos = pCaretXArray[ i ];
+    for( i = 0; i < 2 * nLen; ++i )
+    {
+        if( pCaretXArray[ i ] >= 0 )
+        {
+            nXPos = pCaretXArray[ i ];
+        }
+        else
+        {
+            pCaretXArray[ i ] = nXPos;
+        }
+    }
+    if( nWidthFactor != 1 )
+    {
+        for( i = 0; i < 2*nLen; ++i )
+        {
+            pDevCaretXArray[i] /= nWidthFactor;
+        }
+    }
+
+    // handle window mirroring
+    if( IsRTLEnabled() )
+    {
+        for( i = 0; i < 2 * nLen; ++i )
+        {
+            pDevCaretXArray[i] = nWidth - pDevCaretXArray[i] - 1;
+        }
+    }
+
+    // convert from font units to logical units
+    if( mbMap )
+    {
+        for( i = 0; i < 2*nLen; ++i )
+        {
+            pCaretXArray[i] = DeviceCoordinateToLogicWidth( pDevCaretXArray[i] );
+        }
+    }
+    else
+    {
+        for( i = 0; i < 2*nLen; ++i )
+        {
+            pCaretXArray[i] = (long)pDevCaretXArray[i];
+        }
+    }
+#else
     int nWidthFactor = pSalLayout->GetUnitsPerPixel();
+
     pSalLayout->GetCaretPositions( 2*nLen, pCaretXArray );
-    long nWidth = pSalLayout->GetTextWidth();
+    DeviceCoordinate nWidth = pSalLayout->GetTextWidth();
     pSalLayout->Release();
 
     // fixup unknown caret positions
     int i;
     for( i = 0; i < 2 * nLen; ++i )
+    {
         if( pCaretXArray[ i ] >= 0 )
+        {
             break;
-    long nXPos = pCaretXArray[ i ];
+        }
+    }
+    DeviceCoordinate nXPos = pCaretXArray[ i ];
     for( i = 0; i < 2 * nLen; ++i )
     {
         if( pCaretXArray[ i ] >= 0 )
+        {
             nXPos = pCaretXArray[ i ];
+        }
         else
+        {
             pCaretXArray[ i ] = nXPos;
+        }
     }
 
     // handle window mirroring
     if( IsRTLEnabled() )
     {
         for( i = 0; i < 2 * nLen; ++i )
+        {
             pCaretXArray[i] = nWidth - pCaretXArray[i] - 1;
+        }
     }
 
     // convert from font units to logical units
     if( mbMap )
     {
         for( i = 0; i < 2*nLen; ++i )
+        {
             pCaretXArray[i] = ImplDevicePixelToLogicWidth( pCaretXArray[i] );
+        }
     }
-
     if( nWidthFactor != 1 )
     {
         for( i = 0; i < 2*nLen; ++i )
+        {
             pCaretXArray[i] /= nWidthFactor;
+        }
     }
-
-    // if requested move caret position to cell limits
-    if( bCellBreaking )
-    {
-        ; // FIXME
-    }
+#endif
 
     return true;
 }
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index eff3f9c..a232bd7 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -147,7 +147,7 @@ public:
 
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const;
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const;
 
     // for glyph+font+script fallback
     virtual void    MoveGlyph( int nStart, long nNewXPos );
@@ -667,9 +667,9 @@ sal_Int32 SimpleWinLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoord
     return -1;
 }
 
-void SimpleWinLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const
+void SimpleWinLayout::GetCaretPositions( int nMaxIdx, DeviceCoordinat* pCaretXArray ) const
 {
-    long nXPos = mnBaseAdv;
+    DeviceCoordinate nXPos = mnBaseAdv;
 
     if( !mpGlyphs2Chars )
     {
@@ -684,13 +684,13 @@ void SimpleWinLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const
     {
         int  i;
         for( i = 0; i < nMaxIdx; ++i )
-            pCaretXArray[ i ] = -1;
+            pCaretXArray[ i ] = (DeviceCoordinate)-1;
 
         // assign glyph positions to character positions
         for( i = 0; i < mnGlyphCount; ++i )
         {
             int nCurrIdx = mpGlyphs2Chars[ i ] - mnMinCharPos;
-            long nXRight = nXPos + mpCharWidths[ nCurrIdx ];
+            DeviceCoordinate nXRight = nXPos + mpCharWidths[ nCurrIdx ];
             nCurrIdx *= 2;
             if( !(mpGlyphRTLFlags && mpGlyphRTLFlags[i]) )
             {
@@ -968,7 +968,7 @@ public:
 
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const;
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
-    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const;
+    virtual void    GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const;
     virtual bool    IsKashidaPosValid ( int nCharPos ) const;
 
     // for glyph+font+script fallback
@@ -2158,16 +2158,16 @@ sal_Int32 UniscribeLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoord
     return -1;
 }
 
-void UniscribeLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const
+void UniscribeLayout::GetCaretPositions( int nMaxIdx, DeviceCoordinate* pCaretXArray ) const
 {
     int i;
     for( i = 0; i < nMaxIdx; ++i )
         pCaretXArray[ i ] = -1;
-    long* const pGlyphPos = (long*)alloca( (mnGlyphCount+1) * sizeof(long) );
+    DeviceCoordinate* const pGlyphPos = (DeviceCoordinate*)alloca( (mnGlyphCount+1) * sizeof(DeviceCoordinate) );
     for( i = 0; i <= mnGlyphCount; ++i )
         pGlyphPos[ i ] = -1;
 
-    long nXPos = 0;
+    DeviceCoordinate nXPos = 0;
     for( int nItem = 0; nItem < mnItemCount; ++nItem )
     {
         const VisualItem& rVisualItem = mpVisualItems[ nItem ];
@@ -2643,7 +2643,7 @@ public:
     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra=0, int nFactor=1) const SAL_OVERRIDE;
     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const;
 
-    virtual void  GetCaretPositions( int nArraySize, long* pCaretXArray ) const;
+    virtual void  GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const;
 
     // methods using glyph indexing
     virtual int   GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&,
@@ -2787,7 +2787,7 @@ DeviceCoordinate GraphiteWinLayout::FillDXArray( DeviceCoordinate* pDXArray ) co
     return maImpl.FillDXArray(pDXArray);
 }
 
-void GraphiteWinLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const
+void GraphiteWinLayout::GetCaretPositions( int nArraySize, DeviceCoordinate* pCaretXArray ) const
 {
     maImpl.GetCaretPositions(nArraySize, pCaretXArray);
 }


More information about the Libreoffice-commits mailing list