1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "TextureManager.h"
12 #include "utils/Color.h"
13 #include "utils/Geometry.h"
14 #include "guiinfo/GUIInfoColor.h"
15 
16 // image alignment for <aspect>keep</aspect>, <aspect>scale</aspect> or <aspect>center</aspect>
17 #define ASPECT_ALIGN_CENTER  0
18 #define ASPECT_ALIGN_LEFT    1
19 #define ASPECT_ALIGN_RIGHT   2
20 #define ASPECT_ALIGNY_CENTER 0
21 #define ASPECT_ALIGNY_TOP    4
22 #define ASPECT_ALIGNY_BOTTOM 8
23 #define ASPECT_ALIGN_MASK    3
24 #define ASPECT_ALIGNY_MASK  ~3
25 
26 class CAspectRatio
27 {
28 public:
29   enum ASPECT_RATIO { AR_STRETCH = 0, AR_SCALE, AR_KEEP, AR_CENTER };
30   CAspectRatio(ASPECT_RATIO aspect = AR_STRETCH)
31   {
32     ratio = aspect;
33     align = ASPECT_ALIGN_CENTER | ASPECT_ALIGNY_CENTER;
34     scaleDiffuse = true;
35   };
36   bool operator!=(const CAspectRatio &right) const
37   {
38     if (ratio != right.ratio) return true;
39     if (align != right.align) return true;
40     if (scaleDiffuse != right.scaleDiffuse) return true;
41     return false;
42   };
43 
44   ASPECT_RATIO ratio;
45   uint32_t     align;
46   bool         scaleDiffuse;
47 };
48 
49 class CTextureInfo
50 {
51 public:
52   CTextureInfo();
53   explicit CTextureInfo(const std::string &file);
54   CTextureInfo& operator=(const CTextureInfo& right) = default;
55   bool       useLarge;
56   CRect      border;          // scaled  - unneeded if we get rid of scale on load
57   int        orientation;     // orientation of the texture (0 - 7 == EXIForientation - 1)
58   std::string diffuse;         // diffuse overlay texture
59   KODI::GUILIB::GUIINFO::CGUIInfoColor diffuseColor; // diffuse color
60   std::string filename;        // main texture file
61 };
62 
63 class CGUITexture
64 {
65 public:
66   virtual ~CGUITexture() = default;
67   static CGUITexture* CreateTexture(
68       float posX, float posY, float width, float height, const CTextureInfo& texture);
69   virtual CGUITexture* Clone() const = 0;
70 
71   static void DrawQuad(const CRect& coords,
72                        UTILS::Color color,
73                        CTexture* texture = nullptr,
74                        const CRect* texCoords = nullptr);
75 
76   bool Process(unsigned int currentTime);
77   void Render();
78 
79   void DynamicResourceAlloc(bool bOnOff);
80   bool AllocResources();
81   void FreeResources(bool immediately = false);
82   void SetInvalid();
83 
84   bool SetVisible(bool visible);
85   bool SetAlpha(unsigned char alpha);
86   bool SetDiffuseColor(UTILS::Color color);
87   bool SetPosition(float x, float y);
88   bool SetWidth(float width);
89   bool SetHeight(float height);
90   bool SetFileName(const std::string &filename);
91   void SetUseCache(const bool useCache = true);
92   bool SetAspectRatio(const CAspectRatio &aspect);
93 
GetFileName()94   const std::string& GetFileName() const { return m_info.filename; };
GetTextureWidth()95   float GetTextureWidth() const { return m_frameWidth; };
GetTextureHeight()96   float GetTextureHeight() const { return m_frameHeight; };
GetWidth()97   float GetWidth() const { return m_width; };
GetHeight()98   float GetHeight() const { return m_height; };
GetXPosition()99   float GetXPosition() const { return m_posX; };
GetYPosition()100   float GetYPosition() const { return m_posY; };
101   int GetOrientation() const;
GetRenderRect()102   const CRect &GetRenderRect() const { return m_vertex; };
IsLazyLoaded()103   bool IsLazyLoaded() const { return m_info.useLarge; };
104 
HitTest(const CPoint & point)105   bool HitTest(const CPoint &point) const { return CRect(m_posX, m_posY, m_posX + m_width, m_posY + m_height).PtInRect(point); };
IsAllocated()106   bool IsAllocated() const { return m_isAllocated != NO; };
FailedToAlloc()107   bool FailedToAlloc() const { return m_isAllocated == NORMAL_FAILED || m_isAllocated == LARGE_FAILED; };
108   bool ReadyToRender() const;
109 
110 protected:
111   CGUITexture(float posX, float posY, float width, float height, const CTextureInfo& texture);
112   CGUITexture(const CGUITexture& left);
113 
114   bool CalculateSize();
115   void LoadDiffuseImage();
116   bool AllocateOnDemand();
117   bool UpdateAnimFrame(unsigned int currentTime);
118   void Render(float left,
119               float top,
120               float right,
121               float bottom,
122               float u1,
123               float v1,
124               float u2,
125               float v2,
126               float u3,
127               float v3);
128   static void OrientateTexture(CRect &rect, float width, float height, int orientation);
129   void ResetAnimState();
130 
131   // functions that our implementation classes handle
Allocate()132   virtual void Allocate() {}; ///< called after our textures have been allocated
Free()133   virtual void Free() {};     ///< called after our textures have been freed
134   virtual void Begin(UTILS::Color color) = 0;
135   virtual void Draw(float* x,
136                     float* y,
137                     float* z,
138                     const CRect& texture,
139                     const CRect& diffuse,
140                     int orientation) = 0;
141   virtual void End() = 0;
142 
143   bool m_visible;
144   UTILS::Color m_diffuseColor;
145 
146   float m_posX;         // size of the frame
147   float m_posY;
148   float m_width;
149   float m_height;
150 
151   CRect m_vertex;       // vertex coords to render
152   bool m_invalid;       // if true, we need to recalculate
153   bool m_use_cache;
154   unsigned char m_alpha;
155 
156   float m_frameWidth, m_frameHeight;          // size in pixels of the actual frame within the texture
157   float m_texCoordsScaleU, m_texCoordsScaleV; // scale factor for pixel->texture coordinates
158 
159   // animations
160   int m_currentLoop;
161   unsigned int m_currentFrame;
162   uint32_t m_lasttime;
163 
164   float m_diffuseU, m_diffuseV;           // size of the diffuse frame (in tex coords)
165   float m_diffuseScaleU, m_diffuseScaleV; // scale factor of the diffuse frame (from texture coords to diffuse tex coords)
166   CPoint m_diffuseOffset;                 // offset into the diffuse frame (it's not always the origin)
167 
168   bool m_allocateDynamically;
169   enum ALLOCATE_TYPE { NO = 0, NORMAL, LARGE, NORMAL_FAILED, LARGE_FAILED };
170   ALLOCATE_TYPE m_isAllocated;
171 
172   CTextureInfo m_info;
173   CAspectRatio m_aspect;
174 
175   CTextureArray m_diffuse;
176   CTextureArray m_texture;
177 };
178