OpenClonk
C4GameMessage.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Text messages drawn inside the viewport */
19 
20 #include "C4Include.h"
21 #include "gui/C4GameMessage.h"
22 
23 #include "graphics/C4Draw.h"
25 #include "object/C4Def.h"
26 #include "object/C4Object.h"
27 #include "player/C4Player.h"
28 #include "player/C4PlayerList.h"
29 
30 const int32_t ObjectMsgDelayFactor = 2, GlobalMsgDelayFactor = 3; // frames per char message display time
31 
33 
35 {
36  delete pFrameDeco;
37 }
38 
39 void C4GameMessage::Init(int32_t iType, const StdStrBuf & sText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, C4PropList *pSrc, uint32_t dwFlags, int width)
40 {
41  // safety!
42  if (pTarget && !pTarget->Status) pTarget = nullptr;
43  // Set data
44  Text.Copy(sText);
45  Target=pTarget;
46  X=iX; Y=iY; Wdt=width; Hgt=0;
47  Player=iPlayer;
48  ColorDw=dwClr;
49  Type=iType;
51  DecoID=idDecoID;
52  this->dwFlags=dwFlags;
53  PictureDef=nullptr;
55  if (pSrc)
56  {
57  // retain special width/height properties when using a message box on an object-local message
58  if (Target)
59  {
60  C4Value val;
61  if (pSrc->GetProperty(P_Wdt, &val))
62  Wdt = val.getInt();
63  if (pSrc->GetProperty(P_Hgt, &val))
64  Hgt = val.getInt();
65  }
66 
67  // retain object or definition from the proplist
68  PictureDef = pSrc->GetObject();
69  if (!PictureDef) PictureDef = pSrc->GetDef();
71  {
72  PictureDef = pSrc;
74  }
75  }
76  // Permanent message
77  if ('@' == Text[0])
78  {
79  Delay=-1;
80  Text.Move(1, Text.getLength());
81  Text.Shrink(1);
82  }
83  // frame decoration
84  delete pFrameDeco; pFrameDeco = nullptr;
85  if (DecoID)
86  {
88  if (!pFrameDeco->SetByDef(DecoID))
89  {
90  delete pFrameDeco;
91  pFrameDeco = nullptr;
92  }
93  }
94 }
95 
96 void C4GameMessage::Append(const char *szText, bool fNoDuplicates)
97 {
98  // Check for duplicates
99  if (fNoDuplicates)
100  for (const char *pPos = Text.getData(); *pPos; pPos = SAdvancePast(pPos, '|'))
101  if (SEqual2(pPos, szText))
102  return;
103  // Append new line
104  Text.AppendFormat("|%s", szText);
106 }
107 
109 {
110  // Delay / removal
111  if (Delay>0) Delay--;
112  if (Delay==0) return false;
113  // Done
114  return true;
115 }
116 
117 int32_t DrawMessageOffset = -35; // For finding the optimum place to draw startup info & player messages...
118 int32_t PictureWidth = 64;
119 int32_t PictureIndent = 10;
120 
121 void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer)
122 {
123  // Globals or player
124  if (Type == C4GM_Global || ((Type == C4GM_GlobalPlayer) && (iPlayer == Player)))
125  {
126  int32_t iTextWdt,iTextHgt;
127  StdStrBuf sText;
128  int32_t x,y,wdt;
129  if (dwFlags & C4GM_XRel) x = X * cgo.Wdt / 100; else x = X;
130  if (dwFlags & C4GM_YRel) y = Y * cgo.Hgt / 100; else y = Y;
131  if (dwFlags & C4GM_WidthRel) wdt = Wdt * cgo.Wdt / 100; else wdt = Wdt;
132  if (~dwFlags & C4GM_NoBreak)
133  {
134  // Word wrap to cgo width
135  if (PictureDef)
136  {
137  if (!wdt) wdt = Clamp<int32_t>(cgo.Wdt/2, 50, std::min<int32_t>(500, cgo.Wdt-10));
138  int32_t iUnbrokenTextWidth = ::GraphicsResource.FontRegular.GetTextWidth(Text.getData(), true);
139  wdt = std::min<int32_t>(wdt, iUnbrokenTextWidth+10);
140  }
141  else
142  {
143  if (!wdt)
144  wdt = Clamp<int32_t>(cgo.Wdt-50, 50, 500);
145  else
146  wdt = Clamp<int32_t>(wdt, 10, cgo.Wdt-10);
147  }
148  iTextWdt = wdt * cgo.Zoom;
149  iTextHgt = ::GraphicsResource.FontRegular.BreakMessage(Text.getData(), iTextWdt, &sText, true);
150  }
151  else
152  {
153  ::GraphicsResource.FontRegular.GetTextExtent(Text.getData(), iTextWdt, iTextHgt, true);
154  sText.Ref(Text);
155  }
156  int32_t iDrawX = cgo.X+x;
157  int32_t iDrawY = cgo.Y+y;
158  // draw message
159  if (PictureDef)
160  {
161  // message with portrait
162  // bottom-placed portrait message: Y-Positioning 0 refers to bottom of viewport
163  if (dwFlags & C4GM_Bottom) iDrawY += cgo.Hgt;
164  else if (dwFlags & C4GM_VCenter) iDrawY += cgo.Hgt/2;
165  if (dwFlags & C4GM_Right) iDrawX += cgo.Wdt;
166  else if (dwFlags & C4GM_HCenter) iDrawX += cgo.Wdt/2;
167  // draw decoration
168  if (pFrameDeco)
169  {
170  iDrawX *= cgo.Zoom; iDrawY *= cgo.Zoom;
171  C4Rect rect(iDrawX-cgo.TargetX, iDrawY-cgo.TargetY, iTextWdt + PictureWidth + PictureIndent + pFrameDeco->iBorderLeft + pFrameDeco->iBorderRight, std::max(iTextHgt, PictureWidth) + pFrameDeco->iBorderTop + pFrameDeco->iBorderBottom);
172  if (dwFlags & C4GM_Bottom) { rect.y -= rect.Hgt; iDrawY -= rect.Hgt; }
173  else if (dwFlags & C4GM_VCenter) { rect.y -= rect.Hgt/2; iDrawY -= rect.Hgt/2; }
174  if (dwFlags & C4GM_Right) { rect.x -= rect.Wdt; iDrawX -= rect.Wdt; }
175  else if (dwFlags & C4GM_HCenter) { rect.x -= rect.Wdt/2; iDrawX -= rect.Wdt/2; }
176  pFrameDeco->Draw(cgo, rect);
177  iDrawX += pFrameDeco->iBorderLeft;
178  iDrawY += pFrameDeco->iBorderTop;
179  }
180  else
181  iDrawY -= iTextHgt;
182  // draw picture
183  // can only be def or object because has been checked on assignment
184 
185  C4Facet facet(cgo.Surface, iDrawX, iDrawY, PictureWidth, PictureWidth);
186  if(PictureDef->GetObject())
187  PictureDef->GetObject()->DrawPicture(facet);
188  else if (PictureDef->GetDef())
189  PictureDef->GetDef()->Draw(facet);
190  else
192 
193  // draw message
195  }
196  else
197  {
198  // message without picture
199  iDrawX += (cgo.Wdt/2) * cgo.Zoom;
200  iDrawY += (2 * cgo.Hgt / 3 + 50) * cgo.Zoom;
201  if (!(dwFlags & C4GM_Bottom)) iDrawY += DrawMessageOffset;
202  pDraw->TextOut(sText.getData(),::GraphicsResource.FontRegular,1.0,cgo.Surface,iDrawX,iDrawY,ColorDw,ACenter);
203  }
204  }
205  // Positioned
206  else if (Type == C4GM_Target || ((Type == C4GM_TargetPlayer) && (iPlayer == Player)))
207  {
208  // adjust position by object; care about parallaxity
209  float iMsgX, iMsgY, newzoom;
210  Target->GetDrawPosition(cgo, iMsgX, iMsgY, newzoom);
211  if(~dwFlags & C4GM_YRel)
212  iMsgY -= Target->Def->Shape.Hgt/2+5;
213  iMsgX+=X; iMsgY+=Y;
214  // check output bounds
215  if (Inside<float>((iMsgX - cgo.X) * newzoom, 0, cgo.Wdt * cgo.Zoom - 1) || (dwFlags & C4GM_XRel))
216  if (Inside<float>((iMsgY - cgo.Y) * newzoom, 0, cgo.Hgt * cgo.Zoom - 1) || (dwFlags & C4GM_YRel))
217  {
218  // if the message is attached to an object and the object
219  // is invisible for that player, the message won't be drawn
220  if (Type == C4GM_Target)
221  if (!Target->IsVisible(iPlayer, false))
222  return;
223  // Word wrap to cgo width
224  StdStrBuf sText;
225  if (~dwFlags & C4GM_NoBreak)
226  {
227  // standard break width
228  int breakWdt = Clamp<int32_t>(cgo.Wdt * cgo.Zoom, 50, 200);
229 
230  // user supplied width?
231  if (Wdt)
232  breakWdt = Wdt;
233 
234  ::GraphicsResource.FontRegular.BreakMessage(Text.getData(), breakWdt, &sText, true);
235  }
236  else
237  sText.Ref(Text);
238 
239  // vertical placement
240  if (dwFlags & C4GM_Bottom)
241  iMsgY += Hgt; // iTHgt will be substracted below
242  else if (dwFlags & C4GM_Top)
243  ;
244  else if (dwFlags & C4GM_VCenter)
245  iMsgY += Hgt / 2;
246 
247  // horizontal placement
248  int alignment = ACenter;
249 
250  if (dwFlags & C4GM_Left)
251  alignment = ALeft;
252  else if (dwFlags & C4GM_Right)
253  {
254  alignment = ARight;
255  iMsgX += Wdt;
256  }
257  else if (dwFlags & C4GM_HCenter)
258  iMsgX += Wdt / 2;
259 
260  // calculate display position and adjust position by output boundaries
261  float iTX, iTY;
262  iTX = (iMsgX - cgo.X) * newzoom;
263  iTY = (iMsgY - cgo.Y) * newzoom;
264  int iTWdt, iTHgt;
265  ::GraphicsResource.FontRegular.GetTextExtent(sText.getData(),iTWdt,iTHgt,true);
266 
267  // adjust zoom if needed
268  float zoom = 1.0;
269  if(dwFlags & C4GM_Zoom)
270  zoom = cgo.Zoom;
271 
272  if (dwFlags & C4GM_Bottom)
273  iTY -= zoom * float(iTHgt);
274  else if (dwFlags & C4GM_VCenter)
275  iTY -= zoom * float(iTHgt/2);
276  else if (~dwFlags & C4GM_Top)
277  iTY -= zoom * float(iTHgt); // above object is standard
278 
279  if (dwFlags & C4GM_Right)
280  iTX += 0.25f * float(iTWdt) * (1.0f - zoom);
281 
282  // adjustment for objects at border of screen?
283  // +0.5f for proper rounding; avoids oscillations near pixel border:
284  if (~dwFlags & C4GM_XRel) iTX = Clamp<float>(iTX, iTWdt/2, cgo.Wdt * cgo.Zoom - iTWdt / 2) + 0.5f;
285  if (~dwFlags & C4GM_YRel) iTY = Clamp<float>(iTY, 0, cgo.Hgt * cgo.Zoom - iTHgt) + 0.5f;
286 
287  // Draw
289  cgo.Surface,
290  cgo.X + iTX,
291  cgo.Y + iTY,
292  ColorDw, alignment);
293  return;
294  }
295  }
296 }
297 
299 {
300  // frame deco might be using updated/deleted def
301  if (pFrameDeco)
302  {
303  if (!pFrameDeco->UpdateGfx())
304  {
305  delete pFrameDeco;
306  pFrameDeco = nullptr;
307  }
308  }
309 }
310 
312 {
313  Default();
314 }
315 
317 {
318  Clear();
319 }
320 
322 {
323  First=nullptr;
324 }
325 
327 {
328  C4GameMessage *cmsg,*next,*prev=nullptr;
329  for (cmsg=First; cmsg; cmsg=next)
330  {
331  next=cmsg->Next;
332  if (cmsg->Target==pObj)
333  { delete cmsg; if (prev) prev->Next=next; else First=next; }
334  else
335  prev=cmsg;
336  }
337 }
338 
340 {
341  C4GameMessage *cmsg,*next;
342  for (cmsg=First; cmsg; cmsg=next)
343  {
344  next=cmsg->Next;
345  delete cmsg;
346  }
347  First=nullptr;
348 }
349 
351 {
352  C4GameMessage *cmsg,*next,*prev=nullptr;
353  for (cmsg=First; cmsg; cmsg=next)
354  {
355  next=cmsg->Next;
356  if (!cmsg->Execute())
357  { delete cmsg; if (prev) prev->Next=next; else First=next; }
358  else
359  prev=cmsg;
360  }
361 }
362 
363 bool C4GameMessageList::New(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, C4PropList *pSrc, uint32_t dwFlags, int32_t width)
364 {
365  return New(iType, StdStrBuf(szText), pTarget, iPlayer, iX, iY, dwClr, idDecoID, pSrc, dwFlags, width);
366 }
367 
368 bool C4GameMessageList::New(int32_t iType, const StdStrBuf & sText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, C4PropList *pSrc, uint32_t dwFlags, int32_t width)
369 {
370  if (!(dwFlags & C4GM_Multiple))
371  {
372  // Clear messages with same target
373  if (pTarget) ClearPointers(pTarget);
374 
375  // Clear other global messages for the given player
376  if (iType == C4GM_Global || iType == C4GM_GlobalPlayer) ClearPlayers(iPlayer, dwFlags & C4GM_PositioningFlags);
377  }
378 
379  // Object deleted?
380  if (pTarget && !pTarget->Status) return false;
381 
382  // Empty message? (only deleting old message)
383  if (!sText.getLength()) return true;
384 
385  // Add new message
386  C4GameMessage *msgNew = new C4GameMessage;
387  msgNew->Init(iType, sText,pTarget,iPlayer,iX,iY,dwClr, idDecoID, pSrc, dwFlags, width);
388  msgNew->Next=First;
389  First=msgNew;
390 
391  return true;
392 }
393 
394 bool C4GameMessageList::Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t bCol, bool fNoDuplicates)
395 {
396  C4GameMessage *cmsg = nullptr;
397  if (iType == C4GM_Target)
398  {
399  for (cmsg=::Messages.First; cmsg; cmsg=cmsg->Next)
400  if (pTarget == cmsg->Target)
401  break;
402  }
403  if (iType == C4GM_Global || iType == C4GM_GlobalPlayer)
404  {
405  for (cmsg=::Messages.First; cmsg; cmsg=cmsg->Next)
406  if (iPlayer == cmsg->Player)
407  break;
408  }
409  if (!cmsg || pTarget!=cmsg->Target)
410  {
411  New(iType, szText, pTarget, iPlayer, iX, iY, bCol);
412  }
413  else
414  {
415  cmsg->Append(szText, fNoDuplicates);
416  }
417  return true;
418 }
419 
420 void C4GameMessageList::ClearPlayers(int32_t iPlayer, int32_t dwPositioningFlags)
421 {
422  C4GameMessage *cmsg,*next,*prev=nullptr;
423  for (cmsg=First; cmsg; cmsg=next)
424  {
425  next=cmsg->Next;
426  if ( (cmsg->Type == C4GM_Global || cmsg->Type == C4GM_GlobalPlayer) && cmsg->Player==iPlayer && cmsg->GetPositioningFlags() == dwPositioningFlags)
427  { delete cmsg; if (prev) prev->Next=next; else First=next; }
428  else
429  prev=cmsg;
430  }
431 }
432 
434 {
435  C4GameMessage *cmsg;
436  for (cmsg=First; cmsg; cmsg=cmsg->Next) cmsg->UpdateDef(idUpdDef);
437 }
438 
439 void C4GameMessageList::Draw(C4TargetFacet &gui_cgo, C4TargetFacet &cgo, int32_t iPlayer)
440 {
441  C4GameMessage *cmsg;
442  for (cmsg=First; cmsg; cmsg=cmsg->Next)
443  {
444  if ((cmsg->Target && (cmsg->Target->Category & C4D_Foreground)) || cmsg->Type == C4GM_Global || cmsg->Type == C4GM_GlobalPlayer)
445  cmsg->Draw(gui_cgo,iPlayer);
446  else
447  cmsg->Draw(cgo,iPlayer);
448  }
449 }
450 
451 void GameMsgObjectError(const char *szText, C4Object *pTarget, bool Red)
452 {
453  ::Messages.New(C4GM_TargetPlayer,szText,pTarget,pTarget->Controller,0,0, Red ? C4RGB(0xca, 0, 0) : C4RGB(0xff, 0xff, 0xff));
454 }
455 
const int32_t C4D_Foreground
Definition: C4Def.h:53
C4Draw * pDraw
Definition: C4Draw.cpp:42
int32_t PictureIndent
const int32_t ObjectMsgDelayFactor
int32_t DrawMessageOffset
int32_t PictureWidth
void GameMsgObjectError(const char *szText, C4Object *pTarget, bool Red)
const int32_t GlobalMsgDelayFactor
C4GameMessageList Messages
const int32_t C4GM_Bottom
Definition: C4GameMessage.h:35
const int32_t C4GM_NoBreak
Definition: C4GameMessage.h:34
const int32_t C4GM_Multiple
Definition: C4GameMessage.h:36
const int32_t C4GM_XRel
Definition: C4GameMessage.h:44
const int32_t C4GM_HCenter
Definition: C4GameMessage.h:40
const int32_t C4GM_VCenter
Definition: C4GameMessage.h:41
const int32_t C4GM_GlobalPlayer
Definition: C4GameMessage.h:30
const int32_t C4GM_Top
Definition: C4GameMessage.h:37
const int32_t C4GM_PositioningFlags
Definition: C4GameMessage.h:48
const int32_t C4GM_Right
Definition: C4GameMessage.h:39
const int32_t C4GM_TargetPlayer
Definition: C4GameMessage.h:32
const int32_t C4GM_Zoom
Definition: C4GameMessage.h:46
const int32_t C4GM_MinDelay
Definition: C4GameMessage.h:27
const int32_t C4GM_WidthRel
Definition: C4GameMessage.h:43
const int32_t C4GM_Target
Definition: C4GameMessage.h:31
const int32_t C4GM_Left
Definition: C4GameMessage.h:38
const int32_t C4GM_Global
Definition: C4GameMessage.h:29
const int32_t C4GM_YRel
Definition: C4GameMessage.h:45
C4Game Game
Definition: C4Globals.cpp:52
C4GraphicsResource GraphicsResource
@ P_Wdt
@ P_Hgt
@ P_Source
const int ARight
Definition: C4Surface.h:41
const int ALeft
Definition: C4Surface.h:41
const int ACenter
Definition: C4Surface.h:41
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:204
const char * SAdvancePast(const char *szSPos, char cPast)
Definition: Standard.cpp:438
size_t SLen(const char *sptr)
Definition: Standard.h:74
#define C4RGB(r, g, b)
Definition: StdColors.h:26
C4Shape Shape
Definition: C4Def.h:104
void Draw(C4Facet &cgo, bool fSelected=false, DWORD iColor=0, C4Object *pObj=nullptr, int32_t iPhaseX=0, int32_t iPhaseY=0, C4DrawTransform *trans=nullptr, const char *graphicsName=nullptr)
Definition: C4Def.cpp:607
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:561
C4Surface * Surface
Definition: C4Facet.h:117
float Hgt
Definition: C4Facet.h:118
float Wdt
Definition: C4Facet.h:118
float Y
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
bool SetByDef(C4Def *pSrcDef)
void Draw(C4TargetFacet &cgo, C4Rect &rcDrawArea)
bool DrawPropListSpecImage(C4Facet &target, C4PropList *spec)
Definition: C4Game.cpp:4692
int32_t GetPositioningFlags() const
Definition: C4GameMessage.h:79
C4GUI::FrameDecoration * pFrameDeco
Definition: C4GameMessage.h:69
void Init(int32_t iType, const StdStrBuf &Text, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwCol, C4ID idDecoID, C4PropList *pSrc, uint32_t dwFlags, int width)
int32_t Player
Definition: C4GameMessage.h:61
C4GameMessage * Next
Definition: C4GameMessage.h:65
uint32_t dwFlags
Definition: C4GameMessage.h:70
StdCopyStrBuf Text
Definition: C4GameMessage.h:64
void UpdateDef(C4ID idUpdDef)
C4PropList * PictureDef
Definition: C4GameMessage.h:67
void Append(const char *szText, bool fNoDuplicates=false)
C4Value PictureDefVal
Definition: C4GameMessage.h:68
void Draw(C4TargetFacet &cgo, int32_t iPlayer)
C4Object * Target
Definition: C4GameMessage.h:63
bool Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t bCol, bool fNoDuplicates=false)
void Draw(C4TargetFacet &gui_cgo, C4TargetFacet &cgo, int32_t iPlayer)
void ClearPlayers(int32_t iPlayer, int32_t dwPositioningFlags)
C4GameMessage * First
Definition: C4GameMessage.h:88
bool New(int32_t iType, const StdStrBuf &Text, C4Object *pTarget, int32_t iPlayer, int32_t iX=-1, int32_t iY=-1, uint32_t dwClr=0xffFFFFFF, C4ID idDecoID=C4ID::None, C4PropList *pSrc=nullptr, uint32_t dwFlags=0u, int32_t width=0)
void ClearPointers(C4Object *pObj)
void UpdateDef(C4ID idUpdDef)
Definition: C4Id.h:26
bool GetDrawPosition(const C4TargetFacet &cgo, float &resultx, float &resulty, float &resultzoom) const
void DrawPicture(C4Facet &cgo, bool fSelected=false, C4DrawTransform *transform=nullptr)
int32_t Category
Definition: C4Object.h:111
bool IsVisible(int32_t iForPlr, bool fAsOverlay) const
int32_t Controller
Definition: C4Object.h:109
C4Def * Def
Definition: C4Object.h:141
virtual C4Object * GetObject()
Definition: C4PropList.cpp:636
int32_t Status
Definition: C4PropList.h:173
C4PropList * GetPropertyPropList(C4PropertyName k) const
Definition: C4PropList.cpp:869
virtual C4Def const * GetDef() const
Definition: C4PropList.cpp:654
bool GetProperty(C4PropertyName k, C4Value *pResult) const
Definition: C4PropList.h:105
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
float Zoom
Definition: C4Facet.h:165
void SetPropList(C4PropList *PropList)
Definition: C4Value.h:141
int32_t getInt() const
Definition: C4Value.h:112
void Set0()
Definition: C4Value.h:332
int32_t GetTextWidth(const char *szText, bool fCheckMarkup=true)
Definition: C4FontLoader.h:140
std::tuple< std::string, int > BreakMessage(const char *szMsg, int iWdt, bool fCheckMarkup, float fZoom=1.0f)
bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup=true)
void Move(size_t iFrom, size_t inSize, size_t iTo=0)
Definition: StdBuf.h:471
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:190
void Ref(const char *pnData)
Definition: StdBuf.h:455
void Shrink(size_t iShrink)
Definition: StdBuf.h:503
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
size_t getLength() const
Definition: StdBuf.h:445