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.
This commit is contained in:
Marek Roszko 2020-11-24 00:55:28 -05:00
parent 52d8b70d3a
commit 272ec53e03
2 changed files with 76 additions and 4 deletions

View File

@ -72,6 +72,9 @@
* by following the object to world conversion * by following the object to world conversion
* 6. Blocks are virtual groups, blocks must be placed by a INSERT entity * 6. Blocks are virtual groups, blocks must be placed by a INSERT entity
* 7. Blocks may be repeated multiple times * 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 ) void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData )
{ {
DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() ); 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() ) ); wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
DXF_IMPORT_STYLE* style = getImportStyle( aData.style.c_str() );
double textHeight = mapDim( aData.height ); 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; double charWidth = textHeight * 0.9;
if( style != nullptr )
charWidth *= style->m_widthFactor;
double textWidth = charWidth * text.length(); // Rough approximation double textWidth = charWidth * text.length(); // Rough approximation
double textThickness = textHeight/8.0; // Use a reasonable line thickness for this text 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 text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
wxString attrib, tmp; wxString attrib, tmp;
DXF_IMPORT_STYLE* style = getImportStyle( aData.style.c_str() );
double textHeight = mapDim( aData.height ); 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; double charWidth = textHeight * 0.9;
if( style != nullptr )
charWidth *= style->m_widthFactor;
double textWidth = charWidth * text.length(); // Rough approximation double textWidth = charWidth * text.length(); // Rough approximation
double textThickness = textHeight/8.0; // Use a reasonable line thickness for this text 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 ) void DXF_IMPORT_PLUGIN::addTextStyle( const DL_StyleData& aData )
{ {
// TODO wxString name = wxString::FromUTF8( aData.name.c_str() );
std::unique_ptr<DXF_IMPORT_STYLE> style =
std::make_unique<DXF_IMPORT_STYLE>( name, aData.fixedTextHeight, aData.widthFactor, aData.bold, aData.italic );
m_styles.push_back( std::move( style ) );
} }

View File

@ -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 * DXF Units enum with values as specified in DXF 2012 Specification
*/ */
@ -222,6 +247,7 @@ private:
std::vector<std::unique_ptr<DXF_IMPORT_LAYER>> m_layers; // List of layers as we import, used just to grab props for objects std::vector<std::unique_ptr<DXF_IMPORT_LAYER>> m_layers; // List of layers as we import, used just to grab props for objects
std::vector<std::unique_ptr<DXF_IMPORT_BLOCK>> m_blocks; // List of blocks as we import std::vector<std::unique_ptr<DXF_IMPORT_BLOCK>> m_blocks; // List of blocks as we import
std::vector<std::unique_ptr<DXF_IMPORT_STYLE>> m_styles; // List of blocks as we import
DXF_IMPORT_BLOCK* m_currentBlock; DXF_IMPORT_BLOCK* m_currentBlock;
public: public:
@ -352,10 +378,18 @@ private:
* Returns the import layer block * Returns the import layer block
* *
* @param aBlockName is the raw string from dxflib * @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 ); 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 // Functions to aid in the creation of a Polyline
void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth ); void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth );
void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd,