FreeRDP
rdtk_button.c
1 
19 #include <winpr/assert.h>
20 #include <winpr/cast.h>
21 
22 #include <rdtk/config.h>
23 
24 #include "rdtk_font.h"
25 
26 #include "rdtk_button.h"
27 
28 int rdtk_button_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth,
29  uint16_t nHeight, rdtkButton* button, const char* text)
30 {
31  uint16_t textWidth = 0;
32  uint16_t textHeight = 0;
33 
34  WINPR_ASSERT(surface);
35  WINPR_ASSERT(button);
36  WINPR_ASSERT(text);
37 
38  rdtkEngine* engine = surface->engine;
39  rdtkFont* font = engine->font;
40  rdtkNinePatch* ninePatch = button->ninePatch;
41 
42  rdtk_font_text_draw_size(font, &textWidth, &textHeight, text);
43 
44  rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch);
45 
46  if ((textWidth > 0) && (textHeight > 0))
47  {
48  const int wd = (ninePatch->width - ninePatch->fillWidth);
49  const int hd = (ninePatch->height - ninePatch->fillHeight);
50 
51  const uint16_t fillWidth = nWidth - WINPR_ASSERTING_INT_CAST(uint16_t, wd);
52  const uint16_t fillHeight = nHeight - WINPR_ASSERTING_INT_CAST(uint16_t, hd);
53  uint16_t offsetX = WINPR_ASSERTING_INT_CAST(UINT16, ninePatch->fillLeft);
54  uint16_t offsetY = WINPR_ASSERTING_INT_CAST(UINT16, ninePatch->fillTop);
55 
56  if (textWidth < fillWidth)
57  {
58  const int twd = ((fillWidth - textWidth) / 2) + ninePatch->fillLeft;
59  offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
60  }
61  else if (textWidth < ninePatch->width)
62  {
63  const int twd = ((ninePatch->width - textWidth) / 2);
64  offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
65  }
66 
67  if (textHeight < fillHeight)
68  {
69  const int twd = ((fillHeight - textHeight) / 2) + ninePatch->fillTop;
70  offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
71  }
72  else if (textHeight < ninePatch->height)
73  {
74  const int twd = ((ninePatch->height - textHeight) / 2);
75  offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
76  }
77 
78  rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text);
79  }
80 
81  return 1;
82 }
83 
84 rdtkButton* rdtk_button_new(rdtkEngine* engine, rdtkNinePatch* ninePatch)
85 {
86  WINPR_ASSERT(engine);
87  WINPR_ASSERT(ninePatch);
88 
89  rdtkButton* button = (rdtkButton*)calloc(1, sizeof(rdtkButton));
90 
91  if (!button)
92  return NULL;
93 
94  button->engine = engine;
95  button->ninePatch = ninePatch;
96 
97  return button;
98 }
99 
100 void rdtk_button_free(rdtkButton* button)
101 {
102  free(button);
103 }
104 
105 int rdtk_button_engine_init(rdtkEngine* engine)
106 {
107  WINPR_ASSERT(engine);
108 
109  if (!engine->button)
110  {
111  engine->button = rdtk_button_new(engine, engine->button9patch);
112  if (!engine->button)
113  return -1;
114  }
115 
116  return 1;
117 }
118 
119 int rdtk_button_engine_uninit(rdtkEngine* engine)
120 {
121  WINPR_ASSERT(engine);
122 
123  if (engine->button)
124  {
125  rdtk_button_free(engine->button);
126  engine->button = NULL;
127  }
128 
129  return 1;
130 }