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