Browse Source

Added a flag JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING to juce_graphics

tags/2021-05-28
jules 7 years ago
parent
commit
119d9a79c6
3 changed files with 62 additions and 45 deletions
  1. +9
    -0
      modules/juce_graphics/juce_graphics.h
  2. +3
    -3
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h
  3. +50
    -42
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm

+ 9
- 0
modules/juce_graphics/juce_graphics.h View File

@@ -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


+ 3
- 3
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h View File

@@ -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;


+ 50
- 42
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -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…
Cancel
Save