diff options
Diffstat (limited to 'vcl/aqua/source')
-rw-r--r-- | vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx | 603 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/coretext/salcoretextlayout.cxx | 458 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/coretext/salcoretextstyle.cxx | 93 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/coretext/salgdi.cxx | 234 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/salgdicommon.cxx | 2 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/salgdiutils.cxx | 8 |
6 files changed, 1397 insertions, 1 deletions
diff --git a/vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx b/vcl/aqua/source/gdi/coretext/salcoretextfontutils.cxx new file mode 100644 index 000000000000..08db4fdc19ec --- /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 000000000000..408f2b2ec34e --- /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 000000000000..5a092af3c96a --- /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 000000000000..62e0903b2171 --- /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 0a844292e6e1..72f97ed0e4ca 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 7032fcda1c20..a2cc9a002bd8 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) { |