From 6a219c5ed4f7ab524037c291215c0de76ffb673a Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 23 Nov 2021 13:11:56 +0200 Subject: [PATCH] Port set version bug from solvespace fork and cleanup version handling in DRW_TextCodec. One of the most intrusive changes in QGIS' fork was that the debugging code was replaced with hardcoded changes to redirect the output to QGIS' internal logging mechanism. In this PR I've setup an interface to allow clients to create custom output debugging classes and assign these to be used by the library. This will allow me to remove all the related downstream changes in QGIS' fork and re-sync these files back to upstream. Interface for debug printers. --- src/libs/vdxf/libdxfrw/drw_base.cpp | 19 ++++ src/libs/vdxf/libdxfrw/drw_base.h | 77 +++++++++++++--- src/libs/vdxf/libdxfrw/intern/drw_dbg.cpp | 56 ++++++------ src/libs/vdxf/libdxfrw/intern/drw_dbg.h | 11 ++- .../vdxf/libdxfrw/intern/drw_textcodec.cpp | 89 +++++++++++++------ src/libs/vdxf/libdxfrw/intern/drw_textcodec.h | 7 +- src/libs/vdxf/vdxf.pri | 1 + 7 files changed, 189 insertions(+), 71 deletions(-) create mode 100644 src/libs/vdxf/libdxfrw/drw_base.cpp diff --git a/src/libs/vdxf/libdxfrw/drw_base.cpp b/src/libs/vdxf/libdxfrw/drw_base.cpp new file mode 100644 index 000000000..219c1b643 --- /dev/null +++ b/src/libs/vdxf/libdxfrw/drw_base.cpp @@ -0,0 +1,19 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include "drw_base.h" +#include "intern/drw_dbg.h" + +void DRW::setCustomDebugPrinter(DebugPrinter *printer) +{ + DRW_dbg::getInstance()->setCustomDebugPrinter(std::unique_ptr(printer)); +} diff --git a/src/libs/vdxf/libdxfrw/drw_base.h b/src/libs/vdxf/libdxfrw/drw_base.h index ea395e919..2c5c17a74 100644 --- a/src/libs/vdxf/libdxfrw/drw_base.h +++ b/src/libs/vdxf/libdxfrw/drw_base.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -100,16 +101,46 @@ namespace DRW { //! Version numbers for the DXF Format. enum Version { - UNKNOWNV, /*!< UNKNOWN VERSION. */ - AC1006, /*!< R10. */ - AC1009, /*!< R11 & R12. */ - AC1012, /*!< R13. */ - AC1014, /*!< R14. */ - AC1015, /*!< ACAD 2000. */ - AC1018, /*!< ACAD 2004. */ - AC1021, /*!< ACAD 2007. */ - AC1024, /*!< ACAD 2010. */ - AC1027 /*!< ACAD 2013. */ + UNKNOWNV, //!< UNKNOWN VERSION. + MC00, //!< DWG Release 1.1 + AC12, //!< DWG Release 1.2 + AC14, //!< DWG Release 1.4 + AC150, //!< DWG Release 2.0 + AC210, //!< DWG Release 2.10 + AC1002, //!< DWG Release 2.5 + AC1003, //!< DWG Release 2.6 + AC1004, //!< DWG Relase 9 + AC1006, //!< DWG Release 10 (R10) + AC1009, //!< DWG Release 11/12 (LT R1/R2) (R11 & R12) + AC1012, //!< DWG Release 13 (LT95) (R13) + AC1014, //!< DWG Release 14/14.01 (LT97/LT98) (R14) + AC1015, //!< AutoCAD 2000/2000i/2002 (ACAD 2000) + AC1018, //!< AutoCAD 2004/2005/2006 (ACAD 2004) + AC1021, //!< AutoCAD 2007/2008/2009 (ACAD 2007) + AC1024, //!< AutoCAD 2010/2011/2012 (ACAD 2010) + AC1027, //!< AutoCAD 2013/2014/2015/2016/2017 (ACAD 2013) + AC1032, //!< AutoCAD 2018/2019/2020 (ACAD 2018) +}; + +const std::unordered_map< const char*, DRW::Version > dwgVersionStrings { + { "MC0.0", DRW::MC00 }, + { "AC1.2", DRW::AC12 }, + { "AC1.4", DRW::AC14 }, + { "AC1.50", DRW::AC150 }, + { "AC2.10", DRW::AC210 }, + { "AC1002", DRW::AC1002 }, + { "AC1003", DRW::AC1003 }, + { "AC1004", DRW::AC1004 }, + { "AC1006", DRW::AC1006 }, + { "AC1009", DRW::AC1009 }, + { "AC1012", DRW::AC1012 }, + { "AC1014", DRW::AC1014 }, + { "AC1015", DRW::AC1015 }, + { "AC1018", DRW::AC1018 }, + { "AC1021", DRW::AC1021 }, + { "AC1024", DRW::AC1024 }, + { "AC1027", DRW::AC1027 }, + { "AC1032", DRW::AC1032 }, }; enum error { @@ -133,6 +164,32 @@ enum class DebugLevel { Debug }; +/** + * Interface for debug printers. + * + * The base class is silent and ignores all debugging. + */ +class DebugPrinter { +public: + virtual void printS(const std::string &s){(void)s;} + virtual void printI(long long int i){(void)i;} + virtual void printUI(long long unsigned int i){(void)i;} + virtual void printD(double d){(void)d;} + virtual void printH(long long int i){(void)i;} + virtual void printB(int i){(void)i;} + virtual void printHL(int c, int s, int h){(void)c;(void)s;(void)h;} + virtual void printPT(double x, double y, double z){(void)x;(void)y;(void)z;} + DebugPrinter()=default; + virtual ~DebugPrinter()=default; +}; + +/** + * Sets a custom debug printer to use when outputting debug messages. + * + * Ownership of `printer` is transferred. + */ +void setCustomDebugPrinter( DebugPrinter* printer ); + //! Special codes for colors enum ColorCodes { black = 250, diff --git a/src/libs/vdxf/libdxfrw/intern/drw_dbg.cpp b/src/libs/vdxf/libdxfrw/intern/drw_dbg.cpp index 52cd204a2..4a99e0921 100644 --- a/src/libs/vdxf/libdxfrw/intern/drw_dbg.cpp +++ b/src/libs/vdxf/libdxfrw/intern/drw_dbg.cpp @@ -18,21 +18,8 @@ DRW_dbg *DRW_dbg::instance{nullptr}; /*********private clases*************/ -class print_none { -public: - virtual void printS(const std::string &s){(void)s;} - virtual void printI(long long int i){(void)i;} - virtual void printUI(long long unsigned int i){(void)i;} - virtual void printD(double d){(void)d;} - virtual void printH(long long int i){(void)i;} - virtual void printB(int i){(void)i;} - virtual void printHL(int c, int s, int h){(void)c;(void)s;(void)h;} - virtual void printPT(double x, double y, double z){(void)x;(void)y;(void)z;} - print_none()= default; - virtual ~print_none()=default; -}; -class print_debug : public print_none { +class print_debug : public DRW::DebugPrinter { public: void printS(const std::string &s) override; void printI(long long int i) override; @@ -56,17 +43,28 @@ DRW_dbg *DRW_dbg::getInstance(){ } DRW_dbg::DRW_dbg() : - prClass(std::make_unique()) -{} + debugPrinter(std::make_unique()) +{ + currentPrinter = &silentDebug; +} + +void DRW_dbg::setCustomDebugPrinter(std::unique_ptr printer) +{ + debugPrinter = std::move( printer ); + if (level == Level::Debug){ + currentPrinter = debugPrinter.get(); + } +} void DRW_dbg::setLevel(Level lvl){ level = lvl; switch (level){ case Level::Debug: - prClass = std::make_unique(); + currentPrinter = debugPrinter.get(); break; default: - prClass = std::make_unique(); + currentPrinter = &silentDebug; + break; } } @@ -75,46 +73,46 @@ DRW_dbg::Level DRW_dbg::getLevel() const{ } void DRW_dbg::print(const std::string &s){ - prClass->printS(s); + currentPrinter->printS(s); } void DRW_dbg::print(int i){ - prClass->printI(i); + currentPrinter->printI(i); } void DRW_dbg::print(unsigned int i){ - prClass->printUI(i); + currentPrinter->printUI(i); } void DRW_dbg::print(long long int i){ - prClass->printI(i); + currentPrinter->printI(i); } void DRW_dbg::print(long unsigned int i){ - prClass->printUI(i); + currentPrinter->printUI(i); } void DRW_dbg::print(long long unsigned int i){ - prClass->printUI(i); + currentPrinter->printUI(i); } void DRW_dbg::print(double d){ - prClass->printD(d); + currentPrinter->printD(d); } void DRW_dbg::printH(long long int i){ - prClass->printH(i); + currentPrinter->printH(i); } void DRW_dbg::printB(int i){ - prClass->printB(i); + currentPrinter->printB(i); } void DRW_dbg::printHL(int c, int s, int h){ - prClass->printHL(c, s, h); + currentPrinter->printHL(c, s, h); } void DRW_dbg::printPT(double x, double y, double z){ - prClass->printPT(x, y, z); + currentPrinter->printPT(x, y, z); } void print_debug::printS(const std::string &s){ diff --git a/src/libs/vdxf/libdxfrw/intern/drw_dbg.h b/src/libs/vdxf/libdxfrw/intern/drw_dbg.h index ab752ac09..81a3d8f39 100644 --- a/src/libs/vdxf/libdxfrw/intern/drw_dbg.h +++ b/src/libs/vdxf/libdxfrw/intern/drw_dbg.h @@ -17,6 +17,7 @@ #include #include #include +#include "../drw_base.h" //#include #define DRW_DBGSL(a) DRW_dbg::getInstance()->setLevel(a) @@ -37,6 +38,11 @@ public: Debug }; void setLevel(Level lvl); + /** + * Sets a custom debug printer to use when non-silent output + * is required. + */ + void setCustomDebugPrinter(std::unique_ptr printer); Level getLevel() const; static DRW_dbg *getInstance(); void print(const std::string &s); @@ -57,8 +63,9 @@ private: ~DRW_dbg(); static DRW_dbg *instance; Level level{Level::None}; - std::ios_base::fmtflags flags{std::cerr.flags()}; - std::unique_ptr prClass; + DRW::DebugPrinter silentDebug{}; + std::unique_ptr< DRW::DebugPrinter > debugPrinter; + DRW::DebugPrinter* currentPrinter{nullptr}; }; diff --git a/src/libs/vdxf/libdxfrw/intern/drw_textcodec.cpp b/src/libs/vdxf/libdxfrw/intern/drw_textcodec.cpp index 6a0bb113e..72dbf92e0 100644 --- a/src/libs/vdxf/libdxfrw/intern/drw_textcodec.cpp +++ b/src/libs/vdxf/libdxfrw/intern/drw_textcodec.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -42,44 +43,78 @@ QMap QtCodecs() {"UTF-16", {"UTF-16", "UTF16", "UTF16-BIT"}}, }; } -} +} // namespace DRW_TextCodec::DRW_TextCodec() : version(DRW::AC1021) {} -void DRW_TextCodec::setVersion(int v, bool dxfFormat){ - if (v == DRW::AC1009 || v == DRW::AC1006) { - version = DRW::AC1009; - cp = "ANSI_1252"; - setCodePage(cp, dxfFormat); - } else if (v == DRW::AC1012 || v == DRW::AC1014 - || v == DRW::AC1015 || v == DRW::AC1018) { - version = DRW::AC1015; -// if (cp.empty()) { //codepage not set, initialize +void DRW_TextCodec::setVersion(DRW::Version v, bool dxfFormat){ + switch (v) + { + case DRW::UNKNOWNV: + case DRW::MC00: + case DRW::AC12: + case DRW::AC14: + case DRW::AC150: + case DRW::AC210: + case DRW::AC1002: + case DRW::AC1003: + case DRW::AC1004: + // unhandled? + break; + case DRW::AC1006: + case DRW::AC1009: + { + version = DRW::AC1009; cp = "ANSI_1252"; setCodePage(cp, dxfFormat); -// } - } else { - version = DRW::AC1021; - if (dxfFormat) - cp = "UTF-8";//RLZ: can be UCS2 or UTF-16 16bits per char - else - cp = "UTF-16";//RLZ: can be UCS2 or UTF-16 16bits per char - setCodePage(cp, dxfFormat); + break; + } + case DRW::AC1012: + case DRW::AC1014: + case DRW::AC1015: + case DRW::AC1018: + { + version = DRW::AC1015; +// if (cp.empty()) { //codepage not set, initialize + cp = "ANSI_1252"; + setCodePage(cp, dxfFormat); +// } + break; + } + case DRW::AC1021: + case DRW::AC1024: + case DRW::AC1027: + case DRW::AC1032: + { + version = DRW::AC1021; + if (dxfFormat) + { + cp = "UTF-8";//RLZ: can be UCS2 or UTF-16 16bits per char + } + else + { + cp = "UTF-16";//RLZ: can be UCS2 or UTF-16 16bits per char + } + setCodePage(cp, dxfFormat); + break; + } + default: + break; } } -void DRW_TextCodec::setVersion(const std::string &versionStr, bool dxfFormat){ - if (versionStr == "AC1009" || versionStr == "AC1006") { - setVersion(DRW::AC1009, dxfFormat); - } else if (versionStr == "AC1012" || versionStr == "AC1014" - || versionStr == "AC1015" || versionStr == "AC1018") { - setVersion(DRW::AC1015, dxfFormat); - } - else +void DRW_TextCodec::setVersion(const std::string &v, bool dxfFormat){ + version = DRW::UNKNOWNV; + for (auto dwgVersionString : DRW::dwgVersionStrings) { - setVersion(DRW::AC1021, dxfFormat); + if (std::strcmp( v.c_str(), dwgVersionString.first ) == 0) + { + version = dwgVersionString.second; + setVersion( dwgVersionString.second, dxfFormat); + break; + } } } diff --git a/src/libs/vdxf/libdxfrw/intern/drw_textcodec.h b/src/libs/vdxf/libdxfrw/intern/drw_textcodec.h index 634496c22..3f1fca855 100644 --- a/src/libs/vdxf/libdxfrw/intern/drw_textcodec.h +++ b/src/libs/vdxf/libdxfrw/intern/drw_textcodec.h @@ -3,6 +3,7 @@ #include #include +#include "../drw_base.h" class QTextCodec; class QStringList; @@ -15,8 +16,8 @@ public: std::string fromUtf8(const std::string &s); std::string toUtf8(const std::string &s); int getVersion() const {return version;} - void setVersion(const std::string &versionStr, bool dxfFormat); - void setVersion(int v, bool dxfFormat); + void setVersion(const std::string &v, bool dxfFormat); + void setVersion(DRW::Version v, bool dxfFormat); void setCodePage(const std::string &c, bool dxfFormat); std::string getCodePage() const {return cp;} @@ -28,7 +29,7 @@ private: private: Q_DISABLE_COPY(DRW_TextCodec) - int version; + DRW::Version version{DRW::UNKNOWNV}; std::string cp{}; QTextCodec *conv{nullptr}; }; diff --git a/src/libs/vdxf/vdxf.pri b/src/libs/vdxf/vdxf.pri index ce0441c08..f38e1199b 100644 --- a/src/libs/vdxf/vdxf.pri +++ b/src/libs/vdxf/vdxf.pri @@ -2,6 +2,7 @@ # This need for corect working file translations.pro SOURCES += \ + $$PWD/libdxfrw/drw_base.cpp \ $$PWD/vdxfengine.cpp \ $$PWD/vdxfpaintdevice.cpp \ $$PWD/libdxfrw/intern/drw_dbg.cpp \