Otclient  14/8/2020
uiwidgetimage.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "uiwidget.h"
28 
29 void UIWidget::initImage()
30 {
31  m_imageCoordsBuffer.enableHardwareCaching();
32 }
33 
34 void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
35 {
36  for(const OTMLNodePtr& node : styleNode->children()) {
37  if(node->tag() == "image-source")
38  setImageSource(stdext::resolve_path(node->value(), node->source()));
39  else if(node->tag() == "image-offset-x")
40  setImageOffsetX(node->value<int>());
41  else if(node->tag() == "image-offset-y")
42  setImageOffsetY(node->value<int>());
43  else if(node->tag() == "image-offset")
44  setImageOffset(node->value<Point>());
45  else if(node->tag() == "image-width")
46  setImageWidth(node->value<int>());
47  else if(node->tag() == "image-height")
48  setImageHeight(node->value<int>());
49  else if(node->tag() == "image-size")
50  setImageSize(node->value<Size>());
51  else if(node->tag() == "image-rect")
52  setImageRect(node->value<Rect>());
53  else if(node->tag() == "image-clip")
54  setImageClip(node->value<Rect>());
55  else if(node->tag() == "image-fixed-ratio")
56  setImageFixedRatio(node->value<bool>());
57  else if(node->tag() == "image-repeated")
58  setImageRepeated(node->value<bool>());
59  else if(node->tag() == "image-smooth")
60  setImageSmooth(node->value<bool>());
61  else if(node->tag() == "image-color")
62  setImageColor(node->value<Color>());
63  else if(node->tag() == "image-border-top")
64  setImageBorderTop(node->value<int>());
65  else if(node->tag() == "image-border-right")
66  setImageBorderRight(node->value<int>());
67  else if(node->tag() == "image-border-bottom")
68  setImageBorderBottom(node->value<int>());
69  else if(node->tag() == "image-border-left")
70  setImageBorderLeft(node->value<int>());
71  else if(node->tag() == "image-border")
72  setImageBorder(node->value<int>());
73  else if(node->tag() == "image-auto-resize")
74  setImageAutoResize(node->value<bool>());
75  }
76 }
77 
78 void UIWidget::drawImage(const Rect& screenCoords)
79 {
80  if(!m_imageTexture || !screenCoords.isValid())
81  return;
82 
83  // cache vertex buffers
84  if(m_imageCachedScreenCoords != screenCoords || m_imageMustRecache) {
85  m_imageCoordsBuffer.clear();
86  m_imageCachedScreenCoords = screenCoords;
87  m_imageMustRecache = false;
88 
89  Rect drawRect = screenCoords;
90  drawRect.translate(m_imageRect.topLeft());
91  if(m_imageRect.isValid())
92  drawRect.resize(m_imageRect.size());
93 
95 
96  if(!m_imageBordered) {
97  if(m_imageFixedRatio) {
98  Size textureSize = m_imageTexture->getSize();
99 
100  Size textureClipSize = drawRect.size();
101  textureClipSize.scale(textureSize, Fw::KeepAspectRatio);
102 
103  Point texCoordsOffset;
104  if(textureSize.height() > textureClipSize.height())
105  texCoordsOffset.y = (textureSize.height() - textureClipSize.height())/2;
106  else if(textureSize.width() > textureClipSize.width())
107  texCoordsOffset.x = (textureSize.width() - textureClipSize.width())/2;
108 
109  Rect textureClipRect(texCoordsOffset, textureClipSize);
110 
111  m_imageCoordsBuffer.addRect(drawRect, textureClipRect);
112  } else {
113  if(m_imageRepeated)
114  m_imageCoordsBuffer.addRepeatedRects(drawRect, clipRect);
115  else
116  m_imageCoordsBuffer.addRect(drawRect, clipRect);
117  }
118  } else {
119  int top = m_imageBorder.top;
120  int bottom = m_imageBorder.bottom;
121  int left = m_imageBorder.left;
122  int right = m_imageBorder.right;
123 
124  // calculates border coords
125  const Rect clip = clipRect;
126  Rect leftBorder(clip.left(), clip.top() + top, left, clip.height() - top - bottom);
127  Rect rightBorder(clip.right() - right + 1, clip.top() + top, right, clip.height() - top - bottom);
128  Rect topBorder(clip.left() + left, clip.top(), clip.width() - right - left, top);
129  Rect bottomBorder(clip.left() + left, clip.bottom() - bottom + 1, clip.width() - right - left, bottom);
130  Rect topLeftCorner(clip.left(), clip.top(), left, top);
131  Rect topRightCorner(clip.right() - right + 1, clip.top(), right, top);
132  Rect bottomLeftCorner(clip.left(), clip.bottom() - bottom + 1, left, bottom);
133  Rect bottomRightCorner(clip.right() - right + 1, clip.bottom() - bottom + 1, right, bottom);
134  Rect center(clip.left() + left, clip.top() + top, clip.width() - right - left, clip.height() - top - bottom);
135  Size bordersSize(leftBorder.width() + rightBorder.width(), topBorder.height() + bottomBorder.height());
136  Size centerSize = drawRect.size() - bordersSize;
137  Rect rectCoords;
138 
139  // first the center
140  if(centerSize.area() > 0) {
141  rectCoords = Rect(drawRect.left() + leftBorder.width(), drawRect.top() + topBorder.height(), centerSize);
142  m_imageCoordsBuffer.addRepeatedRects(rectCoords, center);
143  }
144  // top left corner
145  rectCoords = Rect(drawRect.topLeft(), topLeftCorner.size());
146  m_imageCoordsBuffer.addRepeatedRects(rectCoords, topLeftCorner);
147  // top
148  rectCoords = Rect(drawRect.left() + topLeftCorner.width(), drawRect.topLeft().y, centerSize.width(), topBorder.height());
149  m_imageCoordsBuffer.addRepeatedRects(rectCoords, topBorder);
150  // top right corner
151  rectCoords = Rect(drawRect.left() + topLeftCorner.width() + centerSize.width(), drawRect.top(), topRightCorner.size());
152  m_imageCoordsBuffer.addRepeatedRects(rectCoords, topRightCorner);
153  // left
154  rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height(), leftBorder.width(), centerSize.height());
155  m_imageCoordsBuffer.addRepeatedRects(rectCoords, leftBorder);
156  // right
157  rectCoords = Rect(drawRect.left() + leftBorder.width() + centerSize.width(), drawRect.top() + topRightCorner.height(), rightBorder.width(), centerSize.height());
158  m_imageCoordsBuffer.addRepeatedRects(rectCoords, rightBorder);
159  // bottom left corner
160  rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height() + centerSize.height(), bottomLeftCorner.size());
161  m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomLeftCorner);
162  // bottom
163  rectCoords = Rect(drawRect.left() + bottomLeftCorner.width(), drawRect.top() + topBorder.height() + centerSize.height(), centerSize.width(), bottomBorder.height());
164  m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomBorder);
165  // bottom right corner
166  rectCoords = Rect(drawRect.left() + bottomLeftCorner.width() + centerSize.width(), drawRect.top() + topRightCorner.height() + centerSize.height(), bottomRightCorner.size());
167  m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomRightCorner);
168  }
169  }
170 
171  // smooth is now enabled by default for all textures
172  //m_imageTexture->setSmooth(m_imageSmooth);
173 
175  g_painter->drawTextureCoords(m_imageCoordsBuffer, m_imageTexture);
176 }
177 
178 void UIWidget::setImageSource(const std::string& source)
179 {
180  if(source.empty())
181  m_imageTexture = nullptr;
182  else
184 
186  Size size = getSize();
187  Size imageSize = m_imageTexture->getSize();
188  if(size.width() <= 0 || m_imageAutoResize)
189  size.setWidth(imageSize.width());
190  if(size.height() <= 0 || m_imageAutoResize)
191  size.setHeight(imageSize.height());
192  setSize(size);
193  }
194 
195  m_imageMustRecache = true;
196 }
UIWidget::setImageOffset
void setImageOffset(const Point &pos)
Definition: uiwidget.h:430
CoordsBuffer::addRepeatedRects
void addRepeatedRects(const Rect &dest, const Rect &src)
Definition: coordsbuffer.cpp:57
Painter::setColor
virtual void setColor(const Color &color)
Definition: painter.h:77
EdgeGroup::right
T right
Definition: uiwidget.h:41
UIWidget::setImageOffsetY
void setImageOffsetY(int y)
Definition: uiwidget.h:429
TRect::resize
void resize(const TSize< T > &size)
Definition: rect.h:100
UIWidget::setImageRepeated
void setImageRepeated(bool repeated)
Definition: uiwidget.h:437
graphics.h
Color
Definition: color.h:32
UIWidget::setImageClip
void setImageClip(const Rect &clipRect)
Definition: uiwidget.h:427
TPoint::y
T y
Definition: point.h:83
TSize::setWidth
void setWidth(T w)
Definition: size.h:47
TRect< int >
Texture::getSize
const Size & getSize()
Definition: texture.h:50
TSize::scale
void scale(const TSize< T > &s, Fw::AspectRatioMode mode)
Definition: size.h:76
UIWidget::setImageColor
void setImageColor(const Color &color)
Definition: uiwidget.h:435
Fw::KeepAspectRatio
@ KeepAspectRatio
Definition: const.h:188
UIWidget::setImageRect
void setImageRect(const Rect &rect)
Definition: uiwidget.h:434
EdgeGroup::top
T top
Definition: uiwidget.h:40
TRect::left
T left() const
Definition: rect.h:52
TSize::area
T area() const
Definition: size.h:101
UIWidget::setImageWidth
void setImageWidth(int width)
Definition: uiwidget.h:431
texturemanager.h
UIWidget::m_imageBorder
EdgeGroup< int > m_imageBorder
Definition: uiwidget.h:423
UIWidget::setImageHeight
void setImageHeight(int height)
Definition: uiwidget.h:432
OTMLNode::children
OTMLNodeList children()
Definition: otmlnode.cpp:170
TRect::bottom
T bottom() const
Definition: rect.h:55
UIWidget::m_imageTexture
TexturePtr m_imageTexture
Definition: uiwidget.h:414
uiwidget.h
UIWidget::setImageAutoResize
void setImageAutoResize(bool autoResize)
Definition: uiwidget.h:439
TSize::width
int width() const
Definition: size.h:43
UIWidget::m_rect
Rect m_rect
Definition: uiwidget.h:62
CoordsBuffer::enableHardwareCaching
void enableHardwareCaching(HardwareBuffer::UsagePattern usagePattern=HardwareBuffer::DynamicDraw)
Definition: coordsbuffer.cpp:86
UIWidget::m_imageColor
Color m_imageColor
Definition: uiwidget.h:417
TRect::topLeft
TPoint< T > topLeft() const
Definition: rect.h:60
painter.h
UIWidget::setImageSmooth
void setImageSmooth(bool smooth)
Definition: uiwidget.h:438
stdext::resolve_path
std::string resolve_path(const std::string &filePath, std::string sourcePath)
Resolve a file path by combining sourcePath with filePath.
Definition: string.cpp:35
TSize::setHeight
void setHeight(T h)
Definition: size.h:48
UIWidget::setImageOffsetX
void setImageOffsetX(int x)
Definition: uiwidget.h:428
UIWidget::m_imageAutoResize
stdext::boolean< false > m_imageAutoResize
Definition: uiwidget.h:422
UIWidget::setImageBorder
void setImageBorder(int border)
Definition: uiwidget.h:444
UIWidget::m_imageFixedRatio
stdext::boolean< false > m_imageFixedRatio
Definition: uiwidget.h:419
CoordsBuffer::clear
void clear()
Definition: coordsbuffer.h:38
UIWidget::m_imageRepeated
stdext::boolean< false > m_imageRepeated
Definition: uiwidget.h:420
TPoint::x
T x
Definition: point.h:83
UIWidget::m_imageClipRect
Rect m_imageClipRect
Definition: uiwidget.h:415
TextureManager::getTexture
TexturePtr getTexture(const std::string &fileName)
Definition: texturemanager.cpp:90
UIWidget::setImageBorderBottom
void setImageBorderBottom(int border)
Definition: uiwidget.h:442
UIWidget::getSize
Size getSize()
Definition: uiwidget.h:357
Rect
TRect< int > Rect
Definition: rect.h:319
UIWidget::setImageFixedRatio
void setImageFixedRatio(bool fixedRatio)
Definition: uiwidget.h:436
UIWidget::drawImage
void drawImage(const Rect &screenCoords)
Definition: uiwidgetimage.cpp:78
UIWidget::setImageSize
void setImageSize(const Size &size)
Definition: uiwidget.h:433
TSize::height
int height() const
Definition: size.h:44
TRect::right
T right() const
Definition: rect.h:54
UIWidget::m_imageRect
Rect m_imageRect
Definition: uiwidget.h:416
texture.h
TRect::isValid
bool isValid() const
Definition: rect.h:50
stdext::shared_object_ptr< OTMLNode >
CoordsBuffer::addRect
void addRect(const Rect &dest)
Definition: coordsbuffer.h:48
g_painter
Painter * g_painter
Definition: painter.cpp:28
UIWidget::setSize
void setSize(const Size &size)
Definition: uiwidget.h:303
TRect::height
T height() const
Definition: rect.h:70
UIWidget::setImageSource
void setImageSource(const std::string &source)
Definition: uiwidgetimage.cpp:178
TRect::top
T top() const
Definition: rect.h:53
g_textures
TextureManager g_textures
Definition: texturemanager.cpp:33
UIWidget::setImageBorderLeft
void setImageBorderLeft(int border)
Definition: uiwidget.h:443
TPoint< int >
TRect::size
TSize< T > size() const
Definition: rect.h:71
EdgeGroup::bottom
T bottom
Definition: uiwidget.h:42
EdgeGroup::left
T left
Definition: uiwidget.h:43
TRect::width
T width() const
Definition: rect.h:69
UIWidget::setImageBorderTop
void setImageBorderTop(int border)
Definition: uiwidget.h:440
TSize< int >
Painter::drawTextureCoords
virtual void drawTextureCoords(CoordsBuffer &coordsBuffer, const TexturePtr &texture)=0
UIWidget::setImageBorderRight
void setImageBorderRight(int border)
Definition: uiwidget.h:441
TRect::translate
void translate(T x, T y)
Definition: rect.h:98