явно написано, какие фичи работают в OOXML, а какие в ODT
Что-то - как расширение стандарта odt.
pub type SinglePrecision = f32;
pub type DoublePrecision = f64;
#[derive(Debug, Clone, Copy)]
pub struct Size2D {
pub width: SinglePrecision,
pub height: SinglePrecision,
}
// coordinates are assumed to start from top-left corner
#[derive(Debug, Clone, Copy)]
pub struct Position2D {
pub top: SinglePrecision,
pub left: SinglePrecision,
}
#[derive(Debug, Clone, Copy)]
struct Segment2D {
// {y2,x2} >= {y1,x1}
p1: Position2D,
p2: Position2D,
}
impl Segment2D {
fn new (p1: Position2D, p2: Position2D) -> Self {
let mut array = [p1, p2];
array.sort_by(
|p1, p2|
p1.top.partial_cmp(&p2.top).unwrap()
.then(p1.left.partial_cmp(&p2.left).unwrap())
);
Self {p1: array[0], p2: array[1]}
}
}
#[derive(Debug, Clone, Copy)]
pub struct BoundingRect2D {
pub size: Size2D,
pub position: Position2D,
}
impl BoundingRect2D {
fn from_size_at_0 (size: Size2D) -> Self {
Self {size, position: Position2D {top: 0., left: 0.}}
}
fn height (&self) -> SinglePrecision {
self.size.height
}
fn left (&self) -> SinglePrecision {
self.position.left
}
fn right (&self) -> SinglePrecision {
self.position.left + self.size.width
}
fn top (&self) -> SinglePrecision {
self.position.top
}
fn bottom (&self) -> SinglePrecision {
self.position.top + self.size.height
}
fn left_top (&self) -> Position2D {
Position2D{top: self.top(), left: self.left()}
}
fn right_top (&self) -> Position2D {
Position2D{top: self.top(), left: self.right()}
}
fn left_bottom (&self) -> Position2D {
Position2D{top: self.bottom(), left: self.left()}
}
fn right_bottom (&self) -> Position2D {
Position2D{top: self.bottom(), left: self.right()}
}
fn does_x_intersect_with (&self, left: SinglePrecision, right: SinglePrecision) -> bool {
// !((a.max < b.min) || (b.max < a.min))
!((right <= self.left()) || (self.right() <= left))
}
}
trait MyAverage1
{
type Output;
fn my_average (self) -> Self::Output;
}
trait MyAverage2
{
type Output;
fn my_average (self) -> Self::Output;
}
impl<T> MyAverage1 for T
where T: Iterator<Item=SinglePrecision>
{
type Output = DoublePrecision;
fn my_average (self) -> Self::Output {
let (mut total, mut count) = (DoublePrecision::from(0u8), DoublePrecision::from(0u8));
for v in self {
total += DoublePrecision::from(v);
count += DoublePrecision::from(1u8);
}
total / count
}
}
impl<T> MyAverage2 for T
where T: Iterator<Item=(SinglePrecision, SinglePrecision)>
{
type Output = (DoublePrecision, DoublePrecision);
fn my_average (self) -> Self::Output {
let (mut total, mut count) = ((DoublePrecision::from(0u8), DoublePrecision::from(0u8)), DoublePrecision::from(0u8));
for v in self {
total.0 += DoublePrecision::from(v.0);
total.1 += DoublePrecision::from(v.1);
count += DoublePrecision::from(1u8);
}
(total.0 / count, total.1 / count)
}
}
fn gen_initial_size_for_undefined<It: Iterator<Item=Option<Size2D>>> (sizes_opt_it: It, minimal_rect_size: Size2D) -> Size2D
{
let (avg_width, avg_height)
= sizes_opt_it
.filter_map(
|size_opt|
size_opt.map(|size| (size.width, size.height))
)
.my_average();
let middle_or
= |middle: DoublePrecision, minimal: SinglePrecision|
if middle < minimal.into() {minimal} else {middle as SinglePrecision};
Size2D {
width: middle_or(avg_width, minimal_rect_size.width),
height: middle_or(avg_height, minimal_rect_size.height),
}
}
fn get_min_and_premin_for<T: PartialOrd + Copy, It: Iterator<Item=T>> (mut it: It) -> Option<((usize, T), Option<(usize, T)>)> {
let mut min_idx_and_value = match it.next() {
None => return None,
Some(v) => (0, v),
};
let mut pre_min_idx_and_value = None;
let mut it = it.enumerate().map(|(idx, v)| (1 + idx, v));
while let Some((i, v)) = it.next() {
if v < min_idx_and_value.1 {
pre_min_idx_and_value = Some(min_idx_and_value);
min_idx_and_value = (i, v);
}
}
Some((min_idx_and_value, pre_min_idx_and_value))
}
struct Step {
value: DoublePrecision,
sourse: *const InteractableBoundingRect2D,
relative_size: SinglePrecision,
}
struct InteractableBoundingRect2D {
bounding_rect: BoundingRect2D,
top_steps: Vec<Step>,
bottom_steps: Vec<Step>,
left_steps: Vec<Step>,
right_steps: Vec<Step>,
}
fn make_bounding_rects_interactable (rects: Vec<BoundingRect2D>) -> Vec<InteractableBoundingRect2D> {
rects.into_iter().map(
|bounding_rect|
InteractableBoundingRect2D {
bounding_rect,
top_steps: Vec::new(),
bottom_steps: Vec::new(),
left_steps: Vec::new(),
right_steps: Vec::new()
}
).collect()
}
#[derive(Debug, Clone, Copy)]
enum Direction {
Top,
Bottom,
Left,
Right,
}
impl Direction {
fn into_reverse (self) -> Self {
match self {
Self::Top => Self::Bottom,
Self::Bottom => Self::Top,
Self::Left => Self::Right,
Self::Right => Self::Left,
}
}
}
#[derive(Debug, Clone, Copy, Default)]
struct Segment1D {
// p2 >= p1
p1: SinglePrecision,
p2: SinglePrecision,
}
impl Segment1D {
fn new (p1: SinglePrecision, p2: SinglePrecision) -> Self {
let mut array = [p1, p2];
array.sort_by(|p1, p2| p1.partial_cmp(p2).unwrap());
Self {p1: array[0], p2: array[1]}
}
fn from_bounding_rect_side (br: BoundingRect2D, direction: Direction) -> Self {
match direction {
Direction::Top | Direction::Bottom => Self {p1: br.left(), p2: br.right()},
Direction::Left | Direction::Right => Self {p1: br.top(), p2: br.bottom()},
}
}
fn from_bounding_rect_side_reverse (br: BoundingRect2D, direction: Direction) -> Self {
Self::from_bounding_rect_side(br, direction.into_reverse())
}
fn does_intersect_with (&self, other: Self) -> bool {
// !((a.max < b.min) || (b.max < a.min))
!((self.p2 <= other.p1) || (other.p2 <= self.p1))
}
}
struct Segment1DSideCollection {
from: SinglePrecision,
to: SinglePrecision,
used_rect_idx_acc: Vec<(usize, Segment1D)>,
direction: Direction,
}
impl Segment1DSideCollection {
fn new_empty () -> Self {
Self {from: 0., to: 0., used_rect_idx_acc: Vec::new(), direction: Direction::Top}
}
fn reset (&mut self, from: SinglePrecision, to: SinglePrecision, direction: Direction) {
self.used_rect_idx_acc.clear();
(self.from, self.to, self.direction) = (from, to, direction);
}
fn get_new_part_opt (&self, next_segment: Segment1D) -> Option<Segment1D> {
self.used_rect_idx_acc.iter().position(|(_, existing)| existing.does_intersect_with(next_segment)).is_some()
}
fn try_next_down<It: Iterator<Item=(usize, Segment1D)>> (&mut self, it: It) -> Option<It> {
while let Some((usize, segment)) = it.next() {
}
None
}
fn try_next<Map: Fn(&BoundingRect2D)->SinglePrecision, Filter: Fn(&BoundingRect2D,&Self)->bool> (&mut self, for_segment: Segment2D, next_i: usize, rects: &Vec<InteractableBoundingRect2D>) -> Option<usize> {
}
fn is_next_reasonable (&mut self, next_i: usize, rects: &mut Vec<InteractableBoundingRect2D>, direction: Direction) {
}
fn get_rects_new (&mut self, from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>, direction: Direction) -> Vec<&mut InteractableBoundingRect2D> {
self.reinit(rects[from_idx].bounding_rect, direction);
let mut result = Vec::new();
result
}
fn get_rects_left (&mut self, from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>) -> Vec<&mut InteractableBoundingRect2D> {
self.get_rects_new(from_idx, rects, Direction::Top)
}
}
fn get_rects_left (from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>) -> Vec<&mut InteractableBoundingRect2D> {
}
fn get_rects_right (from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>) -> Vec<&mut InteractableBoundingRect2D> {
}
fn get_rects_top (from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>) -> Vec<&mut InteractableBoundingRect2D> {
}
fn get_rects_bottom (from_idx: usize, rects: &mut Vec<InteractableBoundingRect2D>) -> Vec<&mut InteractableBoundingRect2D> {
}