From d86a71f79afe0e4dac768f61d6bff690567aca5b Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 24 May 2020 01:40:02 +0800 Subject: ... --- src/win/graph/direct/CMakeLists.txt | 34 ++++----- src/win/graph/direct/TextLayout.cpp | 137 +++++++++++++++++++++++++++++++++++ src/win/graph/direct/brush.cpp | 8 +- src/win/graph/direct/factory.cpp | 16 ++-- src/win/graph/direct/font.cpp | 8 +- src/win/graph/direct/geometry.cpp | 8 +- src/win/graph/direct/painter.cpp | 16 ++-- src/win/graph/direct/resource.cpp | 4 +- src/win/graph/direct/text_layout.cpp | 137 ----------------------------------- 9 files changed, 184 insertions(+), 184 deletions(-) create mode 100644 src/win/graph/direct/TextLayout.cpp delete mode 100644 src/win/graph/direct/text_layout.cpp (limited to 'src/win/graph') diff --git a/src/win/graph/direct/CMakeLists.txt b/src/win/graph/direct/CMakeLists.txt index 492f6749..5505b0b5 100644 --- a/src/win/graph/direct/CMakeLists.txt +++ b/src/win/graph/direct/CMakeLists.txt @@ -1,25 +1,25 @@ set(CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/win/graph/direct) add_library(cru_win_graph_direct STATIC - brush.cpp - font.cpp - geometry.cpp - factory.cpp - painter.cpp - resource.cpp - text_layout.cpp + Brush.cpp + Font.cpp + Geometry.cpp + Factory.cpp + Painter.cpp + Resource.cpp + TextLayout.cpp ) target_sources(cru_win_graph_direct PUBLIC - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/brush.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/com_resource.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/convert_util.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/exception.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/font.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/geometry.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/factory.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/painter.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/resource.hpp - ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/text_layout.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Brush.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/ComResource.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/ConvertUtil.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Exception.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Font.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Geometry.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Factory.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Painter.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/Resource.hpp + ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/TextLayout.hpp ) target_link_libraries(cru_win_graph_direct PUBLIC D3D11 D2d1 DWrite) target_link_libraries(cru_win_graph_direct PUBLIC cru_win_base cru_platform_graph) diff --git a/src/win/graph/direct/TextLayout.cpp b/src/win/graph/direct/TextLayout.cpp new file mode 100644 index 00000000..16db77f0 --- /dev/null +++ b/src/win/graph/direct/TextLayout.cpp @@ -0,0 +1,137 @@ +#include "cru/win/graph/direct/TextLayout.hpp" + +#include "cru/common/Logger.hpp" +#include "cru/platform/Check.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Factory.hpp" +#include "cru/win/graph/direct/Font.hpp" +#include "cru/win/String.hpp" + +#include + +namespace cru::platform::graph::win::direct { +using cru::platform::win::IndexUtf16ToUtf8; +using cru::platform::win::IndexUtf8ToUtf16; + +DWriteTextLayout::DWriteTextLayout(DirectGraphFactory* factory, + std::shared_ptr font, + std::string text) + : DirectGraphResource(factory), text_(std::move(text)) { + Expects(font); + font_ = CheckPlatform(font, GetPlatformId()); + + w_text_ = cru::platform::win::ToUtf16String(text_); + + ThrowIfFailed(factory->GetDWriteFactory()->CreateTextLayout( + w_text_.c_str(), static_cast(w_text_.size()), + font_->GetComInterface(), max_width_, max_height_, &text_layout_)); +} + +DWriteTextLayout::~DWriteTextLayout() = default; + +std::string DWriteTextLayout::GetText() { return text_; } + +void DWriteTextLayout::SetText(std::string new_text) { + text_.swap(new_text); + w_text_ = cru::platform::win::ToUtf16String(text_); + ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout( + w_text_.c_str(), static_cast(w_text_.size()), + font_->GetComInterface(), max_width_, max_height_, &text_layout_)); +} + +std::shared_ptr DWriteTextLayout::GetFont() { + return std::dynamic_pointer_cast(font_); +} + +void DWriteTextLayout::SetFont(std::shared_ptr font) { + font_ = CheckPlatform(font, GetPlatformId()); + ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout( + w_text_.c_str(), static_cast(w_text_.size()), + font_->GetComInterface(), max_width_, max_height_, &text_layout_)); +} + +void DWriteTextLayout::SetMaxWidth(float max_width) { + max_width_ = max_width; + ThrowIfFailed(text_layout_->SetMaxWidth(max_width_)); +} + +void DWriteTextLayout::SetMaxHeight(float max_height) { + max_height_ = max_height; + ThrowIfFailed(text_layout_->SetMaxHeight(max_height_)); +} + +Rect DWriteTextLayout::GetTextBounds() { + DWRITE_TEXT_METRICS metrics; + ThrowIfFailed(text_layout_->GetMetrics(&metrics)); + return Rect{metrics.left, metrics.top, metrics.width, metrics.height}; +} + +std::vector DWriteTextLayout::TextRangeRect( + const TextRange& text_range_arg) { + if (text_range_arg.count == 0) { + return {}; + } + const auto text_range = text_range_arg.Normalize(); + + // TODO: This can be faster with one iteration. + const int start_index = + IndexUtf8ToUtf16(text_, static_cast(text_range.position), w_text_); + const int end_index = IndexUtf8ToUtf16( + text_, static_cast(text_range.position + text_range.count), w_text_); + + DWRITE_TEXT_METRICS text_metrics; + ThrowIfFailed(text_layout_->GetMetrics(&text_metrics)); + const auto metrics_count = + text_metrics.lineCount * text_metrics.maxBidiReorderingDepth; + + std::vector hit_test_metrics(metrics_count); + UINT32 actual_count; + ThrowIfFailed(text_layout_->HitTestTextRange( + static_cast(start_index), + static_cast(end_index - start_index), 0, 0, + hit_test_metrics.data(), metrics_count, &actual_count)); + + hit_test_metrics.erase(hit_test_metrics.cbegin() + actual_count, + hit_test_metrics.cend()); + + std::vector result; + result.reserve(actual_count); + + for (const auto& metrics : hit_test_metrics) { + result.push_back( + Rect{metrics.left, metrics.top, metrics.width, metrics.height}); + } + + return result; +} + +Point DWriteTextLayout::TextSinglePoint(gsl::index position, bool trailing) { + const auto index = + IndexUtf8ToUtf16(text_, static_cast(position), w_text_); + + DWRITE_HIT_TEST_METRICS metrics; + FLOAT left; + FLOAT top; + ThrowIfFailed(text_layout_->HitTestTextPosition(static_cast(index), + static_cast(trailing), + &left, &top, &metrics)); + return Point{left, top}; +} + +TextHitTestResult DWriteTextLayout::HitTest(const Point& point) { + BOOL trailing; + BOOL inside; + DWRITE_HIT_TEST_METRICS metrics; + + ThrowIfFailed(text_layout_->HitTestPoint(point.x, point.y, &trailing, &inside, + &metrics)); + + const auto index = + IndexUtf16ToUtf8(w_text_, static_cast(metrics.textPosition), text_); + TextHitTestResult result; + result.position = index; + result.trailing = trailing != 0; + result.insideText = inside != 0; + return result; +} +} // namespace cru::platform::graph::win::direct diff --git a/src/win/graph/direct/brush.cpp b/src/win/graph/direct/brush.cpp index 329ce509..2b9d4ac3 100644 --- a/src/win/graph/direct/brush.cpp +++ b/src/win/graph/direct/brush.cpp @@ -1,8 +1,8 @@ -#include "cru/win/graph/direct/brush.hpp" +#include "cru/win/graph/direct/Brush.hpp" -#include "cru/win/graph/direct/convert_util.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/factory.hpp" +#include "cru/win/graph/direct/ConvertUtil.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Factory.hpp" namespace cru::platform::graph::win::direct { D2DSolidColorBrush::D2DSolidColorBrush(DirectGraphFactory* factory) diff --git a/src/win/graph/direct/factory.cpp b/src/win/graph/direct/factory.cpp index 0f4739ee..d9213994 100644 --- a/src/win/graph/direct/factory.cpp +++ b/src/win/graph/direct/factory.cpp @@ -1,11 +1,11 @@ -#include "cru/win/graph/direct/factory.hpp" - -#include "cru/common/logger.hpp" -#include "cru/win/graph/direct/brush.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/font.hpp" -#include "cru/win/graph/direct/geometry.hpp" -#include "cru/win/graph/direct/text_layout.hpp" +#include "cru/win/graph/direct/Factory.hpp" + +#include "cru/common/Logger.hpp" +#include "cru/win/graph/direct/Brush.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Font.hpp" +#include "cru/win/graph/direct/Geometry.hpp" +#include "cru/win/graph/direct/TextLayout.hpp" #include #include diff --git a/src/win/graph/direct/font.cpp b/src/win/graph/direct/font.cpp index 6d50fafe..edbbc59d 100644 --- a/src/win/graph/direct/font.cpp +++ b/src/win/graph/direct/font.cpp @@ -1,8 +1,8 @@ -#include "cru/win/graph/direct/font.hpp" +#include "cru/win/graph/direct/Font.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/factory.hpp" -#include "cru/win/string.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Factory.hpp" +#include "cru/win/String.hpp" #include #include diff --git a/src/win/graph/direct/geometry.cpp b/src/win/graph/direct/geometry.cpp index 57b7f237..e77b4749 100644 --- a/src/win/graph/direct/geometry.cpp +++ b/src/win/graph/direct/geometry.cpp @@ -1,8 +1,8 @@ -#include "cru/win/graph/direct/geometry.hpp" +#include "cru/win/graph/direct/Geometry.hpp" -#include "cru/win/graph/direct/convert_util.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/factory.hpp" +#include "cru/win/graph/direct/ConvertUtil.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Factory.hpp" namespace cru::platform::graph::win::direct { D2DGeometryBuilder::D2DGeometryBuilder(DirectGraphFactory* factory) diff --git a/src/win/graph/direct/painter.cpp b/src/win/graph/direct/painter.cpp index df0075e0..3ffb5208 100644 --- a/src/win/graph/direct/painter.cpp +++ b/src/win/graph/direct/painter.cpp @@ -1,11 +1,11 @@ -#include "cru/win/graph/direct/painter.hpp" - -#include "cru/platform/check.hpp" -#include "cru/win/graph/direct/brush.hpp" -#include "cru/win/graph/direct/convert_util.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/geometry.hpp" -#include "cru/win/graph/direct/text_layout.hpp" +#include "cru/win/graph/direct/Painter.hpp" + +#include "cru/platform/Check.hpp" +#include "cru/win/graph/direct/Brush.hpp" +#include "cru/win/graph/direct/ConvertUtil.hpp" +#include "cru/win/graph/direct/Exception.hpp" +#include "cru/win/graph/direct/Geometry.hpp" +#include "cru/win/graph/direct/TextLayout.hpp" #include diff --git a/src/win/graph/direct/resource.cpp b/src/win/graph/direct/resource.cpp index c2be27ed..772bb74b 100644 --- a/src/win/graph/direct/resource.cpp +++ b/src/win/graph/direct/resource.cpp @@ -1,6 +1,6 @@ -#include "cru/win/graph/direct/resource.hpp" +#include "cru/win/graph/direct/Resource.hpp" -#include "cru/win/graph/direct/factory.hpp" +#include "cru/win/graph/direct/Factory.hpp" namespace cru::platform::graph::win::direct { DirectGraphResource::DirectGraphResource(DirectGraphFactory* factory) diff --git a/src/win/graph/direct/text_layout.cpp b/src/win/graph/direct/text_layout.cpp deleted file mode 100644 index 7b8d2ab0..00000000 --- a/src/win/graph/direct/text_layout.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "cru/win/graph/direct/text_layout.hpp" - -#include "cru/common/logger.hpp" -#include "cru/platform/check.hpp" -#include "cru/win/graph/direct/exception.hpp" -#include "cru/win/graph/direct/factory.hpp" -#include "cru/win/graph/direct/font.hpp" -#include "cru/win/string.hpp" - -#include - -namespace cru::platform::graph::win::direct { -using cru::platform::win::IndexUtf16ToUtf8; -using cru::platform::win::IndexUtf8ToUtf16; - -DWriteTextLayout::DWriteTextLayout(DirectGraphFactory* factory, - std::shared_ptr font, - std::string text) - : DirectGraphResource(factory), text_(std::move(text)) { - Expects(font); - font_ = CheckPlatform(font, GetPlatformId()); - - w_text_ = cru::platform::win::ToUtf16String(text_); - - ThrowIfFailed(factory->GetDWriteFactory()->CreateTextLayout( - w_text_.c_str(), static_cast(w_text_.size()), - font_->GetComInterface(), max_width_, max_height_, &text_layout_)); -} - -DWriteTextLayout::~DWriteTextLayout() = default; - -std::string DWriteTextLayout::GetText() { return text_; } - -void DWriteTextLayout::SetText(std::string new_text) { - text_.swap(new_text); - w_text_ = cru::platform::win::ToUtf16String(text_); - ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout( - w_text_.c_str(), static_cast(w_text_.size()), - font_->GetComInterface(), max_width_, max_height_, &text_layout_)); -} - -std::shared_ptr DWriteTextLayout::GetFont() { - return std::dynamic_pointer_cast(font_); -} - -void DWriteTextLayout::SetFont(std::shared_ptr font) { - font_ = CheckPlatform(font, GetPlatformId()); - ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout( - w_text_.c_str(), static_cast(w_text_.size()), - font_->GetComInterface(), max_width_, max_height_, &text_layout_)); -} - -void DWriteTextLayout::SetMaxWidth(float max_width) { - max_width_ = max_width; - ThrowIfFailed(text_layout_->SetMaxWidth(max_width_)); -} - -void DWriteTextLayout::SetMaxHeight(float max_height) { - max_height_ = max_height; - ThrowIfFailed(text_layout_->SetMaxHeight(max_height_)); -} - -Rect DWriteTextLayout::GetTextBounds() { - DWRITE_TEXT_METRICS metrics; - ThrowIfFailed(text_layout_->GetMetrics(&metrics)); - return Rect{metrics.left, metrics.top, metrics.width, metrics.height}; -} - -std::vector DWriteTextLayout::TextRangeRect( - const TextRange& text_range_arg) { - if (text_range_arg.count == 0) { - return {}; - } - const auto text_range = text_range_arg.Normalize(); - - // TODO: This can be faster with one iteration. - const int start_index = - IndexUtf8ToUtf16(text_, static_cast(text_range.position), w_text_); - const int end_index = IndexUtf8ToUtf16( - text_, static_cast(text_range.position + text_range.count), w_text_); - - DWRITE_TEXT_METRICS text_metrics; - ThrowIfFailed(text_layout_->GetMetrics(&text_metrics)); - const auto metrics_count = - text_metrics.lineCount * text_metrics.maxBidiReorderingDepth; - - std::vector hit_test_metrics(metrics_count); - UINT32 actual_count; - ThrowIfFailed(text_layout_->HitTestTextRange( - static_cast(start_index), - static_cast(end_index - start_index), 0, 0, - hit_test_metrics.data(), metrics_count, &actual_count)); - - hit_test_metrics.erase(hit_test_metrics.cbegin() + actual_count, - hit_test_metrics.cend()); - - std::vector result; - result.reserve(actual_count); - - for (const auto& metrics : hit_test_metrics) { - result.push_back( - Rect{metrics.left, metrics.top, metrics.width, metrics.height}); - } - - return result; -} - -Point DWriteTextLayout::TextSinglePoint(gsl::index position, bool trailing) { - const auto index = - IndexUtf8ToUtf16(text_, static_cast(position), w_text_); - - DWRITE_HIT_TEST_METRICS metrics; - FLOAT left; - FLOAT top; - ThrowIfFailed(text_layout_->HitTestTextPosition(static_cast(index), - static_cast(trailing), - &left, &top, &metrics)); - return Point{left, top}; -} - -TextHitTestResult DWriteTextLayout::HitTest(const Point& point) { - BOOL trailing; - BOOL inside; - DWRITE_HIT_TEST_METRICS metrics; - - ThrowIfFailed(text_layout_->HitTestPoint(point.x, point.y, &trailing, &inside, - &metrics)); - - const auto index = - IndexUtf16ToUtf8(w_text_, static_cast(metrics.textPosition), text_); - TextHitTestResult result; - result.position = index; - result.trailing = trailing != 0; - result.insideText = inside != 0; - return result; -} -} // namespace cru::platform::graph::win::direct -- cgit v1.2.3