You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2014/03/19 11:15:07 UTC
svn commit: r1579184 [30/33] - in /openoffice/branches/alg_writerframes: ./
ext_sources/ extras/l10n/source/de/ extras/l10n/source/es/
extras/l10n/source/eu/ extras/l10n/source/hi/ extras/l10n/source/kk/
extras/l10n/source/lt/ extras/l10n/source/nb/ ex...
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.cxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.cxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.cxx Wed Mar 19 10:14:42 2014
@@ -19,302 +19,547 @@
*
*************************************************************/
-
-
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <boost/assert.hpp>
#include <vector>
+#include <hash_map>
#include <set>
+#include "salgdi.h"
+#include "atsfonts.hxx"
+
#include "vcl/svapp.hxx"
+#include "vcl/impfont.hxx"
-#include "aqua/salgdi.h"
-#include "aqua/saldata.hxx"
-#include "atsfonts.hxx"
-#include "impfont.hxx"
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
+
+typedef GlyphID ATSGlyphID;
+
+// =======================================================================
+
+// mac specific physically available font face
+class AtsFontData
+: public ImplMacFontData
+{
+public:
+ explicit AtsFontData( const ImplDevFontAttributes&, ATSUFontID );
+ virtual ~AtsFontData( void );
+ virtual ImplFontData* Clone( void ) const;
+
+ virtual ImplMacTextStyle* CreateMacTextStyle( const ImplFontSelectData& ) const;
+ virtual ImplFontEntry* CreateFontInstance( /*const*/ ImplFontSelectData& ) const;
+ virtual int GetFontTable( const char pTagName[5], unsigned char* ) const;
+};
+
+// =======================================================================
+
+class AtsFontList
+: public SystemFontList
+{
+public:
+ explicit AtsFontList( void );
+ virtual ~AtsFontList( void );
+
+ virtual void AnnounceFonts( ImplDevFontList& ) const;
+ virtual ImplMacFontData* GetFontDataFromId( sal_IntPtr nFontId ) const;
+
+private:
+ typedef std::hash_map<sal_IntPtr,AtsFontData*> AtsFontContainer;
+ AtsFontContainer maFontContainer;
+
+ void InitGlyphFallbacks( void );
+ ATSUFontFallbacks maFontFallbacks;
+};
+
+// =======================================================================
+
+AtsFontData::AtsFontData( const ImplDevFontAttributes& rDFA, ATSUFontID nFontId )
+: ImplMacFontData( rDFA, (sal_IntPtr)nFontId )
+{}
+
+// -----------------------------------------------------------------------
+
+AtsFontData::~AtsFontData( void )
+{}
+
+// -----------------------------------------------------------------------
+
+ImplFontData* AtsFontData::Clone( void ) const
+{
+ AtsFontData* pClone = new AtsFontData(*this);
+ return pClone;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMacTextStyle* AtsFontData::CreateMacTextStyle( const ImplFontSelectData& rFSD ) const
+{
+ return new AtsTextStyle( rFSD );
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontEntry* AtsFontData::CreateFontInstance( /*const*/ ImplFontSelectData& rFSD ) const
+{
+ return new ImplFontEntry( rFSD );
+}
+
+// -----------------------------------------------------------------------
+
+int AtsFontData::GetFontTable( const char pTagName[5], unsigned char* pResultBuf ) const
+{
+ DBG_ASSERT( aTagName[4]=='\0', "AtsFontData::GetFontTable with invalid tagname!\n" );
+
+ const FourCharCode pTagCode = (pTagName[0]<<24) + (pTagName[1]<<16) + (pTagName[2]<<8) + (pTagName[3]<<0);
+
+ // get the byte size of the raw table
+ ATSFontRef rATSFont = FMGetATSFontRefFromFont( (ATSUFontID)mnFontId );
+ ByteCount nBufSize = 0;
+ OSStatus eStatus = ATSFontGetTable( rATSFont, pTagCode, 0, 0, NULL, &nBufSize );
+ if( eStatus != noErr )
+ return 0;
+
+ // get the raw table data if requested
+ if( pResultBuf && (nBufSize > 0))
+ {
+ ByteCount nRawLength = 0;
+ eStatus = ATSFontGetTable( rATSFont, pTagCode, 0, nBufSize, (void*)pResultBuf, &nRawLength );
+ if( eStatus != noErr )
+ return 0;
+ DBG_ASSERT( (nBufSize==nRawLength), "AtsFontData::GetFontTable ByteCount mismatch!\n");
+ }
+
+ return nBufSize;
+}
+
+// =======================================================================
+
+AtsTextStyle::AtsTextStyle( const ImplFontSelectData& rFSD )
+: ImplMacTextStyle( rFSD )
+{
+ // create the style object for ATSUI font attributes
+ ATSUCreateStyle( &maATSUStyle );
+ const ImplFontSelectData* const pReqFont = &rFSD;
+
+ mpFontData = (AtsFontData*)rFSD.mpFontData;
+
+ // limit the ATS font size to avoid Fixed16.16 overflows
+ double fScaledFontHeight = pReqFont->mfExactHeight;
+ static const float fMaxFontHeight = 144.0;
+ if( fScaledFontHeight > fMaxFontHeight )
+ {
+ mfFontScale = fScaledFontHeight / fMaxFontHeight;
+ fScaledFontHeight = fMaxFontHeight;
+ }
+
+ // convert font rotation to radian
+ mfFontRotation = pReqFont->mnOrientation * (M_PI / 1800.0);
+
+ // determine if font stretching is needed
+ if( (pReqFont->mnWidth != 0) && (pReqFont->mnWidth != pReqFont->mnHeight) )
+ {
+ mfFontStretch = (float)pReqFont->mnWidth / pReqFont->mnHeight;
+ // set text style to stretching matrix
+ CGAffineTransform aMatrix = CGAffineTransformMakeScale( mfFontStretch, 1.0F );
+ const ATSUAttributeTag aMatrixTag = kATSUFontMatrixTag;
+ const ATSUAttributeValuePtr aAttr = &aMatrix;
+ const ByteCount aMatrixBytes = sizeof(aMatrix);
+ /*OSStatus eStatus =*/ ATSUSetAttributes( maATSUStyle, 1, &aMatrixTag, &aMatrixBytes, &aAttr );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+AtsTextStyle::~AtsTextStyle( void )
+{
+ ATSUDisposeStyle( maATSUStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void AtsTextStyle::GetFontMetric( float fDPIY, ImplFontMetricData& rMetric ) const
+{
+ // get the font metrics (in point units)
+ // of the font that has eventually been size-limited
+
+ // get the matching ATSU font handle
+ ATSUFontID fontId;
+ OSStatus err = ::ATSUGetAttribute( maATSUStyle, kATSUFontTag, sizeof(ATSUFontID), &fontId, 0 );
+ DBG_ASSERT( (err==noErr), "AquaSalGraphics::GetFontMetric() : could not get font id\n");
+
+ ATSFontMetrics aMetrics;
+ ATSFontRef rFont = FMGetATSFontRefFromFont( fontId );
+ err = ATSFontGetHorizontalMetrics ( rFont, kATSOptionFlagsDefault, &aMetrics );
+ DBG_ASSERT( (err==noErr), "AquaSalGraphics::GetFontMetric() : could not get font metrics\n");
+ if( err != noErr )
+ return;
+
+ // all ATS fonts are scalable fonts
+ rMetric.mbScalableFont = true;
+ // TODO: check if any kerning is possible
+ rMetric.mbKernableFont = true;
+
+ // convert into VCL font metrics (in unscaled pixel units)
+
+ Fixed ptSize;
+ err = ATSUGetAttribute( maATSUStyle, kATSUSizeTag, sizeof(Fixed), &ptSize, 0);
+ DBG_ASSERT( (err==noErr), "AquaSalGraphics::GetFontMetric() : could not get font size\n");
+ const double fPointSize = Fix2X( ptSize );
+
+ // convert quartz units to pixel units
+ // please see the comment in AquaSalGraphics::SetFont() for details
+ const double fPixelSize = (mfFontScale * fDPIY * fPointSize);
+ rMetric.mnAscent = static_cast<long>(+aMetrics.ascent * fPixelSize + 0.5);
+ rMetric.mnDescent = static_cast<long>(-aMetrics.descent * fPixelSize + 0.5);
+ const long nExtDescent = static_cast<long>((-aMetrics.descent + aMetrics.leading) * fPixelSize + 0.5);
+ rMetric.mnExtLeading = nExtDescent - rMetric.mnDescent;
+ rMetric.mnIntLeading = 0;
+ // since ImplFontMetricData::mnWidth is only used for stretching/squeezing fonts
+ // setting this width to the pixel height of the fontsize is good enough
+ // it also makes the calculation of the stretch factor simple
+ rMetric.mnWidth = static_cast<long>(mfFontStretch * fPixelSize + 0.5);
+}
+
+// -----------------------------------------------------------------------
+
+void AtsTextStyle::SetTextColor( const RGBAColor& rColor )
+{
+ RGBColor aAtsColor;
+ aAtsColor.red = (unsigned short)( rColor.GetRed() * 65535.0 );
+ aAtsColor.green = (unsigned short)( rColor.GetGreen() * 65535.0 );
+ aAtsColor.blue = (unsigned short)( rColor.GetColor() * 65535.0 );
+
+ ATSUAttributeTag aTag = kATSUColorTag;
+ ByteCount aValueSize = sizeof( aAtsColor );
+ ATSUAttributeValuePtr aValue = &aAtsColor;
+
+ /*OSStatus err =*/ ATSUSetAttributes( maATSUStyle, 1, &aTag, &aValueSize, &aValue );
+}
+
+// -----------------------------------------------------------------------
+
+bool AtsTextStyle::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect ) const
+{
+ ATSUStyle rATSUStyle = maATSUStyle; // TODO: handle glyph fallback
+ ATSGlyphID aGlyphId = aGlyphId;
+ ATSGlyphScreenMetrics aGlyphMetrics;
+ const bool bNonAntialiasedText = false;
+ OSStatus eStatus = ATSUGlyphGetScreenMetrics( rATSUStyle,
+ 1, &aGlyphId, 0, FALSE, !bNonAntialiasedText, &aGlyphMetrics );
+ if( eStatus != noErr )
+ return false;
+
+ const long nMinX = (long)(+aGlyphMetrics.topLeft.x * mfFontScale - 0.5);
+ const long nMaxX = (long)(aGlyphMetrics.width * mfFontScale + 0.5) + nMinX;
+ const long nMinY = (long)(-aGlyphMetrics.topLeft.y * mfFontScale - 0.5);
+ const long nMaxY = (long)(aGlyphMetrics.height * mfFontScale + 0.5) + nMinY;
+ rRect = Rectangle( nMinX, nMinY, nMaxX, nMaxY );
+ return true;
+}
// -----------------------------------------------------------------------
+// callbacks from ATSUGlyphGetCubicPaths() fore GetGlyphOutline()
+struct GgoData { basegfx::B2DPolygon maPolygon; basegfx::B2DPolyPolygon* mpPolyPoly; };
+
+static OSStatus GgoLineToProc( const Float32Point* pPoint, void* pData )
+{
+ basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon;
+ const basegfx::B2DPoint aB2DPoint( pPoint->x, pPoint->y );
+ rPolygon.append( aB2DPoint );
+ return noErr;
+}
+
+static OSStatus GgoCurveToProc( const Float32Point* pCP1, const Float32Point* pCP2,
+ const Float32Point* pPoint, void* pData )
+{
+ basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon;
+ const sal_uInt32 nPointCount = rPolygon.count();
+ const basegfx::B2DPoint aB2DControlPoint1( pCP1->x, pCP1->y );
+ rPolygon.setNextControlPoint( nPointCount-1, aB2DControlPoint1 );
+ const basegfx::B2DPoint aB2DEndPoint( pPoint->x, pPoint->y );
+ rPolygon.append( aB2DEndPoint );
+ const basegfx::B2DPoint aB2DControlPoint2( pCP2->x, pCP2->y );
+ rPolygon.setPrevControlPoint( nPointCount, aB2DControlPoint2 );
+ return noErr;
+}
+
+static OSStatus GgoClosePathProc( void* pData )
+{
+ GgoData* pGgoData = static_cast<GgoData*>(pData);
+ basegfx::B2DPolygon& rPolygon = pGgoData->maPolygon;
+ if( rPolygon.count() > 0 )
+ pGgoData->mpPolyPoly->append( rPolygon );
+ rPolygon.clear();
+ return noErr;
+}
+
+static OSStatus GgoMoveToProc( const Float32Point* pPoint, void* pData )
+{
+ GgoClosePathProc( pData );
+ OSStatus eStatus = GgoLineToProc( pPoint, pData );
+ return eStatus;
+}
+
+bool AtsTextStyle::GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& rResult ) const
+{
+ GgoData aGgoData;
+ aGgoData.mpPolyPoly = &rResult;
+ rResult.clear();
+
+ OSStatus eGgoStatus = noErr;
+ OSStatus eStatus = ATSUGlyphGetCubicPaths( maATSUStyle, aGlyphId,
+ GgoMoveToProc, GgoLineToProc, GgoCurveToProc, GgoClosePathProc,
+ &aGgoData, &eGgoStatus );
+ if( (eStatus != noErr) ) // TODO: why is (eGgoStatus!=noErr) when curves are involved?
+ return false;
+
+ GgoClosePathProc( &aGgoData );
+
+ // apply the font scale
+ if( mfFontScale != 1.0 ) {
+ basegfx::B2DHomMatrix aScale;
+ aScale.scale( +mfFontScale, +mfFontScale );
+ rResult.transform( aScale );
+ }
+
+ return true;
+}
+
+// =======================================================================
+
static bool GetDevFontAttributes( ATSUFontID nFontID, ImplDevFontAttributes& rDFA )
{
- // all ATSU fonts are device fonts that can be directly rotated
- rDFA.mbOrientation = true;
- rDFA.mbDevice = true;
- rDFA.mnQuality = 0;
-
- // reset the attributes
- rDFA.meFamily = FAMILY_DONTKNOW;
- rDFA.mePitch = PITCH_VARIABLE;
- rDFA.meWidthType = WIDTH_NORMAL;
- rDFA.meWeight = WEIGHT_NORMAL;
- rDFA.meItalic = ITALIC_NONE;
- rDFA.mbSymbolFlag = false;
-
- // ignore bitmap fonts
- ATSFontRef rATSFontRef = FMGetATSFontRefFromFont( nFontID );
- ByteCount nHeadLen = 0;
- OSStatus rc = ATSFontGetTable( rATSFontRef, 0x68656164/*head*/, 0, 0, NULL, &nHeadLen );
- if( (rc != noErr) || (nHeadLen <= 0) )
- return false;
+ // all ATSU fonts are device fonts that can be directly rotated
+ rDFA.mbOrientation = true;
+ rDFA.mbDevice = true;
+ rDFA.mnQuality = 0;
+
+ // reset the attributes
+ rDFA.meFamily = FAMILY_DONTKNOW;
+ rDFA.mePitch = PITCH_VARIABLE;
+ rDFA.meWidthType = WIDTH_NORMAL;
+ rDFA.meWeight = WEIGHT_NORMAL;
+ rDFA.meItalic = ITALIC_NONE;
+ rDFA.mbSymbolFlag = false;
+
+ // ignore bitmap fonts
+ ATSFontRef rATSFontRef = FMGetATSFontRefFromFont( nFontID );
+ ByteCount nHeadLen = 0;
+ OSStatus rc = ATSFontGetTable( rATSFontRef, 0x68656164/*head*/, 0, 0, NULL, &nHeadLen );
+ if( (rc != noErr) || (nHeadLen <= 0) )
+ return false;
// all scalable fonts on this platform are subsettable
rDFA.mbSubsettable = true;
rDFA.mbEmbeddable = false;
+ // TODO: these members are needed only for our X11 platform targets
+ rDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
+ rDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
// prepare iterating over all name strings of the font
- ItemCount nFontNameCount = 0;
- rc = ATSUCountFontNames( nFontID, &nFontNameCount );
- if( rc != noErr )
- return false;
- int nBestNameValue = 0;
- int nBestStyleValue = 0;
+ ItemCount nFontNameCount = 0;
+ rc = ATSUCountFontNames( nFontID, &nFontNameCount );
+ if( rc != noErr )
+ return false;
+ int nBestNameValue = 0;
+ int nBestStyleValue = 0;
FontLanguageCode eBestLangCode = 0;
const FontLanguageCode eUILangCode = Application::GetSettings().GetUILanguage();
typedef std::vector<char> NameBuffer;
- NameBuffer aNameBuffer( 256 );
+ NameBuffer aNameBuffer( 256 );
+
+ // iterate over all available name strings of the font
+ for( ItemCount nNameIndex = 0; nNameIndex < nFontNameCount; ++nNameIndex )
+ {
+ ByteCount nNameLength = 0;
+
+ FontNameCode eFontNameCode;
+ FontPlatformCode eFontNamePlatform;
+ FontScriptCode eFontNameScript;
+ FontLanguageCode eFontNameLanguage;
+ rc = ATSUGetIndFontName( nFontID, nNameIndex, 0, NULL,
+ &nNameLength, &eFontNameCode, &eFontNamePlatform, &eFontNameScript, &eFontNameLanguage );
+ if( rc != noErr )
+ continue;
+
+ // ignore non-interesting name entries
+ if( (eFontNameCode != kFontFamilyName)
+ && (eFontNameCode != kFontStyleName)
+ && (eFontNameCode != kFontPostscriptName) )
+ continue;
+
+ // heuristic to find the most common font name
+ // prefering default language names or even better the names matching to the UI language
+ int nNameValue = (eFontNameLanguage==eUILangCode) ? 0 : ((eFontNameLanguage==0) ? -10 : -20);
+ rtl_TextEncoding eEncoding = RTL_TEXTENCODING_UNICODE;
+ const int nPlatformEncoding = ((int)eFontNamePlatform << 8) + (int)eFontNameScript;
+ switch( nPlatformEncoding )
+ {
+ case 0x000: nNameValue += 23; break; // Unicode 1.0
+ case 0x001: nNameValue += 24; break; // Unicode 1.1
+ case 0x002: nNameValue += 25; break; // iso10646_1993
+ case 0x003: nNameValue += 26; break; // UCS-2
+ case 0x301: nNameValue += 27; break; // Win UCS-2
+ case 0x004: // UCS-4
+ case 0x30A: nNameValue += 0; // Win-UCS-4
+ eEncoding = RTL_TEXTENCODING_UCS4;
+ break;
+ case 0x100: nNameValue += 21; // Mac Roman
+ eEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
+ break;
+ case 0x300: nNameValue = 0; // Win Symbol encoded name!
+ rDFA.mbSymbolFlag = true; // (often seen for symbol fonts)
+ break;
+ default: nNameValue = 0; // ignore other encodings
+ break;
+ }
+
+ // ignore name entries with no useful encoding
+ if( nNameValue <= 0 )
+ continue;
+ if( nNameLength >= aNameBuffer.size() )
+ continue;
+
+ // get the encoded name
+ aNameBuffer.reserve( nNameLength+1 ); // extra byte helps for debugging
+ rc = ATSUGetIndFontName( nFontID, nNameIndex, nNameLength, &aNameBuffer[0],
+ &nNameLength, &eFontNameCode, &eFontNamePlatform, &eFontNameScript, &eFontNameLanguage );
+ if( rc != noErr )
+ continue;
+
+ // convert to unicode name
+ UniString aUtf16Name;
+ if( eEncoding == RTL_TEXTENCODING_UNICODE ) // we are just interested in UTF16 encoded names
+ aUtf16Name = UniString( (const sal_Unicode*)&aNameBuffer[0], nNameLength/2 );
+ else if( eEncoding == RTL_TEXTENCODING_UCS4 )
+ aUtf16Name = UniString(); // TODO
+ else // assume the non-unicode encoded names are byte encoded
+ aUtf16Name = UniString( &aNameBuffer[0], nNameLength, eEncoding );
+
+ // ignore empty strings
+ if( aUtf16Name.Len() <= 0 )
+ continue;
- // iterate over all available name strings of the font
- for( ItemCount nNameIndex = 0; nNameIndex < nFontNameCount; ++nNameIndex )
- {
- ByteCount nNameLength = 0;
-
- FontNameCode eFontNameCode;
- FontPlatformCode eFontNamePlatform;
- FontScriptCode eFontNameScript;
- FontLanguageCode eFontNameLanguage;
- rc = ATSUGetIndFontName( nFontID, nNameIndex, 0, NULL,
- &nNameLength, &eFontNameCode, &eFontNamePlatform, &eFontNameScript, &eFontNameLanguage );
- if( rc != noErr )
- continue;
-
- // ignore non-interesting name entries
- if( (eFontNameCode != kFontFamilyName)
- && (eFontNameCode != kFontStyleName)
- && (eFontNameCode != kFontPostscriptName) )
- continue;
-
- // heuristic to find the most common font name
- // prefering default language names or even better the names matching to the UI language
- int nNameValue = (eFontNameLanguage==eUILangCode) ? 0 : ((eFontNameLanguage==0) ? -10 : -20);
- rtl_TextEncoding eEncoding = RTL_TEXTENCODING_UNICODE;
- const int nPlatformEncoding = ((int)eFontNamePlatform << 8) + (int)eFontNameScript;
- switch( nPlatformEncoding )
- {
- case 0x000: nNameValue += 23; break; // Unicode 1.0
- case 0x001: nNameValue += 24; break; // Unicode 1.1
- case 0x002: nNameValue += 25; break; // iso10646_1993
- case 0x003: nNameValue += 26; break; // UCS-2
- case 0x301: nNameValue += 27; break; // Win UCS-2
- case 0x004: // UCS-4
- case 0x30A: nNameValue += 0; // Win-UCS-4
- eEncoding = RTL_TEXTENCODING_UCS4;
- break;
- case 0x100: nNameValue += 21; // Mac Roman
- eEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
- break;
- case 0x300: nNameValue = 0; // Win Symbol encoded name!
- rDFA.mbSymbolFlag = true; // (often seen for symbol fonts)
- break;
- default: nNameValue = 0; // ignore other encodings
+ // handle the name depending on its namecode
+ switch( eFontNameCode )
+ {
+ case kFontFamilyName:
+ // ignore font names starting with '.'
+ if( aUtf16Name.GetChar(0) == '.' )
+ nNameValue = 0;
+ else if( rDFA.maName.Len() )
+ {
+ // even if a family name is not the one we are looking for
+ // it is still useful as a font name alternative
+ if( rDFA.maMapNames.Len() )
+ rDFA.maMapNames += ';';
+ rDFA.maMapNames += (nBestNameValue < nNameValue) ? rDFA.maName : aUtf16Name;
+ }
+ if( nBestNameValue < nNameValue )
+ {
+ // get the best family name
+ nBestNameValue = nNameValue;
+ eBestLangCode = eFontNameLanguage;
+ rDFA.maName = aUtf16Name;
+ }
+ break;
+ case kFontStyleName:
+ // get a style name matching to the family name
+ if( nBestStyleValue < nNameValue )
+ {
+ nBestStyleValue = nNameValue;
+ rDFA.maStyleName = aUtf16Name;
+ }
+ break;
+ case kFontPostscriptName:
+ // use the postscript name to get some useful info
+ UpdateAttributesFromPSName( aUtf16Name, rDFA );
+ break;
+ default:
+ // TODO: use other name entries too?
break;
- }
+ }
+ }
- // ignore name entries with no useful encoding
- if( nNameValue <= 0 )
- continue;
- if( nNameLength >= aNameBuffer.size() )
- continue;
-
- // get the encoded name
- aNameBuffer.reserve( nNameLength+1 ); // extra byte helps for debugging
- rc = ATSUGetIndFontName( nFontID, nNameIndex, nNameLength, &aNameBuffer[0],
- &nNameLength, &eFontNameCode, &eFontNamePlatform, &eFontNameScript, &eFontNameLanguage );
- if( rc != noErr )
- continue;
-
- // convert to unicode name
- UniString aUtf16Name;
- if( eEncoding == RTL_TEXTENCODING_UNICODE ) // we are just interested in UTF16 encoded names
- aUtf16Name = UniString( (const sal_Unicode*)&aNameBuffer[0], nNameLength/2 );
- else if( eEncoding == RTL_TEXTENCODING_UCS4 )
- aUtf16Name = UniString(); // TODO
- else // assume the non-unicode encoded names are byte encoded
- aUtf16Name = UniString( &aNameBuffer[0], nNameLength, eEncoding );
-
- // ignore empty strings
- if( aUtf16Name.Len() <= 0 )
- continue;
+ bool bRet = (rDFA.maName.Len() > 0);
+ return bRet;
+}
- // handle the name depending on its namecode
- switch( eFontNameCode )
- {
- case kFontFamilyName:
- // ignore font names starting with '.'
- if( aUtf16Name.GetChar(0) == '.' )
- nNameValue = 0;
- else if( rDFA.maName.Len() )
- {
- // even if a family name is not the one we are looking for
- // it is still useful as a font name alternative
- if( rDFA.maMapNames.Len() )
- rDFA.maMapNames += ';';
- rDFA.maMapNames += (nBestNameValue < nNameValue) ? rDFA.maName : aUtf16Name;
- }
- if( nBestNameValue < nNameValue )
- {
- // get the best family name
- nBestNameValue = nNameValue;
- eBestLangCode = eFontNameLanguage;
- rDFA.maName = aUtf16Name;
- }
- break;
- case kFontStyleName:
- // get a style name matching to the family name
- if( nBestStyleValue < nNameValue )
- {
- nBestStyleValue = nNameValue;
- rDFA.maStyleName = aUtf16Name;
- }
- break;
- case kFontPostscriptName:
- // use the postscript name to get some useful info
- UpdateAttributesFromPSName( aUtf16Name, rDFA );
- break;
- default:
- // TODO: use other name entries too?
- break;
- }
- }
-
-#if 0 // multiple-master fonts are mostly obsolete nowadays
- // if we still want to support them this should probably be done one frame higher
- ItemCount nMaxInstances = 0;
- rc = ATSUCountFontInstances ( nFontID, &nMaxInstances );
- for( ItemCount nInstanceIndex = 0; nInstanceIndex < nMaxInstances; ++nInstanceIndex )
- {
- ItemCount nMaxVariations = 0;
- rc = ATSUGetFontInstance( nFontID, nInstanceIndex, 0, NULL, NULL, &nMaxVariations );
- if( (rc == noErr) && (nMaxVariations > 0) )
- {
- fprintf(stderr,"\tnMaxVariations=%d\n",(int)nMaxVariations);
- typedef ::std::vector<ATSUFontVariationAxis> VariationAxisVector;
- typedef ::std::vector<ATSUFontVariationValue> VariationValueVector;
- VariationAxisVector aVariationAxes( nMaxVariations );
- VariationValueVector aVariationValues( nMaxVariations );
- ItemCount nVariationCount = 0;
- rc = ATSUGetFontInstance ( nFontID, nInstanceIndex, nMaxVariations,
- &aVariationAxes[0], &aVariationValues[0], &nVariationCount );
- fprintf(stderr,"\tnVariationCount=%d\n",(int)nVariationCount);
- for( ItemCount nVariationIndex = 0; nVariationIndex < nMaxVariations; ++nVariationIndex )
- {
- const char* pTag = (const char*)&aVariationAxes[nVariationIndex];
- fprintf(stderr,"\tvariation[%d] \'%c%c%c%c\' is %d\n", (int)nVariationIndex,
- pTag[3],pTag[2],pTag[1],pTag[0], (int)aVariationValues[nVariationIndex]);
- }
- }
- }
-#endif
-
-#if 0 // selecting non-defaulted font features is not enabled yet
- ByteString aFName( rDFA.maName, RTL_TEXTENCODING_UTF8 );
- ByteString aSName( rDFA.maStyleName, RTL_TEXTENCODING_UTF8 );
- ItemCount nMaxFeatures = 0;
- rc = ATSUCountFontFeatureTypes( nFontID, &nMaxFeatures );
- fprintf(stderr,"Font \"%s\" \"%s\" has %d features\n",aFName.GetBuffer(),aSName.GetBuffer(),rc);
- if( (rc == noErr) && (nMaxFeatures > 0) )
- {
- typedef std::vector<ATSUFontFeatureType> FeatureVector;
- FeatureVector aFeatureVector( nMaxFeatures );
- ItemCount nFeatureCount = 0;
- rc = ATSUGetFontFeatureTypes( nFontID, nMaxFeatures, &aFeatureVector[0], &nFeatureCount );
- fprintf(stderr,"nFeatureCount=%d\n",(int)nFeatureCount);
- for( ItemCount nFeatureIndex = 0; nFeatureIndex < nFeatureCount; ++nFeatureIndex )
- {
- ItemCount nMaxSelectors = 0;
- rc = ATSUCountFontFeatureSelectors( nFontID, aFeatureVector[nFeatureIndex], &nMaxSelectors );
- fprintf(stderr,"\tFeature[%d] = %d has %d selectors\n",
- (int)nFeatureIndex, (int)aFeatureVector[nFeatureIndex], (int)nMaxSelectors );
- typedef std::vector<ATSUFontFeatureSelector> SelectorVector;
- SelectorVector aSelectorVector( nMaxSelectors );
- typedef std::vector<MacOSBoolean> BooleanVector;
- BooleanVector aEnabledVector( nMaxSelectors );
- BooleanVector aExclusiveVector( nMaxSelectors );
- ItemCount nSelectorCount = 0;
- rc = ATSUGetFontFeatureSelectors ( nFontID, aFeatureVector[nFeatureIndex], nMaxSelectors,
- &aSelectorVector[0], &aEnabledVector[0], &nSelectorCount, &aExclusiveVector[0]);
- for( ItemCount nSelectorIndex = 0; nSelectorIndex < nSelectorCount; ++nSelectorIndex )
- {
- FontNameCode eFontNameCode;
- rc = ATSUGetFontFeatureNameCode( nFontID, aFeatureVector[nFeatureIndex],
- aSelectorVector[nSelectorIndex], &eFontNameCode );
- fprintf(stderr,"\t\tselector[%d] n=%d e=%d, x=%d\n",
- (int)nSelectorIndex, (int)eFontNameCode,
- aEnabledVector[nSelectorIndex], aExclusiveVector[nSelectorIndex] );
- }
- }
- }
-#endif
+// =======================================================================
- bool bRet = (rDFA.maName.Len() > 0);
- return bRet;
+SystemFontList* GetAtsFontList( void )
+{
+ return new AtsFontList();
}
// =======================================================================
-SystemFontList::SystemFontList()
+AtsFontList::AtsFontList()
{
- // count available system fonts
- ItemCount nATSUICompatibleFontsAvailable = 0;
- if( ATSUFontCount(&nATSUICompatibleFontsAvailable) != noErr )
- return;
- if( nATSUICompatibleFontsAvailable <= 0 )
- return;
+ // count available system fonts
+ ItemCount nATSUICompatibleFontsAvailable = 0;
+ if( ATSUFontCount(&nATSUICompatibleFontsAvailable) != noErr )
+ return;
+ if( nATSUICompatibleFontsAvailable <= 0 )
+ return;
+
+ // enumerate available system fonts
+ typedef std::vector<ATSUFontID> AtsFontIDVector;
+ AtsFontIDVector aFontIDVector( nATSUICompatibleFontsAvailable );
+ ItemCount nFontItemsCount = 0;
+ if( ATSUGetFontIDs( &aFontIDVector[0], aFontIDVector.capacity(), &nFontItemsCount ) != noErr )
+ return;
+
+ BOOST_ASSERT(nATSUICompatibleFontsAvailable == nFontItemsCount && "Strange I would expect them to be equal");
+
+ // prepare use of the available fonts
+ AtsFontIDVector::const_iterator it = aFontIDVector.begin();
+ for(; it != aFontIDVector.end(); ++it )
+ {
+ const ATSUFontID nFontID = *it;
+ ImplDevFontAttributes aDevFontAttr;
+ if( !GetDevFontAttributes( nFontID, aDevFontAttr ) )
+ continue;
+ AtsFontData* pFontData = new AtsFontData( aDevFontAttr, nFontID );
+ maFontContainer[ nFontID ] = pFontData;
+ }
- // enumerate available system fonts
- typedef std::vector<ATSUFontID> AtsFontIDVector;
- AtsFontIDVector aFontIDVector( nATSUICompatibleFontsAvailable );
- ItemCount nFontItemsCount = 0;
- if( ATSUGetFontIDs( &aFontIDVector[0], aFontIDVector.capacity(), &nFontItemsCount ) != noErr )
- return;
+ InitGlyphFallbacks();
+}
- BOOST_ASSERT(nATSUICompatibleFontsAvailable == nFontItemsCount && "Strange I would expect them to be equal");
+// -----------------------------------------------------------------------
- // prepare use of the available fonts
- AtsFontIDVector::const_iterator it = aFontIDVector.begin();
- for(; it != aFontIDVector.end(); ++it )
- {
- const ATSUFontID nFontID = *it;
- ImplDevFontAttributes aDevFontAttr;
- if( !GetDevFontAttributes( nFontID, aDevFontAttr ) )
- continue;
- ImplMacFontData* pFontData = new ImplMacFontData( aDevFontAttr, nFontID );
- maFontContainer[ nFontID ] = pFontData;
- }
+AtsFontList::~AtsFontList()
+{
+ AtsFontContainer::const_iterator it = maFontContainer.begin();
+ for(; it != maFontContainer.end(); ++it )
+ delete (*it).second;
+ maFontContainer.clear();
- InitGlyphFallbacks();
+ ATSUDisposeFontFallbacks( maFontFallbacks );
}
// -----------------------------------------------------------------------
-SystemFontList::~SystemFontList()
+void AtsFontList::AnnounceFonts( ImplDevFontList& rFontList ) const
{
- MacFontContainer::const_iterator it = maFontContainer.begin();
- for(; it != maFontContainer.end(); ++it )
- delete (*it).second;
- maFontContainer.clear();
-
- ATSUDisposeFontFallbacks( maFontFallbacks );
+ AtsFontContainer::const_iterator it = maFontContainer.begin();
+ for(; it != maFontContainer.end(); ++it )
+ rFontList.Add( (*it).second->Clone() );
}
// -----------------------------------------------------------------------
-void SystemFontList::AnnounceFonts( ImplDevFontList& rFontList ) const
+ImplMacFontData* AtsFontList::GetFontDataFromId( sal_IntPtr nFontId ) const
{
- MacFontContainer::const_iterator it = maFontContainer.begin();
- for(; it != maFontContainer.end(); ++it )
- rFontList.Add( (*it).second->Clone() );
+ AtsFontContainer::const_iterator it = maFontContainer.find( nFontId );
+ if( it == maFontContainer.end() )
+ return NULL;
+ return (*it).second;
}
// -----------------------------------------------------------------------
@@ -352,46 +597,38 @@ inline bool GfbCompare::operator()( cons
return false;
}
-void SystemFontList::InitGlyphFallbacks()
-{
- // sort fonts for "glyph fallback"
- typedef std::multiset<const ImplMacFontData*,GfbCompare> FallbackSet;
- FallbackSet aFallbackSet;
- MacFontContainer::const_iterator it = maFontContainer.begin();
- for(; it != maFontContainer.end(); ++it )
- {
- const ImplMacFontData* pIFD = (*it).second;
- // TODO: subsettable/embeddable glyph fallback only for PDF export?
- if( pIFD->IsSubsettable() || pIFD->IsEmbeddable() )
- aFallbackSet.insert( pIFD );
- }
-
- // tell ATSU about font preferences for "glyph fallback"
- typedef std::vector<ATSUFontID> AtsFontIDVector;
- AtsFontIDVector aFallbackVector;
- aFallbackVector.reserve( maFontContainer.size() );
- FallbackSet::const_iterator itFData = aFallbackSet.begin();
- for(; itFData != aFallbackSet.end(); ++itFData )
- {
- const ImplMacFontData* pFontData = (*itFData);
- ATSUFontID nFontID = (ATSUFontID)pFontData->GetFontId();
- aFallbackVector.push_back( nFontID );
- }
-
- ATSUCreateFontFallbacks( &maFontFallbacks );
- ATSUSetObjFontFallbacks( maFontFallbacks,
- aFallbackVector.size(), &aFallbackVector[0], kATSUSequentialFallbacksPreferred );
-}
-
// -----------------------------------------------------------------------
-ImplMacFontData* SystemFontList::GetFontDataFromId( ATSUFontID nFontId ) const
+void AtsFontList::InitGlyphFallbacks()
{
- MacFontContainer::const_iterator it = maFontContainer.find( nFontId );
- if( it == maFontContainer.end() )
- return NULL;
- return (*it).second;
+ // sort fonts for "glyph fallback"
+ typedef std::multiset<const ImplMacFontData*,GfbCompare> FallbackSet;
+ FallbackSet aFallbackSet;
+ AtsFontContainer::const_iterator it = maFontContainer.begin();
+ for(; it != maFontContainer.end(); ++it )
+ {
+ const ImplMacFontData* pIFD = (*it).second;
+ // TODO: subsettable/embeddable glyph fallback only for PDF export?
+ if( pIFD->IsSubsettable() || pIFD->IsEmbeddable() )
+ aFallbackSet.insert( pIFD );
+ }
+
+ // tell ATSU about font preferences for "glyph fallback"
+ typedef std::vector<ATSUFontID> AtsFontIDVector;
+ AtsFontIDVector aFallbackVector;
+ aFallbackVector.reserve( maFontContainer.size() );
+ FallbackSet::const_iterator itFData = aFallbackSet.begin();
+ for(; itFData != aFallbackSet.end(); ++itFData )
+ {
+ const ImplMacFontData* pFontData = (*itFData);
+ ATSUFontID nFontID = (ATSUFontID)pFontData->GetFontId();
+ aFallbackVector.push_back( nFontID );
+ }
+
+ ATSUCreateFontFallbacks( &maFontFallbacks );
+ ATSUSetObjFontFallbacks( maFontFallbacks,
+ aFallbackVector.size(), &aFallbackVector[0], kATSUSequentialFallbacksPreferred );
}
-// -----------------------------------------------------------------------
+// =======================================================================
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.hxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.hxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atsfonts.hxx Wed Mar 19 10:14:42 2014
@@ -19,39 +19,27 @@
*
*************************************************************/
-#ifndef _ATSFONTS_HXX
-#define _ATSFONTS_HXX
+// =======================================================================
-class ImplMacFontData;
-class ImplDevFontList;
-
-#include <premac.h>
-#include <ApplicationServices/ApplicationServices.h>
-#include <postmac.h>
-
-#include <map>
-
-/* This class has the responsibility of assembling a list
- of atsui compatible fonts available on the system and
- enabling access to that list.
- */
-class SystemFontList
+class AtsTextStyle
+: public ImplMacTextStyle
{
public:
- SystemFontList();
- ~SystemFontList();
-
- void AnnounceFonts( ImplDevFontList& ) const;
- ImplMacFontData* GetFontDataFromId( ATSUFontID ) const;
+ explicit AtsTextStyle( const ImplFontSelectData& );
+ virtual ~AtsTextStyle( void );
- ATSUFontFallbacks maFontFallbacks;
+ virtual SalLayout* GetTextLayout( void ) const;
-private:
- typedef std::hash_map<ATSUFontID,ImplMacFontData*> MacFontContainer;
- MacFontContainer maFontContainer;
+ virtual void GetFontMetric( float fDPIY, ImplFontMetricData& ) const;
+ virtual bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const;
+ virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const;
- void InitGlyphFallbacks();
+ virtual void SetTextColor( const RGBAColor& );
+
+private:
+ /// ATSU text style object
+ ATSUStyle maATSUStyle;
};
-#endif // _ATSFONTS_HXX
+// =======================================================================
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atslayout.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atslayout.cxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atslayout.cxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/atslayout.cxx Wed Mar 19 10:14:42 2014
@@ -37,14 +37,14 @@
class ATSLayout : public SalLayout
{
public:
- ATSLayout( ATSUStyle&, float fFontScale );
+ explicit ATSLayout( ATSUStyle&, float fFontScale );
virtual ~ATSLayout();
virtual bool LayoutText( ImplLayoutArgs& );
virtual void AdjustLayout( ImplLayoutArgs& );
virtual void DrawText( SalGraphics& ) const;
- virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
+ virtual int GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, int&,
sal_Int32* pGlyphAdvances, int* pCharIndexes ) const;
virtual long GetTextWidth() const;
@@ -80,50 +80,50 @@ private:
int AtsuPix2Vcl( int ) const; // convert ATSU-Pixel units to VCL units
Fixed Vcl2Fixed( int ) const; // convert VCL units to ATSU-Fixed units
- // cached details about the resulting layout
- // mutable members since these details are all lazy initialized
- mutable int mnGlyphCount; // glyph count
- mutable Fixed mnCachedWidth; // cached value of resulting typographical width
- int mnTrailingSpaceWidth; // in Pixels
+ // cached details about the resulting layout
+ // mutable members since these details are all lazy initialized
+ mutable int mnGlyphCount; // glyph count
+ mutable Fixed mnCachedWidth; // cached value of resulting typographical width
+ int mnTrailingSpaceWidth; // in Pixels
mutable ATSGlyphRef* mpGlyphIds; // ATSU glyph ids
- mutable Fixed* mpCharWidths; // map relative charpos to charwidth
- mutable int* mpChars2Glyphs; // map relative charpos to absolute glyphpos
- mutable int* mpGlyphs2Chars; // map absolute glyphpos to absolute charpos
- mutable bool* mpGlyphRTLFlags; // BiDi status for glyphs: true if RTL
- mutable Fixed* mpGlyphAdvances; // contains glyph widths for the justified layout
- mutable Fixed* mpGlyphOrigAdvs; // contains glyph widths for the unjustified layout
- mutable Fixed* mpDeltaY; // vertical offset from the baseline
+ mutable Fixed* mpCharWidths; // map relative charpos to charwidth
+ mutable int* mpChars2Glyphs; // map relative charpos to absolute glyphpos
+ mutable int* mpGlyphs2Chars; // map absolute glyphpos to absolute charpos
+ mutable bool* mpGlyphRTLFlags; // BiDi status for glyphs: true if RTL
+ mutable Fixed* mpGlyphAdvances; // contains glyph widths for the justified layout
+ mutable Fixed* mpGlyphOrigAdvs; // contains glyph widths for the unjustified layout
+ mutable Fixed* mpDeltaY; // vertical offset from the baseline
struct SubPortion { int mnMinCharPos, mnEndCharPos; Fixed mnXOffset; };
typedef std::vector<SubPortion> SubPortionVector;
mutable SubPortionVector maSubPortions; // Writer&ATSUI layouts can differ quite a bit...
- // storing details about fonts used in glyph-fallback for this layout
- mutable class FallbackInfo* mpFallbackInfo;
+ // storing details about fonts used in glyph-fallback for this layout
+ mutable class FallbackInfo* mpFallbackInfo;
- // x-offset relative to layout origin
- // currently only used in RTL-layouts
- mutable Fixed mnBaseAdv;
+ // x-offset relative to layout origin
+ // currently only used in RTL-layouts
+ mutable Fixed mnBaseAdv;
};
class FallbackInfo
{
public:
- FallbackInfo() : mnMaxLevel(0) {}
- int AddFallback( ATSUFontID );
- const ImplFontData* GetFallbackFontData( int nLevel ) const;
+ FallbackInfo() : mnMaxLevel(0) {}
+ int AddFallback( ATSUFontID );
+ const ImplFontData* GetFallbackFontData( int nLevel ) const;
private:
- const ImplMacFontData* maFontData[ MAX_FALLBACK ];
- ATSUFontID maATSUFontId[ MAX_FALLBACK ];
- int mnMaxLevel;
+ const ImplMacFontData* maFontData[ MAX_FALLBACK ];
+ ATSUFontID maATSUFontId[ MAX_FALLBACK ];
+ int mnMaxLevel;
};
// =======================================================================
ATSLayout::ATSLayout( ATSUStyle& rATSUStyle, float fFontScale )
-: mrATSUStyle( rATSUStyle ),
+: mrATSUStyle( rATSUStyle ),
maATSULayout( NULL ),
mnCharCount( 0 ),
mfFontScale( fFontScale ),
@@ -146,23 +146,23 @@ ATSLayout::ATSLayout( ATSUStyle& rATSUSt
ATSLayout::~ATSLayout()
{
- if( mpDeltaY )
- ATSUDirectReleaseLayoutDataArrayPtr( NULL,
- kATSUDirectDataBaselineDeltaFixedArray, (void**)&mpDeltaY );
+ if( mpDeltaY )
+ ATSUDirectReleaseLayoutDataArrayPtr( NULL,
+ kATSUDirectDataBaselineDeltaFixedArray, (void**)&mpDeltaY );
- if( maATSULayout )
- ATSUDisposeTextLayout( maATSULayout );
+ if( maATSULayout )
+ ATSUDisposeTextLayout( maATSULayout );
- delete[] mpGlyphRTLFlags;
- delete[] mpGlyphs2Chars;
- delete[] mpChars2Glyphs;
- if( mpCharWidths != mpGlyphAdvances )
- delete[] mpCharWidths;
- delete[] mpGlyphIds;
- delete[] mpGlyphOrigAdvs;
- delete[] mpGlyphAdvances;
+ delete[] mpGlyphRTLFlags;
+ delete[] mpGlyphs2Chars;
+ delete[] mpChars2Glyphs;
+ if( mpCharWidths != mpGlyphAdvances )
+ delete[] mpCharWidths;
+ delete[] mpGlyphIds;
+ delete[] mpGlyphOrigAdvs;
+ delete[] mpGlyphAdvances;
- delete mpFallbackInfo;
+ delete mpFallbackInfo;
}
// -----------------------------------------------------------------------
@@ -205,12 +205,12 @@ bool ATSLayout::LayoutText( ImplLayoutAr
if( maATSULayout )
ATSUDisposeTextLayout( maATSULayout );
- maATSULayout = NULL;
+ maATSULayout = NULL;
// Layout text
// set up our locals, verify parameters...
- DBG_ASSERT( (rArgs.mpStr!=NULL), "ATSLayout::LayoutText() with rArgs.mpStr==NULL !!!");
- DBG_ASSERT( (mrATSUStyle!=NULL), "ATSLayout::LayoutText() with ATSUStyle==NULL !!!");
+ DBG_ASSERT( (rArgs.mpStr!=NULL), "ATSLayout::LayoutText() with rArgs.mpStr==NULL !!!");
+ DBG_ASSERT( (mrATSUStyle!=NULL), "ATSLayout::LayoutText() with ATSUStyle==NULL !!!");
SalLayout::AdjustLayout( rArgs );
mnCharCount = mnEndCharPos - mnMinCharPos;
@@ -219,23 +219,12 @@ bool ATSLayout::LayoutText( ImplLayoutAr
if( mnCharCount<=0 )
return false;
-#if (OSL_DEBUG_LEVEL > 3)
- Fixed fFontSize = 0;
- ByteCount nDummy;
- ATSUGetAttribute( mrATSUStyle, kATSUSizeTag, sizeof(fFontSize), &fFontSize, &nDummy);
- String aUniName( &rArgs.mpStr[rArgs.mnMinCharPos], mnCharCount );
- ByteString aCName( aUniName, RTL_TEXTENCODING_UTF8 );
- fprintf( stderr, "ATSLayout( \"%s\" %d..%d of %d) with h=%4.1f\n",
- aCName.GetBuffer(),rArgs.mnMinCharPos,rArgs.mnEndCharPos,rArgs.mnLength,Fix2X(fFontSize) );
-#endif
-
// create the ATSUI layout
UniCharCount nRunLengths[1] = { mnCharCount };
const int nRunCount = sizeof(nRunLengths)/sizeof(*nRunLengths);
OSStatus eStatus = ATSUCreateTextLayoutWithTextPtr( rArgs.mpStr,
- rArgs.mnMinCharPos, mnCharCount, rArgs.mnLength,
- nRunCount, &nRunLengths[0], &mrATSUStyle,
- &maATSULayout);
+ rArgs.mnMinCharPos, mnCharCount, rArgs.mnLength,
+ nRunCount, &nRunLengths[0], &mrATSUStyle, &maATSULayout);
DBG_ASSERT( (eStatus==noErr), "ATSUCreateTextLayoutWithTextPtr failed\n");
if( eStatus != noErr )
@@ -271,7 +260,7 @@ bool ATSLayout::LayoutText( ImplLayoutAr
aTagSizes[0] = sizeof( nLineDirTag );
aTagValues[0] = &nLineDirTag;
// set run-specific layout controls
-#if 0 // why don't line-controls work as reliably as layout-controls???
+#if 0 // why don't line-controls work as reliable as layout-controls???
ATSUSetLineControls( maATSULayout, rArgs.mnMinCharPos, 1, aTagAttrs, aTagSizes, aTagValues );
#else
ATSUSetLayoutControls( maATSULayout, 1, aTagAttrs, aTagSizes, aTagValues );
@@ -309,7 +298,7 @@ void ATSLayout::AdjustLayout( ImplLayout
mnTrailingSpaceWidth = rArgs.mpDXArray[ mnCharCount-1 ];
if( i > 0 )
mnTrailingSpaceWidth -= rArgs.mpDXArray[ i-1 ];
- InitGIA(); // ensure valid mpCharWidths[], TODO: use GetIdealX() instead?
+ InitGIA(); // ensure valid mpCharWidths[], TODO: use GetIdealX() instead?
mnTrailingSpaceWidth -= Fixed2Vcl( mpCharWidths[i] );
// ignore trailing space for calculating the available width
nOrigWidth -= mnTrailingSpaceWidth;
@@ -380,11 +369,11 @@ void ATSLayout::DrawText( SalGraphics& r
return;
// the view is vertically flipped => flipped glyphs
- // so apply a temporary transformation that it flips back
+ // so apply a temporary transformation that it flips back
// also compensate if the font was size limited
- CGContextSaveGState( rAquaGraphics.mrContext );
- CGContextScaleCTM( rAquaGraphics.mrContext, +mfFontScale, -mfFontScale );
- CGContextSetShouldAntialias( rAquaGraphics.mrContext, !rAquaGraphics.mbNonAntialiasedText );
+ CGContextSaveGState( rAquaGraphics.mrContext );
+ CGContextScaleCTM( rAquaGraphics.mrContext, +mfFontScale, -mfFontScale );
+ CGContextSetShouldAntialias( rAquaGraphics.mrContext, !rAquaGraphics.mbNonAntialiasedText );
// prepare ATSUI drawing attributes
static const ItemCount nMaxControls = 8;
@@ -394,9 +383,9 @@ void ATSLayout::DrawText( SalGraphics& r
ItemCount numcontrols = 0;
// Tell ATSUI to use CoreGraphics
- theTags[numcontrols] = kATSUCGContextTag;
- theSizes[numcontrols] = sizeof( CGContextRef );
- theValues[numcontrols++] = &rAquaGraphics.mrContext;
+ theTags[numcontrols] = kATSUCGContextTag;
+ theSizes[numcontrols] = sizeof( CGContextRef );
+ theValues[numcontrols++] = &rAquaGraphics.mrContext;
// Rotate if necessary
if( rAquaGraphics.mnATSUIRotation != 0 )
@@ -447,21 +436,21 @@ void ATSLayout::DrawText( SalGraphics& r
theErr = ATSUMeasureTextImage( maATSULayout,
mnMinCharPos, mnCharCount, nFixedX, nFixedY, &drawRect );
if( theErr == noErr )
- {
- // FIXME: transformation from baseline to top left
- // with the simple approach below we invalidate too much
- short d = drawRect.bottom - drawRect.top;
- drawRect.top -= d;
- drawRect.bottom += d;
- CGRect aRect = CGRectMake( drawRect.left, drawRect.top,
- drawRect.right - drawRect.left,
- drawRect.bottom - drawRect.top );
- aRect = CGContextConvertRectToDeviceSpace( rAquaGraphics.mrContext, aRect );
+ {
+ // FIXME: transformation from baseline to top left
+ // with the simple approach below we invalidate too much
+ short d = drawRect.bottom - drawRect.top;
+ drawRect.top -= d;
+ drawRect.bottom += d;
+ CGRect aRect = CGRectMake( drawRect.left, drawRect.top,
+ drawRect.right - drawRect.left,
+ drawRect.bottom - drawRect.top );
+ aRect = CGContextConvertRectToDeviceSpace( rAquaGraphics.mrContext, aRect );
rAquaGraphics.RefreshRect( aRect );
- }
+ }
}
- // restore the original graphic context transformations
+ // restore the original graphic context transformations
CGContextRestoreGState( rAquaGraphics.mrContext );
}
@@ -481,7 +470,7 @@ void ATSLayout::DrawText( SalGraphics& r
* @return : number of glyph details that were provided
**/
int ATSLayout::GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, int& nStart,
- sal_Int32* pGlyphAdvances, int* pCharIndexes ) const
+ sal_Int32* pGlyphAdvances, int* pCharIndexes ) const
{
if( nStart < 0 ) // first glyph requested?
nStart = 0;
@@ -499,103 +488,103 @@ int ATSLayout::GetNextGlyphs( int nLen,
return 0;
// calculate glyph position relative to layout base
- // TODO: avoid for nStart!=0 case by reusing rPos
- Fixed nXOffset = mnBaseAdv;
- for( int i = 0; i < nStart; ++i )
- nXOffset += mpGlyphAdvances[ i ];
- // if sub-portion offsets are involved there is an additional x-offset
- if( !maSubPortions.empty() )
- {
- // prepare to find the sub-portion
- int nCharPos = nStart + mnMinCharPos;
- if( mpGlyphs2Chars )
- nCharPos = mpGlyphs2Chars[nStart];
-
- // find the matching subportion
- // TODO: is a non-linear search worth it?
- SubPortionVector::const_iterator it = maSubPortions.begin();
- for(; it != maSubPortions.end(); ++it) {
- const SubPortion& r = *it;
- if( nCharPos < r.mnMinCharPos )
- continue;
- if( nCharPos >= r.mnEndCharPos )
- continue;
- // apply the sub-portion xoffset
- nXOffset += r.mnXOffset;
- break;
- }
- }
+ // TODO: avoid for nStart!=0 case by reusing rPos
+ Fixed nXOffset = mnBaseAdv;
+ for( int i = 0; i < nStart; ++i )
+ nXOffset += mpGlyphAdvances[ i ];
+ // if sub-portion offsets are involved there is an additional x-offset
+ if( !maSubPortions.empty() )
+ {
+ // prepare to find the sub-portion
+ int nCharPos = nStart + mnMinCharPos;
+ if( mpGlyphs2Chars )
+ nCharPos = mpGlyphs2Chars[nStart];
+
+ // find the matching subportion
+ // TODO: is a non-linear search worth it?
+ SubPortionVector::const_iterator it = maSubPortions.begin();
+ for(; it != maSubPortions.end(); ++it) {
+ const SubPortion& r = *it;
+ if( nCharPos < r.mnMinCharPos )
+ continue;
+ if( nCharPos >= r.mnEndCharPos )
+ continue;
+ // apply the sub-portion xoffset
+ nXOffset += r.mnXOffset;
+ break;
+ }
+ }
Fixed nYOffset = 0;
if( mpDeltaY )
nYOffset = mpDeltaY[ nStart ];
- // calculate absolute position in pixel units
- const Point aRelativePos( Fix2Long(static_cast<Fixed>(nXOffset*mfFontScale)), Fix2Long(static_cast<Fixed>(nYOffset*mfFontScale)) );
- rPos = GetDrawPosition( aRelativePos );
+ // calculate absolute position in pixel units
+ const Point aRelativePos( Fix2Long(static_cast<Fixed>(nXOffset*mfFontScale)), Fix2Long(static_cast<Fixed>(nYOffset*mfFontScale)) );
+ rPos = GetDrawPosition( aRelativePos );
// update return values
int nCount = 0;
- while( nCount < nLen )
- {
- ++nCount;
- sal_GlyphId aGlyphId = mpGlyphIds[ nStart];
-
- // check if glyph fallback is needed for this glyph
- // TODO: use ATSUDirectGetLayoutDataArrayPtrFromTextLayout(kATSUDirectDataStyleIndex) API instead?
- const int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[nStart] : nStart + mnMinCharPos;
- ATSUFontID nFallbackFontID = kATSUInvalidFontID;
- UniCharArrayOffset nChangedOffset = 0;
- UniCharCount nChangedLength = 0;
- OSStatus eStatus = ATSUMatchFontsToText( maATSULayout, nCharPos, kATSUToTextEnd,
- &nFallbackFontID, &nChangedOffset, &nChangedLength );
- if( (eStatus == kATSUFontsMatched) && ((int)nChangedOffset == nCharPos) )
- {
- // fallback is needed
- if( !mpFallbackInfo )
- mpFallbackInfo = new FallbackInfo;
- // register fallback font
- const int nLevel = mpFallbackInfo->AddFallback( nFallbackFontID );
- // update sal_GlyphId with fallback level
- aGlyphId |= (nLevel << GF_FONTSHIFT);
- }
-
- // update resulting glyphid array
- *(pOutGlyphIds++) = aGlyphId;
-
- // update returned glyph advance array
- if( pGlyphAdvances )
- *(pGlyphAdvances++) = Fixed2Vcl( mpGlyphAdvances[nStart] );
-
- // update returned index-into-string array
- if( pCharIndexes )
- {
- int nCharPos;
- if( mpGlyphs2Chars )
- nCharPos = mpGlyphs2Chars[nStart];
- else
- nCharPos = nStart + mnMinCharPos;
- *(pCharIndexes++) = nCharPos;
- }
-
- // stop at last glyph
- if( ++nStart >= mnGlyphCount )
- break;
-
- // stop when next the x-position is unexpected
- if( !maSubPortions.empty() )
- break; // TODO: finish the complete sub-portion
- if( !pGlyphAdvances && mpGlyphOrigAdvs )
- if( mpGlyphAdvances[nStart-1] != mpGlyphOrigAdvs[nStart-1] )
- break;
-
- // stop when the next y-position is unexpected
- if( mpDeltaY )
- if( mpDeltaY[nStart-1] != mpDeltaY[nStart] )
- break;
- }
+ while( nCount < nLen )
+ {
+ ++nCount;
+ sal_GlyphId aGlyphId = mpGlyphIds[nStart];
- return nCount;
+ // check if glyph fallback is needed for this glyph
+ // TODO: use ATSUDirectGetLayoutDataArrayPtrFromTextLayout(kATSUDirectDataStyleIndex) API instead?
+ const int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[nStart] : nStart + mnMinCharPos;
+ ATSUFontID nFallbackFontID = kATSUInvalidFontID;
+ UniCharArrayOffset nChangedOffset = 0;
+ UniCharCount nChangedLength = 0;
+ OSStatus eStatus = ATSUMatchFontsToText( maATSULayout, nCharPos, kATSUToTextEnd,
+ &nFallbackFontID, &nChangedOffset, &nChangedLength );
+ if( (eStatus == kATSUFontsMatched) && ((int)nChangedOffset == nCharPos) )
+ {
+ // fallback is needed
+ if( !mpFallbackInfo )
+ mpFallbackInfo = new FallbackInfo;
+ // register fallback font
+ const int nLevel = mpFallbackInfo->AddFallback( nFallbackFontID );
+ // update sal_GlyphId with fallback level
+ aGlyphId |= (nLevel << GF_FONTSHIFT);
+ }
+
+ // update resulting glyphid array
+ *(pOutGlyphIds++) = aGlyphId;
+
+ // update returned glyph advance array
+ if( pGlyphAdvances )
+ *(pGlyphAdvances++) = Fixed2Vcl( mpGlyphAdvances[nStart] );
+
+ // update returned index-into-string array
+ if( pCharIndexes )
+ {
+ int nCharPos;
+ if( mpGlyphs2Chars )
+ nCharPos = mpGlyphs2Chars[nStart];
+ else
+ nCharPos = nStart + mnMinCharPos;
+ *(pCharIndexes++) = nCharPos;
+ }
+
+ // stop at last glyph
+ if( ++nStart >= mnGlyphCount )
+ break;
+
+ // stop when next the x-position is unexpected
+ if( !maSubPortions.empty() )
+ break; // TODO: finish the complete sub-portion
+ if( !pGlyphAdvances && mpGlyphOrigAdvs )
+ if( mpGlyphAdvances[nStart-1] != mpGlyphOrigAdvs[nStart-1] )
+ break;
+
+ // stop when the next y-position is unexpected
+ if( mpDeltaY )
+ if( mpDeltaY[nStart-1] != mpDeltaY[nStart] )
+ break;
+ }
+
+ return nCount;
}
// -----------------------------------------------------------------------
@@ -656,9 +645,9 @@ long ATSLayout::GetTextWidth() const
// adjust for eliminated trailing space widths
}
- int nScaledWidth = Fixed2Vcl( mnCachedWidth );
+ int nScaledWidth = Fixed2Vcl( mnCachedWidth );
nScaledWidth += mnTrailingSpaceWidth;
- return nScaledWidth;
+ return nScaledWidth;
}
// -----------------------------------------------------------------------
@@ -673,29 +662,29 @@ long ATSLayout::GetTextWidth() const
**/
long ATSLayout::FillDXArray( long* pDXArray ) const
{
- // short circuit requests which don't need full details
- if( !pDXArray )
- return GetTextWidth();
+ // short circuit requests which don't need full details
+ if( !pDXArray )
+ return GetTextWidth();
// check assumptions
DBG_ASSERT( !mnTrailingSpaceWidth, "ATSLayout::FillDXArray() with nTSW!=0" );
// initialize details about the resulting layout
- InitGIA();
+ InitGIA();
- // distribute the widths among the string elements
- int nPixWidth = 0;
- mnCachedWidth = 0;
- for( int i = 0; i < mnCharCount; ++i )
- {
- // convert and adjust for accumulated rounding errors
- mnCachedWidth += mpCharWidths[i];
- const int nOldPixWidth = nPixWidth;
- nPixWidth = Fixed2Vcl( mnCachedWidth );
- pDXArray[i] = nPixWidth - nOldPixWidth;
- }
+ // distribute the widths among the string elements
+ int nPixWidth = 0;
+ mnCachedWidth = 0;
+ for( int i = 0; i < mnCharCount; ++i )
+ {
+ // convert and adjust for accumulated rounding errors
+ mnCachedWidth += mpCharWidths[i];
+ const int nOldPixWidth = nPixWidth;
+ nPixWidth = Fixed2Vcl( mnCachedWidth );
+ pDXArray[i] = nPixWidth - nOldPixWidth;
+ }
- return nPixWidth;
+ return nPixWidth;
}
// -----------------------------------------------------------------------
@@ -742,9 +731,9 @@ int ATSLayout::GetTextBreak( long nMaxWi
}
// get a quick overview on what could fit
- const long nPixelWidth = (nMaxWidth - (nCharExtra * mnCharCount)) / nFactor;
- if( nPixelWidth <= 0 )
- return mnMinCharPos;
+ const long nPixelWidth = (nMaxWidth - (nCharExtra * mnCharCount)) / nFactor;
+ if( nPixelWidth <= 0 )
+ return mnMinCharPos;
// check assumptions
DBG_ASSERT( !mnTrailingSpaceWidth, "ATSLayout::GetTextBreak() with nTSW!=0" );
@@ -803,8 +792,8 @@ void ATSLayout::GetCaretPositions( int n
"ATSLayout::GetCaretPositions() : invalid number of caret pairs requested");
// initialize the caret positions
- for( int i = 0; i < nMaxIndex; ++i )
- pCaretXArray[ i ] = -1;
+ for( int i = 0; i < nMaxIndex; ++i )
+ pCaretXArray[ i ] = -1;
for( int n = 0; n <= mnCharCount; ++n )
{
@@ -1043,7 +1032,7 @@ bool ATSLayout::GetDeltaY() const
return true;
#if 1
- if( !maATSULayout )
+ if( !maATSULayout )
return false;
// get and keep the y-deltas in the mpDeltaY member variable
@@ -1211,13 +1200,13 @@ void ATSLayout::Simplify( bool /*bIsBase
// for a glyphid that was returned by ATSLayout::GetNextGlyphs()
const ImplFontData* ATSLayout::GetFallbackFontData( sal_GlyphId aGlyphId ) const
{
- // check if any fallback fonts were needed
- if( !mpFallbackInfo )
- return NULL;
- // check if the current glyph needs a fallback font
- int nFallbackLevel = (aGlyphId & GF_FONTMASK) >> GF_FONTSHIFT;
- if( !nFallbackLevel )
- return NULL;
+ // check if any fallback fonts were needed
+ if( !mpFallbackInfo )
+ return NULL;
+ // check if the current glyph needs a fallback font
+ int nFallbackLevel = (aGlyphId & GF_FONTMASK) >> GF_FONTSHIFT;
+ if( !nFallbackLevel )
+ return NULL;
return mpFallbackInfo->GetFallbackFontData( nFallbackLevel );
}
@@ -1225,38 +1214,38 @@ const ImplFontData* ATSLayout::GetFallba
int FallbackInfo::AddFallback( ATSUFontID nFontId )
{
- // check if the fallback font is already known
- for( int nLevel = 0; nLevel < mnMaxLevel; ++nLevel )
- if( maATSUFontId[ nLevel ] == nFontId )
- return (nLevel + 1);
+ // check if the fallback font is already known
+ for( int nLevel = 0; nLevel < mnMaxLevel; ++nLevel )
+ if( maATSUFontId[ nLevel ] == nFontId )
+ return (nLevel + 1);
// append new fallback font if possible
- if( mnMaxLevel >= MAX_FALLBACK-1 )
- return 0;
- // keep ATSU font id of fallback font
- maATSUFontId[ mnMaxLevel ] = nFontId;
- // find and cache the corresponding ImplFontData pointer
- const SystemFontList* pSFL = GetSalData()->mpFontList;
- const ImplMacFontData* pFontData = pSFL->GetFontDataFromId( nFontId );
- maFontData[ mnMaxLevel ] = pFontData;
- // increase fallback level by one
- return (++mnMaxLevel);
+ if( mnMaxLevel >= MAX_FALLBACK-1 )
+ return 0;
+ // keep ATSU font id of fallback font
+ maATSUFontId[ mnMaxLevel ] = nFontId;
+ // find and cache the corresponding ImplFontData pointer
+ const SystemFontList* pSFL = GetSalData()->mpFontList;
+ const ImplMacFontData* pFontData = pSFL->GetFontDataFromId( nFontId );
+ maFontData[ mnMaxLevel ] = pFontData;
+ // increase fallback level by one
+ return (++mnMaxLevel);
}
// -----------------------------------------------------------------------
const ImplFontData* FallbackInfo::GetFallbackFontData( int nFallbackLevel ) const
{
- const ImplMacFontData* pFallbackFont = maFontData[ nFallbackLevel-1 ];
- return pFallbackFont;
+ const ImplMacFontData* pFallbackFont = maFontData[ nFallbackLevel-1 ];
+ return pFallbackFont;
}
// =======================================================================
SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs&, int /*nFallbackLevel*/ )
{
- ATSLayout* pATSLayout = new ATSLayout( maATSUStyle, mfFontScale );
- return pATSLayout;
+ ATSLayout* pATSLayout = new ATSLayout( maATSUStyle, mfFontScale );
+ return pATSLayout;
}
// =======================================================================
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctfonts.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctfonts.cxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctfonts.cxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctfonts.cxx Wed Mar 19 10:14:42 2014
@@ -109,6 +109,15 @@ CTTextStyle::CTTextStyle( const ImplFont
pMatrix = &aMatrix;
}
+ // handle emulation of italic/oblique styles if requested and the font doesn't provide them
+ if( ((pReqFont->meItalic == ITALIC_NORMAL) || (pReqFont->meItalic == ITALIC_OBLIQUE))
+ && (mpFontData->meItalic == ITALIC_NONE))
+ {
+ if( !pMatrix)
+ pMatrix = &(aMatrix = CGAffineTransformIdentity);
+ aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMake( 1, 0, 0.375F, 1, 0, 0));
+ }
+
// create the style object for CoreText font attributes
static const CFIndex nMaxDictSize = 16; // TODO: does this really suffice?
mpStyleDict = CFDictionaryCreateMutable( NULL, nMaxDictSize,
@@ -131,6 +140,16 @@ CTTextStyle::CTTextStyle( const ImplFont
CFDictionarySetValue( mpStyleDict, kCTFontAttributeName, pNewCTFont );
CFRelease( pNewCTFont);
+ // handle emulation of bold styles if requested and the font that doesn't provide them
+ if( (pReqFont->meWeight > WEIGHT_MEDIUM)
+ && (mpFontData->meWeight <= WEIGHT_MEDIUM)
+ && (mpFontData->meWeight != WEIGHT_DONTKNOW))
+ {
+ const int nBoldFactor = -lrint( (3.5F * pReqFont->meWeight) / mpFontData->meWeight);
+ CFNumberRef pCFIntBold = CFNumberCreate( NULL, kCFNumberIntType, &nBoldFactor);
+ CFDictionarySetValue( mpStyleDict, kCTStrokeWidthAttributeName, pCFIntBold);
+ }
+
#if 0 // LastResort is implicit in CoreText's font cascading
const void* aGFBDescriptors[] = { CTFontDescriptorCreateWithNameAndSize( CFSTR("LastResort"), 0) }; // TODO: use the full GFB list
const int nGfbCount = sizeof(aGFBDescriptors) / sizeof(*aGFBDescriptors);
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctlayout.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctlayout.cxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctlayout.cxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/ctlayout.cxx Wed Mar 19 10:14:42 2014
@@ -19,9 +19,6 @@
*
*************************************************************/
-//#include "salgdi.hxx"
-#include "tools/debug.hxx"
-
#include "ctfonts.hxx"
// =======================================================================
@@ -62,7 +59,8 @@ private:
CTLineRef mpCTLine;
int mnCharCount; // ==mnEndCharPos-mnMinCharPos
- int mnTrailingSpaces;
+ int mnTrailingSpaceCount;
+ double mfTrailingSpaceWidth; // preserves the width of stripped-off trailing space
// to prevent overflows
// font requests get size limited by downscaling huge fonts
@@ -72,7 +70,6 @@ private:
// cached details about the resulting layout
// mutable members since these details are all lazy initialized
mutable double mfCachedWidth; // cached value of resulting typographical width
- mutable double mfTrailingSpaceWidth; // in Pixels
// x-offset relative to layout origin
// currently only used in RTL-layouts
@@ -86,10 +83,10 @@ CTLayout::CTLayout( const CTTextStyle* p
, mpAttrString( NULL )
, mpCTLine( NULL )
, mnCharCount( 0 )
-, mnTrailingSpaces( 0 )
+, mnTrailingSpaceCount( 0 )
+, mfTrailingSpaceWidth( 0.0 )
, mfFontScale( pTextStyle->mfFontScale )
, mfCachedWidth( -1 )
-, mfTrailingSpaceWidth( 0 )
, mnBaseAdv( 0 )
{
CFRetain( mpTextStyle->GetStyleDict() );
@@ -131,9 +128,10 @@ bool CTLayout::LayoutText( ImplLayoutArg
CFRelease( aCFText);
// get info about trailing whitespace to prepare for text justification in AdjustLayout()
- mnTrailingSpaces = 0;
- for( int i = mnEndCharPos; --i >= mnMinCharPos; ++mnTrailingSpaces )
- if( !IsSpacingGlyph( rArgs.mpStr[i] | GF_ISCHAR ))
+ mnTrailingSpaceCount = 0;
+ for( int i = mnEndCharPos; --i >= mnMinCharPos; ++mnTrailingSpaceCount )
+ if( !IsSpacingGlyph( rArgs.mpStr[i] | GF_ISCHAR )
+ && (rArgs.mpStr[i] != 0x00A0) )
break;
return true;
}
@@ -145,31 +143,22 @@ void CTLayout::AdjustLayout( ImplLayoutA
if( !mpCTLine)
return;
- const DynCoreTextSyms& rCT = DynCoreTextSyms::get();
- // CoreText fills trailing space during justification so we have to
- // take that into account when requesting CT to justify something
- mfTrailingSpaceWidth = rCT.LineGetTrailingWhitespaceWidth( mpCTLine );
- const int nTrailingSpaceWidth = rint( mfFontScale * mfTrailingSpaceWidth );
-
- int nOrigWidth = GetTextWidth();
int nPixelWidth = rArgs.mnLayoutWidth;
- if( nPixelWidth )
- {
- nPixelWidth -= nTrailingSpaceWidth;
- if( nPixelWidth <= 0)
- return;
- }
- else if( rArgs.mpDXArray )
+ if( rArgs.mpDXArray )
{
// for now we are only interested in the layout width
// TODO: use all mpDXArray elements for layouting
- nPixelWidth = rArgs.mpDXArray[ mnCharCount - 1 - mnTrailingSpaces ];
+ nPixelWidth = rArgs.mpDXArray[ mnCharCount-1 ];
}
+ else if( !nPixelWidth ) // short-circuit if there is nothing to adjust
+ return;
- // in RTL-layouts trailing spaces are leftmost
- // TODO: use BiDi-algorithm to thoroughly check this assumption
- if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL)
- mnBaseAdv = nTrailingSpaceWidth;
+ // short-circuit when justifying an all-whitespace string
+ if( mnTrailingSpaceCount >= mnCharCount)
+ {
+ mfCachedWidth = nPixelWidth / mfFontScale;
+ return;
+ }
// return early if there is nothing to do
if( nPixelWidth <= 0 )
@@ -177,33 +166,46 @@ void CTLayout::AdjustLayout( ImplLayoutA
// HACK: justification requests which change the width by just one pixel are probably
// #i86038# introduced by lossy conversions between integer based coordinate system
+ const int nOrigWidth = GetTextWidth();
if( (nOrigWidth >= nPixelWidth-1) && (nOrigWidth <= nPixelWidth+1) )
return;
// if the text to be justified has whitespace in it then
// - Writer goes crazy with its HalfSpace magic
- // - LayoutEngine handles spaces specially (in particular at the text start or end)
- if( mnTrailingSpaces ) {
- // adjust for Writer's SwFntObj::DrawText() Halfspace magic at the text end
- std::vector<sal_Int32> aOrigDXAry;
- aOrigDXAry.resize( mnCharCount);
- FillDXArray( &aOrigDXAry[0] );
- int nLastCharSpace = rArgs.mpDXArray[ mnCharCount-1-mnTrailingSpaces ]
- - aOrigDXAry[ mnCharCount-1-mnTrailingSpaces ];
- nPixelWidth -= nLastCharSpace;
- if( nPixelWidth < 0 )
+ // - CoreText handles spaces specially (in particular at the text end)
+ if( mnTrailingSpaceCount ) {
+ int nTrailingSpaceWidth = 0;
+ if( rArgs.mpDXArray) {
+ const int nFullPixWidth = nPixelWidth;
+ nPixelWidth = rArgs.mpDXArray[ mnCharCount-1-mnTrailingSpaceCount ];
+ nTrailingSpaceWidth = nFullPixWidth - nPixelWidth;
+ mfTrailingSpaceWidth = nTrailingSpaceWidth;
+ } else {
+ if( mfTrailingSpaceWidth <= 0.0 )
+ mfTrailingSpaceWidth = CTLineGetTrailingWhitespaceWidth( mpCTLine );
+ nTrailingSpaceWidth = rint( mfTrailingSpaceWidth );
+ nPixelWidth -= nTrailingSpaceWidth;
+ }
+ if( nPixelWidth <= 0 )
return;
+
// recreate the CoreText line layout without trailing spaces
CFRelease( mpCTLine );
CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, rArgs.mpStr + mnMinCharPos,
- mnCharCount - mnTrailingSpaces, kCFAllocatorNull );
+ mnCharCount - mnTrailingSpaceCount, kCFAllocatorNull );
CFAttributedStringRef pAttrStr = CFAttributedStringCreate( NULL, aCFText, mpTextStyle->GetStyleDict() );
mpCTLine = CTLineCreateWithAttributedString( pAttrStr );
CFRelease( aCFText);
CFRelease( pAttrStr );
+
+ // in RTL-layouts trailing spaces are leftmost
+ // TODO: use BiDi-algorithm to thoroughly check this assumption
+ if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL)
+ mnBaseAdv = nTrailingSpaceWidth;
}
- CTLineRef pNewCTLine = rCT.LineCreateJustifiedLine( mpCTLine, 1.0, nPixelWidth / mfFontScale );
+ const double fAdjustedWidth = nPixelWidth / mfFontScale;
+ CTLineRef pNewCTLine = CTLineCreateJustifiedLine( mpCTLine, 1.0, fAdjustedWidth );
if( !pNewCTLine ) { // CTLineCreateJustifiedLine can and does fail
// handle failure by keeping the unjustified layout
// TODO: a better solution such as
@@ -214,8 +216,7 @@ void CTLayout::AdjustLayout( ImplLayoutA
}
CFRelease( mpCTLine );
mpCTLine = pNewCTLine;
- mfCachedWidth = -1; // TODO: can we set it directly to target width we requested? For now we re-measure
- mfTrailingSpaceWidth = 0;
+ mfCachedWidth = fAdjustedWidth + mfTrailingSpaceWidth;
}
// -----------------------------------------------------------------------
@@ -383,10 +384,14 @@ long CTLayout::FillDXArray( sal_Int32* p
long nPixWidth = GetTextWidth();
if( pDXArray ) {
- // initialize the result array
- for( int i = 0; i < mnCharCount; ++i)
- pDXArray[i] = 0;
- //Â handle each glyph run
+ // prepare the sub-pixel accurate logical-width array
+ ::std::vector<float> aWidthVector( mnCharCount );
+ if( mnTrailingSpaceCount && (mfTrailingSpaceWidth > 0.0) ) {
+ const double fOneWidth = mfTrailingSpaceWidth / mnTrailingSpaceCount;
+ for( int i = 1; i <= mnTrailingSpaceCount; ++i)
+ aWidthVector[ mnCharCount - i ] = fOneWidth;
+ }
+ //Â measure advances in each glyph run
CFArrayRef aGlyphRuns = CTLineGetGlyphRuns( mpCTLine );
const int nRunCount = CFArrayGetCount( aGlyphRuns );
typedef std::vector<CGSize> CGSizeVector;
@@ -397,14 +402,23 @@ long CTLayout::FillDXArray( sal_Int32* p
CTRunRef pGlyphRun = (CTRunRef)CFArrayGetValueAtIndex( aGlyphRuns, nRunIndex );
const CFIndex nGlyphCount = CTRunGetGlyphCount( pGlyphRun );
const CFRange aFullRange = CFRangeMake( 0, nGlyphCount );
- aSizeVec.reserve( nGlyphCount );
- aIndexVec.reserve( nGlyphCount );
+ aSizeVec.resize( nGlyphCount );
+ aIndexVec.resize( nGlyphCount );
CTRunGetAdvances( pGlyphRun, aFullRange, &aSizeVec[0] );
CTRunGetStringIndices( pGlyphRun, aFullRange, &aIndexVec[0] );
for( int i = 0; i != nGlyphCount; ++i ) {
const int nRelIdx = aIndexVec[i];
- pDXArray[ nRelIdx ] += aSizeVec[i].width;
- }
+ aWidthVector[nRelIdx] += aSizeVec[i].width;
+ }
+ }
+
+ // convert the sub-pixel accurate array into classic pDXArray integers
+ float fWidthSum = 0.0;
+ sal_Int32 nOldDX = 0;
+ for( int i = 0; i < mnCharCount; ++i) {
+ const sal_Int32 nNewDX = rint( fWidthSum += aWidthVector[i]);
+ pDXArray[i] = nNewDX - nOldDX;
+ nOldDX = nNewDX;
}
}
Modified: openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/salbmp.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/salbmp.cxx?rev=1579184&r1=1579183&r2=1579184&view=diff
==============================================================================
--- openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/salbmp.cxx (original)
+++ openoffice/branches/alg_writerframes/main/vcl/aqua/source/gdi/salbmp.cxx Wed Mar 19 10:14:42 2014
@@ -772,7 +772,7 @@ CGImageRef AquaSalBitmap::CreateWithMask
CFRelease( xMask );
CGDataProviderRef xDataProvider( CGDataProviderCreateWithData( NULL,
pMaskMem, nHeight * nMaskBytesPerRow, &CFRTLFree ) );
- static const float* pDecode = NULL;
+ static const CGFloat* pDecode = NULL;
xMask = CGImageMaskCreate( nWidth, nHeight, 8, 8, nMaskBytesPerRow, xDataProvider, pDecode, false );
CFRelease( xDataProvider );
CFRelease( xMaskContext );