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 8606c879d82bc883f62aac7e240d06f0c027b31b Author: Peter Kovacs <[email protected]> AuthorDate: Mon Jul 6 22:35:44 2026 +0200 encoding is now based on RTL_TEXTENCODING_MS_1252 as a default. The dxf filter is now prepared to receive a overide which encoding is to be used. With this fix no higher level has been included to use this method. no test have been done on the code. All test are done in a compilde AOO version, by loading test files. --- main/filter/source/graphicfilter/idxf/dxfreprd.cxx | 85 +++++++++++++++++++--- main/filter/source/graphicfilter/idxf/idxf.cxx | 19 ++++- main/filter/source/graphicfilter/idxf/makefile.mk | 2 +- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/main/filter/source/graphicfilter/idxf/dxfreprd.cxx b/main/filter/source/graphicfilter/idxf/dxfreprd.cxx index baac269954..6cc60e1aa6 100644 --- a/main/filter/source/graphicfilter/idxf/dxfreprd.cxx +++ b/main/filter/source/graphicfilter/idxf/dxfreprd.cxx @@ -26,6 +26,9 @@ #include <string.h> #include <math.h> +#include <tools/string.hxx> // gsl_getSystemTextEncoding +#include <rtl/tencinfo.h> // rtl_getTextEncodingFromWindowsCodePage +#include <rtl/string.h> // rtl_str_compareIgnoreAsciiCase #include <dxfreprd.hxx> @@ -136,7 +139,32 @@ void DXFPalette::SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sa DXFRepresentation::DXFRepresentation() { - setTextEncoding(RTL_TEXTENCODING_IBM_437); + // Default text encoding for a DXF that neither declares a $DWGCODEPAGE nor + // receives an override from the caller (see GraphicImport / FilterConfigItem). + // The historic hard-coded IBM_437 (DOS OEM) is almost never right for a modern + // DXF and garbles any high-bit text (issue 99892). Prefer the system encoding, + // which usually matches the locale the file came from (e.g. a Russian machine + // -> MS_1251). + // + // BUT the system encoding is not necessarily a legacy 8-bit code page any more: + // on Windows with the "Use Unicode UTF-8 for worldwide language support" option + // GetACP() returns 65001, and on modern Linux the locale is UTF-8 as well, so + // the system encoding is RTL_TEXTENCODING_UTF8. Legacy DXF text predates UTF-8 + // and is never encoded that way (test13.dxf: windows-1252 Ä/ü/ß on a UTF-8 host + // came out as artefacts), so decoding those bytes as UTF-8 fails. When the + // system encoding is Unicode/unknown, fall back to windows-1252 — the most + // common encoding for untagged DXF and AOO's usual Western default (cf. the + // msfilter legacy importers); other scripts come from an explicit $DWGCODEPAGE + // or the Phase B chooser. + // Precedence: file $DWGCODEPAGE > caller override > this default. + rtl_TextEncoding eDefault = gsl_getSystemTextEncoding(); + if ( eDefault == RTL_TEXTENCODING_UTF8 || + eDefault == RTL_TEXTENCODING_UTF7 || + eDefault == RTL_TEXTENCODING_UCS2 || + eDefault == RTL_TEXTENCODING_UCS4 || + eDefault == RTL_TEXTENCODING_DONTKNOW ) + eDefault = RTL_TEXTENCODING_MS_1252; + setTextEncoding(eDefault); setGlobalLineTypeScale(1.0); } @@ -199,6 +227,45 @@ sal_Bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 nMinPercent, s } +// Map a DXF $DWGCODEPAGE value to an rtl text encoding. +// The values AutoCAD writes are "ANSI_<cp>" (e.g. ANSI_1252, ANSI_1251), +// "DOS<cp>" (e.g. DOS932, DOS850) or a few named ones ("MACINTOSH", "UTF8"). +// For the ANSI_/DOS_ forms the trailing number IS the Windows code page, so we +// extract it and let rtl resolve it (covers the whole family in one line instead +// of the old single ANSI_932 special case). Returns RTL_TEXTENCODING_DONTKNOW +// when the value is empty/unrecognised so the caller can keep its current +// (default or caller-supplied) encoding. +static rtl_TextEncoding DXFCodePageToTextEncoding(const char * pCodePage) +{ + if (pCodePage==NULL || *pCodePage==0) + return RTL_TEXTENCODING_DONTKNOW; + + // find the first digit (start of the code-page number, if any) + const char * p = pCodePage; + while (*p!=0 && (*p<'0' || *p>'9')) + p++; + if (*p!=0) { + sal_uInt32 nCodePage = 0; + while (*p>='0' && *p<='9') { + nCodePage = nCodePage*10 + (sal_uInt32)(*p-'0'); + p++; + } + rtl_TextEncoding eEnc = rtl_getTextEncodingFromWindowsCodePage(nCodePage); + if (eEnc!=RTL_TEXTENCODING_DONTKNOW) + return eEnc; + } + + // named values without a code-page number + if (rtl_str_compareIgnoreAsciiCase(pCodePage,"MACINTOSH")==0) + return RTL_TEXTENCODING_APPLE_ROMAN; + if (rtl_str_compareIgnoreAsciiCase(pCodePage,"UTF8")==0 || + rtl_str_compareIgnoreAsciiCase(pCodePage,"UTF-8")==0) + return RTL_TEXTENCODING_UTF8; + + return RTL_TEXTENCODING_DONTKNOW; +} + + void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR) { @@ -224,15 +291,13 @@ void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR) { rDGR.Read(); - // FIXME: we really need a whole table of - // $DWGCODEPAGE to encodings mappings - if ( (strcmp(rDGR.GetS(),"ANSI_932")==0) || - (strcmp(rDGR.GetS(),"ansi_932")==0) || - (strcmp(rDGR.GetS(),"DOS932")==0) || - (strcmp(rDGR.GetS(),"dos932")==0) ) - { - setTextEncoding(RTL_TEXTENCODING_MS_932); - } + // The file declares its encoding: this is + // authoritative and overrides both the + // default and any caller-supplied override. + rtl_TextEncoding eEnc = + DXFCodePageToTextEncoding(rDGR.GetS()); + if (eEnc!=RTL_TEXTENCODING_DONTKNOW) + setTextEncoding(eEnc); } else if (strcmp(rDGR.GetS(),"$LTSCALE")==0) { diff --git a/main/filter/source/graphicfilter/idxf/idxf.cxx b/main/filter/source/graphicfilter/idxf/idxf.cxx index a1fd94a11c..f44cf85278 100644 --- a/main/filter/source/graphicfilter/idxf/idxf.cxx +++ b/main/filter/source/graphicfilter/idxf/idxf.cxx @@ -28,17 +28,34 @@ #include <vcl/gdimtf.hxx> #include <vcl/graph.hxx> #include <vcl/virdev.hxx> +#include <svtools/FilterConfigItem.hxx> #include "dxf2mtf.hxx" #include <math.h> //================== GraphicImport - die exportierte Funktion ================ -extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool ) +extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem, sal_Bool ) { DXFRepresentation aDXF; DXF2GDIMetaFile aConverter; GDIMetaFile aMTF; + // A DXF may not declare its text encoding ($DWGCODEPAGE). In that case the + // caller (a higher layer that knows the user's intent) can supply a fallback + // encoding as a "CharacterSet" filter option; it is applied before reading so + // that a $DWGCODEPAGE actually present in the file still wins over it. + // See idxf/cases/case-99892 (Phase B concept) for how this option is meant to + // be populated. When neither the file nor the caller provides one, + // DXFRepresentation defaults to the system ANSI encoding. + if ( pConfigItem ) + { + sal_Int32 nEncoding = pConfigItem->ReadInt32( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharacterSet" ) ), + RTL_TEXTENCODING_DONTKNOW ); + if ( nEncoding != RTL_TEXTENCODING_DONTKNOW ) + aDXF.setTextEncoding( (rtl_TextEncoding)nEncoding ); + } + if ( aDXF.Read( rStream, 0, 60 ) == sal_False ) return sal_False; if ( aConverter.Convert( aDXF, aMTF, 60, 100 ) == sal_False ) diff --git a/main/filter/source/graphicfilter/idxf/makefile.mk b/main/filter/source/graphicfilter/idxf/makefile.mk index ba69c76043..71a2d76637 100644 --- a/main/filter/source/graphicfilter/idxf/makefile.mk +++ b/main/filter/source/graphicfilter/idxf/makefile.mk @@ -54,7 +54,7 @@ SLOFILES = $(SLO)$/dxfgrprd.obj \ SHL1TARGET= idx$(DLLPOSTFIX) SHL1IMPLIB= idxf -SHL1STDLIBS= $(VCLLIB) $(TOOLSLIB) $(SALLIB) +SHL1STDLIBS= $(VCLLIB) $(TOOLSLIB) $(SALLIB) $(SVTOOLLIB) .IF "$(GUI)" == "OS2" SHL1STDLIBS+= $(CPPULIB) .ENDIF
