glcanvas.h File Reference

Go to the documentation of this file. Source: include/ffw/graphics/glcanvas.h

/* This file is part of FineFramework project */
#ifndef FFW_GRAPHICS_CANVAS
#define FFW_GRAPHICS_CANVAS

#include <string>
#include <memory>
#include "config.h"
#include "color.h"
#include "mat4.h"
#include "mat3.h"
#include "vec2.h"
#include "gltexture2d.h"

namespace ffw {
    class FFW_API GLCanvas {
    public:
        enum class API {
            AUTO = 0,
            GL2,
            GL3,
            GLES2,
            GLES3
        };

        struct Settings {
            API api = API::AUTO;
            bool antialias = true;
            bool strokes = true;
            // Device pixel ration allows to control the rendering on Hi - DPI devices.
            float devicePixelRatio = 1.0f;
        };

        enum class Mode {
            FILL,
            STROKE,
            FILL_AND_STROKE,
        };

        enum class Winding {
            // Winding for solid shapes
            CCW,
            // Winding for holes
            CW,
        };

        enum class Solidity {
            SOLID,
            HOLE,
        };

        enum class LineCap {
            BUTT,
            ROUND,
            SQUARE
        };

        enum class LineJoin {
            ROUND,
            BEVEL,
            MITER
        };

        struct TextAlign {
            typedef uint32_t Flag;
            // Default, align text horizontally to left.
            static const Flag LEFT = 1 << 0;
            // Align text horizontally to center.
            static const Flag CENTER = 1 << 1;
            // Align text horizontally to right.
            static const Flag RIGHT = 1 << 2;
            // Align text vertically to top.
            static const Flag TOP = 1 << 3;
            // Align text vertically to middle.
            static const Flag MIDDLE = 1 << 4;
            // Align text vertically to bottom.
            static const Flag BOTTOM = 1 << 5;
            // Default, align text vertically to baseline.
            static const Flag BASELINE = 1 << 6;
        };

        enum class BlendFactor {
            ZERO,
            ONE,
            SRC_COLOR,
            ONE_MINUS_SRC_COLOR,
            DST_COLOR,
            ONE_MINUS_DST_COLOR,
            SRC_ALPHA,
            ONE_MINUS_SRC_ALPHA,
            DST_ALPHA,
            ONE_MINUS_DST_ALPHA,
            SRC_ALPHA_SATURATE,
        };

        enum class CompositeOperation {
            SOURCE_OVER,
            SOURCE_IN,
            SOURCE_OUT,
            ATOP,
            DESTINATION_OVER,
            DESTINATION_IN,
            DESTINATION_OUT,
            DESTINATION_ATOP,
            LIGHTER,
            COPY,
            XOR,
        };

        class FFW_API Image {
        public:
            Image() = default;
            Image(const GLCanvas* canvas, int ref);
            Image(const Image& other) = delete;
            Image(Image&& other) NOEXCEPT;
            Image& operator = (const Image& other) = delete;
            Image& operator = (Image&& other) NOEXCEPT;
            void swap(Image& other) NOEXCEPT;
            virtual ~Image();

            inline bool isCreated() const {
                return ref >= 0;
            }

            const GLCanvas* canvas = nullptr;
            int ref = -1;
        };

        class FFW_API Font {
        public:
            Font() = default;
            Font(const GLCanvas* canvas, int ref);
            Font(const Font& other) = delete;
            Font(Font&& other) NOEXCEPT;
            Font& operator = (const Font& other) = delete;
            Font& operator = (Font&& other) NOEXCEPT;
            void swap(Font& other) NOEXCEPT;
            virtual ~Font();

            inline bool isCreated() const {
                return ref >= 0;
            }

            const GLCanvas* canvas = nullptr;
            int ref = -1;
        };

        struct FFW_API Paint {
#if defined(_MSC_VER) && _MSC_VER == 1800
            Paint() {
                xform[0] = xform[1] = xform[2] = xform[3] = xform[4] = xform[5] = 0;
                extent[0] = extent[1] = 0;
            }
            float xform[6];
            float extent[2];
#else
            float xform[6] = { 0 };
            float extent[2] = { 0 };
#endif
            float radius = 0;
            float feather = 0;
            Color innerColor;
            Color outerColor;
            int image = 0;
        };

        struct GlyphPosition {
            const char* str;    // Position of the glyph in the input string.
            float x;            // The x-coordinate of the logical glyph position.
            float minx, maxx;   // The bounds of the glyph shape.
        };

        struct TextRow {
            const char* start;  // Pointer to the input text where the row starts.
            const char* end;    // Pointer to the input text where the row ends (one past the last character).
            const char* next;   // Pointer to the beginning of the next row.
            float width;        // Logical width of the row.
            float minx, maxx;   // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending.
        };

        struct ImageFlags {
            typedef uint32_t Flag;
            const static Flag IMAGE_GENERATE_MIPMAPS = 1 << 0;
            const static Flag IMAGE_REPEATX = 1 << 1;
            const static Flag IMAGE_REPEATY = 1 << 2;
            const static Flag IMAGE_FLIPY = 1 << 3;
            const static Flag IMAGE_PREMULTIPLIED = 1 << 4;
            const static Flag IMAGE_NEAREST = 1 << 5;
        };

        GLCanvas();
        GLCanvas(const Settings& settings);
        GLCanvas(const GLCanvas& other) = delete;
        GLCanvas(GLCanvas&& other) NOEXCEPT;
        GLCanvas& operator = (const GLCanvas& other) = delete;
        GLCanvas& operator = (GLCanvas&& other) NOEXCEPT;
        void swap(GLCanvas& other) NOEXCEPT;
        virtual ~GLCanvas();
        void destroy();

