1532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#ifndef SkDeviceProperties_DEFINED
2532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#define SkDeviceProperties_DEFINED
3532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
41a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import.
51a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com#include "SkFontLCDConfig.h"
6532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
7532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comstruct SkDeviceProperties {
8532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    struct Geometry {
9532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        /** The orientation of the pixel specifies the interpretation of the
10532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *  layout. If the orientation is horizontal, the layout is interpreted as
11532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *  left to right. It the orientation is vertical, the layout is
12532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *  interpreted top to bottom (rotated 90deg cw from horizontal).
13532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        */
14532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        enum Orientation {
15532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kUnknown_Orientation      = 0x0,
16532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kKnown_Orientation        = 0x2,
17532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
18532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kHorizontal_Orientation   = 0x2,  //!< this is the default
19532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kVertical_Orientation     = 0x3,
20532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
21532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kOrientationMask          = 0x3,
22532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        };
23532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
24532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        /** The layout of the pixel specifies its subpixel geometry.
25532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *
26532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *  kUnknown_Layout means that the subpixel elements are not spatially
27532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        *  separated in any known or usable fashion.
28532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        */
29532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        enum Layout {
30532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kUnknown_Layout   = 0x0,
31532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kKnown_Layout     = 0x8,
32532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
33532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kRGB_Layout       = 0x8,  //!< this is the default
34532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kBGR_Layout       = 0xC,
35532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
36532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            kLayoutMask       = 0xC,
37532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        };
38532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
39532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        Orientation getOrientation() {
40c5fd46171841711973b9433c726ff8608335940ccommit-bot@chromium.org            return static_cast<Orientation>(fGeometry & kOrientationMask);
41532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
42532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        Layout getLayout() {
43c5fd46171841711973b9433c726ff8608335940ccommit-bot@chromium.org            return static_cast<Layout>(fGeometry & kLayoutMask);
44532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
45532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
46532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        bool isOrientationKnown() {
47ba3284e7bbb830749206414890f8152e421969f2bungeman@google.com            return SkToBool(fGeometry & kKnown_Orientation);
48532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
49532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        bool isLayoutKnown() {
50ba3284e7bbb830749206414890f8152e421969f2bungeman@google.com            return SkToBool(fGeometry & kKnown_Layout);
51532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
52532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
53532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    private:
541a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com        //TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants.
551a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com        static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) {
56532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            switch (orientation) {
571a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation;
581a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation;
59532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            default: return kUnknown_Orientation;
60532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            }
61532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
621a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com        static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) {
63532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            switch (order) {
641a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout;
651a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout;
66532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            default: return kUnknown_Layout;
67532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            }
68532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
69532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    public:
70532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        static Geometry MakeDefault() {
711a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation
721a64a54b278c07b33a3b5e8883b1fdf3173c840ereed@google.com            Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout
7323c2939a4f59e8c57a88122fa430095a84797c38bungeman@google.com            Geometry ret = { SkToU8(orientation | layout) };
74532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            return ret;
75532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
76532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
77532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        static Geometry Make(Orientation orientation, Layout layout) {
7823c2939a4f59e8c57a88122fa430095a84797c38bungeman@google.com            Geometry ret = { SkToU8(orientation | layout) };
79532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com            return ret;
80532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        }
81532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
82532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        uint8_t fGeometry;
83532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    };
84532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
85532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    static SkDeviceProperties MakeDefault() {
86532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT };
87532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        return ret;
88532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    }
89532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
90532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) {
91532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        SkDeviceProperties ret = { geometry, gamma };
92532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        return ret;
93532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    }
94532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
95532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    /** Each pixel of an image will have some number of channels.
96532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com     *  Can the layout of those channels be exploited? */
97532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    Geometry fGeometry;
98532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
99532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    /** Represents the color space of the image. This is a woefully inadequate beginning. */
100532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    SkScalar fGamma;
101532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com};
102532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
103532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#endif
104