| ... | ... | @@ -135,6 +135,7 @@ impl TextEngine { |
| 135 | 135 | let mut start = 0; |
| 136 | 136 | for (index, span) in paragraph.spans().iter().enumerate() { |
| 137 | 137 | let format = &span.format; |
| 138 | let link = format.hyperlink == Some(true); |
| 138 | 139 | let size = format.font_size.unwrap_or(11.0); |
| 139 | 140 | if !size.is_finite() || size <= 0.0 { |
| 140 | 141 | return Err(LayoutError::InvalidFontSize); |
| ... | ... | @@ -160,10 +161,15 @@ impl TextEngine { |
| 160 | 161 | FontStyle::Normal |
| 161 | 162 | }), |
| 162 | 163 | StyleProperty::Brush(TextBrush { |
| 163 | | color: format.color.unwrap_or(0), |
| 164 | // Links take OneNote's blue unless given a colour of their own. |
| 165 | color: match format.color { |
| 166 | Some(color) if color != 0xff000000 => color, |
| 167 | _ if link => 0x00ff0000, |
| 168 | _ => 0, |
| 169 | }, |
| 164 | 170 | highlight: format.highlight.filter(|color| *color != 0xff000000), |
| 165 | 171 | }), |
| 166 | | StyleProperty::Underline(format.underline.unwrap_or(false)), |
| 172 | StyleProperty::Underline(format.underline.unwrap_or(false) || link), |
| 167 | 173 | StyleProperty::Strikethrough(format.strike.unwrap_or(false)), |
| 168 | 174 | ]; |
| 169 | 175 | for property in properties { |
| ... | ... | @@ -554,6 +560,43 @@ mod tests { |
| 554 | 560 | assert_eq!(fonts.len(), 1); |
| 555 | 561 | } |
| 556 | 562 | |
| 563 | #[test] |
| 564 | fn links_draw_blue_and_underlined_unless_coloured() { |
| 565 | let mut engine = TextEngine::default(); |
| 566 | let link = Format { |
| 567 | hyperlink: Some(true), |
| 568 | ..Format::default() |
| 569 | }; |
| 570 | let layout = engine |
| 571 | .layout( |
| 572 | &Paragraph::from_runs([ |
| 573 | ("plain ".into(), Format::default()), |
| 574 | ("link".into(), link.clone()), |
| 575 | ( |
| 576 | " red".into(), |
| 577 | Format { |
| 578 | color: Some(0x0000_00ff), |
| 579 | ..link |
| 580 | }, |
| 581 | ), |
| 582 | ]), |
| 583 | 300.0, |
| 584 | ) |
| 585 | .unwrap(); |
| 586 | let runs: Vec<_> = layout |
| 587 | .lines() |
| 588 | .flat_map(|(line, _)| line.items().collect::<Vec<_>>()) |
| 589 | .filter_map(|item| match item { |
| 590 | PositionedLayoutItem::GlyphRun(run) => { |
| 591 | let style = run.style(); |
| 592 | Some((style.brush.color, style.underline.is_some())) |
| 593 | } |
| 594 | _ => None, |
| 595 | }) |
| 596 | .collect(); |
| 597 | assert_eq!(runs, [(0, false), (0x00ff_0000, true), (0x0000_00ff, true)]); |
| 598 | } |
| 599 | |
| 557 | 600 | #[test] |
| 558 | 601 | fn paragraph_alignment_offsets_lines_within_the_wrap_width() { |
| 559 | 602 | let mut engine = TextEngine::default(); |