From 47f138464f0ea3423245bd2d472291dab952702e Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Fri, 17 Jan 2020 16:34:50 +0000 Subject: [PATCH] macOS: Fixed a CoreGraphics text layout bug --- .../fonts/juce_GlyphArrangement.cpp | 2 +- .../native/juce_mac_CoreGraphicsContext.h | 3 +- .../native/juce_mac_CoreGraphicsContext.mm | 44 +++++++++---------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index de5c1dca8d..148c655e30 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -711,7 +711,7 @@ void GlyphArrangement::draw (const Graphics& g, AffineTransform transform) const for (int i = 0; i < glyphs.size(); ++i) { - auto& pg = glyphs.getReference(i); + auto& pg = glyphs.getReference (i); if (pg.font.isUnderlined()) drawGlyphUnderline (g, pg, i, transform); diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h index 02c69a5aec..910304d485 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h @@ -93,7 +93,8 @@ private: FillType fillType; Font font; CGFontRef fontRef = {}; - AffineTransform fontTransform, inverseFontTransform; + CGAffineTransform textMatrix = CGAffineTransformIdentity, + inverseTextMatrix = CGAffineTransformIdentity; CGGradientRef gradient = {}; }; diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm index f34002a69d..26aeb8a2c5 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm @@ -383,6 +383,8 @@ void CoreGraphicsContext::restoreState() if (auto* top = stateStack.getLast()) { state.reset (top); + CGContextSetTextMatrix (context, state->textMatrix); + stateStack.removeLast (1, false); lastClipRectIsValid = false; } @@ -623,20 +625,11 @@ void CoreGraphicsContext::setFont (const Font& newFont) CGContextSetFont (context, state->fontRef); CGContextSetFontSize (context, state->font.getHeight() * osxTypeface->fontHeightToPointsFactor); - auto fontTransform = osxTypeface->renderingTransform; - fontTransform.a *= state->font.getHorizontalScale(); - CGContextSetTextMatrix (context, fontTransform); - - auto cgTransformToJuceTransform = [](CGAffineTransform& t) -> AffineTransform - { - return { (float) t.a, (float) t.c, (float) t.tx, - (float) t.b, (float) t.d, (float) t.ty }; - }; - - state->fontTransform = cgTransformToJuceTransform (fontTransform); - auto inverseFontTransform = CGAffineTransformInvert (fontTransform); - state->inverseFontTransform = cgTransformToJuceTransform (inverseFontTransform); - } + state->textMatrix = osxTypeface->renderingTransform; + state->textMatrix.a *= state->font.getHorizontalScale(); + CGContextSetTextMatrix (context, state->textMatrix); + state->inverseTextMatrix = CGAffineTransformInvert (state->textMatrix); + } } } @@ -649,12 +642,18 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra { if (state->fontRef != nullptr && state->fillType.isColour()) { - if (transform.isOnlyTranslation() && state->fontTransform.isOnlyTranslation()) + auto cgTransformIsOnlyTranslation = [](CGAffineTransform t) { - auto t = transform.followedBy (state->inverseFontTransform); + return t.a == 1.0f && t.d == 1.0f && t.b == 0.0f && t.c == 0.0f; + }; + + if (transform.isOnlyTranslation() && cgTransformIsOnlyTranslation (state->inverseTextMatrix)) + { + auto x = transform.mat02 + state->inverseTextMatrix.tx; + auto y = transform.mat12 + state->inverseTextMatrix.ty; CGGlyph glyphs[1] = { (CGGlyph) glyphNumber }; - CGPoint positions[1] = { { t.getTranslationX(), flipHeight - roundToInt (t.getTranslationY()) } }; + CGPoint positions[1] = { { x, flipHeight - roundToInt (y) } }; CGContextShowGlyphsAtPositions (context, glyphs, positions, 1); } else @@ -662,9 +661,11 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra CGContextSaveGState (context); flip(); - auto fontTransform = state->fontTransform; - fontTransform.mat11 = -fontTransform.mat11; - applyTransform (fontTransform.followedBy (state->inverseFontTransform).followedBy (transform)); + applyTransform (transform); + CGContextConcatCTM (context, state->inverseTextMatrix); + auto cgTransform = state->textMatrix; + cgTransform.d = -cgTransform.d; + CGContextConcatCTM (context, cgTransform); CGGlyph glyphs[1] = { (CGGlyph) glyphNumber }; CGPoint positions[1] = { { 0.0f, 0.0f } }; @@ -697,8 +698,7 @@ CoreGraphicsContext::SavedState::SavedState() CoreGraphicsContext::SavedState::SavedState (const SavedState& other) : fillType (other.fillType), font (other.font), fontRef (other.fontRef), - fontTransform (other.fontTransform), - inverseFontTransform (other.inverseFontTransform), + textMatrix (other.textMatrix), inverseTextMatrix (other.inverseTextMatrix), gradient (other.gradient) { if (gradient != nullptr)