KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eda_text.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <algorithm> // for max
26#include <stddef.h> // for NULL
27#include <type_traits> // for swap
28#include <vector>
29
30#include <eda_item.h>
31#include <base_units.h>
32#include <callback_gal.h>
33#include <eda_text.h> // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF...
34#include <gal/color4d.h> // for COLOR4D, COLOR4D::BLACK
35#include <font/glyph.h>
36#include <gr_text.h>
37#include <string_utils.h> // for UnescapeString
39#include <math/util.h> // for KiROUND
40#include <math/vector2d.h>
41#include <core/kicad_algo.h>
42#include <richio.h>
43#include <render_settings.h>
44#include <trigo.h> // for RotatePoint
45#include <i18n_utility.h>
49#include <font/outline_font.h>
52#include <ctl_flags.h>
53#include <api/api_enums.h>
54#include <api/api_utils.h>
55#include <api/common/types/base_types.pb.h>
56
57#include <wx/debug.h> // for wxASSERT
58#include <wx/string.h>
59#include <wx/url.h> // for wxURL
62#include "font/fontconfig.h"
63#include "pgm_base.h"
64
65class OUTPUTFORMATTER;
66
67
69{
70 wxASSERT( aHorizJustify >= GR_TEXT_H_ALIGN_LEFT && aHorizJustify <= GR_TEXT_H_ALIGN_RIGHT );
71
72 if( aHorizJustify > GR_TEXT_H_ALIGN_RIGHT )
74
75 if( aHorizJustify < GR_TEXT_H_ALIGN_LEFT )
77
78 return static_cast<GR_TEXT_H_ALIGN_T>( aHorizJustify );
79}
80
81
83{
84 wxASSERT( aVertJustify >= GR_TEXT_V_ALIGN_TOP && aVertJustify <= GR_TEXT_V_ALIGN_BOTTOM );
85
86 if( aVertJustify > GR_TEXT_V_ALIGN_BOTTOM )
88
89 if( aVertJustify < GR_TEXT_V_ALIGN_TOP )
91
92 return static_cast<GR_TEXT_V_ALIGN_T>( aVertJustify );
93}
94
95
96EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
97 m_text( aText ),
98 m_IuScale( aIuScale ),
99 m_render_cache_font( nullptr ),
100 m_visible( true )
101{
104
105 if( m_text.IsEmpty() )
106 {
107 m_shown_text = wxEmptyString;
109 }
110 else
111 {
113 m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
114 }
115}
116
117
119 m_IuScale( aText.m_IuScale )
120{
121 m_text = aText.m_text;
124
126 m_pos = aText.m_pos;
127 m_visible = aText.m_visible;
128
133
134 m_render_cache.clear();
135
136 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
137 {
138 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
139 m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
140 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
141 m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
142 }
143
145
147}
148
149
153
154
156{
157 m_text = aText.m_text;
160
162 m_pos = aText.m_pos;
163 m_visible = aText.m_visible;
164
169
170 m_render_cache.clear();
171
172 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
173 {
174 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
175 m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
176 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
177 m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
178 }
179
181
183
184 return *this;
185}
186
187
188void EDA_TEXT::Serialize( google::protobuf::Any &aContainer ) const
189{
190 using namespace kiapi::common;
191 types::Text text;
192
193 text.set_text( GetText().ToStdString() );
194 text.set_hyperlink( GetHyperlink().ToStdString() );
195 PackVector2( *text.mutable_position(), GetTextPos() );
196
197 types::TextAttributes* attrs = text.mutable_attributes();
198
199 if( GetFont() )
200 attrs->set_font_name( GetFont()->GetName().ToStdString() );
201
202 attrs->set_horizontal_alignment(
204
205 attrs->set_vertical_alignment(
207
208 attrs->mutable_angle()->set_value_degrees( GetTextAngleDegrees() );
209 attrs->set_line_spacing( GetLineSpacing() );
210 attrs->mutable_stroke_width()->set_value_nm( GetTextThickness() );
211 attrs->set_italic( IsItalic() );
212 attrs->set_bold( IsBold() );
213 attrs->set_underlined( GetAttributes().m_Underlined );
214 attrs->set_visible( true );
215 attrs->set_mirrored( IsMirrored() );
216 attrs->set_multiline( IsMultilineAllowed() );
217 attrs->set_keep_upright( IsKeepUpright() );
218 PackVector2( *attrs->mutable_size(), GetTextSize() );
219
220 aContainer.PackFrom( text );
221}
222
223
224bool EDA_TEXT::Deserialize( const google::protobuf::Any &aContainer )
225{
226 using namespace kiapi::common;
227 types::Text text;
228
229 if( !aContainer.UnpackTo( &text ) )
230 return false;
231
232 SetText( wxString( text.text().c_str(), wxConvUTF8 ) );
233 SetHyperlink( wxString( text.hyperlink().c_str(), wxConvUTF8 ) );
234 SetTextPos( UnpackVector2( text.position() ) );
235
236 if( text.has_attributes() )
237 {
239
240 attrs.m_Bold = text.attributes().bold();
241 attrs.m_Italic = text.attributes().italic();
242 attrs.m_Underlined = text.attributes().underlined();
243 attrs.m_Mirrored = text.attributes().mirrored();
244 attrs.m_Multiline = text.attributes().multiline();
245 attrs.m_KeepUpright = text.attributes().keep_upright();
246 attrs.m_Size = UnpackVector2( text.attributes().size() );
247
248 if( !text.attributes().font_name().empty() )
249 {
251 wxString( text.attributes().font_name().c_str(), wxConvUTF8 ), attrs.m_Bold,
252 attrs.m_Italic );
253 }
254
255 attrs.m_Angle = EDA_ANGLE( text.attributes().angle().value_degrees(), DEGREES_T );
256 attrs.m_LineSpacing = text.attributes().line_spacing();
257 attrs.m_StrokeWidth = text.attributes().stroke_width().value_nm();
259 text.attributes().horizontal_alignment() );
260
262 text.attributes().vertical_alignment() );
263
264 SetAttributes( attrs );
265 }
266
267 return true;
268}
269
270
271void EDA_TEXT::SetText( const wxString& aText )
272{
273 m_text = aText;
275}
276
277
278void EDA_TEXT::CopyText( const EDA_TEXT& aSrc )
279{
280 m_text = aSrc.m_text;
282}
283
284
286{
287 m_attributes.m_StrokeWidth = aWidth;
290}
291
292
294{
295 if( GetAutoThickness() != aAuto )
297}
298
299
301{
302 m_attributes.m_Angle = aAngle;
305}
306
307
308void EDA_TEXT::SetItalic( bool aItalic )
309{
310 if( m_attributes.m_Italic != aItalic )
311 {
312 const KIFONT::FONT* font = GetFont();
313
314 if( !font || font->IsStroke() )
315 {
316 // For stroke fonts, just need to set the attribute.
317 }
318 else
319 {
320 // For outline fonts, italic-ness is determined by the font itself.
321 SetFont( KIFONT::FONT::GetFont( font->GetName(), IsBold(), aItalic ) );
322 }
323 }
324
325 SetItalicFlag( aItalic );
326}
327
328void EDA_TEXT::SetItalicFlag( bool aItalic )
329{
330 m_attributes.m_Italic = aItalic;
333}
334
335
336void EDA_TEXT::SetBold( bool aBold )
337{
338 if( m_attributes.m_Bold != aBold )
339 {
340 const KIFONT::FONT* font = GetFont();
341
342 if( !font || font->IsStroke() )
343 {
344 // For stroke fonts, boldness is determined by the pen size.
345 const int size = std::min( m_attributes.m_Size.x, m_attributes.m_Size.y );
346
347 if( aBold )
348 {
349 m_attributes.m_StoredStrokeWidth = m_attributes.m_StrokeWidth;
350 m_attributes.m_StrokeWidth = GetPenSizeForBold( size );
351 }
352 else
353 {
354 // Restore the original stroke width from `m_StoredStrokeWidth` if it was
355 // previously stored, resetting the width after unbolding.
356 if( m_attributes.m_StoredStrokeWidth )
357 m_attributes.m_StrokeWidth = m_attributes.m_StoredStrokeWidth;
358 else
359 {
360 m_attributes.m_StrokeWidth = GetPenSizeForNormal( size );
361 // Sets `m_StrokeWidth` to the normal pen size and stores it in
362 // `m_StoredStrokeWidth` as the default, but only if the bold option was
363 // applied before this feature was implemented.
364 m_attributes.m_StoredStrokeWidth = m_attributes.m_StrokeWidth;
365 }
366 }
367 }
368 else
369 {
370 // For outline fonts, boldness is determined by the font itself.
371 SetFont( KIFONT::FONT::GetFont( font->GetName(), aBold, IsItalic() ) );
372 }
373 }
374
375 SetBoldFlag( aBold );
376}
377
378
379void EDA_TEXT::SetBoldFlag( bool aBold )
380{
381 m_attributes.m_Bold = aBold;
384}
385
386
387void EDA_TEXT::SetVisible( bool aVisible )
388{
389 m_visible = aVisible;
391}
392
393
394void EDA_TEXT::SetMirrored( bool isMirrored )
395{
396 m_attributes.m_Mirrored = isMirrored;
399}
400
401
403{
404 m_attributes.m_Multiline = aAllow;
407}
408
409
411{
412 m_attributes.m_Halign = aType;
415}
416
417
419{
420 m_attributes.m_Valign = aType;
423}
424
425
426void EDA_TEXT::SetKeepUpright( bool aKeepUpright )
427{
428 m_attributes.m_KeepUpright = aKeepUpright;
431}
432
433
434void EDA_TEXT::SetAttributes( const EDA_TEXT& aSrc, bool aSetPosition )
435{
437
438 if( aSetPosition )
439 m_pos = aSrc.m_pos;
440
443}
444
445
446void EDA_TEXT::SwapText( EDA_TEXT& aTradingPartner )
447{
448 std::swap( m_text, aTradingPartner.m_text );
450}
451
452
453void EDA_TEXT::SwapAttributes( EDA_TEXT& aTradingPartner )
454{
455 std::swap( m_attributes, aTradingPartner.m_attributes );
456 std::swap( m_pos, aTradingPartner.m_pos );
457
459 aTradingPartner.ClearRenderCache();
460
462 aTradingPartner.ClearBoundingBoxCache();
463}
464
465
466int EDA_TEXT::GetEffectiveTextPenWidth( int aDefaultPenWidth ) const
467{
468 int penWidth = GetTextThickness();
469
470 if( penWidth <= 1 )
471 {
472 penWidth = aDefaultPenWidth;
473
474 if( IsBold() )
475 penWidth = GetPenSizeForBold( GetTextWidth() );
476 else if( penWidth <= 1 )
477 penWidth = GetPenSizeForNormal( GetTextWidth() );
478 }
479
480 // Clip pen size for small texts:
481 penWidth = ClampTextPenSize( penWidth, GetTextSize() );
482
483 return penWidth;
484}
485
486
487bool EDA_TEXT::Replace( const EDA_SEARCH_DATA& aSearchData )
488{
489 bool retval = EDA_ITEM::Replace( aSearchData, m_text );
490
492
495
496 return retval;
497}
498
499
501{
502 m_attributes.m_Font = aFont;
505}
506
507
508bool EDA_TEXT::ResolveFont( const std::vector<wxString>* aEmbeddedFonts )
509{
510 if( !m_unresolvedFontName.IsEmpty() )
511 {
513 aEmbeddedFonts );
514
515 if( !m_render_cache.empty() )
517
518 m_unresolvedFontName = wxEmptyString;
519 return true;
520 }
521
522 return false;
523}
524
525
526void EDA_TEXT::SetLineSpacing( double aLineSpacing )
527{
528 m_attributes.m_LineSpacing = aLineSpacing;
531}
532
533
534void EDA_TEXT::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
535{
536 // Plotting uses unityScale and independently scales the text. If we clamp here we'll
537 // clamp to *really* small values.
538 if( m_IuScale.get().IU_PER_MM == unityScale.IU_PER_MM )
539 aEnforceMinTextSize = false;
540
541 if( aEnforceMinTextSize )
542 {
543 int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
544 int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
545
546 aNewSize = VECTOR2I( std::clamp( aNewSize.x, min, max ),
547 std::clamp( aNewSize.y, min, max ) );
548 }
549
550 m_attributes.m_Size = aNewSize;
551
554}
555
556
557void EDA_TEXT::SetTextWidth( int aWidth )
558{
559 int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
560 int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
561
562 m_attributes.m_Size.x = std::clamp( aWidth, min, max );
565}
566
567
568void EDA_TEXT::SetTextHeight( int aHeight )
569{
570 int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
571 int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
572
573 m_attributes.m_Size.y = std::clamp( aHeight, min, max );
576}
577
578
579void EDA_TEXT::SetTextPos( const VECTOR2I& aPoint )
580{
581 Offset( VECTOR2I( aPoint.x - m_pos.x, aPoint.y - m_pos.y ) );
582}
583
584
585void EDA_TEXT::SetTextX( int aX )
586{
587 Offset( VECTOR2I( aX - m_pos.x, 0 ) );
588}
589
590
591void EDA_TEXT::SetTextY( int aY )
592{
593 Offset( VECTOR2I( 0, aY - m_pos.y ) );
594}
595
596
597void EDA_TEXT::Offset( const VECTOR2I& aOffset )
598{
599 if( aOffset.x == 0 && aOffset.y == 0 )
600 return;
601
602 m_pos += aOffset;
603
604 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache )
605 {
606 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
607 outline->Move( aOffset );
608 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
609 glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
610 }
611
613}
614
615
617{
618 m_text.Empty();
621}
622
623
625{
626 if( m_text.IsEmpty() )
627 {
628 m_shown_text = wxEmptyString;
630 }
631 else
632 {
634 m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
635 }
636
639}
640
641
642wxString EDA_TEXT::EvaluateText( const wxString& aText ) const
643{
644 static EXPRESSION_EVALUATOR evaluator;
645
646 return evaluator.Evaluate( aText );
647}
648
649
651{
652 KIFONT::FONT* font = GetFont();
653
654 if( !font )
655 {
656 if( aSettings )
657 font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), IsBold(), IsItalic() );
658 else
659 font = KIFONT::FONT::GetFont( wxEmptyString, IsBold(), IsItalic() );
660 }
661
662 return font;
663}
664
665
670
671
673{
674 m_render_cache.clear();
675}
676
677
679{
680 m_bbox_cache.clear();
681}
682
683
684std::vector<std::unique_ptr<KIFONT::GLYPH>>*
685EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolvedText,
686 const VECTOR2I& aOffset ) const
687{
688 if( aFont->IsOutline() )
689 {
690 EDA_ANGLE resolvedAngle = GetDrawRotation();
691
692 if( m_render_cache.empty()
693 || m_render_cache_font != aFont
694 || m_render_cache_text != forResolvedText
695 || m_render_cache_angle != resolvedAngle
696 || m_render_cache_offset != aOffset )
697 {
698 m_render_cache.clear();
699
700 const KIFONT::OUTLINE_FONT* font = static_cast<const KIFONT::OUTLINE_FONT*>( aFont );
702
703 attrs.m_Angle = resolvedAngle;
704
705 font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
706 attrs, getFontMetrics() );
707 m_render_cache_font = aFont;
708 m_render_cache_angle = resolvedAngle;
709 m_render_cache_text = forResolvedText;
710 m_render_cache_offset = aOffset;
711 }
712
713 return &m_render_cache;
714 }
715
716 return nullptr;
717}
718
719
720void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const KIFONT::FONT* aFont,
721 const EDA_ANGLE& aAngle, const VECTOR2I& aOffset )
722{
723 m_render_cache_text = aResolvedText;
724 m_render_cache_font = aFont;
725 m_render_cache_angle = aAngle;
726 m_render_cache_offset = aOffset;
727 m_render_cache.clear();
728}
729
730
732{
733 m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( aPoly ) );
734 static_cast<KIFONT::OUTLINE_GLYPH*>( m_render_cache.back().get() )->CacheTriangulation();
735}
736
737
738int EDA_TEXT::GetInterline( const RENDER_SETTINGS* aSettings ) const
739{
740 return KiROUND( GetDrawFont( aSettings )->GetInterline( GetTextHeight(), getFontMetrics() ) );
741}
742
743
744BOX2I EDA_TEXT::GetTextBox( const RENDER_SETTINGS* aSettings, int aLine ) const
745{
746 VECTOR2I drawPos = GetDrawPos();
747
748 auto cache_it = m_bbox_cache.find( aLine );
749
750 if( cache_it != m_bbox_cache.end() && cache_it->second.m_pos == drawPos )
751 return cache_it->second.m_bbox;
752
753 BOX2I bbox;
754 wxArrayString strings;
755 wxString text = GetShownText( true );
756 int thickness = GetEffectiveTextPenWidth();
757
758 if( IsMultilineAllowed() )
759 {
760 wxStringSplit( text, strings, '\n' );
761
762 if( strings.GetCount() ) // GetCount() == 0 for void strings with multilines allowed
763 {
764 if( aLine >= 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) )
765 text = strings.Item( aLine );
766 else
767 text = strings.Item( 0 );
768 }
769 }
770
771 // calculate the H and V size
772 KIFONT::FONT* font = GetDrawFont( aSettings );
773 VECTOR2D fontSize( GetTextSize() );
774 bool bold = IsBold();
775 bool italic = IsItalic();
776 VECTOR2I extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic, getFontMetrics() );
777 int overbarOffset = 0;
778
779 // Creates bounding box (rectangle) for horizontal, left and top justified text. The
780 // bounding box will be moved later according to the actual text options
781 VECTOR2I textsize = VECTOR2I( extents.x, extents.y );
782 VECTOR2I pos = drawPos;
783 int fudgeFactor = KiROUND( extents.y * 0.17 );
784
785 if( font->IsStroke() )
786 textsize.y += fudgeFactor;
787
788 if( IsMultilineAllowed() && aLine > 0 && aLine < (int) strings.GetCount() )
789 pos.y -= KiROUND( aLine * font->GetInterline( fontSize.y, getFontMetrics() ) );
790
791 if( text.Contains( wxT( "~{" ) ) )
792 overbarOffset = extents.y / 6;
793
794 bbox.SetOrigin( pos );
795
796 // for multiline texts and aLine < 0, merge all rectangles (aLine == -1 signals all lines)
797 if( IsMultilineAllowed() && aLine < 0 && strings.GetCount() > 1 )
798 {
799 for( unsigned ii = 1; ii < strings.GetCount(); ii++ )
800 {
801 text = strings.Item( ii );
802 extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic, getFontMetrics() );
803 textsize.x = std::max( textsize.x, extents.x );
804 }
805
806 // interline spacing is only *between* lines, so total height is the height of the first
807 // line plus the interline distance (with interline spacing) for all subsequent lines
808 textsize.y += KiROUND( ( strings.GetCount() - 1 ) * font->GetInterline( fontSize.y, getFontMetrics() ) );
809 }
810
811 textsize.y += overbarOffset;
812
813 bbox.SetSize( textsize );
814
815 /*
816 * At this point the rectangle origin is the text origin (m_Pos). This is correct only for
817 * left and top justified, non-mirrored, non-overbarred texts. Recalculate for all others.
818 */
819 int italicOffset = IsItalic() ? KiROUND( fontSize.y * ITALIC_TILT ) : 0;
820
821 switch( GetHorizJustify() )
822 {
824 if( IsMirrored() )
825 bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) );
826
827 break;
828
830 bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) / 2 );
831 break;
832
834 if( !IsMirrored() )
835 bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) );
836 break;
837
839 wxFAIL_MSG( wxT( "Indeterminate state legal only in dialogs." ) );
840 break;
841 }
842
843 switch( GetVertJustify() )
844 {
846 bbox.Offset( 0, -fudgeFactor );
847 break;
848
850 bbox.SetY( bbox.GetY() - bbox.GetHeight() / 2 );
851 break;
852
854 bbox.SetY( bbox.GetY() - bbox.GetHeight() );
855 bbox.Offset( 0, fudgeFactor );
856 break;
857
859 wxFAIL_MSG( wxT( "Indeterminate state legal only in dialogs." ) );
860 break;
861 }
862
863 bbox.Normalize(); // Make h and v sizes always >= 0
864
865 m_bbox_cache[ aLine ] = { drawPos, bbox };
866
867 return bbox;
868}
869
870
871bool EDA_TEXT::TextHitTest( const VECTOR2I& aPoint, int aAccuracy ) const
872{
873 const BOX2I rect = GetTextBox( nullptr ).GetInflated( aAccuracy );
874 const VECTOR2I location = GetRotated( aPoint, GetDrawPos(), -GetDrawRotation() );
875 return rect.Contains( location );
876}
877
878
879bool EDA_TEXT::TextHitTest( const BOX2I& aRect, bool aContains, int aAccuracy ) const
880{
881 const BOX2I rect = aRect.GetInflated( aAccuracy );
882
883 if( aContains )
884 return rect.Contains( GetTextBox( nullptr ) );
885
886 return rect.Intersects( GetTextBox( nullptr ), GetDrawRotation() );
887}
888
889
890void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset, const COLOR4D& aColor )
891{
892 if( IsMultilineAllowed() )
893 {
894 std::vector<VECTOR2I> positions;
895 wxArrayString strings;
896 wxStringSplit( GetShownText( true ), strings, '\n' );
897
898 positions.reserve( strings.Count() );
899
900 GetLinePositions( aSettings, positions, (int) strings.Count() );
901
902 for( unsigned ii = 0; ii < strings.Count(); ii++ )
903 printOneLineOfText( aSettings, aOffset, aColor, strings[ii], positions[ii] );
904 }
905 else
906 {
907 printOneLineOfText( aSettings, aOffset, aColor, GetShownText( true ), GetDrawPos() );
908 }
909}
910
911
912void EDA_TEXT::GetLinePositions( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPositions,
913 int aLineCount ) const
914{
915 VECTOR2I pos = GetDrawPos(); // Position of first line of the multiline text according
916 // to the center of the multiline text block
917
918 VECTOR2I offset; // Offset to next line.
919
920 offset.y = GetInterline( aSettings );
921
922 if( aLineCount > 1 )
923 {
924 switch( GetVertJustify() )
925 {
927 break;
928
930 pos.y -= ( aLineCount - 1 ) * offset.y / 2;
931 break;
932
934 pos.y -= ( aLineCount - 1 ) * offset.y;
935 break;
936
938 wxFAIL_MSG( wxT( "Indeterminate state legal only in dialogs." ) );
939 break;
940 }
941 }
942
943 // Rotate the position of the first line around the center of the multiline text block
945
946 // Rotate the offset lines to increase happened in the right direction
947 RotatePoint( offset, GetDrawRotation() );
948
949 for( int ii = 0; ii < aLineCount; ii++ )
950 {
951 aPositions.push_back( (VECTOR2I) pos );
952 pos += offset;
953 }
954}
955
956
957void EDA_TEXT::printOneLineOfText( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
958 const COLOR4D& aColor, const wxString& aText, const VECTOR2I& aPos )
959{
960 wxDC* DC = aSettings->GetPrintDC();
961 int penWidth = GetEffectiveTextPenWidth( aSettings->GetDefaultPenWidth() );
962
963 VECTOR2I size = GetTextSize();
964
965 if( IsMirrored() )
966 size.x = -size.x;
967
968 KIFONT::FONT* font = GetDrawFont( aSettings );
969
970 GRPrintText( DC, aOffset + aPos, aColor, aText, GetDrawRotation(), size, GetHorizJustify(),
971 GetVertJustify(), penWidth, IsItalic(), IsBold(), font, getFontMetrics() );
972}
973
974
976{
977 int style = 0;
978
979 if( IsItalic() )
980 style = 1;
981
982 if( IsBold() )
983 style += 2;
984
985 wxString stylemsg[4] = {
986 _("Normal"),
987 _("Italic"),
988 _("Bold"),
989 _("Bold+Italic")
990 };
991
992 return stylemsg[style];
993}
994
995
996wxString EDA_TEXT::GetFontName() const
997{
998 if( GetFont() )
999 return GetFont()->GetName();
1000 else
1001 return wxEmptyString;
1002}
1003
1004
1006{
1007 if( KIFONT::FONT* font = GetFont() )
1008 return font->GetName();
1009
1010 if( IsEeschemaType( dynamic_cast<const EDA_ITEM*>( this )->Type() ) )
1011 return _( "Default Font" );
1012 else
1013 return KICAD_FONT_NAME;
1014}
1015
1016
1017void EDA_TEXT::SetFontProp( const wxString& aFontName )
1018{
1019 if( IsEeschemaType( dynamic_cast<const EDA_ITEM*>( this )->Type() ) )
1020 {
1021 if( aFontName == _( "Default Font" ) )
1022 SetFont( nullptr );
1023 else
1024 SetFont( KIFONT::FONT::GetFont( aFontName, IsBold(), IsItalic() ) );
1025 }
1026 else
1027 {
1028 if( aFontName == KICAD_FONT_NAME )
1029 SetFont( nullptr );
1030 else
1031 SetFont( KIFONT::FONT::GetFont( aFontName, IsBold(), IsItalic() ) );
1032 }
1033}
1034
1035
1037{
1038 return ( !IsMirrored()
1041 && GetAutoThickness()
1042 && !IsItalic()
1043 && !IsBold()
1044 && !IsMultilineAllowed()
1045 && GetFontName().IsEmpty()
1046 );
1047}
1048
1049
1050void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aControlBits ) const
1051{
1052 aFormatter->Print( "(effects" );
1053
1054 aFormatter->Print( "(font" );
1055
1056 if( GetFont() && !GetFont()->GetName().IsEmpty() )
1057 aFormatter->Print( "(face %s)", aFormatter->Quotew( GetFont()->NameAsToken() ).c_str() );
1058
1059 // Text size
1060 aFormatter->Print( "(size %s %s)",
1063
1064 if( GetLineSpacing() != 1.0 )
1065 {
1066 aFormatter->Print( "(line_spacing %s)",
1067 FormatDouble2Str( GetLineSpacing() ).c_str() );
1068 }
1069
1070 if( !GetAutoThickness() )
1071 {
1072 aFormatter->Print( "(thickness %s)",
1074 }
1075
1076 if( IsBold() )
1077 KICAD_FORMAT::FormatBool( aFormatter, "bold", true );
1078
1079 if( IsItalic() )
1080 KICAD_FORMAT::FormatBool( aFormatter, "italic", true );
1081
1082 if( !( aControlBits & CTL_OMIT_COLOR ) && GetTextColor() != COLOR4D::UNSPECIFIED )
1083 {
1084 aFormatter->Print( "(color %d %d %d %s)",
1085 KiROUND( GetTextColor().r * 255.0 ),
1086 KiROUND( GetTextColor().g * 255.0 ),
1087 KiROUND( GetTextColor().b * 255.0 ),
1088 FormatDouble2Str( GetTextColor().a ).c_str() );
1089 }
1090
1091 aFormatter->Print( ")"); // (font
1092
1095 {
1096 aFormatter->Print( "(justify");
1097
1099 aFormatter->Print( GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT ? " left" : " right" );
1100
1102 aFormatter->Print( GetVertJustify() == GR_TEXT_V_ALIGN_TOP ? " top" : " bottom" );
1103
1104 if( IsMirrored() )
1105 aFormatter->Print( " mirror" );
1106
1107 aFormatter->Print( ")" ); // (justify
1108 }
1109
1110 if( !( aControlBits & CTL_OMIT_HYPERLINK ) && HasHyperlink() )
1111 aFormatter->Print( "(href %s)", aFormatter->Quotew( GetHyperlink() ).c_str() );
1112
1113 aFormatter->Print( ")" ); // (effects
1114}
1115
1116
1117std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangulate,
1118 const BOX2I& aBBox,
1119 const EDA_ANGLE& aAngle ) const
1120{
1121 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
1122 KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
1123 KIFONT::FONT* font = GetDrawFont( nullptr );
1124 int penWidth = GetEffectiveTextPenWidth();
1125 wxString shownText( GetShownText( true ) );
1126 VECTOR2I drawPos = GetDrawPos();
1128
1129 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
1130
1131 if( aBBox.GetWidth() )
1132 {
1133 drawPos = aBBox.GetCenter();
1136 attrs.m_Angle = aAngle;
1137 }
1138 else
1139 {
1140 attrs.m_Angle = GetDrawRotation();
1141
1142 if( font->IsOutline() )
1143 cache = GetRenderCache( font, shownText, VECTOR2I() );
1144 }
1145
1146 if( aTriangulate )
1147 {
1148 CALLBACK_GAL callback_gal(
1149 empty_opts,
1150 // Stroke callback
1151 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
1152 {
1153 shape->AddShape( new SHAPE_SEGMENT( aPt1, aPt2, penWidth ) );
1154 },
1155 // Triangulation callback
1156 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
1157 {
1158 SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE;
1159
1160 for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } )
1161 triShape->Append( point.x, point.y );
1162
1163 shape->AddShape( triShape );
1164 } );
1165
1166 if( cache )
1167 callback_gal.DrawGlyphs( *cache );
1168 else
1169 font->Draw( &callback_gal, shownText, drawPos, attrs, getFontMetrics() );
1170 }
1171 else
1172 {
1173 CALLBACK_GAL callback_gal(
1174 empty_opts,
1175 // Stroke callback
1176 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
1177 {
1178 shape->AddShape( new SHAPE_SEGMENT( aPt1, aPt2, penWidth ) );
1179 },
1180 // Outline callback
1181 [&]( const SHAPE_LINE_CHAIN& aPoly )
1182 {
1183 shape->AddShape( aPoly.Clone() );
1184 } );
1185
1186 if( cache )
1187 callback_gal.DrawGlyphs( *cache );
1188 else
1189 font->Draw( &callback_gal, shownText, drawPos, attrs, getFontMetrics() );
1190 }
1191
1192 return shape;
1193}
1194
1195
1196int EDA_TEXT::Compare( const EDA_TEXT* aOther ) const
1197{
1198 wxCHECK( aOther, 1 );
1199
1200 int val = m_attributes.Compare( aOther->m_attributes );
1201
1202 if( val != 0 )
1203 return val;
1204
1205 if( m_pos.x != aOther->m_pos.x )
1206 return m_pos.x - aOther->m_pos.x;
1207
1208 if( m_pos.y != aOther->m_pos.y )
1209 return m_pos.y - aOther->m_pos.y;
1210
1211 val = GetFontName().Cmp( aOther->GetFontName() );
1212
1213 if( val != 0 )
1214 return val;
1215
1216 return m_text.Cmp( aOther->m_text );
1217}
1218
1219
1220bool EDA_TEXT::ValidateHyperlink( const wxString& aURL )
1221{
1222 if( aURL.IsEmpty() || IsGotoPageHref( aURL ) )
1223 return true;
1224
1225 wxURI uri;
1226
1227 return( uri.Create( aURL ) && uri.HasScheme() );
1228}
1229
1230double EDA_TEXT::Levenshtein( const EDA_TEXT& aOther ) const
1231{
1232 // Compute the Levenshtein distance between the two strings
1233 const wxString& str1 = GetText();
1234 const wxString& str2 = aOther.GetText();
1235
1236 int m = str1.length();
1237 int n = str2.length();
1238
1239 if( n == 0 || m == 0 )
1240 return 0.0;
1241
1242 // Create a matrix to store the distance values
1243 std::vector<std::vector<int>> distance(m + 1, std::vector<int>(n + 1));
1244
1245 // Initialize the matrix
1246 for( int i = 0; i <= m; i++ )
1247 distance[i][0] = i;
1248 for( int j = 0; j <= n; j++ )
1249 distance[0][j] = j;
1250
1251 // Calculate the distance
1252 for( int i = 1; i <= m; i++ )
1253 {
1254 for( int j = 1; j <= n; j++ )
1255 {
1256 if( str1[i - 1] == str2[j - 1] )
1257 {
1258 distance[i][j] = distance[i - 1][j - 1];
1259 }
1260 else
1261 {
1262 distance[i][j] = std::min( { distance[i - 1][j], distance[i][j - 1],
1263 distance[i - 1][j - 1] } ) + 1;
1264 }
1265 }
1266 }
1267
1268 // Calculate similarity score
1269 int maxLen = std::max( m, n );
1270 double similarity = 1.0 - ( static_cast<double>( distance[m][n] ) / maxLen );
1271
1272 return similarity;
1273}
1274
1275
1276double EDA_TEXT::Similarity( const EDA_TEXT& aOther ) const
1277{
1278 double retval = 1.0;
1279
1280 if( !( m_attributes == aOther.m_attributes ) )
1281 retval *= 0.9;
1282
1283 if( m_pos != aOther.m_pos )
1284 retval *= 0.9;
1285
1286 retval *= Levenshtein( aOther );
1287
1288 return retval;
1289}
1290
1291
1292bool EDA_TEXT::IsGotoPageHref( const wxString& aHref, wxString* aDestination )
1293{
1294 return aHref.StartsWith( wxT( "#" ), aDestination );
1295}
1296
1297
1298wxString EDA_TEXT::GotoPageHref( const wxString& aDestination )
1299{
1300 return wxT( "#" ) + aDestination;
1301}
1302
1303
1304std::ostream& operator<<( std::ostream& aStream, const EDA_TEXT& aText )
1305{
1306 aStream << aText.GetText();
1307
1308 return aStream;
1309}
1310
1311
1312static struct EDA_TEXT_DESC
1313{
1315 {
1316 // These are defined in SCH_FIELD as well but initialization order is
1317 // not defined, so this needs to be conditional. Defining in both
1318 // places leads to duplicate symbols.
1320
1321 if( h_inst.Choices().GetCount() == 0)
1322 {
1323 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _( "Left" ) );
1324 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _( "Center" ) );
1325 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _( "Right" ) );
1326 }
1327
1329
1330 if( v_inst.Choices().GetCount() == 0)
1331 {
1332 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _( "Top" ) );
1333 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _( "Center" ) );
1334 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _( "Bottom" ) );
1335 }
1336
1339
1340 propMgr.AddProperty( new PROPERTY<EDA_TEXT, double>( _HKI( "Orientation" ),
1343
1344 const wxString textProps = _HKI( "Text Properties" );
1345
1346 propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _HKI( "Text" ),
1348 textProps );
1349
1350 propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _HKI( "Font" ),
1352 textProps )
1354 .SetChoicesFunc( []( INSPECTABLE* aItem )
1355 {
1356 EDA_ITEM* eda_item = static_cast<EDA_ITEM*>( aItem );
1357 wxPGChoices fonts;
1358 std::vector<std::string> fontNames;
1359
1360 Fontconfig()->ListFonts( fontNames,
1361 std::string( Pgm().GetLanguageTag().utf8_str() ),
1362 eda_item->GetEmbeddedFonts() );
1363
1364 if( IsEeschemaType( eda_item->Type() ) )
1365 fonts.Add( _( "Default Font" ) );
1366
1367 fonts.Add( KICAD_FONT_NAME );
1368
1369 for( const std::string& fontName : fontNames )
1370 fonts.Add( wxString( fontName ) );
1371
1372 return fonts;
1373 } );
1374
1375 propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Auto Thickness" ),
1377 textProps );
1378 propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Thickness" ),
1381 textProps );
1382 propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Italic" ),
1385 textProps );
1386 propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Bold" ),
1388 textProps );
1389 propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Mirrored" ),
1391 textProps );
1392
1393 auto isField =
1394 []( INSPECTABLE* aItem ) -> bool
1395 {
1396 if( EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( aItem ) )
1397 return item->Type() == SCH_FIELD_T || item->Type() == PCB_FIELD_T;
1398
1399 return false;
1400 };
1401
1402 propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Visible" ),
1404 textProps )
1405 .SetAvailableFunc( isField );
1406
1407 propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Width" ),
1410 textProps );
1411
1412 propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Height" ),
1415 textProps );
1416
1417 propMgr.AddProperty( new PROPERTY_ENUM<EDA_TEXT, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1419 textProps );
1420 propMgr.AddProperty( new PROPERTY_ENUM<EDA_TEXT, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1422 textProps );
1423
1424 propMgr.AddProperty( new PROPERTY<EDA_TEXT, COLOR4D>( _HKI( "Color" ),
1426 textProps );
1427
1428 propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _HKI( "Hyperlink" ),
1430 textProps );
1431 }
1433
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
Definition api_enums.cpp:95
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:35
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:115
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:237
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:146
constexpr coord_type GetY() const
Definition box2.h:208
constexpr size_type GetWidth() const
Definition box2.h:214
constexpr coord_type GetX() const
Definition box2.h:207
constexpr const Vec GetCenter() const
Definition box2.h:230
constexpr void SetSize(const SizeVec &size)
Definition box2.h:248
constexpr size_type GetHeight() const
Definition box2.h:215
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:168
constexpr void SetX(coord_type val)
Definition box2.h:277
constexpr BOX2< Vec > GetInflated(coord_type aDx, coord_type aDy) const
Get a new rectangle that is this one, inflated by aDx and aDy.
Definition box2.h:638
constexpr void SetY(coord_type val)
Definition box2.h:282
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:259
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:311
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual const std::vector< wxString > * GetEmbeddedFonts()
Definition eda_item.h:469
static bool Replace(const EDA_SEARCH_DATA &aSearchData, wxString &aText)
Perform a text replace on aText using the find and replace criteria in aSearchData on items that supp...
Definition eda_item.cpp:236
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:79
int GetTextHeight() const
Definition eda_text.h:266
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition eda_text.cpp:188
void SetTextColor(const COLOR4D &aColor)
Definition eda_text.h:268
const VECTOR2I & GetTextPos() const
Definition eda_text.h:272
COLOR4D GetTextColor() const
Definition eda_text.h:269
wxString GetTextStyleName() const
Definition eda_text.cpp:975
VECTOR2I m_pos
Definition eda_text.h:475
wxString m_text
Definition eda_text.h:453
std::map< int, BBOX_CACHE_ENTRY > m_bbox_cache
Definition eda_text.h:471
bool IsDefaultFormatting() const
static bool IsGotoPageHref(const wxString &aHref, wxString *aDestination=nullptr)
Check if aHref is a valid internal hyperlink.
void SetFontProp(const wxString &aFontName)
std::vector< std::unique_ptr< KIFONT::GLYPH > > m_render_cache
Definition eda_text.h:463
wxString GetFontName() const
Definition eda_text.cpp:996
virtual ~EDA_TEXT()
Definition eda_text.cpp:150
bool IsItalic() const
Definition eda_text.h:168
bool m_visible
Definition eda_text.h:476
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:534
bool IsMultilineAllowed() const
Definition eda_text.h:196
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:97
bool IsKeepUpright() const
Definition eda_text.h:205
virtual bool IsVisible() const
Definition eda_text.h:186
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:579
void SetTextX(int aX)
Definition eda_text.cpp:585
bool m_shown_text_has_text_var_refs
Definition eda_text.h:455
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition eda_text.cpp:224
KIFONT::FONT * GetFont() const
Definition eda_text.h:246
bool ResolveFont(const std::vector< wxString > *aEmbeddedFonts)
Definition eda_text.cpp:508
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:434
wxString m_shown_text
Definition eda_text.h:454
void SetMirrored(bool isMirrored)
Definition eda_text.cpp:394
wxString GetFontProp() const
void SetTextY(int aY)
Definition eda_text.cpp:591
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const KIFONT::FONT *aFont, const wxString &forResolvedText, const VECTOR2I &aOffset={ 0, 0 }) const
Definition eda_text.cpp:685
const KIFONT::FONT * m_render_cache_font
Definition eda_text.h:460
virtual EDA_ANGLE GetDrawRotation() const
Definition eda_text.h:376
wxString m_unresolvedFontName
Definition eda_text.h:474
virtual VECTOR2I GetDrawPos() const
Definition eda_text.h:377
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition eda_text.cpp:155
int GetTextWidth() const
Definition eda_text.h:263
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition eda_text.cpp:744
virtual bool HasHyperlink() const
Definition eda_text.h:399
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:418
wxString GetHyperlink() const
Definition eda_text.h:400
void Offset(const VECTOR2I &aOffset)
Definition eda_text.cpp:597
virtual void Format(OUTPUTFORMATTER *aFormatter, int aControlBits) const
Output the object to aFormatter in s-expression form.
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:199
void SetTextWidth(int aWidth)
Definition eda_text.cpp:557
virtual KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const
Definition eda_text.cpp:650
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
Definition eda_text.cpp:379
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:487
void SetupRenderCache(const wxString &aResolvedText, const KIFONT::FONT *aFont, const EDA_ANGLE &aAngle, const VECTOR2I &aOffset)
Definition eda_text.cpp:720
int Compare(const EDA_TEXT *aOther) const
std::reference_wrapper< const EDA_IU_SCALE > m_IuScale
Definition eda_text.h:457
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:387
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:96
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:678
bool GetAutoThickness() const
Definition eda_text.h:138
double GetLineSpacing() const
Definition eda_text.h:257
double Similarity(const EDA_TEXT &aOther) const
VECTOR2I m_render_cache_offset
Definition eda_text.h:462
void SetLineSpacing(double aLineSpacing)
Definition eda_text.cpp:526
wxString EvaluateText(const wxString &aText) const
Definition eda_text.cpp:642
void AddRenderCacheGlyph(const SHAPE_POLY_SET &aPoly)
Definition eda_text.cpp:731
void Empty()
Definition eda_text.cpp:616
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition eda_text.cpp:285
virtual bool TextHitTest(const VECTOR2I &aPoint, int aAccuracy=0) const
Test if aPoint is within the bounds of this object.
Definition eda_text.cpp:871
void SetTextHeight(int aHeight)
Definition eda_text.cpp:568
virtual void cacheShownText()
Definition eda_text.cpp:624
EDA_ANGLE m_render_cache_angle
Definition eda_text.h:461
static GR_TEXT_H_ALIGN_T MapHorizJustify(int aHorizJustify)
Definition eda_text.cpp:68
virtual void ClearRenderCache()
Definition eda_text.cpp:672
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:230
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition eda_text.cpp:336
static bool ValidateHyperlink(const wxString &aURL)
Check if aURL is a valid hyperlink.
void SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
Definition eda_text.cpp:328
void SetAutoThickness(bool aAuto)
Definition eda_text.cpp:293
bool IsMirrored() const
Definition eda_text.h:189
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:466
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition eda_text.cpp:453
wxString m_render_cache_text
Definition eda_text.h:459
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, const COLOR4D &aColor)
Print this text object to the device context aDC.
Definition eda_text.cpp:890
double GetTextAngleDegrees() const
Definition eda_text.h:153
void GetLinePositions(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPositions, int aLineCount) const
Populate aPositions with the position of each line of a multiline text, according to the vertical jus...
Definition eda_text.cpp:912
virtual const KIFONT::METRICS & getFontMetrics() const
Definition eda_text.cpp:666
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape(bool aTriangulate=true, const BOX2I &aBBox=BOX2I(), const EDA_ANGLE &aAngle=ANGLE_0) const
build a list of segments (SHAPE_SEGMENT) to describe a text shape.
bool IsBold() const
Definition eda_text.h:183
void SetTextAngleDegrees(double aOrientation)
Definition eda_text.h:149
void SetHyperlink(wxString aLink)
Definition eda_text.h:401
static GR_TEXT_V_ALIGN_T MapVertJustify(int aVertJustify)
Definition eda_text.cpp:82
void SetKeepUpright(bool aKeepUpright)
Definition eda_text.cpp:426
void CopyText(const EDA_TEXT &aSrc)
Definition eda_text.cpp:278
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:202
int GetInterline(const RENDER_SETTINGS *aSettings) const
Return the distance between two lines of text.
Definition eda_text.cpp:738
int GetTextThicknessProperty() const
Definition eda_text.h:129
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:108
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:271
double Levenshtein(const EDA_TEXT &aOther) const
Return the levenstein distance between two texts.
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:300
int GetTextThickness() const
Definition eda_text.h:127
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition eda_text.cpp:308
void SwapText(EDA_TEXT &aTradingPartner)
Definition eda_text.cpp:446
void SetMultilineAllowed(bool aAllow)
Definition eda_text.cpp:402
void SetFont(KIFONT::FONT *aFont)
Definition eda_text.cpp:500
void printOneLineOfText(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, const COLOR4D &aColor, const wxString &aText, const VECTOR2I &aPos)
Print each line of this EDA_TEXT.
Definition eda_text.cpp:957
VECTOR2I GetTextSize() const
Definition eda_text.h:260
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:410
TEXT_ATTRIBUTES m_attributes
Definition eda_text.h:473
static ENUM_MAP< T > & Instance()
Definition property.h:699
High-level wrapper for evaluating mathematical and string expressions in wxString format.
wxString Evaluate(const wxString &aInput)
Main evaluation function - processes input string and evaluates all} expressions.
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:37
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:147
virtual bool IsStroke() const
Definition font.h:138
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
Definition font.cpp:250
const wxString & GetName() const
Definition font.h:149
virtual bool IsOutline() const
Definition font.h:139
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic, const METRICS &aFontMetrics) const
Compute the boundary limits of aText (the bounding box of all shapes).
Definition font.cpp:427
virtual double GetInterline(double aGlyphHeight, const METRICS &aFontMetrics) const =0
Compute the distance (interline) between 2 lines of text (for multiline texts).
static const METRICS & Default()
Definition font.cpp:52
Class OUTLINE_FONT implements outline font drawing.
void GetLinesAsGlyphs(std::vector< std::unique_ptr< GLYPH > > *aGlyphs, const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs, const METRICS &aFontMetrics) const
void CacheTriangulation(bool aPartition=true, bool aSimplify=false) override
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
Definition glyph.cpp:153
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
virtual void DrawGlyphs(const std::vector< std::unique_ptr< KIFONT::GLYPH > > &aGlyphs)
Draw polygons representing font glyphs.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const wxString & GetDefaultFont() const
An interface used to output 8 bit text in a convenient way.
Definition richio.h:322
std::string Quotew(const wxString &aWrapee) const
Definition richio.cpp:548
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition richio.cpp:463
PROPERTY_BASE & SetChoicesFunc(std::function< wxPGChoices(INSPECTABLE *)> aFunc)
Definition property.h:273
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition property.h:259
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
Definition property.h:323
Provide class metadata.Helper macro to map type hashes to names.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
void Append(int aX, int aY)
Append a new point at the end of the polygon.
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
KIFONT::FONT * m_Font
#define CTL_OMIT_HYPERLINK
Omit the hyperlink attribute in .kicad_xxx files.
Definition ctl_flags.h:46
#define CTL_OMIT_COLOR
Omit the color attribute in .kicad_xxx files.
Definition ctl_flags.h:45
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
@ DEGREES_T
Definition eda_angle.h:31
std::ostream & operator<<(std::ostream &aStream, const EDA_TEXT &aText)
static struct EDA_TEXT_DESC _EDA_TEXT_DESC
#define TEXT_MIN_SIZE_MM
Minimum text size (1 micron).
Definition eda_text.h:46
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition eda_text.h:47
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
Definition eda_text.h:69
static constexpr double ITALIC_TILT
Tilt factor for italic style (this is the scaling factor on dY relative coordinates to give a tilted ...
Definition font.h:61
FONTCONFIG * Fontconfig()
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:37
int GetPenSizeForNormal(int aTextSize)
Definition gr_text.cpp:61
void GRPrintText(wxDC *aDC, const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics)
Print a graphic text through wxDC.
Definition gr_text.cpp:117
int ClampTextPenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition gr_text.cpp:73
Some functions to handle hotkeys in KiCad.
#define KICAD_FONT_NAME
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition eda_units.h:166
KICOMMON_API std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue)
Converts aValue from internal units to a string appropriate for writing to file.
void FormatBool(OUTPUTFORMATTER *aOut, const wxString &aKey, bool aValue)
Writes a boolean to the formatter, in the style (aKey [yes|no])
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition api_utils.cpp:85
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput)
Definition api_utils.cpp:78
#define _HKI(x)
Definition page_info.cpp:44
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:913
see class PGM_BASE
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition property.h:801
@ PT_DEGREE
Angle expressed in degrees.
Definition property.h:65
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:62
#define REGISTER_TYPE(x)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
wxString UnescapeString(const wxString &aSource)
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
VECTOR2I location
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
Definition trigo.h:77
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:229
@ SCH_FIELD_T
Definition typeinfo.h:152
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:90
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition typeinfo.h:370
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694