Update StrokeStyle

This commit is contained in:
Nomango 2020-02-11 12:09:59 +08:00
parent 7b8ea2fa76
commit 08a50ca474
12 changed files with 267 additions and 173 deletions

View File

@ -38,27 +38,12 @@ LayerActor::LayerActor()
LayerActor::~LayerActor() {}
void LayerActor::SetClipRect(Rect const& clip_rect)
{
layer_.SetClipRect(clip_rect);
}
void LayerActor::SetOpacity(float opacity)
{
// Actor::SetOpacity(opacity);
layer_.SetOpacity(opacity);
}
void LayerActor::SetMaskShape(ShapePtr mask)
{
layer_.SetMaskShape(mask);
}
void LayerActor::SetMaskTransform(Matrix3x2 const& transform)
{
layer_.SetMaskTransform(transform);
}
bool LayerActor::DispatchEvent(Event* evt)
{
if (!IsVisible())

View File

@ -34,7 +34,7 @@ KGE_DECLARE_SMART_PTR(LayerActor);
/**
* \~chinese
* @brief
* @brief
*/
class KGE_API LayerActor : public Actor
{
@ -51,40 +51,29 @@ public:
/// @brief 是否开启消息吞没
bool IsSwallowEventsEnabled() const;
/// \~chinese
/// @brief 获取图层区域
Layer const& GetLayer() const;
/// \~chinese
/// @brief 获取图层区域
Layer& GetLayer();
/// \~chinese
/// @brief 设置图层
/// @param layer 图层
void SetLayer(Layer const& layer);
/// \~chinese
/// @brief 设置消息吞没功能
/// @param enabled 是否启用
void SetSwallowEvents(bool enabled);
/// \~chinese
/// @brief 设置裁剪区域
/// @param clip_rect 裁剪矩形
void SetClipRect(Rect const& clip_rect);
/// \~chinese
/// @brief 设置图层透明度
/// @param opacity 透明度
void SetOpacity(float opacity) override;
/// \~chinese
/// @brief 设置几何蒙层
/// @param mask 蒙层的形状
void SetMaskShape(ShapePtr mask);
/// \~chinese
/// @brief 设置几何蒙层的二维变换
/// @param transform 应用于蒙层的二维变换
void SetMaskTransform(Matrix3x2 const& transform);
/// \~chinese
/// @brief 设置图层区域
/// @param area 图层区域属性
void SetLayer(Layer const& layer);
/// \~chinese
/// @brief 获取图层区域
Layer const& GetLayer() const;
bool DispatchEvent(Event* evt) override;
protected:
@ -118,4 +107,10 @@ inline Layer const& LayerActor::GetLayer() const
{
return layer_;
}
inline Layer& LayerActor::GetLayer()
{
return layer_;
}
} // namespace kiwano

View File

@ -59,16 +59,6 @@ bool ShapeActor::ContainsPoint(const Point& point) const
return shape_->ContainsPoint(point, &GetTransformMatrix());
}
void ShapeActor::SetStrokeWidth(float width)
{
stroke_width_ = std::max(width, 0.f);
}
void ShapeActor::SetStrokeStyle(StrokeStylePtr stroke_style)
{
stroke_style_ = stroke_style;
}
void ShapeActor::SetShape(ShapePtr shape)
{
shape_ = shape;

View File

@ -350,43 +350,62 @@ inline void ShapeActor::SetFillBrush(BrushPtr brush)
{
fill_brush_ = brush;
}
inline void ShapeActor::SetStrokeBrush(BrushPtr brush)
{
stroke_brush_ = brush;
}
inline BrushPtr ShapeActor::GetFillBrush() const
{
return fill_brush_;
}
inline BrushPtr ShapeActor::GetStrokeBrush() const
{
return stroke_brush_;
}
inline float ShapeActor::GetStrokeWidth() const
{
return stroke_width_;
}
inline StrokeStylePtr ShapeActor::GetStrokeStyle() const
{
return stroke_style_;
}
inline ShapePtr ShapeActor::GetShape() const
{
return shape_;
}
inline void ShapeActor::SetStrokeWidth(float width)
{
stroke_width_ = std::max(width, 0.f);
}
inline void ShapeActor::SetStrokeStyle(StrokeStylePtr stroke_style)
{
stroke_style_ = stroke_style;
}
inline Point const& LineActor::GetBeginPoint() const
{
return begin_;
}
inline Point const& LineActor::GetEndPoint() const
{
return end_;
}
inline void LineActor::SetBeginPoint(Point const& begin)
{
SetLine(begin, end_);
}
inline void LineActor::SetEndPoint(Point const& end)
{
SetLine(begin_, end);
@ -401,6 +420,7 @@ inline Vec2 RoundedRectActor::GetRadius() const
{
return radius_;
}
inline Size RoundedRectActor::GetRectSize() const
{
return GetSize();
@ -415,4 +435,5 @@ inline Vec2 EllipseActor::GetRadius() const
{
return radius_;
}
} // namespace kiwano

View File

@ -66,6 +66,10 @@ public:
/// @brief 获取文本布局
const TextLayout& GetLayout() const;
/// \~chinese
/// @brief 获取文本布局
TextLayout& GetLayout();
/// \~chinese
/// @brief 获取文本布局大小
Size GetLayoutSize() const;
@ -194,6 +198,11 @@ inline const TextLayout& TextActor::GetLayout() const
return text_layout_;
}
inline TextLayout& TextActor::GetLayout()
{
return text_layout_;
}
inline Size TextActor::GetLayoutSize() const
{
return text_layout_.GetLayoutSize();

View File

@ -133,18 +133,10 @@ void RenderContextImpl::DrawTextLayout(TextLayout const& layout, Point const& of
}
HRESULT hr = S_OK;
ID2D1StrokeStyle* stroke_style = style.outline_stroke ? style.outline_stroke->GetStrokeStyle().get() : nullptr;
if (style.outline_stroke)
{
hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(),
outline_brush.get(), style.outline_width,
style.outline_stroke->GetStrokeStyle().get());
}
else
{
hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(),
outline_brush.get(), style.outline_width, nullptr);
}
hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(),
outline_brush.get(), style.outline_width, stroke_style);
if (SUCCEEDED(hr))
{
@ -164,16 +156,9 @@ void RenderContextImpl::DrawShape(Shape const& shape, StrokeStylePtr stroke, flo
if (shape.IsValid())
{
if (stroke)
{
render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width,
stroke->GetStrokeStyle().get());
}
else
{
render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width,
nullptr);
}
ID2D1StrokeStyle* stroke_style = stroke ? stroke->GetStrokeStyle().get() : nullptr;
render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width,
stroke_style);
IncreasePrimitivesCount();
}
@ -184,16 +169,9 @@ void RenderContextImpl::DrawLine(Point const& point1, Point const& point2, Strok
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (stroke)
{
render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2),
current_brush_->GetBrush().get(), stroke_width, stroke->GetStrokeStyle().get());
}
else
{
render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2),
current_brush_->GetBrush().get(), stroke_width, nullptr);
}
ID2D1StrokeStyle* stroke_style = stroke ? stroke->GetStrokeStyle().get() : nullptr;
render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2),
current_brush_->GetBrush().get(), stroke_width, stroke_style);
IncreasePrimitivesCount();
}
@ -203,16 +181,9 @@ void RenderContextImpl::DrawRectangle(Rect const& rect, StrokeStylePtr stroke, f
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (stroke)
{
render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width,
stroke->GetStrokeStyle().get());
}
else
{
render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width,
nullptr);
}
ID2D1StrokeStyle* stroke_style = stroke ? stroke->GetStrokeStyle().get() : nullptr;
render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width,
stroke_style);
IncreasePrimitivesCount();
}
@ -223,17 +194,10 @@ void RenderContextImpl::DrawRoundedRectangle(Rect const& rect, Vec2 const& radiu
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (stroke)
{
render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width,
stroke->GetStrokeStyle().get());
}
else
{
render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width, nullptr);
}
ID2D1StrokeStyle* stroke_style = stroke ? stroke->GetStrokeStyle().get() : nullptr;
render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width, stroke_style);
IncreasePrimitivesCount();
}
@ -242,16 +206,9 @@ void RenderContextImpl::DrawEllipse(Point const& center, Vec2 const& radius, Str
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (stroke)
{
render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width, stroke->GetStrokeStyle().get());
}
else
{
render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width, nullptr);
}
ID2D1StrokeStyle* stroke_style = stroke ? stroke->GetStrokeStyle().get() : nullptr;
render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
current_brush_->GetBrush().get(), stroke_width, stroke_style);
IncreasePrimitivesCount();
}

