This means that an early return or an exception between
a manual Push/Pop (or an omission of the Pop) cannot
corrupt the layer stack.
It also means the GAL doesn't have to maintain its own
stack (with the in-scope GAL_SCOPED_ATTRS taking that role).
Reomve the Push/PopDepth functions, as they're only ever
used in pairs, and doing it manually needs more care.
Implement a simple RAII GAL attribute save/restore
class that handles putting the GAL back the way it was found.
This makes draw methods easier to write, as they don't need
to worry if a called method will upset the attribute context
(as long as the caller saves the context, or the callee does).
Obviously not a good idea to use in tight loops, but when text
is involved, this is negligible!
On reflection, the forward vector makes more sense, because
the value in the edit box is then the same as the vector the
user just drew with the ruler.
For segment, circle, beziers, these are the same in all editors and only
need access to the EDA_SHAPE nature, so we can remove the duplication
entirely.
For TABLECELLs, while the cells are polymorphic in that PCB and SCH
cells are both EDA_SHAPEs (via the TEXTBOXes), the parent TABLES
are not polymorphic, and thus the implementation can't be trivially
de-duplicated. Rather than do something with templates, just keep
it simple for now and maybe look at unifying tables later on.
SCH_IO_KICAD_SEXPR_PARSER::parseSheet() can create a dangling pointer when reading
a property if the font used by the property text is not the default font: the
initial SCH_FIELD item is a temporary item and leave a dangling pointer in
m_fontTextMap liast when deleted. This pointer is now removed from list.
The first commit fixed for a "old" footprint (from version 7 and older) a
use after free pointer creating a crash. but this first commit lost the font
for texts related to this pointer.
This is now fixed.
These implementaitons were always very verbose and repetitive.
This doesn't try to be too clever in slimming them down just
yet, in favour of just transplanting first.
This adds the concept of editing _other_ items to the one
that informs the POINT_EDIT_BEHAVIOR - in this case connected
lines. This is one of the motivations behind this system,
as it will allow to bring similar logic to Pcbnew.
Saving the best for last - the one that wound me up enough to
start this process - textboxes, which sometimes, but not always
behave like rectangles.
Rather than some exciting multiple inheritance of
RECTANGLE_POINT_EDIT_BEHAVIOR and a hypothetical rotated
rectangle behavior, delegate the rectangular behavior to
static helpers in the rectangle one.
They still can't be edited when rotated, but at least now there
is some hope that it's tractable!
Especially the aligned dims are fiddly, but all the
dimensions need the array size to be carefully kept
controlled, which is now part of the invariant of
each behavior.
This also changes the interface on the GENERATOR classes
to no longer take a shared_ptr - these methods are synchronous
and don't store (shared) ownership of the EDIT_POINTs.
This is a pretty straightforward one
(though there was a latent bug here because both CIRCLE
and ARC used CIRC_CENTER for the constrainer. If an ARC
and CIRCLE center were not the same index (and nothing says they
have to be) that could be wrong or crash.
This is a good example of an edit behaviour that had a lot
of code in PCB_POINT_EDITOR that was only used for a single
item type. Many of these (now static) functions will probably
find use in other places arcs crop up like filleted shapes
and also in eeschema.
But for now, keep it simpler and keep them near where they
are used.
This introduces the POINT_EDITOR_BEHAVIOR class, which
allows a "behavior" to be defined, which covers the creation
of edit points, updating the points on edit, and pushing the
edited points back into the object.
This keeps the logic for a single item "type" (e.g. a SEGMENT
or TEXTBOX, etc) in one place, rather than fragmneted throughout
the POINT_EDITOR class, where the invariants like point count
are difficult to keep track of as the TOOL progresses.
For now, it's implemented as an optional class, just for SEGMENT
and other tpyes work as before. Adding new types is then a
"pin-compatible" drop-in process.