aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-06-08 16:25:33 +0800
committercrupest <crupest@outlook.com>2022-06-08 16:25:33 +0800
commit47f143ca8ee8eefe48906e410eb25e564d06f49b (patch)
tree0ab6316bb91876a6abec27f4fb80bafb580939c8 /src/platform
parentb922e4271166c9edf034109a42d403a147f0720d (diff)
downloadcru-47f143ca8ee8eefe48906e410eb25e564d06f49b.tar.gz
cru-47f143ca8ee8eefe48906e410eb25e564d06f49b.tar.bz2
cru-47f143ca8ee8eefe48906e410eb25e564d06f49b.zip
...
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/graphics/cairo/CMakeLists.txt3
-rw-r--r--src/platform/graphics/cairo/PangoTextLayout.cpp73
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