[Libreoffice-commits] .: 6 commits - config_host.mk.in configure.in slideshow/source solenv/gbuild vcl/aqua vcl/inc vcl/Library_vcl.mk

Norbert Thiebaud nthiebaud at kemper.freedesktop.org
Sat Jun 23 21:25:13 PDT 2012


 config_host.mk.in                                     |    3 
 configure.in                                          |   20 
 slideshow/source/engine/OGLTrans/mac/aquaOpenGLView.m |    7 
 solenv/gbuild/Module.mk                               |    2 
 vcl/Library_vcl.mk                                    |   36 
 vcl/aqua/source/gdi/atsui/salatslayout.cxx            | 1167 +++++++
 vcl/aqua/source/gdi/atsui/salatsuifontutils.cxx       |  493 +++
 vcl/aqua/source/gdi/atsui/salgdi.cxx                  | 1152 +++++++
 vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx |  603 +++
 vcl/aqua/source/gdi/coretext/salcoretextlayout.cxx    |  458 +++
 vcl/aqua/source/gdi/coretext/salcoretextstyle.cxx     |   93 
 vcl/aqua/source/gdi/coretext/salgdi.cxx               |  234 +
 vcl/aqua/source/gdi/salatslayout.cxx                  | 1167 -------
 vcl/aqua/source/gdi/salatsuifontutils.cxx             |  493 ---
 vcl/aqua/source/gdi/salgdi.cxx                        | 2718 ------------------
 vcl/aqua/source/gdi/salgdicommon.cxx                  | 1649 ++++++++++
 vcl/aqua/source/gdi/salgdiutils.cxx                   |    8 
 vcl/aqua/source/window/salframeview.mm                |    7 
 vcl/inc/aqua/atsui/salatsuifontutils.hxx              |   65 
 vcl/inc/aqua/atsui/salgdi.h                           |  370 ++
 vcl/inc/aqua/common.h                                 |   31 
 vcl/inc/aqua/coretext/salcoretextfontutils.hxx        |   67 
 vcl/inc/aqua/coretext/salcoretextlayout.hxx           |   64 
 vcl/inc/aqua/coretext/salcoretextstyle.hxx            |   42 
 vcl/inc/aqua/coretext/salgdi.h                        |  297 +
 vcl/inc/aqua/salatsuifontutils.hxx                    |   65 
 vcl/inc/aqua/salgdi.h                                 |  419 --
 vcl/inc/aqua/salgdicommon.hxx                         |   58 
 vcl/inc/vcl/sysdata.hxx                               |    8 
 29 files changed, 6927 insertions(+), 4869 deletions(-)

New commits:
commit 398552182ca6933a3f1693c8ca793cc35cd5e20c
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Apr 2 00:18:09 2012 -0500

    Export NOCPPUNIT to disable all cppunit test in gbuild.
    
    This is convinient when coding/debuging stuff that break
    unittest downstream, but oen still want to have a fully built
    product to test
    
    Change-Id: I4970db6ede1ed29bb3c421b56b5092c19fd9fa90

