From 272ec53e03381d4f902ae7c5adf6ed463be042df Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Tue, 24 Nov 2020 00:55:28 -0500 Subject: [PATCH] Make DXF import slightly prettier by copying text style width factor It's impossible to replicate the original cad font style but replicating width factors at least gives you something closer. --- pcbnew/import_gfx/dxf_import_plugin.cpp | 44 +++++++++++++++++++++++-- pcbnew/import_gfx/dxf_import_plugin.h | 36 +++++++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index 3e50ddeb65..8ccb4cebfd 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -72,6 +72,9 @@ * by following the object to world conversion * 6. Blocks are virtual groups, blocks must be placed by a INSERT entity * 7. Blocks may be repeated multiple times + * 8. There is no sane way to make text look perfect like the original CAD. + * DXF simply does mpt secifying text/font enough to make it portable. + * We however make do try to get it somewhat close/visually appealing. */ @@ -328,6 +331,24 @@ DXF_IMPORT_BLOCK* DXF_IMPORT_PLUGIN::getImportBlock( const std::string& aBlockNa } +DXF_IMPORT_STYLE* DXF_IMPORT_PLUGIN::getImportStyle( const std::string& aStyleName ) +{ + DXF_IMPORT_STYLE* style = nullptr; + wxString styleName = wxString::FromUTF8( aStyleName.c_str() ); + + if( !styleName.IsEmpty() ) + { + auto resultIt = std::find_if( m_styles.begin(), m_styles.end(), + [styleName]( const auto& it ) { return it->m_name == styleName; } ); + + if( resultIt != m_styles.end() ) + style = resultIt->get(); + } + + return style; +} + + void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData ) { DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() ); @@ -561,9 +582,15 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); + DXF_IMPORT_STYLE* style = getImportStyle( aData.style.c_str() ); + double textHeight = mapDim( aData.height ); - // The 0.9 factor gives a better height/width ratio with our font + // The 0.9 factor gives a better height/width base ratio with our font double charWidth = textHeight * 0.9; + + if( style != nullptr ) + charWidth *= style->m_widthFactor; + double textWidth = charWidth * text.length(); // Rough approximation double textThickness = textHeight/8.0; // Use a reasonable line thickness for this text @@ -691,9 +718,15 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; + DXF_IMPORT_STYLE* style = getImportStyle( aData.style.c_str() ); + double textHeight = mapDim( aData.height ); - // The 0.9 factor gives a better height/width ratio with our font + + // The 0.9 factor gives a better height/width base ratio with our font double charWidth = textHeight * 0.9; + if( style != nullptr ) + charWidth *= style->m_widthFactor; + double textWidth = charWidth * text.length(); // Rough approximation double textThickness = textHeight/8.0; // Use a reasonable line thickness for this text @@ -1143,7 +1176,12 @@ wxString DXF_IMPORT_PLUGIN::toNativeString( const wxString& aData ) void DXF_IMPORT_PLUGIN::addTextStyle( const DL_StyleData& aData ) { - // TODO + wxString name = wxString::FromUTF8( aData.name.c_str() ); + + std::unique_ptr style = + std::make_unique( name, aData.fixedTextHeight, aData.widthFactor, aData.bold, aData.italic ); + + m_styles.push_back( std::move( style ) ); } diff --git a/pcbnew/import_gfx/dxf_import_plugin.h b/pcbnew/import_gfx/dxf_import_plugin.h index e3da7d6147..7431b53dd1 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.h +++ b/pcbnew/import_gfx/dxf_import_plugin.h @@ -151,6 +151,31 @@ public: } }; +/** + * A helper class to hold style settings temporarily during import + */ +class DXF_IMPORT_STYLE +{ +public: + wxString m_name; + double m_textHeight; + double m_widthFactor; + bool m_bold; + bool m_italic; + + GRAPHICS_IMPORTER_BUFFER m_buffer; + + DXF_IMPORT_STYLE( wxString aName, double aTextHeight, double aWidthFactor, bool aBold, bool aItalic ) + { + m_name = aName; + m_textHeight = aTextHeight; + m_widthFactor = aWidthFactor; + m_bold = aBold; + m_italic = aItalic; + } +}; + + /** * DXF Units enum with values as specified in DXF 2012 Specification */ @@ -222,6 +247,7 @@ private: std::vector> m_layers; // List of layers as we import, used just to grab props for objects std::vector> m_blocks; // List of blocks as we import + std::vector> m_styles; // List of blocks as we import DXF_IMPORT_BLOCK* m_currentBlock; public: @@ -352,10 +378,18 @@ private: * Returns the import layer block * * @param aBlockName is the raw string from dxflib - * @returns The given block by name or nullptf if not found + * @returns The given block by name or nullptr if not found */ DXF_IMPORT_BLOCK* getImportBlock( const std::string& aBlockName ); + /** + * Returns the import style + * + * @param aStyleName is the raw string from dxflib + * @returns The given style by name or nullptr if not found + */ + DXF_IMPORT_STYLE* getImportStyle( const std::string& aStyleName ); + // Functions to aid in the creation of a Polyline void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth ); void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd,