TextLayout.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include "AK/Forward.h"
  9. #include "LibGfx/Forward.h"
  10. #include <AK/String.h>
  11. #include <AK/Utf32View.h>
  12. #include <AK/Utf8View.h>
  13. #include <AK/Vector.h>
  14. #include <LibGfx/Font/Font.h>
  15. #include <LibGfx/Rect.h>
  16. #include <LibGfx/TextElision.h>
  17. #include <LibGfx/TextWrapping.h>
  18. namespace Gfx {
  19. enum class FitWithinRect {
  20. Yes,
  21. No
  22. };
  23. // FIXME: This currently isn't an ideal way of doing things; ideally, TextLayout
  24. // would be doing the rendering by painting individual glyphs. However, this
  25. // would regress our Unicode bidirectional text support. Therefore, fixing this
  26. // requires:
  27. // - Moving the bidirectional algorithm either here, or some place TextLayout
  28. // can access;
  29. // - Making TextLayout render the given text into something like a Vector<Line>
  30. // where:
  31. // using Line = Vector<DirectionalRun>;
  32. // struct DirectionalRun {
  33. // Utf32View glyphs;
  34. // Vector<int> advance;
  35. // TextDirection direction;
  36. // };
  37. // - Either;
  38. // a) Making TextLayout output these Lines directly using a given Painter, or
  39. // b) Taking the Lines from TextLayout and painting each glyph.
  40. class TextLayout {
  41. public:
  42. TextLayout(Gfx::Font const* font, Utf8View const& text, IntRect const& rect)
  43. : m_font(font)
  44. , m_text(text)
  45. , m_rect(rect)
  46. {
  47. }
  48. Font const& font() const { return *m_font; }
  49. void set_font(Font const* font) { m_font = font; }
  50. Utf8View const& text() const { return m_text; }
  51. void set_text(Utf8View const& text) { m_text = text; }
  52. IntRect const& rect() const { return m_rect; }
  53. void set_rect(IntRect const& rect) { m_rect = rect; }
  54. Vector<String, 32> lines(TextElision elision, TextWrapping wrapping, int line_spacing) const
  55. {
  56. return wrap_lines(elision, wrapping, line_spacing, FitWithinRect::Yes);
  57. }
  58. IntRect bounding_rect(TextWrapping wrapping, int line_spacing) const;
  59. private:
  60. Vector<String, 32> wrap_lines(TextElision, TextWrapping, int line_spacing, FitWithinRect) const;
  61. String elide_text_from_right(Utf8View, bool force_elision) const;
  62. Font const* m_font;
  63. Utf8View m_text;
  64. IntRect m_rect;
  65. };
  66. }