diff --git a/solenv/gbuild/Module.mk b/solenv/gbuild/Module.mk
index 20fbba5..435d1c9 100644
--- a/solenv/gbuild/Module.mk
+++ b/solenv/gbuild/Module.mk
@@ -235,6 +235,7 @@ $(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
 
 endef
 
+ifeq ($(strip $(NOCPPUNIT)),)
 define gb_Module_add_check_target
 $(call gb_Module__read_targetfile,$(1),$(2),check target)
 
@@ -242,6 +243,7 @@ $(call gb_Module_get_check_target,$(1)) : $$(gb_Module_CURRENTTARGET)
 $(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
 
 endef
+endif # NOCPPUNIT
 
 define gb_Module_add_slowcheck_target
 $(call gb_Module__read_targetfile,$(1),$(2),slowcheck target)
commit 8c91ec1ab0b6f437b8b60ed9aee067f088fa4718
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Apr 2 00:15:07 2012 -0500

    Initial basic support for CoreText. very partial and highly unstable.
    
    Change-Id: I5dc9fb342e45fa3d428e340a597a2d9d4e246cb5

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index f98ca98..451c15b 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -335,6 +335,17 @@ $(eval $(call gb_Library_add_defs,vcl,\
     -DENABLE_CORETEXT \
 ))
 
+$(eval $(call gb_Library_add_exception_objects,vcl,\
+    vcl/aqua/source/gdi/coretext/salcoretextfontutils \
+    vcl/aqua/source/gdi/coretext/salcoretextlayout \
+    vcl/aqua/source/gdi/coretext/salcoretextstyle \
+    vcl/aqua/source/gdi/coretext/salgdi \
+))
+
+$(eval $(call gb_Library_use_externals,vcl,\
+	coretext \
+))
+
 else # ATSUI
 
 $(eval $(call gb_Library_add_exception_objects,vcl,\
@@ -399,6 +410,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/aqua/source/dtrans/service_entry \
     vcl/aqua/source/gdi/salbmp \
     vcl/aqua/source/gdi/salcolorutils \
+    vcl/aqua/source/gdi/salgdicommon \
     vcl/aqua/source/gdi/salgdiutils \
     vcl/aqua/source/gdi/salmathutils \
     vcl/aqua/source/gdi/salnativewidgets \
diff --git a/vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx b/vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx
new file mode 100644
index 0000000..08db4fd
--- /dev/null
+++ b/vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx
@@ -0,0 +1,603 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include "aqua/common.h"
+
+#include "aqua/coretext/salcoretextfontutils.hxx"
+#include "aqua/coretext/salgdi.h"
+
+#include "sft.hxx"
+#include "aqua/salinst.h"
+
+
+static bool GetDevFontAttributes( CTFontDescriptorRef font_descriptor, ImplDevFontAttributes& rDFA  )
+{
+
+    // 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;
+    rDFA.mbOrientation = true;
+    rDFA.mbDevice      = true;
+    rDFA.mnQuality     = 0;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+    CTFontRef font = CTFontCreateWithFontDescriptor(font_descriptor, 0.0, NULL);
+    CFDataRef rHeadTable = CTFontCopyTable(font, kCTFontTableHead, kCTFontTableOptionNoOptions);
+    CFRelease(font);
+    if(!rHeadTable || CFDataGetLength(rHeadTable) == 0)
+    {
+        SafeCFRelease(rHeadTable);
+        return false;
+    }
+    CFRelease(rHeadTable);
+#else
+    CFNumberRef format = (CFNumberRef)CTFontDescriptorCopyAttribute(font_descriptor, kCTFontFormatAttribute);
+    int value = 0;
+    CFNumberGetValue(format, kCFNumberIntType, &value);
+    CFRelease(format);
+
+    if(value == kCTFontFormatBitmap)
+    {
+        /* we don't want bitmap fonts */
+        return false;
+    }
+#endif
+    rDFA.mbSubsettable  = true;
+    rDFA.mbEmbeddable   = false;
+
+    CFStringRef family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font_descriptor, kCTFontFamilyNameAttribute);
+    rDFA.maName = GetOUString(family_name);
+    CFRelease(family_name);
+
+    CFDictionaryRef traits = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font_descriptor, kCTFontTraitsAttribute);
+    CFNumberRef symbolics = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait);
+    int value = 0;
+    CFNumberGetValue(symbolics, kCFNumberIntType, &value);
+    CFRelease(symbolics);
+
+    if(value & kCTFontMonoSpaceTrait)
+    {
+        rDFA.mePitch = PITCH_FIXED;
+    }
+
+    if(value & kCTFontItalicTrait)
+    {
+        rDFA.meItalic = ITALIC_NORMAL;
+    }
+
+    if(value & kCTFontBoldTrait)
+    {
+        rDFA.meWeight = WEIGHT_BOLD;
+    }
+
+    if(value & kCTFontCondensedTrait)
+    {
+        rDFA.meWidthType = WIDTH_CONDENSED;
+    }
+    else if(value & kCTFontExpandedTrait)
+    {
+        rDFA.meWidthType = WIDTH_EXPANDED;
+    }
+    switch(value & kCTFontClassMaskTrait)
+    {
+    case kCTFontOldStyleSerifsClass:
+        rDFA.meFamily = FAMILY_ROMAN;
+        break;
+    case kCTFontTransitionalSerifsClass:
+    case kCTFontModernSerifsClass:
+    case kCTFontClarendonSerifsClass:
+    case kCTFontSlabSerifsClass:
+    case kCTFontFreeformSerifsClass:
+        break;
+    case kCTFontSansSerifClass:
+        rDFA.meFamily = FAMILY_SWISS;
+    case kCTFontOrnamentalsClass:
+        rDFA.meFamily = FAMILY_DECORATIVE;
+        break;
+    case kCTFontScriptsClass:
+        rDFA.meFamily = FAMILY_SCRIPT;
+        break;
+    case kCTFontSymbolicClass:
+        rDFA.mbSymbolFlag = true;
+        break;
+    }
+
+    CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontWeightTrait);
+    float fdval = 0.0;
+    CFNumberGetValue(weight, kCFNumberFloatType, &fdval);
+    if(fdval > 0.6)
+    {
+        rDFA.meWeight = WEIGHT_BLACK;
+    }
+    else if(fdval > 0.4)
+    {
+        rDFA.meWeight = WEIGHT_ULTRABOLD;
+    }
+    else if (fdval > 0.3)
+    {
+        rDFA.meWeight = WEIGHT_BOLD;
+    }
+    else if (fdval > 0.0)
+    {
+        rDFA.meWeight = WEIGHT_SEMIBOLD;
+    }
+    else if (fdval <= -0.8)
+    {
+        rDFA.meWeight = WEIGHT_ULTRALIGHT;
+    }
+    else if (fdval <= -0.4)
+    {
+        rDFA.meWeight = WEIGHT_LIGHT;
+    }
+    else if (fdval <= -0.3)
+    {
+        rDFA.meWeight = WEIGHT_SEMILIGHT;
+    }
+    else if (fdval <= -0.2)
+    {
+        rDFA.meWeight = WEIGHT_THIN;
+    }
+    else
+    {
+        rDFA.meWeight = WEIGHT_NORMAL;
+    }
+
+    CFStringRef string_ref = (CFStringRef)CTFontDescriptorCopyAttribute(font_descriptor, kCTFontStyleNameAttribute);
+    rtl::OUString font_name = GetOUString(string_ref);
+    rtl::OUString font_name_lc(font_name.toAsciiLowerCase());
+    CFRelease(string_ref);
+
+    // heuristics to adjust font slant
+    if( (font_name_lc.indexOf("oblique") != -1) ||
+        (font_name_lc.indexOf("inclined") != -1) ||
+        (font_name_lc.indexOf("slanted") != -1) )
+    {
+        rDFA.meItalic = ITALIC_OBLIQUE;
+    }
+
+    // heuristics to adjust font width
+    if (font_name_lc.indexOf("narrow") != -1)
+    {
+        rDFA.meWidthType = WIDTH_SEMI_CONDENSED;
+    }
+
+    // heuristics for font family type
+    if( (font_name_lc.indexOf("script") != -1) ||
+        (font_name_lc.indexOf("chancery") != -1) ||
+        (font_name_lc.indexOf("zapfino") != -1))
+    {
+        rDFA.meFamily = FAMILY_SCRIPT;
+    }
+    else if( (font_name_lc.indexOf("comic") != -1) ||
+             (font_name_lc.indexOf("outline") != -1) ||
+             (font_name_lc.indexOf("pinpoint") != -1) )
+    {
+        rDFA.meFamily = FAMILY_DECORATIVE;
+    }
+    else if( (font_name_lc.indexOf("sans") != -1) ||
+             (font_name_lc.indexOf("arial") != -1) )
+    {
+        rDFA.meFamily = FAMILY_SWISS;
+    }
+    else if( (font_name_lc.indexOf("roman") != -1) ||
+             (font_name_lc.indexOf("times") != -1) )
+    {
+        rDFA.meFamily = FAMILY_ROMAN;
+    }
+    return true;
+}
+
+SystemFontList::SystemFontList()
+{
+	CTFontCollectionRef font_collection = CTFontCollectionCreateFromAvailableFonts(NULL);
+    if(font_collection)
+    {
+        CFArrayRef font_descriptors = CTFontCollectionCreateMatchingFontDescriptors(font_collection);
+
+        for(int i = 0; i < CFArrayGetCount(font_descriptors); i++)
+        {
+            CTFontDescriptorRef font_descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(font_descriptors, i);
+            CTFontRef font = CTFontCreateWithFontDescriptor(font_descriptor, 0, NULL);
+            ImplDevFontAttributes devfont_attr;
+            if(GetDevFontAttributes( font_descriptor, devfont_attr ) )
+            {
+                ImplCoreTextFontData* font_data = new ImplCoreTextFontData(devfont_attr, font);
+                if(font_data && font_data->GetCTFont())
+                {
+                    m_aFontContainer [ font_data->GetCTFont() ] = font_data;
+                }
+            }
+            CFRelease(font);
+        }
+        CFRelease(font_descriptors);
+    }
+    CFRelease(font_collection);
+}
+
+SystemFontList::~SystemFontList()
+{
+    CoreTextFontContainer::const_iterator it = m_aFontContainer.begin();
+    for(; it != m_aFontContainer.end(); ++it )
+        delete (*it).second;
+    m_aFontContainer.clear();
+}
+
+ImplCoreTextFontData* SystemFontList::GetFontDataFromRef( CTFontRef font ) const
+{
+    CoreTextFontContainer::const_iterator it = m_aFontContainer.find( font );
+    return it == m_aFontContainer.end() ? NULL : (*it).second;
+}
+
+
+void SystemFontList::AnnounceFonts( ImplDevFontList& rFontList ) const
+{
+    CoreTextFontContainer::const_iterator it = m_aFontContainer.begin();
+    for(; it != m_aFontContainer.end(); ++it )
+    {
+        rFontList.Add( (*it).second->Clone() );
+    }
+}
+
+ImplCoreTextFontData::ImplCoreTextFontData( const ImplDevFontAttributes& rDFA, CTFontRef font )
+:   PhysicalFontFace( rDFA, 0 )
+,   m_CTFontRef((CTFontRef)CFRetain(font))
+,   m_pCharMap( NULL )
+,   m_bHasOs2Table( false )
+,   m_bOs2TableRead( false )
+,   m_bCmapTableRead( false )
+,   m_bHasCJKSupport( false )
+,   m_bFontCapabilitiesRead( false )
+{
+}
+
+ImplCoreTextFontData::~ImplCoreTextFontData()
+{
+    if( m_pCharMap )
+    {
+        m_pCharMap->DeReference();
+    }
+    if( m_CTFontRef )
+    {
+        CFRelease(m_CTFontRef);
+    }
+}
+
+PhysicalFontFace* ImplCoreTextFontData::Clone() const
+{
+    ImplCoreTextFontData* pClone = new ImplCoreTextFontData(*this);
+    if( m_pCharMap )
+    {
+        m_pCharMap->AddReference();
+    }
+    if( m_CTFontRef )
+    {
+        pClone->m_CTFontRef = (CTFontRef)CFRetain(m_CTFontRef);
+    }
+    return pClone;
+}
+
+ImplFontEntry* ImplCoreTextFontData::CreateFontInstance(FontSelectPattern& rFSD) const
+{
+    return new ImplFontEntry(rFSD);
+}
+
+const ImplFontCharMap* ImplCoreTextFontData::GetImplFontCharMap()
+{
+    // return the cached charmap
+    if( m_pCharMap )
+    {
+        return m_pCharMap;
+    }
+    // set the default charmap
+    m_pCharMap = ImplFontCharMap::GetDefaultMap();
+    m_pCharMap->AddReference();
+
+    // get the CMAP byte size
+    CFDataRef rCmapTable = CTFontCopyTable( m_CTFontRef, kCTFontTableCmap, kCTFontTableOptionNoOptions);
+    if(!rCmapTable)
+    {
+        return m_pCharMap;
+    }
+    if(!m_bCmapTableRead)
+    {
+        m_bCmapTableRead = true;
+        DetermineCJKSupport_cmap(rCmapTable);
+    }
+    // parse the CMAP
+    CmapResult aCmapResult;
+    if(ParseCMAP( CFDataGetBytePtr(rCmapTable), CFDataGetLength(rCmapTable), aCmapResult ) )
+    {
+        m_pCharMap = new ImplFontCharMap( aCmapResult );
+        m_pCharMap->AddReference();
+    }
+    CFRelease(rCmapTable);
+    return m_pCharMap;
+}
+
+bool ImplCoreTextFontData::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities)
+{
+    // read this only once per font
+    if( m_bFontCapabilitiesRead )
+    {
+        rFontCapabilities = m_aFontCapabilities;
+        return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty();
+    }
+    m_bFontCapabilitiesRead = true;
+
+    // get the GSUB table raw data
+    CFDataRef rGSUBTable = CTFontCopyTable( m_CTFontRef, kCTFontTableGSUB, kCTFontTableOptionNoOptions);
+    if(rGSUBTable)
+    {
+
+        vcl::getTTScripts(m_aFontCapabilities.maGSUBScriptTags,
+                          CFDataGetBytePtr(rGSUBTable), CFDataGetLength(rGSUBTable));
+        CFRelease(rGSUBTable);
+    }
+    CFDataRef OS2_Table = CTFontCopyTable( m_CTFontRef, kCTFontTableOS2, kCTFontTableOptionNoOptions);
+    if(OS2_Table)
+    {
+        vcl::getTTCoverage(
+                m_aFontCapabilities.maUnicodeRange,
+                m_aFontCapabilities.maCodePageRange,
+                CFDataGetBytePtr(OS2_Table), CFDataGetLength(OS2_Table));
+        /* while we are at it let's solve HasCJK for the same price */
+        if(!m_bOs2TableRead )
+        {
+            m_bOs2TableRead = true;
+            m_bHasOs2Table = true;
+            DetermineCJKSupport_OS2(OS2_Table);
+        }
+        CFRelease(OS2_Table);
+    }
+    rFontCapabilities = m_aFontCapabilities;
+    return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty();
+}
+
+struct font_table
+{
+    unsigned char* table;
+    unsigned char* dir_entry;
+    unsigned char* cursor;
+};
+
+void addTable(struct font_table* table, CTFontTableTag tag, CFDataRef data)
+{
+    if(data && CFDataGetLength(data) > 0)
+    {
+        *(uint32_t*)table->dir_entry = CFSwapInt32HostToBig(tag);
+        table->dir_entry += 4;
+        *(uint32_t*)table->dir_entry = 0; /* TODO: checksum */
+        table->dir_entry += 4;
+        *(uint32_t*)table->dir_entry = CFSwapInt32HostToBig((uint32_t)((uintptr_t)table->cursor - (uintptr_t)table));
+        table->dir_entry += 4;
+        *(uint32_t*)table->dir_entry = CFSwapInt32HostToBig(CFDataGetLength(data));
+        table->dir_entry += 4;
+
+        memcpy(table->cursor, CFDataGetBytePtr(data), CFDataGetLength(data));
+        table->cursor += CFDataGetLength(data);
+    }
+}
+
+bool ImplCoreTextFontData::GetRawFontData( std::vector<unsigned char>& rBuffer, bool* pJustCFF ) const
+{
+    bool rc;
+    int table_count = 0;
+
+    CFDataRef CFF_table = CTFontCopyTable( m_CTFontRef, kCTFontTableCFF, kCTFontTableOptionNoOptions);
+    if(pJustCFF)
+    {
+        if(CFF_table)
+        {
+            *pJustCFF = CFDataGetLength(CFF_table) ? true : false;
+        }
+        if(CFF_table)
+        {
+            CFRelease(CFF_table);
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    size_t total_len = 0;
+    CFDataRef head_table = CTFontCopyTable( m_CTFontRef, kCTFontTableHead, kCTFontTableOptionNoOptions);
+    CFDataRef maxp_table = CTFontCopyTable( m_CTFontRef, kCTFontTableMaxp, kCTFontTableOptionNoOptions);
+    CFDataRef cmap_table = CTFontCopyTable( m_CTFontRef, kCTFontTableHead, kCTFontTableOptionNoOptions);
+    CFDataRef name_table = CTFontCopyTable( m_CTFontRef, kCTFontTableName, kCTFontTableOptionNoOptions);
+    CFDataRef hhea_table = CTFontCopyTable( m_CTFontRef, kCTFontTableHhea, kCTFontTableOptionNoOptions);
+    CFDataRef hmtx_table = CTFontCopyTable( m_CTFontRef, kCTFontTableHmtx, kCTFontTableOptionNoOptions);
+    rc = false;
+    if(head_table && maxp_table && cmap_table && name_table && hhea_table && hmtx_table)
+    {
+        if(CFDataGetLength(head_table) &&
+           CFDataGetLength(maxp_table) &&
+           CFDataGetLength(name_table) &&
+           CFDataGetLength(hhea_table) &&
+           CFDataGetLength(hmtx_table))
+        {
+            table_count += 6;
+            total_len = CFDataGetLength(head_table) +
+                CFDataGetLength(maxp_table) +
+                CFDataGetLength(name_table) +
+                CFDataGetLength(hhea_table) +
+                CFDataGetLength(hmtx_table);
+            rc = true;
+        }
+    }
+
+    CFDataRef loca_table = NULL;
+    CFDataRef glyf_table = NULL;
+    CFDataRef prep_table = NULL;
+    CFDataRef cvt_table = NULL;
+    CFDataRef fpgm_table = NULL;
+    if(rc)
+    {
+        if(!CFF_table || CFDataGetLength(CFF_table) == 0)
+        {
+            loca_table = CTFontCopyTable( m_CTFontRef, kCTFontTableLoca, kCTFontTableOptionNoOptions);
+            glyf_table = CTFontCopyTable( m_CTFontRef, kCTFontTableGlyf, kCTFontTableOptionNoOptions);
+            if(!loca_table  || !glyf_table || !CFDataGetLength(loca_table) || !CFDataGetLength(glyf_table))
+            {
+                rc = false;
+            }
+            else
+            {
+                table_count += 2;
+                total_len += CFDataGetLength(loca_table) + CFDataGetLength(glyf_table);
+                prep_table = CTFontCopyTable( m_CTFontRef, kCTFontTablePrep, kCTFontTableOptionNoOptions);
+                cvt_table = CTFontCopyTable( m_CTFontRef, kCTFontTableCvt, kCTFontTableOptionNoOptions);
+                fpgm_table = CTFontCopyTable( m_CTFontRef, kCTFontTableFpgm, kCTFontTableOptionNoOptions);
+                if(prep_table || CFDataGetLength(prep_table) > 0)
+                {
+                    table_count += 1;
+                    total_len += CFDataGetLength(prep_table);
+                }
+                if(cvt_table || CFDataGetLength(cvt_table) > 0)
+                {
+                    table_count += 1;
+                    total_len += CFDataGetLength(cvt_table);
+                }
+                if(fpgm_table || CFDataGetLength(fpgm_table) > 0)
+                {
+                    table_count += 1;
+                    total_len += CFDataGetLength(fpgm_table);
+                }
+            }
+        }
+        else
+        {
+            table_count += 1;
+            total_len += CFDataGetLength(CFF_table);
+        }
+    }
+    if(rc)
+    {
+        total_len += 12 + 16 * table_count;
+        rBuffer.resize(total_len);
+        struct font_table table;
+        unsigned char* cursor = &rBuffer[0];
+        int nLog2 = 0;
+
+        while( (table_count >> nLog2) > 1 ) ++nLog2;
+
+        table.table = cursor;
+        *(uint16_t*)cursor = CFSwapInt16HostToBig(1);
+        cursor += 2;
+        *(uint16_t*)cursor = 0;
+        cursor += 2;
+        *(uint16_t*)cursor = CFSwapInt16HostToBig(table_count);
+        cursor += 2;
+        *(uint16_t*)cursor = CFSwapInt16HostToBig(nLog2 * 16);
+        cursor += 2;
+        *(uint16_t*)cursor = CFSwapInt16HostToBig(nLog2);
+        cursor += 2;
+        *(uint16_t*)cursor = CFSwapInt16HostToBig((table_count - nLog2) * 16); // rangeShift
+        cursor += 2;
+        table.dir_entry = cursor;
+        cursor += (16 * table_count);
+        table.cursor = cursor;
+        addTable(&table, kCTFontTableCmap, cmap_table);
+        addTable(&table, kCTFontTableCvt, cvt_table);
+        addTable(&table, kCTFontTableFpgm, fpgm_table);
+        addTable(&table, kCTFontTableCFF, CFF_table);
+        addTable(&table, kCTFontTableGlyf, glyf_table);
+        addTable(&table, kCTFontTableLoca, loca_table);
+        addTable(&table, kCTFontTableHead, head_table);
+        addTable(&table, kCTFontTableHhea, hhea_table);
+        addTable(&table, kCTFontTableHmtx, hmtx_table);
+        addTable(&table, kCTFontTableMaxp, maxp_table);
+        addTable(&table, kCTFontTableName, name_table);
+        addTable(&table, kCTFontTablePrep, prep_table);
+    }
+    SafeCFRelease(cmap_table);
+    SafeCFRelease(cvt_table);
+    SafeCFRelease(fpgm_table);
+    SafeCFRelease(CFF_table);
+    SafeCFRelease(glyf_table);
+    SafeCFRelease(loca_table);
+    SafeCFRelease(head_table);
+    SafeCFRelease(hhea_table);
+    SafeCFRelease(hmtx_table);
+    SafeCFRelease(maxp_table);
+    SafeCFRelease(name_table);
+    SafeCFRelease(prep_table);
+
+    return rc;
+}
+
+void ImplCoreTextFontData::DetermineCJKSupport_OS2(CFDataRef rOS2Table)
+{
+    if(CFDataGetLength(rOS2Table) >= 48)
+    {
+        const unsigned short* pOS2buffer = (const unsigned short*)CFDataGetBytePtr(rOS2Table);
+        const unsigned short version = CFSwapInt16BigToHost(pOS2buffer[0]);
+        if( version >= 1)
+        {
+            const unsigned short unicode_range = CFSwapInt16BigToHost(pOS2buffer[23]);
+            if( unicode_range & 0x2DF0)
+            {
+                m_bHasCJKSupport = true;
+            }
+        }
+    }
+}
+
+void ImplCoreTextFontData::DetermineCJKSupport_cmap(CFDataRef rCmapTable)
+{
+    int table_len = CFDataGetLength(rCmapTable) / 2;
+    if(table_len >= 12)
+    {
+        const unsigned short* pCmap = (const unsigned short*)CFDataGetBytePtr(rCmapTable);
+        if(pCmap[0] == 0)
+        {
+            short nb_sub_tables = CFSwapInt16BigToHost(pCmap[1]);
+            for(int i = 2; --nb_sub_tables >= 0 && i < table_len; i += 4)
+            {
+                short platform = CFSwapInt16BigToHost(pCmap[i]);
+                if( platform == kFontMacintoshPlatform )
+                {
+                    short encoding = CFSwapInt16BigToHost(pCmap[i+1]);
+                    if( encoding == kFontJapaneseScript ||
+                        encoding == kFontTraditionalChineseScript ||
+                        encoding == kFontKoreanScript ||
+                        encoding == kFontSimpleChineseScript )
+                    {
+                        m_bHasCJKSupport = true;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+
+bool ImplCoreTextFontData::HasCJKSupport( void )
+{
+    // read this only once per font
+    if(!m_bOs2TableRead )
+    {
+        m_bOs2TableRead = true;
+        CFDataRef rOS2Table = CTFontCopyTable( m_CTFontRef, kCTFontTableOS2, kCTFontTableOptionNoOptions);
+        if(rOS2Table)
+        {
+            m_bHasOs2Table = true;
+            DetermineCJKSupport_OS2(rOS2Table);
+            CFRelease(rOS2Table);
+        }
+    }
+    if( !m_bCmapTableRead && !m_bHasOs2Table && !m_bHasCJKSupport )
+    {
+        m_bCmapTableRead = true;
+        CFDataRef rCmapTable = CTFontCopyTable( m_CTFontRef, kCTFontTableCmap, kCTFontTableOptionNoOptions);
+        if(rCmapTable)
+        {
+            DetermineCJKSupport_cmap(rCmapTable);
+            CFRelease(rCmapTable);
+        }
+    }
+    return m_bHasCJKSupport;
+}
diff --git a/vcl/aqua/source/gdi/coretext/salcoretextlayout.cxx b/vcl/aqua/source/gdi/coretext/salcoretextlayout.cxx
new file mode 100644
index 0000000..408f2b2
--- /dev/null
+++ b/vcl/aqua/source/gdi/coretext/salcoretextlayout.cxx
@@ -0,0 +1,458 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include "aqua/common.h"
+#include "aqua/coretext/salcoretextstyle.hxx"
+#include "aqua/coretext/salcoretextlayout.hxx"
+#include "aqua/coretext/salgdi.h"
+
+
+CoreTextLayout::CoreTextLayout(AquaSalGraphics* graphics, CoreTextStyleInfo* style) :
+    m_graphics(graphics),
+    m_style(style),
+    m_glyphs_count(-1),
+    m_chars_count(-1),
+    m_chars2glyphs(NULL),
+    m_glyphs2chars(NULL),
+    m_glyphs(NULL),
+    m_char_widths(NULL),
+    m_glyph_advances(NULL),
+    m_glyph_positions(NULL),
+    m_typesetter(NULL),
+    m_line(NULL),
+    m_has_bound_rec(false),
+    m_base_advance(0),
+    m_cached_width(0.0F),
+    m_current_run_index(0),
+    m_current_glyph_index(0),
+    m_current_glyphrun_index(0),
+    m_runs(NULL)
+{
+}
+
+CoreTextLayout::~CoreTextLayout()
+{
+    Clean();
+}
+
+void CoreTextLayout::AdjustLayout( ImplLayoutArgs& /*rArgs*/ )
+{
+    msgs_debug(layout,"-->");
+    msgs_debug(layout,"<--");
+    /* TODO */
+}
+
+void CoreTextLayout::Clean()
+{
+    msgs_debug(layout,"-->");
+    if(m_glyphs)
+    {
+        delete[] m_glyphs;
+        m_glyphs = NULL;
+    }
+    if(m_chars2glyphs)
+    {
+        delete[] m_chars2glyphs;
+        m_chars2glyphs = NULL;
+    }
+    if(m_glyphs2chars)
+    {
+        delete[] m_glyphs2chars;
+        m_glyphs2chars = NULL;
+    }
+    if(m_char_widths)
+    {
+        delete[] m_char_widths;
+        m_char_widths = NULL;
+    }
+    if(m_glyph_advances)
+    {
+        delete[] m_glyph_advances;
+        m_glyph_advances = NULL;
+    }
+    if(m_glyph_positions)
+    {
+        delete[] m_glyph_positions;
+        m_glyph_positions = NULL;
+    }
+    SafeCFRelease(m_typesetter);
+    SafeCFRelease(m_line);
+    m_has_bound_rec = false;
+    msgs_debug(layout,"<--");
+}
+
+void CoreTextLayout::DrawText( SalGraphics& rGraphics ) const
+{
+    msgs_debug(layout,"-->");
+    AquaSalGraphics& gr = static_cast<AquaSalGraphics&>(rGraphics);
+    if(m_chars_count <= 0 || !gr.CheckContext())
+    {
+        return;
+    }
+    CGContextSaveGState( gr.mrContext );
+    Point pos = GetDrawPosition(Point(0,0));
+#if 0
+    msgs_debug(layout,"at pos (%ld, %ld)", pos.X(), pos.Y());
+    CGContextSetTextMatrix(gr.mrContext, CGAffineTransformMakeScale(1.0, -1.0));
+    CGContextSetShouldAntialias( gr.mrContext, !gr.mbNonAntialiasedText );
+    CGContextSetTextPosition(gr.mrContext, pos.X(), pos.Y());
+    CTLineDraw(m_line, gr.mrContext);
+#else
+    InitGIA();
+    msgs_debug(layout,"at- pos (%ld, %ld)", pos.X(), pos.Y());
+    CGFontRef cg_font = CTFontCopyGraphicsFont(m_style->GetFont(), NULL);
+    CGContextSetFont(gr.mrContext, cg_font);
+    CGContextSetFontSize(gr.mrContext, CTFontGetSize(m_style->GetFont()));
+    CGContextSetTextDrawingMode(gr.mrContext, kCGTextFill);
+    CGContextSetShouldAntialias( gr.mrContext, true );
+    if(m_style->GetColor())
+    {
+        CGContextSetFillColorWithColor(gr.mrContext, m_style->GetColor());
+        CGContextSetStrokeColorWithColor(gr.mrContext, m_style->GetColor());
+    }
+    else
+    {
+        CGContextSetRGBFillColor(gr.mrContext, 0.0, 0.0, 0.0, 1.0);
+    }
+    CFRelease(cg_font);
+//    CGContextSetTextPosition(gr.mrContext, pos.X(), pos.Y());
+    CGContextSetTextMatrix(gr.mrContext, CGAffineTransformMakeScale(1.0, -1.0));
+    CGContextSetShouldAntialias( gr.mrContext, !gr.mbNonAntialiasedText );
+    CGContextTranslateCTM(gr.mrContext, pos.X(), pos.Y());
+//    for(int i = 0; i < m_glyphs_count ; ++i)
+//    {
+//        msgs_debug(layout,"m_glyph=%p m_glyph_positions=%p count=%d", m_glyphs, m_glyph_positions, m_glyphs_count);
+//        msgs_debug(layout,"glyph[%d]=0x%x position(%g,%g)", i, m_glyphs[i], m_glyph_positions[i].x, m_glyph_positions[i].y);
+        CGContextShowGlyphs(gr.mrContext, m_glyphs, m_glyphs_count);
+//        CGContextShowGlyphsAtPositions(gr.mrContext, m_glyphs, m_glyph_positions, m_glyphs_count);
+//        CGContextShowGlyphsWidthAdvances(gr.mrContext, m_glyphs, m_glyph_advances, m_glyphs_count);
+
+//        CGContextShowGlyphsAtPoint(gr.mrContext, pos.X(), pos.Y(), m_glyphs, m_glyphs_count);
+//    }
+#endif
+    // restore the original graphic context transformations
+    CGContextRestoreGState( gr.mrContext );
+    msgs_debug(layout,"<--");
+
+}
+
+// not needed. CoreText manage fallback directly
+void CoreTextLayout::DropGlyph( int /*nStart*/ ) {}
+
+long CoreTextLayout::FillDXArray( long* pDXArray ) const
+{
+    msgs_debug(layout,"-->");
+    // short circuit requests which don't need full details
+    if( !pDXArray )
+    {
+        return GetTextWidth();
+    }
+    // check assumptions
+    DBG_ASSERT( !mnTrailingSpaceWidth, "CoreText::FillDXArray() with nTSW!=0" );
+
+    // initialize details about the resulting layout
+    InitGIA();
+
+    // distribute the widths among the string elements
+    long width = 0;
+    float scale = m_style->GetFontStretchFactor();
+    m_cached_width = 0;
+
+    for( int i = 0; i < m_chars_count; ++i )
+    {
+        // convert and adjust for accumulated rounding errors
+        m_cached_width += m_char_widths[i];
+        const long old_width = width;
+        width = round_to_long(m_cached_width * scale);
+        pDXArray[i] = width - old_width;
+    }
+    msgs_debug(layout," w=%ld <--", width);
+    return width;
+}
+
+bool CoreTextLayout::GetBoundRect( SalGraphics& rGraphics, Rectangle& rVCLRect ) const
+{
+
+    msgs_debug(layout,"-->");
+    if ( !m_has_bound_rec )
+    {
+        AquaSalGraphics& gr = static_cast<AquaSalGraphics&>(rGraphics);
+        CGRect bound_rect = CTLineGetImageBounds( m_line, gr.mrContext );
+        if ( !CGRectIsNull( bound_rect ) )
+        {
+            m_bound_rect = Rectangle(
+                Point( round_to_long(bound_rect.origin.x * m_style->GetFontStretchFactor()),
+                       round_to_long(bound_rect.origin.y - bound_rect.size.height )),
+                Size( round_to_long(bound_rect.size.width * m_style->GetFontStretchFactor()), round_to_long(bound_rect.size.height)));
+            m_bound_rect.Justify();
+        }
+        m_has_bound_rec = true;
+    }
+    rVCLRect = m_bound_rect;
+    msgs_debug(layout,"<--");
+    return true;
+}
+
+void CoreTextLayout::GetCaretPositions( int max_index, long* caret_position) const
+{
+    msgs_debug(layout,"max_index %d -->", max_index);
+    int local_max = max_index < m_chars_count * 2 ? max_index : m_chars_count;
+    for(int i = 0 ; i < max_index - 1; i+=2)
+    {
+        CGFloat primary, secondary;
+        primary = CTLineGetOffsetForStringIndex(m_line, i >> 1, &secondary);
+        caret_position[i] = round_to_long(m_base_advance + primary);
+        caret_position[i+1] = round_to_long(m_base_advance + secondary);
+        i += 2;
+    }
+    for(int i = local_max ; i < max_index ; ++i)
+    {
+        caret_position[i] = -1;
+    }
+    msgs_debug(layout,"<--");
+}
+
+bool CoreTextLayout::GetGlyphOutlines( SalGraphics&, PolyPolyVector& ) const { return false; }
+
+int CoreTextLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIDs, Point& rPos, int& nStart,
+                                   sal_Int32* pGlyphAdvances, int* pCharIndexes ) const
+{
+    msgs_debug(layout,"nLen=%d nStart=%d-->", nLen, nStart);
+    // get glyph measurements
+    InitGIA();
+
+    if( nStart < 0 )                // first glyph requested?
+    {
+        nStart = 0;
+        m_current_run_index = 0;
+        m_current_glyph_index = 0;
+        m_current_glyphrun_index = 0;
+    }
+    else if(nStart >= m_glyphs_count)
+    {
+        m_current_run_index = 0;
+        m_current_glyph_index = 0;
+        m_current_glyphrun_index = 0;
+        return 0;
+    }
+    if(!m_runs)
+    {
+        m_runs = CTLineGetGlyphRuns(m_line);
+    }
+    CFIndex nb_runs = CFArrayGetCount( m_runs );
+    CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex( m_runs, m_current_run_index );
+    CFIndex nb_glyphs = CTRunGetGlyphCount( run );
+
+    int i = 0;
+    bool first = true;
+    while(i < nLen)
+    {
+        if(m_current_glyphrun_index >= nb_glyphs)
+        {
+            m_current_run_index += 1;
+            if(m_current_run_index >= nb_runs)
+            {
+                break;
+            }
+            run = (CTRunRef)CFArrayGetValueAtIndex( m_runs, m_current_run_index );
+            nb_glyphs = CTRunGetGlyphCount( run );
+            m_current_glyphrun_index = 0;
+        }
+        if(first)
+        {
+            CGPoint first_pos;
+            CTRunGetPositions(run, CFRangeMake(m_current_glyphrun_index,1), &first_pos);
+            Point pos(first_pos.x, first_pos.y);
+            rPos = GetDrawPosition(pos);
+            msgs_debug(layout,"rPos(%ld, %ld)", rPos.X(),rPos.Y());
+            first = false;
+        }
+        pGlyphIDs[i] = m_glyphs[m_current_glyph_index];
+        if(pGlyphAdvances)
+        {
+            pGlyphAdvances[i] = m_glyph_advances[m_current_glyph_index];
+        }
+        if(pCharIndexes)
+        {
+            pCharIndexes[i] = m_glyphs2chars[m_current_glyph_index];
+        }
+        m_current_glyph_index += 1;
+        m_current_glyphrun_index += 1;
+        i += 1;
+        nStart += 1;
+    }
+    msgs_debug(layout,"i=%d <--", i);
+    return i;
+}
+
+int CoreTextLayout::GetTextBreak( long /*nMaxWidth*/, long /*nCharExtra*/, int /*nFactor*/ ) const
+{
+    /* TODO */
+    return false;
+}
+
+long CoreTextLayout::GetTextWidth() const
+{
+    msgs_debug(layout,"-->");
+
+    CGRect bound_rect = CTLineGetImageBounds(m_line, m_graphics->GetContext());
+    long w = round_to_long(bound_rect.size.width * m_style->GetFontStretchFactor());
+    msgs_debug(layout,"w=%ld <--", w);
+    return w;
+}
+
+// not needed. CoreText manage fallback directly
+void CoreTextLayout::InitFont() const
+{
+    msgs_debug(layout,"<-->");
+}
+
+bool CoreTextLayout::InitGIA() const
+{
+    msgs_debug(layout,"count=%d <--",  m_chars_count);
+
+    if( m_chars_count <= 0)
+    {
+        return false;
+    }
+    if(m_glyphs)
+    {
+        return true;
+    }
+
+    m_glyphs = new CGGlyph[m_glyphs_count];
+    m_char_widths = new int[ m_chars_count ];
+    m_chars2glyphs = new int[ m_chars_count ];
+    for( int i = 0; i < m_chars_count; ++i)
+    {
+        m_char_widths[i] = 0.0;
+        m_chars2glyphs[i] = -1;
+    }
+    m_glyphs2chars = new int[m_glyphs_count];
+    m_glyph_advances = new int[m_glyphs_count];
+    m_glyph_positions = new CGPoint[m_glyphs_count];
+
+
+    CFArrayRef runs = CTLineGetGlyphRuns( m_line );
+    CFIndex nb_runs = CFArrayGetCount( runs );
+    int p = 0;
+    for( CFIndex i = 0; i < nb_runs; ++i )
+    {
+        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex( runs, i );
+        if( run )
+        {
+			CFIndex nb_glyphs = CTRunGetGlyphCount( run );
+            if(nb_glyphs)
+            {
+                CFRange text_range = CTRunGetStringRange( run );
+                if( text_range.location != kCFNotFound && text_range.length > 0 )
+                {
+                    CFIndex indices[ nb_glyphs ];
+                    CGGlyph glyphs[ nb_glyphs ];
+                    CTRunGetStringIndices( run, CFRangeMake( 0, 0 ), indices );
+                    CTRunGetGlyphs( run, CFRangeMake( 0, 0 ), glyphs );
+                    CTRunGetPositions( run, CFRangeMake( 0, 0 ), &m_glyph_positions[p] );
+                    bool is_vertical_run = false;
+                    CFDictionaryRef aDict = CTRunGetAttributes( run );
+                    if ( aDict )
+                    {
+                        const CFBooleanRef aValue = (const CFBooleanRef)CFDictionaryGetValue( aDict, kCTVerticalFormsAttributeName );
+                        is_vertical_run =  (aValue == kCFBooleanTrue) ? true : false;
+                    }
+
+                    for (CFIndex j = 0 ; j < nb_glyphs; ++p, ++j )
+                    {
+                        m_glyphs[ p ] = glyphs[ j ];
+                        CFIndex k = indices[ j ];
+                        m_glyphs2chars[p] = k;
+                        m_chars2glyphs[k] = p;
+
+                        if ( j < nb_glyphs - 1 )
+                        {
+                            m_char_widths[ k ] += m_glyph_positions[ p + 1 ].x - m_glyph_positions[ p ].x;
+                        }
+                        if( p > 0)
+                        {
+                            m_glyph_advances[p - 1] = m_glyph_positions[ p ].x - m_glyph_positions[p - 1].x;
+                        }
+                    }
+                }
+			}
+        }
+    }
+    msgs_debug(layout,"<--");
+    return true;
+}
+
+bool CoreTextLayout::LayoutText(ImplLayoutArgs& args)
+{
+    msgs_debug(layout,"-->");
+    Clean();
+    m_style->SetColor();
+    /* retreive MinCharPos EndCharPos Flags and Orientation */
+    SalLayout::AdjustLayout(args);
+    m_chars_count = mnEndCharPos - mnMinCharPos;
+
+    /* don't layout emptty (or worse negative size) strings */
+    if(m_chars_count <= 0)
+    {
+        return false;
+    }
+    /* c0 and c1 are construction objects */
+    CFStringRef c0 = CFStringCreateWithCharactersNoCopy( NULL, &(args.mpStr[args.mnMinCharPos]), m_chars_count, kCFAllocatorNull );
+    if ( !c0 )
+    {
+        Clean();
+        return false;
+    }
+
+    CFStringRef keys[6];
+    CFTypeRef   values[6];
+    int nb_attributes = 0;
+
+    keys[nb_attributes]= kCTFontAttributeName;
+    values[nb_attributes] = m_style->GetFont();
+    nb_attributes += 1;
+
+    CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault,
+                                                    (const void**)&keys,
+                                                    (const void**)&values,
+                                                    nb_attributes,
+                                                    &kCFTypeDictionaryKeyCallBacks,
+                                                    &kCFTypeDictionaryValueCallBacks);
+
+
+    CFAttributedStringRef string = CFAttributedStringCreate( NULL, c0, attributes );
+    CFRelease( c0 );
+    CFRelease( attributes );
+    if ( !string )
+    {
+        Clean();
+        return false;
+    }
+    m_typesetter = CTTypesetterCreateWithAttributedString(string);
+    CFRelease(string);
+    if(!m_typesetter)
+    {
+        Clean();
+        return false;
+    }
+    m_line = CTTypesetterCreateLine(m_typesetter, CFRangeMake(0, 0));
+    if(!m_line)
+    {
+        Clean();
+        return false;
+    }
+    m_glyphs_count = CTLineGetGlyphCount(m_line);
+
+    msgs_debug(layout,"glyph_count=%d <--", m_glyphs_count);
+    return true;
+}
+
+// not needed. CoreText manage fallback directly
+void CoreTextLayout::MoveGlyph( int /*nStart*/, long /*nNewXPos*/ ) {}
+
+// not needed. CoreText manage fallback directly
+void CoreTextLayout::Simplify( bool /*bIsBase*/ ) {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/vcl/aqua/source/gdi/coretext/salcoretextstyle.cxx b/vcl/aqua/source/gdi/coretext/salcoretextstyle.cxx
new file mode 100644
index 0000000..5a092af
--- /dev/null
+++ b/vcl/aqua/source/gdi/coretext/salcoretextstyle.cxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include "aqua/common.h"
+#include "outfont.hxx"
+#include "aqua/coretext/salcoretextfontutils.hxx"
+#include "aqua/coretext/salcoretextstyle.hxx"
+
+CoreTextStyleInfo::CoreTextStyleInfo() :
+    m_fake_bold(false),
+    m_fake_italic(false),
+    m_matrix(CGAffineTransformIdentity),
+    m_stretch_factor(1.0),
+    m_CTParagraphStyle(NULL),
+    m_CTFont(NULL),
+    m_color(NULL),
+    m_font_data(NULL)
+{
+    msgs_debug(style,"create <-->");
+}
+
+CoreTextStyleInfo::~CoreTextStyleInfo()
+{
+    msgs_debug(style,"destroy (font:%p) <-->", m_CTFont);
+    SafeCFRelease(m_CTFont);
+    SafeCFRelease(m_CTParagraphStyle);
+    SafeCFRelease(m_color);
+}
+
+long CoreTextStyleInfo::GetFontStretchedSize() const
+{
+    CGFloat size = CTFontGetSize(m_CTFont);
+    return static_cast<long>(size * m_stretch_factor + 0.5);
+}
+
+void CoreTextStyleInfo::SetFont(FontSelectPattern* requested_font)
+{
+    msgs_debug(style,"req(%p) release font %p -->", requested_font, m_CTFont);
+    SafeCFRelease(m_CTFont);
+    if(!requested_font)
+    {
+        m_font_data = NULL;
+        return;
+    }
+    const ImplCoreTextFontData* font_data = static_cast<const ImplCoreTextFontData*>(requested_font->mpFontData);
+
+    m_font_data = (ImplCoreTextFontData*)font_data;
+    m_matrix = CGAffineTransformIdentity;
+    CGFloat font_size = (CGFloat)requested_font->mfExactHeight;
+
+    // enable bold-emulation if needed
+    if( (requested_font->GetWeight() >= WEIGHT_BOLD) &&
+        (font_data->GetWeight() < WEIGHT_SEMIBOLD) )
+    {
+        /* FIXME: add support for fake bold */
+        m_fake_bold = true;
+    }
+    if( ((requested_font->GetSlant() == ITALIC_NORMAL) || (requested_font->GetSlant() == ITALIC_OBLIQUE)) &&
+        !((font_data->GetSlant() == ITALIC_NORMAL) || (font_data->GetSlant() == ITALIC_OBLIQUE)) )
+    {
+#define kRotationForItalicText 10
+        m_fake_italic = true;
+        /* about 6 degree of slant */
+        m_matrix = CGAffineTransformMake( 1, 0, -tanf( kRotationForItalicText * acosf(0) / 90 ), 1, 0, 0);
+    }
+
+    // prepare font stretching
+    if( (requested_font->mnWidth != 0) && (requested_font->mnWidth != requested_font->mnHeight) )
+    {
+        m_stretch_factor = (float)requested_font->mnWidth / requested_font->mnHeight;
+        m_matrix = CGAffineTransformScale(m_matrix, m_stretch_factor, 1.0F );
+    }
+
+    /* FIXME: pass attribute to take into accout 'VerticalStyle' */
+    /* FIXME: how to deal with 'rendering options' i.e anti-aliasing, does it even matter in CoreText ? */
+    m_CTFont = CTFontCreateCopyWithAttributes(font_data->GetCTFont(), font_size, &m_matrix, NULL);
+    msgs_debug(style,"font %p <--", m_CTFont);
+}
+
+void CoreTextStyleInfo::SetColor(SalColor color)
+{
+    msgs_debug(style, "r:%d g:%d b:%d -->", SALCOLOR_RED(color), SALCOLOR_GREEN(color), SALCOLOR_BLUE(color));
+    SafeCFRelease(m_color);
+    m_color = CGColorCreateGenericRGB(SALCOLOR_RED(color) / 255.0, SALCOLOR_GREEN(color) / 255.0, SALCOLOR_BLUE(color) / 255.0, 1.0);
+    msgs_debug(style,"color=%p <--", m_color);
+}
+
+void CoreTextStyleInfo::SetColor(void)
+{
+    msgs_debug(style, "null -->");
+    SafeCFRelease(m_color);
+    msgs_debug(style,"color=%p <--", m_color);
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/aqua/source/gdi/coretext/salgdi.cxx b/vcl/aqua/source/gdi/coretext/salgdi.cxx
new file mode 100644
index 0000000..62e0903
--- /dev/null
+++ b/vcl/aqua/source/gdi/coretext/salgdi.cxx
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include "aqua/common.h"
+
+#include "aqua/salframe.h"
+
+#include "aqua/coretext/salgdi.h"
+#include "aqua/coretext/salcoretextstyle.hxx"
+#include "aqua/coretext/salcoretextlayout.hxx"
+
+AquaSalGraphics::AquaSalGraphics()
+    : mpFrame( NULL )
+    , mxLayer( NULL )
+    , mrContext( NULL )
+    , mpXorEmulation( NULL )
+    , mnXorMode( 0 )
+    , mnWidth( 0 )
+    , mnHeight( 0 )
+    , mnBitmapDepth( 0 )
+    , mnRealDPIX( 0 )
+    , mnRealDPIY( 0 )
+    , mfFakeDPIScale( 1.0 )
+    , mxClipPath( NULL )
+    , maLineColor( COL_WHITE )
+    , maFillColor( COL_BLACK )
+    , m_pCoreTextFontData( NULL )
+    , mbNonAntialiasedText( false )
+    , mbPrinter( false )
+    , mbVirDev( false )
+    , mbWindow( false )
+{
+    msgs_debug(gr,"-->");
+    m_style = new CoreTextStyleInfo();
+    msgs_debug(gr,"m_style=%p <--", m_style);
+}
+
+AquaSalGraphics::~AquaSalGraphics()
+{
+    msgs_debug(gr,"-->");
+    if(m_style)
+    {
+        delete m_style;
+        m_style = NULL;
+    }
+    msgs_debug(gr,"<--");
+}
+
+inline bool AquaSalGraphics::AddTempDevFont( ImplDevFontList*,
+                                             const rtl::OUString& ,
+                                             const rtl::OUString& )
+{
+    OSL_ASSERT( FALSE );
+    return false;
+}
+
+void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+{
+}
+
+void AquaSalGraphics::FreeEmbedFontData( const void* pData, long /*nDataLen*/ )
+{
+    // TODO: implementing this only makes sense when the implementation of
+    //      AquaSalGraphics::GetEmbedFontData() returns non-NULL
+    (void)pData;
+    DBG_ASSERT( (pData!=NULL), "AquaSalGraphics::FreeEmbedFontData() is not implemented\n");
+}
+
+void AquaSalGraphics::GetDevFontList( ImplDevFontList* pFontList )
+{
+    DBG_ASSERT( pFontList, "AquaSalGraphics::GetDevFontList(NULL) !");
+
+    SalData* pSalData = GetSalData();
+    if (pSalData->mpFontList == NULL)
+    {
+        pSalData->mpFontList = new SystemFontList();
+    }
+    // Copy all PhysicalFontFace objects contained in the SystemFontList
+    pSalData->mpFontList->AnnounceFonts( *pFontList );
+}
+
+void AquaSalGraphics::GetDevFontSubstList( OutputDevice* )
+{
+    // nothing to do since there are no device-specific fonts on Aqua
+}
+
+const void* AquaSalGraphics::GetEmbedFontData( const PhysicalFontFace*,
+                              const sal_Ucs* /*pUnicodes*/,
+                              sal_Int32* /*pWidths*/,
+                              FontSubsetInfo&,
+                              long* /*pDataLen*/ )
+{
+    return NULL;
+}
+
+const Ucs2SIntMap* AquaSalGraphics::GetFontEncodingVector(const PhysicalFontFace*,
+                                                          const Ucs2OStrMap** /*ppNonEncoded*/ )
+{
+    return NULL;
+}
+
+void AquaSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel )
+{
+    (void)nFallbackLevel; // glyph-fallback on CoreText is done differently -> no fallback level
+
+    pMetric->mbScalableFont = true;
+    pMetric->mbKernableFont = true;
+    CTFontRef font = m_style->GetFont();
+    DBG_ASSERT(font, "GetFontMetric without font set in style");
+
+    pMetric->mnAscent = static_cast<long>( CTFontGetAscent(font) * mfFakeDPIScale + 0.5);
+    pMetric->mnDescent = static_cast<long>(CTFontGetDescent(font) * mfFakeDPIScale + 0.5);
+    const long nExtDescent  = static_cast<long>((CTFontGetLeading(font) + CTFontGetDescent(font)) *
+                                                mfFakeDPIScale + 0.5);
+    pMetric->mnExtLeading   = nExtDescent + pMetric->mnDescent;
+    pMetric->mnIntLeading   = 0;
+    pMetric->mnWidth = m_style->GetFontStretchedSize();
+    msgs_debug(gr,"ascent=%ld, descent=%ld, extleading=%ld, intleading=%ld,w=%ld",
+               pMetric->mnAscent, pMetric->mnDescent,
+               pMetric->mnExtLeading,
+               pMetric->mnIntLeading,
+               pMetric->mnWidth);
+}
+
+sal_Bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId /*nGlyphId*/, Rectangle& /*rRect*/ )
+{
+    /* TODO: create a Ghyph iterator to keep track ot 'state' between call */
+    return false;
+}
+
+sal_Bool AquaSalGraphics::GetGlyphOutline( sal_GlyphId /*nGlyphId*/, basegfx::B2DPolyPolygon& /*rPolyPoly*/ )
+{
+    /* TODO */
+    return false;
+}
+
+void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* /*pFontData*/, bool /*bVertical*/,
+                                      Int32Vector& /*rGlyphWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/ )
+{
+}
+
+sal_uLong AquaSalGraphics::GetKernPairs( sal_uLong, ImplKernPairData* )
+{
+    return 0;
+}
+
+bool AquaSalGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
+{
+    if( !m_pCoreTextFontData )
+    {
+        return false;
+    }
+    return m_pCoreTextFontData->GetImplFontCapabilities(rFontCapabilities);
+}
+
+const ImplFontCharMap* AquaSalGraphics::GetImplFontCharMap() const
+{
+    if( !m_pCoreTextFontData )
+    {
+        return ImplFontCharMap::GetDefaultMap();
+    }
+    return m_pCoreTextFontData->GetImplFontCharMap();
+}
+
+bool AquaSalGraphics::GetRawFontData( const PhysicalFontFace* pFontData,
+                     std::vector<unsigned char>& rBuffer, bool* pJustCFF )
+{
+    const ImplCoreTextFontData* font_data = static_cast<const ImplCoreTextFontData*>(pFontData);
+
+    return font_data->GetRawFontData(rBuffer, pJustCFF);
+}
+
+SystemFontData AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
+{
+    msgs_debug(gr,"-->");
+    SystemFontData aSysFontData;
+    aSysFontData.nSize = sizeof( SystemFontData );
+    aSysFontData.bAntialias = true;
+
+    CTFontRef font = CTFontCreateUIFontForLanguage(kCTFontSystemFontType, 0.0, NULL);
+    font = (CTFontRef)CFRetain(font);
+    aSysFontData.rCTFont = (void*)font;
+
+    CTFontRef italic_font = CTFontCreateCopyWithSymbolicTraits( font,
+                                                                0.0,
+                                                                NULL,
+                                                                kCTFontItalicTrait,
+                                                                kCTFontItalicTrait + kCTFontBoldTrait);
+    aSysFontData.bFakeItalic = italic_font ? false : true;
+    SafeCFRelease(italic_font);
+
+    CTFontRef bold_font = CTFontCreateCopyWithSymbolicTraits( font,
+                                                              0.0,
+                                                              NULL,
+                                                              kCTFontBoldTrait,
+                                                              kCTFontItalicTrait + kCTFontBoldTrait);
+    aSysFontData.bFakeBold = bold_font ? false : true;
+    SafeCFRelease(bold_font);
+
+    CTFontRef vertical_font = CTFontCreateCopyWithSymbolicTraits( font,
+                                                                  0.0,
+                                                                  NULL,
+                                                                  kCTFontVerticalTrait,
+                                                                  kCTFontVerticalTrait);
+    aSysFontData.bVerticalCharacterType = vertical_font ? true : false;
+    SafeCFRelease(vertical_font);
+
+    msgs_debug(gr,"<--");
+    return aSysFontData;
+}
+
+SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs&, int /*nFallbackLevel*/ )
+{
+    msgs_debug(gr,"-->");
+    CoreTextLayout* layout = new CoreTextLayout( this, m_style );
+    msgs_debug(gr,"layout:%p <--", layout);
+    return layout;
+}
+
+sal_uInt16 AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ )
+{
+    msgs_debug(gr,"m_style=%p -->", m_style);
+    m_style->SetFont(pReqFont);
+    msgs_debug(gr,"<--");
+    return 0;
+}
+
+void AquaSalGraphics::SetTextColor( SalColor nSalColor )
+{
+    msgs_debug(gr,"m_style=%p -->", m_style);
+    m_style->SetColor(nSalColor);
+    msgs_debug(gr,"<--");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/aqua/source/gdi/salgdicommon.cxx b/vcl/aqua/source/gdi/salgdicommon.cxx
index 0a84429..72f97ed 100644
--- a/vcl/aqua/source/gdi/salgdicommon.cxx
+++ b/vcl/aqua/source/gdi/salgdicommon.cxx
@@ -117,7 +117,7 @@ static void AddPolyPolygonToPath( CGMutablePathRef xPath,
 }
 
 sal_Bool AquaSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
-                                            const ImplFontData* pFontData,
+                                            const PhysicalFontFace* pFontData,
                                             long* pGlyphIDs, sal_uInt8* pEncoding,
                                             sal_Int32* pGlyphWidths, int nGlyphCount,
                                             FontSubsetInfo& rInfo )
diff --git a/vcl/aqua/source/gdi/salgdiutils.cxx b/vcl/aqua/source/gdi/salgdiutils.cxx
index 7032fcd..a2cc9a0 100644
--- a/vcl/aqua/source/gdi/salgdiutils.cxx
+++ b/vcl/aqua/source/gdi/salgdiutils.cxx
@@ -234,6 +234,14 @@ bool AquaSalGraphics::CheckContext()
     return (mrContext != NULL);
 }
 
+CGContextRef AquaSalGraphics::GetContext()
+{
+    if(!mrContext)
+    {
+        CheckContext();
+    }
+    return mrContext;
+}
 
 void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
 {
diff --git a/vcl/inc/aqua/atsui/salgdi.h b/vcl/inc/aqua/atsui/salgdi.h
index 0ee4420..5827706 100644
--- a/vcl/inc/aqua/atsui/salgdi.h
+++ b/vcl/inc/aqua/atsui/salgdi.h
@@ -161,6 +161,7 @@ public:
     void                ImplDrawPixel( long nX, long nY, const RGBAColor& ); // helper to draw single pixels
 
     bool                CheckContext();
+    CGContextRef        GetContext();
     void                UpdateWindow( NSRect& ); // delivered in NSView coordinates
     void                RefreshRect( const CGRect& );
     void                RefreshRect( const NSRect& );
@@ -347,7 +348,7 @@ private:
     void Pattern50Fill();
     UInt32 getState( ControlState nState );
     UInt32 getTrackState( ControlState nState );
-    bool GetRawFontData( const ImplFontData* pFontData,
+    bool GetRawFontData( const PhysicalFontFace* pFontData,
                          std::vector<unsigned char>& rBuffer,
                          bool* pJustCFF );
 };
diff --git a/vcl/inc/aqua/common.h b/vcl/inc/aqua/common.h
index d7a6541..c3789a5 100644
--- a/vcl/inc/aqua/common.h
+++ b/vcl/inc/aqua/common.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 
 #ifndef _VCL_AQUA_COMMON_H
 #define _VCL_AQUA_COMMON_H
@@ -6,11 +7,25 @@
 #include <premac.h>
 #include <ApplicationServices/ApplicationServices.h>
 #include <postmac.h>
+#include <tools/debug.hxx>
 
 // CoreFoundation designers, in their wisdom, decided that CFRelease of NULL
 // cause a Crash, yet few API can return NULL when asking for the creation
 // of an object, which force us to peper the code with egly if construct everywhere
 // and open the door to very nasty crash on rare occasion
 // this macro hide the mess
-#define SafeCFRelease(a) do { if(a) { CFRelease(a); } } while(false)
-#endif
+#define SafeCFRelease(a) do { if(a) { CFRelease(a); (a)=NULL; } } while(false)
+
+
+#define round_to_long(a) ((a) >= 0 ? ((long)((a) + 0.5)) : ((long)((a) - 0.5)))
+
+#include "vcl/salgtype.hxx"
+#endif/* _VCL_AQUA_COMMON_H */
+
+//#define msgs_debug(c,f,...)
+//    fprintf(stderr, "%s::%s(%p:%04.4x)\n", this, #c, __func__, 0, __VA_ARGS__ )
+
+#define msgs_debug(c,f,...)                                             \
+    fprintf(stderr, "%s::%s(%p:%4.4u)" f "\n", #c, __func__, this, ((unsigned int)pthread_self() & 8191), ##__VA_ARGS__ );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/aqua/coretext/salcoretextfontutils.hxx b/vcl/inc/aqua/coretext/salcoretextfontutils.hxx
new file mode 100644
index 0000000..3c75899
--- /dev/null
+++ b/vcl/inc/aqua/coretext/salcoretextfontutils.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef _VCL_AQUA_CORETEXT_SALCORETEXTFONTUTILS_HXX
+#define _VCL_AQUA_CORETEXT_SALCORETEXTFONTUTILS_HXX
+
+class ImplCoreTextFontData;
+class ImplDevFontList;
+
+#include <boost/unordered_map.hpp>
+
+#include <vcl/fontcapabilities.hxx>
+
+#include "outfont.hxx"
+#include "impfont.hxx"
+
+class ImplCoreTextFontData : public PhysicalFontFace
+{
+public:
+    ImplCoreTextFontData(const ImplDevFontAttributes&, CTFontRef font);
+    virtual ~ImplCoreTextFontData();
+    virtual PhysicalFontFace* Clone() const;
+    virtual ImplFontEntry* CreateFontInstance( FontSelectPattern& ) const;
+    virtual sal_IntPtr GetFontId() const { return (sal_IntPtr)m_CTFontRef;};
+    CTFontRef GetCTFont() const { return m_CTFontRef; };
+    const ImplFontCharMap* GetImplFontCharMap();
+    bool GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities);
+    bool HasChar( sal_uInt32 cChar ) const;
+    void ReadOs2Table();
+    void ReadIosCmapEncoding();
+    bool HasCJKSupport();
+    bool GetRawFontData( std::vector<unsigned char>& rBuffer, bool* pJustCFF ) const;
+
+private:
+    void DetermineCJKSupport_OS2(CFDataRef rOS2Table);
+    void DetermineCJKSupport_cmap(CFDataRef rCmapTable);
+    CTFontRef m_CTFontRef;
+    mutable const ImplFontCharMap* m_pCharMap;
+    mutable vcl::FontCapabilities m_aFontCapabilities;
+    mutable bool m_bHasOs2Table;
+    mutable bool m_bOs2TableRead;
+    mutable bool m_bCmapTableRead; // true if cmap encoding of Mac font is read
+    mutable bool m_bHasCJKSupport; // #i78970# CJK fonts need extra leading
+    mutable bool m_bFontCapabilitiesRead;
+};
+
+/* This class has the responsibility of assembling a list of CoreText
+   fonts available on the system and enabling access to that list.
+ */
+class SystemFontList
+{
+public:
+    SystemFontList();
+    ~SystemFontList();
+
+    void AnnounceFonts( ImplDevFontList& ) const;
+    ImplCoreTextFontData* GetFontDataFromRef( CTFontRef ) const;
+
+private:
+    typedef boost::unordered_map<CTFontRef,ImplCoreTextFontData*> CoreTextFontContainer;
+    CoreTextFontContainer m_aFontContainer;
+
+    void InitGlyphFallbacks();
+};
+
+#endif  // _VCL_AQUA_CORETEXT_SALCORETEXTFONTUTILS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/aqua/coretext/salcoretextlayout.hxx b/vcl/inc/aqua/coretext/salcoretextlayout.hxx
new file mode 100644
index 0000000..e427522
--- /dev/null
+++ b/vcl/inc/aqua/coretext/salcoretextlayout.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef _VCL_AQUA_CORETEXT_SALCORETEXTLAYOUT_HXX
+#define _VCL_AQUA_CORETEXT_SALCORETEXTLAYOUT_HXX
+
+#include <tools/poly.hxx>
+
+#include "sallayout.hxx"
+
+class AquaSalGraphics;
+class CoreTextStyleInfo;
+
+class CoreTextLayout : public SalLayout
+{
+public:
+    CoreTextLayout( AquaSalGraphics* graphics, CoreTextStyleInfo* style);
+    virtual         ~CoreTextLayout();
+
+    virtual void AdjustLayout( ImplLayoutArgs& );
+    virtual void DrawText( SalGraphics& ) const;
+    virtual void DropGlyph( int nStart );
+    virtual long FillDXArray( long* pDXArray ) const;
+    virtual bool GetBoundRect( SalGraphics&, Rectangle& ) const;
+    virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const;
+    virtual bool GetGlyphOutlines( SalGraphics&, PolyPolyVector& ) const;
+    virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
+                               sal_Int32* pGlyphAdvances, int* pCharIndexes ) const;
+    virtual int GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const;
+    virtual long GetTextWidth() const;
+    virtual void InitFont() const;
+    virtual bool LayoutText( ImplLayoutArgs& );
+    virtual void MoveGlyph( int nStart, long nNewXPos );
+    virtual void Simplify( bool bIsBase );
+
+private:
+    void Clean();
+    bool InitGIA() const;
+
+    AquaSalGraphics* m_graphics;
+    CoreTextStyleInfo* m_style;
+    mutable int m_glyphs_count;
+    mutable int m_chars_count;
+    mutable int* m_chars2glyphs;
+    mutable int* m_glyphs2chars;
+    mutable CGGlyph* m_glyphs;
+    mutable int* m_char_widths;
+    mutable int* m_glyph_advances;
+    mutable CGPoint* m_glyph_positions;
+    CTTypesetterRef m_typesetter;
+    CTLineRef m_line;
+    mutable bool m_has_bound_rec;
+    mutable Rectangle m_bound_rect;
+    CGFloat m_base_advance;
+    mutable CGFloat m_cached_width;
+    mutable CFIndex m_current_run_index;
+    mutable CFIndex m_current_glyph_index;
+    mutable CFIndex m_current_glyphrun_index;
+    mutable CFArrayRef m_runs;
+
+};
+
+#endif // _VCL_AQUA_CORETEXT_SALCORETEXTLAYOUT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/aqua/coretext/salcoretextstyle.hxx b/vcl/inc/aqua/coretext/salcoretextstyle.hxx
new file mode 100644
index 0000000..91bde52
--- /dev/null
+++ b/vcl/inc/aqua/coretext/salcoretextstyle.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef _VCL_AQUA_CORETEXT_SALCORETEXTSTYLE_HXX
+#define _VCL_AQUA_CORETEXT_SALCORETEXTSTYLE_HXX
+
+#include "aqua/salgdicommon.hxx"
+
+class FontSelectPattern;
+class ImplCoreTextFontData;
+
+class CoreTextStyleInfo
+{
+public:
+    CoreTextStyleInfo();
+    ~CoreTextStyleInfo();
+    CTFontRef GetFont() const { return m_CTFont; };
+    long GetFontStretchedSize() const;
+    float GetFontStretchFactor() const { return m_stretch_factor; };
+    CTParagraphStyleRef GetParagraphStyle() const { return m_CTParagraphStyle; } ;
+    CGSize    GetSize() const;
+    CGColorRef GetColor() const { return m_color; } ;
+    void SetColor(SalColor color);
+    void SetColor(void);
+    void SetFont(FontSelectPattern* requested_font);
+
+private:
+    bool m_fake_bold;
+    bool m_fake_italic;
+    CGAffineTransform m_matrix;
+    float m_stretch_factor;
+    float m_font_scale;
+    float m_fake_dpi_scale;
+    CTParagraphStyleRef m_CTParagraphStyle;
+    CTFontRef m_CTFont;
+    CGColorRef m_color;
+    const ImplCoreTextFontData* m_font_data;
+
+};
+
+#endif // _VCL_AQUA_CORETEXT_SALCORETEXTSTYLE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/aqua/coretext/salgdi.h b/vcl/inc/aqua/coretext/salgdi.h
new file mode 100644
index 0000000..7f59de2
--- /dev/null
+++ b/vcl/inc/aqua/coretext/salgdi.h
@@ -0,0 +1,297 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef _VCL_AQUA_CORETEXT_SALGDI_H
+#define _VCL_AQUA_CORETEXT_SALGDI_H
+
+
+#include "premac.h"
+#include <ApplicationServices/ApplicationServices.h>
+#include "postmac.h"
+
+#include "aqua/aquavcltypes.h"
+#include "aqua/coretext/salcoretextfontutils.hxx"
+#include "aqua/salframe.h"
+#include "salgdi.hxx"
+
+#include "aqua/salgdicommon.hxx"
+
+class CoreTextStyleInfo;
+
+// -------------------
+// - AquaSalGraphics -
+// -------------------
+class AquaSalGraphics : public SalGraphics
+{
+    friend class CoreTextLayout;
+protected:
+    AquaSalFrame* mpFrame;
+    CGLayerRef mxLayer;    //< Quartz graphics layer
+    CGContextRef mrContext;  //< Quartz drawing context
+    class XorEmulation* mpXorEmulation;
+    int mnXorMode; //< 0: off 1: on 2: invert only
+    int mnWidth;
+    int mnHeight;
+    int mnBitmapDepth;  //< zero unless bitmap
+    long mnRealDPIX; //< device X-resolution of this graphics
+    long mnRealDPIY; //< device Y-resolution of this graphics
+
+    /// some graphics implementations (e.g. AquaSalInfoPrinter) scale
+    /// everything down by a factor (see SetupPrinterGraphics for details)
+    /// so we have to compensate for it with the inverse factor
+    double mfFakeDPIScale;
+    double mfFontScale;
+
+
+    CGMutablePathRef mxClipPath; //< path representing current clip region
+
+    /// Drawing colors
+    RGBAColor maLineColor; //< pen color RGBA
+    RGBAColor maFillColor; //< brush color RGBA
+
+    ImplCoreTextFontData* m_pCoreTextFontData; //< Device Font settings
+
+    bool mbNonAntialiasedText; //< allows text to be rendered without antialiasing
+
+    // Graphics types
+
+    bool mbPrinter; //< is this a printer graphics
+    bool mbVirDev; //< is this a virtual device graphics
+    bool mbWindow; //< is this a window graphics
+
+    RGBColor m_TextColor;
+
+    CoreTextStyleInfo* m_style;
+
+public:
+    AquaSalGraphics();
+    virtual ~AquaSalGraphics();
+
+    bool IsPenVisible() const { return maLineColor.IsVisible(); }
+    bool IsBrushVisible() const { return maFillColor.IsVisible(); }
+
+    void SetWindowGraphics( AquaSalFrame* pFrame );
+    void SetPrinterGraphics( CGContextRef, long nRealDPIX, long nRealDPIY, double fFakeScale );
+    void SetVirDevGraphics( CGLayerRef, CGContextRef, int nBitDepth = 0 );
+
+    void initResolution( NSWindow* );
+    void copyResolution( AquaSalGraphics& );
+    void updateResolution();
+
+    bool IsWindowGraphics() const { return mbWindow; }
+    bool IsPrinterGraphics() const { return mbPrinter; }
+    bool IsVirDevGraphics() const { return mbVirDev; }
+    AquaSalFrame* getGraphicsFrame() const { return mpFrame; }
+    void setGraphicsFrame( AquaSalFrame* pFrame ) { mpFrame = pFrame; }
+
+    void ImplDrawPixel( long nX, long nY, const RGBAColor& ); // helper to draw single pixels
+
+    bool CheckContext();
+    CGContextRef GetContext();
+    void UpdateWindow( NSRect& ); // delivered in NSView coordinates
+    void RefreshRect( const CGRect& );
+    void RefreshRect( const NSRect& );
+    void RefreshRect(float lX, float lY, float lWidth, float lHeight);
+
+    void SetState();
+    void UnsetState();
+    // InvalidateContext does an UnsetState and sets mrContext to 0
+    void InvalidateContext();
+
+    virtual bool setClipRegion( const Region& );
+
+    // draw --> LineColor and FillColor and RasterOp and ClipRegion
+    virtual void drawPixel( long nX, long nY );
+    virtual void drawPixel( long nX, long nY, SalColor nSalColor );
+    virtual void drawLine( long nX1, long nY1, long nX2, long nY2 );
+    virtual void drawRect( long nX, long nY, long nWidth, long nHeight );
+    virtual void drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry );
+    virtual void drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry );
+    virtual void drawPolyPolygon( sal_uLong nPoly, const sal_uLong* pPoints, PCONSTSALPOINT* pPtAry );
+    virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency );
+    virtual sal_Bool drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
+    virtual sal_Bool drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry );
+    virtual sal_Bool drawPolyPolygonBezier( sal_uLong nPoly, const sal_uLong* pPoints,
+                                            const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry );
+    virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency,
+                               const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin );
+
+    // CopyArea --> No RasterOp, but ClipRegion
+    virtual void copyArea( long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth,
+                           long nSrcHeight, sal_uInt16 nFlags );
+
+    // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+    // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+    virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics );
+    virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap );
+    virtual void drawBitmap( const SalTwoRect* pPosAry,
+                             const SalBitmap& rSalBitmap,
+                             SalColor nTransparentColor );
+    virtual void drawBitmap( const SalTwoRect* pPosAry,
+                             const SalBitmap& rSalBitmap,
+                             const SalBitmap& rTransparentBitmap );
+    virtual void drawMask( const SalTwoRect* pPosAry,
+                           const SalBitmap& rSalBitmap,
+                           SalColor nMaskColor );
+
+    virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight );
+    virtual SalColor getPixel( long nX, long nY );
+
+    // invert --> ClipRegion (only Windows or VirDevs)
+    virtual void invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags);
+    virtual void invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nFlags );
+
+    virtual sal_Bool drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize );
+
+    virtual bool drawAlphaBitmap( const SalTwoRect&,
+                                  const SalBitmap& rSourceBitmap,
+                                  const SalBitmap& rAlphaBitmap );
+
+    virtual bool drawAlphaRect( long nX, long nY, long nWidth,
+                                long nHeight, sal_uInt8 nTransparency );
+
+    CGPoint* makeCGptArray(sal_uLong nPoints, const SalPoint*  pPtAry);
+    // native widget rendering methods that require mirroring
+    virtual sal_Bool hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
+                                           const Point& aPos, sal_Bool& rIsInside );
+    virtual sal_Bool drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
+                                        ControlState nState, const ImplControlValue& aValue,
+                                        const rtl::OUString& aCaption );
+    virtual sal_Bool getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
+                                             ControlState nState, const ImplControlValue& aValue,
+                                             const rtl::OUString& aCaption,
+                                             Rectangle &rNativeBoundingRegion,
+                                             Rectangle &rNativeContentRegion );
+
+    // get device resolution
+    virtual void GetResolution( long& rDPIX, long& rDPIY );
+    // get the depth of the device
+    virtual sal_uInt16 GetBitCount() const;
+    // get the width of the device
+    virtual long GetGraphicsWidth() const;
+
+    // set the clip region to empty
+    virtual void ResetClipRegion();
+
+    // set the line color to transparent (= don't draw lines)
+    virtual void SetLineColor();
+    // set the line color to a specific color
+    virtual void SetLineColor( SalColor nSalColor );
+    // set the fill color to transparent (= don't fill)
+    virtual void SetFillColor();
+    // set the fill color to a specific color, shapes will be
+    // filled accordingly
+    virtual void SetFillColor( SalColor nSalColor );
+    // enable/disable XOR drawing
+    virtual void SetXORMode( bool bSet, bool bInvertOnly );
+    // set line color for raster operations
+    virtual void SetROPLineColor( SalROPColor nROPColor );
+    // set fill color for raster operations
+    virtual void SetROPFillColor( SalROPColor nROPColor );
+    // set the text color to a specific color
+    virtual void SetTextColor( SalColor nSalColor );
+    // set the font
+    virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel );
+    // get the current font's etrics
+    virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel );
+    // get kernign pairs of the current font
+    // return only PairCount if (pKernPairs == NULL)
+    virtual sal_uLong GetKernPairs( sal_uLong nPairs, ImplKernPairData* pKernPairs );
+    // get the repertoire of the current font
+    virtual const ImplFontCharMap* GetImplFontCharMap() const;
+    virtual bool GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
+    // graphics must fill supplied font list
+    virtual void GetDevFontList( ImplDevFontList* );
+    // graphics should call ImplAddDevFontSubstitute on supplied
+    // OutputDevice for all its device specific preferred font substitutions
+    virtual void GetDevFontSubstList( OutputDevice* );
+    virtual bool AddTempDevFont( ImplDevFontList*, const rtl::OUString& rFileURL,
+                                 const rtl::OUString& rFontName );
+    // CreateFontSubset: a method to get a subset of glyhps of a font
+    // inside a new valid font file
+    // returns TRUE if creation of subset was successfull
+    // parameters: rToFile: contains a osl file URL to write the subset to
+    //             pFont: describes from which font to create a subset
+    //             pGlyphIDs: the glyph ids to be extracted
+    //             pEncoding: the character code corresponding to each glyph
+    //             pWidths: the advance widths of the correspoding glyphs (in PS font units)
+    //             nGlyphs: the number of glyphs
+    //             rInfo: additional outgoing information
+    // implementation note: encoding 0 with glyph id 0 should be added implicitly
+    // as "undefined character"
+    virtual sal_Bool CreateFontSubset( const rtl::OUString& rToFile,
+                                       const PhysicalFontFace* pFont,
+                                       long* pGlyphIDs,
+                                       sal_uInt8* pEncoding,
+                                       sal_Int32* pWidths,
+                                       int nGlyphs,
+                                       FontSubsetInfo& rInfo);
+
+    // GetFontEncodingVector: a method to get the encoding map Unicode
+    // to font encoded character; this is only used for type1 fonts and
+    // may return NULL in case of unknown encoding vector
+    // if ppNonEncoded is set and non encoded characters (that is type1
+    // glyphs with only a name) exist it is set to the corresponding
+    // map for non encoded glyphs; the encoding vector contains -1
+    // as encoding for these cases
+    virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded );
+
+    // GetEmbedFontData: gets the font data for a font marked
+    // embeddable by GetDevFontList or NULL in case of error
+    // parameters: pFont: describes the font in question
+    //             pWidths: the widths of all glyphs from char code 0 to 255
+    //                      pWidths MUST support at least 256 members;
+    //             rInfo: additional outgoing information
+    //             pDataLen: out parameter, contains the byte length of the returned buffer
+    virtual const void* GetEmbedFontData( const PhysicalFontFace*,
+                                          const sal_Ucs* pUnicodes,
+                                          sal_Int32* pWidths,
+                                          FontSubsetInfo& rInfo,
+                                          long* pDataLen );
+    // frees the font data again
+    virtual void FreeEmbedFontData( const void* pData, long nDataLen );
+
+    virtual void GetGlyphWidths( const PhysicalFontFace*,
+                                 bool bVertical,
+                                 Int32Vector& rWidths,
+                                 Ucs2UIntMap& rUnicodeEnc );
+
+    virtual sal_Bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& );
+    virtual sal_Bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& );
+
+    virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel );
+    virtual void DrawServerFontLayout( const ServerFontLayout& );
+    virtual bool supportsOperation( OutDevSupportType ) const;
+
+    // Query the platform layer for control support
+    virtual sal_Bool IsNativeControlSupported( ControlType nType, ControlPart nPart );
+
+    virtual SystemGraphicsData GetGraphicsData() const;
+    virtual SystemFontData GetSysFontData( int /* nFallbacklevel */ ) const;
+
+private:
+    // differences between VCL, Quartz and kHiThemeOrientation coordinate systems
+    // make some graphics seem to be vertically-mirrored from a VCL perspective
+    bool IsFlipped() const { return mbWindow; };
+
+    void ApplyXorContext();
+    void Pattern50Fill();
+    UInt32 getState( ControlState nState );
+    UInt32 getTrackState( ControlState nState );
+    bool GetRawFontData( const PhysicalFontFace* pFontData,
+                         std::vector<unsigned char>& rBuffer,
+                         bool* pJustCFF );
+};
+
+inline void AquaSalGraphics::RefreshRect( const CGRect& rRect )
+{
+    RefreshRect( rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height );
+}
+
+inline void AquaSalGraphics::RefreshRect( const NSRect& rRect )
+{
+    RefreshRect( rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height );
+}
+
+#endif /*  _VCL_AQUA_CORETEXT_SALGDI_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/vcl/sysdata.hxx b/vcl/inc/vcl/sysdata.hxx
index d52cd94..1033239 100644
--- a/vcl/inc/vcl/sysdata.hxx
+++ b/vcl/inc/vcl/sysdata.hxx
@@ -194,7 +194,6 @@ struct SystemGlyphData
 // --------------------
 // - SystemFontData -
 // --------------------
