blob: 54a1f8a7a1e9b0255276b49ff2c690579bc3c301 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
namespace blink {
// This class represents CSS property values to convert between logical and
// physical coordinate systems. See:
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
class CORE_EXPORT WritingModeConverter {
STACK_ALLOCATED();
public:
// @param writing_direction |WritingMode| and |TextDirection|.
// @param outer_size the size of the rect (typically a fragment). Some
// combinations of |WritingMode| and |TextDirection| require the size of the
// container to make the offset relative to the right or the bottom edges.
WritingModeConverter(WritingDirectionMode writing_direction,
const PhysicalSize& outer_size)
: writing_direction_(writing_direction), outer_size_(outer_size) {}
// Construct without |outer_size|. Caller should call |SetOuterSize| before
// conversions.
explicit WritingModeConverter(WritingDirectionMode writing_direction)
: writing_direction_(writing_direction) {}
// Conversion properties and utilities.
WritingDirectionMode GetWritingDirection() const {
return writing_direction_;
}
WritingMode GetWritingMode() const {
return writing_direction_.GetWritingMode();
}
TextDirection Direction() const { return writing_direction_.Direction(); }
bool IsLtr() const { return writing_direction_.IsLtr(); }
void SetOuterSize(const PhysicalSize& outer_size) {
outer_size_ = outer_size;
}
// |LogicalOffset| and |PhysicalOffset| conversions.
// PhysicalOffset will be the physical top left point of the rectangle
// described by offset + inner_size. Setting inner_size to 0,0 will return
// the same point.
// @param inner_size the size of the inner rect (typically a child fragment).
LogicalOffset ToLogical(const PhysicalOffset& offset,
const PhysicalSize& inner_size) const;
PhysicalOffset ToPhysical(const LogicalOffset& offset,
const PhysicalSize& inner_size) const;
// |LogicalSize| and |PhysicalSize| conversions.
LogicalSize ToLogical(const PhysicalSize& size) const;
PhysicalSize ToPhysical(const LogicalSize& size) const;
// |LogicalRect| and |PhysicalRect| conversions.
LogicalRect ToLogical(const PhysicalRect& rect) const;
PhysicalRect ToPhysical(const LogicalRect& rect) const;
private:
LogicalOffset SlowToLogical(const PhysicalOffset& offset,
const PhysicalSize& inner_size) const;
PhysicalOffset SlowToPhysical(const LogicalOffset& offset,
const PhysicalSize& inner_size) const;
LogicalRect SlowToLogical(const PhysicalRect& rect) const;
PhysicalRect SlowToPhysical(const LogicalRect& rect) const;
WritingDirectionMode writing_direction_;
PhysicalSize outer_size_;
};
inline LogicalOffset WritingModeConverter::ToLogical(
const PhysicalOffset& offset,
const PhysicalSize& inner_size) const {
if (writing_direction_.IsHorizontalLtr())
return LogicalOffset(offset.left, offset.top);
return SlowToLogical(offset, inner_size);
}
inline PhysicalOffset WritingModeConverter::ToPhysical(
const LogicalOffset& offset,
const PhysicalSize& inner_size) const {
if (writing_direction_.IsHorizontalLtr())
return PhysicalOffset(offset.inline_offset, offset.block_offset);
return SlowToPhysical(offset, inner_size);
}
inline LogicalSize WritingModeConverter::ToLogical(
const PhysicalSize& size) const {
return size.ConvertToLogical(GetWritingMode());
}
inline PhysicalSize WritingModeConverter::ToPhysical(
const LogicalSize& size) const {
return ToPhysicalSize(size, GetWritingMode());
}
inline LogicalRect WritingModeConverter::ToLogical(
const PhysicalRect& rect) const {
if (writing_direction_.IsHorizontalLtr())
return LogicalRect(rect.X(), rect.Y(), rect.Width(), rect.Height());
return SlowToLogical(rect);
}
inline PhysicalRect WritingModeConverter::ToPhysical(
const LogicalRect& rect) const {
if (writing_direction_.IsHorizontalLtr()) {
return PhysicalRect(rect.offset.inline_offset, rect.offset.block_offset,
rect.size.inline_size, rect.size.block_size);
}
return SlowToPhysical(rect);
}
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_