Add remaining files
[juce-lv2.git] / juce / source / src / gui / graphics / fonts / juce_GlyphArrangement.h
blob197e68a04ea578475ec042f2f41d008f65f43ae4
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
27 #define __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
29 #include "juce_Font.h"
30 #include "../contexts/juce_Graphics.h"
33 //==============================================================================
34 /**
35 A glyph from a particular font, with a particular size, style,
36 typeface and position.
38 You should rarely need to use this class directly - for most purposes, the
39 GlyphArrangement class will do what you need for text layout.
41 @see GlyphArrangement, Font
43 class JUCE_API PositionedGlyph
45 public:
46 //==============================================================================
47 PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber,
48 float anchorX, float baselineY, float width, bool isWhitespace);
50 PositionedGlyph (const PositionedGlyph& other);
51 PositionedGlyph& operator= (const PositionedGlyph& other);
52 ~PositionedGlyph();
54 /** Returns the character the glyph represents. */
55 juce_wchar getCharacter() const noexcept { return character; }
56 /** Checks whether the glyph is actually empty. */
57 bool isWhitespace() const noexcept { return whitespace; }
59 /** Returns the position of the glyph's left-hand edge. */
60 float getLeft() const noexcept { return x; }
61 /** Returns the position of the glyph's right-hand edge. */
62 float getRight() const noexcept { return x + w; }
63 /** Returns the y position of the glyph's baseline. */
64 float getBaselineY() const noexcept { return y; }
65 /** Returns the y position of the top of the glyph. */
66 float getTop() const { return y - font.getAscent(); }
67 /** Returns the y position of the bottom of the glyph. */
68 float getBottom() const { return y + font.getDescent(); }
69 /** Returns the bounds of the glyph. */
70 const Rectangle<float> getBounds() const { return Rectangle<float> (x, getTop(), w, font.getHeight()); }
72 //==============================================================================
73 /** Shifts the glyph's position by a relative amount. */
74 void moveBy (float deltaX, float deltaY);
76 //==============================================================================
77 /** Draws the glyph into a graphics context. */
78 void draw (const Graphics& g) const;
80 /** Draws the glyph into a graphics context, with an extra transform applied to it. */
81 void draw (const Graphics& g, const AffineTransform& transform) const;
83 /** Returns the path for this glyph.
85 @param path the glyph's outline will be appended to this path
87 void createPath (Path& path) const;
89 /** Checks to see if a point lies within this glyph. */
90 bool hitTest (float x, float y) const;
92 private:
93 //==============================================================================
94 friend class GlyphArrangement;
95 Font font;
96 juce_wchar character;
97 int glyph;
98 float x, y, w;
99 bool whitespace;
101 JUCE_LEAK_DETECTOR (PositionedGlyph);
105 //==============================================================================
107 A set of glyphs, each with a position.
109 You can create a GlyphArrangement, text to it and then draw it onto a
110 graphics context. It's used internally by the text methods in the
111 Graphics class, but can be used directly if more control is needed.
113 @see Font, PositionedGlyph
115 class JUCE_API GlyphArrangement
117 public:
118 //==============================================================================
119 /** Creates an empty arrangement. */
120 GlyphArrangement();
122 /** Takes a copy of another arrangement. */
123 GlyphArrangement (const GlyphArrangement& other);
125 /** Copies another arrangement onto this one.
126 To add another arrangement without clearing this one, use addGlyphArrangement().
128 GlyphArrangement& operator= (const GlyphArrangement& other);
130 /** Destructor. */
131 ~GlyphArrangement();
133 //==============================================================================
134 /** Returns the total number of glyphs in the arrangement. */
135 int getNumGlyphs() const noexcept { return glyphs.size(); }
137 /** Returns one of the glyphs from the arrangement.
139 @param index the glyph's index, from 0 to (getNumGlyphs() - 1). Be
140 careful not to pass an out-of-range index here, as it
141 doesn't do any bounds-checking.
143 PositionedGlyph& getGlyph (int index) const;
145 //==============================================================================
146 /** Clears all text from the arrangement and resets it.
148 void clear();
150 /** Appends a line of text to the arrangement.
152 This will add the text as a single line, where x is the left-hand edge of the
153 first character, and y is the position for the text's baseline.
155 If the text contains new-lines or carriage-returns, this will ignore them - use
156 addJustifiedText() to add multi-line arrangements.
158 void addLineOfText (const Font& font,
159 const String& text,
160 float x, float y);
162 /** Adds a line of text, truncating it if it's wider than a specified size.
164 This is the same as addLineOfText(), but if the line's width exceeds the value
165 specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."),
166 if useEllipsis is true, or if this is false, it will just drop any subsequent characters.
168 void addCurtailedLineOfText (const Font& font,
169 const String& text,
170 float x, float y,
171 float maxWidthPixels,
172 bool useEllipsis);
174 /** Adds some multi-line text, breaking lines at word-boundaries if they are too wide.
176 This will add text to the arrangement, breaking it into new lines either where there
177 is a new-line or carriage-return character in the text, or where a line's width
178 exceeds the value set in maxLineWidth.
180 Each line that is added will be laid out using the flags set in horizontalLayout, so
181 the lines can be left- or right-justified, or centred horizontally in the space
182 between x and (x + maxLineWidth).
184 The y co-ordinate is the position of the baseline of the first line of text - subsequent
185 lines will be placed below it, separated by a distance of font.getHeight().
187 void addJustifiedText (const Font& font,
188 const String& text,
189 float x, float y,
190 float maxLineWidth,
191 const Justification& horizontalLayout);
193 /** Tries to fit some text withing a given space.
195 This does its best to make the given text readable within the specified rectangle,
196 so it useful for labelling things.
198 If the text is too big, it'll be squashed horizontally or broken over multiple lines
199 if the maximumLinesToUse value allows this. If the text just won't fit into the space,
200 it'll cram as much as possible in there, and put some ellipsis at the end to show that
201 it's been truncated.
203 A Justification parameter lets you specify how the text is laid out within the rectangle,
204 both horizontally and vertically.
206 @see Graphics::drawFittedText
208 void addFittedText (const Font& font,
209 const String& text,
210 float x, float y, float width, float height,
211 const Justification& layout,
212 int maximumLinesToUse,
213 float minimumHorizontalScale = 0.7f);
215 /** Appends another glyph arrangement to this one. */
216 void addGlyphArrangement (const GlyphArrangement& other);
218 /** Appends a custom glyph to the arrangement. */
219 void addGlyph (const PositionedGlyph& glyph);
221 //==============================================================================
222 /** Draws this glyph arrangement to a graphics context.
224 This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&)
225 method, which renders the glyphs as filled vectors.
227 void draw (const Graphics& g) const;
229 /** Draws this glyph arrangement to a graphics context.
231 This renders the paths as filled vectors, so is far slower than the draw (Graphics&)
232 method for non-transformed arrangements.
234 void draw (const Graphics& g, const AffineTransform& transform) const;
236 /** Converts the set of glyphs into a path.
238 @param path the glyphs' outlines will be appended to this path
240 void createPath (Path& path) const;
242 /** Looks for a glyph that contains the given co-ordinate.
244 @returns the index of the glyph, or -1 if none were found.
246 int findGlyphIndexAt (float x, float y) const;
248 //==============================================================================
249 /** Finds the smallest rectangle that will enclose a subset of the glyphs.
252 @param startIndex the first glyph to test
253 @param numGlyphs the number of glyphs to include; if this is < 0, all glyphs after
254 startIndex will be included
255 @param includeWhitespace if true, the extent of any whitespace characters will also
256 be taken into account
258 const Rectangle<float> getBoundingBox (int startIndex, int numGlyphs, bool includeWhitespace) const;
260 /** Shifts a set of glyphs by a given amount.
262 @param startIndex the first glyph to transform
263 @param numGlyphs the number of glyphs to move; if this is < 0, all glyphs after
264 startIndex will be used
265 @param deltaX the amount to add to their x-positions
266 @param deltaY the amount to add to their y-positions
268 void moveRangeOfGlyphs (int startIndex, int numGlyphs,
269 float deltaX, float deltaY);
271 /** Removes a set of glyphs from the arrangement.
273 @param startIndex the first glyph to remove
274 @param numGlyphs the number of glyphs to remove; if this is < 0, all glyphs after
275 startIndex will be deleted
277 void removeRangeOfGlyphs (int startIndex, int numGlyphs);
279 /** Expands or compresses a set of glyphs horizontally.
281 @param startIndex the first glyph to transform
282 @param numGlyphs the number of glyphs to stretch; if this is < 0, all glyphs after
283 startIndex will be used
284 @param horizontalScaleFactor how much to scale their horizontal width by
286 void stretchRangeOfGlyphs (int startIndex, int numGlyphs,
287 float horizontalScaleFactor);
289 /** Justifies a set of glyphs within a given space.
291 This moves the glyphs as a block so that the whole thing is located within the
292 given rectangle with the specified layout.
294 If the Justification::horizontallyJustified flag is specified, each line will
295 be stretched out to fill the specified width.
297 void justifyGlyphs (int startIndex, int numGlyphs,
298 float x, float y, float width, float height,
299 const Justification& justification);
302 private:
303 //==============================================================================
304 OwnedArray <PositionedGlyph> glyphs;
306 int insertEllipsis (const Font&, float maxXPos, int startIndex, int endIndex);
307 int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font&,
308 const Justification&, float minimumHorizontalScale);
309 void spreadOutLine (int start, int numGlyphs, float targetWidth);
311 JUCE_LEAK_DETECTOR (GlyphArrangement);
315 #endif // __JUCE_GLYPHARRANGEMENT_JUCEHEADER__