Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
WordWrappedTextImager.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_WordWrappedTextImager_h_
5#define _Stroika_Frameworks_Led_WordWrappedTextImager_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9/*
10@MODULE: WordWrappedTextImager
11@DESCRIPTION:
12 <p>This module implements the @'WordWrappedTextImager' class. This class provides a @'TextImager' which wraps
13 its text into rows, at word-boudaries, filling in as much of a row of text as possible, before wrapping (subject
14 to standard text UI rules).</p>
15 */
16
17#include "Stroika/Frameworks/Led/MultiRowTextImager.h"
18
19namespace Stroika::Frameworks::Led {
20
21/*
22 @CONFIGVAR: qDefaultLedSoftLineBreakChar
23 @DESCRIPTION: <p>This is the magic (sentinel) character that will appear in a Led text buffer to indicate
24 a soft line break. This is generated in MSWord (on Mac 5.1 and Windows WinWord 7.0) by the SHIFT-RETURN
25 key combination. I have no idea what value is stored internally in MSWord. This is the value WE will
26 store internally for Led. And so its somewhat subject to change - if I find THIS value conflicts with anything
27 useful.</p>
28 */
29#ifndef qDefaultLedSoftLineBreakChar
30#define qDefaultLedSoftLineBreakChar '\001'
31#endif
32
33 /**
34 * <p>Sentinel character used to mark a soft line-break.</p>
35 */
36 constexpr Led_tChar kSoftLineBreakChar = qDefaultLedSoftLineBreakChar;
37
38#if qStroika_Frameworks_Led_SupportGDI
39 /*
40 @CLASS: WordWrappedTextImager
41 @BASES: @'MultiRowTextImager'
42 @DESCRIPTION: <p>Implement the multirow calculations of a MultiRowTextImager using standard word-wrapping algorithms.
43 Though this will be commonly used for word-wrapping text editors, it isn't the only plasible way to break rows.
44 Some other sort of semantic content in the text might be taken as the thing which guides breaking rows.</p>
45 */
46 class WordWrappedTextImager : public MultiRowTextImager {
47 protected:
48 WordWrappedTextImager () = default;
49 virtual ~WordWrappedTextImager () = default;
50
51 private:
52 using inherited = MultiRowTextImager;
53
54 public:
55 /*
56 @METHOD: WordWrappedTextImager::GetLayoutMargins
57 @DESCRIPTION:
58 <p>NB: this routine must @'Ensure' that the *rhs and *lhs results be valid after a call (garbage in), and must ensure *rhs > *lhs,
59 assuming that both 'lhs' and 'rhs' are non-null pointers (either or both of these pointers can be null).</p>
60 <p>You must specify the wrap-width for each paragraph in a subclass. This routine can be overriden
61 to return a constant width - eg. width of the window, or a different per-paragraph width. But note,
62 it is the subclassers responsability to invalidate whatever caches need to be invalidated (typically in MutliRowTextImager)
63 when the layout width is changed. (nb: this changed in Led 2.2 - 970623-LGP).</p>
64 <p>It is because of the need to notify / invalidate caches that we don't provide a default implementation here.
65 The most likely default would be to wrap to the width of the window, and to successfully implement that strategy,
66 we would need to OVERRIDE SetWindowRect () here. But that would leave those <em>subclassing us</em> with the job
67 of circumventing that needless invalidation, and that seems ugly, and awkward. Better to keep the choice of specifying
68 this width in the same place as where we handle the invalidation.</p>
69 <P>NEW FOR LED 3.1d1. This routine used to be used AMBIGUOUSLY. Sometimes it was interpretted that the return values
70 were RELATIVE to the window rect, and sometimes it was interpretted that they took into account the window rect.
71 REWRITE THE ABOVE DOCS SO CLEARER ABOUT THIS CHOICE. FROM NOW ON, RETURNS VALUES RELATIVE TO LHS OF WINDOW RECT - LGP 2002-10-25
72 </p>
73 */
74 virtual void GetLayoutMargins (RowReference row, CoordinateType* lhs, CoordinateType* rhs) const = 0;
75
76 public:
77 virtual void FillCache (PartitionMarker* pm, PartitionElementCacheInfo& cacheInfo) override;
78
79 protected:
80 virtual void AdjustBestRowLength (size_t textStart, const Led_tChar* text, const Led_tChar* end, size_t* rowLength);
81
82 protected:
83 virtual bool ContainsMappedDisplayCharacters (const Led_tChar* text, size_t nTChars) const override;
84 virtual size_t RemoveMappedDisplayCharacters (Led_tChar* copyText, size_t nTChars) const override;
85 virtual void PatchWidthRemoveMappedDisplayCharacters (const Led_tChar* srcText, DistanceType* distanceResults, size_t nTChars) const override;
86
87 /*
88 * Word wrapping helpers.
89 */
90 private:
91 nonvirtual size_t FindWrapPointForMeasuredText (const Led_tChar* text, size_t length, DistanceType wrapWidth,
92 size_t offsetToMarkerCoords, const DistanceType* widthsVector, size_t startSoFar);
93 nonvirtual size_t TryToFindWrapPointForMeasuredText1 (const Led_tChar* text, size_t length, DistanceType wrapWidth,
94 size_t offsetToMarkerCoords, const DistanceType* widthsVector,
95 size_t startSoFar, size_t searchStart, size_t wrapLength);
96 nonvirtual size_t FindWrapPointForOneLongWordForMeasuredText (const Led_tChar* text, size_t length, DistanceType wrapWidth,
97 size_t offsetToMarkerCoords, const DistanceType* widthsVector, size_t startSoFar);
98 };
99
100 /*
101 @CLASS: TrivialWordWrappedImager<TEXTSTORE, IMAGER>
102 @BASES: @'TrivialImager<TEXTSTORE,IMAGER>'
103 @DESCRIPTION: <p>Handy little class to image text directly. Like Mac "TextBox" or Win32 "DrawText", in that
104 you can directly use it (no setup), and it images and wraps the text into the given box.</p>
105 <p>The usuage can be as simple as:
106 <code>
107 void SomeAppDrawCall (Tablet* t, const Led_Rect& r, bool printing)
108 {
109 TrivialWordWrappedImager<ChunkedArrayTextStore> (t, r, LED_TCHAR_OF ("Hi mom")).Draw ();
110 }
111 </code>
112 </p>
113 * @see @'TrivialImager<TEXTSTORE,IMAGER>', and @'TrivialImager_Interactor<TEXTSTORE,IMAGER>'.</p>
114 */
115 template <typename TEXTSTORE, typename IMAGER = WordWrappedTextImager>
116 class TrivialWordWrappedImager : public TrivialImager<TEXTSTORE, IMAGER> {
117 protected:
118 TrivialWordWrappedImager (Tablet* t);
119
120 public:
121 TrivialWordWrappedImager (Tablet* t, Led_Rect bounds, const Led_tString& initialText = LED_TCHAR_OF (""));
122
123 public:
124 virtual void GetLayoutMargins (MultiRowTextImager::RowReference row, CoordinateType* lhs, CoordinateType* rhs) const override;
125 nonvirtual DistanceType GetHeight () const;
126 };
127#endif
128
129}
130
131/*
132 ********************************************************************************
133 ***************************** Implementation Details ***************************
134 ********************************************************************************
135 */
136#include "WordWrappedTextImager.inl"
137
138#endif /*_Stroika_Frameworks_Led_WordWrappedTextImager_h_*/