JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_AttributedString.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29namespace
30{
31 int getLength (const Array<AttributedString::Attribute>& atts) noexcept
32 {
33 return atts.size() != 0 ? atts.getReference (atts.size() - 1).range.getEnd() : 0;
34 }
35
37 {
38 for (int i = atts.size(); --i >= 0;)
39 {
40 const auto& att = atts.getUnchecked (i);
41 auto offset = position - att.range.getStart();
42
43 if (offset >= 0)
44 {
45 if (offset > 0 && position < att.range.getEnd())
46 {
47 atts.insert (i + 1, AttributedString::Attribute (att));
48 atts.getReference (i).range.setEnd (position);
49 atts.getReference (i + 1).range.setStart (position);
50 }
51
52 break;
53 }
54 }
55 }
56
57 inline bool areInvariantsMaintained (const String& text, const Array<AttributedString::Attribute>& atts)
58 {
59 if (atts.isEmpty())
60 return true;
61
62 if (atts.getFirst().range.getStart() != 0)
63 return false;
64
65 if (atts.getLast().range.getEnd() != text.length())
66 return false;
67
68 for (auto it = std::next (atts.begin()); it != atts.end(); ++it)
69 if (it->range.getStart() != std::prev (it)->range.getEnd())
70 return false;
71
72 return true;
73 }
74
76 {
77 newRange = newRange.getIntersectionWith ({ 0, getLength (atts) });
78
79 if (! newRange.isEmpty())
80 {
83 }
84
85 return newRange;
86 }
87
89 {
90 for (int i = atts.size() - 1; --i >= 0;)
91 {
92 auto& a1 = atts.getReference (i);
93 auto& a2 = atts.getReference (i + 1);
94
95 if (a1.colour == a2.colour && a1.font == a2.font)
96 {
97 a1.range.setEnd (a2.range.getEnd());
98 atts.remove (i + 1);
99
100 if (i < atts.size() - 1)
101 ++i;
102 }
103 }
104 }
105
107 int length, const Font* f, const Colour* c)
108 {
109 if (atts.size() == 0)
110 {
111 atts.add ({ Range<int> (0, length), f != nullptr ? *f : Font(), c != nullptr ? *c : Colour (0xff000000) });
112 }
113 else
114 {
115 auto start = getLength (atts);
116 atts.add ({ Range<int> (start, start + length),
117 f != nullptr ? *f : atts.getReference (atts.size() - 1).font,
118 c != nullptr ? *c : atts.getReference (atts.size() - 1).colour });
119
121 }
122 }
123
125 Range<int> range, const Font* f, const Colour* c)
126 {
127 range = splitAttributeRanges (atts, range);
128
129 for (auto& att : atts)
130 {
131 if (range.getStart() < att.range.getEnd())
132 {
133 if (range.getEnd() <= att.range.getStart())
134 break;
135
136 if (c != nullptr) att.colour = *c;
137 if (f != nullptr) att.font = *f;
138 }
139 }
140
142 }
143
145 {
147
148 for (int i = atts.size(); --i >= 0;)
149 if (atts.getReference (i).range.getStart() >= newLength)
150 atts.remove (i);
151 }
152}
153
154//==============================================================================
155AttributedString::Attribute::Attribute (Range<int> r, const Font& f, Colour c) noexcept
156 : range (r), font (f), colour (c)
157{
158}
159
160//==============================================================================
162{
163 auto newLength = newText.length();
164 auto oldLength = getLength (attributes);
165
166 if (newLength > oldLength)
167 appendRange (attributes, newLength - oldLength, nullptr, nullptr);
168 else if (newLength < oldLength)
169 truncate (attributes, newLength);
170
171 text = newText;
172 jassert (areInvariantsMaintained (text, attributes));
173}
174
176{
177 text += textToAppend;
178 appendRange (attributes, textToAppend.length(), nullptr, nullptr);
179 jassert (areInvariantsMaintained (text, attributes));
180}
181
183{
184 text += textToAppend;
185 appendRange (attributes, textToAppend.length(), &font, nullptr);
186 jassert (areInvariantsMaintained (text, attributes));
187}
188
190{
191 text += textToAppend;
192 appendRange (attributes, textToAppend.length(), nullptr, &colour);
193 jassert (areInvariantsMaintained (text, attributes));
194}
195
196void AttributedString::append (const String& textToAppend, const Font& font, Colour colour)
197{
198 text += textToAppend;
199 appendRange (attributes, textToAppend.length(), &font, &colour);
200 jassert (areInvariantsMaintained (text, attributes));
201}
202
204{
205 auto originalLength = getLength (attributes);
206 auto originalNumAtts = attributes.size();
207 text += other.text;
208 attributes.addArray (other.attributes);
209
210 for (auto i = originalNumAtts; i < attributes.size(); ++i)
211 attributes.getReference (i).range += originalLength;
212
213 mergeAdjacentRanges (attributes);
214 jassert (areInvariantsMaintained (text, attributes));
215}
216
218{
219 text.clear();
220 attributes.clear();
221}
222
227
229{
230 wordWrap = newWordWrap;
231}
232
237
239{
240 lineSpacing = newLineSpacing;
241}
242
244{
245 applyFontAndColour (attributes, range, nullptr, &colour);
246 jassert (areInvariantsMaintained (text, attributes));
247}
248
250{
251 applyFontAndColour (attributes, range, &font, nullptr);
252 jassert (areInvariantsMaintained (text, attributes));
253}
254
256{
257 setColour ({ 0, getLength (attributes) }, colour);
258 jassert (areInvariantsMaintained (text, attributes));
259}
260
262{
263 setFont ({ 0, getLength (attributes) }, font);
264 jassert (areInvariantsMaintained (text, attributes));
265}
266
268{
269 if (text.isNotEmpty() && g.clipRegionIntersects (area.getSmallestIntegerContainer()))
270 {
271 jassert (text.length() == getLength (attributes));
272
273 if (! g.getInternalContext().drawTextLayout (*this, area))
274 {
275 TextLayout layout;
276 layout.createLayout (*this, area.getWidth());
277 layout.draw (g, area);
278 }
279 }
280}
281
282} // namespace juce
A text string with a set of colour/font settings that are associated with sub-ranges of the text.
void setColour(Range< int > range, Colour colour)
Adds a colour attribute for the specified range.
void setLineSpacing(float newLineSpacing) noexcept
Sets an extra line-spacing distance.
void clear()
Resets the string, clearing all text and attributes.
void draw(Graphics &g, const Rectangle< float > &area) const
Draws this string within the given area.
void setReadingDirection(ReadingDirection newReadingDirection) noexcept
Sets the reading direction that should be used for the text.
void append(const String &textToAppend)
Appends some text (with a default font and colour).
ReadingDirection
Types of reading direction that can be used.
WordWrap
Types of word-wrap behaviour.
void setText(const String &newText)
Replaces all the text.
void setJustification(Justification newJustification) noexcept
Sets the justification that should be used for laying-out the text.
void setWordWrap(WordWrap newWordWrap) noexcept
Sets the word-wrapping behaviour.
void setFont(Range< int > range, const Font &font)
Adds a font attribute for the specified range.
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
Represents a particular font, including its size, style, etc.
Definition juce_Font.h:42
A graphics context, used for drawing a component or image.
bool clipRegionIntersects(Rectangle< int > area) const
Checks whether a rectangle overlaps the context's clipping region.
Represents a type of justification to be used when positioning graphical items.
A general-purpose range object, that simply represents any linear range with a start and end point.
Definition juce_Range.h:40
Manages a rectangle and allows geometric operations to be performed on it.
Rectangle< int > getSmallestIntegerContainer() const noexcept
Returns the smallest integer-aligned rectangle that completely contains this one.
ValueType getWidth() const noexcept
Returns the width of the rectangle.
The JUCE String class!
Definition juce_String.h:53
A Pre-formatted piece of text, which may contain multiple fonts and colours.
void draw(Graphics &, Rectangle< float > area) const
Draws the layout within the specified area.
void createLayout(const AttributedString &, float maxWidth)
Creates a layout from the given attributed string.
#define jassert(expression)
Platform-independent assertion macro.
JUCE Namespace.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
T next(T... args)
T prev(T... args)
truncate