diff options
author | Mike Kaganski <mikekaganski@hotmail.com> | 2015-05-05 01:13:04 +1000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-05-07 14:15:36 +0000 |
commit | 28a2f0d6d803569952e7b3efb0269001af8e9c7e (patch) | |
tree | 273faf45f7974f38e885e74fa0ddb4445424e0f3 | |
parent | 1779568f6610dd93a2eeb637dabaed3476dc04ca (diff) |
tdf#74299: improve DXF import
1. Now there's no fixed string length limit; see
http://www.autodesk.com/techpubs/autocad/acad2000/dxf/group_code_value_types_dxf_01.htm
The Autodesk's own DXF reference is inconsistent on this matter;
the "Group Code Value Types Reference" tells opposite to "About Group
Codes in DXF Files".
AutoCAD itself easily creates lines 10 000+ characters long!
This removes the hardcoded line length limit; also simplifies
internal struct DXFGroupReader used to parse DXF codes.
2. Improved text import: honor unicode strings in AutoCAD 2007+ DXF;
use more $DWGCODEPAGE values (note: when more codepages will be
discovered, they should be handled in DXFRepresentation::ReadHeader()).
Use LO locale when DXF doesn't specify one. Handle AutoCAD character
names.
3. General fixes & simplifications.
Change-Id: Ifde08978e2da7511696100520732bd76c1a660bb
Reviewed-on: https://gerrit.libreoffice.org/15627
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | filter/source/graphicfilter/idxf/dxf2mtf.cxx | 6 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfblkrd.cxx | 12 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfentrd.cxx | 70 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfgrprd.cxx | 238 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfgrprd.hxx | 53 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfreprd.cxx | 197 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxfreprd.hxx | 13 | ||||
-rw-r--r-- | filter/source/graphicfilter/idxf/dxftblrd.cxx | 28 |
8 files changed, 282 insertions, 335 deletions
diff --git a/filter/source/graphicfilter/idxf/dxf2mtf.cxx b/filter/source/graphicfilter/idxf/dxf2mtf.cxx index ffca879871cb..d02c38913b27 100644 --- a/filter/source/graphicfilter/idxf/dxf2mtf.cxx +++ b/filter/source/graphicfilter/idxf/dxf2mtf.cxx @@ -427,8 +427,7 @@ void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity & rE, const DXFTransfor aT.TransDir(DXFVector(1,0,0),aV); if ( SetFontAttribute( rE,nAng, nHeight, aV. Abs() ) ) { - OUString const aUString( - OStringToOUString(rE.m_sText, pDXF->getTextEncoding())); + OUString const aUString(pDXF->ToOUString(rE.m_sText, true)); aT.Transform( DXFVector( 0, 0, 0 ), aPt ); pVirDev->DrawText( aPt, aUString ); } @@ -486,8 +485,7 @@ void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity & rE, const DXFTran aT.TransDir(DXFVector(1,0,0),aV); if (SetFontAttribute(rE,nAng,nHeight,aV.Abs())) { - OUString const aUString( - OStringToOUString(rE.m_sText, pDXF->getTextEncoding())); + OUString const aUString(pDXF->ToOUString(rE.m_sText, true)); aT.Transform( DXFVector( 0, 0, 0 ), aPt ); pVirDev->DrawText( aPt, aUString ); } diff --git a/filter/source/graphicfilter/idxf/dxfblkrd.cxx b/filter/source/graphicfilter/idxf/dxfblkrd.cxx index d84a2fac3454..00f8e4f4fee5 100644 --- a/filter/source/graphicfilter/idxf/dxfblkrd.cxx +++ b/filter/source/graphicfilter/idxf/dxfblkrd.cxx @@ -53,13 +53,13 @@ void DXFBlock::Read(DXFGroupReader & rDGR) { switch (rDGR.GetG()) { - case 2: m_sName = OString(rDGR.GetS()); break; - case 3: m_sAlsoName = OString(rDGR.GetS()); break; + case 2: m_sName = rDGR.GetS(); break; + case 3: m_sAlsoName = rDGR.GetS(); break; case 70: nFlags=rDGR.GetI(); break; case 10: aBasePoint.fx=rDGR.GetF(); break; case 20: aBasePoint.fy=rDGR.GetF(); break; case 30: aBasePoint.fz=rDGR.GetF(); break; - case 1: m_sXRef = OString(rDGR.GetS()); break; + case 1: m_sXRef = rDGR.GetS(); break; } } DXFEntities::Read(rDGR); @@ -92,9 +92,9 @@ void DXFBlocks::Read(DXFGroupReader & rDGR) for (;;) { while (rDGR.GetG()!=0) rDGR.Read(); - if (strcmp(rDGR.GetS(),"ENDSEC")==0 || - strcmp(rDGR.GetS(),"EOF")==0) break; - if (strcmp(rDGR.GetS(),"BLOCK")==0) { + if (rDGR.GetS() == "ENDSEC" || + rDGR.GetS() == "EOF") break; + if (rDGR.GetS() == "BLOCK") { pB=new DXFBlock; pB->Read(rDGR); *ppSucc=pB; diff --git a/filter/source/graphicfilter/idxf/dxfentrd.cxx b/filter/source/graphicfilter/idxf/dxfentrd.cxx index 3966e1cca7ea..0291d5be8f85 100644 --- a/filter/source/graphicfilter/idxf/dxfentrd.cxx +++ b/filter/source/graphicfilter/idxf/dxfentrd.cxx @@ -47,8 +47,8 @@ void DXFBasicEntity::EvaluateGroup(DXFGroupReader & rDGR) { switch (rDGR.GetG()) { - case 8: m_sLayer = OString(rDGR.GetS()); break; - case 6: m_sLineType = OString(rDGR.GetS()); break; + case 8: m_sLayer = rDGR.GetS(); break; + case 6: m_sLineType = rDGR.GetS(); break; case 38: fElevation=rDGR.GetF(); break; case 39: fThickness=rDGR.GetF(); break; case 62: nColor=rDGR.GetI(); break; @@ -210,11 +210,11 @@ void DXFTextEntity::EvaluateGroup(DXFGroupReader & rDGR) case 20: aP0.fy=rDGR.GetF(); break; case 30: aP0.fz=rDGR.GetF(); break; case 40: fHeight=rDGR.GetF(); break; - case 1: m_sText = OString(rDGR.GetS()); break; + case 1: m_sText = rDGR.GetS(); break; case 50: fRotAngle=rDGR.GetF(); break; case 41: fXScale=rDGR.GetF(); break; case 42: fOblAngle=rDGR.GetF(); break; - case 7: m_sStyle = OString(rDGR.GetS()); break; + case 7: m_sStyle = rDGR.GetS(); break; case 71: nGenFlags=rDGR.GetI(); break; case 72: nHorzJust=rDGR.GetI(); break; case 73: nVertJust=rDGR.GetI(); break; @@ -242,7 +242,7 @@ void DXFShapeEntity::EvaluateGroup(DXFGroupReader & rDGR) case 20: aP0.fy=rDGR.GetF(); break; case 30: aP0.fz=rDGR.GetF(); break; case 40: fSize=rDGR.GetF(); break; - case 2: m_sName = OString(rDGR.GetS()); break; + case 2: m_sName = rDGR.GetS(); break; case 50: fRotAngle=rDGR.GetF(); break; case 41: fXScale=rDGR.GetF(); break; case 51: fOblAngle=rDGR.GetF(); break; @@ -269,7 +269,7 @@ void DXFInsertEntity::EvaluateGroup(DXFGroupReader & rDGR) { switch (rDGR.GetG()) { case 66: nAttrFlag=rDGR.GetI(); break; - case 2: m_sName = OString(rDGR.GetS()); break; + case 2: m_sName = rDGR.GetS(); break; case 10: aP0.fx=rDGR.GetF(); break; case 20: aP0.fy=rDGR.GetF(); break; case 30: aP0.fz=rDGR.GetF(); break; @@ -309,15 +309,15 @@ void DXFAttDefEntity::EvaluateGroup(DXFGroupReader & rDGR) case 20: aP0.fy=rDGR.GetF(); break; case 30: aP0.fz=rDGR.GetF(); break; case 40: fHeight=rDGR.GetF(); break; - case 1: m_sDefVal = OString(rDGR.GetS()); break; - case 3: m_sPrompt = OString(rDGR.GetS()); break; - case 2: m_sTagStr = OString(rDGR.GetS()); break; + case 1: m_sDefVal = rDGR.GetS(); break; + case 3: m_sPrompt = rDGR.GetS(); break; + case 2: m_sTagStr = rDGR.GetS(); break; case 70: nAttrFlags=rDGR.GetI(); break; case 73: nFieldLen=rDGR.GetI(); break; case 50: fRotAngle=rDGR.GetF(); break; case 41: fXScale=rDGR.GetF(); break; case 51: fOblAngle=rDGR.GetF(); break; - case 7: m_sStyle = OString(rDGR.GetS()); break; + case 7: m_sStyle = rDGR.GetS(); break; case 71: nGenFlags=rDGR.GetI(); break; case 72: nHorzJust=rDGR.GetI(); break; case 74: nVertJust=rDGR.GetI(); break; @@ -352,14 +352,14 @@ void DXFAttribEntity::EvaluateGroup(DXFGroupReader & rDGR) case 20: aP0.fy=rDGR.GetF(); break; case 30: aP0.fz=rDGR.GetF(); break; case 40: fHeight=rDGR.GetF(); break; - case 1: m_sText = OString(rDGR.GetS()); break; - case 2: m_sTagStr = OString(rDGR.GetS()); break; + case 1: m_sText = rDGR.GetS(); break; + case 2: m_sTagStr = rDGR.GetS(); break; case 70: nAttrFlags=rDGR.GetI(); break; case 73: nFieldLen=rDGR.GetI(); break; case 50: fRotAngle=rDGR.GetF(); break; case 41: fXScale=rDGR.GetF(); break; case 51: fOblAngle=rDGR.GetF(); break; - case 7: m_sStyle = OString(rDGR.GetS()); break; + case 7: m_sStyle = rDGR.GetS(); break; case 71: nGenFlags=rDGR.GetI(); break; case 72: nHorzJust=rDGR.GetI(); break; case 74: nVertJust=rDGR.GetI(); break; @@ -791,7 +791,7 @@ DXFDimensionEntity::DXFDimensionEntity() : DXFBasicEntity(DXF_DIMENSION) void DXFDimensionEntity::EvaluateGroup(DXFGroupReader & rDGR) { switch (rDGR.GetG()) { - case 2: m_sPseudoBlock = OString(rDGR.GetS()); break; + case 2: m_sPseudoBlock = rDGR.GetS(); break; default: DXFBasicEntity::EvaluateGroup(rDGR); } } @@ -807,29 +807,29 @@ void DXFEntities::Read(DXFGroupReader & rDGR) while (rDGR.GetG()!=0) rDGR.Read(); - while (strcmp(rDGR.GetS(),"ENDBLK")!=0 && - strcmp(rDGR.GetS(),"ENDSEC")!=0 && - strcmp(rDGR.GetS(),"EOF")!=0 ) + while (rDGR.GetS()!="ENDBLK" && + rDGR.GetS()!="ENDSEC" && + rDGR.GetS()!="EOF" ) { - if (strcmp(rDGR.GetS(),"LINE" )==0) pE=new DXFLineEntity; - else if (strcmp(rDGR.GetS(),"POINT" )==0) pE=new DXFPointEntity; - else if (strcmp(rDGR.GetS(),"CIRCLE" )==0) pE=new DXFCircleEntity; - else if (strcmp(rDGR.GetS(),"ARC" )==0) pE=new DXFArcEntity; - else if (strcmp(rDGR.GetS(),"TRACE" )==0) pE=new DXFTraceEntity; - else if (strcmp(rDGR.GetS(),"SOLID" )==0) pE=new DXFSolidEntity; - else if (strcmp(rDGR.GetS(),"TEXT" )==0) pE=new DXFTextEntity; - else if (strcmp(rDGR.GetS(),"SHAPE" )==0) pE=new DXFShapeEntity; - else if (strcmp(rDGR.GetS(),"INSERT" )==0) pE=new DXFInsertEntity; - else if (strcmp(rDGR.GetS(),"ATTDEF" )==0) pE=new DXFAttDefEntity; - else if (strcmp(rDGR.GetS(),"ATTRIB" )==0) pE=new DXFAttribEntity; - else if (strcmp(rDGR.GetS(),"POLYLINE" )==0) pE=new DXFPolyLineEntity; - else if (strcmp(rDGR.GetS(),"LWPOLYLINE")==0) pE=new DXFLWPolyLineEntity; - else if (strcmp(rDGR.GetS(),"VERTEX" )==0) pE=new DXFVertexEntity; - else if (strcmp(rDGR.GetS(),"SEQEND" )==0) pE=new DXFSeqEndEntity; - else if (strcmp(rDGR.GetS(),"3DFACE" )==0) pE=new DXF3DFaceEntity; - else if (strcmp(rDGR.GetS(),"DIMENSION" )==0) pE=new DXFDimensionEntity; - else if (strcmp(rDGR.GetS(),"HATCH" )==0) pE=new DXFHatchEntity; + if (rDGR.GetS() == "LINE" ) pE=new DXFLineEntity; + else if (rDGR.GetS() == "POINT" ) pE=new DXFPointEntity; + else if (rDGR.GetS() == "CIRCLE" ) pE=new DXFCircleEntity; + else if (rDGR.GetS() == "ARC" ) pE=new DXFArcEntity; + else if (rDGR.GetS() == "TRACE" ) pE=new DXFTraceEntity; + else if (rDGR.GetS() == "SOLID" ) pE=new DXFSolidEntity; + else if (rDGR.GetS() == "TEXT" ) pE=new DXFTextEntity; + else if (rDGR.GetS() == "SHAPE" ) pE=new DXFShapeEntity; + else if (rDGR.GetS() == "INSERT" ) pE=new DXFInsertEntity; + else if (rDGR.GetS() == "ATTDEF" ) pE=new DXFAttDefEntity; + else if (rDGR.GetS() == "ATTRIB" ) pE=new DXFAttribEntity; + else if (rDGR.GetS() == "POLYLINE" ) pE=new DXFPolyLineEntity; + else if (rDGR.GetS() == "LWPOLYLINE") pE=new DXFLWPolyLineEntity; + else if (rDGR.GetS() == "VERTEX" ) pE=new DXFVertexEntity; + else if (rDGR.GetS() == "SEQEND" ) pE=new DXFSeqEndEntity; + else if (rDGR.GetS() == "3DFACE" ) pE=new DXF3DFaceEntity; + else if (rDGR.GetS() == "DIMENSION" ) pE=new DXFDimensionEntity; + else if (rDGR.GetS() == "HATCH" ) pE=new DXFHatchEntity; else { do { diff --git a/filter/source/graphicfilter/idxf/dxfgrprd.cxx b/filter/source/graphicfilter/idxf/dxfgrprd.cxx index ecba39f4d2fa..7ab0b8792a64 100644 --- a/filter/source/graphicfilter/idxf/dxfgrprd.cxx +++ b/filter/source/graphicfilter/idxf/dxfgrprd.cxx @@ -17,15 +17,12 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <string.h> #include <stdlib.h> #include <rtl/strbuf.hxx> #include <tools/stream.hxx> #include "dxfgrprd.hxx" - - // we use an own ReadLine function, because Stream::ReadLine stops if // a 0-sign occurs; this function converts 0-signs to blanks and reads // a complete line until a cr/lf is found @@ -87,42 +84,42 @@ OString DXFReadLine(SvStream& rIStm) return aBuf.makeStringAndClear(); } - - -DXFGroupReader::DXFGroupReader(SvStream & rIStream, sal_uInt16 nminpercent, sal_uInt16 nmaxpercent ) : - rIS(rIStream) +void DXFSkipLine(SvStream& rIStm) { - sal_uInt16 i; - - nIBuffPos=0; - nIBuffSize=0; - bStatus=true; - nLastG=0; - nGCount=0; - - nMinPercent=(sal_uLong)nminpercent; - nMaxPercent=(sal_uLong)nmaxpercent; - nLastPercent=nMinPercent; + while (!rIStm.GetError()) // !!! do not check for EOF + // !!! because we read blockwise + { + char buf[256 + 1]; + sal_uInt16 nLen = (sal_uInt16)rIStm.Read(buf, sizeof(buf) - 1); + for (sal_uInt16 n = 0; n < nLen; n++) + { + char c = buf[n]; + if ((c == '\n') || (c == '\r')) + { + rIStm.SeekRel(n-nLen+1); // return stream to next to current position + char c1 = 0; + rIStm.Read(&c1, 1); + if (c1 == c || (c1 != '\n' && c1!= '\r')) + rIStm.SeekRel(-1); + return; + } + } + } +} +DXFGroupReader::DXFGroupReader(SvStream & rIStream) + : rIS(rIStream) + , bStatus(true) + , nLastG(0) + , nGCount(0) + , S() + , I(0) +{ rIS.Seek(STREAM_SEEK_TO_END); nFileSize=rIS.Tell(); rIS.Seek(0); - - for (i=0; i<10; i++) S0_9[i][0]=0; - S100[ 0 ] = S102[ 0 ] = 0; - for (i=0; i<50; i++) F10_59[i]=0.0; - for (i=0; i<20; i++) I60_79[i]=0; - for (i=0; i<10; i++) I90_99[i]=0; - for (i=0; i< 8; i++) F140_147[i]=0.0; - for (i=0; i< 6; i++) I170_175[i]=0; - for (i=0; i<30; i++) F210_239[i]=0.0; - for (i=0; i<11; i++) S999_1009[i][0]=0; - for (i=0; i<50; i++) F1010_1059[i]=0.0; - for (i=0; i<20; i++) I1060_1079[i]=0; - } - sal_uInt16 DXFGroupReader::Read() { sal_uInt16 nG = 0; @@ -132,40 +129,36 @@ sal_uInt16 DXFGroupReader::Read() nG = (sal_uInt16)ReadI(); if ( bStatus ) { - char aTmp[ DXF_MAX_STRING_LEN + 1 ]; - - if (nG< 10) ReadS(S0_9[nG]); - else if (nG< 60) F10_59[nG-10]=ReadF(); - else if (nG< 80) I60_79[nG-60]=ReadI(); - else if (nG< 90) ReadS( aTmp ); - else if (nG< 99) I90_99[nG-90]=ReadI(); - else if (nG==100) ReadS(S100); - else if (nG==102) ReadS(S102); - else if (nG==105) ReadS( aTmp ); - else if (nG< 140) ReadS( aTmp ); - else if (nG< 148) F140_147[nG-140]=ReadF(); - else if (nG< 170) ReadS( aTmp ); - else if (nG< 176) I170_175[nG-175]=ReadI(); - else if (nG< 180) ReadI(); - else if (nG< 210) ReadS( aTmp ); - else if (nG< 240) F210_239[nG-210]=ReadF(); - else if (nG<=369) ReadS( aTmp ); - else if (nG< 999) ReadS( aTmp ); - else if (nG<1010) ReadS(S999_1009[nG-999]); - else if (nG<1060) F1010_1059[nG-1010]=ReadF(); - else if (nG<1080) I1060_1079[nG-1060]=ReadI(); + if (nG< 10) ReadS(); + else if (nG< 60) F = ReadF(); + else if (nG< 80) I = ReadI(); + else if (nG< 90) DXFSkipLine(rIS); + else if (nG< 99) I = ReadI(); + else if (nG==100) ReadS(); + else if (nG==102) ReadS(); + else if (nG==105) DXFSkipLine(rIS); + else if (nG< 140) DXFSkipLine(rIS); + else if (nG< 148) F = ReadF(); + else if (nG< 170) DXFSkipLine(rIS); + else if (nG< 176) I = ReadI(); + else if (nG< 180) DXFSkipLine(rIS); // ReadI(); + else if (nG< 210) DXFSkipLine(rIS); + else if (nG< 240) F = ReadF(); + else if (nG<=369) DXFSkipLine(rIS); + else if (nG< 999) DXFSkipLine(rIS); + else if (nG<1010) ReadS(); + else if (nG<1060) F = ReadF(); + else if (nG<1072) I = ReadI(); else bStatus = false; } } - if ( bStatus ) - nLastG = nG; - else + if ( !bStatus ) { nG = 0; SetS(); if ( nGCount != 0xffffffff ) { - // InfoBox(NULL,String("Fehler ab Gruppe Nr ")+String(nGCount)).Execute(); + // InfoBox(NULL,String("Error in group # ")+String(nGCount)).Execute(); nGCount=0xffffffff; } } @@ -173,124 +166,37 @@ sal_uInt16 DXFGroupReader::Read() return nG; } - -long DXFGroupReader::GetI(sal_uInt16 nG) const -{ - sal_Int32 nRetValue = 0; - if ( ( nG >= 60 ) && ( nG <= 79 ) ) - nRetValue = I60_79[ nG - 60 ]; - else if ( ( nG >= 90 ) && ( nG <= 99 ) ) - nRetValue = I90_99[ nG - 90 ]; - else if ( ( nG >= 170 ) && ( nG <= 175 ) ) - nRetValue = I170_175[ nG - 170 ]; - else if ( ( nG >= 1060 ) && ( nG <= 1079 ) ) - nRetValue = I1060_1079[ nG - 1060 ]; - return nRetValue; -} - -double DXFGroupReader::GetF(sal_uInt16 nG) const -{ - nG-=10; - if (nG<50) return F10_59[nG]; - else { - nG-=130; - if (nG<8) return F140_147[nG]; - else { - nG-=70; - if (nG<30) return F210_239[nG]; - else { - nG-=800; - if (nG<50) return F1010_1059[nG]; - else return 0; - } - } - } -} - -const char * DXFGroupReader::GetS(sal_uInt16 nG) const -{ - if (nG<10) return S0_9[nG]; - else if ( nG == 100 ) - return S100; - else if ( nG == 102 ) - return S102; - else - { - nG-=999; - if (nG<11) return S999_1009[nG]; - else return NULL; - } -} - -void DXFGroupReader::SetF(sal_uInt16 nG, double fF) -{ - nG-=10; - if (nG<50) F10_59[nG]=fF; - else { - nG-=130; - if (nG<8) F140_147[nG]=fF; - else { - nG-=70; - if (nG<30) F210_239[nG]=fF; - else { - nG-=800; - if (nG<50) F1010_1059[nG]=fF; - } - } - } -} - - void DXFGroupReader::SetS() { - strncpy(S0_9[0], "EOF", DXF_MAX_STRING_LEN); - S0_9[0][DXF_MAX_STRING_LEN] = 0; -} - - -void DXFGroupReader::ReadLine(char * ptgt) -{ - OString aStr = DXFReadLine(rIS); - - size_t nLen = aStr.getLength(); - if ( nLen > DXF_MAX_STRING_LEN ) - nLen = DXF_MAX_STRING_LEN; - - memcpy( ptgt, aStr.getStr(), nLen ); - ptgt[ nLen ] = 0x00; + S = "EOF"; } - long DXFGroupReader::ReadI() { - char sl[DXF_MAX_STRING_LEN+1],*p; - long res,nv; - - ReadLine(sl); - - p=sl; + OString s = DXFReadLine(rIS); + char *p=s.pData->buffer; + const char *end = s.pData->buffer + s.pData->length; - while(*p==0x20) p++; + while((p != end) && (*p==0x20)) p++; - if ((*p<'0' || *p>'9') && *p!='-') { + if ((p == end) || ((*p<'0' || *p>'9') && *p!='-')) { bStatus=false; return 0; } - if (*p=='-') { + long res = 0, nv = 1; + if (*p == '-') { nv=-1; p++; } - else nv=1; - res=0; - do { - res=res*10+(long)(*p-'0'); + while ((p != end) && *p >= '0' && *p <= '9') { + res=res*10+static_cast<long>(*p-'0'); p++; - } while (*p>='0' && *p<='9'); + } - while (*p==0x20) p++; - if (*p!=0) { + while ((p != end) && (*p==0x20)) p++; + if (p != end) { bStatus=false; return 0; } @@ -298,25 +204,23 @@ long DXFGroupReader::ReadI() return res*nv; } - double DXFGroupReader::ReadF() { - char sl[DXF_MAX_STRING_LEN+1],*p; + OString s = DXFReadLine(rIS); + char *p = s.pData->buffer; + const char *end = s.pData->buffer + s.pData->length; - ReadLine(sl); - p=sl; - while(*p==0x20) p++; - if ((*p<'0' || *p>'9') && *p!='.' && *p!='-') { + while((p != end) && (*p==0x20)) p++; + if ((p == end) || ((*p<'0' || *p>'9') && *p!='.' && *p!='-')) { bStatus=false; return 0.0; } return atof(p); } - -void DXFGroupReader::ReadS(char * ptgt) +void DXFGroupReader::ReadS() { - ReadLine(ptgt); + S = DXFReadLine(rIS); } diff --git a/filter/source/graphicfilter/idxf/dxfgrprd.hxx b/filter/source/graphicfilter/idxf/dxfgrprd.hxx index d1fb88060d10..e8429b53bd73 100644 --- a/filter/source/graphicfilter/idxf/dxfgrprd.hxx +++ b/filter/source/graphicfilter/idxf/dxfgrprd.hxx @@ -24,18 +24,13 @@ #include <tools/stream.hxx> -#define DXF_MAX_STRING_LEN 256 // Max Stringlaenge (ohne die 0) - class DXFGroupReader { public: - // note: - // sizeof(DXFGroupReader) is big, so only create dynamically - - DXFGroupReader( SvStream & rIStream, sal_uInt16 nMinPercent, sal_uInt16 nMaxPercent ); + DXFGroupReader( SvStream & rIStream ); bool GetStatus() const; @@ -45,6 +40,7 @@ public: // Reads next group and returns the group code. // In case of an error GetStatus() returns sal_False, group code will be set // to 0 and SetS(0,"EOF") will be executed. + bool Read(sal_uInt16 nExpectedG) { return Read() == nExpectedG; } sal_uInt16 GetG() const; // Return the last group code (the one the last Read() did return). @@ -59,57 +55,34 @@ public: // This read must have returned a group code for datatype Floatingpoint. // If not 0 is returend - const char * GetS() const; + const OString& GetS() const; // Returns the string of the group which was read earlier with Read(). // This read must have returned a group code for datatype String. // If not NULL is returend - // The following three methods work like the above execp that a different than the - // current group code can bet set. (DXFGroupReader stroes the parameters of all - // group codes. Therefore it is possible to first Read() some groups and then analyze - // them afterwards.) - - long GetI(sal_uInt16 nG) const; - double GetF(sal_uInt16 nG) const; - const char * GetS(sal_uInt16 nG) const; - // The following methods can change the current values of group codes // (e.g. to set default values, before 'blindly' reading lots of groups) - void SetF(sal_uInt16 nG, double fF); void SetS(); // (will be copied) private: - void ReadLine(char * ptgt); long ReadI(); double ReadF(); - void ReadS(char * ptgt); + void ReadS(); SvStream & rIS; - sal_uInt16 nIBuffSize,nIBuffPos; bool bStatus; sal_uInt16 nLastG; sal_uLong nGCount; - sal_uLong nMinPercent; - sal_uLong nMaxPercent; - sal_uLong nLastPercent; sal_uLong nFileSize; - char S0_9 [10][DXF_MAX_STRING_LEN+1]; // Strings group codes 0..9 - double F10_59 [50]; // Floats group codes 10..59 - long I60_79 [20]; // Integers group codes 60..79 - long I90_99 [10]; - char S100 [DXF_MAX_STRING_LEN+1]; - char S102 [DXF_MAX_STRING_LEN+1]; - double F140_147 [ 8]; // Floats group codes 140..147 - long I170_175 [ 6]; // Integers group codes 170..175 - double F210_239 [30]; // Floats group codes 210..239 - char S999_1009 [11][DXF_MAX_STRING_LEN+1]; // Strings group codes 999..1009 - double F1010_1059[50]; // Floats group codes 1010..1059 - long I1060_1079[20]; // Integers group codes 1060..1079 - + OString S; + union { + double F; + long I; + }; }; @@ -131,17 +104,17 @@ inline sal_uInt16 DXFGroupReader::GetG() const inline long DXFGroupReader::GetI() const { - return GetI(nLastG); + return I; } inline double DXFGroupReader::GetF() const { - return GetF(nLastG); + return F; } -inline const char * DXFGroupReader::GetS() const +inline const OString& DXFGroupReader::GetS() const { - return GetS(nLastG); + return S; } #endif diff --git a/filter/source/graphicfilter/idxf/dxfreprd.cxx b/filter/source/graphicfilter/idxf/dxfreprd.cxx index d715714427b3..c276e58e8766 100644 --- a/filter/source/graphicfilter/idxf/dxfreprd.cxx +++ b/filter/source/graphicfilter/idxf/dxfreprd.cxx @@ -20,7 +20,7 @@ #include <string.h> #include <dxfreprd.hxx> -#include <boost/scoped_ptr.hpp> +#include "osl/nlsupport.h" //------------------DXFBoundingBox-------------------------------------------- @@ -128,9 +128,10 @@ void DXFPalette::SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sa DXFRepresentation::DXFRepresentation() + : bUseUTF8(false) { - setTextEncoding(RTL_TEXTENCODING_IBM_437); - setGlobalLineTypeScale(1.0); + setTextEncoding(osl_getTextEncodingFromLocale(nullptr)); // Use default encoding if none specified + setGlobalLineTypeScale(1.0); } @@ -139,7 +140,7 @@ DXFRepresentation::~DXFRepresentation() } -bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 nMinPercent, sal_uInt16 nMaxPercent) +bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 /*nMinPercent*/, sal_uInt16 /*nMaxPercent*/) { bool bRes; @@ -147,27 +148,25 @@ bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 nMinPercent, sal_u aBlocks.Clear(); aEntities.Clear(); - boost::scoped_ptr<DXFGroupReader> pDGR(new DXFGroupReader( rIStream, nMinPercent, nMaxPercent )); + DXFGroupReader DGR( rIStream ); - pDGR->Read(); - while (pDGR->GetG()!=0 || strcmp(pDGR->GetS(),"EOF")!=0) { - if (pDGR->GetG()==0 && strcmp(pDGR->GetS(),"SECTION")==0) { - if (pDGR->Read()!=2) { - pDGR->SetError(); + DGR.Read(); + while (DGR.GetG()!=0 || (DGR.GetS() != "EOF")) { + if (DGR.GetG()==0 && DGR.GetS() == "SECTION") { + if (DGR.Read()!=2) { + DGR.SetError(); break; } - if (strcmp(pDGR->GetS(),"HEADER" )==0) ReadHeader(*pDGR); - else if (strcmp(pDGR->GetS(),"TABLES" )==0) aTables.Read(*pDGR); - else if (strcmp(pDGR->GetS(),"BLOCKS" )==0) aBlocks.Read(*pDGR); - else if (strcmp(pDGR->GetS(),"ENTITIES")==0) aEntities.Read(*pDGR); - else pDGR->Read(); + if (DGR.GetS() == "HEADER") ReadHeader(DGR); + else if (DGR.GetS() == "TABLES") aTables.Read(DGR); + else if (DGR.GetS() == "BLOCKS") aBlocks.Read(DGR); + else if (DGR.GetS() == "ENTITIES") aEntities.Read(DGR); + else DGR.Read(); } - else pDGR->Read(); + else DGR.Read(); } - bRes=pDGR->GetStatus(); - - pDGR.reset(); + bRes=DGR.GetStatus(); if (bRes && aBoundingBox.bEmpty) CalcBoundingBox(aEntities,aBoundingBox); @@ -175,55 +174,72 @@ bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 nMinPercent, sal_u return bRes; } - void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR) { - - while (rDGR.GetG()!=0 || (strcmp(rDGR.GetS(),"EOF")!=0 && strcmp(rDGR.GetS(),"ENDSEC")!=0) ) - { - if (rDGR.GetG()==9) { - if (strcmp(rDGR.GetS(),"$EXTMIN")==0 || - strcmp(rDGR.GetS(),"$EXTMAX")==0) - { - DXFVector aVector; - rDGR.SetF(10,0.0); - rDGR.SetF(20,0.0); - rDGR.SetF(30,0.0); - do { - rDGR.Read(); - } while (rDGR.GetG()!=9 && rDGR.GetG()!=0); - aVector.fx=rDGR.GetF(10); - aVector.fy=rDGR.GetF(20); - aVector.fz=rDGR.GetF(30); - aBoundingBox.Union(aVector); - } else { - if (strcmp(rDGR.GetS(),"$DWGCODEPAGE")==0) - { - 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); - } - } - else if (strcmp(rDGR.GetS(),"$LTSCALE")==0) - { - rDGR.Read(); - setGlobalLineTypeScale(getGlobalLineTypeScale() * rDGR.GetF()); - } - else rDGR.Read(); - } - } - else rDGR.Read(); - } + while (rDGR.GetG()!=0 || (rDGR.GetS() != "EOF" && rDGR.GetS() != "ENDSEC") ) + { + if (rDGR.GetG()==9) { + if (rDGR.GetS() == "$EXTMIN" || + rDGR.GetS() == "$EXTMAX") + { + DXFVector aVector; + while (rDGR.Read()!=9 && rDGR.GetG()!=0) { + switch (rDGR.GetG()) { + case 10: aVector.fx = rDGR.GetF(); break; + case 20: aVector.fy = rDGR.GetF(); break; + case 30: aVector.fz = rDGR.GetF(); break; + } + } + aBoundingBox.Union(aVector); + } + else if (rDGR.GetS() == "$ACADVER") + { + if (!rDGR.Read(1)) + continue; + if (rDGR.GetS() >= "AC1021") + bUseUTF8 = true; + } + else if (rDGR.GetS() == "$DWGCODEPAGE") + { + if (!rDGR.Read(3)) + continue; + + // FIXME: we really need a whole table of + // $DWGCODEPAGE to encodings mappings + if ( (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_932")) || + (rDGR.GetS().equalsIgnoreAsciiCase("DOS932")) ) + { + setTextEncoding(RTL_TEXTENCODING_MS_932); + } + else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_936")) + { + setTextEncoding(RTL_TEXTENCODING_MS_936); + } + else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_949")) + { + setTextEncoding(RTL_TEXTENCODING_MS_949); + } + else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_950")) + { + setTextEncoding(RTL_TEXTENCODING_MS_950); + } + else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_1251")) + { + setTextEncoding(RTL_TEXTENCODING_MS_1251); + } + } + else if (rDGR.GetS() == "$LTSCALE") + { + if (!rDGR.Read(40)) + continue; + setGlobalLineTypeScale(getGlobalLineTypeScale() * rDGR.GetF()); + } + else rDGR.Read(); + } + else rDGR.Read(); + } } - void DXFRepresentation::CalcBoundingBox(const DXFEntities & rEntities, DXFBoundingBox & rBox) { @@ -373,4 +389,57 @@ void DXFRepresentation::CalcBoundingBox(const DXFEntities & rEntities, } } +namespace { + inline bool lcl_isDec(sal_Unicode ch) + { + return ch >= L'0' && ch <= L'9'; + } + inline bool lcl_isHex(sal_Unicode ch) + { + return lcl_isDec(ch) || (ch >= L'A' && ch <= L'F') || (ch >= L'a' && ch <= L'f'); + } +} + +OUString DXFRepresentation::ToOUString(const OString& s, bool bSpecials) const +{ + OUString result = OStringToOUString(s, getTextEncoding()); + if (bSpecials) { + result = result.replaceAll("%%o", "") // Overscore - simply remove + .replaceAll("%%u", "") // Underscore - simply remove + .replaceAll("%%d", OUString(sal_Unicode(L'\u00B0'))) // Degrees symbol (°) + .replaceAll("%%p", OUString(sal_Unicode(L'\u00B1'))) // Tolerance symbol (±) + .replaceAll("%%c", OUString(sal_Unicode(L'\u2205'))) // Diameter symbol + .replaceAll("%%%", "%"); // Percent symbol + + sal_Int32 pos = result.indexOf("%%"); // %%nnn, where nnn - 3-digit decimal ASCII code + while (pos != -1 && pos <= result.getLength() - 5) { + OUString asciiNum = result.copy(pos + 2, 3); + if (lcl_isDec(asciiNum[0]) && + lcl_isDec(asciiNum[1]) && + lcl_isDec(asciiNum[2])) + { + char ch = static_cast<char>(asciiNum.toUInt32()); + OUString codePt(&ch, 1, mEnc); + result = result.replaceAll(result.copy(pos, 5), codePt, pos); + } + pos = result.indexOf("%%", pos + 1); + } + + pos = result.indexOf("\\U+"); // \U+XXXX, where XXXX - 4-digit hex unicode + while (pos != -1 && pos <= result.getLength() - 7) { + OUString codePtNum = result.copy(pos + 3, 4); + if (lcl_isHex(codePtNum[0]) && + lcl_isHex(codePtNum[1]) && + lcl_isHex(codePtNum[2]) && + lcl_isHex(codePtNum[3])) + { + OUString codePt(static_cast<sal_Unicode>(codePtNum.toUInt32(16))); + result = result.replaceAll(result.copy(pos, 7), codePt, pos); + } + pos = result.indexOf("\\U+", pos + 1); + } + } + return result; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/graphicfilter/idxf/dxfreprd.hxx b/filter/source/graphicfilter/idxf/dxfreprd.hxx index 6a43ddd8af7c..a2e6d7aabb48 100644 --- a/filter/source/graphicfilter/idxf/dxfreprd.hxx +++ b/filter/source/graphicfilter/idxf/dxfreprd.hxx @@ -92,16 +92,19 @@ public: rtl_TextEncoding mEnc; // $DWGCODEPAGE + bool bUseUTF8; // for AC1021 and higher + double mfGlobalLineTypeScale; // $LTSCALE DXFRepresentation(); ~DXFRepresentation(); - rtl_TextEncoding getTextEncoding() const; - void setTextEncoding(rtl_TextEncoding aEnc); + rtl_TextEncoding getTextEncoding() const; + void setTextEncoding(rtl_TextEncoding aEnc); + OUString ToOUString(const OString& s, bool bSpecials=false) const; - double getGlobalLineTypeScale() const; - void setGlobalLineTypeScale(double fGlobalLineTypeScale); + double getGlobalLineTypeScale() const; + void setGlobalLineTypeScale(double fGlobalLineTypeScale); bool Read( SvStream & rIStream, sal_uInt16 nMinPercent, sal_uInt16 nMaxPercent); // Reads complete DXF file. @@ -120,7 +123,7 @@ private: inline sal_uInt8 DXFPalette::GetRed(sal_uInt8 nIndex) const { return pRed[nIndex]; } inline sal_uInt8 DXFPalette::GetGreen(sal_uInt8 nIndex) const { return pGreen[nIndex]; } inline sal_uInt8 DXFPalette::GetBlue(sal_uInt8 nIndex) const { return pBlue[nIndex]; } -inline rtl_TextEncoding DXFRepresentation::getTextEncoding() const { return mEnc; } +inline rtl_TextEncoding DXFRepresentation::getTextEncoding() const { return bUseUTF8 ? RTL_TEXTENCODING_UTF8 : mEnc; } inline void DXFRepresentation::setTextEncoding(rtl_TextEncoding aEnc) { mEnc = aEnc; } inline double DXFRepresentation::getGlobalLineTypeScale() const { return mfGlobalLineTypeScale; } inline void DXFRepresentation::setGlobalLineTypeScale(double fGlobalLineTypeScale) { mfGlobalLineTypeScale = fGlobalLineTypeScale; } diff --git a/filter/source/graphicfilter/idxf/dxftblrd.cxx b/filter/source/graphicfilter/idxf/dxftblrd.cxx index be1d6c062c34..26d96dd3a653 100644 --- a/filter/source/graphicfilter/idxf/dxftblrd.cxx +++ b/filter/source/graphicfilter/idxf/dxftblrd.cxx @@ -40,10 +40,10 @@ void DXFLType::Read(DXFGroupReader & rDGR) switch (rDGR.GetG()) { case 2: - m_sName = OString(rDGR.GetS()); + m_sName = rDGR.GetS(); break; case 3: - m_sDescription = OString(rDGR.GetS()); + m_sDescription = rDGR.GetS(); break; case 70: nFlags=rDGR.GetI(); @@ -93,10 +93,10 @@ void DXFLayer::Read(DXFGroupReader & rDGR) switch(rDGR.GetG()) { case 2: - m_sName = OString(rDGR.GetS()); + m_sName = rDGR.GetS(); break; case 6: - m_sLineType = OString(rDGR.GetS()); + m_sLineType = rDGR.GetS(); break; case 70: nFlags=rDGR.GetI(); @@ -128,13 +128,13 @@ void DXFStyle::Read(DXFGroupReader & rDGR) switch(rDGR.GetG()) { case 2: - m_sName = OString(rDGR.GetS()); + m_sName = rDGR.GetS(); break; case 3: - m_sPrimFontFile = OString(rDGR.GetS()); + m_sPrimFontFile = rDGR.GetS(); break; case 4: - m_sBigFontFile = OString(rDGR.GetS()); + m_sBigFontFile = rDGR.GetS(); break; case 70: nFlags=rDGR.GetI(); @@ -204,7 +204,7 @@ void DXFVPort::Read(DXFGroupReader & rDGR) switch(rDGR.GetG()) { case 2: - m_sName = OString(rDGR.GetS()); + m_sName = rDGR.GetS(); break; case 10: fMinX=rDGR.GetF(); break; case 11: fMaxX=rDGR.GetF(); break; @@ -284,27 +284,27 @@ void DXFTables::Read(DXFGroupReader & rDGR) for (;;) { while (rDGR.GetG()!=0) rDGR.Read(); - if (strcmp(rDGR.GetS(),"EOF")==0 || - strcmp(rDGR.GetS(),"ENDSEC")==0) break; - else if (strcmp(rDGR.GetS(),"LTYPE")==0) { + if (rDGR.GetS() == "EOF" || + rDGR.GetS() == "ENDSEC") break; + else if (rDGR.GetS() == "LTYPE") { pLT=new DXFLType; pLT->Read(rDGR); *ppLT=pLT; ppLT=&(pLT->pSucc); } - else if (strcmp(rDGR.GetS(),"LAYER")==0) { + else if (rDGR.GetS() == "LAYER") { pLa=new DXFLayer; pLa->Read(rDGR); *ppLa=pLa; ppLa=&(pLa->pSucc); } - else if (strcmp(rDGR.GetS(),"STYLE")==0) { + else if (rDGR.GetS() == "STYLE") { pSt=new DXFStyle; pSt->Read(rDGR); *ppSt=pSt; ppSt=&(pSt->pSucc); } - else if (strcmp(rDGR.GetS(),"VPORT")==0) { + else if (rDGR.GetS() == "VPORT") { pVP=new DXFVPort; pVP->Read(rDGR); *ppVP=pVP; |