-
 struct SystemFontData
 {
     unsigned long   nSize;          // size in bytes of this structure
@@ -202,7 +201,7 @@ struct SystemFontData
     HFONT           hFont;          // native font object
 #elif defined( QUARTZ )
 #ifdef ENABLE_CORETEXT
-    CTFontRef       rCTFont;
+    void*           rCTFont;
 #else
     void*           aATSUFontID;    // native font object
 #endif
commit 2c506447fcf020b17797c30d001fda9c177a4235
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Apr 2 00:11:29 2012 -0500

    WaE on Mac SDK > 10.4
    
    Change-Id: Ie0e413a6beef87d399807f98f345103c82442a9c

diff --git a/slideshow/source/engine/OGLTrans/mac/aquaOpenGLView.m b/slideshow/source/engine/OGLTrans/mac/aquaOpenGLView.m
index 64af815..7d23b17 100644
--- a/slideshow/source/engine/OGLTrans/mac/aquaOpenGLView.m
+++ b/slideshow/source/engine/OGLTrans/mac/aquaOpenGLView.m
@@ -81,12 +81,13 @@ typedef int NSColorRenderingIntent;
 - (void)prepareOpenGL
 {
     // for overriding to initialize OpenGL state, occurs after context creation
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
-    GLint swapInt = 1;
-#else
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
     long swapInt = 1;
+#else
+    NSInteger swapInt = 1;
 #endif
 
+
     [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
 
     // init GL stuff here
diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm
index 86e3dc4..02afa6c 100644
--- a/vcl/aqua/source/window/salframeview.mm
+++ b/vcl/aqua/source/window/salframeview.mm
@@ -1595,11 +1595,10 @@ private:
     return 0;
 }
 
-#if defined (NSFoundationVersionNumber10_5)
-/* SDK 10.5 or greater, even if MAC_OS_X_VERSION_MAX_ALLOWED might be less than 10.5 */
-- (NSInteger)conversationIdentifier
-#else
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
 - (long)conversationIdentifier
+#else
+- (NSInteger)conversationIdentifier
 #endif
 {
     return (long)self;
commit a95dbe7ad0bc8cf780bb9142bd9ffca3b0417d18
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Mon Apr 2 00:10:17 2012 -0500

    Add a configure flag to enable CoreText Support
    
    Change-Id: I0f3865beff53f199fae49e806f308c6dab3e3c11

diff --git a/config_host.mk.in b/config_host.mk.in
index 7a7e161..8aac2ea 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -110,6 +110,7 @@ export ENABLE_EVOAB2=@ENABLE_EVOAB2@
 export ENABLE_GCONF=@ENABLE_GCONF@
 export ENABLE_GIO=@ENABLE_GIO@
 export ENABLE_GNOMEVFS=@ENABLE_GNOMEVFS@
+export ENABLE_CORETEXT?=@ENABLE_CORETEXT@
 export ENABLE_GRAPHITE=@ENABLE_GRAPHITE@
 export ENABLE_GSTREAMER=@ENABLE_GSTREAMER@
 export ENABLE_GTK3=@ENABLE_GTK3@
@@ -167,7 +168,7 @@ export GIT_REPO_NAMES=@GIT_REPO_NAMES@
 export GLIB_CFLAGS=@GLIB_CFLAGS@
 export GLIB_LIBS=@GLIB_LIBS@
 export GMAKE_MODULE_PARALLELISM=@GMAKE_MODULE_PARALLELISM@
-export GMAKE_PARALLELISM=@GMAKE_PARALLELISM@
+export GMAKE_PARALLELISM?=@GMAKE_PARALLELISM@
 export GNOMEVFS_CFLAGS=@GNOMEVFS_CFLAGS@
 export GNOMEVFS_LIBS=@GNOMEVFS_LIBS@
 @x_GNUCP@ export GNUCOPY=@GNUCP@
diff --git a/configure.in b/configure.in
index d8ab8ab..b1f049d 100644
--- a/configure.in
+++ b/configure.in
@@ -975,6 +975,11 @@ AC_ARG_ENABLE(postgresql-sdbc,
         [Disable the build of the PostgreSQL-SDBC driver.])
 )
 
+AC_ARG_ENABLE(coretext,
+    AS_HELP_STRING([--enable-coretext],
+        [Use CoreText framework on Mac (instead of ATSU).]),
+)
+
 dnl ===================================================================
 dnl Optional Packages (--with/without-)
 dnl ===================================================================
@@ -10093,6 +10098,21 @@ else
 fi
 AC_SUBST(WITH_HELPPACK_INTEGRATION)
 
+dnl ===================================================================
+dnl Test whether to use CoreText framework
+dnl ===================================================================
+ENABLE_CORETEXT=NO
+if test "$_os" = "Darwin"; then
+    AC_MSG_CHECKING([whether to use CoreText framework])
+    if test "$enable_coretext" = "yes"; then
+        AC_MSG_RESULT([yes])
+        ENABLE_CORETEXT=YES
+    else
+        AC_MSG_RESULT([no])
+    fi
+fi
+AC_SUBST(ENABLE_CORETEXT)
+
 ###############################################################################
 # Extensions checking
 ###############################################################################
commit 9db88e11882c38cd22564c4a76bb0b878de5fe86
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Fri Mar 16 23:58:39 2012 -0500

    factorize what we can share for salgdi between CoreText and ATSUI

diff --git a/vcl/aqua/source/gdi/atsui/salgdi.cxx b/vcl/aqua/source/gdi/atsui/salgdi.cxx
index 7fdd19f..18fe982 100644
--- a/vcl/aqua/source/gdi/atsui/salgdi.cxx
+++ b/vcl/aqua/source/gdi/atsui/salgdi.cxx
@@ -53,7 +53,6 @@
 
 #include "fontsubset.hxx"
 #include "impfont.hxx"
-#include "region.h"
 #include "sallayout.hxx"
 #include "sft.hxx"
 
@@ -372,1200 +371,8 @@ AquaSalGraphics::~AquaSalGraphics()
     }
 }
 
