diff --git a/platforms/windows/src/text.rs b/platforms/windows/src/text.rs index 50d19ebc..f3406284 100644 --- a/platforms/windows/src/text.rs +++ b/platforms/windows/src/text.rs @@ -5,7 +5,7 @@ #![allow(non_upper_case_globals)] -use accesskit::{Action, ActionData, ActionRequest, ScrollHint}; +use accesskit::{Action, ActionData, ActionRequest, ScrollHint, VerticalOffset}; use accesskit_consumer::{ Node, TextPosition as Position, TextRange as Range, Tree, TreeState, WeakTextRange as WeakRange, }; @@ -426,15 +426,13 @@ impl ITextRangeProvider_Impl for PlatformRange_Impl { } fn GetAttributeValue(&self, id: UIA_TEXTATTRIBUTE_ID) -> Result { - match id { + self.read(|range| match id { UIA_IsReadOnlyAttributeId => { // TBD: do we ever want to support mixed read-only/editable text? - self.with_node(|node| { - let value = node.is_read_only(); - Ok(value.into()) - }) + let value = range.node().is_read_only(); + Ok(value.into()) } - UIA_CaretPositionAttributeId => self.read(|range| { + UIA_CaretPositionAttributeId => { let mut value = CaretPosition_Unknown; if range.is_degenerate() { let pos = range.start(); @@ -445,25 +443,55 @@ impl ITextRangeProvider_Impl for PlatformRange_Impl { } } Ok(value.0.into()) - }), - UIA_CultureAttributeId => { - self.read(|range| Ok(Variant::from(range.language().map(LocaleName)).into())) - } - UIA_FontNameAttributeId => { - self.read(|range| Ok(Variant::from(range.font_family()).into())) } - UIA_FontSizeAttributeId => self.read(|range| { + UIA_CultureAttributeId => Ok(Variant::from(range.language().map(LocaleName)).into()), + UIA_FontNameAttributeId => Ok(Variant::from(range.font_family()).into()), + UIA_FontSizeAttributeId => { Ok(Variant::from(range.font_size().map(|value| value as f64)).into()) - }), - UIA_FontWeightAttributeId => self.read(|range| { + } + UIA_FontWeightAttributeId => { Ok(Variant::from(range.font_weight().map(|value| value as i32)).into()) - }), + } + UIA_IsItalicAttributeId => Ok(Variant::from(range.is_italic()).into()), + UIA_BackgroundColorAttributeId => Ok(Variant::from(range.background_color()).into()), + UIA_ForegroundColorAttributeId => Ok(Variant::from(range.foreground_color()).into()), + UIA_OverlineStyleAttributeId => { + Ok(Variant::from(range.overline().map(|d| d.style)).into()) + } + UIA_OverlineColorAttributeId => { + Ok(Variant::from(range.overline().map(|d| d.color)).into()) + } + UIA_StrikethroughStyleAttributeId => { + Ok(Variant::from(range.strikethrough().map(|d| d.style)).into()) + } + UIA_StrikethroughColorAttributeId => { + Ok(Variant::from(range.strikethrough().map(|d| d.color)).into()) + } + UIA_UnderlineStyleAttributeId => { + Ok(Variant::from(range.underline().map(|d| d.style)).into()) + } + UIA_UnderlineColorAttributeId => { + Ok(Variant::from(range.underline().map(|d| d.color)).into()) + } + UIA_HorizontalTextAlignmentAttributeId => Ok(Variant::from(range.text_align()).into()), + UIA_IsSubscriptAttributeId => Ok(Variant::from( + range + .vertical_offset() + .map(|o| o == VerticalOffset::Subscript), + ) + .into()), + UIA_IsSuperscriptAttributeId => Ok(Variant::from( + range + .vertical_offset() + .map(|o| o == VerticalOffset::Superscript), + ) + .into()), // TODO: implement more attributes _ => { let value = unsafe { UiaGetReservedNotSupportedValue() }.unwrap(); Ok(value.into()) } - } + }) } fn GetBoundingRectangles(&self) -> Result<*mut SAFEARRAY> { diff --git a/platforms/windows/src/util.rs b/platforms/windows/src/util.rs index 94cac694..44e21efa 100644 --- a/platforms/windows/src/util.rs +++ b/platforms/windows/src/util.rs @@ -3,7 +3,7 @@ // the LICENSE-APACHE file) or the MIT license (found in // the LICENSE-MIT file), at your option. -use accesskit::Point; +use accesskit::{Color, Point, TextAlign, TextDecorationStyle}; use accesskit_consumer::{TextRangePropertyValue, TreeState}; use std::{ fmt::{self, Write}, @@ -146,6 +146,39 @@ impl From for Variant { } } +impl From for Variant { + fn from(value: Color) -> Self { + let rgb: i32 = + (value.red as i32) | ((value.green as i32) << 8) | ((value.blue as i32) << 16); + Self(rgb.into()) + } +} + +impl From for Variant { + fn from(value: TextDecorationStyle) -> Self { + let value = match value { + TextDecorationStyle::Solid => TextDecorationLineStyle_Single, + TextDecorationStyle::Dotted => TextDecorationLineStyle_Dot, + TextDecorationStyle::Dashed => TextDecorationLineStyle_Dash, + TextDecorationStyle::Double => TextDecorationLineStyle_Double, + TextDecorationStyle::Wavy => TextDecorationLineStyle_Wavy, + }; + Self::from(value.0) + } +} + +impl From for Variant { + fn from(value: TextAlign) -> Self { + let value = match value { + TextAlign::Left => HorizontalTextAlignment_Left, + TextAlign::Right => HorizontalTextAlignment_Right, + TextAlign::Center => HorizontalTextAlignment_Centered, + TextAlign::Justify => HorizontalTextAlignment_Justified, + }; + Self::from(value.0) + } +} + impl From for Variant { fn from(value: bool) -> Self { Self(value.into())