vcl/quartz/ctfonts.cxx | 6 +- vcl/quartz/salgdi.cxx | 67 +++++++++++-------------- vcl/unx/generic/glyphs/freetype_glyphcache.cxx | 8 -- 3 files changed, 37 insertions(+), 44 deletions(-)
New commits: commit ebfe8bb2b2cfc3dba063260bf746db923a3693f2 Author: Khaled Hosny <[email protected]> Date: Sun Nov 13 18:59:44 2016 +0200 tdf#103895: Another fix too macOS glyph bounding Apply font rotation when calculating glyph bounding rectangle. Change-Id: I9c533ec3b33a5858d46b60d1700a50d3b6f915a4 diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index 20fba1f..c111613 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -167,7 +167,11 @@ bool CoreTextStyle::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect ) SAL_WNODEPRECATED_DECLARATIONS_PUSH //TODO: 10.11 kCTFontDefaultOrientation const CTFontOrientation aFontOrientation = kCTFontDefaultOrientation; // TODO: horz/vert SAL_WNODEPRECATED_DECLARATIONS_POP - const CGRect aCGRect = CTFontGetBoundingRectsForGlyphs( aCTFontRef, aFontOrientation, &nCGGlyph, nullptr, 1 ); + CGRect aCGRect = CTFontGetBoundingRectsForGlyphs(aCTFontRef, aFontOrientation, &nCGGlyph, nullptr, 1); + + // Apply font rotation to non-upright glyphs. + if (mfFontRotation && !(aGlyphId & GF_ROTMASK)) + aCGRect = CGRectApplyAffineTransform(aCGRect, CGAffineTransformMakeRotation(mfFontRotation)); rRect.Left() = lrint( aCGRect.origin.x ); rRect.Top() = lrint(-aCGRect.origin.y ); commit e760de7db53a6ccfa0b4732d9c4639441dc22434 Author: Khaled Hosny <[email protected]> Date: Sun Nov 13 18:36:35 2016 +0200 The nAngle is set but never used Change-Id: I7c8493e06ab3d7bab60f5af14100b1e25dd68fba diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index 5dff458..7ef42b8 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -753,9 +753,8 @@ static inline void SplitGlyphFlags( const FreetypeFont& rFont, sal_GlyphId& rGly void FreetypeFont::ApplyGlyphTransform( int nGlyphFlags, FT_Glyph pGlyphFT ) const { - int nAngle = GetFontSelData().mnOrientation; // shortcut most common case - if( !nAngle && !nGlyphFlags ) + if (!GetFontSelData().mnOrientation && !nGlyphFlags) return; const FT_Size_Metrics& rMetrics = maFaceFT->size->metrics; @@ -775,7 +774,6 @@ void FreetypeFont::ApplyGlyphTransform( int nGlyphFlags, FT_Glyph pGlyphFT ) con aMatrix.yx = +mnSin; break; case GF_ROTL: // left - nAngle += 900; bStretched = (mfStretch != 1.0); aVector.x = (FT_Pos)(+rMetrics.descender * mfStretch); aVector.y = -rMetrics.ascender; @@ -785,7 +783,6 @@ void FreetypeFont::ApplyGlyphTransform( int nGlyphFlags, FT_Glyph pGlyphFT ) con aMatrix.yx = (FT_Pos)(+mnCos / mfStretch); break; case GF_ROTR: // right - nAngle -= 900; bStretched = (mfStretch != 1.0); aVector.x = -maFaceFT->glyph->metrics.horiAdvance; aVector.x += (FT_Pos)(rMetrics.descender * mnSin/65536.0); @@ -797,9 +794,6 @@ void FreetypeFont::ApplyGlyphTransform( int nGlyphFlags, FT_Glyph pGlyphFT ) con break; } - while( nAngle < 0 ) - nAngle += 3600; - if( pGlyphFT->format != FT_GLYPH_FORMAT_BITMAP ) { FT_Glyph_Transform( pGlyphFT, nullptr, &aVector ); commit 3a64e01a7e2ac65daa4f3fa623d9ef5b9ca24f7f Author: Khaled Hosny <[email protected]> Date: Sun Nov 13 16:00:34 2016 +0200 Simplify vertical text drawing on macOS Rotate only the rotated glyphs instead of rotating everything, then unrotating the upright glyphs. No need for a rotated font either, rotating the graphics is fine. Change-Id: I1fce2c9c6a29abb1353a5fc8485a9c0d34edfbf1 diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 91454c7..7daefd5 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -430,31 +430,39 @@ void AquaSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout) return; CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(rStyle.GetStyleDict(), kCTFontAttributeName)); + CGAffineTransform aRotMatrix = CGAffineTransformMakeRotation(-rStyle.mfFontRotation); Point aPos; sal_GlyphId aGlyphId; std::vector<CGGlyph> aGlyphIds; std::vector<CGPoint> aGlyphPos; - std::vector<bool> aGlyphRotation; + std::vector<bool> aGlyphOrientation; int nStart = 0; while (rLayout.GetNextGlyphs(1, &aGlyphId, aPos, nStart)) { - // Transform the position of non-vertical glyphs. - CGAffineTransform aMatrix = CGAffineTransformMakeRotation(-rStyle.mfFontRotation); + CGPoint aGCPos = CGPointMake(aPos.X(), -aPos.Y()); - // Transform the position of vertical glyphs. - // We donât handle GF_ROTR as it is not used in CommonSalLayout. - bool nGlyphRotation = false; - if ((aGlyphId & GF_ROTMASK) == GF_ROTL) + // Whether the glyph should be upright in vertical mode or not + bool bUprightGlyph = false; + + if (rStyle.mfFontRotation) { - nGlyphRotation = true; - double nYdiff = CTFontGetAscent(pFont) - CTFontGetDescent(pFont); - aMatrix = CGAffineTransformTranslate(aMatrix, 0, -nYdiff); + if ((aGlyphId & GF_ROTMASK) == GF_ROTL) + { + bUprightGlyph = true; + // Adjust the position of upright (vertical) glyphs. + aGCPos.y -= CTFontGetAscent(pFont) - CTFontGetDescent(pFont); + } + else + { + // Transform the position of rotated glyphs. + aGCPos = CGPointApplyAffineTransform(aGCPos, aRotMatrix); + } } aGlyphIds.push_back(aGlyphId & GF_IDXMASK); - aGlyphPos.push_back(CGPointApplyAffineTransform(CGPointMake(aPos.X(), -aPos.Y()), aMatrix)); - aGlyphRotation.push_back(nGlyphRotation); + aGlyphPos.push_back(aGCPos); + aGlyphOrientation.push_back(bUprightGlyph); } if (aGlyphIds.empty()) @@ -462,43 +470,30 @@ void AquaSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout) CGContextSaveGState(mrContext); - // Create a transformed font for drawing vertical glyphs. - CTFontRef pRotatedFont = nullptr; - if (rStyle.mfFontRotation) - { - CTFontDescriptorRef pDesc = CTFontCopyFontDescriptor(pFont); - CGFloat nSize = CTFontGetSize(pFont); - CGAffineTransform aMatrix = CTFontGetMatrix(pFont); - aMatrix = CGAffineTransformRotate(aMatrix, -rStyle.mfFontRotation); - pRotatedFont = CTFontCreateWithFontDescriptor(pDesc, nSize, &aMatrix); - CFRelease(pDesc); - } - + // The view is vertically flipped (no idea why), flip it back. CGContextScaleCTM(mrContext, 1.0, -1.0); - CGContextRotateCTM(mrContext, rStyle.mfFontRotation); CGContextSetShouldAntialias(mrContext, !mbNonAntialiasedText); CGContextSetFillColor(mrContext, maTextColor.AsArray()); - auto aIt = aGlyphRotation.cbegin(); - while (aIt != aGlyphRotation.cend()) + auto aIt = aGlyphOrientation.cbegin(); + while (aIt != aGlyphOrientation.cend()) { - bool nGlyphRotation = *aIt; + bool bUprightGlyph = *aIt; // Find the boundary of the run of glyphs with the same rotation, to be // drawn together. - auto aNext = std::find(aIt, aGlyphRotation.cend(), !nGlyphRotation); - size_t nStartIndex = std::distance(aGlyphRotation.cbegin(), aIt); + auto aNext = std::find(aIt, aGlyphOrientation.cend(), !bUprightGlyph); + size_t nStartIndex = std::distance(aGlyphOrientation.cbegin(), aIt); size_t nLen = std::distance(aIt, aNext); - if (nGlyphRotation && pRotatedFont) - CTFontDrawGlyphs(pRotatedFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrContext); - else - CTFontDrawGlyphs(pFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrContext); + CGContextSaveGState(mrContext); + if (rStyle.mfFontRotation && !bUprightGlyph) + CGContextRotateCTM(mrContext, rStyle.mfFontRotation); + CTFontDrawGlyphs(pFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrContext); + CGContextRestoreGState(mrContext); aIt = aNext; } - if (pRotatedFont) - CFRelease(pRotatedFont); CGContextRestoreGState(mrContext); }
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
