diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 877a3526fc..96f5da8b07 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -861,145 +861,186 @@ void DXF_PLOTTER::Text( const VECTOR2I& aPos, } else { - /* Emit text as a text entity. This loses formatting and shape but it's - more useful as a CAD object */ - VECTOR2D origin_dev = userToDeviceCoordinates( aPos ); - SetColor( aColor ); - wxString cname = getDXFColorName( m_currentColor ); - VECTOR2D size_dev = userToDeviceSize( aSize ); - int h_code = 0, v_code = 0; - - switch( aH_justify ) - { - case GR_TEXT_H_ALIGN_LEFT: h_code = 0; break; - case GR_TEXT_H_ALIGN_CENTER: h_code = 1; break; - case GR_TEXT_H_ALIGN_RIGHT: h_code = 2; break; - } - - switch( aV_justify ) - { - case GR_TEXT_V_ALIGN_TOP: v_code = 3; break; - case GR_TEXT_V_ALIGN_CENTER: v_code = 2; break; - case GR_TEXT_V_ALIGN_BOTTOM: v_code = 1; break; - } - - // Position, size, rotation and alignment - // The two alignment point usages is somewhat idiot (see the DXF ref) - // Anyway since we don't use the fit/aligned options, they're the same - fprintf( m_outputFile, - " 0\n" - "TEXT\n" - " 7\n" - "%s\n" // Text style - " 8\n" - "%s\n" // Layer name - " 10\n" - "%g\n" // First point X - " 11\n" - "%g\n" // Second point X - " 20\n" - "%g\n" // First point Y - " 21\n" - "%g\n" // Second point Y - " 40\n" - "%g\n" // Text height - " 41\n" - "%g\n" // Width factor - " 50\n" - "%g\n" // Rotation - " 51\n" - "%g\n" // Oblique angle - " 71\n" - "%d\n" // Mirror flags - " 72\n" - "%d\n" // H alignment - " 73\n" - "%d\n", // V alignment - aBold ? (aItalic ? "KICADBI" : "KICADB") : (aItalic ? "KICADI" : "KICAD"), - TO_UTF8( cname ), - origin_dev.x, origin_dev.x, - origin_dev.y, origin_dev.y, - size_dev.y, fabs( size_dev.x / size_dev.y ), - aOrient.AsDegrees(), - aItalic ? DXF_OBLIQUE_ANGLE : 0, - size_dev.x < 0 ? 2 : 0, // X mirror flag - h_code, v_code ); - - /* There are two issue in emitting the text: - - Our overline character (~) must be converted to the appropriate - control sequence %%O or %%o - - Text encoding in DXF is more or less unspecified since depends on - the DXF declared version, the acad version reading it *and* some - system variables to be put in the header handled only by newer acads - Also before R15 unicode simply is not supported (you need to use - bigfonts which are a massive PITA). Common denominator solution: - use Latin1 (and however someone could choke on it, anyway). Sorry - for the extended latin people. If somewant want to try fixing this - recent version seems to use UTF-8 (and not UCS2 like the rest of - Windows) - - XXX Actually there is a *third* issue: older DXF formats are limited - to 255 bytes records (it was later raised to 2048); since I'm lazy - and text so long is not probable I just don't implement this rule. - If someone is interested in fixing this, you have to emit the first - partial lines with group code 3 (max 250 bytes each) and then finish - with a group code 1 (less than 250 bytes). The DXF refs explains it - in no more details... - */ - - int braceNesting = 0; - int overbarDepth = -1; - - fputs( " 1\n", m_outputFile ); - - for( unsigned int i = 0; i < aText.length(); i++ ) - { - /* Here I do a bad thing: writing the output one byte at a time! - but today I'm lazy and I have no idea on how to coerce a Unicode - wxString to spit out latin1 encoded text ... - - At least stdio is *supposed* to do output buffering, so there is - hope is not too slow */ - wchar_t ch = aText[i]; - - if( ch > 255 ) - { - // I can't encode this... - putc( '?', m_outputFile ); - } - else - { - if( aText[i] == '~' && i+1 < aText.length() && aText[i+1] == '{' ) - { - fputs( "%%o", m_outputFile ); - overbarDepth = braceNesting; - - // Skip the '{' - i++; - continue; - } - else if( aText[i] == '{' ) - { - braceNesting++; - } - else if( aText[i] == '}' ) - { - if( braceNesting > 0 ) - braceNesting--; - - if( braceNesting == overbarDepth ) - { - fputs( "%%O", m_outputFile ); - overbarDepth = -1; - continue; - } - } - - putc( ch, m_outputFile ); - } - } - - putc( '\n', m_outputFile ); + TEXT_ATTRIBUTES attrs; + attrs.m_Halign = aH_justify; + attrs.m_Valign =aV_justify; + attrs.m_StrokeWidth = aWidth; + attrs.m_Angle = aOrient; + attrs.m_Italic = aItalic; + attrs.m_Bold = aBold; + attrs.m_Mirrored = aSize.x < 0; + attrs.m_Multiline = false; + plotOneLineOfText( aPos, aColor, aText, attrs ); } } + +void DXF_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + TEXT_ATTRIBUTES attrs = aAttributes; + // Fix me: see how to use DXF text mode for multiline texts + if( attrs.m_Multiline && !aText.Contains( wxT( "\n" ) ) ) + attrs.m_Multiline = false; // the text has only one line. + + bool processSuperSub = aText.Contains( wxT( "^{" ) ) || aText.Contains( wxT( "_{" ) ); + + if( m_textAsLines || containsNonAsciiChars( aText ) || attrs.m_Multiline || processSuperSub ) + { + // output text as graphics. + // Perhaps multiline texts could be handled as DXF text entity + // but I do not want spend time about that (JPC) + PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData ); + } + else + plotOneLineOfText( aPos, aColor, aText, attrs ); +} + +void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes ) +{ + /* Emit text as a text entity. This loses formatting and shape but it's + more useful as a CAD object */ + VECTOR2D origin_dev = userToDeviceCoordinates( aPos ); + SetColor( aColor ); + wxString cname = getDXFColorName( m_currentColor ); + VECTOR2D size_dev = userToDeviceSize( aAttributes.m_Size ); + int h_code = 0, v_code = 0; + + switch( aAttributes.m_Halign ) + { + case GR_TEXT_H_ALIGN_LEFT: h_code = 0; break; + case GR_TEXT_H_ALIGN_CENTER: h_code = 1; break; + case GR_TEXT_H_ALIGN_RIGHT: h_code = 2; break; + } + + switch( aAttributes.m_Valign ) + { + case GR_TEXT_V_ALIGN_TOP: v_code = 3; break; + case GR_TEXT_V_ALIGN_CENTER: v_code = 2; break; + case GR_TEXT_V_ALIGN_BOTTOM: v_code = 1; break; + } + + // Position, size, rotation and alignment + // The two alignment point usages is somewhat idiot (see the DXF ref) + // Anyway since we don't use the fit/aligned options, they're the same + fprintf( m_outputFile, + " 0\n" + "TEXT\n" + " 7\n" + "%s\n" // Text style + " 8\n" + "%s\n" // Layer name + " 10\n" + "%g\n" // First point X + " 11\n" + "%g\n" // Second point X + " 20\n" + "%g\n" // First point Y + " 21\n" + "%g\n" // Second point Y + " 40\n" + "%g\n" // Text height + " 41\n" + "%g\n" // Width factor + " 50\n" + "%g\n" // Rotation + " 51\n" + "%g\n" // Oblique angle + " 71\n" + "%d\n" // Mirror flags + " 72\n" + "%d\n" // H alignment + " 73\n" + "%d\n", // V alignment + aAttributes.m_Bold ? + (aAttributes.m_Italic ? "KICADBI" : "KICADB") + : (aAttributes.m_Italic ? "KICADI" : "KICAD"), TO_UTF8( cname ), + origin_dev.x, origin_dev.x, + origin_dev.y, origin_dev.y, + size_dev.y, fabs( size_dev.x / size_dev.y ), + aAttributes.m_Angle.AsDegrees(), + aAttributes.m_Italic ? DXF_OBLIQUE_ANGLE : 0, + aAttributes.m_Mirrored ? 2 : 0, // X mirror flag + h_code, v_code ); + + /* There are two issue in emitting the text: + - Our overline character (~) must be converted to the appropriate + control sequence %%O or %%o + - Text encoding in DXF is more or less unspecified since depends on + the DXF declared version, the acad version reading it *and* some + system variables to be put in the header handled only by newer acads + Also before R15 unicode simply is not supported (you need to use + bigfonts which are a massive PITA). Common denominator solution: + use Latin1 (and however someone could choke on it, anyway). Sorry + for the extended latin people. If somewant want to try fixing this + recent version seems to use UTF-8 (and not UCS2 like the rest of + Windows) + + XXX Actually there is a *third* issue: older DXF formats are limited + to 255 bytes records (it was later raised to 2048); since I'm lazy + and text so long is not probable I just don't implement this rule. + If someone is interested in fixing this, you have to emit the first + partial lines with group code 3 (max 250 bytes each) and then finish + with a group code 1 (less than 250 bytes). The DXF refs explains it + in no more details... + */ + + int braceNesting = 0; + int overbarDepth = -1; + + fputs( " 1\n", m_outputFile ); + + for( unsigned int i = 0; i < aText.length(); i++ ) + { + /* Here I do a bad thing: writing the output one byte at a time! + but today I'm lazy and I have no idea on how to coerce a Unicode + wxString to spit out latin1 encoded text ... + + At least stdio is *supposed* to do output buffering, so there is + hope is not too slow */ + wchar_t ch = aText[i]; + + if( ch > 255 ) + { + // I can't encode this... + putc( '?', m_outputFile ); + } + else + { + if( aText[i] == '~' && i+1 < aText.length() && aText[i+1] == '{' ) + { + fputs( "%%o", m_outputFile ); + overbarDepth = braceNesting; + + // Skip the '{' + i++; + continue; + } + else if( aText[i] == '{' ) + { + braceNesting++; + } + else if( aText[i] == '}' ) + { + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == overbarDepth ) + { + fputs( "%%O", m_outputFile ); + overbarDepth = -1; + continue; + } + } + + putc( ch, m_outputFile ); + } + } + + putc( '\n', m_outputFile ); +} diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index f65058f36f..33d93505c4 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -2003,6 +2003,20 @@ void GERBER_PLOTTER::Text( const VECTOR2I& aPos, } +void GERBER_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + GBR_METADATA* gbr_metadata = static_cast( aData ); + + if( gbr_metadata ) + formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); + + PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData ); +} + void GERBER_PLOTTER::SetLayerPolarity( bool aPositive ) { if( aPositive ) diff --git a/common/plotters/PDF_plotter.cpp b/common/plotters/PDF_plotter.cpp index fa38b83354..f41e64cfcc 100644 --- a/common/plotters/PDF_plotter.cpp +++ b/common/plotters/PDF_plotter.cpp @@ -1376,7 +1376,9 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos, double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f; double wideningFactor, heightFactor; - computeTextParameters( aPos, aText, aOrient, aSize, m_plotMirror, aH_justify, + VECTOR2I t_size( std::abs( aSize.x ), std::abs( aSize.y ) ); + + computeTextParameters( aPos, aText, aOrient, t_size, m_plotMirror, aH_justify, aV_justify, aWidth, aItalic, aBold, &wideningFactor, &ctm_a, &ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor ); @@ -1389,7 +1391,7 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos, if( !aFont ) aFont = KIFONT::FONT::GetFont(); - VECTOR2I full_box( aFont->StringBoundaryLimits( aText, aSize, aWidth, aBold, aItalic ) ); + VECTOR2I full_box( aFont->StringBoundaryLimits( aText, t_size, aWidth, aBold, aItalic ) ); VECTOR2I box_x( full_box.x, 0 ); VECTOR2I box_y( 0, full_box.y ); @@ -1410,13 +1412,13 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos, { wxString word = str_tok.GetNextToken(); - computeTextParameters( pos, word, aOrient, aSize, m_plotMirror, GR_TEXT_H_ALIGN_LEFT, + computeTextParameters( pos, word, aOrient, t_size, m_plotMirror, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_BOTTOM, aWidth, aItalic, aBold, &wideningFactor, &ctm_a, &ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor ); // Extract the changed width and rotate by the orientation to get the offset for the // next word - VECTOR2I bbox( aFont->StringBoundaryLimits( word, aSize, aWidth, aBold, aItalic ).x, 0 ); + VECTOR2I bbox( aFont->StringBoundaryLimits( word, t_size, aWidth, aBold, aItalic ).x, 0 ); RotatePoint( bbox, aOrient ); pos += bbox; @@ -1444,6 +1446,30 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos, } +void PDF_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + VECTOR2I size = aAttributes.m_Size; + + // PDF files do not like 0 sized texts which create broken files. + if( size.x == 0 || size.y == 0 ) + return; + + if( aAttributes.m_Mirrored ) + size.x = -size.x; + + PDF_PLOTTER::Text( aPos, aColor, aText, aAttributes.m_Angle, size, + aAttributes.m_Halign, aAttributes.m_Valign, + aAttributes.m_StrokeWidth, + aAttributes.m_Italic, aAttributes.m_Bold, + aAttributes.m_Multiline, + aFont, aData ); +} + + void PDF_PLOTTER::HyperlinkBox( const BOX2I& aBox, const wxString& aDestinationURL ) { m_hyperlinksInPage.push_back( std::make_pair( aBox, aDestinationURL ) ); diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index 1078e0e530..0a4fa8a38b 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -967,6 +967,28 @@ void PS_PLOTTER::Text( const VECTOR2I& aPos, } +void PS_PLOTTER::PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + SetCurrentLineWidth( aAttributes.m_StrokeWidth ); + SetColor( aColor ); + + // Draw the hidden postscript text (if requested) + if( m_textMode == PLOT_TEXT_MODE::PHANTOM ) + { + std::string ps_test = encodeStringForPlotter( aText ); + VECTOR2D pos_dev = userToDeviceCoordinates( aPos ); + fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y ); + } + + PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData ); +} + + /** * Character widths for Helvetica */ diff --git a/common/plotters/SVG_plotter.cpp b/common/plotters/SVG_plotter.cpp index 40ceaa677b..b1b67e86ca 100644 --- a/common/plotters/SVG_plotter.cpp +++ b/common/plotters/SVG_plotter.cpp @@ -853,3 +853,23 @@ void SVG_PLOTTER::Text( const VECTOR2I& aPos, fputs( "", m_outputFile ); } + + +void SVG_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + VECTOR2I size = aAttributes.m_Size; + + if( aAttributes.m_Mirrored ) + size.x = -size.x; + + SVG_PLOTTER::Text( aPos, aColor, aText, aAttributes.m_Angle, size, + aAttributes.m_Halign, aAttributes.m_Valign, + aAttributes.m_StrokeWidth, + aAttributes.m_Italic, aAttributes.m_Bold, + aAttributes.m_Multiline, + aFont, aData ); +} diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 78df76b157..edab6452ee 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -694,23 +694,6 @@ void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int a } -/** - * Same as GRText, but plot graphic text instead of draw it. - * - * @param aPos is the text position (according to aH_justify, aV_justify). - * @param aColor is the text color. - * @param aText is the text to draw. - * @param aOrient is the angle. - * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). - * @param aH_justify is the horizontal justification (Left, center, right). - * @param aV_justify is the vertical justification (bottom, center, top). - * @param aPenWidth is the line width (if = 0, use plot default line width). - * @param aItalic is the true to simulate an italic font. - * @param aBold use true to use a bold font Useful only with default width value (aPenWidth = 0). - * @param aMultilineAllowed use true to plot text as multiline, otherwise single line. - * @param aData is a parameter used by some plotters in SetCurrentLineWidth(), - * not directly used here. - */ void PLOTTER::Text( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, @@ -771,3 +754,45 @@ void PLOTTER::Text( const VECTOR2I& aPos, aFont->Draw( &callback_gal, aText, aPos, attributes ); } + +void PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData ) +{ + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + + TEXT_ATTRIBUTES attributes = aAttributes; + int penWidth = attributes.m_StrokeWidth; + + SetColor( aColor ); + SetCurrentLineWidth( penWidth, aData ); + + if( penWidth == 0 && attributes.m_Bold ) // Use default values if aPenWidth == 0 + penWidth = GetPenSizeForBold( std::min( attributes.m_Size.x, attributes.m_Size.y ) ); + + if( penWidth < 0 ) + penWidth = -penWidth; + + attributes.m_StrokeWidth = penWidth; + + CALLBACK_GAL callback_gal( empty_opts, + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + MoveTo( aPt1 ); + LineTo( aPt2 ); + PenFinish(); + }, + // Polygon callback + [&]( const SHAPE_LINE_CHAIN& aPoly ) + { + PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData ); + } ); + + if( !aFont ) + aFont = KIFONT::FONT::GetFont(); + + aFont->Draw( &callback_gal, aText, aPos, attributes ); +} diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index 2152164bed..995a401d88 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -383,8 +383,14 @@ void LIB_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOffs if( !font ) font = KIFONT::FONT::GetFont( renderSettings->GetDefaultFont(), IsBold(), IsItalic() ); - aPlotter->Text( textpos, color, GetShownText(), orient, GetTextSize(), hjustify, vjustify, - penWidth, IsItalic(), IsBold(), false, font ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Halign = hjustify; + attrs.m_Valign = vjustify; + attrs.m_Angle = orient; + attrs.m_Multiline = false; + + aPlotter->PlotText( textpos, color, GetShownText(), attrs, font ); } diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index e74b291b71..be371cc66e 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -812,8 +812,15 @@ void LIB_PIN::PlotPinTexts( PLOTTER *aPlotter, const VECTOR2I &aPinPos, int aPin int size, GR_TEXT_H_ALIGN_T hJustify, GR_TEXT_V_ALIGN_T vJustify, int penWidth ) { - aPlotter->Text( VECTOR2I( px, py ), color, text, angle, VECTOR2I( size, size ), - hJustify, vJustify, penWidth, false, false, false, font ); + TEXT_ATTRIBUTES attrs; + attrs.m_StrokeWidth = std::min( penWidth, size / 5 ); // Keep text readable + attrs.m_Angle = angle; + attrs.m_Size = VECTOR2I( size, size ); + attrs.m_Halign = hJustify; + attrs.m_Valign = vJustify; + attrs.m_Multiline = false; + + aPlotter->PlotText( VECTOR2I( px, py ), color, text, attrs, font ); }; /* Draw the text inside, but the pin numbers outside. */ diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp index c1fe980033..f15cfcfebd 100644 --- a/eeschema/lib_text.cpp +++ b/eeschema/lib_text.cpp @@ -326,9 +326,10 @@ void LIB_TEXT::Plot( PLOTTER* plotter, bool aBackground, const VECTOR2I& offset, if( !font ) font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), IsBold(), IsItalic() ); - plotter->Text( pos, color, GetText(), t1 ? ANGLE_HORIZONTAL : ANGLE_VERTICAL, GetTextSize(), - GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), - true, font ); + attrs.m_StrokeWidth = penWidth; + attrs.m_Angle = t1 ? ANGLE_HORIZONTAL : ANGLE_VERTICAL; + + plotter->PlotText( pos, color, GetText(), attrs, font ); } diff --git a/eeschema/lib_textbox.cpp b/eeschema/lib_textbox.cpp index ea21f48d7a..3b981ce6dc 100644 --- a/eeschema/lib_textbox.cpp +++ b/eeschema/lib_textbox.cpp @@ -465,11 +465,13 @@ void LIB_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOf text.GetLinePositions( positions, (int) strings_list.Count() ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Multiline = false; + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - aPlotter->Text( positions[ii], color, strings_list.Item( ii ), text.GetTextAngle(), - text.GetTextSize(), text.GetHorizJustify(), text.GetVertJustify(), - penWidth, text.IsItalic(), text.IsBold(), false, font ); + aPlotter->PlotText( positions[ii], color, strings_list.Item( ii ), attrs, font ); } } diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index f205047680..b7402937d3 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -968,6 +968,9 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground ) const penWidth = std::max( penWidth, settings->GetMinPenWidth() ); + // clamp the pen width to be sure the text is readable + penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 ); + if( !IsVisible() ) return; @@ -1021,8 +1024,14 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground ) const if( !font ) font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), IsBold(), IsItalic() ); - aPlotter->Text( textpos, color, GetShownText(), orient, GetTextSize(), hjustify, vjustify, - penWidth, IsItalic(), IsBold(), false, font ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Halign = hjustify; + attrs.m_Valign = vjustify; + attrs.m_Angle = orient; + attrs.m_Multiline = false; + + aPlotter->PlotText( textpos, color, GetShownText(), attrs, font ); if( IsHypertext() ) { diff --git a/eeschema/sch_label.cpp b/eeschema/sch_label.cpp index ba8b6a17e5..ab807d1a07 100644 --- a/eeschema/sch_label.cpp +++ b/eeschema/sch_label.cpp @@ -928,15 +928,17 @@ void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground ) const VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( aPlotter->RenderSettings() ); CreateGraphicShape( aPlotter->RenderSettings(), s_poly, GetTextPos() ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Multiline = false; + if( aBackground ) { // No filled shapes (yet) } else { - aPlotter->Text( textpos, color, GetShownText(), GetTextAngle(), GetTextSize(), - GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), - false, font ); + aPlotter->PlotText( textpos, color, GetShownText(), attrs, font ); if( s_poly.size() ) aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth ); diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 1b6be4e712..ffa67f9493 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -462,12 +462,15 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter, bool aBackground ) const GetLinePositions( positions, (int) strings_list.Count() ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Multiline = false; + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { VECTOR2I textpos = positions[ii] + text_offset; wxString& txt = strings_list.Item( ii ); - aPlotter->Text( textpos, color, txt, GetTextAngle(), GetTextSize(), GetHorizJustify(), - GetVertJustify(), penWidth, IsItalic(), IsBold(), false, font ); + aPlotter->PlotText( textpos, color, txt, attrs, font ); } if( HasHyperlink() ) diff --git a/eeschema/sch_textbox.cpp b/eeschema/sch_textbox.cpp index 8800b5ca7e..558ee3e926 100644 --- a/eeschema/sch_textbox.cpp +++ b/eeschema/sch_textbox.cpp @@ -410,11 +410,13 @@ void SCH_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground ) const GetLinePositions( positions, (int) strings_list.Count() ); + TEXT_ATTRIBUTES attrs = GetAttributes(); + attrs.m_StrokeWidth = penWidth; + attrs.m_Multiline = false; + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - aPlotter->Text( positions[ii], color, strings_list.Item( ii ), GetTextAngle(), - GetTextSize(), GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), - IsBold(), false, font ); + aPlotter->PlotText( positions[ii], color, strings_list.Item( ii ), attrs, font ); } if( HasHyperlink() ) diff --git a/include/plotters/plotter.h b/include/plotters/plotter.h index 1beac0ed02..308b598547 100644 --- a/include/plotters/plotter.h +++ b/include/plotters/plotter.h @@ -409,8 +409,22 @@ public: /** * Draw text with the plotter. * - * For convenience it accept the color to use for specific plotters (GERBER) aData is used - * to pass extra parameters. + * For convenience it accept the color to use for specific plotters + * aData is used to pass extra parameters (GERBER). + * + * @param aPos is the text position (according to aH_justify, aV_justify). + * @param aColor is the text color. + * @param aText is the text to draw. + * @param aOrient is the angle. + * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). + * @param aH_justify is the horizontal justification (Left, center, right). + * @param aV_justify is the vertical justification (bottom, center, top). + * @param aPenWidth is the line width (if = 0, use plot default line width). + * @param aItalic is the true to simulate an italic font. + * @param aBold use true to use a bold font Useful only with default width value (aPenWidth = 0). + * @param aMultilineAllowed use true to plot text as multiline, otherwise single line. + * @param aData is a parameter used by some plotters in SetCurrentLineWidth(), + * not directly used here. */ virtual void Text( const VECTOR2I& aPos, const COLOR4D& aColor, @@ -426,6 +440,12 @@ public: KIFONT::FONT* aFont, void* aData = nullptr ); + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ); /** * Create a clickable hyperlink with a rectangular click area * diff --git a/include/plotters/plotter_dxf.h b/include/plotters/plotter_dxf.h index 90aa09585a..fe75764889 100644 --- a/include/plotters/plotter_dxf.h +++ b/include/plotters/plotter_dxf.h @@ -166,7 +166,12 @@ public: KIFONT::FONT* aFont = nullptr, void* aData = nullptr ) override; - + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ) override; /** * Set the units to use for plotting the DXF file. * @@ -210,6 +215,10 @@ protected: const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH ) override; + void plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes ); + bool m_textAsLines; COLOR4D m_currentColor; PLOT_DASH_TYPE m_currentLineType; diff --git a/include/plotters/plotter_gerber.h b/include/plotters/plotter_gerber.h index 90d5a01da4..d60c78c7ca 100644 --- a/include/plotters/plotter_gerber.h +++ b/include/plotters/plotter_gerber.h @@ -124,6 +124,14 @@ public: KIFONT::FONT* aFont = nullptr, void* aData = nullptr ) override; + + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ) override; + /** * Filled circular flashes are stored as apertures */ diff --git a/include/plotters/plotters_pslike.h b/include/plotters/plotters_pslike.h index 2da0189301..be4e99a763 100644 --- a/include/plotters/plotters_pslike.h +++ b/include/plotters/plotters_pslike.h @@ -231,6 +231,14 @@ public: KIFONT::FONT* aFont = nullptr, void* aData = nullptr ) override; + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ) override; + + protected: virtual void emitSetRGBColor( double r, double g, double b, double a ) override; }; @@ -352,6 +360,13 @@ public: KIFONT::FONT* aFont = nullptr, void* aData = nullptr ) override; + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ) override; + void HyperlinkBox( const BOX2I& aBox, const wxString& aDestinationURL ) override; void HyperlinkMenu( const BOX2I& aBox, const std::vector& aDestURLs ) override; @@ -599,6 +614,14 @@ public: KIFONT::FONT* aFont = nullptr, void* aData = nullptr ) override; + + virtual void PlotText( const VECTOR2I& aPos, + const COLOR4D& aColor, + const wxString& aText, + const TEXT_ATTRIBUTES& aAttributes, + KIFONT::FONT* aFont, + void* aData = nullptr ) override; + protected: virtual void Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle, int aRadius, diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp index 4ecda8c78a..3d48511838 100644 --- a/pcbnew/exporters/gen_drill_report_files.cpp +++ b/pcbnew/exporters/gen_drill_report_files.cpp @@ -266,10 +266,16 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ // Plot title "Info" wxString Text = wxT( "Drill Map:" ); - plotter->Text( VECTOR2I( plotX, plotY ), COLOR4D::UNSPECIFIED, Text, ANGLE_HORIZONTAL, - wxSize( KiROUND( charSize * charScale ), KiROUND( charSize * charScale ) ), - GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, TextWidth, false, false, - false, nullptr /* stroke font */ ); + + TEXT_ATTRIBUTES attrs; + attrs.m_StrokeWidth = TextWidth; + attrs.m_Angle = ANGLE_HORIZONTAL; + attrs.m_Size = VECTOR2I( KiROUND( charSize * charScale ), KiROUND( charSize * charScale ) ); + attrs.m_Halign = GR_TEXT_H_ALIGN_LEFT; + attrs.m_Valign = GR_TEXT_V_ALIGN_CENTER; + attrs.m_Multiline = false; + + plotter->PlotText( VECTOR2I( plotX, plotY ), COLOR4D::UNSPECIFIED, Text, attrs, nullptr /* stroke font */ ); // For some formats (PS, PDF SVG) we plot the drill size list on more than one column // because the list must be contained inside the printed page @@ -328,10 +334,7 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ if( tool.m_Hole_NotPlated ) msg += wxT( " (not plated)" ); - plotter->Text( VECTOR2I( plotX, y ), COLOR4D::UNSPECIFIED, msg, ANGLE_HORIZONTAL, - VECTOR2I( KiROUND( charSize * charScale ), KiROUND( charSize * charScale ) ), - GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, TextWidth, false, false, - false, nullptr /* stroke font */ ); + plotter->PlotText( VECTOR2I( plotX, y ), COLOR4D::UNSPECIFIED, msg, attrs, nullptr /* stroke font */ ); intervalle = KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 ); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index b5760ca2ed..77a5095127 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -402,8 +402,7 @@ void BRDITEMS_PLOTTER::PlotFootprintTextItem( const FP_TEXT* aText, const COLOR4 m_plotter->SetColor( color ); // calculate some text parameters : - TEXT_ATTRIBUTES attrs = aText->GetAttributes(); - VECTOR2I size = aText->GetTextSize(); + //VECTOR2I size = aText->GetTextSize(); VECTOR2I pos = aText->GetTextPos(); int thickness = aText->GetEffectiveTextPenWidth(); KIFONT::FONT* font = aText->GetFont(); @@ -416,14 +415,15 @@ void BRDITEMS_PLOTTER::PlotFootprintTextItem( const FP_TEXT* aText, const COLOR4 aText->IsBold(), aText->IsItalic() ); } - if( aText->IsMirrored() ) - size.x = -size.x; // Text is mirrored - // Non bold texts thickness is clamped at 1/6 char size by the low level draw function. // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size // (like bold text) and we manage the thickness. // So we set bold flag to true - bool allow_bold = true; + TEXT_ATTRIBUTES attrs = aText->GetAttributes(); + attrs.m_StrokeWidth = thickness; + attrs.m_Angle = aText->GetDrawRotation(); + attrs.m_Bold = true; + attrs.m_Multiline = false; GBR_METADATA gbr_metadata; @@ -434,6 +434,8 @@ void BRDITEMS_PLOTTER::PlotFootprintTextItem( const FP_TEXT* aText, const COLOR4 const FOOTPRINT* parent = static_cast ( aText->GetParent() ); gbr_metadata.SetCmpReference( parent->GetReference() ); + m_plotter->SetCurrentLineWidth( thickness ); + if( aText->IsKnockout() ) { KIGFX::GAL_DISPLAY_OPTIONS empty_opts; @@ -462,12 +464,7 @@ void BRDITEMS_PLOTTER::PlotFootprintTextItem( const FP_TEXT* aText, const COLOR4 m_plotter->PlotPoly( finalPoly.Outline( ii ), FILL_T::FILLED_SHAPE, 0, &gbr_metadata ); } else - { - m_plotter->SetCurrentLineWidth( thickness ); - m_plotter->Text( pos, aColor, aText->GetShownText(), aText->GetDrawRotation(), size, - aText->GetHorizJustify(), aText->GetVertJustify(), thickness, - aText->IsItalic(), allow_bold, false, font, &gbr_metadata ); - } + m_plotter->PlotText( pos, aColor, aText->GetShownText(), attrs, font, &gbr_metadata ); } @@ -840,7 +837,6 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, } wxString shownText( aText->GetShownText() ); - TEXT_ATTRIBUTES attrs = aText->GetAttributes(); if( shownText.IsEmpty() ) return; @@ -856,13 +852,16 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, COLOR4D color = getColor( aLayer ); m_plotter->SetColor( color ); - VECTOR2I size = aText->GetTextSize(); + //VECTOR2I size = aText->GetTextSize(); VECTOR2I pos = aText->GetTextPos(); + TEXT_ATTRIBUTES attrs = aText->GetAttributes(); attrs.m_StrokeWidth = aText->GetEffectiveTextPenWidth(); + attrs.m_Angle = aText->GetDrawRotation(); + attrs.m_Multiline = false; - if( aText->IsMirrored() ) - size.x = -size.x; + //if( aText->IsMirrored() ) + // size.x = -size.x; m_plotter->SetCurrentLineWidth( attrs.m_StrokeWidth ); @@ -905,16 +904,12 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { wxString& txt = strings_list.Item( ii ); - m_plotter->Text( positions[ii], color, txt, aText->GetDrawRotation(), size, - attrs.m_Halign, attrs.m_Valign, attrs.m_StrokeWidth, attrs.m_Italic, - attrs.m_Bold, false, font, &gbr_metadata ); + m_plotter->PlotText( positions[ii], color, txt, attrs, font, &gbr_metadata ); } } else { - m_plotter->Text( pos, color, shownText, aText->GetDrawRotation(), size, attrs.m_Halign, - attrs.m_Valign, attrs.m_StrokeWidth, attrs.m_Italic, attrs.m_Bold, false, - font, &gbr_metadata ); + m_plotter->PlotText( pos, color, shownText, attrs, font, &gbr_metadata ); } }