1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4
5 #include "cdrawmethods.h"
6 #include "cbitmap.h"
7 #include "cstring.h"
8 #include "cdrawcontext.h"
9 #include "platform/iplatformfont.h"
10
11 namespace VSTGUI {
12 namespace CDrawMethods {
13
14 //------------------------------------------------------------------------
createTruncatedText(TextTruncateMode mode,const UTF8String & text,CFontRef font,CCoord maxWidth,const CPoint & textInset,uint32_t flags)15 UTF8String createTruncatedText (TextTruncateMode mode, const UTF8String& text, CFontRef font,
16 CCoord maxWidth, const CPoint& textInset, uint32_t flags)
17 {
18 if (mode == kTextTruncateNone)
19 return text;
20 auto painter = font->getPlatformFont () ? font->getPlatformFont ()->getPainter () : nullptr;
21 if (!painter)
22 return text;
23 CCoord width = painter->getStringWidth (nullptr, text.getPlatformString (), true);
24 width += textInset.x * 2;
25 if (width > maxWidth)
26 {
27 std::string truncatedText;
28 UTF8String result;
29 auto left = text.begin ();
30 auto right = text.end ();
31 while (width > maxWidth && left != right)
32 {
33 if (mode == kTextTruncateHead)
34 {
35 ++left;
36 truncatedText = "..";
37 }
38 else if (mode == kTextTruncateTail)
39 {
40 --right;
41 truncatedText = "";
42 }
43
44 truncatedText += {left.base (), right.base ()};
45
46 if (mode == kTextTruncateTail)
47 truncatedText += "..";
48
49 result = truncatedText;
50 width = painter->getStringWidth (nullptr, result.getPlatformString (), true);
51 width += textInset.x * 2;
52 }
53 if (left == right && flags & kReturnEmptyIfTruncationIsPlaceholderOnly)
54 result = "";
55 return result;
56 }
57 return text;
58 }
59
60 //------------------------------------------------------------------------
drawIconAndText(CDrawContext * context,CBitmap * iconToDraw,IconPosition iconPosition,CHoriTxtAlign textAlignment,CCoord textIconMargin,CRect drawRect,const UTF8String & title,CFontRef font,CColor textColor,TextTruncateMode textTruncateMode)61 void drawIconAndText (CDrawContext* context, CBitmap* iconToDraw, IconPosition iconPosition,
62 CHoriTxtAlign textAlignment, CCoord textIconMargin, CRect drawRect,
63 const UTF8String& title, CFontRef font, CColor textColor,
64 TextTruncateMode textTruncateMode)
65 {
66 if (iconToDraw)
67 {
68 CRect iconRect (0, 0, iconToDraw->getWidth (), iconToDraw->getHeight ());
69 iconRect.offset (drawRect.left, drawRect.top);
70 switch (iconPosition)
71 {
72 case kIconLeft:
73 {
74 iconRect.offset (textIconMargin,
75 drawRect.getHeight () / 2. - iconRect.getHeight () / 2.);
76 drawRect.left = iconRect.right;
77 drawRect.right -= textIconMargin;
78 if (textAlignment == kLeftText)
79 drawRect.left += textIconMargin;
80 break;
81 }
82 case kIconRight:
83 {
84 iconRect.offset (drawRect.getWidth () - (textIconMargin + iconRect.getWidth ()),
85 drawRect.getHeight () / 2. - iconRect.getHeight () / 2.);
86 drawRect.right = iconRect.left;
87 drawRect.left += textIconMargin;
88 if (textAlignment == kRightText)
89 drawRect.right -= textIconMargin;
90 break;
91 }
92 case kIconCenterAbove:
93 {
94 iconRect.offset (drawRect.getWidth () / 2. - iconRect.getWidth () / 2., 0);
95 if (title.empty ())
96 iconRect.offset (0, drawRect.getHeight () / 2. - iconRect.getHeight () / 2.);
97 else
98 {
99 iconRect.offset (0, drawRect.getHeight () / 2. -
100 (iconRect.getHeight () / 2. +
101 (textIconMargin + font->getSize ()) / 2.));
102 drawRect.top = iconRect.bottom + textIconMargin;
103 drawRect.setHeight (font->getSize ());
104 if (textAlignment == kLeftText)
105 drawRect.left += textIconMargin;
106 else if (textAlignment == kRightText)
107 drawRect.right -= textIconMargin;
108 }
109 break;
110 }
111 case kIconCenterBelow:
112 {
113 iconRect.offset (drawRect.getWidth () / 2. - iconRect.getWidth () / 2., 0);
114 if (title.empty ())
115 iconRect.offset (0, drawRect.getHeight () / 2. - iconRect.getHeight () / 2.);
116 else
117 {
118 iconRect.offset (0, drawRect.getHeight () / 2. - (iconRect.getHeight () / 2.) +
119 (textIconMargin + font->getSize ()) / 2.);
120 drawRect.top = iconRect.top - (textIconMargin + font->getSize ());
121 drawRect.setHeight (font->getSize ());
122 if (textAlignment == kLeftText)
123 drawRect.left += textIconMargin;
124 else if (textAlignment == kRightText)
125 drawRect.right -= textIconMargin;
126 }
127 break;
128 }
129 }
130 context->drawBitmap (iconToDraw, iconRect);
131 }
132 else
133 {
134 if (textAlignment == kLeftText)
135 drawRect.left += textIconMargin;
136 else if (textAlignment == kRightText)
137 drawRect.right -= textIconMargin;
138 }
139 if (!title.empty ())
140 {
141 context->setFont (font);
142 context->setFontColor (textColor);
143 if (textTruncateMode != kTextTruncateNone)
144 {
145 UTF8String truncatedText =
146 createTruncatedText (textTruncateMode, title, font, drawRect.getWidth (),
147 CPoint (0, 0), kReturnEmptyIfTruncationIsPlaceholderOnly);
148 context->drawString (truncatedText.getPlatformString (), drawRect, textAlignment);
149 }
150 else
151 context->drawString (title.getPlatformString (), drawRect, textAlignment);
152 }
153 }
154 }
155 } // namespaces
156