Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 - 2020 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #include <QColor> #include "main.h" namespace ldraw { struct Color; struct ColorDefinition; class ColorTable; Color directColor(const QColor& color); bool isDirectColor(Color color); QColor directColorFace(Color color); QColor colorFace(Color color, const ColorTable& colorTable); QColor colorEdge(Color color, const ColorTable& colorTable); QString colorDisplayName(Color color, const ColorTable& colorTable); } /** * @brief Represents an LDraw color index (e.g 16, 24, ...) * * @details * This is essentially just an integer. It is its own structure for the sake * of type correctness. Commonly used color values are 16 for the main color * and 24 for the edge color. * * Use @c ldraw::ColorTable to obtain rgb values for color indices. * * Direct colors are colors whose index is at least 0x2000000. These colors * encode the rgb values directly in the index. The color table code also * handles these cases. * * Note that it only makes sense to construct a color index from an integer * value if the integer comes from an external source (e.g. user or * LDConfig.ldr). Since this structure only contains an integer, it should be * passed by value to functions instead of l-value reference. */ struct ldraw::Color { qint32 index = 0; constexpr auto operator<=>(const Color&) const = default; }; Q_DECLARE_METATYPE(ldraw::Color) QDataStream& operator<<(QDataStream&, ldraw::Color); QDataStream& operator>>(QDataStream&, ldraw::Color&); namespace ldraw { static constexpr Color MAIN_COLOR {16}; static constexpr Color EDGE_COLOR {24}; } /** * @brief Contains the information about a specific color */ struct ldraw::ColorDefinition { /** * @brief The face color. This is the color used for most objects. * This is also used for the polygons of a subfile reference. */ QColor faceColor; /** * @brief The edge color, used for the edge lines of a subfile reference. * Note that edges using a color actually use the face color. LDraw standards * require edges to use color 24, however. */ QColor edgeColor; /** * @brief Name of the color */ QString name; /** * @brief A version of the name that can be shown to the user. */ QString displayName; }; /** * @brief Reads LDConfig.ldr and contains color table information for lookup purposes. */ class ldraw::ColorTable { public: void clear(); Result load(QIODevice& device, QTextStream& errors); const ColorDefinition& operator[](Color index) const; static const ColorDefinition unknownColor; auto begin() const { return this->definitions.begin(); } auto end() const { return this->definitions.end(); } int size() const; private: void loadColorFromString(const QString& string); std::map<qint32, ColorDefinition> definitions; }; double luma(const QColor& color);