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