View File

@ -39,22 +39,19 @@ public:
void EndDraw() override;
void DrawTexture(Texture const& texture, const Rect* src_rect = nullptr, const Rect* dest_rect = nullptr) override;
void DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect) override;
void DrawTextLayout(TextLayout const& layout, Point const& offset = Point()) override;
void DrawTextLayout(TextLayout const& layout, Point const& offset) override;
void DrawShape(Shape const& shape, StrokeStylePtr stroke = nullptr, float stroke_width = 1.0f) override;
void DrawShape(Shape const& shape, StrokeStylePtr stroke, float stroke_width) override;
void DrawLine(Point const& point1, Point const& point2, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) override;
void DrawLine(Point const& point1, Point const& point2, StrokeStylePtr stroke, float stroke_width) override;
void DrawRectangle(Rect const& rect, StrokeStylePtr stroke = nullptr, float stroke_width = 1.0f) override;
void DrawRectangle(Rect const& rect, StrokeStylePtr stroke, float stroke_width) override;
void DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) override;
void DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, StrokeStylePtr stroke, float stroke_width) override;
void DrawEllipse(Point const& center, Vec2 const& radius, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) override;
void DrawEllipse(Point const& center, Vec2 const& radius, StrokeStylePtr stroke, float stroke_width) override;
void FillShape(Shape const& shape) override;

