diff options
author | crupest <crupest@outlook.com> | 2022-06-08 16:25:33 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-06-08 16:25:33 +0800 |
commit | 47f143ca8ee8eefe48906e410eb25e564d06f49b (patch) | |
tree | 0ab6316bb91876a6abec27f4fb80bafb580939c8 /src/platform | |
parent | b922e4271166c9edf034109a42d403a147f0720d (diff) | |
download | cru-47f143ca8ee8eefe48906e410eb25e564d06f49b.tar.gz cru-47f143ca8ee8eefe48906e410eb25e564d06f49b.tar.bz2 cru-47f143ca8ee8eefe48906e410eb25e564d06f49b.zip |
...
Diffstat (limited to 'src/platform')
-rw-r--r-- | src/platform/graphics/cairo/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/platform/graphics/cairo/PangoTextLayout.cpp | 73 |
2 files changed, 75 insertions, 1 deletions
diff --git a/src/platform/graphics/cairo/CMakeLists.txt b/src/platform/graphics/cairo/CMakeLists.txt index 9a21ab87..606b0075 100644 --- a/src/platform/graphics/cairo/CMakeLists.txt +++ b/src/platform/graphics/cairo/CMakeLists.txt @@ -4,6 +4,7 @@ if (UNIX) message("${LIB_ARCH_DIR}") find_library(LIB_CAIRO cairo REQUIRED) + find_library(LIB_GOBJECT NAMES gobject gobject-2.0 REQUIRED) find_library(LIB_PANGO NAMES pango pango-1.0 REQUIRED) find_path(GLIB_HEADER_DIR NAMES glib.h PATH_SUFFIXES glib glib-2.0 REQUIRED) find_path(GLIBCONFIG_HEADER_DIR NAMES glibconfig.h HINTS ${LIB_ARCH_DIR} PATH_SUFFIXES glib glib/include glib-2.0 glib-2.0/include REQUIRED) @@ -20,6 +21,6 @@ if (UNIX) PangoTextLayout.cpp ) target_compile_definitions(CruPlatformGraphicsCairo PRIVATE CRU_PLATFORM_GRAPHICS_CAIRO_EXPORT_API) - target_link_libraries(CruPlatformGraphicsCairo PUBLIC CruPlatformGraphics PUBLIC ${LIB_CAIRO} ${LIB_PANGO}) + target_link_libraries(CruPlatformGraphicsCairo PUBLIC CruPlatformGraphics PUBLIC ${LIB_GOBJECT} ${LIB_CAIRO} ${LIB_PANGO}) target_include_directories(CruPlatformGraphicsCairo PUBLIC ${GLIB_HEADER_DIR} ${GLIBCONFIG_HEADER_DIR} ${HARFBUZZ_HEADER_DIR} ${PANGO_HEADER_DIR}) endif() diff --git a/src/platform/graphics/cairo/PangoTextLayout.cpp b/src/platform/graphics/cairo/PangoTextLayout.cpp index 9f43af11..25e84707 100644 --- a/src/platform/graphics/cairo/PangoTextLayout.cpp +++ b/src/platform/graphics/cairo/PangoTextLayout.cpp @@ -1,6 +1,8 @@ #include "cru/platform/graphics/cairo/PangoTextLayout.h" #include "cru/common/StringUtil.h" #include "cru/platform/Check.h" +#include "cru/platform/GraphicsBase.h" +#include "cru/platform/graphics/Base.h" #include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" #include "cru/platform/graphics/cairo/PangoFont.h" @@ -86,4 +88,75 @@ Index PangoTextLayout::FromUtf16IndexToUtf8Index(Index index) { return iter.GetPosition(); } +Rect PangoTextLayout::GetTextBounds(bool includingTrailingSpace) { + PangoRectangle rectangle; + pango_layout_get_extents(pango_layout_, nullptr, &rectangle); + return Rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); +} + +std::vector<Rect> PangoTextLayout::TextRangeRect(const TextRange& text_range) { + auto tr = text_range.Normalize(); + auto utf8_start_index = FromUtf16IndexToUtf8Index(tr.GetStart()); + auto utf8_end_index = FromUtf16IndexToUtf8Index(tr.GetEnd()); + + int start_line_index, end_line_index, start_x_pos, end_x_pos; + pango_layout_index_to_line_x(pango_layout_, utf8_start_index, false, + &start_line_index, &start_x_pos); + pango_layout_index_to_line_x(pango_layout_, utf8_end_index, false, + &end_line_index, &end_x_pos); + + if (start_line_index == end_line_index) { + auto line = pango_layout_get_line(pango_layout_, start_line_index); + PangoRectangle rectangle; + pango_layout_line_get_extents(line, nullptr, &rectangle); + return {Rect(rectangle.x + start_x_pos, rectangle.y, + end_x_pos - start_x_pos, rectangle.height)}; + } else { + std::vector<Rect> result; + + PangoRectangle rectangle; + + auto start_line = pango_layout_get_line(pango_layout_, start_line_index); + pango_layout_line_get_extents(start_line, nullptr, &rectangle); + result.push_back(Rect(rectangle.x + start_x_pos, rectangle.y, + rectangle.width - start_x_pos, rectangle.height)); + + for (int line_index = start_line_index + 1; line_index < end_line_index; + line_index++) { + auto line = pango_layout_get_line(pango_layout_, line_index); + pango_layout_line_get_extents(line, nullptr, &rectangle); + result.push_back( + Rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height)); + } + + auto end_line = pango_layout_get_line(pango_layout_, end_line_index); + pango_layout_line_get_extents(end_line, nullptr, &rectangle); + result.push_back( + Rect(rectangle.x, rectangle.y, end_x_pos, rectangle.height)); + + return result; + } +} + +Rect PangoTextLayout::TextSinglePoint(Index position, bool trailing) { + auto utf8_index = FromUtf16IndexToUtf8Index(position); + int line_index, x_pos; + pango_layout_index_to_line_x(pango_layout_, utf8_index, trailing, &line_index, + &x_pos); + + auto line = pango_layout_get_line(pango_layout_, line_index); + PangoRectangle rectangle; + pango_layout_line_get_extents(line, nullptr, &rectangle); + + return Rect(rectangle.x + x_pos, rectangle.y, 0, rectangle.height); +} + +TextHitTestResult PangoTextLayout::HitTest(const Point& point) { + int index, trailing; + auto inside_text = pango_layout_xy_to_index(pango_layout_, point.x, point.y, + &index, &trailing); + return TextHitTestResult{FromUtf8IndexToUtf16Index(index), trailing != 0, + inside_text != 0}; +} + } // namespace cru::platform::graphics::cairo |