-bool AquaSalGraphics::supportsOperation( OutDevSupportType eType ) const
-{
-    bool bRet = false;
-    switch( eType )
-    {
-    case OutDevSupport_TransparentRect:
-    case OutDevSupport_B2DClip:
-    case OutDevSupport_B2DDraw:
-        bRet = true;
-        break;
-    default: break;
-    }
-    return bRet;
-}
-
 // =======================================================================
 
-void AquaSalGraphics::updateResolution()
-{
-    DBG_ASSERT( mbWindow, "updateResolution on inappropriate graphics" );
-
-    initResolution( (mbWindow && mpFrame) ?  mpFrame->mpWindow : nil );
-}
-
-void AquaSalGraphics::initResolution( NSWindow* )
-{
-    // #i100617# read DPI only once; there is some kind of weird caching going on
-    // if the main screen changes
-    // FIXME: this is really unfortunate and needs to be investigated
-
-    SalData* pSalData = GetSalData();
-    if( pSalData->mnDPIX == 0 || pSalData->mnDPIY == 0 )
-    {
-        NSScreen* pScreen = nil;
-
-        /* #i91301#
-        many woes went into the try to have different resolutions
-        on different screens. The result of these trials is that OOo is not ready
-        for that yet, vcl and applications would need to be adapted.
-
-        Unfortunately this is not possible in the 3.0 timeframe.
-        So let's stay with one resolution for all Windows and VirtualDevices
-        which is the resolution of the main screen
-
-        This of course also means that measurements are exact only on the main screen.
-        For activating different resolutions again just comment out the two lines below.
-
-        if( pWin )
-        pScreen = [pWin screen];
-        */
-        if( pScreen == nil )
-        {
-            NSArray* pScreens = [NSScreen screens];
-            if( pScreens )
-                pScreen = [pScreens objectAtIndex: 0];
-        }
-
-        mnRealDPIX = mnRealDPIY = 96;
-        if( pScreen )
-        {
-            NSDictionary* pDev = [pScreen deviceDescription];
-            if( pDev )
-            {
-                NSNumber* pVal = [pDev objectForKey: @"NSScreenNumber"];
-                if( pVal )
-                {
-                    // FIXME: casting a long to CGDirectDisplayID is evil, but
-                    // Apple suggest to do it this way
-                    const CGDirectDisplayID nDisplayID = (CGDirectDisplayID)[pVal longValue];
-                    const CGSize aSize = CGDisplayScreenSize( nDisplayID ); // => result is in millimeters
-                    mnRealDPIX = static_cast<long>((CGDisplayPixelsWide( nDisplayID ) * 25.4) / aSize.width);
-                    mnRealDPIY = static_cast<long>((CGDisplayPixelsHigh( nDisplayID ) * 25.4) / aSize.height);
-                }
-                else
-                {
-                    OSL_FAIL( "no resolution found in device description" );
-                }
-            }
-            else
-            {
-                OSL_FAIL( "no device description" );
-            }
-        }
-        else
-        {
-            OSL_FAIL( "no screen found" );
-        }
-
-        // #i107076# maintaining size-WYSIWYG-ness causes many problems for
-        //           low-DPI, high-DPI or for mis-reporting devices
-        //           => it is better to limit the calculation result then
-        static const int nMinDPI = 72;
-        if( (mnRealDPIX < nMinDPI) || (mnRealDPIY < nMinDPI) )
-            mnRealDPIX = mnRealDPIY = nMinDPI;
-        static const int nMaxDPI = 200;
-        if( (mnRealDPIX > nMaxDPI) || (mnRealDPIY > nMaxDPI) )
-            mnRealDPIX = mnRealDPIY = nMaxDPI;
-
-        // for OSX any anisotropy reported for the display resolution is best ignored (e.g. TripleHead2Go)
-        mnRealDPIX = mnRealDPIY = (mnRealDPIX + mnRealDPIY + 1) / 2;
-
-        pSalData->mnDPIX = mnRealDPIX;
-        pSalData->mnDPIY = mnRealDPIY;
-    }
-    else
-    {
-        mnRealDPIX = pSalData->mnDPIX;
-        mnRealDPIY = pSalData->mnDPIY;
-    }
-
-    mfFakeDPIScale = 1.0;
-}
-
-void AquaSalGraphics::GetResolution( long& rDPIX, long& rDPIY )
-{
-    if( !mnRealDPIY )
-        initResolution( (mbWindow && mpFrame) ? mpFrame->mpWindow : nil );
-
-    rDPIX = static_cast<long>(mfFakeDPIScale * mnRealDPIX);
-    rDPIY = static_cast<long>(mfFakeDPIScale * mnRealDPIY);
-}
-
-void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
-{
-    if( !rGraphics.mnRealDPIY && rGraphics.mbWindow && rGraphics.mpFrame )
-        rGraphics.initResolution( rGraphics.mpFrame->mpWindow );
-
-    mnRealDPIX = rGraphics.mnRealDPIX;
-    mnRealDPIY = rGraphics.mnRealDPIY;
-    mfFakeDPIScale = rGraphics.mfFakeDPIScale;
-}
-
-// -----------------------------------------------------------------------
-
-sal_uInt16 AquaSalGraphics::GetBitCount() const
-{
-    sal_uInt16 nBits = mnBitmapDepth ? mnBitmapDepth : 32;//24;
-    return nBits;
-}
-
-// -----------------------------------------------------------------------
-
-static const basegfx::B2DPoint aHalfPointOfs ( 0.5, 0.5 );
-
-static void AddPolygonToPath( CGMutablePathRef xPath,
-    const ::basegfx::B2DPolygon& rPolygon, bool bClosePath, bool bPixelSnap, bool bLineDraw )
-{
-    // short circuit if there is nothing to do
-    const int nPointCount = rPolygon.count();
-    if( nPointCount <= 0 )
-        return;
-
-    (void)bPixelSnap; // TODO
-    const CGAffineTransform* pTransform = NULL;
-
-    const bool bHasCurves = rPolygon.areControlPointsUsed();
-    for( int nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++ )
-    {
-        int nClosedIdx = nPointIdx;
-        if( nPointIdx >= nPointCount )
-        {
-            // prepare to close last curve segment if needed
-            if( bClosePath && (nPointIdx == nPointCount) )
-                nClosedIdx = 0;
-            else
-                break;
-        }
-
-        ::basegfx::B2DPoint aPoint = rPolygon.getB2DPoint( nClosedIdx );
-
-        if( bPixelSnap)
-        {
-            // snap device coordinates to full pixels
-            aPoint.setX( basegfx::fround( aPoint.getX() ) );
-            aPoint.setY( basegfx::fround( aPoint.getY() ) );
-        }
-
-        if( bLineDraw )
-            aPoint += aHalfPointOfs;
-
-        if( !nPointIdx ) { // first point => just move there
-            CGPathMoveToPoint( xPath, pTransform, aPoint.getX(), aPoint.getY() );
-            continue;
-        }
-
-        bool bPendingCurve = false;
-        if( bHasCurves )
-        {
-            bPendingCurve = rPolygon.isNextControlPointUsed( nPrevIdx );
-            bPendingCurve |= rPolygon.isPrevControlPointUsed( nClosedIdx );
-        }
-
-        if( !bPendingCurve )    // line segment
-            CGPathAddLineToPoint( xPath, pTransform, aPoint.getX(), aPoint.getY() );
-        else                        // cubic bezier segment
-        {
-            basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint( nPrevIdx );
-            basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint( nClosedIdx );
-            if( bLineDraw )
-            {
-                aCP1 += aHalfPointOfs;
-                aCP2 += aHalfPointOfs;
-            }
-            CGPathAddCurveToPoint( xPath, pTransform, aCP1.getX(), aCP1.getY(),
-                aCP2.getX(), aCP2.getY(), aPoint.getX(), aPoint.getY() );
-        }
-    }
-
-    if( bClosePath )
-        CGPathCloseSubpath( xPath );
-}
-
-static void AddPolyPolygonToPath( CGMutablePathRef xPath,
-    const ::basegfx::B2DPolyPolygon& rPolyPoly, bool bPixelSnap, bool bLineDraw )
-{
-    // short circuit if there is nothing to do
-    const int nPolyCount = rPolyPoly.count();
-    if( nPolyCount <= 0 )
-        return;
-
-    for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
-    {
-        const ::basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx );
-        AddPolygonToPath( xPath, rPolygon, true, bPixelSnap, bLineDraw );
-    }
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::ResetClipRegion()
-{
-    // release old path and indicate no clipping
-    if( mxClipPath )
-    {
-        CGPathRelease( mxClipPath );
-        mxClipPath = NULL;
-    }
-    if( CheckContext() )
-        SetState();
-}
-
-// -----------------------------------------------------------------------
-
-bool AquaSalGraphics::setClipRegion( const Region& i_rClip )
-{
-    // release old clip path
-    if( mxClipPath )
-    {
-        CGPathRelease( mxClipPath );
-        mxClipPath = NULL;
-    }
-    mxClipPath = CGPathCreateMutable();
-
-    // set current path, either as polypolgon or sequence of rectangles
-    if( i_rClip.HasPolyPolygon() )
-    {
-        basegfx::B2DPolyPolygon aClip( const_cast<Region&>(i_rClip).ConvertToB2DPolyPolygon() );
-        AddPolyPolygonToPath( mxClipPath, aClip, !getAntiAliasB2DDraw(), false );
-    }
-    else
-    {
-        long nX, nY, nW, nH;
-        ImplRegionInfo aInfo;
-        bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-        while( bRegionRect )
-        {
-            if( nW && nH )
-            {
-                CGRect aRect = {{nX,nY}, {nW,nH}};
-                CGPathAddRect( mxClipPath, NULL, aRect );
-            }
-            bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
-        }
-    }
-    // set the current path as clip region
-    if( CheckContext() )
-        SetState();
-    return true;
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::SetLineColor()
-{
-    maLineColor.SetAlpha( 0.0 );   // transparent
-    if( CheckContext() )
-        CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::SetLineColor( SalColor nSalColor )
-{
-    maLineColor = RGBAColor( nSalColor );
-    if( CheckContext() )
-        CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::SetFillColor()
-{
-    maFillColor.SetAlpha( 0.0 );   // transparent
-    if( CheckContext() )
-        CGContextSetFillColor( mrContext, maFillColor.AsArray() );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::SetFillColor( SalColor nSalColor )
-{
-    maFillColor = RGBAColor( nSalColor );
-    if( CheckContext() )
-        CGContextSetFillColor( mrContext, maFillColor.AsArray() );
-}
-
-// -----------------------------------------------------------------------
-
-static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
-{
-    SalColor nSalColor;
-    if ( nROPColor == SAL_ROP_0 )
-        nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
-    else
-        nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
-    return nSalColor;
-}
-
-void AquaSalGraphics::SetROPLineColor( SalROPColor nROPColor )
-{
-    if( ! mbPrinter )
-        SetLineColor( ImplGetROPSalColor( nROPColor ) );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::SetROPFillColor( SalROPColor nROPColor )
-{
-    if( ! mbPrinter )
-        SetFillColor( ImplGetROPSalColor( nROPColor ) );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::ImplDrawPixel( long nX, long nY, const RGBAColor& rColor )
-{
-    if( !CheckContext() )
-        return;
-
-    // overwrite the fill color
-    CGContextSetFillColor( mrContext, rColor.AsArray() );
-    // draw 1x1 rect, there is no pixel drawing in Quartz
-    CGRect aDstRect = {{nX,nY,},{1,1}};
-    CGContextFillRect( mrContext, aDstRect );
-    RefreshRect( aDstRect );
-    // reset the fill color
-    CGContextSetFillColor( mrContext, maFillColor.AsArray() );
-}
-
-void AquaSalGraphics::drawPixel( long nX, long nY )
-{
-    // draw pixel with current line color
-    ImplDrawPixel( nX, nY, maLineColor );
-}
-
-void AquaSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
-{
-    const RGBAColor aPixelColor( nSalColor );
-    ImplDrawPixel( nX, nY, aPixelColor );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
-{
-    if( nX1 == nX2 && nY1 == nY2 )
-    {
-        // #i109453# platform independent code expects at least one pixel to be drawn
-        drawPixel( nX1, nY1 );
-        return;
-    }
-
-    if( !CheckContext() )
-        return;
-
-    CGContextBeginPath( mrContext );
-    CGContextMoveToPoint( mrContext, static_cast<float>(nX1)+0.5, static_cast<float>(nY1)+0.5 );
-    CGContextAddLineToPoint( mrContext, static_cast<float>(nX2)+0.5, static_cast<float>(nY2)+0.5 );
-    CGContextDrawPath( mrContext, kCGPathStroke );
-
-    Rectangle aRefreshRect( nX1, nY1, nX2, nY2 );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
-{
-    if( !CheckContext() )
-        return;
-
-     CGRect aRect( CGRectMake(nX, nY, nWidth, nHeight) );
-     if( IsPenVisible() )
-     {
-         aRect.origin.x      += 0.5;
-         aRect.origin.y      += 0.5;
-         aRect.size.width    -= 1;
-         aRect.size.height -= 1;
-     }
-
-     if( IsBrushVisible() )
-         CGContextFillRect( mrContext, aRect );
-
-     if( IsPenVisible() )
-         CGContextStrokeRect( mrContext, aRect );
-
-    RefreshRect( nX, nY, nWidth, nHeight );
-}
-
-// -----------------------------------------------------------------------
-
-static void getBoundRect( sal_uLong nPoints, const SalPoint *pPtAry, long &rX, long& rY, long& rWidth, long& rHeight )
-{
-    long nX1 = pPtAry->mnX;
-    long nX2 = nX1;
-    long nY1 = pPtAry->mnY;
-    long nY2 = nY1;
-    for( sal_uLong n = 1; n < nPoints; n++ )
-    {
-        if( pPtAry[n].mnX < nX1 )
-            nX1 = pPtAry[n].mnX;
-        else if( pPtAry[n].mnX > nX2 )
-            nX2 = pPtAry[n].mnX;
-
-        if( pPtAry[n].mnY < nY1 )
-            nY1 = pPtAry[n].mnY;
-        else if( pPtAry[n].mnY > nY2 )
-            nY2 = pPtAry[n].mnY;
-    }
-    rX = nX1;
-    rY = nY1;
-    rWidth = nX2 - nX1 + 1;
-    rHeight = nY2 - nY1 + 1;
-}
-
-static inline void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_fY )
-{
-    o_fX = static_cast<float>(i_pIn->mnX ) + 0.5;
-    o_fY = static_cast<float>(i_pIn->mnY ) + 0.5;
-}
-
-void AquaSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry )
-{
-    if( nPoints < 1 )
-        return;
-    if( !CheckContext() )
-        return;
-
-    long nX = 0, nY = 0, nWidth = 0, nHeight = 0;
-    getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight );
-
-    float fX, fY;
-
-    CGContextBeginPath( mrContext );
-    alignLinePoint( pPtAry, fX, fY );
-    CGContextMoveToPoint( mrContext, fX, fY );
-    pPtAry++;
-    for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
-    {
-        alignLinePoint( pPtAry, fX, fY );
-        CGContextAddLineToPoint( mrContext, fX, fY );
-    }
-    CGContextDrawPath( mrContext, kCGPathStroke );
-
-    RefreshRect( nX, nY, nWidth, nHeight );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint *pPtAry )
-{
-    if( nPoints <= 1 )
-        return;
-    if( !CheckContext() )
-        return;
-
-    long nX = 0, nY = 0, nWidth = 0, nHeight = 0;
-    getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight );
-
-    CGPathDrawingMode eMode;
-    if( IsBrushVisible() && IsPenVisible() )
-        eMode = kCGPathEOFillStroke;
-    else if( IsPenVisible() )
-        eMode = kCGPathStroke;
-    else if( IsBrushVisible() )
-        eMode = kCGPathEOFill;
-    else
-        return;
-
-    CGContextBeginPath( mrContext );
-
-    if( IsPenVisible() )
-    {
-        float fX, fY;
-        alignLinePoint( pPtAry, fX, fY );
-        CGContextMoveToPoint( mrContext, fX, fY );
-        pPtAry++;
-        for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
-        {
-            alignLinePoint( pPtAry, fX, fY );
-            CGContextAddLineToPoint( mrContext, fX, fY );
-        }
-    }
-    else
-    {
-        CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
-        pPtAry++;
-        for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
-            CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
-    }
-
-    CGContextDrawPath( mrContext, eMode );
-    RefreshRect( nX, nY, nWidth, nHeight );
-}
-
-// -----------------------------------------------------------------------
-
-void AquaSalGraphics::drawPolyPolygon( sal_uLong nPolyCount, const sal_uLong *pPoints, PCONSTSALPOINT  *ppPtAry )
-{
-    if( nPolyCount <= 0 )
-        return;
-    if( !CheckContext() )
-        return;
-
-    // find bound rect
-    long leftX = 0, topY = 0, maxWidth = 0, maxHeight = 0;
-    getBoundRect( pPoints[0], ppPtAry[0], leftX, topY, maxWidth, maxHeight );
-    for( sal_uLong n = 1; n < nPolyCount; n++ )
-    {
-        long nX = leftX, nY = topY, nW = maxWidth, nH = maxHeight;
-        getBoundRect( pPoints[n], ppPtAry[n], nX, nY, nW, nH );
-        if( nX < leftX )
-        {
-            maxWidth += leftX - nX;
-            leftX = nX;
-        }
-        if( nY < topY )
-        {
-            maxHeight += topY - nY;
-            topY = nY;
-        }
-        if( nX + nW > leftX + maxWidth )
-            maxWidth = nX + nW - leftX;
-        if( nY + nH > topY + maxHeight )
-            maxHeight = nY + nH - topY;
-    }
-
-    // prepare drawing mode
-    CGPathDrawingMode eMode;
-    if( IsBrushVisible() && IsPenVisible() )
-        eMode = kCGPathEOFillStroke;
-    else if( IsPenVisible() )
-        eMode = kCGPathStroke;
-    else if( IsBrushVisible() )
-        eMode = kCGPathEOFill;
-    else
-        return;
-
-    // convert to CGPath
-    CGContextBeginPath( mrContext );
-    if( IsPenVisible() )
-    {
-        for( sal_uLong nPoly = 0; nPoly < nPolyCount; nPoly++ )
-        {
-            const sal_uLong nPoints = pPoints[nPoly];
-            if( nPoints > 1 )
-            {
-                const SalPoint *pPtAry = ppPtAry[nPoly];
-                float fX, fY;
-                alignLinePoint( pPtAry, fX, fY );
-                CGContextMoveToPoint( mrContext, fX, fY );
-                pPtAry++;
-                for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
-                {
-                    alignLinePoint( pPtAry, fX, fY );
-                    CGContextAddLineToPoint( mrContext, fX, fY );
-                }
-                CGContextClosePath(mrContext);
-            }
-        }
-    }
-    else
-    {
-        for( sal_uLong nPoly = 0; nPoly < nPolyCount; nPoly++ )
-        {
-            const sal_uLong nPoints = pPoints[nPoly];
-            if( nPoints > 1 )
-            {
-                const SalPoint *pPtAry = ppPtAry[nPoly];
-                CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
-                pPtAry++;
-                for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
-                    CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
-                CGContextClosePath(mrContext);
-            }
-        }
-    }
-
-    CGContextDrawPath( mrContext, eMode );
-
-    RefreshRect( leftX, topY, maxWidth, maxHeight );
-}
-
-// -----------------------------------------------------------------------
-
-bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly,
-    double fTransparency )
-{
-    // short circuit if there is nothing to do
-    const int nPolyCount = rPolyPoly.count();
-    if( nPolyCount <= 0 )
-        return true;
-
-    // ignore invisible polygons
-    if( (fTransparency >= 1.0) || (fTransparency < 0) )
-        return true;
-
-    // setup poly-polygon path
-    CGMutablePathRef xPath = CGPathCreateMutable();
-    for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
-    {
-        const ::basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list