@@ -254,7 +254,7 @@ | |||
actually show it to the user in a list (why??)... Anyway, this macro lets you | |||
provide a sensible name for that class to make it clear what plugin it refers to. | |||
Obviously this has to be a valid obj-C class name. | |||
Just to make things a little more complicated, this name must also be unique to this | |||
precise version of your software. Otherwise, if the host loads two plugins that use the | |||
same class name, the obj-C linker will almost certainly connect the wrong modules together | |||
@@ -553,7 +553,6 @@ | |||
}; | |||
C0E91ACA08A95435008D54AB /* Debug */ = { | |||
isa = XCBuildConfiguration; | |||
baseConfigurationReference = 846929130A49DB9C00314975 /* juce.xcconfig */; | |||
buildSettings = { | |||
GCC_VERSION = 4.0; | |||
GCC_WARN_ABOUT_RETURN_TYPE = YES; | |||
@@ -565,7 +564,6 @@ | |||
}; | |||
C0E91ACB08A95435008D54AB /* Release */ = { | |||
isa = XCBuildConfiguration; | |||
baseConfigurationReference = 846929130A49DB9C00314975 /* juce.xcconfig */; | |||
buildSettings = { | |||
GCC_VERSION = 4.0; | |||
GCC_WARN_ABOUT_RETURN_TYPE = YES; | |||
@@ -86677,7 +86677,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||
{ | |||
// curtail the string if it's too wide.. | |||
if (useEllipsis && textLen > 3 && glyphs.size() >= 3) | |||
appendEllipsis (font, xOffset + maxWidthPixels); | |||
insertEllipsis (font, xOffset + maxWidthPixels, 0, glyphs.size()); | |||
break; | |||
} | |||
@@ -86697,8 +86697,11 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||
} | |||
} | |||
void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) throw() | |||
int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, | |||
const int startIndex, int endIndex) throw() | |||
{ | |||
int numDeleted = 0; | |||
if (glyphs.size() > 0) | |||
{ | |||
Array<int> dotGlyphs; | |||
@@ -86708,15 +86711,16 @@ void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) | |||
const float dx = dotXs[1]; | |||
float xOffset = 0.0f, yOffset = 0.0f; | |||
for (int dotPos = 3; --dotPos >= 0 && glyphs.size() > 0;) | |||
while (endIndex > startIndex) | |||
{ | |||
const PositionedGlyph* pg = glyphs.getUnchecked (glyphs.size() - 1); | |||
const PositionedGlyph* pg = glyphs.getUnchecked (--endIndex); | |||
xOffset = pg->x; | |||
yOffset = pg->y; | |||
glyphs.removeLast(); | |||
glyphs.remove (endIndex); | |||
++numDeleted; | |||
if (xOffset + dx * 3 <= maxXPixels) | |||
if (xOffset + dx * 3 <= maxXPos) | |||
break; | |||
} | |||
@@ -86729,11 +86733,17 @@ void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) | |||
pg->font = font; | |||
pg->character = '.'; | |||
pg->glyph = dotGlyphs.getFirst(); | |||
glyphs.add (pg); | |||
glyphs.insert (endIndex++, pg); | |||
--numDeleted; | |||
xOffset += dx; | |||
if (xOffset > maxXPos) | |||
break; | |||
} | |||
} | |||
return numDeleted; | |||
} | |||
void GlyphArrangement::addJustifiedText (const Font& font, | |||
@@ -86820,8 +86830,8 @@ void GlyphArrangement::addJustifiedText (const Font& font, | |||
void GlyphArrangement::addFittedText (const Font& f, | |||
const String& text, | |||
float x, float y, | |||
float width, float height, | |||
const float x, const float y, | |||
const float width, const float height, | |||
const Justification& layout, | |||
int maximumLines, | |||
const float minimumHorizontalScale) throw() | |||
@@ -86869,37 +86879,24 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
if (lineWidth * minimumHorizontalScale < width) | |||
{ | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (startIndex, glyphs.size() - startIndex, | |||
width / lineWidth); | |||
} | |||
justifyGlyphs (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, layout); | |||
} | |||
else if (maximumLines <= 1) | |||
{ | |||
const float ratio = jmax (minimumHorizontalScale, width / lineWidth); | |||
stretchRangeOfGlyphs (startIndex, glyphs.size() - startIndex, ratio); | |||
while (glyphs.size() > 0 && glyphs.getUnchecked (glyphs.size() - 1)->getRight() >= x + width) | |||
glyphs.removeLast(); | |||
appendEllipsis (f, x + width); | |||
justifyGlyphs (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, layout); | |||
fitLineIntoSpace (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, f, layout, minimumHorizontalScale); | |||
} | |||
else | |||
{ | |||
Font font (f); | |||
String txt (text.trim()); | |||
const int length = txt.length(); | |||
int numLines = 1; | |||
const int originalStartIndex = startIndex; | |||
int numLines = 1; | |||
if (length <= 12 && ! txt.containsAnyOf (T(" -\t\r\n"))) | |||
maximumLines = 1; | |||
@@ -86912,23 +86909,18 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
const float newFontHeight = height / (float) numLines; | |||
if (newFontHeight < 8.0f) | |||
break; | |||
if (newFontHeight < font.getHeight()) | |||
{ | |||
font.setHeight (newFontHeight); | |||
while (glyphs.size() > startIndex) | |||
glyphs.removeLast(); | |||
font.setHeight (jmax (8.0f, newFontHeight)); | |||
removeRangeOfGlyphs (startIndex, -1); | |||
addLineOfText (font, txt, x, y); | |||
lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() | |||
- glyphs.getUnchecked (startIndex)->getLeft(); | |||
} | |||
if (numLines > lineWidth / width) | |||
if (numLines > lineWidth / width || newFontHeight < 8.0f) | |||
break; | |||
} | |||
@@ -86945,77 +86937,78 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
lastLineStartIndex = i; | |||
float lineStartX = glyphs.getUnchecked (startIndex)->getLeft(); | |||
while (i < glyphs.size()) | |||
if (line == numLines - 1) | |||
{ | |||
lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); | |||
if (lineWidth > widthPerLine) | |||
widthPerLine = width; | |||
i = glyphs.size(); | |||
} | |||
else | |||
{ | |||
while (i < glyphs.size()) | |||
{ | |||
// got to a point where the line's too long, so skip forward to find a | |||
// good place to break it.. | |||
const int searchStartIndex = i; | |||
lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); | |||
while (i < glyphs.size()) | |||
if (lineWidth > widthPerLine) | |||
{ | |||
if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) | |||
// got to a point where the line's too long, so skip forward to find a | |||
// good place to break it.. | |||
const int searchStartIndex = i; | |||
while (i < glyphs.size()) | |||
{ | |||
if (glyphs.getUnchecked (i)->isWhitespace() | |||
|| glyphs.getUnchecked (i)->getCharacter() == T('-')) | |||
if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) | |||
{ | |||
++i; | |||
break; | |||
if (glyphs.getUnchecked (i)->isWhitespace() | |||
|| glyphs.getUnchecked (i)->getCharacter() == T('-')) | |||
{ | |||
++i; | |||
break; | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// can't find a suitable break, so try looking backwards.. | |||
i = searchStartIndex; | |||
for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) | |||
else | |||
{ | |||
if (glyphs.getUnchecked (i - back)->isWhitespace() | |||
|| glyphs.getUnchecked (i - back)->getCharacter() == T('-')) | |||
// can't find a suitable break, so try looking backwards.. | |||
i = searchStartIndex; | |||
for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) | |||
{ | |||
i -= back - 1; | |||
break; | |||
if (glyphs.getUnchecked (i - back)->isWhitespace() | |||
|| glyphs.getUnchecked (i - back)->getCharacter() == T('-')) | |||
{ | |||
i -= back - 1; | |||
break; | |||
} | |||
} | |||
break; | |||
} | |||
break; | |||
++i; | |||
} | |||
++i; | |||
break; | |||
} | |||
break; | |||
++i; | |||
} | |||
++i; | |||
} | |||
int wsStart = i; | |||
while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) | |||
--wsStart; | |||
int wsEnd = i; | |||
while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) | |||
++wsEnd; | |||
int wsStart = i; | |||
while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) | |||
--wsStart; | |||
removeRangeOfGlyphs (wsStart, wsEnd - wsStart); | |||
i = jmax (wsStart, startIndex + 1); | |||
int wsEnd = i; | |||
lineWidth = glyphs.getUnchecked (i - 1)->getRight() - lineStartX; | |||
while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) | |||
++wsEnd; | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (startIndex, i - startIndex, | |||
width / lineWidth); | |||
removeRangeOfGlyphs (wsStart, wsEnd - wsStart); | |||
i = jmax (wsStart, startIndex + 1); | |||
} | |||
justifyGlyphs (startIndex, i - startIndex, | |||
x, lineY, width, font.getHeight(), | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred); | |||
i -= fitLineIntoSpace (startIndex, i - startIndex, | |||
x, lineY, width, font.getHeight(), font, | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred, | |||
minimumHorizontalScale); | |||
startIndex = i; | |||
lineY += font.getHeight(); | |||
@@ -87024,32 +87017,7 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
break; | |||
} | |||
if (startIndex < glyphs.size()) | |||
{ | |||
removeRangeOfGlyphs (startIndex, -1); | |||
if (startIndex - originalStartIndex > 4) | |||
{ | |||
const float lineStartX = glyphs.getUnchecked (lastLineStartIndex)->getLeft(); | |||
appendEllipsis (font, lineStartX + width); | |||
lineWidth = glyphs.getUnchecked (startIndex - 1)->getRight() - lineStartX; | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex, | |||
width / lineWidth); | |||
} | |||
justifyGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex, | |||
x, lineY - font.getHeight(), width, font.getHeight(), | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred); | |||
} | |||
startIndex = glyphs.size(); | |||
} | |||
justifyGlyphs (originalStartIndex, startIndex - originalStartIndex, | |||
justifyGlyphs (originalStartIndex, glyphs.size() - originalStartIndex, | |||
x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified); | |||
} | |||
} | |||
@@ -87070,6 +87038,32 @@ void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, | |||
} | |||
} | |||
int GlyphArrangement::fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, | |||
const Justification& justification, float minimumHorizontalScale) throw() | |||
{ | |||
int numDeleted = 0; | |||
const float lineStartX = glyphs.getUnchecked (start)->getLeft(); | |||
float lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX; | |||
if (lineWidth > w) | |||
{ | |||
if (minimumHorizontalScale < 1.0f) | |||
{ | |||
stretchRangeOfGlyphs (start, numGlyphs, jmax (minimumHorizontalScale, w / lineWidth)); | |||
lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX - 0.5f; | |||
} | |||
if (lineWidth > w) | |||
{ | |||
numDeleted = insertEllipsis (font, lineStartX + w, start, start + numGlyphs); | |||
numGlyphs -= numDeleted; | |||
} | |||
} | |||
justifyGlyphs (start, numGlyphs, x, y, w, h, justification); | |||
return numDeleted; | |||
} | |||
void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num, | |||
const float horizontalScaleFactor) throw() | |||
{ | |||
@@ -262822,6 +262816,7 @@ public: | |||
{ | |||
CGContextRetain (context); | |||
CGContextSetShouldSmoothFonts (context, true); | |||
CGContextSetShouldAntialias (context, true); | |||
CGContextSetBlendMode (context, kCGBlendModeNormal); | |||
rgbColourSpace = CGColorSpaceCreateDeviceRGB(); | |||
greyColourSpace = CGColorSpaceCreateDeviceGray(); | |||
@@ -267250,6 +267245,7 @@ public: | |||
{ | |||
CGContextRetain (context); | |||
CGContextSetShouldSmoothFonts (context, true); | |||
CGContextSetShouldAntialias (context, true); | |||
CGContextSetBlendMode (context, kCGBlendModeNormal); | |||
rgbColourSpace = CGColorSpaceCreateDeviceRGB(); | |||
greyColourSpace = CGColorSpaceCreateDeviceGray(); | |||
@@ -271718,7 +271714,13 @@ public: | |||
{ | |||
StringArray files; | |||
for (unsigned int i = 0; i < [filenames count]; ++i) | |||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
{ | |||
String filename (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
if (filename.containsChar (T(' '))) | |||
filename = filename.quoted('"'); | |||
files.add (filename); | |||
} | |||
if (files.size() > 0 && JUCEApplication::getInstance() != 0) | |||
{ | |||
@@ -39734,8 +39734,8 @@ public: | |||
*/ | |||
void addFittedText (const Font& font, | |||
const String& text, | |||
float x, float y, | |||
float width, float height, | |||
const float x, const float y, | |||
const float width, const float height, | |||
const Justification& layout, | |||
int maximumLinesToUse, | |||
const float minimumHorizontalScale = 0.7f) throw(); | |||
@@ -39839,7 +39839,9 @@ public: | |||
private: | |||
OwnedArray <PositionedGlyph> glyphs; | |||
void appendEllipsis (const Font& font, const float maxXPixels) throw(); | |||
int insertEllipsis (const Font& font, const float maxXPos, const int startIndex, int endIndex) throw(); | |||
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, | |||
const Justification& justification, float minimumHorizontalScale) throw(); | |||
void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw(); | |||
}; | |||
@@ -200,7 +200,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||
{ | |||
// curtail the string if it's too wide.. | |||
if (useEllipsis && textLen > 3 && glyphs.size() >= 3) | |||
appendEllipsis (font, xOffset + maxWidthPixels); | |||
insertEllipsis (font, xOffset + maxWidthPixels, 0, glyphs.size()); | |||
break; | |||
} | |||
@@ -220,8 +220,11 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||
} | |||
} | |||
void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) throw() | |||
int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, | |||
const int startIndex, int endIndex) throw() | |||
{ | |||
int numDeleted = 0; | |||
if (glyphs.size() > 0) | |||
{ | |||
Array<int> dotGlyphs; | |||
@@ -231,15 +234,16 @@ void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) | |||
const float dx = dotXs[1]; | |||
float xOffset = 0.0f, yOffset = 0.0f; | |||
for (int dotPos = 3; --dotPos >= 0 && glyphs.size() > 0;) | |||
while (endIndex > startIndex) | |||
{ | |||
const PositionedGlyph* pg = glyphs.getUnchecked (glyphs.size() - 1); | |||
const PositionedGlyph* pg = glyphs.getUnchecked (--endIndex); | |||
xOffset = pg->x; | |||
yOffset = pg->y; | |||
glyphs.removeLast(); | |||
glyphs.remove (endIndex); | |||
++numDeleted; | |||
if (xOffset + dx * 3 <= maxXPixels) | |||
if (xOffset + dx * 3 <= maxXPos) | |||
break; | |||
} | |||
@@ -252,11 +256,17 @@ void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) | |||
pg->font = font; | |||
pg->character = '.'; | |||
pg->glyph = dotGlyphs.getFirst(); | |||
glyphs.add (pg); | |||
glyphs.insert (endIndex++, pg); | |||
--numDeleted; | |||
xOffset += dx; | |||
if (xOffset > maxXPos) | |||
break; | |||
} | |||
} | |||
return numDeleted; | |||
} | |||
void GlyphArrangement::addJustifiedText (const Font& font, | |||
@@ -343,8 +353,8 @@ void GlyphArrangement::addJustifiedText (const Font& font, | |||
void GlyphArrangement::addFittedText (const Font& f, | |||
const String& text, | |||
float x, float y, | |||
float width, float height, | |||
const float x, const float y, | |||
const float width, const float height, | |||
const Justification& layout, | |||
int maximumLines, | |||
const float minimumHorizontalScale) throw() | |||
@@ -392,37 +402,24 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
if (lineWidth * minimumHorizontalScale < width) | |||
{ | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (startIndex, glyphs.size() - startIndex, | |||
width / lineWidth); | |||
} | |||
justifyGlyphs (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, layout); | |||
} | |||
else if (maximumLines <= 1) | |||
{ | |||
const float ratio = jmax (minimumHorizontalScale, width / lineWidth); | |||
stretchRangeOfGlyphs (startIndex, glyphs.size() - startIndex, ratio); | |||
while (glyphs.size() > 0 && glyphs.getUnchecked (glyphs.size() - 1)->getRight() >= x + width) | |||
glyphs.removeLast(); | |||
appendEllipsis (f, x + width); | |||
justifyGlyphs (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, layout); | |||
fitLineIntoSpace (startIndex, glyphs.size() - startIndex, | |||
x, y, width, height, f, layout, minimumHorizontalScale); | |||
} | |||
else | |||
{ | |||
Font font (f); | |||
String txt (text.trim()); | |||
const int length = txt.length(); | |||
int numLines = 1; | |||
const int originalStartIndex = startIndex; | |||
int numLines = 1; | |||
if (length <= 12 && ! txt.containsAnyOf (T(" -\t\r\n"))) | |||
maximumLines = 1; | |||
@@ -435,23 +432,18 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
const float newFontHeight = height / (float) numLines; | |||
if (newFontHeight < 8.0f) | |||
break; | |||
if (newFontHeight < font.getHeight()) | |||
{ | |||
font.setHeight (newFontHeight); | |||
while (glyphs.size() > startIndex) | |||
glyphs.removeLast(); | |||
font.setHeight (jmax (8.0f, newFontHeight)); | |||
removeRangeOfGlyphs (startIndex, -1); | |||
addLineOfText (font, txt, x, y); | |||
lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() | |||
- glyphs.getUnchecked (startIndex)->getLeft(); | |||
} | |||
if (numLines > lineWidth / width) | |||
if (numLines > lineWidth / width || newFontHeight < 8.0f) | |||
break; | |||
} | |||
@@ -468,77 +460,78 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
lastLineStartIndex = i; | |||
float lineStartX = glyphs.getUnchecked (startIndex)->getLeft(); | |||
while (i < glyphs.size()) | |||
if (line == numLines - 1) | |||
{ | |||
lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); | |||
if (lineWidth > widthPerLine) | |||
widthPerLine = width; | |||
i = glyphs.size(); | |||
} | |||
else | |||
{ | |||
while (i < glyphs.size()) | |||
{ | |||
// got to a point where the line's too long, so skip forward to find a | |||
// good place to break it.. | |||
const int searchStartIndex = i; | |||
lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); | |||
while (i < glyphs.size()) | |||
if (lineWidth > widthPerLine) | |||
{ | |||
if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) | |||
// got to a point where the line's too long, so skip forward to find a | |||
// good place to break it.. | |||
const int searchStartIndex = i; | |||
while (i < glyphs.size()) | |||
{ | |||
if (glyphs.getUnchecked (i)->isWhitespace() | |||
|| glyphs.getUnchecked (i)->getCharacter() == T('-')) | |||
if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) | |||
{ | |||
++i; | |||
break; | |||
if (glyphs.getUnchecked (i)->isWhitespace() | |||
|| glyphs.getUnchecked (i)->getCharacter() == T('-')) | |||
{ | |||
++i; | |||
break; | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// can't find a suitable break, so try looking backwards.. | |||
i = searchStartIndex; | |||
for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) | |||
else | |||
{ | |||
if (glyphs.getUnchecked (i - back)->isWhitespace() | |||
|| glyphs.getUnchecked (i - back)->getCharacter() == T('-')) | |||
// can't find a suitable break, so try looking backwards.. | |||
i = searchStartIndex; | |||
for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) | |||
{ | |||
i -= back - 1; | |||
break; | |||
if (glyphs.getUnchecked (i - back)->isWhitespace() | |||
|| glyphs.getUnchecked (i - back)->getCharacter() == T('-')) | |||
{ | |||
i -= back - 1; | |||
break; | |||
} | |||
} | |||
break; | |||
} | |||
break; | |||
++i; | |||
} | |||
++i; | |||
break; | |||
} | |||
break; | |||
++i; | |||
} | |||
++i; | |||
} | |||
int wsStart = i; | |||
while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) | |||
--wsStart; | |||
int wsStart = i; | |||
while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) | |||
--wsStart; | |||
int wsEnd = i; | |||
int wsEnd = i; | |||
while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) | |||
++wsEnd; | |||
while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) | |||
++wsEnd; | |||
removeRangeOfGlyphs (wsStart, wsEnd - wsStart); | |||
i = jmax (wsStart, startIndex + 1); | |||
lineWidth = glyphs.getUnchecked (i - 1)->getRight() - lineStartX; | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (startIndex, i - startIndex, | |||
width / lineWidth); | |||
removeRangeOfGlyphs (wsStart, wsEnd - wsStart); | |||
i = jmax (wsStart, startIndex + 1); | |||
} | |||
justifyGlyphs (startIndex, i - startIndex, | |||
x, lineY, width, font.getHeight(), | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred); | |||
i -= fitLineIntoSpace (startIndex, i - startIndex, | |||
x, lineY, width, font.getHeight(), font, | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred, | |||
minimumHorizontalScale); | |||
startIndex = i; | |||
lineY += font.getHeight(); | |||
@@ -547,32 +540,7 @@ void GlyphArrangement::addFittedText (const Font& f, | |||
break; | |||
} | |||
if (startIndex < glyphs.size()) | |||
{ | |||
removeRangeOfGlyphs (startIndex, -1); | |||
if (startIndex - originalStartIndex > 4) | |||
{ | |||
const float lineStartX = glyphs.getUnchecked (lastLineStartIndex)->getLeft(); | |||
appendEllipsis (font, lineStartX + width); | |||
lineWidth = glyphs.getUnchecked (startIndex - 1)->getRight() - lineStartX; | |||
if (lineWidth > width) | |||
{ | |||
stretchRangeOfGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex, | |||
width / lineWidth); | |||
} | |||
justifyGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex, | |||
x, lineY - font.getHeight(), width, font.getHeight(), | |||
layout.getOnlyHorizontalFlags() | Justification::verticallyCentred); | |||
} | |||
startIndex = glyphs.size(); | |||
} | |||
justifyGlyphs (originalStartIndex, startIndex - originalStartIndex, | |||
justifyGlyphs (originalStartIndex, glyphs.size() - originalStartIndex, | |||
x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified); | |||
} | |||
} | |||
@@ -594,6 +562,32 @@ void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, | |||
} | |||
} | |||
int GlyphArrangement::fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, | |||
const Justification& justification, float minimumHorizontalScale) throw() | |||
{ | |||
int numDeleted = 0; | |||
const float lineStartX = glyphs.getUnchecked (start)->getLeft(); | |||
float lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX; | |||
if (lineWidth > w) | |||
{ | |||
if (minimumHorizontalScale < 1.0f) | |||
{ | |||
stretchRangeOfGlyphs (start, numGlyphs, jmax (minimumHorizontalScale, w / lineWidth)); | |||
lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX - 0.5f; | |||
} | |||
if (lineWidth > w) | |||
{ | |||
numDeleted = insertEllipsis (font, lineStartX + w, start, start + numGlyphs); | |||
numGlyphs -= numDeleted; | |||
} | |||
} | |||
justifyGlyphs (start, numGlyphs, x, y, w, h, justification); | |||
return numDeleted; | |||
} | |||
void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num, | |||
const float horizontalScaleFactor) throw() | |||
{ | |||
@@ -201,8 +201,8 @@ public: | |||
*/ | |||
void addFittedText (const Font& font, | |||
const String& text, | |||
float x, float y, | |||
float width, float height, | |||
const float x, const float y, | |||
const float width, const float height, | |||
const Justification& layout, | |||
int maximumLinesToUse, | |||
const float minimumHorizontalScale = 0.7f) throw(); | |||
@@ -312,7 +312,9 @@ public: | |||
private: | |||
OwnedArray <PositionedGlyph> glyphs; | |||
void appendEllipsis (const Font& font, const float maxXPixels) throw(); | |||
int insertEllipsis (const Font& font, const float maxXPos, const int startIndex, int endIndex) throw(); | |||
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, | |||
const Justification& justification, float minimumHorizontalScale) throw(); | |||
void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw(); | |||
}; | |||
@@ -73,6 +73,7 @@ public: | |||
{ | |||
CGContextRetain (context); | |||
CGContextSetShouldSmoothFonts (context, true); | |||
CGContextSetShouldAntialias (context, true); | |||
CGContextSetBlendMode (context, kCGBlendModeNormal); | |||
rgbColourSpace = CGColorSpaceCreateDeviceRGB(); | |||
greyColourSpace = CGColorSpaceCreateDeviceGray(); | |||
@@ -105,7 +105,13 @@ public: | |||
{ | |||
StringArray files; | |||
for (unsigned int i = 0; i < [filenames count]; ++i) | |||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
{ | |||
String filename (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
if (filename.containsChar (T(' '))) | |||
filename = filename.quoted('"'); | |||
files.add (filename); | |||
} | |||
if (files.size() > 0 && JUCEApplication::getInstance() != 0) | |||
{ | |||