This is an automated email from the ASF dual-hosted git repository.

leginee pushed a commit to branch bugfix-dxf-filter
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 999d0e5d3c8f710c68c553b185539e922d0809c9
Author: Peter Kovacs <[email protected]>
AuthorDate: Thu Jul 2 22:15:55 2026 +0200

    filter: idxf: chunk oversized LWPOLYLINE instead of truncating the count
    
    A DXF LWPOLYLINE vertex count (group code 90) is 32-bit, but tools::Polygon
    is indexed by sal_uInt16. Render polylines with more than 65535 points as
    consecutive Polygon segments that overlap by one point, walking the source
    array with the full 32-bit index, so the whole line is drawn without
    narrowing it to 16 bits.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    (cherry picked from commit 2f0de83e3857a766280165977d6304354eb43806)
    (cherry picked from commit ac9bccefb1d87a770f60d12a2e6523cc8ef496a9)
---
 main/filter/source/graphicfilter/idxf/dxf2mtf.cxx | 65 +++++++++++++++++------
 1 file changed, 48 insertions(+), 17 deletions(-)

diff --git a/main/filter/source/graphicfilter/idxf/dxf2mtf.cxx 
b/main/filter/source/graphicfilter/idxf/dxf2mtf.cxx
index 7f2706117d..3ee67f6797 100644
--- a/main/filter/source/graphicfilter/idxf/dxf2mtf.cxx
+++ b/main/filter/source/graphicfilter/idxf/dxf2mtf.cxx
@@ -586,24 +586,55 @@ void DXF2GDIMetaFile::DrawPolyLineEntity(const 
DXFPolyLineEntity & rE, const DXF
 
 void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, 
const DXFTransform & rTransform )
 {
-       sal_Int32 i, nPolySize = rE.nCount;
-       if ( nPolySize && rE.pP )
+       const sal_Int32 nPolySize = rE.nCount;
+       if ( nPolySize <= 0 || rE.pP == NULL )
+               return;
+
+       double fW = rE.fConstantWidth;
+       if ( !SetLineAttribute( rE, rTransform.TransLineWidth( fW ) ) )
+               return;
+
+       const sal_Bool bClosed = ( rE.nFlags & 1 ) != 0;
+
+       if ( nPolySize <= 0xFFFF )
        {
-               Polygon aPoly( (sal_uInt16)nPolySize);
-               for ( i = 0; i < nPolySize; i++ )
-               {
-                       rTransform.Transform( rE.pP[ (sal_uInt16)i ], aPoly[ 
(sal_uInt16)i ] );
-               }
-               double fW = rE.fConstantWidth;
-               if ( SetLineAttribute( rE, rTransform.TransLineWidth( fW ) ) )
-               {
-                       if ( ( rE.nFlags & 1 ) != 0 )
-                               pVirDev->DrawPolygon( aPoly );
-                       else
-                               pVirDev->DrawPolyLine( aPoly );
-                               // ####
-                               //pVirDev->DrawPolyLine( aPoly, aDXFLineInfo );
-               }
+               // Fits in a single tools Polygon (which is indexed by 
sal_uInt16).
+               Polygon aPoly( (sal_uInt16)nPolySize );
+               for ( sal_Int32 i = 0; i < nPolySize; i++ )
+                       rTransform.Transform( rE.pP[ i ], aPoly[ (sal_uInt16)i 
] );
+               if ( bClosed )
+                       pVirDev->DrawPolygon( aPoly );
+               else
+                       pVirDev->DrawPolyLine( aPoly );
+               return;
+       }
+
+       // The DXF vertex count (group code 90) is a 32-bit value, but a tools 
Polygon
+       // holds at most 0xFFFF points. Render a larger polyline as a sequence 
of
+       // Polygon segments that overlap by one point, so the whole line is 
drawn
+       // without truncation and the stroke stays continuous. The source array 
pP is
+       // walked with the full 32-bit position; only the per-segment index is 
16-bit.
+       const sal_Int32 nMaxChunk = 0xFFFF;
+       sal_Int32 nStart = 0;
+       while ( nStart + 1 < nPolySize )
+       {
+               sal_Int32 nEnd = nStart + nMaxChunk;
+               if ( nEnd > nPolySize )
+                       nEnd = nPolySize;
+               const sal_uInt16 nChunk = (sal_uInt16)( nEnd - nStart );
+               Polygon aChunk( nChunk );
+               for ( sal_uInt16 j = 0; j < nChunk; j++ )
+                       rTransform.Transform( rE.pP[ nStart + j ], aChunk[ j ] 
);
+               pVirDev->DrawPolyLine( aChunk );
+               nStart = nEnd - 1;   // next segment shares this segment's last 
point
+       }
+       if ( bClosed )
+       {
+               // Close the outline: last vertex back to the first.
+               Polygon aClose( 2 );
+               rTransform.Transform( rE.pP[ nPolySize - 1 ], aClose[ 0 ] );
+               rTransform.Transform( rE.pP[ 0 ],             aClose[ 1 ] );
+               pVirDev->DrawPolyLine( aClose );
        }
 }
 

Reply via email to