blob: 5f30b34cf7fdbcca646d607bdb6a554191615ba3 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include "aqua/salinst.h"
#include "aqua/salgdi.h"
#include "aqua11ytextattributeswrapper.h"
#include <com/sun/star/accessibility/AccessibleTextType.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/awt/FontStrikeout.hpp>
namespace css_awt = ::com::sun::star::awt;
using namespace ::com::sun::star::accessibility;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::rtl;
@implementation AquaA11yTextAttributesWrapper : NSObject
+(int)convertUnderlineStyle:(PropertyValue)property {
int underlineStyle = NSNoUnderlineStyle;
sal_Int16 value = 0;
property.Value >>= value;
if ( value != ::css_awt::FontUnderline::NONE
&& value != ::css_awt::FontUnderline::DONTKNOW) {
underlineStyle = NSSingleUnderlineStyle;
}
return underlineStyle;
}
+(int)convertBoldStyle:(PropertyValue)property {
int boldStyle = 0;
float value = 0;
property.Value >>= value;
if ( value == ::css_awt::FontWeight::SEMIBOLD
|| value == ::css_awt::FontWeight::BOLD
|| value == ::css_awt::FontWeight::ULTRABOLD
|| value == ::css_awt::FontWeight::BLACK ) {
boldStyle = NSBoldFontMask;
}
return boldStyle;
}
+(int)convertItalicStyle:(PropertyValue)property {
int italicStyle = 0;
const sal_Int16 value = property.Value.get< ::css_awt::FontSlant>();
if ( value == ::css_awt::FontSlant_ITALIC ) {
italicStyle = NSItalicFontMask;
}
return italicStyle;
}
+(BOOL)isStrikethrough:(PropertyValue)property {
BOOL strikethrough = NO;
sal_Int16 value = 0;
property.Value >>= value;
if ( value != ::css_awt::FontStrikeout::NONE
&& value != ::css_awt::FontStrikeout::DONTKNOW ) {
strikethrough = YES;
}
return strikethrough;
}
+(BOOL)convertBoolean:(PropertyValue)property {
BOOL myBoolean = NO;
bool value = sal_False;
property.Value >>= value;
if ( value ) {
myBoolean = YES;
}
return myBoolean;
}
+(NSNumber *)convertShort:(PropertyValue)property {
sal_Int16 value = 0;
property.Value >>= value;
return [ NSNumber numberWithShort: value ];
}
+(void)addColor:(SalColor)nSalColor forAttribute:(NSString *)attribute andRange:(NSRange)range toString:(NSMutableAttributedString *)string {
if( nSalColor == COL_TRANSPARENT )
return;
const RGBAColor aRGBAColor( nSalColor);
CGColorRef aColorRef = CGColorCreate ( CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB ), aRGBAColor.AsArray() );
[ string addAttribute: attribute value: (id) aColorRef range: range ];
CGColorRelease( aColorRef );
}
+(void)addFont:(NSFont *)font toString:(NSMutableAttributedString *)string forRange:(NSRange)range {
if ( font != nil ) {
NSDictionary * fontDictionary = [ NSDictionary dictionaryWithObjectsAndKeys:
[ font fontName ], NSAccessibilityFontNameKey,
[ font familyName ], NSAccessibilityFontFamilyKey,
[ font displayName ], NSAccessibilityVisibleNameKey,
[ NSNumber numberWithFloat: [ font pointSize ] ], NSAccessibilityFontSizeKey,
nil
];
[ string addAttribute: NSAccessibilityFontTextAttribute
value: fontDictionary
range: range
];
}
}
+(void)applyAttributesFrom:(Sequence < PropertyValue >)attributes toString:(NSMutableAttributedString *)string forRange:(NSRange)range storeDefaultsTo:(AquaA11yWrapper *)wrapperStore getDefaultsFrom:(AquaA11yWrapper *)wrapper {
NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ];
// constants
static const OUString attrUnderline = OUString::createFromAscii("CharUnderline");
static const OUString attrBold = OUString::createFromAscii("CharWeight");
static const OUString attrFontname = OUString::createFromAscii("CharFontName");
static const OUString attrItalic = OUString::createFromAscii("CharPosture");
static const OUString attrHeight = OUString::createFromAscii("CharHeight");
static const OUString attrStrikethrough = OUString::createFromAscii("CharStrikeout");
static const OUString attrShadow = OUString::createFromAscii("CharShadowed");
static const OUString attrUnderlineColor = OUString::createFromAscii("CharUnderlineColor");
static const OUString attrUnderlineHasColor = OUString::createFromAscii("CharUnderlineHasColor");
static const OUString attrForegroundColor = OUString::createFromAscii("CharColor");
static const OUString attrBackgroundColor = OUString::createFromAscii("CharBackColor");
static const OUString attrSuperscript = OUString::createFromAscii("CharEscapement");
// vars
OUString fontname;
int fonttraits = 0;
float fontsize = 0.0;
sal_Int32 underlineColor = 0;
BOOL underlineHasColor = NO;
// add attributes to string
for ( int attrIndex = 0; attrIndex < attributes.getLength(); attrIndex++ ) {
PropertyValue property = attributes [ attrIndex ];
// TODO: NSAccessibilityMisspelledTextAttribute, NSAccessibilityAttachmentTextAttribute, NSAccessibilityLinkTextAttribute
// NSAccessibilityStrikethroughColorTextAttribute is unsupported by UNP-API
if ( property.Value.hasValue() ) {
if ( property.Name.equals ( attrUnderline ) ) {
int style = [ AquaA11yTextAttributesWrapper convertUnderlineStyle: property ];
if ( style != NSNoUnderlineStyle ) {
[ string addAttribute: NSAccessibilityUnderlineTextAttribute value: [ NSNumber numberWithInt: style ] range: range ];
}
} else if ( property.Name.equals ( attrFontname ) ) {
property.Value >>= fontname;
} else if ( property.Name.equals ( attrBold ) ) {
fonttraits |= [ AquaA11yTextAttributesWrapper convertBoldStyle: property ];
} else if ( property.Name.equals ( attrItalic ) ) {
fonttraits |= [ AquaA11yTextAttributesWrapper convertItalicStyle: property ];
} else if ( property.Name.equals ( attrHeight ) ) {
property.Value >>= fontsize;
} else if ( property.Name.equals ( attrStrikethrough ) ) {
if ( [ AquaA11yTextAttributesWrapper isStrikethrough: property ] ) {
[ string addAttribute: NSAccessibilityStrikethroughTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ];
}
} else if ( property.Name.equals ( attrShadow ) ) {
if ( [ AquaA11yTextAttributesWrapper convertBoolean: property ] ) {
[ string addAttribute: NSAccessibilityShadowTextAttribute value: [ NSNumber numberWithBool: YES ] range: range ];
}
} else if ( property.Name.equals ( attrUnderlineColor ) ) {
property.Value >>= underlineColor;
} else if ( property.Name.equals ( attrUnderlineHasColor ) ) {
underlineHasColor = [ AquaA11yTextAttributesWrapper convertBoolean: property ];
} else if ( property.Name.equals ( attrForegroundColor ) ) {
[ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityForegroundColorTextAttribute andRange: range toString: string ];
} else if ( property.Name.equals ( attrBackgroundColor ) ) {
[ AquaA11yTextAttributesWrapper addColor: property.Value.get<sal_Int32>() forAttribute: NSAccessibilityBackgroundColorTextAttribute andRange: range toString: string ];
} else if ( property.Name.equals ( attrSuperscript ) ) {
// values < zero mean subscript
// values > zero mean superscript
// this is true for both NSAccessibility-API and UNO-API
NSNumber * number = [ AquaA11yTextAttributesWrapper convertShort: property ];
if ( [ number shortValue ] != 0 ) {
[ string addAttribute: NSAccessibilitySuperscriptTextAttribute value: number range: range ];
}
}
}
}
// add underline information
if ( underlineHasColor ) {
[ AquaA11yTextAttributesWrapper addColor: underlineColor forAttribute: NSAccessibilityUnderlineColorTextAttribute andRange: range toString: string ];
}
// add font information
if ( wrapperStore != nil ) { // default
[ wrapperStore setDefaultFontname: CreateNSString ( fontname ) ];
[ wrapperStore setDefaultFontsize: fontsize ];
NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: CreateNSString ( fontname ) traits: fonttraits weight: 0 size: fontsize ];
[ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ];
} else if ( wrapper != nil && fonttraits != 0 ) { // attribute run and bold and/or italic was found
NSFont * font = [ [ NSFontManager sharedFontManager ] fontWithFamily: [ wrapper defaultFontname ] traits: fonttraits weight: 0 size: [ wrapper defaultFontsize ] ];
[ AquaA11yTextAttributesWrapper addFont: font toString: string forRange: range ];
}
[ pool release ];
}
+(NSMutableAttributedString *)createAttributedStringForElement:(AquaA11yWrapper *)wrapper inOrigRange:(id)origRange {
static const Sequence < OUString > emptySequence;
// vars
NSMutableAttributedString * string = nil;
int loc = [ origRange rangeValue ].location;
int len = [ origRange rangeValue ].length;
int endIndex = loc + len;
int currentIndex = loc;
try {
NSString * myString = CreateNSString ( [ wrapper accessibleText ] -> getText() ); // TODO: dirty fix for i87817
string = [ [ NSMutableAttributedString alloc ] initWithString: CreateNSString ( [ wrapper accessibleText ] -> getTextRange ( loc, loc + len ) ) ];
if ( [ wrapper accessibleTextAttributes ] != nil && [myString characterAtIndex:0] != 57361) { // TODO: dirty fix for i87817
[ string beginEditing ];
// add default attributes for whole string
Sequence < PropertyValue > defaultAttributes = [ wrapper accessibleTextAttributes ] -> getDefaultAttributes ( emptySequence );
NSRange offsetRange = NSMakeRange ( 0, len );
[ AquaA11yTextAttributesWrapper applyAttributesFrom: defaultAttributes toString: string forRange: offsetRange storeDefaultsTo: wrapper getDefaultsFrom: nil ];
// add attributes for attribute run(s)
while ( currentIndex < endIndex ) {
TextSegment textSegment = [ wrapper accessibleText ] -> getTextAtIndex ( currentIndex, AccessibleTextType::ATTRIBUTE_RUN );
int endOfRange = endIndex > textSegment.SegmentEnd ? textSegment.SegmentEnd : endIndex;
NSRange rangeForAttributeRun = NSMakeRange ( currentIndex-loc, endOfRange - currentIndex );
// add run attributes
Sequence < PropertyValue > attributes = [ wrapper accessibleTextAttributes ] -> getRunAttributes ( currentIndex, emptySequence );
[ AquaA11yTextAttributesWrapper applyAttributesFrom: attributes toString: string forRange: rangeForAttributeRun storeDefaultsTo: nil getDefaultsFrom: wrapper ];
currentIndex = textSegment.SegmentEnd;
}
[ string endEditing ];
}
} catch ( IllegalArgumentException & e ) {
// empty
} catch ( IndexOutOfBoundsException & e ) {
// empty
} catch ( RuntimeException& ) {
// at least don't crash
}
return string;
}
@end