Kaydet (Commit) 472884c5 authored tarafından Herbert Dürr's avatar Herbert Dürr

#i124617# make CoreText tolerate PDF-export's unexpected font switches

For some documents it was observed that the PDF-export switches the font after
text layout and before text drawing/measuring. This use case is quite atrocious
and unexpected and crashed our CoreText glue code. The other platforms survive
it though; to minimize the risk to them only the CoreText glue gets adapted to
survive this scenario.
üst 4d57671f
...@@ -52,9 +52,8 @@ public: ...@@ -52,9 +52,8 @@ public:
virtual void Simplify( bool bIsBase ); virtual void Simplify( bool bIsBase );
private: private:
const CTTextStyle* const mpTextStyle;
// CoreText specific objects // CoreText specific objects
CFMutableDictionaryRef mpStyleDict;
CFAttributedStringRef mpAttrString; CFAttributedStringRef mpAttrString;
CTLineRef mpCTLine; CTLineRef mpCTLine;
...@@ -67,6 +66,9 @@ private: ...@@ -67,6 +66,9 @@ private:
// in these cases the font scale becomes something bigger than 1.0 // in these cases the font scale becomes something bigger than 1.0
float mfFontScale; // TODO: does CoreText have a font size limit? float mfFontScale; // TODO: does CoreText have a font size limit?
CGFloat mfFontRotation; // text direction angle (in radians)
CGFloat mfFontStretch; <1.0: font is squeezed, >1.0 font is stretched
// cached details about the resulting layout // cached details about the resulting layout
// mutable members since these details are all lazy initialized // mutable members since these details are all lazy initialized
mutable double mfCachedWidth; // cached value of resulting typographical width mutable double mfCachedWidth; // cached value of resulting typographical width
...@@ -79,17 +81,19 @@ private: ...@@ -79,17 +81,19 @@ private:
// ======================================================================= // =======================================================================
CTLayout::CTLayout( const CTTextStyle* pTextStyle ) CTLayout::CTLayout( const CTTextStyle* pTextStyle )
: mpTextStyle( pTextStyle ) : mpStyleDict( pTextStyle->GetStyleDict() )
, mpAttrString( NULL ) , mpAttrString( NULL )
, mpCTLine( NULL ) , mpCTLine( NULL )
, mnCharCount( 0 ) , mnCharCount( 0 )
, mnTrailingSpaceCount( 0 ) , mnTrailingSpaceCount( 0 )
, mfTrailingSpaceWidth( 0.0 ) , mfTrailingSpaceWidth( 0.0 )
, mfFontScale( pTextStyle->mfFontScale ) , mfFontScale( pTextStyle->mfFontScale )
, mfFontRotation( pTextStyle->mfFontRotation )
, mfFontStretch( pTextStyle->mfFontStretch )
, mfCachedWidth( -1 ) , mfCachedWidth( -1 )
, mnBaseAdv( 0 ) , mnBaseAdv( 0 )
{ {
CFRetain( mpTextStyle->GetStyleDict() ); CFRetain( mpStyleDict );
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
...@@ -100,7 +104,7 @@ CTLayout::~CTLayout() ...@@ -100,7 +104,7 @@ CTLayout::~CTLayout()
CFRelease( mpCTLine ); CFRelease( mpCTLine );
if( mpAttrString ) if( mpAttrString )
CFRelease( mpAttrString ); CFRelease( mpAttrString );
CFRelease( mpTextStyle->GetStyleDict() ); CFRelease( mpStyleDict );
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
...@@ -131,7 +135,7 @@ bool CTLayout::LayoutText( ImplLayoutArgs& rArgs ) ...@@ -131,7 +135,7 @@ bool CTLayout::LayoutText( ImplLayoutArgs& rArgs )
} }
// create the CoreText line layout using the requested text style // create the CoreText line layout using the requested text style
mpAttrString = CFAttributedStringCreate( NULL, aCFText, mpTextStyle->GetStyleDict() ); mpAttrString = CFAttributedStringCreate( NULL, aCFText, mpStyleDict );
mpCTLine = CTLineCreateWithAttributedString( mpAttrString ); mpCTLine = CTLineCreateWithAttributedString( mpAttrString );
CFRelease( aCFText); CFRelease( aCFText);
...@@ -201,7 +205,7 @@ void CTLayout::AdjustLayout( ImplLayoutArgs& rArgs ) ...@@ -201,7 +205,7 @@ void CTLayout::AdjustLayout( ImplLayoutArgs& rArgs )
CFRelease( mpCTLine ); CFRelease( mpCTLine );
CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, rArgs.mpStr + mnMinCharPos, CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, rArgs.mpStr + mnMinCharPos,
mnCharCount - mnTrailingSpaceCount, kCFAllocatorNull ); mnCharCount - mnTrailingSpaceCount, kCFAllocatorNull );
CFAttributedStringRef pAttrStr = CFAttributedStringCreate( NULL, aCFText, mpTextStyle->GetStyleDict() ); CFAttributedStringRef pAttrStr = CFAttributedStringCreate( NULL, aCFText, mpStyleDict );
mpCTLine = CTLineCreateWithAttributedString( pAttrStr ); mpCTLine = CTLineCreateWithAttributedString( pAttrStr );
CFRelease( aCFText); CFRelease( aCFText);
CFRelease( pAttrStr ); CFRelease( pAttrStr );
...@@ -249,12 +253,11 @@ void CTLayout::DrawText( SalGraphics& rGraphics ) const ...@@ -249,12 +253,11 @@ void CTLayout::DrawText( SalGraphics& rGraphics ) const
const Point aVclPos = GetDrawPosition( Point(mnBaseAdv,0) ); const Point aVclPos = GetDrawPosition( Point(mnBaseAdv,0) );
CGPoint aTextPos = { +aVclPos.X()/mfFontScale, -aVclPos.Y()/mfFontScale }; CGPoint aTextPos = { +aVclPos.X()/mfFontScale, -aVclPos.Y()/mfFontScale };
if( mpTextStyle->mfFontRotation != 0.0 ) if( mfFontRotation != 0.0 )
{ {
const CGFloat fRadians = mpTextStyle->mfFontRotation; CGContextRotateCTM( rAquaGraphics.mrContext, +mfFontRotation );
CGContextRotateCTM( rAquaGraphics.mrContext, +fRadians );
const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians ); const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -mfFontRotation );
aTextPos = CGPointApplyAffineTransform( aTextPos, aInvMatrix ); aTextPos = CGPointApplyAffineTransform( aTextPos, aInvMatrix );
} }
...@@ -353,12 +356,12 @@ int CTLayout::GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, i ...@@ -353,12 +356,12 @@ int CTLayout::GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, i
// convert glyph details for VCL // convert glyph details for VCL
*(pOutGlyphIds++) = pCGGlyphIdx[ nSubIndex ]; *(pOutGlyphIds++) = pCGGlyphIdx[ nSubIndex ];
if( pGlyphAdvances ) if( pGlyphAdvances )
*(pGlyphAdvances++) = pCGGlyphAdvs[ nSubIndex ].width; *(pGlyphAdvances++) = mfFontStretch * pCGGlyphAdvs[ nSubIndex ].width;
if( pCharIndexes ) if( pCharIndexes )
*(pCharIndexes++) = pCGGlyphStrIdx[ nSubIndex] + mnMinCharPos; *(pCharIndexes++) = pCGGlyphStrIdx[ nSubIndex] + mnMinCharPos;
if( !nCount++ ) { if( !nCount++ ) {
const CGPoint& rCurPos = pCGGlyphPos[ nSubIndex ]; const CGPoint& rCurPos = pCGGlyphPos[ nSubIndex ];
rPos = GetDrawPosition( Point( mfFontScale * rCurPos.x, mfFontScale * rCurPos.y) ); rPos = GetDrawPosition( Point( mfFontScale * mfFontStretch * rCurPos.x, mfFontScale * rCurPos.y) );
} }
} }
nSubIndex = 0; // prepare for the next glyph run nSubIndex = 0; // prepare for the next glyph run
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment