From c1702d3c54f36dcb59f6ab7ba01ff78355f7158a Mon Sep 17 00:00:00 2001 From: Andrey Kalmykov Date: Thu, 20 Jun 2024 22:02:11 +0200 Subject: [PATCH 1/3] Generalize Text::angle() logic May fix #765 --- qucs/element.cpp | 49 ++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/qucs/element.cpp b/qucs/element.cpp index 46ed43920..834bb2986 100644 --- a/qucs/element.cpp +++ b/qucs/element.cpp @@ -70,28 +70,37 @@ void Text::draw(QPainter *painter, QRectF* br) const { } double Text::angle() const { - // Historically Text uses mSin and mCos values to store - // its rotation factor. + // Historically Text uses mSin and mCos values to describe + // at what angle the text is rotated. // - // The actual rotation was implemented as a clever - // tranformation for a painter, like: - // QTransform(mCos, -mSin, mSin, mCos, … + // It employed some clever technique to draw the text rotated + // by applying "skew" transformations to QPainter and using mCos + // and mSin as skew factors, but later the whole drawing routine + // was refactored and it switched to using QPainter::rotate() and + // degrees to describe the rotation angle. // - // There were only four combinations of these values - // and here we convert them to their human-readable - // equivalents - if (mCos == 0.0) { - if (mSin == 1.0) { - return 270; - } - return 90; - } - - if (mCos == -1.0 && mSin == 0.0) { - return 180; - } - - return 0; + // Many other parts of the codebase still depend on mCos and mSin, + // for example rotating and mirroring of a component and more than + // 200 component constructors. It is a piece of work to get rid + // of mCos and mSin completely, so they're kept as is and their + // "degrees" equivalent is calculated when the text needs to be drawn. + + const double radians = std::acos(mCos); + // convert from radians to degrees and normalize + const double degrees = std::remainder( + (radians * 180.0) / 3.14159265 /* Pi */, 360.0 /* Full circle */); + + // Above we've found the angle in degrees from a cosinus value. + // A single cosinus value corresponds to two angles. If sinus is positive + // the angle is in upper half of a circle. If sinus in negative, then + // in lower half. + // + // At the same time QPainter::rotate() rotates *clockwise*, so if you + // want a text to have rotation angle of 45° (towards up-right direction), + // then the -45° has to be passed to QPainter::rotate(). + // + // QPainter::rotate() is called in Text::draw + return mSin < 0 ? degrees : -degrees; } From a4c9dce46650e07b09bf7aeb7d5820a1c5e017cc Mon Sep 17 00:00:00 2001 From: Andrey Kalmykov Date: Thu, 20 Jun 2024 23:06:11 +0200 Subject: [PATCH 2/3] fixup! Generalize Text::angle() logic --- qucs/element.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qucs/element.cpp b/qucs/element.cpp index 834bb2986..bb683d99c 100644 --- a/qucs/element.cpp +++ b/qucs/element.cpp @@ -18,6 +18,7 @@ #include "element.h" #include "misc.h" +#include #include namespace qucs { From e0363c27441f37b6db6184d37e8e4f93174f6ac0 Mon Sep 17 00:00:00 2001 From: Andrey Kalmykov Date: Fri, 21 Jun 2024 08:25:26 +0200 Subject: [PATCH 3/3] fixup! Generalize Text::angle() logic --- qucs/element.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/qucs/element.cpp b/qucs/element.cpp index bb683d99c..652e3c3f7 100644 --- a/qucs/element.cpp +++ b/qucs/element.cpp @@ -86,22 +86,15 @@ double Text::angle() const { // of mCos and mSin completely, so they're kept as is and their // "degrees" equivalent is calculated when the text needs to be drawn. - const double radians = std::acos(mCos); - // convert from radians to degrees and normalize - const double degrees = std::remainder( - (radians * 180.0) / 3.14159265 /* Pi */, 360.0 /* Full circle */); - - // Above we've found the angle in degrees from a cosinus value. - // A single cosinus value corresponds to two angles. If sinus is positive - // the angle is in upper half of a circle. If sinus in negative, then - // in lower half. - // - // At the same time QPainter::rotate() rotates *clockwise*, so if you - // want a text to have rotation angle of 45° (towards up-right direction), + const double radians = std::atan2(mSin, mCos); + const double degrees = (radians * 180.0) / 3.14159265 /* Pi */; + + // QPainter::rotate() rotates *clockwise*, so if you want a text + // to have rotation angle of 45° (towards up-right direction), // then the -45° has to be passed to QPainter::rotate(). // // QPainter::rotate() is called in Text::draw - return mSin < 0 ? degrees : -degrees; + return -degrees; }