1/************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28// MARKER(update_precomp.py): autogen include statement, do not remove 29#include "precompiled_vcl.hxx" 30 31#include "aqua/salinst.h" 32 33#include "aqua11ytextattributeswrapper.h" 34 35#include <com/sun/star/accessibility/AccessibleTextType.hpp> 36#include <com/sun/star/awt/FontUnderline.hpp> 37#include <com/sun/star/awt/FontWeight.hpp> 38#include <com/sun/star/awt/FontStrikeout.hpp> 39 40using namespace ::com::sun::star::accessibility; 41using namespace ::com::sun::star::awt; 42using namespace ::com::sun::star::beans; 43using namespace ::com::sun::star::lang; 44using namespace ::com::sun::star::uno; 45using namespace ::rtl; 46 47@implementation AquaA11yTextAttributesWrapper : NSObject 48 49+(int)convertUnderlineStyle:(PropertyValue)property { 50 int underlineStyle = NSNoUnderlineStyle; 51 sal_Int16 value = 0; 52 property.Value >>= value; 53 if ( value != FontUnderline::NONE 54 && value != FontUnderline::DONTKNOW) { 55 underlineStyle = NSSingleUnderlineStyle; 56 } 57 return underlineStyle; 58} 59 60+(int)convertBoldStyle:(PropertyValue)property { 61 int boldStyle = 0; 62 float value = 0; 63 property.Value >>= value; 64 if ( value == FontWeight::SEMIBOLD 65 || value == FontWeight::BOLD 66 || value == FontWeight::ULTRABOLD 67 || value == FontWeight::BLACK ) { 68 boldStyle = NSBoldFontMask; 69 } 70 return boldStyle; 71} 72 73+(int)convertItalicStyle:(PropertyValue)property { 74 int italicStyle = 0; 75 sal_Int16 value = property.Value.get<FontSlant>(); 76 if ( value == FontSlant_ITALIC ) { 77 italicStyle = NSItalicFontMask; 78 } 79 return italicStyle; 80} 81 82+(BOOL)isStrikethrough:(PropertyValue)property { 83 BOOL strikethrough = NO; 84 sal_Int16 value = 0; 85 property.Value >>= value; 86 if ( value != FontStrikeout::NONE 87 && value != FontStrikeout::DONTKNOW ) { 88 strikethrough = YES; 89 } 90 return strikethrough; 91} 92 93+(BOOL)convertBoolean:(PropertyValue)property { 94 BOOL myBoolean = NO; 95 bool value = sal_False; 96 property.Value >>= value; 97 if ( value ) { 98 myBoolean = YES; 99 } 100 return myBoolean; 101} 102 103+(NSNumber *)convertShort:(PropertyValue)property { 104 sal_Int16 value = 0; 105 property.Value >>= value; 106 return [ NSNumber numberWithShort: value ]; 107} 108 109+(void)addColor:(sal_Int32)salColor forAttribute:(NSString *)attribute andRange:(NSRange)range toString:(NSMutableAttributedString *)string { 110 if ( salColor != -1 ) { 111 float elements[] = { salColor & 0x00ff0000, salColor & 0x0000ff00, salColor & 0x000000ff }; 112 CGColorRef color = CGColorCreate ( CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB ), elements ); 113 [ string addAttribute: attribute value: (id) color range: range ]; 114 CGColorRelease ( color ); 115 } 116} 117 118+(void)addFont:(NSFont *)font toString:(NSMutableAttributedString *)string forRange:(NSRange)range { 119 if ( font != nil ) { 120 NSDictionary * fontDictionary = [ NSDictionary dictionaryWithObjectsAndKeys: 121 [ font fontName ], NSAccessibilityFontNameKey, 122 [ font familyName ], NSAccessibilityFontFamilyKey, 123 [ font displayName ], NSAccessibilityVisibleNameKey, 124 [ NSNumber numberWithFloat: [ font pointSize ] ], NSAccessibilityFontSizeKey, 125 nil 126 ]; 127 [ string addAttribute: NSAccessibilityFontTextAttribute 128 value: fontDictionary 129 range: range 130 ]; 131 } 132} 133 134+(void)applyAttributesFrom:(Sequence < PropertyValue >)attributes toString:(NSMutableAttributedString *)string forRange:(NSRange)range storeDefaultsTo:(AquaA11yWrapper *)wrapperStore getDefaultsFrom:(AquaA11yWrapper *)wrapper { 135 NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ]; 136 // constants 137 static const OUString attrUnderline = OUString::createFromAscii("CharUnderline"); 138 static const OUString attrBold = OUString::createFromAscii("CharWeight"); 139 static const OUString attrFontname = OUString::createFromAscii("CharFontName"); 140 static const OUString attrItalic = OUString::createFromAscii("CharPosture"); 141 static const OUString attrHeight = OUString::createFromAscii("CharHeight"); 142 static const OUString attrStrikethrough = OUString::createFromAscii("CharStrikeout"); 143 static const OUString attrShadow = OUString::createFromAscii("CharShadowed"); 144 static const OUString attrUnderlineColor = OUString::createFromAscii("CharUnderlineColor"); 145 static const OUString attrUnderlineHasColor = OUString::createFromAscii("CharUnderlineHasColor"); 146 static const OUString attrForegroundColor = OUString::createFromAscii("CharColor"); 147 static const OUString attrBackgroundColor = OUString::createFromAscii("CharBackColor"); 148 static const OUString attrSuperscript = OUString::createFromAscii("CharEscapement"); 149 // vars 150 OUString fontname; 151 int fonttraits = 0; 152 float fontsize = 0.0; 153 sal_Int32 underlineColor = 0; 154 BOOL underlineHasColor = NO; 155 // add attributes to string 156 for ( int attrIndex = 0; attrIndex < attributes.getLength(); attrIndex++ ) { 157 PropertyValue property = attributes [ attrIndex ]; 158 // TODO: NSAccessibilityMisspelledTextAttribute, NSAccessibilityAttachmentTextAttribute, NSAccessibilityLinkTextAttribute 159 // NSAccessibilityStrikethroughColorTextAttribute is unsupported by UNP-API 160 if ( property.Value.hasValue() ) { 161 if ( property.Name.equals ( attrUnderline ) ) { 162 int style = [ AquaA11yTextAttributesWrapper convertUnderlineStyle: property ]; 163 if ( style != NSNoUnderlineStyle ) { 164 [ string addAttribute: NSAccessibilityUnderlineTextAttribute value: [ NSNumber numberWithInt: style ] range: range ]; 165 } 166 } else if ( property.Name.equals ( attrFontname ) ) { 167 property.Value >>= fontname; 168 } else if ( property.Name.equals ( attrBold ) ) { 169 fonttraits |= [ AquaA11yTextAttributesWrapper convertBoldStyle: property ]; 170 } else if ( property.Name.equals ( attrItalic ) ) { 171 fonttraits |= [ AquaA11yTextAttributesWrapper convertItalicStyle: property ]; 172 } else if ( property.Name.equals ( attrHeight ) ) { 173 property.Value >>= fontsize; 174 } else if ( property.Name.equals ( attrStrikethrough ) ) { 175 if ( [ AquaA11yTextAttributesWrapper isStrikethrough: property ] ) { 176 [ string addAttribute: NSAccessibilityStrikethroughTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ]; 177 } 178 } else if ( property.Name.equals ( attrShadow ) ) { 179 if ( [ AquaA11yTextAttributesWrapper convertBoolean: property ] ) { 180 [ string addAttribute: NSAccessibilityShadowTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ]; 181 } 182 } else if ( property.Name.equals ( attrUnderlineColor ) ) { 183 property.Value >>= underlineColor; 184 } else if ( property.Name.equals ( attrUnderlineHasColor ) ) { 185 underlineHasColor = [ AquaA11yTextAttributesWrapper convertBoolean: property ]; 186 } else if ( property.Name.equals ( attrForegroundColor ) ) { 187 [ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityForegroundColorTextAttribute andRange: range toString: string ]; 188 } else if ( property.Name.equals ( attrBackgroundColor ) ) { 189 [ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityBackgroundColorTextAttribute andRange: range toString: string ]; 190 } else if ( property.Name.equals ( attrSuperscript ) ) { 191 // values < zero mean subscript 192 // values > zero mean superscript 193 // this is true for both NSAccessibility-API and UNO-API 194 NSNumber * number = [ AquaA11yTextAttributesWrapper convertShort: property ]; 195 if ( [ number shortValue ] != 0 ) { 196 [ string addAttribute: NSAccessibilitySuperscriptTextAttribute value: number range: range ]; 197 } 198 } 199 } 200 } 201 // add underline information 202 if ( underlineHasColor ) { 203 [ AquaA11yTextAttributesWrapper addColor: underlineColor forAttribute: NSAccessibilityUnderlineColorTextAttribute andRange: range toString: string ]; 204 } 205 // add font information 206 if ( wrapperStore != nil ) { // default 207 [ wrapperStore setDefaultFontname: CreateNSString ( fontname ) ]; 208 [ wrapperStore setDefaultFontsize: fontsize ]; 209 NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: CreateNSString ( fontname ) traits: fonttraits weight: 0 size: fontsize ]; 210 [ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ]; 211 } else if ( wrapper != nil && fonttraits != 0 ) { // attribute run and bold and/or italic was found 212 NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: [ wrapper defaultFontname ] traits: fonttraits weight: 0 size: [ wrapper defaultFontsize ] ]; 213 [ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ]; 214 } 215 [ pool release ]; 216} 217 218+(NSMutableAttributedString *)createAttributedStringForElement:(AquaA11yWrapper *)wrapper inOrigRange:(id)origRange { 219 static const Sequence < OUString > emptySequence; 220 // vars 221 NSMutableAttributedString * string = nil; 222 int loc = [ origRange rangeValue ].location; 223 int len = [ origRange rangeValue ].length; 224 int endIndex = loc + len; 225 int currentIndex = loc; 226 try { 227 NSString * myString = CreateNSString ( [ wrapper accessibleText ] -> getText() ); // TODO: dirty fix for i87817 228 string = [ [ NSMutableAttributedString alloc ] initWithString: CreateNSString ( [ wrapper accessibleText ] -> getTextRange ( loc, loc + len ) ) ]; 229 if ( [ wrapper accessibleTextAttributes ] != nil && [myString characterAtIndex:0] != 57361) { // TODO: dirty fix for i87817 230 [ string beginEditing ]; 231 // add default attributes for whole string 232 Sequence < PropertyValue > defaultAttributes = [ wrapper accessibleTextAttributes ] -> getDefaultAttributes ( emptySequence ); 233 [ AquaA11yTextAttributesWrapper applyAttributesFrom: defaultAttributes toString: string forRange: [ origRange rangeValue ] storeDefaultsTo: wrapper getDefaultsFrom: nil ]; 234 // add attributes for attribute run(s) 235 while ( currentIndex < endIndex ) { 236 TextSegment textSegment = [ wrapper accessibleText ] -> getTextAtIndex ( currentIndex, AccessibleTextType::ATTRIBUTE_RUN ); 237 int endOfRange = endIndex > textSegment.SegmentEnd ? textSegment.SegmentEnd : endIndex; 238 NSRange rangeForAttributeRun = NSMakeRange ( currentIndex, endOfRange - currentIndex ); 239 // add run attributes 240 Sequence < PropertyValue > attributes = [ wrapper accessibleTextAttributes ] -> getRunAttributes ( currentIndex, emptySequence ); 241 [ AquaA11yTextAttributesWrapper applyAttributesFrom: attributes toString: string forRange: rangeForAttributeRun storeDefaultsTo: nil getDefaultsFrom: wrapper ]; 242 currentIndex = textSegment.SegmentEnd; 243 } 244 [ string endEditing ]; 245 } 246 } catch ( IllegalArgumentException & e ) { 247 // empty 248 } catch ( IndexOutOfBoundsException & e ) { 249 // empty 250 } catch ( RuntimeException& ) { 251 // at least don't crash 252 } 253 return string; 254} 255 256@end 257