View File

@ -31,7 +31,7 @@ namespace kiwano
/**
* \~chinese
* @brief
* @brief
*/
class KGE_API Layer
{

View File

@ -89,7 +89,7 @@ public:
/// @param shape 形状
/// @param stroke 线条样式
/// @param stroke_width 线条宽度
virtual void DrawShape(Shape const& shape, StrokeStylePtr stroke = nullptr, float stroke_width = 1.0f) = 0;
virtual void DrawShape(Shape const& shape, StrokeStylePtr stroke, float stroke_width) = 0;
/// \~chinese
/// @brief 绘制线段
@ -97,15 +97,14 @@ public:
/// @param point2 线段终点
/// @param stroke 线条样式
/// @param stroke_width 线条宽度
virtual void DrawLine(Point const& point1, Point const& point2, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) = 0;
virtual void DrawLine(Point const& point1, Point const& point2, StrokeStylePtr stroke, float stroke_width) = 0;
/// \~chinese
/// @brief 绘制矩形边框
/// @param rect 矩形
/// @param stroke 线条样式
/// @param stroke_width 线条宽度
virtual void DrawRectangle(Rect const& rect, StrokeStylePtr stroke = nullptr, float stroke_width = 1.0f) = 0;
virtual void DrawRectangle(Rect const& rect, StrokeStylePtr stroke, float stroke_width) = 0;
/// \~chinese
/// @brief 绘制圆角矩形边框
@ -113,8 +112,8 @@ public:
/// @param radius 圆角半径
/// @param stroke 线条样式
/// @param stroke_width 线条宽度
virtual void DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) = 0;
virtual void DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, StrokeStylePtr stroke,
float stroke_width) = 0;
/// \~chinese
/// @brief 绘制椭圆边框
@ -122,8 +121,8 @@ public:
/// @param radius 椭圆半径
/// @param stroke 线条样式
/// @param stroke_width 线条宽度
virtual void DrawEllipse(Point const& center, Vec2 const& radius, StrokeStylePtr stroke = nullptr,
float stroke_width = 1.0f) = 0;
virtual void DrawEllipse(Point const& center, Vec2 const& radius, StrokeStylePtr stroke,
float stroke_width) = 0;
/// \~chinese
/// @brief 填充形状

View File

@ -26,41 +26,15 @@ namespace kiwano
StrokeStylePtr StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, DashStyle dash, float dash_offset)
{
switch (dash)
StrokeStylePtr ptr = new (std::nothrow) StrokeStyle;
if (ptr)
{
case DashStyle::Solid:
{
return StrokeStyle::Create(cap, line_join, nullptr, 0, dash_offset);
ptr->SetCapStyle(cap);
ptr->SetLineJoinStyle(line_join);
ptr->SetDashStyle(dash);
ptr->SetDashOffset(dash_offset);
}
case DashStyle::Dash:
{
float dash_array[] = { 2, 2 };
return StrokeStyle::Create(cap, line_join, dash_array, dash_offset);
}
case DashStyle::Dot:
{
float dash_array[] = { 0, 2 };
return StrokeStyle::Create(cap, line_join, dash_array, dash_offset);
}
case DashStyle::DashDot:
{
float dash_array[] = { 2, 2, 0, 2 };
return StrokeStyle::Create(cap, line_join, dash_array, dash_offset);
}
case DashStyle::DashDotDot:
{
float dash_array[] = { 2, 2, 0, 2, 0, 2 };
return StrokeStyle::Create(cap, line_join, dash_array, dash_offset);
}
default:
break;
}
return nullptr;
return ptr;
}
StrokeStylePtr StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, const float* dash_array, size_t dash_size,
@ -69,11 +43,84 @@ StrokeStylePtr StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, const
StrokeStylePtr ptr = new (std::nothrow) StrokeStyle;
if (ptr)
{
Renderer::GetInstance().CreateStrokeStyle(*ptr, cap, line_join, dash_array, dash_size, dash_offset);
ptr->SetCapStyle(cap);
ptr->SetLineJoinStyle(line_join);
ptr->SetDashStyle(dash_array, dash_size);
ptr->SetDashOffset(dash_offset);
}
return ptr;
}
StrokeStyle::StrokeStyle() {}
StrokeStyle::StrokeStyle()
: cap_(CapStyle::Flat)
, line_join_(LineJoinStyle::Miter)
, dash_offset_(0.0f)
{
}
void StrokeStyle::SetDashStyle(DashStyle dash_style)
{
switch (dash_style)
{
case DashStyle::Solid:
{
dash_array_.clear();
break;
}
case DashStyle::Dash:
{
dash_array_ = { 2, 2 };
break;
}
case DashStyle::Dot:
{
dash_array_ = { 0, 2 };
break;
}
case DashStyle::DashDot:
{
dash_array_ = { 2, 2, 0, 2 };
break;
}
case DashStyle::DashDotDot:
{
dash_array_ = { 2, 2, 0, 2, 0, 2 };
break;
}
default:
break;
}
}
void StrokeStyle::SetDashStyle(const Vector<float>& dash_array)
{
dash_array_ = dash_array;
style_.reset();
}
void StrokeStyle::SetDashStyle(const float* dash_array, size_t dash_size)
{
if (dash_size == 0)
dash_array_.clear();
else
dash_array_.assign(dash_array, dash_array + dash_size);
style_.reset();
}
ComPtr<ID2D1StrokeStyle> StrokeStyle::GetStrokeStyle() const
{
StrokeStyle& self = const_cast<StrokeStyle&>(*this);
if (dash_array_.empty())
Renderer::GetInstance().CreateStrokeStyle(self, cap_, line_join_, nullptr, 0, dash_offset_);
else
Renderer::GetInstance().CreateStrokeStyle(self, cap_, line_join_, &dash_array_[0], dash_array_.size(),
dash_offset_);
return style_;
}
} // namespace kiwano

View File

@ -97,8 +97,8 @@ public:
/// @param dash_array 线条虚线的长度与间隙数组
/// @param dash_offset 线条虚线偏移量
template <size_t _DashSize>
static StrokeStylePtr Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter,
float (&dash_array)[_DashSize] = nullptr, float dash_offset = 0.0f)
static inline StrokeStylePtr Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter,
float (&dash_array)[_DashSize] = nullptr, float dash_offset = 0.0f)
{
return StrokeStyle::Create(cap, line_join, dash_array, _DashSize, dash_offset);
}
@ -109,6 +109,67 @@ public:
/// @brief 是否有效
bool IsValid() const;
/// \~chinese
/// @brief 获取线条端点样式
CapStyle GetCapStyle() const;
/// \~chinese
/// @brief 获取线条交点样式
LineJoinStyle GetLineJoinStyle() const;
/// \~chinese
/// @brief 获取线条虚线的长度与间隙数组
const Vector<float>& GetDashArray() const;
/// \~chinese
/// @brief 获取虚线偏移量
float GetDashOffset() const;
/// \~chinese
/// @brief 设置线条端点样式
void SetCapStyle(CapStyle cap);
/// \~chinese
/// @brief 设置线条交点样式
void SetLineJoinStyle(LineJoinStyle line_join);
/// \~chinese
/// @brief 设置虚线样式
/// @param dash_style 线条虚线样式
void SetDashStyle(DashStyle dash_style);
/// \~chinese
/// @brief 设置虚线样式
/// @param dash_array 线条虚线的长度与间隙数组
void SetDashStyle(const Vector<float>& dash_array);
/// \~chinese
/// @brief 设置虚线样式
/// @param dash_array 线条虚线的长度与间隙数组
/// @param dash_size 线条虚线数组大小
void SetDashStyle(const float* dash_array, size_t dash_size);
/// \~chinese
/// @brief 设置虚线样式
/// @tparam _DashSize 线条虚线数组大小
/// @param dash_array 线条虚线的长度与间隙数组
template <size_t _DashSize>
inline void SetDashStyle(float (&dash_array)[_DashSize])
{
SetDashStyle(dash_array, _DashSize);
}
/// \~chinese
/// @brief 设置虚线偏移量
/// @param dash_offset 线条虚线偏移量
void SetDashOffset(float dash_offset);
private:
CapStyle cap_;
LineJoinStyle line_join_;
float dash_offset_;
Vector<float> dash_array_;
#if defined(KGE_WIN32)
public:
ComPtr<ID2D1StrokeStyle> GetStrokeStyle() const;
@ -122,15 +183,48 @@ private:
/** @} */
inline bool StrokeStyle::IsValid() const
inline CapStyle StrokeStyle::GetCapStyle() const
{
return style_ != nullptr;
return cap_;
}
inline LineJoinStyle StrokeStyle::GetLineJoinStyle() const
{
return line_join_;
}
inline const Vector<float>& StrokeStyle::GetDashArray() const
{
return dash_array_;
}
inline float StrokeStyle::GetDashOffset() const
{
return dash_offset_;
}
inline void StrokeStyle::SetCapStyle(CapStyle cap)
{
cap_ = cap;
style_.reset();
}
inline void StrokeStyle::SetLineJoinStyle(LineJoinStyle line_join)
{
line_join_ = line_join;
style_.reset();
}
inline void StrokeStyle::SetDashOffset(float dash_offset)
{
dash_offset_ = dash_offset;
style_.reset();
}
#if defined(KGE_WIN32)
inline ComPtr<ID2D1StrokeStyle> StrokeStyle::GetStrokeStyle() const
inline bool StrokeStyle::IsValid() const
{
return style_;
return style_ != nullptr;
}
inline void StrokeStyle::SetStrokeStyle(ComPtr<ID2D1StrokeStyle> style)

View File

@ -32,7 +32,7 @@ namespace kiwano
/// \~chinese
/// @brief 文本布局
class KGE_API TextLayout
class KGE_API TextLayout : public Noncopyable
{
public:
/// \~chinese