This reverts commit 68b1abf77f.
The warnings are valuable and shouldn't be cast aside.
As of 8f509f1, we special case macOS and don't set -fno-sanitize-recover
to allow CI to succeed.
In the future, this could be made stricter again by only suppressing
known bugs, which ideally should also be fixed or reported upstream.
Previously sanitizer flags were set unconditionally for
all code, including that of external libraries.
Set them only for targets in src/, tests/ and exposed/.
Unfortunately, the linker equivalent to add_compile_options,
add_link_options, is only available for CMake version >= 3.13.
So add the sanitizer flags manually to each target's linker options.
This commit performs three related cleanups:
* The slvs library no longer uses explicit platform initialization
(which drags in the side effects of InitPlatform that are not
desirable in a library). Instead, it just ensures that it has
the temporary heap, which is what it was callingInitPlatform for.
* InitPlatform is simplified and moved to platform.cpp, next to
other path related functions.
* InitPlatform is renamed to InitCli and is called from InitGui
implementations. GUI toolkits sometimes have options they use
internally (that's the case for for GTK and Cocoa at least),
and we shouldn't try to parse those as a file to open.
When drawing the graphics window, we flush it twice: once to draw
the geometry, and another time to draw the UI overlay (toolbar,
selection marquee, and FPS counter). Calling glFinish() each time
is (on most platforms) just pointlessly slow, but on macOS Catalina,
without offscreen rendering, it causes the toolbar to flicker.
Instead of calling glFinish() twice per frame in that case, call
glFlush() twice and then glFinish() once we really are done.
Also, mark not just curves, but also points and normals derived from
construction requests as construction.
Also, don't always mark arc center point as construction just to
exclude it from chord tolerance bounding box calculation; instead,
special-case it there.
Before, would guess incorrectly if the CMake source tree was specified
via a relative path (since then the path would not start with /).
Now, directly asks CMake if building on Windows or something else,
and sets a define.
This commit removes a large amount of code partially duplicated
between the text and the graphics windows, and opens the path to
having more than one model window on screen at any given time,
as well as simplifies platform work.
This commit also adds complete support for High-DPI device pixel
ratio. It adds support for font scale factor (a fractional factor
on top of integral device pixel ratio) on the platform side, but not
on the application side.
This commit also adds error checking to all Windows API calls
(within the abstracted code) and fixes a significant number of
misuses and non-future-proof uses of Windows API.
This commit also makes uses of Windows API idiomatic, e.g. using
the built-in vertical scroll bar, native tooltips, control
subclassing instead of hooks in the global dispatch loop, and so on.
It reinstates tooltip support and removes menu-related hacks.
This commit updates a *lot* of rather questionable path handling
logic to be robust. Specifically:
* All path operations go through Platform::Path.
* All ad-hoc path handling functions are removed, together with
PATH_SEP. This removes code that was in platform-independent
parts, but had platform-dependent behavior.
* Group::linkFileRel is removed; only an absolute path is stored
in Group::linkFile. However, only Group::linkFileRel is saved,
with the relative path calculated on the fly, from the filename
passed into SaveToFile. This eliminates dependence on global
state, and makes it unnecessary to have separare code paths
for saved and not yet saved files.
* In a departure from previous practice, functions with
platform-independent code but platform-dependent behavior
are all grouped under platform/. This makes it easy to grep
for functions with platform-dependent behavior.
* Similarly, new (GUI-independent) code for all platforms is added
in the same platform.cpp file, guarded with #ifs. It turns out
that implementations for different platforms had a lot of shared
code that tended to go out of sync.
It was broken because of three bugs:
* Uninitialized variables in RunCommand;
* Trying to use (OEM-encoded) main() argc/argv arguments instead
of GetCommandLineW();
* Trying to pass relative paths directly into ssfopen.
Before this commit, if constraints with newly introduced params were
loaded from a file that linked other files, the upgrade code would
attempt to look up a non-existent entity.
All of our executables need resources; e.g. the vector font is
a resource and it is necessary for generation. Before this commit,
the GUI executable loaded the resources in a nice way, and everything
else did it in a very ad-hoc, fragile way.
After this commit, all executables are placed in <build>/bin and
follow the same algorithm:
* On Windows, resources are compiled and linked into every
executable.
* On Linux, resources are copied into <build>/res (which is
tried first) and <prefix>/share/solvespace (which is tried
second).
* On macOS, resources are copied into <build>/res (which is
tried first) and <build>/bin/solvespace.app/Contents/Resources
(which is tried second).
In practice this means that we can add as many executables as we want
without duplicating lots of code. In addition, on macOS, we can
place supplementary executables into the bundle, and they can use
resources from the bundle transparently.
Before this commit, parallel constraints in 3d are fragile:
constraints that are geometrically fine can end up singular anyway
because VectorsParallel() pivots wrong but converges anyway.
After this commit, much like in cc07058, the constraints are written
in a different form: instead of trying to remove two degrees of
freedom out of three, all three are removed, and one added; namely,
the constraint introduces a free parameter, signed length ratio.
Before this commit, pt-on-line constraints are buggy. To reproduce,
extrude a circle, then add a datum point and constrain it to the
axis of the circle, then move it. The cylinder will collapse.
To quote Jonathan:
> On investigation, I (a) confirm that the problem is
> the unconstrained extrusion depth going to zero, and (b) retract
> my earlier statement blaming extrude and other similar non-entity
> parameter treatment for this problem; you can easily reproduce it
> with a point in 3d constrained to lie on any line whose length
> is free.
>
> PT_ON_LINE is written using VectorsParallel, for no obvious reason.
> Rewriting that constraint to work on two projected distances (using
> any two basis vectors perpendicular to the line) should fix that
> problem, since replacing the "point on line in 3d" constraint with
> two "point on line in 2d" constraints works. That still has
> the hairy ball problem of choosing the basis vectors, which you
> can't do with a continuous function; you'd need Vector::Normal()
> or equivalent.
>
> You could write three equations and make the constraint itself
> introduce one new parameter for t. I don't know how well that
> would work numerically, but it would avoid the hairy ball problem,
> perhaps elegant at the cost of speed.
Indeed, this commit implements the latter solution: it introduces
an additional free parameter. The point being coincident with
the start of the line corresponds to the parameter being zero, and
point being coincident with the end corresponds to one).
In effect, instead of constraining two of three degrees of freedom
(for which the equations do not exist because of the hairy ball
theorem), it constrains three and adds one more.
These points can be used for constraining the width of the text
(or to the width of the text).
The main parts of the commit are:
* TtfFont is restructured to be able to return the aspect ratio
for a given string.
* This aspect ratio is written to the savefile, such that even if
the font is missing, the sketch would still be solved correctly.
* The two additional points are constrained via perpendicularly
to the two main points (which form a v vector).
The compatibility features are as follows:
* When the font is missing in old files, 1:1 aspect ratio is used,
which works for the replacement symbol anyhow.
* When the two additional points are missing in old files, their
would-be positions are calculated and they are moved there,
avoiding 'jumping' of underconstrained sketches.
SolveSpace 2.0 used the height of 'A' (i.e. cap height) to determine
the reference height.
SolveSpace 2.1 completely broke that during transition to Freetype,
and used something more or less random, by using FT_Set_Char_Size
with units_per_EM.
SolveSpace 2.2 attempted to fix that, but also used something more
or less random, by using FT_Request_Size with "unit" values.
Turns out that Freetype actually doesn't have a concept of cap height
at all. It is possible to extract it from the TT_OS2 table that is
present in some TrueType fonts, but it is not present in Microsoft
fonts (the msttcorefonts ones), and for those Linux fonts in which
it is present it doesn't appear very reliable.
So instead, use the height of 'A' instead, like version 2.0 did.
This has the advantage that it is quite bulletproof, and also matches
exactly what the old files are measured against.
One downside is that fonts without an 'A' glyph would not render.
We can deal with that when it becomes a problem.