KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_item.h
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) 2018 Jean-Pierre Charras, jp.charras at wandadoo.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, see <https://www.gnu.org/licenses/>.
19 */
20
21#pragma once
22
23#include <map>
24
25#include <core/mirror.h>
26#include <eda_item.h>
28#include <layer_ids.h>
29#include <properties/property.h>
30#include <lseq.h>
31#include <lset.h>
32#include <stroke_params.h>
33#include <geometry/eda_angle.h>
34#include <macros.h>
36
37
38class BOARD;
42class BOARD_COMMIT;
43class SHAPE_POLY_SET;
44class SHAPE_SEGMENT;
45class PCB_BASE_FRAME;
46class SHAPE;
47class PCB_GROUP;
48class FOOTPRINT;
49namespace KIGFX
50{
51 class RENDER_SETTINGS;
52};
53
54namespace KIFONT
55{
56class METRICS;
57}
58
59
78
84class BOARD_ITEM : public EDA_ITEM
85{
86public:
87 BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype, PCB_LAYER_ID aLayer = F_Cu ) :
88 EDA_ITEM( aParent, idtype, false, true ),
89 m_layer( aLayer ),
90 m_isKnockout( false ),
91 m_isLocked( false )
92 {
93 }
94
95 BOARD_ITEM( const BOARD_ITEM& aOther ) :
96 EDA_ITEM( aOther ),
97 m_layer( aOther.m_layer ),
98 m_isKnockout( aOther.m_isKnockout ),
99 m_isLocked( aOther.m_isLocked )
100 {
101 // Cache membership is owned by BOARD: clones start detached from any board index
102 }
103
105 {
106 if( this == &aOther )
107 return *this;
108
109 EDA_ITEM::operator=( aOther );
110 m_layer = aOther.m_layer;
111 m_isKnockout = aOther.m_isKnockout;
112 m_isLocked = aOther.m_isLocked;
113 // Owner stays with the target, do not copy it
114 return *this;
115 }
116
117 // A default move would copy the owner. Do not move it.
118 BOARD_ITEM( BOARD_ITEM&& aOther ) :
119 BOARD_ITEM( static_cast<const BOARD_ITEM&>( aOther ) )
120 {
121 }
122
124 {
125 return operator=( static_cast<const BOARD_ITEM&>( aOther ) );
126 }
127
128 ~BOARD_ITEM() override;
129
130 virtual void CopyFrom( const BOARD_ITEM* aOther );
131
132 bool IsGroupableType() const;
133
134 int GetX() const
135 {
136 VECTOR2I p = GetPosition();
137 return p.x;
138 }
139
140 int GetY() const
141 {
142 VECTOR2I p = GetPosition();
143 return p.y;
144 }
145
151 virtual VECTOR2I GetCenter() const
152 {
153 return GetBoundingBox().GetCenter();
154 }
155
156 void SetX( int aX )
157 {
158 VECTOR2I p( aX, GetY() );
159 SetPosition( p );
160 }
161
162 void SetY( int aY )
163 {
164 VECTOR2I p( GetX(), aY );
165 SetPosition( p );
166 }
167
173 virtual bool IsConnected() const
174 {
175 return false;
176 }
177
184 virtual double Similarity( const BOARD_ITEM& aItem ) const = 0;
185 virtual bool operator==( const BOARD_ITEM& aItem ) const = 0;
186
190 virtual bool IsOnCopperLayer() const
191 {
192 if( IsSingleLayerType( Type() ) )
193 {
194 return IsCopperLayer( GetLayer() );
195 }
196 else
197 {
198 for( PCB_LAYER_ID layer : GetLayerSet() )
199 {
200 if( IsCopperLayer( layer ) )
201 return true;
202 }
203
204 return false;
205 }
206 }
207
208 virtual bool HasHole() const
209 {
210 return false;
211 }
212
213 virtual bool HasDrilledHole() const
214 {
215 return false;
216 }
217
225 virtual bool IsTented( PCB_LAYER_ID aLayer ) const
226 {
227 return false;
228 }
229
234
253 virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
255 DRC_CONSTRAINT_T aUsage = NULL_CONSTRAINT ) const;
256
257 virtual std::shared_ptr<SHAPE_SEGMENT> GetEffectiveHoleShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
258 DRC_CONSTRAINT_T aUsage = NULL_CONSTRAINT ) const;
259
265 virtual void RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction, RECURSE_MODE aMode ) const {}
266
268
270
276 void SetUuidDirect( const KIID& aUuid );
277
279
280 void SetUuid( const KIID& aUuid );
281 void ResetUuid() { SetUuid( KIID() ); }
282
288 virtual void RemapKIIDs( const std::map<KIID, KIID>& aIdMap ) {}
289
291 void SetFPRelativePosition( const VECTOR2I& aPos );
292
298 virtual bool HasLineStroke() const { return false; }
299
308 virtual bool IsLayerAgnostic() const { return false; }
309
317 virtual bool FitsEnabledLayers( const LSET& aEnabledLayers, int aCopperLayerCount ) const;
318
319 virtual STROKE_PARAMS GetStroke() const;
320 virtual void SetStroke( const STROKE_PARAMS& aStroke );
321
322 const KIFONT::METRICS& GetFontMetrics() const;
323
327 virtual PCB_LAYER_ID GetLayer() const;
328
336
340 virtual int BoardLayerCount() const;
341
345 virtual int BoardCopperLayerCount() const;
346
350 virtual LSET BoardLayerSet() const;
351
355 virtual LSET GetLayerSet() const
356 {
357 if( m_layer == UNDEFINED_LAYER )
358 return LSET();
359 else
360 return LSET( { m_layer } );
361 }
362
363 virtual void SetLayerSet( const LSET& aLayers )
364 {
365 if( aLayers.count() == 1 )
366 {
367 SetLayer( aLayers.Seq()[0] );
368 return;
369 }
370
372
373 // Derived classes which support multiple layers must implement this
374 }
375
376 bool IsSideSpecific() const;
377
383 virtual void SetLayer( PCB_LAYER_ID aLayer )
384 {
385 m_layer = aLayer;
386 }
387
395 virtual BOARD_ITEM* Duplicate( bool addToParentGroup, BOARD_COMMIT* aCommit = nullptr ) const;
396
407 void SwapItemData( BOARD_ITEM* aImage );
408
418 virtual bool IsOnLayer( PCB_LAYER_ID aLayer ) const
419 {
420 return m_layer == aLayer;
421 }
422
423 virtual bool IsKnockout() const { return m_isKnockout; }
424 virtual void SetIsKnockout( bool aKnockout ) { m_isKnockout = aKnockout; }
425
426 bool IsLocked() const override;
427 void SetLocked( bool aLocked ) override { m_isLocked = aLocked; }
428
429 bool IsIndexedInBoard() const { return m_owningIndex != nullptr; }
430
431 int GetMaxError() const;
432
433 virtual void StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings, bool aCheckSide ) { }
434
438 void DeleteStructure();
439
445 virtual void Move( const VECTOR2I& aMoveVector )
446 {
447 wxFAIL_MSG( wxT( "virtual BOARD_ITEM::Move called for " ) + GetClass() );
448 }
449
456 virtual void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle );
457
469 virtual void OnFootprintRescaled( double aRatioX, double aRatioY, double aLinearFactor, const VECTOR2I& aAnchor,
470 const EDA_ANGLE& aParentRotate )
471 {}
472
477 virtual void OnFootprintTransformed() {}
478
485 virtual void Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection );
486
493 virtual void Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection );
494
498 virtual void Normalize() {}
499
505 virtual void NormalizeForCompare() { Normalize(); }
506
510 virtual const BOARD* GetBoard() const;
511 virtual BOARD* GetBoard();
512
517 wxString GetParentAsString() const;
518
524 wxString GetLayerName() const;
525
529 wxString GetLayerName( PCB_LAYER_ID aLayer ) const;
530
531 virtual std::vector<int> ViewGetLayers() const override;
532
544 virtual void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
545 int aClearance, int aError, ERROR_LOC aErrorLoc,
546 bool ignoreLineWidth = false ) const;
547
561 int aClearance, int aError, ERROR_LOC aErrorLoc,
562 KIGFX::RENDER_SETTINGS* aRenderSettings = nullptr ) const
563 {
564 TransformShapeToPolygon( aBuffer, aLayer, aClearance, aError, aErrorLoc );
565 }
566
573 virtual double GetCoverageArea( int aTextMargin ) const;
574
575 const std::vector<wxString>* GetEmbeddedFonts() override;
576
580 virtual wxString LayerMaskDescribe() const;
581
582 enum COMPARE_FLAGS : int
583 {
584 DRC = 0x01,
586 };
587
588 struct ptr_cmp
589 {
590 bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
591 };
592
593protected:
594 virtual void swapData( BOARD_ITEM* aImage );
595
597 static double polygonArea( SHAPE_POLY_SET& aPolySet );
598
599protected:
603
608 mutable BOARD_ITEM_INDEX* m_owningIndex = nullptr;
609
610 friend class BOARD_ITEM_INDEX;
611};
612
614
621{
622public:
624 BOARD_ITEM( nullptr, NOT_USED )
625 {}
626
627 wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override
628 {
629 return _( "(Deleted Item)" );
630 }
631
632 wxString GetClass() const override
633 {
634 return wxT( "DELETED_BOARD_ITEM" );
635 }
636
637 // pure virtuals:
638 void SetPosition( const VECTOR2I& ) override {}
639 VECTOR2I GetPosition() const override { return VECTOR2I( 0, 0 ); }
640
642 {
643 static DELETED_BOARD_ITEM* item = nullptr;
644
645 if( !item )
646 item = new DELETED_BOARD_ITEM();
647
648 return item;
649 }
650
651 double Similarity( const BOARD_ITEM& aItem ) const override
652 {
653 return ( this == &aItem ) ? 1.0 : 0.0;
654 }
655
656 bool operator==( const BOARD_ITEM& aBoardItem ) const override
657 {
658 return ( this == &aBoardItem );
659 }
660
661 bool operator==( const DELETED_BOARD_ITEM& aOther ) const
662 {
663 return ( this == &aOther );
664 }
665
666#if defined(DEBUG)
667 void Show( int , std::ostream& ) const override {}
668#endif
669};
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
ZONE_LAYER_OVERRIDE
Conditionally flashed vias and pads that interact with zones of different priority can be very squirr...
Definition board_item.h:73
@ ZLO_NONE
Definition board_item.h:74
@ ZLO_FORCE_NO_ZONE_CONNECTION
Definition board_item.h:76
@ ZLO_FORCE_FLASHED
Definition board_item.h:75
Container for design settings for a BOARD object.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
Bi-directional index mapping a board's items keyed by identity (KIID).
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:85
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:87
virtual void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Mirror this object relative to a given horizontal axis the layer is not changed.
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void ResetUuidDirect()
Definition board_item.h:278
int GetY() const
Definition board_item.h:140
bool IsGroupableType() const
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
virtual void NormalizeForCompare()
Perform any normalization required to compare 2 graphics, especially if the can be rotated and/or fli...
Definition board_item.h:505
virtual void OnFootprintTransformed()
Hook for items inside a footprint to refresh after the FP transform changes (translate,...
Definition board_item.h:477
void DeleteStructure()
Delete this object after removing from its parent if it has one.
const std::vector< wxString > * GetEmbeddedFonts() override
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
void SetLocked(bool aLocked) override
Definition board_item.h:427
virtual STROKE_PARAMS GetStroke() const
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition board_item.h:173
bool m_isKnockout
Definition board_item.h:601
PCB_LAYER_ID GetFlippedLayer(PCB_LAYER_ID aLayer) const
Return the layer paired with aLayer on the opposite side of the board.
virtual int BoardLayerCount() const
Return the total number of layers for the board that this item resides on.
virtual void SetStroke(const STROKE_PARAMS &aStroke)
void SetUuid(const KIID &aUuid)
static double polygonArea(SHAPE_POLY_SET &aPolySet)
Area of aPolySet with every contour closed first, holes subtracted.
PCB_LAYER_ID m_layer
Definition board_item.h:600
BOARD_ITEM(const BOARD_ITEM &aOther)
Definition board_item.h:95
virtual void SetLayerSet(const LSET &aLayers)
Definition board_item.h:363
bool m_isLocked
Definition board_item.h:602
bool IsIndexedInBoard() const
Definition board_item.h:429
wxString GetParentAsString() const
For "parent" property.
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const
virtual bool IsKnockout() const
Definition board_item.h:423
int GetX() const
Definition board_item.h:134
bool IsLocked() const override
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
void SetX(int aX)
Definition board_item.h:156
void SetY(int aY)
Definition board_item.h:162
virtual VECTOR2I GetCenter() const
This defaults to the center of the bounding box if not overridden.
Definition board_item.h:151
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition board_item.h:445
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition board_item.h:418
virtual void SetIsKnockout(bool aKnockout)
Definition board_item.h:424
virtual double GetCoverageArea(int aTextMargin) const
Return the board area this item covers, used to rank candidates under the cursor so a click on a smal...
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:383
BOARD_ITEM & operator=(BOARD_ITEM &&aOther)
Definition board_item.h:123
virtual std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
VECTOR2I GetFPRelativePosition() const
virtual LSET BoardLayerSet() const
Return the LSET for the board that this item resides on.
BOARD_ITEM(BOARD_ITEM &&aOther)
Definition board_item.h:118
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:355
virtual bool IsTented(PCB_LAYER_ID aLayer) const
Checks if the given object is tented (its copper shape is covered by solder mask) on a given side of ...
Definition board_item.h:225
virtual bool IsLayerAgnostic() const
Check if this item's layer set must not be confined to a board's enabled layers.
Definition board_item.h:308
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const
Convert the item shape to a polyset.
Definition board_item.h:560
virtual void swapData(BOARD_ITEM *aImage)
const KIFONT::METRICS & GetFontMetrics() const
~BOARD_ITEM() override
@ INSTANCE_TO_INSTANCE
Definition board_item.h:585
friend class BOARD_ITEM_INDEX
Definition board_item.h:610
void SetFPRelativePosition(const VECTOR2I &aPos)
virtual wxString LayerMaskDescribe() const
Return a string (to be shown to the user) describing a layer mask.
static VECTOR2I ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
Definition board_item.h:233
virtual bool FitsEnabledLayers(const LSET &aEnabledLayers, int aCopperLayerCount) const
Check if a board offering aEnabledLayers can hold this item.
virtual void CopyFrom(const BOARD_ITEM *aOther)
virtual bool operator==(const BOARD_ITEM &aItem) const =0
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
Definition board_item.h:265
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
Definition board_item.h:104
void ResetUuid()
Definition board_item.h:281
BOARD_ITEM_INDEX * m_owningIndex
Board index that indexes this item, or nullptr.
Definition board_item.h:608
virtual bool HasDrilledHole() const
Definition board_item.h:213
BOARD_ITEM_CONTAINER * GetParent() const
Definition board_item.h:267
bool IsSideSpecific() const
virtual int BoardCopperLayerCount() const
Return the total number of copper layers for the board that this item resides on.
virtual bool IsOnCopperLayer() const
Definition board_item.h:190
virtual bool HasLineStroke() const
Check if this item has line stoke properties.
Definition board_item.h:298
virtual void Normalize()
Perform any normalization required after a user rotate and/or flip.
Definition board_item.h:498
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
virtual void OnFootprintRescaled(double aRatioX, double aRatioY, double aLinearFactor, const VECTOR2I &aAnchor, const EDA_ANGLE &aParentRotate)
Apply a parent footprint scale to this item.
Definition board_item.h:469
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
int GetMaxError() const
virtual double Similarity(const BOARD_ITEM &aItem) const =0
Return a measure of how likely the other object is to represent the same object.
virtual void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide)
Definition board_item.h:433
virtual void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Flip this object, i.e.
virtual bool HasHole() const
Definition board_item.h:208
virtual void RemapKIIDs(const std::map< KIID, KIID > &aIdMap)
Remap KIIDs this item stores to reference other items (e.g.
Definition board_item.h:288
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
constexpr const Vec GetCenter() const
Definition box2.h:227
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition board_item.h:627
static DELETED_BOARD_ITEM * GetInstance()
Definition board_item.h:641
wxString GetClass() const override
Return the class name.
Definition board_item.h:632
double Similarity(const BOARD_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
Definition board_item.h:651
VECTOR2I GetPosition() const override
Definition board_item.h:639
void SetPosition(const VECTOR2I &) override
Definition board_item.h:638
bool operator==(const BOARD_ITEM &aBoardItem) const override
Definition board_item.h:656
bool operator==(const DELETED_BOARD_ITEM &aOther) const
Definition board_item.h:661
virtual VECTOR2I GetPosition() const
Definition eda_item.h:348
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition eda_item.cpp:488
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:349
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:270
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:609
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
virtual wxString GetClass() const =0
Return the class name.
Definition kiid.h:46
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:309
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:51
Represent a set of closed polygons.
An abstract shape on 2D plane.
Definition shape.h:124
Simple container to manage line stroke parameters.
@ NULL_CONSTRAINT
#define _(s)
RECURSE_MODE
Definition eda_item.h:50
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:180
@ DEFAULT
Flashing follows connectivity.
Definition layer_ids.h:181
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:741
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ UNDEFINED_LAYER
Definition layer_ids.h:57
@ F_Cu
Definition layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:92
FLIP_DIRECTION
Definition mirror.h:23
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
#define DECLARE_ENUM_TO_WXANY(type)
Definition property.h:860
bool operator()(const BOARD_ITEM *a, const BOARD_ITEM *b) const
constexpr bool IsSingleLayerType(const KICAD_T aType)
Definition typeinfo.h:516
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
@ NOT_USED
the 3d code uses this value
Definition typeinfo.h:71
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708