KiCad PCB EDA Suite
view.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) 2013-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <base_struct.h>
29 
30 #include <view/view.h>
31 #include <view/view_group.h>
32 #include <view/view_item.h>
33 #include <view/view_rtree.h>
34 #include <gal/definitions.h>
36 #include <painter.h>
37 
38 #ifdef __WXDEBUG__
39 #include <profile.h>
40 #endif /* __WXDEBUG__ */
41 
42 namespace KIGFX {
43 
44 class VIEW;
45 
47 {
48 public:
50  m_view( nullptr ),
51  m_flags( KIGFX::VISIBLE ),
53  m_groups( nullptr ),
54  m_groupsSize( 0 ) {}
55 
57  {
58  deleteGroups();
59  }
60 
61  int getFlags() const
62  {
63  return m_flags;
64  }
65 
66 private:
67  friend class VIEW;
68 
76  void getLayers( int* aLayers, int& aCount ) const
77  {
78  int* layersPtr = aLayers;
79 
80  for( unsigned int i = 0; i < m_layers.size(); ++i )
81  {
82  if( m_layers[i] )
83  *layersPtr++ = i;
84  }
85 
86  aCount = m_layers.count();
87  }
88 
90  int m_flags;
93 
95  typedef std::pair<int, int> GroupPair;
96 
99  GroupPair* m_groups;
101 
109  int getGroup( int aLayer ) const
110  {
111  for( int i = 0; i < m_groupsSize; ++i )
112  {
113  if( m_groups[i].first == aLayer )
114  return m_groups[i].second;
115  }
116 
117  return -1;
118  }
119 
126  std::vector<int> getAllGroups() const
127  {
128  std::vector<int> groups( m_groupsSize );
129 
130  for( int i = 0; i < m_groupsSize; ++i )
131  {
132  groups[i] = m_groups[i].second;
133  }
134 
135  return groups;
136  }
137 
145  void setGroup( int aLayer, int aGroup )
146  {
147  // Look if there is already an entry for the layer
148  for( int i = 0; i < m_groupsSize; ++i )
149  {
150  if( m_groups[i].first == aLayer )
151  {
152  m_groups[i].second = aGroup;
153  return;
154  }
155  }
156 
157  // If there was no entry for the given layer - create one
158  GroupPair* newGroups = new GroupPair[m_groupsSize + 1];
159 
160  if( m_groupsSize > 0 )
161  {
162  std::copy( m_groups, m_groups + m_groupsSize, newGroups );
163  delete[] m_groups;
164  }
165 
166  m_groups = newGroups;
167  newGroups[m_groupsSize++] = GroupPair( aLayer, aGroup );
168  }
169 
170 
176  {
177  delete[] m_groups;
178  m_groups = nullptr;
179  m_groupsSize = 0;
180  }
181 
182 
189  inline bool storesGroups() const
190  {
191  return m_groupsSize > 0;
192  }
193 
195  std::bitset<VIEW::VIEW_MAX_LAYERS> m_layers;
196 
204  void saveLayers( int* aLayers, int aCount )
205  {
206  m_layers.reset();
207 
208  for( int i = 0; i < aCount; ++i )
209  {
210  // this fires on some eagle board after EAGLE_PLUGIN::Load()
211  wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) );
212 
213  m_layers.set( aLayers[i] );
214  }
215  }
216 
221  int requiredUpdate() const
222  {
223  return m_requiredUpdate;
224  }
225 
231  {
232  m_requiredUpdate = NONE;
233  }
234 
239  bool isRenderable() const
240  {
241  return m_flags == VISIBLE;
242  }
243 };
244 
245 
247 {
248  auto data = aItem->viewPrivData();
249 
250  if( !data )
251  return;
252 
253  if( data->m_view )
254  data->m_view->Remove( aItem );
255 
256  delete data;
257 }
258 
259 
260 VIEW::VIEW( bool aIsDynamic ) :
261  m_enableOrderModifier( true ),
262  m_scale( 4.0 ),
263  m_minScale( 4.0 ), m_maxScale( 15000 ),
264  m_mirrorX( false ), m_mirrorY( false ),
265  m_painter( NULL ),
266  m_gal( NULL ),
267  m_dynamic( aIsDynamic ),
268  m_useDrawPriority( false ),
269  m_nextDrawPriority( 0 )
270 {
272  m_allItems.reserve( 32768 );
273 
274  // Redraw everything at the beginning
275  MarkDirty();
276 
277  // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
278  // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
279  // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
280  // silkscreen, pads, vias, etc.
281  for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
282  AddLayer( i );
283 }
284 
285 
287 {
288  for( LAYER_MAP::value_type& l : m_layers )
289  delete l.second.items;
290 }
291 
292 
293 void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
294 {
295  if( m_layers.find( aLayer ) == m_layers.end() )
296  {
297  m_layers[aLayer] = VIEW_LAYER();
298  m_layers[aLayer].id = aLayer;
299  m_layers[aLayer].items = new VIEW_RTREE();
300  m_layers[aLayer].renderingOrder = aLayer;
301  m_layers[aLayer].visible = true;
302  m_layers[aLayer].displayOnly = aDisplayOnly;
303  m_layers[aLayer].target = TARGET_CACHED;
304  }
305 
306  sortLayers();
307 }
308 
309 
310 void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
311 {
312  int layers[VIEW_MAX_LAYERS], layers_count;
313 
314  if( aDrawPriority < 0 )
315  aDrawPriority = m_nextDrawPriority++;
316 
317  if( !aItem->m_viewPrivData )
318  aItem->m_viewPrivData = new VIEW_ITEM_DATA;
319 
320  aItem->m_viewPrivData->m_view = this;
321  aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
322 
323  aItem->ViewGetLayers( layers, layers_count );
324  aItem->viewPrivData()->saveLayers( layers, layers_count );
325 
326  m_allItems.push_back( aItem );
327 
328  for( int i = 0; i < layers_count; ++i )
329  {
330  VIEW_LAYER& l = m_layers[layers[i]];
331  l.items->Insert( aItem );
332  MarkTargetDirty( l.target );
333  }
334 
335  SetVisible( aItem, true );
336  Update( aItem, KIGFX::ALL );
337 }
338 
339 
340 void VIEW::Remove( VIEW_ITEM* aItem )
341 {
342  if( !aItem )
343  return;
344 
345  auto viewData = aItem->viewPrivData();
346 
347  if( !viewData )
348  return;
349 
350  wxASSERT( viewData->m_view == this );
351  auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
352 
353  if( item != m_allItems.end() )
354  {
355  m_allItems.erase( item );
356  viewData->clearUpdateFlags();
357  }
358 
359  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
360  viewData->getLayers( layers, layers_count );
361 
362  for( int i = 0; i < layers_count; ++i )
363  {
364  VIEW_LAYER& l = m_layers[layers[i]];
365  l.items->Remove( aItem );
366  MarkTargetDirty( l.target );
367 
368  // Clear the GAL cache
369  int prevGroup = viewData->getGroup( layers[i] );
370 
371  if( prevGroup >= 0 )
372  m_gal->DeleteGroup( prevGroup );
373  }
374 
375  viewData->deleteGroups();
376  viewData->m_view = nullptr;
377 }
378 
379 
380 void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
381 {
382  wxASSERT( (unsigned) aLayerId < m_layers.size() );
383  wxASSERT( (unsigned) aRequiredId < m_layers.size() );
384 
385  if( aRequired )
386  m_layers[aLayerId].requiredLayers.insert( aRequiredId );
387  else
388  m_layers[aLayerId].requiredLayers.erase( aRequired );
389 }
390 
391 
392 // stupid C++... python lambda would do this in one line
393 template <class Container>
395 {
396  typedef typename Container::value_type item_type;
397 
398  queryVisitor( Container& aCont, int aLayer ) :
399  m_cont( aCont ), m_layer( aLayer )
400  {
401  }
402 
403  bool operator()( VIEW_ITEM* aItem )
404  {
405  if( aItem->viewPrivData()->getFlags() & VISIBLE )
406  m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
407 
408  return true;
409  }
410 
411  Container& m_cont;
412  int m_layer;
413 };
414 
415 
416 int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
417 {
418  if( m_orderedLayers.empty() )
419  return 0;
420 
421  std::vector<VIEW_LAYER*>::const_reverse_iterator i;
422 
423  // execute queries in reverse direction, so that items that are on the top of
424  // the rendering stack are returned first.
425  for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
426  {
427  // ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
428  if( ( *i )->displayOnly )
429  continue;
430 
431  queryVisitor<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
432  ( *i )->items->Query( aRect, visitor );
433  }
434 
435  return aResult.size();
436 }
437 
438 
439 VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
440 {
441  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
442 
443  if( aAbsolute )
444  return VECTOR2D( matrix * aCoord );
445  else
446  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
447 }
448 
449 
450 double VIEW::ToWorld( double aSize ) const
451 {
452  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
453 
454  return matrix.GetScale().x * aSize;
455 }
456 
457 
458 VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
459 {
460  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
461 
462  if( aAbsolute )
463  return VECTOR2D( matrix * aCoord );
464  else
465  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
466 }
467 
468 
469 double VIEW::ToScreen( double aSize ) const
470 {
471  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
472 
473  return matrix.GetScale().x * aSize;
474 }
475 
476 
477 void VIEW::CopySettings( const VIEW* aOtherView )
478 {
479  wxASSERT_MSG( false, wxT( "This is not implemented" ) );
480 }
481 
482 
483 void VIEW::SetGAL( GAL* aGal )
484 {
485  m_gal = aGal;
486 
487  // clear group numbers, so everything is going to be recached
488  clearGroupCache();
489 
490  // every target has to be refreshed
491  MarkDirty();
492 
493  // force the new GAL to display the current viewport.
494  SetCenter( m_center );
495  SetScale( m_scale );
497 }
498 
499 
501 {
502  BOX2D rect;
503  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
504 
505  rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
506  rect.SetEnd( ToWorld( screenSize ) );
507 
508  return rect.Normalize();
509 }
510 
511 
512 void VIEW::SetViewport( const BOX2D& aViewport )
513 {
514  VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
515 
516  wxASSERT( ssize.x > 0 && ssize.y > 0 );
517 
518  VECTOR2D centre = aViewport.Centre();
519  VECTOR2D vsize = aViewport.GetSize();
520  double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
521 
522  SetCenter( centre );
523  SetScale( GetScale() * zoom );
524 }
525 
526 
527 void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
528 {
529  wxASSERT_MSG( !aMirrorY, _( "Mirroring for Y axis is not supported yet" ) );
530 
531  m_mirrorX = aMirrorX;
532  m_mirrorY = aMirrorY;
533  m_gal->SetFlip( aMirrorX, aMirrorY );
534 
535  // Redraw everything
536  MarkDirty();
537 }
538 
539 
540 void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
541 {
542  VECTOR2D a = ToScreen( aAnchor );
543 
544  if( aScale < m_minScale )
546  else if( aScale > m_maxScale )
548  else
549  m_scale = aScale;
550 
553 
554  VECTOR2D delta = ToWorld( a ) - aAnchor;
555 
556  SetCenter( m_center - delta );
557 
558  // Redraw everything after the viewport has changed
559  MarkDirty();
560 }
561 
562 
563 void VIEW::SetCenter( const VECTOR2D& aCenter )
564 {
565  m_center = aCenter;
566 
567  if( !m_boundary.Contains( aCenter ) )
568  {
569  if( m_center.x < m_boundary.GetLeft() )
571  else if( aCenter.x > m_boundary.GetRight() )
573 
574  if( m_center.y < m_boundary.GetTop() )
576  else if( m_center.y > m_boundary.GetBottom() )
578  }
579 
582 
583  // Redraw everything after the viewport has changed
584  MarkDirty();
585 }
586 
587 
588 void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
589 {
590  m_layers[aLayer].renderingOrder = aRenderingOrder;
591 
592  sortLayers();
593 }
594 
595 
596 int VIEW::GetLayerOrder( int aLayer ) const
597 {
598  return m_layers.at( aLayer ).renderingOrder;
599 }
600 
601 
602 void VIEW::SortLayers( int aLayers[], int& aCount ) const
603 {
604  int maxLay, maxOrd, maxIdx;
605 
606  for( int i = 0; i < aCount; ++i )
607  {
608  maxLay = aLayers[i];
609  maxOrd = GetLayerOrder( maxLay );
610  maxIdx = i;
611 
612  // Look for the max element in the range (j..aCount)
613  for( int j = i; j < aCount; ++j )
614  {
615  if( maxOrd < GetLayerOrder( aLayers[j] ) )
616  {
617  maxLay = aLayers[j];
618  maxOrd = GetLayerOrder( maxLay );
619  maxIdx = j;
620  }
621  }
622 
623  // Swap elements
624  aLayers[maxIdx] = aLayers[i];
625  aLayers[i] = maxLay;
626  }
627 }
628 
629 
631 {
632  updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) :
633  layer( aLayer ), painter( aPainter ), gal( aGal )
634  {
635  }
636 
637  bool operator()( VIEW_ITEM* aItem )
638  {
639  // Obtain the color that should be used for coloring the item
640  const COLOR4D color = painter->GetSettings()->GetColor( aItem, layer );
641  int group = aItem->viewPrivData()->getGroup( layer );
642 
643  if( group >= 0 )
644  gal->ChangeGroupColor( group, color );
645 
646  return true;
647  }
648 
649  int layer;
652 };
653 
654 
655 void VIEW::UpdateLayerColor( int aLayer )
656 {
657  // There is no point in updating non-cached layers
658  if( !IsCached( aLayer ) )
659  return;
660 
661  BOX2I r;
662 
663  r.SetMaximum();
664 
665  m_gal->BeginUpdate();
666  updateItemsColor visitor( aLayer, m_painter, m_gal );
667  m_layers[aLayer].items->Query( r, visitor );
668  MarkTargetDirty( m_layers[aLayer].target );
669  m_gal->EndUpdate();
670 }
671 
672 
674 {
675  BOX2I r;
676 
677  r.SetMaximum();
678  m_gal->BeginUpdate();
679 
680  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
681  {
682  VIEW_LAYER* l = &( ( *i ).second );
683 
684  // There is no point in updating non-cached layers
685  if( !IsCached( l->id ) )
686  continue;
687 
688  updateItemsColor visitor( l->id, m_painter, m_gal );
689  l->items->Query( r, visitor );
690  }
691 
692  m_gal->EndUpdate();
693  MarkDirty();
694 }
695 
696 
698 {
699  changeItemsDepth( int aLayer, int aDepth, GAL* aGal ) :
700  layer( aLayer ), depth( aDepth ), gal( aGal )
701  {
702  }
703 
704  bool operator()( VIEW_ITEM* aItem )
705  {
706  int group = aItem->viewPrivData()->getGroup( layer );
707 
708  if( group >= 0 )
709  gal->ChangeGroupDepth( group, depth );
710 
711  return true;
712  }
713 
714  int layer, depth;
716 };
717 
718 
719 void VIEW::ChangeLayerDepth( int aLayer, int aDepth )
720 {
721  // There is no point in updating non-cached layers
722  if( !IsCached( aLayer ) )
723  return;
724 
725  BOX2I r;
726 
727  r.SetMaximum();
728 
729  m_gal->BeginUpdate();
730  changeItemsDepth visitor( aLayer, aDepth, m_gal );
731  m_layers[aLayer].items->Query( r, visitor );
732  m_gal->EndUpdate();
733 
734  MarkTargetDirty( m_layers[aLayer].target );
735 }
736 
737 
738 int VIEW::GetTopLayer() const
739 {
740  if( m_topLayers.size() == 0 )
741  return 0;
742 
743  return *m_topLayers.begin();
744 }
745 
746 
747 void VIEW::SetTopLayer( int aLayer, bool aEnabled )
748 {
749  if( aEnabled )
750  {
751  if( m_topLayers.count( aLayer ) == 1 )
752  return;
753 
754  m_topLayers.insert( aLayer );
755 
756  // Move the layer closer to front
758  m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER;
759  }
760  else
761  {
762  if( m_topLayers.count( aLayer ) == 0 )
763  return;
764 
765  m_topLayers.erase( aLayer );
766 
767  // Restore the previous rendering order
769  m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER;
770  }
771 }
772 
773 
774 void VIEW::EnableTopLayer( bool aEnable )
775 {
776  if( aEnable == m_enableOrderModifier )
777  return;
778 
779  m_enableOrderModifier = aEnable;
780 
781  std::set<unsigned int>::iterator it;
782 
783  if( aEnable )
784  {
785  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
786  m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER;
787  }
788  else
789  {
790  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
791  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
792  }
793 
796 }
797 
798 
800 {
801  std::set<unsigned int>::iterator it;
802 
804  {
805  // Restore the previous rendering order for layers that were marked as top
806  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
807  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
808  }
809 
810  m_topLayers.clear();
811 }
812 
813 
815 {
816  sortLayers();
817 
818  for( LAYER_MAP::value_type& l : m_layers )
819  {
820  ChangeLayerDepth( l.first, l.second.renderingOrder );
821  }
822 
823  MarkDirty();
824 }
825 
826 
828 {
829  drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority ) :
830  view( aView ), layer( aLayer ), useDrawPriority( aUseDrawPriority )
831  {
832  }
833 
834  bool operator()( VIEW_ITEM* aItem )
835  {
836  wxASSERT( aItem->viewPrivData() );
837 
838  // Conditions that have te be fulfilled for an item to be drawn
839  bool drawCondition = aItem->viewPrivData()->isRenderable() &&
840  aItem->ViewGetLOD( layer, view ) < view->m_scale;
841  if( !drawCondition )
842  return true;
843 
844  if( useDrawPriority )
845  drawItems.push_back( aItem );
846  else
847  view->draw( aItem, layer );
848 
849  return true;
850  }
851 
853  {
854  std::sort( drawItems.begin(), drawItems.end(),
855  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
856  return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
857  });
858 
859  for( auto item : drawItems )
860  view->draw( item, layer );
861  }
862 
866  std::vector<VIEW_ITEM*> drawItems;
867 };
868 
869 
870 void VIEW::redrawRect( const BOX2I& aRect )
871 {
872  for( VIEW_LAYER* l : m_orderedLayers )
873  {
874  if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
875  {
876  drawItem drawFunc( this, l->id, m_useDrawPriority );
877 
878  m_gal->SetTarget( l->target );
879  m_gal->SetLayerDepth( l->renderingOrder );
880  l->items->Query( aRect, drawFunc );
881 
882  if( m_useDrawPriority )
883  drawFunc.deferredDraw();
884  }
885  }
886 }
887 
888 
889 void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
890 {
891  auto viewData = aItem->viewPrivData();
892 
893  if( !viewData )
894  return;
895 
896  if( IsCached( aLayer ) && !aImmediate )
897  {
898  // Draw using cached information or create one
899  int group = viewData->getGroup( aLayer );
900 
901  if( group >= 0 )
902  {
903  m_gal->DrawGroup( group );
904  }
905  else
906  {
907  group = m_gal->BeginGroup();
908  viewData->setGroup( aLayer, group );
909 
910  if( !m_painter->Draw( aItem, aLayer ) )
911  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
912 
913  m_gal->EndGroup();
914  }
915  }
916  else
917  {
918  // Immediate mode
919  if( !m_painter->Draw( aItem, aLayer ) )
920  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
921  }
922 }
923 
924 
925 void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
926 {
927  int layers[VIEW_MAX_LAYERS], layers_count;
928 
929  aItem->ViewGetLayers( layers, layers_count );
930 
931  // Sorting is needed for drawing order dependent GALs (like Cairo)
932  SortLayers( layers, layers_count );
933 
934  for( int i = 0; i < layers_count; ++i )
935  {
936  m_gal->SetLayerDepth( m_layers.at( layers[i] ).renderingOrder );
937  draw( aItem, layers[i], aImmediate );
938  }
939 }
940 
941 
942 void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
943 {
944  for( unsigned int i = 0; i < aGroup->GetSize(); i++)
945  draw( aGroup->GetItem(i), aImmediate );
946 }
947 
948 
950 {
951  recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
952  view( aView ), gal( aGal ), layer( aLayer )
953  {
954  }
955 
956  bool operator()( VIEW_ITEM* aItem )
957  {
958  auto viewData = aItem->viewPrivData();
959 
960  if( !viewData )
961  return false;
962 
963  // Remove previously cached group
964  int group = viewData->getGroup( layer );
965 
966  if( group >= 0 )
967  gal->DeleteGroup( group );
968 
969  viewData->setGroup( layer, -1 );
970  view->Update( aItem );
971 
972  return true;
973  }
974 
977  int layer;
978 };
979 
980 
982 {
983  BOX2I r;
984  r.SetMaximum();
985  m_allItems.clear();
986 
987  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
988  i->second.items->RemoveAll();
989 
990  m_nextDrawPriority = 0;
991 
992  m_gal->ClearCache();
993 }
994 
995 
997 {
999  {
1000  // TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
1001  // layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
1004 
1005  MarkDirty();
1006  }
1007 
1008  if( IsTargetDirty( TARGET_OVERLAY ) )
1009  {
1011  }
1012 }
1013 
1014 
1016 {
1017 #ifdef __WXDEBUG__
1018  PROF_COUNTER totalRealTime;
1019 #endif /* __WXDEBUG__ */
1020 
1021  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
1022  BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
1023  ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
1024  rect.Normalize();
1025 
1026  redrawRect( rect );
1027 
1028  // All targets were redrawn, so nothing is dirty
1032 
1033 #ifdef __WXDEBUG__
1034  totalRealTime.Stop();
1035  wxLogTrace( "GAL_PROFILE", wxT( "VIEW::Redraw(): %.1f ms" ), totalRealTime.msecs() );
1036 #endif /* __WXDEBUG__ */
1037 }
1038 
1039 
1041 {
1042  return m_gal->GetScreenPixelSize();
1043 }
1044 
1045 
1047 {
1048  clearLayerCache( VIEW* aView ) :
1049  view( aView )
1050  {
1051  }
1052 
1053  bool operator()( VIEW_ITEM* aItem )
1054  {
1055  aItem->viewPrivData()->deleteGroups();
1056 
1057  return true;
1058  }
1059 
1061 };
1062 
1063 
1065 {
1066  BOX2I r;
1067 
1068  r.SetMaximum();
1069  clearLayerCache visitor( this );
1070 
1071  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1072  {
1073  VIEW_LAYER* l = &( ( *i ).second );
1074  l->items->Query( r, visitor );
1075  }
1076 }
1077 
1078 
1079 void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
1080 {
1081  // updateLayers updates geometry too, so we do not have to update both of them at the same time
1082  if( aUpdateFlags & LAYERS )
1083  updateLayers( aItem );
1084  else if( aUpdateFlags & GEOMETRY )
1085  updateBbox( aItem );
1086 
1087  int layers[VIEW_MAX_LAYERS], layers_count;
1088  aItem->ViewGetLayers( layers, layers_count );
1089 
1090  // Iterate through layers used by the item and recache it immediately
1091  for( int i = 0; i < layers_count; ++i )
1092  {
1093  int layerId = layers[i];
1094 
1095  if( IsCached( layerId ) )
1096  {
1097  if( aUpdateFlags & ( GEOMETRY | LAYERS ) )
1098  updateItemGeometry( aItem, layerId );
1099  else if( aUpdateFlags & COLOR )
1100  updateItemColor( aItem, layerId );
1101  }
1102 
1103  // Mark those layers as dirty, so the VIEW will be refreshed
1104  MarkTargetDirty( m_layers[layerId].target );
1105  }
1106 
1107  aItem->viewPrivData()->clearUpdateFlags();
1108 }
1109 
1110 
1112 {
1113  int n = 0;
1114 
1115  m_orderedLayers.resize( m_layers.size() );
1116 
1117  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1118  m_orderedLayers[n++] = &i->second;
1119 
1120  sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
1121 
1122  MarkDirty();
1123 }
1124 
1125 
1126 void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
1127 {
1128  auto viewData = aItem->viewPrivData();
1129  wxASSERT( (unsigned) aLayer < m_layers.size() );
1130  wxASSERT( IsCached( aLayer ) );
1131 
1132  if( !viewData )
1133  return;
1134 
1135  // Obtain the color that should be used for coloring the item on the specific layerId
1136  const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
1137  int group = viewData->getGroup( aLayer );
1138 
1139  // Change the color, only if it has group assigned
1140  if( group >= 0 )
1141  m_gal->ChangeGroupColor( group, color );
1142 }
1143 
1144 
1145 void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
1146 {
1147  auto viewData = aItem->viewPrivData();
1148  wxASSERT( (unsigned) aLayer < m_layers.size() );
1149  wxASSERT( IsCached( aLayer ) );
1150 
1151  if( !viewData )
1152  return;
1153 
1154  VIEW_LAYER& l = m_layers.at( aLayer );
1155 
1156  m_gal->SetTarget( l.target );
1158 
1159  // Redraw the item from scratch
1160  int group = viewData->getGroup( aLayer );
1161 
1162  if( group >= 0 )
1163  m_gal->DeleteGroup( group );
1164 
1165  group = m_gal->BeginGroup();
1166  viewData->setGroup( aLayer, group );
1167 
1168  if( !m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ) )
1169  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
1170 
1171  m_gal->EndGroup();
1172 }
1173 
1174 
1176 {
1177  int layers[VIEW_MAX_LAYERS], layers_count;
1178 
1179  aItem->ViewGetLayers( layers, layers_count );
1180 
1181  for( int i = 0; i < layers_count; ++i )
1182  {
1183  VIEW_LAYER& l = m_layers[layers[i]];
1184  l.items->Remove( aItem );
1185  l.items->Insert( aItem );
1186  MarkTargetDirty( l.target );
1187  }
1188 }
1189 
1190 
1192 {
1193  auto viewData = aItem->viewPrivData();
1194  int layers[VIEW_MAX_LAYERS], layers_count;
1195 
1196  if( !viewData )
1197  return;
1198 
1199  // Remove the item from previous layer set
1200  viewData->getLayers( layers, layers_count );
1201 
1202  for( int i = 0; i < layers_count; ++i )
1203  {
1204  VIEW_LAYER& l = m_layers[layers[i]];
1205  l.items->Remove( aItem );
1206  MarkTargetDirty( l.target );
1207 
1208  if( IsCached( l.id ) )
1209  {
1210  // Redraw the item from scratch
1211  int prevGroup = viewData->getGroup( layers[i] );
1212 
1213  if( prevGroup >= 0 )
1214  {
1215  m_gal->DeleteGroup( prevGroup );
1216  viewData->setGroup( l.id, -1 );
1217  }
1218  }
1219  }
1220 
1221  // Add the item to new layer set
1222  aItem->ViewGetLayers( layers, layers_count );
1223  viewData->saveLayers( layers, layers_count );
1224 
1225  for( int i = 0; i < layers_count; i++ )
1226  {
1227  VIEW_LAYER& l = m_layers[layers[i]];
1228  l.items->Insert( aItem );
1229  MarkTargetDirty( l.target );
1230  }
1231 }
1232 
1233 
1234 bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
1235 {
1236  wxASSERT( (unsigned) aLayerId < m_layers.size() );
1237 
1238  std::set<int>::const_iterator it, it_end;
1239 
1240  for( it = m_layers.at( aLayerId ).requiredLayers.begin(),
1241  it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
1242  {
1243  // That is enough if just one layer is not enabled
1244  if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) )
1245  return false;
1246  }
1247 
1248  return true;
1249 }
1250 
1251 
1253 {
1254  BOX2I r;
1255 
1256  r.SetMaximum();
1257 
1258  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1259  {
1260  VIEW_LAYER* l = &( ( *i ).second );
1261 
1262  if( IsCached( l->id ) )
1263  {
1264  recacheItem visitor( this, m_gal, l->id );
1265  l->items->Query( r, visitor );
1266  }
1267  }
1268 }
1269 
1270 
1272 {
1273  m_gal->BeginUpdate();
1274 
1275  for( VIEW_ITEM* item : m_allItems )
1276  {
1277  auto viewData = item->viewPrivData();
1278 
1279  if( !viewData )
1280  continue;
1281 
1282  if( viewData->m_requiredUpdate != NONE )
1283  {
1284  invalidateItem( item, viewData->m_requiredUpdate );
1285  viewData->m_requiredUpdate = NONE;
1286  }
1287  }
1288 
1289  m_gal->EndUpdate();
1290 }
1291 
1292 
1294 {
1296  bool first;
1297 
1299  {
1300  first = true;
1301  }
1302 
1303  bool operator()( VIEW_ITEM* aItem )
1304  {
1305  if( first )
1306  extents = aItem->ViewBBox();
1307  else
1308  extents.Merge( aItem->ViewBBox() );
1309 
1310  return false;
1311  }
1312 };
1313 
1314 
1316 {
1317  extentsVisitor v;
1318  BOX2I fullScene;
1319  fullScene.SetMaximum();
1320 
1321  for( VIEW_LAYER* l : m_orderedLayers )
1322  {
1323  l->items->Query( fullScene, v );
1324  }
1325 
1326  return v.extents;
1327 }
1328 
1329 
1330 void VIEW::SetVisible( VIEW_ITEM* aItem, bool aIsVisible )
1331 {
1332  auto viewData = aItem->viewPrivData();
1333 
1334  if( !viewData )
1335  return;
1336 
1337  bool cur_visible = viewData->m_flags & VISIBLE;
1338 
1339  if( cur_visible != aIsVisible )
1340  {
1341  if( aIsVisible )
1342  viewData->m_flags |= VISIBLE;
1343  else
1344  viewData->m_flags &= ~VISIBLE;
1345 
1346  Update( aItem, APPEARANCE | COLOR );
1347  }
1348 }
1349 
1350 
1351 void VIEW::Hide( VIEW_ITEM* aItem, bool aHide )
1352 {
1353  auto viewData = aItem->viewPrivData();
1354 
1355  if( !viewData )
1356  return;
1357 
1358  if( !( viewData->m_flags & VISIBLE ) )
1359  return;
1360 
1361  if( aHide )
1362  viewData->m_flags |= HIDDEN;
1363  else
1364  viewData->m_flags &= ~HIDDEN;
1365 
1366  Update( aItem, APPEARANCE );
1367 }
1368 
1369 
1370 bool VIEW::IsVisible( const VIEW_ITEM* aItem ) const
1371 {
1372  const auto viewData = aItem->viewPrivData();
1373 
1374  return viewData->m_flags & VISIBLE;
1375 }
1376 
1377 
1378 void VIEW::Update( VIEW_ITEM* aItem )
1379 {
1380  Update( aItem, ALL );
1381 }
1382 
1383 
1384 void VIEW::Update( VIEW_ITEM* aItem, int aUpdateFlags )
1385 {
1386  auto viewData = aItem->viewPrivData();
1387 
1388  if( !viewData )
1389  return;
1390 
1391  assert( aUpdateFlags != NONE );
1392 
1393  viewData->m_requiredUpdate |= aUpdateFlags;
1394 
1395 }
1396 
1397 const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
1398 
1399 };
void Stop()
save the time when this function was called, and set the counter stane to stop
Definition: profile.h:82
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Function Hide() Temporarily hides the item in the view (e.g.
Definition: view.cpp:1351
virtual void DrawGroup(int aGroupNumber)
Draw the stored group.
Item is visible (in general)
Definition: view_item.h:68
int GetTopLayer() const
Definition: view.cpp:738
void deleteGroups()
Function deleteGroups() Removes all of the stored group ids.
Definition: view.cpp:175
VIEW_ITEM_DATA * m_viewPrivData
Definition: view_item.h:149
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:512
void updateLayers(VIEW_ITEM *aItem)
Updates set of layers that an item occupies.
Definition: view.cpp:1191
void AddLayer(int aLayer, bool aDisplayOnly=false)
Function AddLayer() Adds a new layer to the view.
Definition: view.cpp:293
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:588
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:380
void updateItemColor(VIEW_ITEM *aItem, int aLayer)
Updates colors that are used for an item to be drawn.
Definition: view.cpp:1126
bool m_useDrawPriority
Flag to respect draw priority when drawing items.
Definition: view.h:801
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:56
virtual void DeleteGroup(int aGroupNumber)
Delete the group from the memory.
void SetTopLayer(int aLayer, bool aEnabled=true)
Function SetTopLayer() Sets given layer to be displayed on the top or sets back the default order of ...
Definition: view.cpp:747
int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Function Query() Finds all visible items that touch or are within the rectangle aRect.
Definition: view.cpp:416
virtual VIEW_ITEM * GetItem(unsigned int aIdx) const
Definition: view_group.cpp:85
static const int TOP_LAYER_MODIFIER
Rendering order modifier for layers that are marked as top layers.
Definition: view.h:795
void sortLayers()
Definition: view.cpp:1111
queryVisitor(Container &aCont, int aLayer)
Definition: view.cpp:398
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:139
int getGroup(int aLayer) const
Function getGroup() Returns number of the group id for the given layer, or -1 in case it was not cach...
Definition: view.cpp:109
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates...
Definition: view.cpp:439
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1252
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:340
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void SetFlip(bool xAxis, bool yAxis)
Sets flipping of the screen.
virtual void EndUpdate()
Disables item update mode.
GAL * m_gal
Gives interface to PAINTER, that is used to draw items.
Definition: view.h:785
coord_type GetRight() const
Definition: box2.h:187
std::set< unsigned int > m_topLayers
Stores set of layers that are displayed on the top.
Definition: view.h:758
void clearUpdateFlags()
Function clearUpdateFlags() Marks an item as already updated, so it is not going to be redrawn...
Definition: view.cpp:230
void UpdateAllLayersOrder()
Function UpdateLayerOrder() Does everything that is needed to apply the rendering order of layers...
Definition: view.cpp:814
No updates are required.
Definition: view_item.h:55
int requiredUpdate() const
Function viewRequiredUpdate() Returns current update flag for an item.
Definition: view.cpp:221
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes an item from the tree.
Definition: view_rtree.h:63
void SetMirror(bool aMirrorX, bool aMirrorY)
Function SetMirror() Controls the mirroring of the VIEW.
Definition: view.cpp:527
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW...
Definition: view_item.h:82
Visibility flag has changed.
Definition: view_item.h:56
bool isRenderable() const
Function isRenderable() Returns if the item should be drawn or not.
Definition: view.cpp:239
Layers have changed.
Definition: view_item.h:59
const Vec & GetSize() const
Definition: box2.h:177
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:45
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:247
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:774
void setGroup(int aLayer, int aGroup)
Function setGroup() Sets a group id for the item and the layer combination.
Definition: view.cpp:145
const MATRIX3x3D & GetWorldScreenMatrix() const
Get the world <-> screen transformation matrix.
coord_type GetTop() const
Definition: box2.h:192
static const int delta[8][2]
Definition: solve.cpp:112
VECTOR2D m_center
Center point of the VIEW (the point at which we are looking at)
Definition: view.h:761
VIEW * m_view
Current dynamic view the item is assigned to.
Definition: view.cpp:89
int getFlags() const
Definition: view.cpp:61
virtual const COLOR4D & GetColor(const VIEW_ITEM *aItem, int aLayer) const =0
Function GetColor Returns the color that should be used to draw the specific VIEW_ITEM on the specifi...
virtual void EndGroup()
End the group.
Auxiliary rendering target (noncached)
Definition: definitions.h:42
void Insert(VIEW_ITEM *aItem)
Function Insert() Inserts an item into the tree.
Definition: view_rtree.h:49
double m_minScale
Scale lower limit.
Definition: view.h:770
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:956
virtual void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor)
Changes the color used to draw the group.
std::vector< int > getAllGroups() const
Function getAllGroups() Returns all group ids for the item (collected from all layers the item occupi...
Definition: view.cpp:126
void SortLayers(int aLayers[], int &aCount) const
Function SortLayers() Changes the order of given layer ids, so after sorting the order corresponds to...
Definition: view.cpp:602
Class PAINTER contains all the knowledge about how to draw graphical object onto any particular outpu...
Definition: painter.h:277
Container::value_type item_type
Definition: view.cpp:396
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:704
clearLayerCache(VIEW *aView)
Definition: view.cpp:1048
VIEW_ITEM class definition.
int m_drawPriority
Order to draw this item in a layer, lowest first.
Definition: view.cpp:92
BOX2I m_boundary
View boundaries.
Definition: view.h:767
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:563
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:500
bool storesGroups() const
Function storesGroups() Returns information if the item uses at least one group id (ie...
Definition: view.cpp:189
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
void Redraw()
Function Redraw() Immediately redraws the whole view.
Definition: view.cpp:1015
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:575
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:981
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:596
drawItem(VIEW *aView, int aLayer, bool aUseDrawPriority)
Definition: view.cpp:829
virtual int BeginGroup()
Begin a group.
const BOX2I CalculateExtents()
Definition: view.cpp:1315
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:117
virtual void ClearTarget(RENDER_TARGET aTarget)
Clears the target for rendering.
void SetMaximum()
Definition: box2.h:61
virtual void ViewGetLayers(int aLayers[], int &aCount) const =0
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
static const int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:640
bool m_mirrorX
Horizontal flip flag
Definition: view.h:776
void invalidateItem(VIEW_ITEM *aItem, int aUpdateFlags)
Function invalidateItem() Manages dirty flags & redraw queueing when updating an item.
Definition: view.cpp:1079
coord_type GetBottom() const
Definition: box2.h:188
Class VIEW_RTREE - Implements an R-tree for fast spatial indexing of VIEW items.
Definition: view_rtree.h:41
bool IsTargetDirty(int aTarget) const
Function IsTargetDirty() Returns true if any of layers belonging to the target or the target itself s...
Definition: view.h:563
int layers[VIEW_MAX_LAYERS]
Definition: view.cpp:864
int id
layer ID
Definition: view.h:649
Items that may change while the view stays the same (noncached)
Definition: definitions.h:43
virtual void BeginUpdate()
Enables item update mode.
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
LAYER_ORDER m_orderedLayers
Sorted list of pointers to members of m_layers.
Definition: view.h:755
void UpdateItems()
Function UpdateItems() Iterates through the list of items that asked for updating and updates them...
Definition: view.cpp:1271
void markTargetClean(int aTarget)
Definition: view.h:673
GroupPair * m_groups
Indexes of cached GAL display lists corresponding to the item (for every layer it occupies)...
Definition: view.cpp:99
void updateBbox(VIEW_ITEM *aItem)
Updates bounding box of an item.
Definition: view.cpp:1175
PAINTER * m_painter
PAINTER contains information how do draw items.
Definition: view.h:782
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
Definition: box2.h:350
changeItemsDepth(int aLayer, int aDepth, GAL *aGal)
Definition: view.cpp:699
void Query(const BOX2I &aBounds, Visitor &aVisitor)
Function Query() Executes a function object aVisitor for each item whose bounding box intersects with...
Definition: view_rtree.h:80
int m_nextDrawPriority
The next sequential drawing priority.
Definition: view.h:804
void Update(VIEW_ITEM *aItem)
Function Update() For dynamic VIEWs, informs the associated VIEW that the graphical representation of...
Definition: view.cpp:1378
void saveLayers(int *aLayers, int aCount)
Function saveLayers() Saves layers used by the item.
Definition: view.cpp:204
Vec Centre() const
Definition: box2.h:67
virtual unsigned int GetSize() const
Function GetSize() Returns the number of stored items.
Definition: view_group.cpp:80
void ClearTopLayers()
Function ClearTopLayers() Removes all layers from the on-the-top set (they are no longer displayed ov...
Definition: view.cpp:799
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:834
virtual bool Draw(const VIEW_ITEM *aItem, int aLayer)=0
Function Draw Takes an instance of VIEW_ITEM and passes it to a function that know how to draw the it...
LAYER_MAP::iterator LAYER_MAP_ITER
Definition: view.h:656
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:213
const VECTOR2I & GetScreenPixelSize() const
Returns GAL canvas size in pixels.
void clearGroupCache()
Definition: view.cpp:1064
VIEW_ITEM_DATA * viewPrivData() const
Definition: view_item.h:141
double m_maxScale
Scale upper limit.
Definition: view.h:773
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:655
double msecs() const
Definition: profile.h:121
std::vector< VIEW_ITEM * > drawItems
Definition: view.cpp:866
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:403
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:637
void redrawRect(const BOX2I &aRect)
Definition: view.cpp:870
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1303
void updateItemGeometry(VIEW_ITEM *aItem, int aLayer)
Updates all informations needed to draw an item.
Definition: view.cpp:1145
Board layer functions and definitions.
Main rendering target (cached)
Definition: definitions.h:41
void ChangeLayerDepth(int aLayer, int aDepth)
Function ChangeLayerDepth() Changes the depth of items on the given layer.
Definition: view.cpp:719
bool areRequiredLayersEnabled(int aLayerId) const
Checks if every layer required by the aLayerId layer is enabled.
Definition: view.cpp:1234
bool m_enableOrderModifier
Definition: view.h:749
#define max(a, b)
Definition: auxiliary.h:86
static void OnDestroy(VIEW_ITEM *aItem)
Definition: view.cpp:246
virtual void ViewDraw(int aLayer, VIEW *aView) const
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
Definition: view_item.h:114
std::vector< VIEW_ITEM * > m_allItems
Flat list of all items.
Definition: view.h:798
void getLayers(int *aLayers, int &aCount) const
Function getLayers() Returns layer numbers used by the item.
Definition: view.cpp:76
std::bitset< VIEW::VIEW_MAX_LAYERS > m_layers
Stores layer numbers used by the item.
Definition: view.cpp:195
bool IsCached(int aLayer) const
Returns true if the layer is cached.
Definition: view.h:583
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:63
void draw(VIEW_ITEM *aItem, int aLayer, bool aImmediate=false)
Function draw() Draws an item, but on a specified layers.
Definition: view.cpp:889
virtual unsigned int ViewGetLOD(int aLayer, VIEW *aView) const
Function ViewGetLOD() Returns the level of detail of the item.
Definition: view_item.h:133
VECTOR2D ToScreen(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToScreen() Converts a world space point/vector to a point/vector in screen space coordinates...
Definition: view.cpp:458
void SetOrigin(const Vec &pos)
Definition: box2.h:198
const VECTOR2I & GetScreenPixelSize() const
Function GetScreenPixelSize() Returns the size of the our rendering area, in pixels.
Definition: view.cpp:1040
void SetZoomFactor(double aZoomFactor)
Set the zoom factor of the scene.
virtual void ChangeGroupDepth(int aGroupNumber, int aDepth)
Changes the depth (Z-axis position) of the group.
bool m_mirrorY
Vertical flip flag
Definition: view.h:779
void ClearTargets()
Function ClearTargets() Clears targets that are marked as dirty.
Definition: view.cpp:996
int m_flags
Visibility flags.
Definition: view.cpp:90
double GetScale() const
Function GetScale()
Definition: view.h:265
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Function SetVisible() Sets the item visibility.
Definition: view.cpp:1330
void CopySettings(const VIEW *aOtherView)
Function CopySettings() Copies layers and visibility settings from another view.
Definition: view.cpp:477
LAYER_MAP m_layers
Contains set of possible displayed layers and its properties.
Definition: view.h:752
double m_scale
Scale of displayed VIEW_ITEMs.
Definition: view.h:764
Position or shape has changed.
Definition: view_item.h:58
int renderingOrder
rendering order of this layer
Definition: view.h:648
void SetLookAtPoint(const VECTOR2D &aPoint)
Set the Point in world space to look at.
Container & m_cont
Definition: view.cpp:411
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:310
std::pair< int, int > GroupPair
Helper for storing cached items group ids
Definition: view.cpp:95
coord_type GetLeft() const
Definition: box2.h:191
Basic classes for most KiCad items.
VIEW(bool aIsDynamic=true)
Constructor.
Definition: view.cpp:260
Class VIEW.
Definition: view.h:58
bool IsVisible(const VIEW_ITEM *aItem) const
Function IsVisible() Returns information if the item is visible (or not).
Definition: view.cpp:1370
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:673
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:483
int m_requiredUpdate
Flag required for updating.
Definition: view.cpp:91
virtual const BOX2I ViewBBox() const =0
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
recacheItem(VIEW *aView, GAL *aGal, int aLayer)
Definition: view.cpp:951
static bool compareRenderingOrder(VIEW_LAYER *aI, VIEW_LAYER *aJ)
Determines rendering order of layers. Used in display order sorting function.
Definition: view.h:740
virtual void ClearCache()
Delete all data created during caching of graphic items.
virtual void SetTarget(RENDER_TARGET aTarget)
Sets the target for rendering.
void MarkDirty()
Function MarkDirty() Forces redraw of view on the next rendering.
Definition: view.h:601
updateItemsColor(int aLayer, PAINTER *aPainter, GAL *aGal)
Definition: view.cpp:632
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
Class GAL is the abstract interface for drawing on a 2D-surface.
Color has changed.
Definition: view_item.h:57
VIEW_RTREE * items
R-tree indexing all items on this layer.
Definition: view.h:647
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1053
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
RENDER_TARGET target
where the layer should be rendered
Definition: view.h:650