diff --git a/sources/createdxf.cpp b/sources/createdxf.cpp index 073ec257a..1a82fb14f 100644 --- a/sources/createdxf.cpp +++ b/sources/createdxf.cpp @@ -27,6 +27,20 @@ const double Createdxf::sheetWidth = 4000; const double Createdxf::sheetHeight = 2700; double Createdxf::xScale = 1; + +namespace { + /// @p text on one line. A DXF value ends at the line break, so a break + /// inside a text would shift every group code after it by one line and + /// a reader would take values for codes (FINDINGS F052). Callers that + /// mean several lines split them first; this is the safety net. + QString singleLine(QString text) + { + text.replace(QLatin1String("\r\n"), QLatin1String(" ")); + text.replace(QLatin1Char('\r'), QLatin1Char(' ')); + text.replace(QLatin1Char('\n'), QLatin1Char(' ')); + return text; + } +} double Createdxf::yScale = 1; Createdxf::Createdxf() @@ -727,7 +741,7 @@ void Createdxf::drawText( To_Dxf << 41 << "\r\n"; To_Dxf << xScaleW << "\r\n"; // X Scale To_Dxf << 1 << "\r\n"; - To_Dxf << text << "\r\n"; // Text Value + To_Dxf << singleLine(text) << "\r\n"; // Text Value To_Dxf << 50 << "\r\n"; To_Dxf << rotation << "\r\n"; // Text Rotation file.close(); @@ -780,7 +794,7 @@ void Createdxf::drawTextAligned( To_Dxf << 41 << "\r\n"; To_Dxf << xScaleW << "\r\n"; // X Scale To_Dxf << 1 << "\r\n"; - To_Dxf << text << "\r\n"; // Text Value + To_Dxf << singleLine(text) << "\r\n"; // Text Value To_Dxf << 50 << "\r\n"; To_Dxf << rotation << "\r\n"; // Text Rotation #if 0 diff --git a/sources/titleblocktemplate.cpp b/sources/titleblocktemplate.cpp index f3c0b04a0..79d6b0adf 100644 --- a/sources/titleblocktemplate.cpp +++ b/sources/titleblocktemplate.cpp @@ -1993,32 +1993,58 @@ void TitleBlockTemplate::renderTextCellDxf( } //painter.setFont(text_font); - qreal ratio = 1.0; - if (cell.hadjust) + //A cell can hold several lines, which the screen shows one under the + //other (QPainter::drawText()). A DXF TEXT is a single line, and a line + //break inside one breaks the file (FINDINGS F052), so each line gets + //its own, stacked as the cell's vertical alignment says: the first at + //y1 when aligned to the top, the last at y1 when aligned to the + //bottom, the block centred on y1 otherwise. Spacing as the diagram + //texts' DXF export: 1.6 times the text height. A single line is + //written exactly as before. + const QStringList lines = text.split(QRegularExpression(QStringLiteral("\r\n|\r|\n"))); + const qreal line_spacing = textHeight * Createdxf::yScale * 1.6; + const int last = lines.size() - 1; + for (int i = 0 ; i < lines.size() ; ++i) { - // Scale font width to fit string in cell width w - // As DXF font aspect ratio is implementation dependent we add a fudge-factor based on tests with AutoCAD - int len = text.length() * textHeight * Createdxf::xScale * 1.2; + const QString &line = lines.at(i); + if (line.isEmpty()) continue; - if(len > w) - ratio = (w/len); + qreal offset; // upward, from y1 + if (vAlign == 3) + offset = -i * line_spacing; + else if (vAlign == 2) + offset = (last / 2.0 - i) * line_spacing; + else + offset = (last - i) * line_spacing; + + qreal ratio = 1.0; + + if (cell.hadjust) + { + // Scale font width to fit string in cell width w + // As DXF font aspect ratio is implementation dependent we add a fudge-factor based on tests with AutoCAD + int len = line.length() * textHeight * Createdxf::xScale * 1.2; + + if(len > w) + ratio = (w/len); + } + + // x offset value below currently set heuristically based on appearance... + Createdxf::drawTextAligned( + file_path, + line, + x - 2*Createdxf::xScale, + y1 + offset, + textHeight*Createdxf::yScale, + 0, + 0, + hAlign, + vAlign, + x2, + ratio, + color); } - - // x offset value below currently set heuristically based on appearance... - Createdxf::drawTextAligned( - file_path, - text, - x - 2*Createdxf::xScale, - y1, - textHeight*Createdxf::yScale, - 0, - 0, - hAlign, - vAlign, - x2, - ratio, - color); } /**