mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added a flag JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING to juce_graphics
This commit is contained in:
parent
cba080396b
commit
119d9a79c6
3 changed files with 62 additions and 45 deletions
|
|
@ -77,6 +77,15 @@
|
|||
#define JUCE_USE_DIRECTWRITE 1
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
|
||||
|
||||
Setting this flag will turn off CoreGraphics font smoothing, which some people
|
||||
find makes the text too 'fat' for their taste.
|
||||
*/
|
||||
#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
|
||||
#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_INCLUDE_PNGLIB_CODE
|
||||
#define JUCE_INCLUDE_PNGLIB_CODE 1
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ private:
|
|||
float targetScale;
|
||||
CGColorSpaceRef rgbColourSpace, greyColourSpace;
|
||||
mutable Rectangle<int> lastClipRect;
|
||||
mutable bool lastClipRectIsValid;
|
||||
mutable bool lastClipRectIsValid = false;
|
||||
|
||||
struct SavedState
|
||||
{
|
||||
|
|
@ -92,9 +92,9 @@ private:
|
|||
|
||||
FillType fillType;
|
||||
Font font;
|
||||
CGFontRef fontRef;
|
||||
CGFontRef fontRef = {};
|
||||
CGAffineTransform fontTransform;
|
||||
CGGradientRef gradient;
|
||||
CGGradientRef gradient = {};
|
||||
};
|
||||
|
||||
std::unique_ptr<SavedState> state;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace juce
|
|||
class CoreGraphicsImage : public ImagePixelData
|
||||
{
|
||||
public:
|
||||
CoreGraphicsImage (const Image::PixelFormat format, const int w, const int h, const bool clearImage)
|
||||
CoreGraphicsImage (const Image::PixelFormat format, int w, int h, bool clearImage)
|
||||
: ImagePixelData (format, w, h), cachedImageRef (0)
|
||||
{
|
||||
pixelStride = format == Image::RGB ? 3 : ((format == Image::ARGB) ? 4 : 1);
|
||||
|
|
@ -76,7 +76,7 @@ public:
|
|||
|
||||
ImagePixelData::Ptr clone() override
|
||||
{
|
||||
CoreGraphicsImage* im = new CoreGraphicsImage (pixelFormat, width, height, false);
|
||||
auto im = new CoreGraphicsImage (pixelFormat, width, height, false);
|
||||
memcpy (im->imageData, imageData, (size_t) (lineStride * height));
|
||||
return im;
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ public:
|
|||
//==============================================================================
|
||||
static CGImageRef getCachedImageRef (const Image& juceImage, CGColorSpaceRef colourSpace)
|
||||
{
|
||||
CoreGraphicsImage* const cgim = dynamic_cast<CoreGraphicsImage*> (juceImage.getPixelData());
|
||||
auto cgim = dynamic_cast<CoreGraphicsImage*> (juceImage.getPixelData());
|
||||
|
||||
if (cgim != nullptr && cgim->cachedImageRef != 0)
|
||||
{
|
||||
|
|
@ -105,7 +105,7 @@ public:
|
|||
return ref;
|
||||
}
|
||||
|
||||
static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, const bool mustOutliveSource)
|
||||
static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, bool mustOutliveSource)
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, Image::BitmapData::readOnly);
|
||||
CGDataProviderRef provider;
|
||||
|
|
@ -166,17 +166,24 @@ ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int widt
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, const float h, const float scale)
|
||||
CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, float h, float scale)
|
||||
: context (c),
|
||||
flipHeight (h),
|
||||
targetScale (scale),
|
||||
lastClipRectIsValid (false),
|
||||
state (new SavedState())
|
||||
{
|
||||
CGContextRetain (context);
|
||||
CGContextSaveGState (context);
|
||||
CGContextSetShouldSmoothFonts (context, true);
|
||||
CGContextSetAllowsFontSmoothing (context, true);
|
||||
|
||||
bool enableFontSmoothing
|
||||
#if JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
|
||||
= false;
|
||||
#else
|
||||
= true;
|
||||
#endif
|
||||
|
||||
CGContextSetShouldSmoothFonts (context, enableFontSmoothing);
|
||||
CGContextSetAllowsFontSmoothing (context, enableFontSmoothing);
|
||||
CGContextSetShouldAntialias (context, true);
|
||||
CGContextSetBlendMode (context, kCGBlendModeNormal);
|
||||
rgbColourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
|
@ -215,14 +222,15 @@ void CoreGraphicsContext::addTransform (const AffineTransform& transform)
|
|||
|
||||
float CoreGraphicsContext::getPhysicalPixelScaleFactor()
|
||||
{
|
||||
const CGAffineTransform t = CGContextGetCTM (context);
|
||||
auto t = CGContextGetCTM (context);
|
||||
|
||||
return targetScale * (float) (juce_hypot (t.a, t.c) + juce_hypot (t.b, t.d)) / 2.0f;
|
||||
}
|
||||
|
||||
bool CoreGraphicsContext::clipToRectangle (const Rectangle<int>& r)
|
||||
{
|
||||
CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()));
|
||||
CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(),
|
||||
r.getWidth(), r.getHeight()));
|
||||
|
||||
if (lastClipRectIsValid)
|
||||
{
|
||||
|
|
@ -295,10 +303,10 @@ void CoreGraphicsContext::clipToImageAlpha (const Image& sourceImage, const Affi
|
|||
CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, greyColourSpace, true);
|
||||
|
||||
flip();
|
||||
AffineTransform t (AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform));
|
||||
auto t = AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform);
|
||||
applyTransform (t);
|
||||
|
||||
CGRect r = convertToCGRect (sourceImage.getBounds());
|
||||
auto r = convertToCGRect (sourceImage.getBounds());
|
||||
CGContextClipToMask (context, r, image);
|
||||
|
||||
applyTransform (t.inverted());
|
||||
|
|
@ -318,7 +326,7 @@ Rectangle<int> CoreGraphicsContext::getClipBounds() const
|
|||
{
|
||||
if (! lastClipRectIsValid)
|
||||
{
|
||||
CGRect bounds = CGRectIntegral (CGContextGetClipBoundingBox (context));
|
||||
auto bounds = CGRectIntegral (CGContextGetClipBoundingBox (context));
|
||||
|
||||
lastClipRectIsValid = true;
|
||||
lastClipRect.setBounds (roundToInt (bounds.origin.x),
|
||||
|
|
@ -402,7 +410,7 @@ void CoreGraphicsContext::setInterpolationQuality (Graphics::ResamplingQuality q
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void CoreGraphicsContext::fillRect (const Rectangle<int>& r, const bool replaceExistingContents)
|
||||
void CoreGraphicsContext::fillRect (const Rectangle<int>& r, bool replaceExistingContents)
|
||||
{
|
||||
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents);
|
||||
}
|
||||
|
|
@ -412,7 +420,7 @@ void CoreGraphicsContext::fillRect (const Rectangle<float>& r)
|
|||
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), false);
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, const bool replaceExistingContents)
|
||||
void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, bool replaceExistingContents)
|
||||
{
|
||||
if (replaceExistingContents)
|
||||
{
|
||||
|
|
@ -481,10 +489,10 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
|
|||
drawImage (sourceImage, transform, false);
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles)
|
||||
void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles)
|
||||
{
|
||||
const int iw = sourceImage.getWidth();
|
||||
const int ih = sourceImage.getHeight();
|
||||
auto iw = sourceImage.getWidth();
|
||||
auto ih = sourceImage.getHeight();
|
||||
CGImageRef image = CoreGraphicsImage::getCachedImageRef (sourceImage, sourceImage.getFormat() == Image::PixelFormat::SingleChannel ? greyColourSpace
|
||||
: rgbColourSpace);
|
||||
|
||||
|
|
@ -493,7 +501,7 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
|
|||
|
||||
flip();
|
||||
applyTransform (AffineTransform::verticalFlip (ih).followedBy (transform));
|
||||
CGRect imageRect = CGRectMake (0, 0, iw, ih);
|
||||
auto imageRect = CGRectMake (0, 0, iw, ih);
|
||||
|
||||
if (fillEntireClipAsTiles)
|
||||
{
|
||||
|
|
@ -509,14 +517,14 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
|
|||
else
|
||||
{
|
||||
// Fallback to manually doing a tiled fill
|
||||
CGRect clip = CGRectIntegral (CGContextGetClipBoundingBox (context));
|
||||
auto clip = CGRectIntegral (CGContextGetClipBoundingBox (context));
|
||||
|
||||
int x = 0, y = 0;
|
||||
while (x > clip.origin.x) x -= iw;
|
||||
while (y > clip.origin.y) y -= ih;
|
||||
|
||||
const int right = (int) (clip.origin.x + clip.size.width);
|
||||
const int bottom = (int) (clip.origin.y + clip.size.height);
|
||||
auto right = (int) (clip.origin.x + clip.size.width);
|
||||
auto bottom = (int) (clip.origin.y + clip.size.height);
|
||||
|
||||
while (y < bottom)
|
||||
{
|
||||
|
|
@ -597,7 +605,7 @@ void CoreGraphicsContext::setFont (const Font& newFont)
|
|||
state->fontRef = 0;
|
||||
state->font = newFont;
|
||||
|
||||
if (OSXTypeface* osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
|
||||
if (auto osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
|
||||
{
|
||||
state->fontRef = osxTypeface->fontRef;
|
||||
CGContextSetFont (context, state->fontRef);
|
||||
|
|
@ -628,7 +636,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
|
|||
{
|
||||
CGContextSetTextMatrix (context, state->fontTransform); // have to set this each time, as it's not saved as part of the state
|
||||
|
||||
CGGlyph g = (CGGlyph) glyphNumber;
|
||||
auto g = (CGGlyph) glyphNumber;
|
||||
CGContextShowGlyphsAtPoint (context, transform.getTranslationX(),
|
||||
flipHeight - roundToInt (transform.getTranslationY()), &g, 1);
|
||||
}
|
||||
|
|
@ -638,11 +646,11 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
|
|||
flip();
|
||||
applyTransform (transform);
|
||||
|
||||
CGAffineTransform t = state->fontTransform;
|
||||
auto t = state->fontTransform;
|
||||
t.d = -t.d;
|
||||
CGContextSetTextMatrix (context, t);
|
||||
|
||||
CGGlyph g = (CGGlyph) glyphNumber;
|
||||
auto g = (CGGlyph) glyphNumber;
|
||||
CGContextShowGlyphsAtPoint (context, 0, 0, &g, 1);
|
||||
|
||||
CGContextRestoreGState (context);
|
||||
|
|
@ -655,7 +663,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
|
|||
else
|
||||
{
|
||||
Path p;
|
||||
Font& f = state->font;
|
||||
auto& f = state->font;
|
||||
f.getTypeface()->getOutlineForGlyph (glyphNumber, p);
|
||||
|
||||
fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight())
|
||||
|
|
@ -670,7 +678,7 @@ bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Re
|
|||
}
|
||||
|
||||
CoreGraphicsContext::SavedState::SavedState()
|
||||
: font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity), gradient (0)
|
||||
: font (1.0f), fontTransform (CGAffineTransformIdentity)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -701,15 +709,15 @@ void CoreGraphicsContext::SavedState::setFill (const FillType& newFill)
|
|||
|
||||
static CGGradientRef createGradient (const ColourGradient& g, CGColorSpaceRef colourSpace)
|
||||
{
|
||||
const int numColours = g.getNumColours();
|
||||
CGFloat* const data = (CGFloat*) alloca ((size_t) numColours * 5 * sizeof (CGFloat));
|
||||
CGFloat* const locations = data;
|
||||
CGFloat* const components = data + numColours;
|
||||
CGFloat* comps = components;
|
||||
auto numColours = g.getNumColours();
|
||||
auto data = (CGFloat*) alloca ((size_t) numColours * 5 * sizeof (CGFloat));
|
||||
auto locations = data;
|
||||
auto components = data + numColours;
|
||||
auto comps = components;
|
||||
|
||||
for (int i = 0; i < numColours; ++i)
|
||||
{
|
||||
const Colour colour (g.getColour (i));
|
||||
auto colour = g.getColour (i);
|
||||
*comps++ = (CGFloat) colour.getFloatRed();
|
||||
*comps++ = (CGFloat) colour.getFloatGreen();
|
||||
*comps++ = (CGFloat) colour.getFloatBlue();
|
||||
|
|
@ -730,10 +738,10 @@ void CoreGraphicsContext::drawGradient()
|
|||
applyTransform (state->fillType.transform);
|
||||
CGContextSetAlpha (context, state->fillType.getOpacity());
|
||||
|
||||
const ColourGradient& g = *state->fillType.gradient;
|
||||
auto& g = *state->fillType.gradient;
|
||||
|
||||
CGPoint p1 (convertToCGPoint (g.point1));
|
||||
CGPoint p2 (convertToCGPoint (g.point2));
|
||||
auto p1 = convertToCGPoint (g.point1);
|
||||
auto p2 = convertToCGPoint (g.point2);
|
||||
|
||||
state->fillType.transform.transformPoints (p1.x, p1.y, p2.x, p2.y);
|
||||
|
||||
|
|
@ -857,7 +865,7 @@ Image juce_loadWithCoreImage (InputStream& input)
|
|||
(int) CGImageGetHeight (loadedImage),
|
||||
hasAlphaChan));
|
||||
|
||||
CoreGraphicsImage* const cgImage = dynamic_cast<CoreGraphicsImage*> (image.getPixelData());
|
||||
auto cgImage = dynamic_cast<CoreGraphicsImage*> (image.getPixelData());
|
||||
jassert (cgImage != nullptr); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsImage class should have been used.
|
||||
|
||||
CGContextDrawImage (cgImage->context, convertToCGRect (image.getBounds()), loadedImage);
|
||||
|
|
@ -875,14 +883,14 @@ Image juce_loadWithCoreImage (InputStream& input)
|
|||
}
|
||||
}
|
||||
|
||||
return Image();
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
Image juce_createImageFromCIImage (CIImage*, int, int);
|
||||
Image juce_createImageFromCIImage (CIImage* im, int w, int h)
|
||||
{
|
||||
CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false);
|
||||
auto cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false);
|
||||
|
||||
CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil];
|
||||
[cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)];
|
||||
|
|
@ -899,11 +907,11 @@ CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef
|
|||
|
||||
CGContextRef juce_getImageContext (const Image& image)
|
||||
{
|
||||
if (CoreGraphicsImage* const cgi = dynamic_cast<CoreGraphicsImage*> (image.getPixelData()))
|
||||
if (auto cgi = dynamic_cast<CoreGraphicsImage*> (image.getPixelData()))
|
||||
return cgi->context;
|
||||
|
||||
jassertfalse;
|
||||
return 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
#if JUCE_IOS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue