You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by pe...@apache.org on 2026/07/07 04:01:03 UTC
(openoffice) 01/11: filter: idxf: chunk oversized LWPOLYLINE instead of truncating the count
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 <pe...@apache.org>
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 <no...@anthropic.com>
(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 );
}
}