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
* 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<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
*/
@ -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_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;
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,