        void beginFrame(const Vec2f& size) const;
        void endFrame() const;
        void cancelFrame() const;
        void globalCompositeOperation(CompositeOperation op) const;
        void globalCompositeBlendFunc(BlendFactor sfactor, BlendFactor dfactor) const;
        void globalCompositeBlendFuncSeparate(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha) const;
        void save() const;
        void restore() const;
        void reset() const;
        void shapeAntiAlias(bool enabled) const;
        void strokeColor(const Color& color) const;
        void strokePaint(const Paint& paint) const;
        void fillColor(const Color& color) const;
        void fillPaint(const Paint& paint) const;
        void miterLimit(float limit) const;
        void strokeWidth(float size) const;
        void lineCap(LineCap cap) const;
        void lineJoin(LineJoin join) const;
        void globalAlpha(float alpha) const;
        void resetTransform() const;
        void transform(const Mat3x3f& mat) const;
        void translate(const Vec2f& pos) const;
        void rotate(float angle) const;
        void rotateRad(float angle) const;
        void skewX(float angle) const;
        void skewXRad(float angle) const;
        void skewY(float angle) const;
        void skewYRad(float angle) const;
        void scale(float x, float y) const;
        Mat3x3f getCurrentTransform() const;
        void setTransform(const Mat3x3f& mat) const;
        Image createImage(const GLTexture2D& texture, ImageFlags::Flag imageFlags = 0) const;
        Paint linearGradient(const ffw::Vec2f& start, const ffw::Vec2f& end,
            const Color& icol, const Color& ocol) const;
        Paint boxGradient(const ffw::Vec2f& pos, const ffw::Vec2f& size,
            float r, float f, const Color& icol, const Color& ocol) const;
        Paint radialGradient(const ffw::Vec2f& center, float inr, float outr,
            const Color& icol, const Color& ocol) const;
        Paint imagePattern(const Vec2f& start, const Vec2f& end,
            float angle, const Image& image, float alpha) const;
        void scissor(const Vec2f& pos, const Vec2f& size) const;
        void intersectScissor(const Vec2f& pos, const Vec2f& size) const;
        void resetScissor() const;
        void beginPath() const;
        void moveTo(const Vec2f& pos) const;
        void lineTo(const Vec2f& pos) const;
        void bezierTo(const Vec2f& c1, const Vec2f& c2, const Vec2f& pos) const;
        void quadTo(const Vec2f& c, const Vec2f& pos) const;
        void arcTo(const Vec2f& x1, const Vec2f& x2, float angle) const;
        void arcToRad(const Vec2f& x1, const Vec2f& x2, float angle) const;
        void closePath() const;
        void pathWinding(Winding dir) const;
        void pathWinding(Solidity dir) const;
        void arc(const Vec2f& center, float r, float a0, float a1, Winding dir) const;
        void arcRad(const Vec2f& center, float r, float a0, float a1, Winding dir) const;
        void rect(const Vec2f& pos, const Vec2f& size) const;
        void roundedRect(const Vec2f& pos, const Vec2f& size, float r) const;
        void roundedRect(const Vec2f& pos, const Vec2f& size, float radTopLeft,
            float radTopRight, float radBottomRight, float radBottomLeft) const;
        void ellipse(const Vec2f& pos, float rx, float ry) const;
        void circle(const Vec2f& pos, float r) const;
        void fill() const;
        void stroke() const;
        Font createFont(const std::string& filename) const;
        Font createFontMem(unsigned char* data, size_t length) const;
        void addFallbackFontId(Font& baseFont, Font& fallbackFont) const;
        void fontSize(float size) const;
        void fontBlur(float blur) const;
        void textLetterSpacing(float spacing) const;
        void textLineHeight(float lineHeight) const;
        void textAlign(TextAlign::Flag align) const;
        void fontFace(const Font& font) const;
        void text(const Vec2f& pos, const char* string, const char* end) const;
        void text(const Vec2f& pos, const std::string& str) const;
        void textBox(const Vec2f& pos, float breakRowWidth, const char* string,
            const char* end) const;
        void textBox(const Vec2f& pos, float breakRowWidth, const std::string& str) const;
        float textBounds(const Vec2f& pos, const char* string,
            const char* end, Vec4f& bounds) const;
        float textBounds(const Vec2f& pos, const std::string& str, Vec4f& bounds) const;
        Vec4f textBoxBounds(const Vec2f& pos, float breakRowWidth,
            const char* string, const char* end) const;
        Vec4f textBoxBounds(const Vec2f& pos, float breakRowWidth, const std::string& str) const ;
        void textMetrics(float& ascender, float& descender, float& lineh) const;
        int textBreakLines(const char* string, const char* end, float width, TextRow* rows, size_t numrows) const;
        int textBreakLines(const std::string& string, float width, TextRow* rows, size_t numrows) const;
        int textGlyphPositions(const Vec2f& pos, const std::string& str, GlyphPosition* positions, size_t numpositions) const;
        int textGlyphPositions(const Vec2f& pos, const char* string, const char* end, GlyphPosition* positions, size_t numpositions) const;
        friend Font;
        friend Image;
    private:
        void removeFont(Font& font) const;
        void removeImage(Image& image) const;

        class Impl;
        std::unique_ptr<Impl> pimpl;
    };
}

inline void swap(ffw::GLCanvas& first, ffw::GLCanvas& second) NOEXCEPT {
    first.swap(second);
}

inline void swap(ffw::GLCanvas::Font& first, ffw::GLCanvas::Font& second) NOEXCEPT {
    first.swap(second);
}

inline void swap(ffw::GLCanvas::Image& first, ffw::GLCanvas::Image& second) NOEXCEPT {
    first.swap(second);
}

#endif