diff options
Diffstat (limited to 'vcl/unx/gtk/a11y/atktext.cxx')
-rw-r--r-- | vcl/unx/gtk/a11y/atktext.cxx | 838 |
1 files changed, 0 insertions, 838 deletions
diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx deleted file mode 100644 index 1406ceea5544..000000000000 --- a/vcl/unx/gtk/a11y/atktext.cxx +++ /dev/null @@ -1,838 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * 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 . - */ - -#include "atkwrapper.hxx" -#include "atktextattributes.hxx" -#include <algorithm> - -#include <osl/diagnose.h> - -#include <com/sun/star/accessibility/AccessibleTextType.hpp> -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> -#include <com/sun/star/text/TextMarkupType.hpp> - -using namespace ::com::sun::star; - -static sal_Int16 -text_type_from_boundary(AtkTextBoundary boundary_type) -{ - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - return accessibility::AccessibleTextType::CHARACTER; - case ATK_TEXT_BOUNDARY_WORD_START: - case ATK_TEXT_BOUNDARY_WORD_END: - return accessibility::AccessibleTextType::WORD; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - case ATK_TEXT_BOUNDARY_SENTENCE_END: - return accessibility::AccessibleTextType::SENTENCE; - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - return accessibility::AccessibleTextType::LINE; - default: - return -1; - } -} - -/*****************************************************************************/ - -static gchar * -adjust_boundaries( css::uno::Reference<css::accessibility::XAccessibleText> const & pText, - accessibility::TextSegment const & rTextSegment, - AtkTextBoundary boundary_type, - gint * start_offset, gint * end_offset ) -{ - accessibility::TextSegment aTextSegment; - OUString aString; - gint start = 0, end = 0; - - if( !rTextSegment.SegmentText.isEmpty() ) - { - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - case ATK_TEXT_BOUNDARY_SENTENCE_START: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - aString = rTextSegment.SegmentText; - break; - - // the OOo break iterator behaves as SENTENCE_START - case ATK_TEXT_BOUNDARY_SENTENCE_END: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - - if( start > 0 ) - --start; - if( end > 0 && end < pText->getCharacterCount() - 1 ) - --end; - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - start = rTextSegment.SegmentStart; - - // Determine the start index of the next segment - aTextSegment = pText->getTextBehindIndex(rTextSegment.SegmentEnd, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - end = aTextSegment.SegmentStart; - else - end = pText->getCharacterCount(); - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - end = rTextSegment.SegmentEnd; - - // Determine the end index of the previous segment - aTextSegment = pText->getTextBeforeIndex(rTextSegment.SegmentStart, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - start = aTextSegment.SegmentEnd; - else - start = 0; - - aString = pText->getTextRange(start, end); - break; - - default: - return nullptr; - } - } - - *start_offset = start; - *end_offset = end; - - return OUStringToGChar(aString); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleText> - getText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpText.is() ) - { - pWrap->mpText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpText; - } - - return css::uno::Reference<css::accessibility::XAccessibleText>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - getTextMarkup( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextMarkup.is() ) - { - pWrap->mpTextMarkup.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextMarkup; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextMarkup>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - getTextAttributes( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextAttributes.is() ) - { - pWrap->mpTextAttributes.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextAttributes; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextAttributes>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleMultiLineText> - getMultiLineText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpMultiLineText.is() ) - { - pWrap->mpMultiLineText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpMultiLineText; - } - - return css::uno::Reference<css::accessibility::XAccessibleMultiLineText>(); -} - -/*****************************************************************************/ - -extern "C" { - -static gchar * -text_wrapper_get_text (AtkText *text, - gint start_offset, - gint end_offset) -{ - gchar * ret = nullptr; - - g_return_val_if_fail( (end_offset == -1) || (end_offset >= start_offset), nullptr ); - - /* at-spi expects the delete event to be send before the deletion happened - * so we save the deleted string object in the UNO event notification and - * fool libatk-bridge.so here .. - */ - void * pData = g_object_get_data( G_OBJECT(text), "ooo::text_changed::delete" ); - if( pData != nullptr ) - { - accessibility::TextSegment * pTextSegment = - static_cast <accessibility::TextSegment *> (pData); - - if( pTextSegment->SegmentStart == start_offset && - pTextSegment->SegmentEnd == end_offset ) - { - OString aUtf8 = OUStringToOString( pTextSegment->SegmentText, RTL_TEXTENCODING_UTF8 ); - return g_strdup( aUtf8.getStr() ); - } - } - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - OUString aText; - sal_Int32 n = pText->getCharacterCount(); - - if( -1 == end_offset ) - aText = pText->getText(); - else if( start_offset < n ) - aText = pText->getTextRange(start_offset, end_offset); - - ret = g_strdup( OUStringToOString(aText, RTL_TEXTENCODING_UTF8 ).getStr() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getText()" ); - } - - return ret; -} - -static gchar * -text_wrapper_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBehindIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_after_offset()" ); - } - - return nullptr; -} - -static gchar * -text_wrapper_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - /* If the user presses the 'End' key, the caret will be placed behind the last character, - * which is the same index as the first character of the next line. In atk the magic offset - * '-2' is used to cover this special case. - */ - if ( - -2 == offset && - (ATK_TEXT_BOUNDARY_LINE_START == boundary_type || - ATK_TEXT_BOUNDARY_LINE_END == boundary_type) - ) - { - css::uno::Reference< - css::accessibility::XAccessibleMultiLineText> pMultiLineText - = getMultiLineText( text ); - if( pMultiLineText.is() ) - { - accessibility::TextSegment aTextSegment = pMultiLineText->getTextAtLineWithCaret(); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - - accessibility::TextSegment aTextSegment = pText->getTextAtIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_at_offset()" ); - } - - return nullptr; -} - -static gunichar -text_wrapper_get_character_at_offset (AtkText *text, - gint offset) -{ - gint start, end; - gunichar uc = 0; - - gchar * char_as_string = - text_wrapper_get_text_at_offset(text, offset, ATK_TEXT_BOUNDARY_CHAR, - &start, &end); - if( char_as_string ) - { - uc = g_utf8_get_char( char_as_string ); - g_free( char_as_string ); - } - - return uc; -} - -static gchar * -text_wrapper_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBeforeIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in text_before_offset()" ); - } - - return nullptr; -} - -static gint -text_wrapper_get_caret_offset (AtkText *text) -{ - gint offset = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - offset = pText->getCaretPosition(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCaretPosition()" ); - } - - return offset; -} - -static gboolean -text_wrapper_set_caret_offset (AtkText *text, - gint offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setCaretPosition( offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setCaretPosition()" ); - } - - return FALSE; -} - -// #i92232# -static AtkAttributeSet* -handle_text_markup_as_run_attribute( css::uno::Reference<css::accessibility::XAccessibleTextMarkup> const & pTextMarkup, - const gint nTextMarkupType, - const gint offset, - AtkAttributeSet* pSet, - gint *start_offset, - gint *end_offset ) -{ - const gint nTextMarkupCount( pTextMarkup->getTextMarkupCount( nTextMarkupType ) ); - if ( nTextMarkupCount > 0 ) - { - for ( gint nTextMarkupIndex = 0; - nTextMarkupIndex < nTextMarkupCount; - ++nTextMarkupIndex ) - { - accessibility::TextSegment aTextSegment = - pTextMarkup->getTextMarkup( nTextMarkupIndex, nTextMarkupType ); - const gint nStartOffsetTextMarkup = aTextSegment.SegmentStart; - const gint nEndOffsetTextMarkup = aTextSegment.SegmentEnd; - if ( nStartOffsetTextMarkup <= offset ) - { - if ( offset < nEndOffsetTextMarkup ) - { - // text markup at <offset> - *start_offset = ::std::max( *start_offset, - nStartOffsetTextMarkup ); - *end_offset = ::std::min( *end_offset, - nEndOffsetTextMarkup ); - switch ( nTextMarkupType ) - { - case css::text::TextMarkupType::SPELLCHECK: - { - pSet = attribute_set_prepend_misspelled( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_INSERTION: - { - pSet = attribute_set_prepend_tracked_change_insertion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_DELETION: - { - pSet = attribute_set_prepend_tracked_change_deletion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE: - { - pSet = attribute_set_prepend_tracked_change_formatchange( pSet ); - } - break; - default: - { - OSL_ASSERT( false ); - } - } - break; // no further iteration needed. - } - else - { - *start_offset = ::std::max( *start_offset, - nEndOffsetTextMarkup ); - // continue iteration. - } - } - else - { - *end_offset = ::std::min( *end_offset, - nStartOffsetTextMarkup ); - break; // no further iteration. - } - } // eof iteration over text markups - } - - return pSet; -} - -static AtkAttributeSet * -text_wrapper_get_run_attributes( AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - AtkAttributeSet *pSet = nullptr; - - try { - bool bOffsetsAreValid = false; - - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is()) - { - uno::Sequence< beans::PropertyValue > aAttributeList; - - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if(pTextAttributes.is()) // Text attributes are available for paragraphs only - { - aAttributeList = pTextAttributes->getRunAttributes( offset, uno::Sequence< OUString > () ); - } - else // For other text objects use character attributes - { - aAttributeList = pText->getCharacterAttributes( offset, uno::Sequence< OUString > () ); - } - - pSet = attribute_set_new_from_property_values( aAttributeList, true, text ); - // #i100938# - // - always provide start_offset and end_offset - { - accessibility::TextSegment aTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - - *start_offset = aTextSegment.SegmentStart; - // #i100938# - // Do _not_ increment the end_offset provide by <accessibility::TextSegment> instance - *end_offset = aTextSegment.SegmentEnd; - bOffsetsAreValid = true; - } - } - - // Special handling for misspelled text - // #i92232# - // - add special handling for tracked changes and refactor the - // corresponding code for handling misspelled text. - css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - pTextMarkup = getTextMarkup( text ); - if( pTextMarkup.is() ) - { - // Get attribute run here if it hasn't been done before - if (!bOffsetsAreValid && pText.is()) - { - accessibility::TextSegment aAttributeTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - *start_offset = aAttributeTextSegment.SegmentStart; - *end_offset = aAttributeTextSegment.SegmentEnd; - } - // handle misspelled text - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::SPELLCHECK, - offset, pSet, start_offset, end_offset ); - // handle tracked changes - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_INSERTION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_DELETION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE, - offset, pSet, start_offset, end_offset ); - } - } - catch(const uno::Exception&){ - - g_warning( "Exception in get_run_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static AtkAttributeSet * -text_wrapper_get_default_attributes( AtkText *text ) -{ - AtkAttributeSet *pSet = nullptr; - - try { - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if( pTextAttributes.is() ) - { - uno::Sequence< beans::PropertyValue > aAttributeList = - pTextAttributes->getDefaultAttributes( uno::Sequence< OUString > () ); - - pSet = attribute_set_new_from_property_values( aAttributeList, false, text ); - } - } - catch(const uno::Exception&) { - - g_warning( "Exception in get_default_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static void -text_wrapper_get_character_extents( AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords ) -{ - *x = *y = *width = *height = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - awt::Rectangle aRect = pText->getCharacterBounds( offset ); - - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_if_fail( ATK_IS_COMPONENT( text ) ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - *x = aRect.X + origin_x; - *y = aRect.Y + origin_y; - *width = aRect.Width; - *height = aRect.Height; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterBounds" ); - } -} - -static gint -text_wrapper_get_character_count (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = pText->getCharacterCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterCount" ); - } - - return rv; -} - -static gint -text_wrapper_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_val_if_fail( ATK_IS_COMPONENT( text ), -1 ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - return pText->getIndexAtPoint( awt::Point(x - origin_x, y - origin_y) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getIndexAtPoint" ); - } - - return -1; -} - -// FIXME: the whole series of selections API is problematic ... - -static gint -text_wrapper_get_n_selections (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = ( pText->getSelectionEnd() > pText->getSelectionStart() ) ? 1 : 0; - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd() or getSelectionStart()" ); - } - - return rv; -} - -static gchar * -text_wrapper_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - *start_offset = pText->getSelectionStart(); - *end_offset = pText->getSelectionEnd(); - - return OUStringToGChar( pText->getSelectedText() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd(), getSelectionStart() or getSelectedText()" ); - } - - return nullptr; -} - -static gboolean -text_wrapper_add_selection (AtkText *text, - gint start_offset, - gint end_offset) -{ - // FIXME: can we try to be more compatible by expanding an - // existing adjacent selection ? - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_remove_selection (AtkText *text, - gint selection_num) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( 0, 0 ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -} // extern "C" - -void -textIfaceInit (AtkTextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_text = text_wrapper_get_text; - iface->get_character_at_offset = text_wrapper_get_character_at_offset; - iface->get_text_before_offset = text_wrapper_get_text_before_offset; - iface->get_text_at_offset = text_wrapper_get_text_at_offset; - iface->get_text_after_offset = text_wrapper_get_text_after_offset; - iface->get_caret_offset = text_wrapper_get_caret_offset; - iface->set_caret_offset = text_wrapper_set_caret_offset; - iface->get_character_count = text_wrapper_get_character_count; - iface->get_n_selections = text_wrapper_get_n_selections; - iface->get_selection = text_wrapper_get_selection; - iface->add_selection = text_wrapper_add_selection; - iface->remove_selection = text_wrapper_remove_selection; - iface->set_selection = text_wrapper_set_selection; - iface->get_run_attributes = text_wrapper_get_run_attributes; - iface->get_default_attributes = text_wrapper_get_default_attributes; - iface->get_character_extents = text_wrapper_get_character_extents; - iface->get_offset_at_point = text_wrapper_get_offset_at_point; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |