add: finished the Canvas

minor fixes
This commit is contained in:
Haibo 2018-11-18 20:26:41 +08:00 committed by Nomango
parent 18990c3ee6
commit 7b67d49c93
22 changed files with 759 additions and 495 deletions

View File

@ -21,91 +21,159 @@
#include "Canvas.h"
#include "render.h"
#include "logs.h"
#include "Image.h"
namespace easy2d
{
//-------------------------------------------------------
// CanvasBrush
//-------------------------------------------------------
CanvasBrush::CanvasBrush()
: render_target_(nullptr)
, fill_brush_(nullptr)
, line_brush_(nullptr)
, stroke_style_(nullptr)
Canvas::Canvas()
: cache_expired_(false)
, stroke_width_(1.0f)
, stroke_(StrokeStyle::Miter)
{
auto graphics = devices::Graphics::Instance();
render_target_ = graphics->GetRenderTarget();
ThrowIfFailed(
graphics->CreateSolidColorBrush(fill_brush_)
devices::Graphics::Instance()->CreateBitmapRenderTarget(render_target_)
);
auto properties = D2D1::BrushProperties();
ThrowIfFailed(
render_target_->CreateSolidColorBrush(
Color(Color::White, 0.f),
properties,
&fill_brush_)
);
ThrowIfFailed(
graphics->CreateSolidColorBrush(line_brush_)
render_target_->CreateSolidColorBrush(
Color(Color::White),
properties,
&stroke_brush_)
);
this->SetStrokeStyle(stroke_);
ThrowIfFailed(
render_target_->CreateSolidColorBrush(
Color(Color::White),
properties,
&text_brush_)
);
ThrowIfFailed(
devices::Graphics::Instance()->CreateTextRenderer(
text_renderer_,
render_target_,
text_brush_
)
);
SetTextStyle(Font{}, TextStyle{});
}
CanvasBrush::~CanvasBrush()
Canvas::Canvas(float width, float height)
: Canvas()
{
this->SetSize(width, height);
}
Canvas::Canvas(Size const & size)
: Canvas(size.width, size.height)
{
}
void CanvasBrush::SetLineColor(Color const& color)
Canvas::~Canvas()
{
line_brush_->SetColor(D2D_COLOR_F(color));
}
void CanvasBrush::SetFillColor(Color const& color)
void Canvas::BeginDraw()
{
fill_brush_->SetColor(D2D_COLOR_F(color));
render_target_->BeginDraw();
}
void CanvasBrush::SetStrokeWidth(float width)
void Canvas::EndDraw()
{
ThrowIfFailed(
render_target_->EndDraw()
);
cache_expired_ = true;
}
void Canvas::OnDraw()
{
if (cache_expired_)
{
GetBitmap();
}
if (bitmap_cached_)
{
devices::Graphics::Instance()->DrawBitmap(bitmap_cached_);
}
}
void Canvas::SetStrokeColor(Color const& color)
{
stroke_brush_->SetColor(color);
}
void Canvas::SetFillColor(Color const& color)
{
fill_brush_->SetColor(color);
}
void Canvas::SetStrokeWidth(float width)
{
stroke_width_ = std::max(width, 0.f);
}
void CanvasBrush::SetStrokeStyle(StrokeStyle stroke)
void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
{
stroke_style_ = devices::Graphics::Instance()->GetStrokeStyle(stroke);
outline_join_style_ = devices::Graphics::Instance()->GetStrokeStyle(outline_join);
}
Color CanvasBrush::GetLineColor() const
void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
{
return line_brush_->GetColor();
text_font_ = font;
text_style_ = text_style;
text_renderer_->SetTextStyle(
text_style_.color,
text_style_.outline,
text_style_.outline_color,
text_style_.outline_width,
devices::Graphics::Instance()->GetStrokeStyle(text_style_.outline_stroke).Get()
);
}
Color CanvasBrush::GetFillColor() const
Color Canvas::GetStrokeColor() const
{
return stroke_brush_->GetColor();
}
Color Canvas::GetFillColor() const
{
return fill_brush_->GetColor();
}
float CanvasBrush::GetStrokeWidth() const
float Canvas::GetStrokeWidth() const
{
return stroke_width_;
}
StrokeStyle CanvasBrush::GetStrokeStyle() const
void Canvas::SetBrushTransform(math::Matrix const & transform)
{
return stroke_;
render_target_->SetTransform(ConvertToD2DMatrix(transform));
}
void CanvasBrush::DrawLine(const Point & begin, const Point & end)
void Canvas::DrawLine(const Point & begin, const Point & end)
{
render_target_->DrawLine(
D2D1::Point2F(begin.x, begin.y),
D2D1::Point2F(end.x, end.y),
line_brush_.Get(),
stroke_brush_.Get(),
stroke_width_,
stroke_style_.Get()
outline_join_style_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::DrawCircle(const Point & center, float radius)
void Canvas::DrawCircle(const Point & center, float radius)
{
render_target_->DrawEllipse(
D2D1::Ellipse(
@ -116,13 +184,14 @@ namespace easy2d
radius,
radius
),
line_brush_.Get(),
stroke_brush_.Get(),
stroke_width_,
stroke_style_.Get()
outline_join_style_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::DrawEllipse(const Point & center, float radius_x, float radius_y)
void Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y)
{
render_target_->DrawEllipse(
D2D1::Ellipse(
@ -133,13 +202,14 @@ namespace easy2d
radius_x,
radius_y
),
line_brush_.Get(),
stroke_brush_.Get(),
stroke_width_,
stroke_style_.Get()
outline_join_style_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::DrawRect(const Rect & rect)
void Canvas::DrawRect(const Rect & rect)
{
render_target_->DrawRectangle(
D2D1::RectF(
@ -148,13 +218,14 @@ namespace easy2d
rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height
),
line_brush_.Get(),
stroke_brush_.Get(),
stroke_width_,
stroke_style_.Get()
outline_join_style_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y)
void Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y)
{
render_target_->DrawRoundedRectangle(
D2D1::RoundedRect(
@ -167,13 +238,62 @@ namespace easy2d
radius_x,
radius_y
),
line_brush_.Get(),
stroke_brush_.Get(),
stroke_width_,
stroke_style_.Get()
outline_join_style_.Get()
);
cache_expired_ = true;
}
void Canvas::DrawImage(spImage const & image, float opacity)
{
if (image->GetBitmap())
{
render_target_->DrawBitmap(
image->GetBitmap().Get(),
Rect{ Point{}, image->GetSize() },
opacity,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
image->GetCropRect()
);
cache_expired_ = true;
}
}
void Canvas::DrawText(String const & text, Point const & point)
{
if (text.empty())
return;
auto graphics = devices::Graphics::Instance();
cpTextFormat text_format;
ThrowIfFailed(
graphics->CreateTextFormat(
text_format,
text_font_,
text_style_
)
);
cpTextLayout text_layout;
Size layout_size;
ThrowIfFailed(
graphics->CreateTextLayout(
text_layout,
layout_size,
text,
text_format,
text_style_
)
);
ThrowIfFailed(
text_layout->Draw(nullptr, text_renderer_.Get(), point.x, point.y)
);
}
void CanvasBrush::FillCircle(const Point & center, float radius)
void Canvas::FillCircle(const Point & center, float radius)
{
render_target_->FillEllipse(
D2D1::Ellipse(
@ -186,9 +306,10 @@ namespace easy2d
),
fill_brush_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::FillEllipse(const Point & center, float radius_x, float radius_y)
void Canvas::FillEllipse(const Point & center, float radius_x, float radius_y)
{
render_target_->FillEllipse(
D2D1::Ellipse(
@ -201,9 +322,10 @@ namespace easy2d
),
fill_brush_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::FillRect(const Rect & rect)
void Canvas::FillRect(const Rect & rect)
{
render_target_->FillRectangle(
D2D1::RectF(
@ -214,9 +336,10 @@ namespace easy2d
),
fill_brush_.Get()
);
cache_expired_ = true;
}
void CanvasBrush::FillRoundedRect(const Rect & rect, float radius_x, float radius_y)
void Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y)
{
render_target_->FillRoundedRectangle(
D2D1::RoundedRect(
@ -231,38 +354,115 @@ namespace easy2d
),
fill_brush_.Get()
);
cache_expired_ = true;
}
//-------------------------------------------------------
// Canvas
//-------------------------------------------------------
Canvas::Canvas()
void Canvas::BeginPath(Point const& begin_pos)
{
current_geometry_ = nullptr;
ThrowIfFailed(
devices::Graphics::Instance()->CreatePathGeometry(current_geometry_)
);
ThrowIfFailed(
current_geometry_->Open(&current_sink_)
);
current_sink_->BeginFigure(begin_pos, D2D1_FIGURE_BEGIN_FILLED);
}
Canvas::Canvas(float width, float height)
void Canvas::EndPath(bool closed)
{
this->SetClipEnabled(true);
this->SetWidth(width);
this->SetHeight(height);
}
Canvas::~Canvas()
if (current_sink_)
{
current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
ThrowIfFailed(
current_sink_->Close()
);
current_sink_ = nullptr;
}
}
void Canvas::SetBrush(spCanvasBrush const & brush)
void Canvas::AddLine(Point const & point)
{
brush_ = brush;
if (current_sink_)
current_sink_->AddLine(point);
}
void Canvas::OnDraw()
void Canvas::AddLines(std::vector<Point> const& points)
{
if (!brush_)
brush_ = new CanvasBrush;
if (current_sink_)
{
if (!points.empty())
{
size_t size = points.size();
std::vector<D2D1_POINT_2F> d2d_points(size);
for (size_t i = 0; i < size; ++i)
{
d2d_points[i] = points[i];
}
OnDraw(*brush_);
current_sink_->AddLines(
&d2d_points[0],
static_cast<UINT32>(size)
);
}
}
}
void Canvas::AddBezier(Point const & point1, Point const & point2, Point const & point3)
{
if (current_sink_)
{
current_sink_->AddBezier(
D2D1::BezierSegment(
point1,
point2,
point3
)
);
}
}
void Canvas::StrokePath()
{
render_target_->DrawGeometry(
current_geometry_.Get(),
stroke_brush_.Get(),
stroke_width_,
outline_join_style_.Get()
);
cache_expired_ = true;
}
void Canvas::FillPath()
{
render_target_->FillGeometry(
current_geometry_.Get(),
fill_brush_.Get()
);
cache_expired_ = true;
}
spImage Canvas::ExportToImage() const
{
auto image = new Image(GetBitmap());
image->Crop(Rect(Point{}, this->GetSize()));
return image;
}
cpBitmap const& easy2d::Canvas::GetBitmap() const
{
if (cache_expired_)
{
bitmap_cached_ = nullptr;
ThrowIfFailed(
render_target_->GetBitmap(&bitmap_cached_)
);
cache_expired_ = false;
}
return bitmap_cached_;
}
}

View File

@ -20,19 +20,37 @@
#pragma once
#include "Node.h"
#include "Font.hpp"
#include "TextStyle.hpp"
#include "TextRenderer.h"
#undef DrawText
namespace easy2d
{
E2D_DECLARE_SMART_PTR(CanvasBrush);
// ť­ąĘ
class CanvasBrush
: public RefCounter
// 画布
class Canvas
: public Node
{
public:
CanvasBrush();
Canvas();
virtual ~CanvasBrush();
Canvas(
Size const& size
);
Canvas(
float width,
float height
);
virtual ~Canvas();
// 开始绘图
void BeginDraw();
// 结束绘图
void EndDraw();
// ť­ÖąĎß
void DrawLine(
@ -65,6 +83,18 @@ namespace easy2d
float radius_y
);
// 画图片
void DrawImage(
spImage const& image,
float opacity = 1.f
);
// 画文字
void DrawText(
String const& text, /* 文字 */
Point const& point /* 文字位置 */
);
// ĚîłäÔ˛ĐÎ
void FillCircle(
const Point& center,
@ -90,72 +120,100 @@ namespace easy2d
float radius_y
);
// ÉčÖĂĎßĚőŃŐÉŤ
void SetLineColor(
const Color& color
// 开始绘制路径
void BeginPath(
Point const& begin_pos /* 路径起始点 */
);
// 结束路径
void EndPath(
bool closed = true /* 路径是否闭合 */
);
// 添加一条线段
void AddLine(
Point const& point /* 端点 */
);
// 添加多条线段
void AddLines(
std::vector<Point> const& points
);
// 添加一条三次方贝塞尔曲线
void AddBezier(
Point const& point1, /* 贝塞尔曲线的第一个控制点 */
Point const& point2, /* 贝塞尔曲线的第二个控制点 */
Point const& point3 /* 贝塞尔曲线的终点 */
);
// 路径描边
void StrokePath();
// 路径填充
void FillPath();
// ÉčÖĂĚîłäŃŐÉŤ
void SetFillColor(
const Color& color
);
// 设置线条颜色
void SetStrokeColor(
const Color& color
);
// ÉčÖĂĎßĚőżíśČ
void SetStrokeWidth(
float width
);
// ÉčÖĂĎßĚőĎཝŃůĘ˝
void SetStrokeStyle(
StrokeStyle stroke
void SetOutlineJoinStyle(
StrokeStyle outline_join
);
// ťńČĄĎßĚőŃŐÉŤ
Color GetLineColor() const;
// 设置文字画刷样式
void SetTextStyle(
Font const& font,
TextStyle const& text_style
);
// ťńČĄĚîłäŃŐÉŤ
Color GetFillColor() const;
// 获取线条颜色
Color GetStrokeColor() const;
// ťńČĄĎßĚőżíśČ
float GetStrokeWidth() const;
// ťńČĄĎßĚőĎཝŃůĘ˝
StrokeStyle GetStrokeStyle() const;
protected:
float stroke_width_;
StrokeStyle stroke_;
cpRenderTarget render_target_;
cpSolidColorBrush fill_brush_;
cpSolidColorBrush line_brush_;
cpStrokeStyle stroke_style_;
};
// ť­˛ź
class Canvas
: public Node
{
public:
Canvas();
Canvas(
float width,
float height
// 变换画笔
void SetBrushTransform(
math::Matrix const& transform
);
virtual ~Canvas();
virtual void OnDraw(CanvasBrush& brush) = 0;
// ÉčÖĂť­Ë˘
void SetBrush(
spCanvasBrush const& brush
);
// 导出为图片
spImage ExportToImage() const;
virtual void OnDraw() override;
private:
spCanvasBrush brush_;
protected:
cpBitmap const& GetBitmap() const;
protected:
mutable bool cache_expired_;
mutable cpBitmap bitmap_cached_;
float stroke_width_;
Font text_font_;
TextStyle text_style_;
cpPathGeometry current_geometry_;
cpGeometrySink current_sink_;
cpStrokeStyle outline_join_style_;
cpSolidColorBrush fill_brush_;
cpSolidColorBrush stroke_brush_;
cpSolidColorBrush text_brush_;
cpTextRenderer text_renderer_;
cpBitmapRenderTarget render_target_;
};
}

View File

@ -118,10 +118,10 @@ namespace easy2d
const auto window = Window::Instance();
::ShowWindow(window->GetHandle(), SW_SHOWNORMAL);
::UpdateWindow(window->GetHandle());
window->Poll();
const int64_t min_interval = 5;
auto last = time::Now();
MSG msg = {};
while (!quit_)
{
@ -142,11 +142,7 @@ namespace easy2d
UpdateScene(dt);
DrawScene();
while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
window->Poll();
}
else
{
@ -279,16 +275,16 @@ namespace easy2d
if (debug_enabled_)
{
graphics->SetTransform(math::Matrix());
graphics->SetOpacity(1.f);
if (curr_scene_)
{
graphics->SetTransform(math::Matrix());
graphics->SetBrushOpacity(1.f);
curr_scene_->DrawBorder();
}
if (next_scene_)
{
graphics->SetTransform(math::Matrix());
graphics->SetBrushOpacity(1.f);
next_scene_->DrawBorder();
}

View File

@ -32,51 +32,51 @@ namespace easy2d
}
Image::Image(Resource const& res)
: bitmap_(nullptr)
, crop_rect_()
: Image()
{
this->Load(res);
}
Image::Image(Resource const& res, Rect const& crop_rect)
: bitmap_(nullptr)
, crop_rect_()
: Image()
{
this->Load(res);
this->Crop(crop_rect);
}
Image::Image(String const& file_name)
: bitmap_(nullptr)
, crop_rect_()
: Image()
{
this->Load(file_name);
}
Image::Image(String const& file_name, const Rect & crop_rect)
: bitmap_(nullptr)
, crop_rect_()
: Image()
{
this->Load(file_name);
this->Crop(crop_rect);
}
Image::Image(cpBitmap const & bitmap)
: Image()
{
SetBitmap(bitmap);
}
Image::~Image()
{
}
bool Image::Load(Resource const& res)
{
HRESULT hr = devices::Graphics::Instance()->CreateBitmapFromResource(bitmap_, res);
cpBitmap bitmap;
HRESULT hr = devices::Graphics::Instance()->CreateBitmapFromResource(bitmap, res);
if (FAILED(hr))
{
logs::Errorln(hr, "Load Image from resource failed!");
return false;
}
crop_rect_.origin.x = crop_rect_.origin.y = 0;
crop_rect_.size.width = bitmap_->GetSize().width;
crop_rect_.size.height = bitmap_->GetSize().height;
SetBitmap(bitmap);
return true;
}
@ -93,16 +93,15 @@ namespace easy2d
// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
String image_file_path = image_file.GetPath();
HRESULT hr = devices::Graphics::Instance()->CreateBitmapFromFile(bitmap_, image_file_path);
cpBitmap bitmap;
HRESULT hr = devices::Graphics::Instance()->CreateBitmapFromFile(bitmap, image_file_path);
if (FAILED(hr))
{
logs::Errorln(hr, "Load Image from file failed!");
return false;
}
crop_rect_.origin.x = crop_rect_.origin.y = 0;
crop_rect_.size.width = bitmap_->GetSize().width;
crop_rect_.size.height = bitmap_->GetSize().height;
SetBitmap(bitmap);
return true;
}
@ -192,4 +191,15 @@ namespace easy2d
return bitmap_;
}
void Image::SetBitmap(cpBitmap const & bitmap)
{
if (bitmap)
{
bitmap_ = bitmap;
crop_rect_.origin.x = crop_rect_.origin.y = 0;
crop_rect_.size.width = bitmap_->GetSize().width;
crop_rect_.size.height = bitmap_->GetSize().height;
}
}
}

View File

@ -49,6 +49,10 @@ namespace easy2d
Rect const& crop_rect /* ²Ã¼ô¾ØÐÎ */
);
explicit Image(
cpBitmap const& bitmap
);
virtual ~Image();
// ¼ÓÔØÍ¼Æ¬×ÊÔ´
@ -98,6 +102,11 @@ namespace easy2d
cpBitmap const& GetBitmap() const;
protected:
void SetBitmap(
cpBitmap const& bitmap
);
protected:
Rect crop_rect_;
cpBitmap bitmap_;

View File

@ -48,8 +48,8 @@ namespace easy2d
, dirty_transform_(false)
, order_(0)
, transform_()
, opacity_(1.f)
, display_opacity_(1.f)
, real_opacity_(1.f)
, children_()
, initial_matrix_()
, final_matrix_()
@ -75,14 +75,16 @@ namespace easy2d
graphics->PushClip(final_matrix_, transform_.size);
}
UpdateTransform();
if (children_.IsEmpty())
{
graphics->SetTransform(final_matrix_);
graphics->SetOpacity(display_opacity_);
OnDraw();
}
else
{
// ×Ó½ÚµãÅÅÐò
if (dirty_sort_)
{
children_.Sort(
@ -107,6 +109,7 @@ namespace easy2d
}
graphics->SetTransform(final_matrix_);
graphics->SetOpacity(display_opacity_);
OnDraw();
for (spNode next; child; child = next)
@ -129,7 +132,6 @@ namespace easy2d
OnUpdate(dt);
UpdateActions(this, dt);
UpdateTasks(dt);
UpdateTransform();
}
else
{
@ -151,7 +153,6 @@ namespace easy2d
OnUpdate(dt);
UpdateActions(this, dt);
UpdateTasks(dt);
UpdateTransform();
for (spNode next; child; child = next)
{
@ -167,7 +168,7 @@ namespace easy2d
{
if (border_)
{
devices::Graphics::Instance()->DrawGeometry(border_, border_color_, 1.f, 1.5f);
devices::Graphics::Instance()->DrawGeometry(border_, border_color_, 1.5f);
}
for (auto child = children_.First(); child; child = child->NextItem())
@ -248,7 +249,7 @@ namespace easy2d
{
if (parent_)
{
display_opacity_ = real_opacity_ * parent_->display_opacity_;
display_opacity_ = opacity_ * parent_->display_opacity_;
}
for (auto child = children_.First(); child; child = child->NextItem())
{
@ -256,106 +257,6 @@ namespace easy2d
}
}
bool Node::IsVisible() const
{
return visible_;
}
String const& Node::GetName() const
{
return name_;
}
size_t Node::GetHashName() const
{
return hash_name_;
}
const Point& Node::GetPosition() const
{
return transform_.position;
}
float Node::GetWidth() const
{
return transform_.size.width * transform_.scale.x;
}
float Node::GetHeight() const
{
return transform_.size.height * transform_.scale.y;
}
float Node::GetRealWidth() const
{
return transform_.size.width;
}
float Node::GetRealHeight() const
{
return transform_.size.height;
}
const Size& Node::GetRealSize() const
{
return transform_.size;
}
float Node::GetPivotX() const
{
return transform_.pivot.x;
}
float Node::GetPivotY() const
{
return transform_.pivot.y;
}
Size Node::GetSize() const
{
return Size{ GetWidth(), GetHeight() };
}
float Node::GetScaleX() const
{
return transform_.scale.x;
}
float Node::GetScaleY() const
{
return transform_.scale.y;
}
float Node::GetSkewX() const
{
return transform_.skew.x;
}
float Node::GetSkewY() const
{
return transform_.skew.y;
}
float Node::GetRotation() const
{
return transform_.rotation;
}
float Node::GetOpacity() const
{
return real_opacity_;
}
float Node::GetDisplayOpacity() const
{
return display_opacity_;
}
int Node::GetOrder() const
{
return order_;
}
void Node::SetOrder(int order)
{
if (order_ == order)
@ -459,10 +360,10 @@ namespace easy2d
void Node::SetOpacity(float opacity)
{
if (real_opacity_ == opacity)
if (opacity_ == opacity)
return;
display_opacity_ = real_opacity_ = std::min(std::max(opacity, 0.f), 1.f);
display_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f);
// ¸üнڵã͸Ã÷¶È
UpdateOpacity();
}
@ -566,11 +467,6 @@ namespace easy2d
}
}
spNode Node::GetParent() const
{
return parent_;
}
Rect Node::GetBounds()
{
return Rect(Point{}, transform_.size);

View File

@ -59,71 +59,59 @@ namespace easy2d
virtual void OnUpdate(Duration const& dt) {}
// 获取节点显示状态
bool IsVisible() const;
bool IsVisible() const { return visible_; }
// 获取节点名称
String const& GetName() const;
String const& GetName() const { return name_; }
// 获取节点名称的 Hash 值
size_t GetHashName() const;
size_t GetHashName() const { return hash_name_; }
// 获取节点绘图顺序
int GetOrder() const;
int GetOrder() const { return order_; }
// 获取节点坐标
const Point& GetPosition() const;
virtual const Point& GetPosition() const { return transform_.position; }
// 获取节点宽度
float GetWidth() const;
virtual float GetWidth() const { return transform_.size.width * transform_.scale.x; }
// 获取节点高度
float GetHeight() const;
// 获取节点宽度(不考虑缩放)
float GetRealWidth() const;
// 获取节点高度(不考虑缩放)
float GetRealHeight() const;
// 获取节点大小(不考虑缩放)
const Size& GetRealSize() const;
// 获取节点的支点
float GetPivotX() const;
// 获取节点的支点
float GetPivotY() const;
virtual float GetHeight() const { return transform_.size.height * transform_.scale.y; }
// 获取节点大小
Size GetSize() const;
Size GetSize() const { return Size{ GetWidth(), GetHeight() }; }
// 获取节点的支点
virtual float GetPivotX() const { return transform_.pivot.x; }
// 获取节点的支点
virtual float GetPivotY() const { return transform_.pivot.y; }
// 获取节点横向缩放比例
float GetScaleX() const;
virtual float GetScaleX() const { return transform_.scale.x; }
// 获取节点纵向缩放比例
float GetScaleY() const;
virtual float GetScaleY() const { return transform_.scale.y; }
// 获取节点横向错切角度
float GetSkewX() const;
virtual float GetSkewX() const { return transform_.skew.x; }
// 获取节点纵向错切角度
float GetSkewY() const;
virtual float GetSkewY() const { return transform_.skew.y; }
// 获取节点旋转角度
float GetRotation() const;
virtual float GetRotation() const { return transform_.rotation; }
// 获取节点透明度
float GetOpacity() const;
// 获取显示透明度
float GetDisplayOpacity() const;
// 获取父节点
spNode GetParent() const;
virtual float GetOpacity() const { return opacity_; }
// 获取包围盒
virtual Rect GetBounds();
// 获取父节点
virtual spNode GetParent() const { return parent_; }
// 设置节点是否显示
void SetVisible(
bool val
@ -248,7 +236,7 @@ namespace easy2d
);
// 修改节点宽度
virtual void SetWidth(
void SetWidth(
float width
);
@ -367,7 +355,7 @@ namespace easy2d
String name_;
size_t hash_name_;
float display_opacity_;
float real_opacity_;
float opacity_;
int order_;
bool visible_;
bool clip_enabled_;

View File

@ -129,15 +129,9 @@ namespace easy2d
void Sprite::OnDraw()
{
if (image_ && image_->GetBitmap())
if (image_)
{
auto crop_pos = image_->GetCropPos();
devices::Graphics::Instance()->DrawImage(
image_,
GetDisplayOpacity(),
Rect(Point(), GetTransform().size),
Rect(crop_pos, GetTransform().size)
);
devices::Graphics::Instance()->DrawImage(image_);
}
}
}

View File

@ -44,7 +44,6 @@ namespace easy2d
Text::Text()
: font_(text_default_font)
, style_(text_default_style)
, dirty_layout_(false)
{
}
@ -67,8 +66,8 @@ namespace easy2d
: font_(font)
, style_(style)
, text_(text)
, dirty_layout_(true)
{
UpdateLayout();
}
Text::~Text()
@ -127,7 +126,6 @@ namespace easy2d
int Text::GetLineCount()
{
UpdateLayout();
if (text_layout_)
{
DWRITE_TEXT_METRICS metrics;
@ -139,12 +137,6 @@ namespace easy2d
return 0;
}
Rect Text::GetBounds()
{
UpdateLayout();
return Node::GetBounds();
}
bool Text::IsItalic() const
{
return font_.italic;
@ -168,19 +160,19 @@ namespace easy2d
void Text::SetText(String const& text)
{
text_ = text;
dirty_layout_ = true;
UpdateLayout();
}
void Text::SetStyle(const TextStyle& style)
{
style_ = style;
dirty_layout_ = true;
UpdateLayout();
}
void Text::SetFont(const Font & font)
{
font_ = font;
dirty_layout_ = true;
UpdateLayout();
}
void Text::SetFontFamily(String const& family)
@ -188,7 +180,7 @@ namespace easy2d
if (font_.family != family)
{
font_.family = family;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -197,7 +189,7 @@ namespace easy2d
if (font_.size != size)
{
font_.size = size;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -206,7 +198,7 @@ namespace easy2d
if (font_.weight != weight)
{
font_.weight = weight;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -220,7 +212,7 @@ namespace easy2d
if (font_.italic != val)
{
font_.italic = val;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -229,7 +221,7 @@ namespace easy2d
if (style_.wrap != wrap)
{
style_.wrap = wrap;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -238,7 +230,7 @@ namespace easy2d
if (style_.wrap_width != wrap_width)
{
style_.wrap_width = std::max(wrap_width, 0.f);
dirty_layout_ = true;
UpdateLayout();
}
}
@ -247,7 +239,7 @@ namespace easy2d
if (style_.line_spacing != line_spacing)
{
style_.line_spacing = line_spacing;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -256,7 +248,7 @@ namespace easy2d
if (style_.alignment != align)
{
style_.alignment = align;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -265,7 +257,7 @@ namespace easy2d
if (style_.underline != underline)
{
style_.underline = underline;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -274,7 +266,7 @@ namespace easy2d
if (style_.strikethrough != strikethrough)
{
style_.strikethrough = strikethrough;
dirty_layout_ = true;
UpdateLayout();
}
}
@ -303,7 +295,6 @@ namespace easy2d
if (text_layout_)
{
auto graphics = devices::Graphics::Instance();
graphics->SetBrushOpacity(GetDisplayOpacity());
graphics->SetTextStyle(
style_.color,
style_.outline,
@ -315,17 +306,8 @@ namespace easy2d
}
}
void Text::Update(Duration const & dt)
{
UpdateLayout();
Node::Update(dt);
}
void Text::UpdateLayout()
{
if (!dirty_layout_)
return;
text_format_ = nullptr;
text_layout_ = nullptr;
@ -337,75 +319,22 @@ namespace easy2d
ThrowIfFailed(
graphics->CreateTextFormat(
text_format_,
font_
font_,
style_
)
);
if (style_.line_spacing == 0.f)
{
text_format_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
}
else
{
text_format_->SetLineSpacing(
DWRITE_LINE_SPACING_METHOD_UNIFORM,
style_.line_spacing,
style_.line_spacing * 0.8f
);
}
text_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(style_.alignment));
text_format_->SetWordWrapping(style_.wrap ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
if (style_.wrap)
{
Size layout_size;
ThrowIfFailed(
graphics->CreateTextLayout(
text_layout_,
layout_size,
text_,
text_format_,
style_.wrap_width
style_
)
);
DWRITE_TEXT_METRICS metrics;
text_layout_->GetMetrics(&metrics);
this->SetSize(metrics.layoutWidth, metrics.height);
}
else
{
ThrowIfFailed(
graphics->CreateTextLayout(
text_layout_,
text_,
text_format_,
0
)
);
DWRITE_TEXT_METRICS metrics;
text_layout_->GetMetrics(&metrics);
this->SetSize(metrics.width, metrics.height);
ThrowIfFailed(
graphics->CreateTextLayout(
text_layout_,
text_,
text_format_,
metrics.width
)
);
}
DWRITE_TEXT_RANGE range = { 0, static_cast<UINT32>(text_.length()) };
if (style_.underline)
{
text_layout_->SetUnderline(true, range);
}
if (style_.strikethrough)
{
text_layout_->SetStrikethrough(true, range);
}
dirty_layout_ = false;
this->SetSize(layout_size);
}
}

View File

@ -87,9 +87,6 @@ namespace easy2d
// 获取文本显示行数
int GetLineCount();
// 삿혤관鍋분
virtual Rect GetBounds() override;
// 是否是斜体
bool IsItalic() const;
@ -202,19 +199,15 @@ namespace easy2d
TextStyle const& style
);
// 斡횡匡俚
virtual void OnDraw() override;
protected:
virtual void Update(Duration const& dt) override;
void UpdateLayout();
protected:
String text_;
Font font_;
TextStyle style_;
bool dirty_layout_;
cpTextFormat text_format_;
cpTextLayout text_layout_;
};

View File

@ -24,7 +24,7 @@
namespace easy2d
{
ITextRenderer::ITextRenderer(ID2D1Factory* pD2DFactory, ID2D1HwndRenderTarget* pRT, ID2D1SolidColorBrush* pBrush)
ITextRenderer::ITextRenderer(ID2D1Factory* pD2DFactory, ID2D1RenderTarget* pRT, ID2D1SolidColorBrush* pBrush)
: cRefCount_(0)
, pD2DFactory_(pD2DFactory)
, pRT_(pRT)
@ -50,7 +50,7 @@ namespace easy2d
HRESULT ITextRenderer::Create(
ITextRenderer** ppTextRenderer,
ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT,
ID2D1RenderTarget* pRT,
ID2D1SolidColorBrush* pBrush)
{
*ppTextRenderer = new (std::nothrow) ITextRenderer(pD2DFactory, pRT, pBrush);

View File

@ -30,7 +30,7 @@ namespace easy2d
static HRESULT Create(
ITextRenderer** ppTextRenderer,
ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT,
ID2D1RenderTarget* pRT,
ID2D1SolidColorBrush* pBrush
);
@ -104,7 +104,7 @@ namespace easy2d
private:
ITextRenderer(
ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT,
ID2D1RenderTarget* pRT,
ID2D1SolidColorBrush* pBrush
);
@ -117,10 +117,10 @@ namespace easy2d
FLOAT fOutlineWidth;
BOOL bShowOutline_;
ID2D1Factory* pD2DFactory_;
ID2D1HwndRenderTarget* pRT_;
ID2D1RenderTarget* pRT_;
ID2D1SolidColorBrush* pBrush_;
ID2D1StrokeStyle* pCurrStrokeStyle_;
};
}
E2D_DECLARE_D2D_SMART_PTR(easy2d::ITextRenderer, spTextRenderer);
E2D_DECLARE_D2D_SMART_PTR(easy2d::ITextRenderer, cpTextRenderer);

View File

@ -65,4 +65,13 @@ namespace easy2d
pivot == other.pivot;
}
};
inline D2D1_MATRIX_3X2_F ConvertToD2DMatrix(math::Matrix const& matrix)
{
return D2D1_MATRIX_3X2_F{
matrix.m[0], matrix.m[1],
matrix.m[2], matrix.m[3],
matrix.m[4], matrix.m[5]
};
}
}

View File

@ -36,12 +36,16 @@ namespace easy2d
E2D_DECLARE_D2D_SMART_PTR(IWICImagingFactory, cpImagingFactory);
E2D_DECLARE_D2D_SMART_PTR(IDWriteFactory, cpWriteFactory);
E2D_DECLARE_D2D_SMART_PTR(ID2D1SolidColorBrush, cpSolidColorBrush);
E2D_DECLARE_D2D_SMART_PTR(ID2D1HwndRenderTarget, cpRenderTarget);
E2D_DECLARE_D2D_SMART_PTR(ID2D1RenderTarget, cpRenderTarget);
E2D_DECLARE_D2D_SMART_PTR(ID2D1HwndRenderTarget, cpHwndRenderTarget);
E2D_DECLARE_D2D_SMART_PTR(ID2D1BitmapRenderTarget, cpBitmapRenderTarget);
E2D_DECLARE_D2D_SMART_PTR(ID2D1StrokeStyle, cpStrokeStyle);
E2D_DECLARE_D2D_SMART_PTR(ID2D1Layer, cpLayer);
E2D_DECLARE_D2D_SMART_PTR(ID2D1Bitmap, cpBitmap);
E2D_DECLARE_D2D_SMART_PTR(ID2D1Geometry, cpGeometry);
E2D_DECLARE_D2D_SMART_PTR(ID2D1PathGeometry, cpPathGeometry);
E2D_DECLARE_D2D_SMART_PTR(ID2D1GeometrySink, cpGeometrySink);
E2D_DECLARE_D2D_SMART_PTR(IDWriteTextFormat, cpTextFormat);
E2D_DECLARE_D2D_SMART_PTR(IDWriteTextLayout, cpTextLayout);

View File

@ -22,6 +22,8 @@
#include "logs.h"
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
namespace easy2d
{

View File

@ -20,9 +20,6 @@
#pragma once
#include "macros.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#ifndef E2D_LOG
# ifdef E2D_DEBUG

View File

@ -27,7 +27,7 @@ namespace easy2d
protected:
Noncopyable() = default;
~Noncopyable() {};
virtual ~Noncopyable() {};
private:
Noncopyable(const Noncopyable&) = delete;

View File

@ -24,27 +24,17 @@
#include "logs.h"
#include "modules.h"
#include "Image.h"
#include "Transform.hpp"
namespace easy2d
{
namespace devices
{
namespace
{
inline D2D1_MATRIX_3X2_F ConvertToD2DMatrix(math::Matrix const& matrix)
{
return D2D1_MATRIX_3X2_F{
matrix.m[0], matrix.m[1],
matrix.m[2], matrix.m[3],
matrix.m[4], matrix.m[5]
};
}
}
GraphicsDevice::GraphicsDevice()
: fps_text_format_(nullptr)
, fps_text_layout_(nullptr)
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
, opacity_(1.f)
, initialized(false)
{
ZeroMemory(&d2d, sizeof(D2DResources));
@ -207,13 +197,21 @@ namespace easy2d
return hr;
}
HRESULT GraphicsDevice::CreateTextFormat(cpTextFormat& text_format, Font const& font) const
HRESULT GraphicsDevice::CreatePathGeometry(cpPathGeometry & geometry) const
{
if (!d2d.factory)
return E_UNEXPECTED;
return d2d.factory->CreatePathGeometry(&geometry);
}
HRESULT GraphicsDevice::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const
{
if (!d2d.write_factory)
return E_UNEXPECTED;
text_format = nullptr;
return d2d.write_factory->CreateTextFormat(
cpTextFormat text_format_tmp;
HRESULT hr = d2d.write_factory->CreateTextFormat(
font.family.c_str(),
nullptr,
DWRITE_FONT_WEIGHT(font.weight),
@ -221,27 +219,129 @@ namespace easy2d
DWRITE_FONT_STRETCH_NORMAL,
font.size,
L"",
&text_format
);;
&text_format_tmp
);
if (SUCCEEDED(hr))
{
if (text_style.line_spacing == 0.f)
{
text_format_tmp->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
}
else
{
text_format_tmp->SetLineSpacing(
DWRITE_LINE_SPACING_METHOD_UNIFORM,
text_style.line_spacing,
text_style.line_spacing * 0.8f
);
}
text_format_tmp->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(text_style.alignment));
text_format_tmp->SetWordWrapping(text_style.wrap ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
text_format = text_format_tmp;
}
return hr;
}
HRESULT GraphicsDevice::CreateTextLayout(cpTextLayout& text_layout, String const& text, cpTextFormat const& text_format, float wrap_width) const
HRESULT GraphicsDevice::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const
{
if (!d2d.write_factory)
return E_UNEXPECTED;
text_layout = nullptr;
HRESULT hr;
cpTextLayout text_layout_tmp;
UINT32 length = static_cast<UINT32>(text.length());
return d2d.write_factory->CreateTextLayout(
if (text_style.wrap)
{
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
wrap_width,
text_style.wrap_width,
0,
&text_layout
&text_layout_tmp
);
}
else
{
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
0,
0,
&text_layout_tmp
);
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (SUCCEEDED(hr))
{
text_layout_tmp = nullptr;
hr = d2d.write_factory->CreateTextLayout(
text.c_str(),
length,
text_format.Get(),
metrics.width,
0,
&text_layout_tmp
);
}
}
if (SUCCEEDED(hr))
{
DWRITE_TEXT_METRICS metrics;
text_layout_tmp->GetMetrics(&metrics);
if (text_style.wrap)
{
layout_size = Size(metrics.layoutWidth, metrics.height);
}
else
{
layout_size = Size(metrics.width, metrics.height);
}
DWRITE_TEXT_RANGE range = { 0, length };
if (text_style.underline)
{
text_layout_tmp->SetUnderline(true, range);
}
if (text_style.strikethrough)
{
text_layout_tmp->SetStrikethrough(true, range);
}
text_layout = text_layout_tmp;
}
return hr;
}
HRESULT GraphicsDevice::CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
)
{
if (!d2d.factory)
return E_UNEXPECTED;
cpTextRenderer text_renderer_tmp;
HRESULT hr = ITextRenderer::Create(
&text_renderer_tmp,
d2d.factory.Get(),
render_target.Get(),
brush.Get()
);
if (SUCCEEDED(hr))
text_renderer = text_renderer_tmp;
return hr;
}
HRESULT GraphicsDevice::CreateLayer(cpLayer& layer)
{
@ -267,7 +367,6 @@ namespace easy2d
HRESULT GraphicsDevice::DrawGeometry(
cpGeometry const& geometry,
Color const& border_color,
float opacity,
float stroke_width,
StrokeStyle stroke
)
@ -277,7 +376,6 @@ namespace easy2d
return E_UNEXPECTED;
d2d.solid_brush->SetColor(border_color);
d2d.solid_brush->SetOpacity(opacity);
d2d.render_target->DrawGeometry(
geometry.Get(),
d2d.solid_brush.Get(),
@ -287,6 +385,24 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::DrawImage(spImage const & image)
{
if (!d2d.render_target)
return E_UNEXPECTED;
if (!image->GetBitmap())
return S_OK;
d2d.render_target->DrawBitmap(
image->GetBitmap().Get(),
D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()),
opacity_,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
image->GetCropRect()
);
return S_OK;
}
cpStrokeStyle const& GraphicsDevice::GetStrokeStyle(StrokeStyle stroke) const
{
switch (stroke)
@ -304,27 +420,21 @@ namespace easy2d
return d2d.miter_stroke_style;
}
cpRenderTarget const & GraphicsDevice::GetRenderTarget() const
{
return d2d.render_target;
}
HRESULT GraphicsDevice::DrawImage(
spImage const& image,
float opacity,
const Rect & dest_rect,
const Rect & source_rect
HRESULT GraphicsDevice::DrawBitmap(
cpBitmap const& bitmap
)
{
if (!d2d.render_target)
return E_UNEXPECTED;
// Do not crop bitmap
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
d2d.render_target->DrawBitmap(
image->GetBitmap().Get(),
dest_rect,
opacity,
bitmap.Get(),
rect,
opacity_,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
source_rect
rect
);
return S_OK;
}
@ -389,6 +499,17 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::GetSize(Size & size)
{
if (!d2d.render_target)
return E_UNEXPECTED;
auto rtsize = d2d.render_target->GetSize();
size.width = rtsize.width;
size.height = rtsize.height;
return S_OK;
}
HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path)
{
if (d2d.imaging_factory == nullptr ||
@ -568,6 +689,15 @@ namespace easy2d
return hr;
}
HRESULT GraphicsDevice::CreateBitmapRenderTarget(cpBitmapRenderTarget & brt)
{
if (!d2d.render_target)
return E_UNEXPECTED;
brt = nullptr;
return d2d.render_target->CreateCompatibleRenderTarget(&brt);
}
HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height)
{
if (!d2d.render_target)
@ -586,11 +716,12 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::SetBrushOpacity(float opacity)
HRESULT GraphicsDevice::SetOpacity(float opacity)
{
if (!d2d.render_target)
return E_UNEXPECTED;
opacity_ = opacity;
d2d.solid_brush->SetOpacity(opacity);
return S_OK;
}
@ -631,7 +762,16 @@ namespace easy2d
if (!fps_text_format_)
{
ThrowIfFailed(
CreateTextFormat(fps_text_format_, Font{ L"", 20 })
d2d.write_factory->CreateTextFormat(
L"",
nullptr,
DWRITE_FONT_WEIGHT::DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
20,
L"",
&fps_text_format_
)
);
fps_text_format_->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
@ -646,8 +786,16 @@ namespace easy2d
last_render_time_ = time::Now();
render_times_ = 0;
fps_text_layout_ = nullptr;
ThrowIfFailed(
CreateTextLayout(fps_text_layout_, fps_text, fps_text_format_, 0)
d2d.write_factory->CreateTextLayout(
fps_text,
len,
fps_text_format_.Get(),
0,
0,
&fps_text_layout_
)
);
}

View File

@ -24,6 +24,7 @@
#include "Font.hpp"
#include "Resource.h"
#include "TextRenderer.h"
#include "TextStyle.hpp"
#include "../math/Matrix.hpp"
namespace easy2d
@ -37,9 +38,9 @@ namespace easy2d
cpFactory factory;
cpImagingFactory imaging_factory;
cpWriteFactory write_factory;
spTextRenderer text_renderer;
cpTextRenderer text_renderer;
cpSolidColorBrush solid_brush;
cpRenderTarget render_target;
cpHwndRenderTarget render_target;
cpStrokeStyle miter_stroke_style;
cpStrokeStyle bevel_stroke_style;
cpStrokeStyle round_stroke_style;
@ -76,18 +77,30 @@ namespace easy2d
const Size& size
) const;
HRESULT CreatePathGeometry(
cpPathGeometry& geometry
) const;
HRESULT CreateTextFormat(
cpTextFormat& text_format,
Font const& font
Font const& font,
TextStyle const& text_style
) const;
HRESULT CreateTextLayout(
cpTextLayout& text_layout,
Size& layout_size,
String const& text,
cpTextFormat const& text_format,
float wrap_width
TextStyle const& text_style
) const;
HRESULT CreateTextRenderer(
cpTextRenderer& text_renderer,
cpRenderTarget const& render_target,
cpSolidColorBrush const& brush
);
HRESULT CreateLayer(
cpLayer& layer
);
@ -96,17 +109,29 @@ namespace easy2d
cpSolidColorBrush& brush
) const;
HRESULT CreateBitmapFromFile(
cpBitmap& bitmap,
String const& file_path
);
HRESULT CreateBitmapFromResource(
cpBitmap& bitmap,
Resource const& res
);
HRESULT CreateBitmapRenderTarget(
cpBitmapRenderTarget& brt
);
cpStrokeStyle const& GetStrokeStyle(
StrokeStyle stroke
) const;
cpRenderTarget const& GetRenderTarget() const;
HRESULT SetTransform(
const math::Matrix& matrix
);
HRESULT SetBrushOpacity(
HRESULT SetOpacity(
float opacity
);
@ -121,16 +146,16 @@ namespace easy2d
HRESULT DrawGeometry(
cpGeometry const& geometry,
const Color& border_color,
float opacity,
float stroke_width,
StrokeStyle stroke = StrokeStyle::Miter
);
HRESULT DrawImage(
spImage const& image,
float opacity,
const Rect& dest_rect,
const Rect& source_rect
spImage const& image
);
HRESULT DrawBitmap(
cpBitmap const& bitmap
);
HRESULT DrawTextLayout(
@ -151,14 +176,8 @@ namespace easy2d
HRESULT PopLayer();
HRESULT CreateBitmapFromFile(
cpBitmap& bitmap,
String const& file_path
);
HRESULT CreateBitmapFromResource(
cpBitmap& bitmap,
Resource const& res
HRESULT GetSize(
Size& size
);
HRESULT Resize(
@ -175,6 +194,7 @@ namespace easy2d
protected:
bool initialized;
float opacity_;
D2DResources d2d;
D2D1_COLOR_F clear_color_;
cpTextFormat fps_text_format_;

View File

@ -220,6 +220,17 @@ namespace easy2d
return scale_y;
}
void WindowImpl::Poll()
{
static MSG msg = {};
while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
namespace
{
void GetContentScale(float* scale_x, float* scale_y)

View File

@ -24,8 +24,6 @@
namespace easy2d
{
class WindowImpl
: protected Noncopyable
{
@ -67,6 +65,8 @@ namespace easy2d
float GetContentScaleY() const;
void Poll();
protected:
WindowImpl();

View File

@ -177,9 +177,9 @@ namespace easy2d
float tx = math::Tan(angle_x);
float ty = math::Tan(angle_y);
return Matrix(
1.f, tx,
ty, 1.f,
-center.y * tx, -center.x * ty
1.f, -ty,
-tx, 1.f,
center.y * tx, center.x * ty
);
}
};