1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-02 03:20:06 +00:00

Improvements to path rendering and fix for PathStrokeType generating incorrect paths for some shapes. Added OSX10.4 compatibility for new new typeface classes.

This commit is contained in:
Julian Storer 2009-11-10 17:45:06 +00:00
parent dc83bf01e1
commit ca727ec2bb
12 changed files with 795 additions and 355 deletions

View file

@ -78825,13 +78825,121 @@ BEGIN_JUCE_NAMESPACE
const int juce_edgeTableDefaultEdgesPerLine = 32;
EdgeTable::EdgeTable (const int top_, const int height_) throw()
EdgeTable::EdgeTable (const int top_, const int height_,
const Path& path, const AffineTransform& transform) throw()
: top (top_),
height (height_),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
table = (int*) juce_calloc (height * lineStrideElements * sizeof (int));
table = (int*) juce_malloc (height_ * lineStrideElements * sizeof (int));
int* t = table;
for (int i = height_; --i >= 0;)
{
*t = 0;
t += lineStrideElements;
}
const int topLimit = top << 8;
const int bottomLimit = height << 8;
PathFlatteningIterator iter (path, transform);
while (iter.next())
{
int y1 = roundFloatToInt (iter.y1 * 256.0f);
int y2 = roundFloatToInt (iter.y2 * 256.0f);
if (y1 != y2)
{
y1 -= topLimit;
y2 -= topLimit;
const double startX = 256.0f * iter.x1;
const int startY = y1;
const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
int winding = -1;
if (y1 > y2)
{
swapVariables (y1, y2);
winding = 1;
}
if (y1 < 0)
y1 = 0;
if (y2 > bottomLimit)
y2 = bottomLimit;
const int stepSize = jlimit (1, 256, 256 / (1 + (int) fabs (multiplier)));
while (y1 < y2)
{
const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
addEdgePoint (roundDoubleToInt (startX + multiplier * (y1 - startY)),
y1 >> 8, winding * step);
y1 += step;
}
}
}
if (! path.isUsingNonZeroWinding())
{
int* lineStart = table;
for (int i = height; --i >= 0;)
{
int* line = lineStart;
lineStart += lineStrideElements;
int num = *line;
int level = 0;
int lastCorrected = 0;
while (--num >= 0)
{
line += 2;
level += *line;
int corrected = abs (level);
if (corrected >> 8)
{
corrected &= 511;
if (corrected >> 8)
corrected = 511 - corrected;
}
*line = corrected - lastCorrected;
lastCorrected = corrected;
}
}
}
}
EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw()
: top (rectangleToAdd.getY()),
height (jmax (1, rectangleToAdd.getHeight())),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1)
{
jassert (! rectangleToAdd.isEmpty());
table = (int*) juce_malloc (height * lineStrideElements * sizeof (int));
*table = 0;
const int x1 = rectangleToAdd.getX();
const int x2 = rectangleToAdd.getRight();
int* t = table;
for (int i = rectangleToAdd.getHeight(); --i >= 0;)
{
t[0] = 2;
t[1] = x1;
t[2] = 256;
t[3] = x2;
t[4] = -256;
t += lineStrideElements;
}
}
EdgeTable::EdgeTable (const EdgeTable& other) throw()
@ -78936,94 +79044,47 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw
lineStart[0]++;
}
void EdgeTable::addPath (const Path& path, const AffineTransform& transform) throw()
void EdgeTable::clearLineSection (const int y, int minX, int maxX) throw()
{
const int bottomLimit = height << 8;
// int* line = table + lineStrideElements * y;
PathFlatteningIterator iter (path, transform);
}
while (iter.next())
void EdgeTable::clipToRectangle (const Rectangle& r) throw()
{
const int rectTop = jmax (0, r.getY() - top);
const int rectBottom = jmin (height, r.getBottom() - top);
for (int i = rectTop - 1; --i >= 0;)
table [lineStrideElements * i] = 0;
for (int i = rectBottom; i < height; ++i)
table [lineStrideElements * i] = 0;
for (int i = rectTop; i < rectBottom; ++i)
{
int y1 = roundFloatToInt (iter.y1 * 256.0f) - (top << 8);
int y2 = roundFloatToInt (iter.y2 * 256.0f) - (top << 8);
if (y1 != y2)
{
const int oldY1 = y1;
const double x1 = 256.0 * iter.x1;
const double x2 = 256.0 * iter.x2;
const double multiplier = (x2 - x1) / (y2 - y1);
int winding = -1;
if (y1 > y2)
{
swapVariables (y1, y2);
winding = 1;
}
if (y1 < 0)
y1 = 0;
if (y2 > bottomLimit)
y2 = bottomLimit;
const int stepSize = jlimit (1, 256, 256 / (1 + abs ((int) multiplier)));
while (y1 < y2)
{
const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
addEdgePoint (roundDoubleToInt (x1 + multiplier * (y1 - oldY1)),
y1 >> 8, winding * step);
y1 += step;
}
}
}
if (! path.isUsingNonZeroWinding())
{
int* lineStart = table;
for (int i = height; --i >= 0;)
{
int* line = lineStart;
lineStart += lineStrideElements;
int num = *line;
int level = 0;
int lastCorrected = 0;
while (--num >= 0)
{
line += 2;
level += *line;
int corrected = abs (level);
if (corrected >> 8)
{
corrected &= 511;
if (corrected >> 8)
corrected = 511 - corrected;
}
*line = corrected - lastCorrected;
lastCorrected = corrected;
}
}
clearLineSection (i, -INT_MAX, r.getX());
clearLineSection (i, r.getRight(), INT_MAX);
}
}
/*void EdgeTable::clipToRectangle (const Rectangle& r) throw()
void EdgeTable::excludeRectangle (const Rectangle& r) throw()
{
const int rectTop = jmax (0, r.getY() - top);
const int rectBottom = jmin (height, r.getBottom() - top);
for (int i = rectTop; i < rectBottom; ++i)
clearLineSection (i, r.getX(), r.getRight());
}
void EdgeTable::clipToEdgeTable (const EdgeTable& other)
{
}
void EdgeTable::intersectWith (const EdgeTable& other)
void EdgeTable::clipToImageAlpha (Image& image, int x, int y) throw()
{
}
void EdgeTable::generateFromImageAlpha (Image& image, int x, int y) throw()
{
}*/
END_JUCE_NAMESPACE
/********* End of inlined file: juce_EdgeTable.cpp *********/
@ -81995,8 +82056,7 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPath (int clipX, int clipY, in
if (getPathBounds (clipX, clipY, clipW, clipH, path, transform, cx, cy, cw, ch))
{
EdgeTable edgeTable (0, ch);
edgeTable.addPath (path, transform.translated ((float) -cx, (float) -cy));
EdgeTable edgeTable (0, ch, path, transform.translated ((float) -cx, (float) -cy));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (cx, cy, cw, ch, stride, pixelStride);
@ -82123,8 +82183,7 @@ void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, i
{
if (Rectangle::intersectRectangles (x, y, w, h, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight()))
{
EdgeTable edgeTable (0, h);
edgeTable.addPath (path, transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
EdgeTable edgeTable (0, h, path, transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
int stride, pixelStride;
uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
@ -85928,17 +85987,21 @@ void Font::getGlyphPositions (const String& text, Array <int>& glyphs, Array <fl
const float scale = font->height * font->horizontalScale;
const int num = xOffsets.size();
float* const x = &(xOffsets.getReference(0));
if (font->kerning != 0)
if (num > 0)
{
for (int i = 0; i < num; ++i)
x[i] = (x[i] + i * font->kerning) * scale;
}
else
{
for (int i = 0; i < num; ++i)
x[i] *= scale;
float* const x = &(xOffsets.getReference(0));
if (font->kerning != 0)
{
for (int i = 0; i < num; ++i)
x[i] = (x[i] + i * font->kerning) * scale;
}
else
{
for (int i = 0; i < num; ++i)
x[i] *= scale;
}
}
}
@ -86069,7 +86132,7 @@ public:
g.fillAlphaChannel (*bitmap [bitmapToUse],
xOrigin [bitmapToUse] + (int) xFloor,
yOrigin [bitmapToUse] + (int) floorf (y));
yOrigin [bitmapToUse] + roundFloatToInt(y));
}
}
@ -89983,8 +90046,8 @@ Image* Path::createMaskBitmap (const AffineTransform& transform,
Image* im = new Image (Image::SingleChannel, imagePosition.getWidth(), imagePosition.getHeight(), true);
EdgeTable edgeTable (0, imagePosition.getHeight());
edgeTable.addPath (*this, transform.translated (-imagePosition.getX(), -imagePosition.getY()));
EdgeTable edgeTable (0, imagePosition.getHeight(), *this,
transform.translated (-imagePosition.getX(), -imagePosition.getY()));
int stride, pixelStride;
uint8* const pixels = (uint8*) im->lockPixelDataReadWrite (0, 0, imagePosition.getWidth(), imagePosition.getHeight(), stride, pixelStride);
@ -90473,20 +90536,47 @@ static void addEdgeAndJoint (Path& destPath,
else
{
// curved joints
float angle = atan2f (x2 - midX, y2 - midY);
float angle1 = atan2f (x2 - midX, y2 - midY);
float angle2 = atan2f (x3 - midX, y3 - midY);
while (angle < angle2 - 0.01f)
angle2 -= float_Pi * 2.0f;
const float angleIncrement = 0.1f;
destPath.lineTo (x2, y2);
while (angle > angle2)
if (fabs (angle1 - angle2) > angleIncrement)
{
destPath.lineTo (midX + width * sinf (angle),
midY + width * cosf (angle));
if (angle2 > angle1 + float_Pi
|| (angle2 < angle1 && angle2 >= angle1 - float_Pi))
{
if (angle2 > angle1)
angle2 -= float_Pi * 2.0f;
angle -= 0.1f;
jassert (angle1 <= angle2 + float_Pi);
angle1 -= angleIncrement;
while (angle1 > angle2)
{
destPath.lineTo (midX + width * sinf (angle1),
midY + width * cosf (angle1));
angle1 -= angleIncrement;
}
}
else
{
if (angle1 > angle2)
angle1 -= float_Pi * 2.0f;
jassert (angle1 >= angle2 - float_Pi);
angle1 += angleIncrement;
while (angle1 < angle2)
{
destPath.lineTo (midX + width * sinf (angle1),
midY + width * cosf (angle1));
angle1 += angleIncrement;
}
}
}
destPath.lineTo (x3, y3);
@ -261922,6 +262012,17 @@ bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
// compiled on its own).
#if JUCE_INCLUDED_FILE
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define SUPPORT_10_4_FONTS 1
#define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0)
END_JUCE_NAMESPACE
@interface NSFont (PrivateHack)
- (NSGlyph) _defaultGlyphForChar: (unichar) theChar;
@end
BEGIN_JUCE_NAMESPACE
#endif
class MacTypeface : public Typeface
{
public:
@ -261973,6 +262074,9 @@ public:
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
#else
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
@ -262004,18 +262108,40 @@ public:
renderingTransform.c = 0.15f;
}
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
#endif
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
if (atsFont == 0)
atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
fontRef = CGFontCreateWithPlatformFont ((void*) &atsFont);
const float totalHeight = fabsf ([nsFont ascender]) + fabsf([nsFont descender]);
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
}
else
#endif
{
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
}
#endif
}
~MacTypeface()
{
[nsFont release];
CGFontRelease (fontRef);
if (fontRef != 0)
CGFontRelease (fontRef);
delete charToGlyphMapper;
}
@ -262031,50 +262157,88 @@ public:
float getStringWidth (const String& text)
{
if (fontRef == 0)
if (fontRef == 0 || text.isEmpty())
return 0;
Array <int> glyphs (128);
createGlyphsForString (text, glyphs);
if (glyphs.size() == 0)
return 0;
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
int x = 0;
int* const advances = (int*) juce_malloc (glyphs.size() * 2 * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, (CGGlyph*) &glyphs.getReference(0), glyphs.size() * 2, advances))
for (int i = 0; i < glyphs.size(); ++i)
x += advances [i * 2];
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
[nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
for (int i = 0; i < length; ++i)
x += advances[i].width;
juce_free (advances);
}
else
#endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))
for (int i = 0; i < length; ++i)
x += advances[i];
juce_free (advances);
}
juce_free (glyphs);
juce_free (advances);
return x * unitsToHeightScaleFactor;
}
void getGlyphPositions (const String& text, Array <int>& glyphs, Array <float>& xOffsets)
void getGlyphPositions (const String& text, Array <int>& resultGlyphs, Array <float>& xOffsets)
{
if (fontRef == 0)
return;
createGlyphsForString (text, glyphs);
xOffsets.add (0);
if (glyphs.size() == 0)
if (fontRef == 0 || text.isEmpty())
return;
int* const advances = (int*) juce_malloc (glyphs.size() * 2 * sizeof (int));
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
if (CGFontGetGlyphAdvances (fontRef, (CGGlyph*) &glyphs.getReference(0), glyphs.size() * 2, advances))
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
[nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
int x = 0;
for (int i = 0; i < glyphs.size(); ++i)
for (int i = 0; i < length; ++i)
{
x += advances [i * 2];
x += advances[i].width;
xOffsets.add (x * unitsToHeightScaleFactor);
resultGlyphs.add (((NSGlyph*) glyphs)[i]);
}
juce_free (advances);
}
else
#endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))
{
int x = 0;
for (int i = 0; i < length; ++i)
{
x += advances [i];
xOffsets.add (x * unitsToHeightScaleFactor);
resultGlyphs.add (glyphs[i]);
}
}
juce_free (advances);
}
juce_free (advances);
juce_free (glyphs);
}
bool getOutlineForGlyph (int glyphNumber, Path& path)
@ -262139,15 +262303,28 @@ private:
AffineTransform pathTransform;
#endif
void createGlyphsForString (const String& text, Array <int>& dest) throw()
CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw()
{
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length);
for (int i = 0; i < length; ++i)
g[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]];
return (CGGlyph*) g;
}
#endif
if (charToGlyphMapper == 0)
charToGlyphMapper = new CharToGlyphMapper (fontRef);
const juce_wchar* t = (const juce_wchar*) text;
CGGlyph* const g = (CGGlyph*) juce_malloc (sizeof (CGGlyph) * length);
while (*t != 0)
dest.add (charToGlyphMapper->getGlyphForCharacter (*t++));
for (int i = 0; i < length; ++i)
g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]);
return g;
}
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
@ -265578,6 +265755,17 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
// compiled on its own).
#if JUCE_INCLUDED_FILE
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define SUPPORT_10_4_FONTS 1
#define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0)
END_JUCE_NAMESPACE
@interface NSFont (PrivateHack)
- (NSGlyph) _defaultGlyphForChar: (unichar) theChar;
@end
BEGIN_JUCE_NAMESPACE
#endif
class MacTypeface : public Typeface
{
public:
@ -265629,6 +265817,9 @@ public:
fontRef = CGFontCreateWithFontName ((CFStringRef) fontName);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
#else
nsFont = [NSFont fontWithName: juceStringToNS (font.getTypefaceName()) size: 1024];
@ -265660,18 +265851,40 @@ public:
renderingTransform.c = 0.15f;
}
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
#endif
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
if (atsFont == 0)
atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault);
fontRef = CGFontCreateWithPlatformFont ((void*) &atsFont);
const float totalHeight = fabsf ([nsFont ascender]) + fabsf([nsFont descender]);
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = 1024.0f / totalHeight;
}
else
#endif
{
fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);
const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef));
unitsToHeightScaleFactor = 1.0f / totalHeight;
fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight;
}
#endif
}
~MacTypeface()
{
[nsFont release];
CGFontRelease (fontRef);
if (fontRef != 0)
CGFontRelease (fontRef);
delete charToGlyphMapper;
}
@ -265687,50 +265900,88 @@ public:
float getStringWidth (const String& text)
{
if (fontRef == 0)
if (fontRef == 0 || text.isEmpty())
return 0;
Array <int> glyphs (128);
createGlyphsForString (text, glyphs);
if (glyphs.size() == 0)
return 0;
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
int x = 0;
int* const advances = (int*) juce_malloc (glyphs.size() * 2 * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, (CGGlyph*) &glyphs.getReference(0), glyphs.size() * 2, advances))
for (int i = 0; i < glyphs.size(); ++i)
x += advances [i * 2];
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
[nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
for (int i = 0; i < length; ++i)
x += advances[i].width;
juce_free (advances);
}
else
#endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))
for (int i = 0; i < length; ++i)
x += advances[i];
juce_free (advances);
}
juce_free (glyphs);
juce_free (advances);
return x * unitsToHeightScaleFactor;
}
void getGlyphPositions (const String& text, Array <int>& glyphs, Array <float>& xOffsets)
void getGlyphPositions (const String& text, Array <int>& resultGlyphs, Array <float>& xOffsets)
{
if (fontRef == 0)
return;
createGlyphsForString (text, glyphs);
xOffsets.add (0);
if (glyphs.size() == 0)
if (fontRef == 0 || text.isEmpty())
return;
int* const advances = (int*) juce_malloc (glyphs.size() * 2 * sizeof (int));
const int length = text.length();
CGGlyph* const glyphs = createGlyphsForString (text, length);
if (CGFontGetGlyphAdvances (fontRef, (CGGlyph*) &glyphs.getReference(0), glyphs.size() * 2, advances))
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize));
[nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length];
int x = 0;
for (int i = 0; i < glyphs.size(); ++i)
for (int i = 0; i < length; ++i)
{
x += advances [i * 2];
x += advances[i].width;
xOffsets.add (x * unitsToHeightScaleFactor);
resultGlyphs.add (((NSGlyph*) glyphs)[i]);
}
juce_free (advances);
}
else
#endif
{
int* const advances = (int*) juce_malloc (length * sizeof (int));
if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))
{
int x = 0;
for (int i = 0; i < length; ++i)
{
x += advances [i];
xOffsets.add (x * unitsToHeightScaleFactor);
resultGlyphs.add (glyphs[i]);
}
}
juce_free (advances);
}
juce_free (advances);
juce_free (glyphs);
}
bool getOutlineForGlyph (int glyphNumber, Path& path)
@ -265795,15 +266046,28 @@ private:
AffineTransform pathTransform;
#endif
void createGlyphsForString (const String& text, Array <int>& dest) throw()
CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw()
{
#if SUPPORT_10_4_FONTS
if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE)
{
NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length);
for (int i = 0; i < length; ++i)
g[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]];
return (CGGlyph*) g;
}
#endif
if (charToGlyphMapper == 0)
charToGlyphMapper = new CharToGlyphMapper (fontRef);
const juce_wchar* t = (const juce_wchar*) text;
CGGlyph* const g = (CGGlyph*) juce_malloc (sizeof (CGGlyph) * length);
while (*t != 0)
dest.add (charToGlyphMapper->getGlyphForCharacter (*t++));
for (int i = 0; i < length; ++i)
g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]);
return g;
}
// Reads a CGFontRef's character map table to convert unicode into glyph numbers
@ -266268,7 +266532,7 @@ public:
if (state->fontRef != 0)
{
CGGlyph g = glyphNumber;
CGContextShowGlyphsAtPoint (context, x, flipHeight - y, &g, 1);
CGContextShowGlyphsAtPoint (context, x, flipHeight - roundFloatToInt (y), &g, 1);
}
else
{