Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
PartitioningTextImager.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
5namespace Stroika::Frameworks::Led {
6
7 /*
8 ********************************************************************************
9 ************************** Partition::PartitionMarker **************************
10 ********************************************************************************
11 */
12 inline Partition::PartitionMarker::PartitionMarker (Partition& owner, PartitionMarker* insertAfterMe)
13 : inherited ()
14 , fPrevious (insertAfterMe)
15 , fNext (insertAfterMe == nullptr ? nullptr : insertAfterMe->fNext)
16 {
17 if (insertAfterMe == nullptr) {
18 owner.fPartitionMarkerFirst = this;
19 }
20 else {
21 Assert (insertAfterMe->fNext == fNext); // I just updated MY next to be what HIS next used to be
22 insertAfterMe->fNext = this; // Now HIS next should be me since I'm AFTER him
23 PartitionMarker* following = fNext;
24 if (following != nullptr) {
25 Assert (following->fPrevious == insertAfterMe); // thats who he USED to point to
26 following->fPrevious = this;
27 }
28 }
29 if (fNext == nullptr) {
30 owner.fPartitionMarkerLast = this;
31 }
32 }
33 /*
34 @METHOD: Partition::PartitionMarker::GetOwner ()
35 @DESCRIPTION: <p>Return a reference to the partition markers owner. Note - since this returns a refernece,
36 we assert that the owner is non-null. Also note that this routine intentionally hides the base-class
37 @'Marker::GetOwner()' method. Use that if the owner could be nullptr. But note that the owner will never
38 be nullptr if the marker has been added (and not yet removed) from the TextStore.</p>
39 */
40 inline Partition& Partition::PartitionMarker::GetOwner () const
41 {
42 EnsureNotNull (inherited::GetOwner ());
43 EnsureMember (inherited::GetOwner (), Partition);
44 return *(dynamic_cast<Partition*> (inherited::GetOwner ()));
45 }
46 inline Partition::PartitionMarker* Partition::PartitionMarker::GetPrevious () const
47 {
48 return fPrevious;
49 }
50 inline Partition::PartitionMarker* Partition::PartitionMarker::GetNext () const
51 {
52 return fNext;
53 }
54 inline void Partition::Invariant () const
55 {
56#if qStroika_Foundation_Debug_AssertionsChecked and qStroika_Frameworks_Led_HeavyDebugging
57 Invariant_ ();
58#endif
59 }
60
61 // class Partition;
62 /*
63 @METHOD: Partition::GetEnd
64 @DESCRIPTION: <p>Return the associated @'TextStore::GetEnd' ().</p>
65 */
66 inline size_t Partition::GetEnd () const
67 {
68 return (fTextStore.GetEnd ());
69 }
70 /*
71 @METHOD: Partition::CopyOut
72 @DESCRIPTION: <p>Calls the associated @'TextStore::CopyOut' ().</p>
73 */
74 inline void Partition::CopyOut (size_t from, size_t byteCount, Led_tChar* buffer) const
75 {
76 GetTextStore ().CopyOut (from, byteCount, buffer);
77 }
78 inline Partition::PartitionMarker* Partition::GetFirstPartitionMarker () const
79 {
80 RequireNotNull (fPartitionMarkerFirst);
81 return fPartitionMarkerFirst;
82 }
83 inline Partition::PartitionMarker* Partition::GetLastPartitionMarker () const
84 {
85 RequireNotNull (fPartitionMarkerLast);
86 return fPartitionMarkerLast;
87 }
88 /*
89 @METHOD: Partition::AddPartitionWatcher
90 @DESCRIPTION: <p>Associate the given @'Partition::PartitionWatcher' with this Partition. Use
91 @'Partition::RemovePartitionWatcher' to remove the callback / association.</p>
92 */
93 inline void Partition::AddPartitionWatcher (PartitionWatcher* watcher)
94 {
95 fPartitionWatchers.push_back (watcher);
96 }
97 /*
98 @METHOD: Partition::RemovePartitionWatcher
99 @DESCRIPTION: <p>Remove the given @'Partition::PartitionWatcher' from being associated with this @'Partition'.
100 Balances calls from @'Partition::AddPartitionWatcher'.</p>
101 */
102 inline void Partition::RemovePartitionWatcher (PartitionWatcher* watcher)
103 {
104 vector<PartitionWatcher*>::iterator it = find (fPartitionWatchers.begin (), fPartitionWatchers.end (), watcher);
105 Assert (it != fPartitionWatchers.end ()); // Be forgiving about not finding in list, in light of exception handling - but give warning...
106 if (it != fPartitionWatchers.end ()) {
107 fPartitionWatchers.erase (it);
108 }
109 }
110 inline void Partition::DoAboutToSplitCalls (PartitionMarker* pm, size_t at, vector<void*>* infos) const noexcept
111 {
112 for (auto it = fPartitionWatchers.begin (); it != fPartitionWatchers.end (); ++it) {
113 void* info;
114 (*it)->AboutToSplit (pm, at, &info);
115 infos->push_back (info);
116 }
117 }
118 inline void Partition::DoDidSplitCalls (const vector<void*>& infos) const noexcept
119 {
120 Assert (infos.size () == fPartitionWatchers.size ());
121 vector<void*>::const_iterator infoIt = infos.begin ();
122 for (auto it = fPartitionWatchers.begin (); it != fPartitionWatchers.end (); ++it) {
123 (*it)->DidSplit (*infoIt);
124 ++infoIt;
125 }
126 }
127 inline void Partition::DoAboutToCoaleceCalls (PartitionMarker* pm, vector<void*>* infos) const noexcept
128 {
129 for (auto it = fPartitionWatchers.begin (); it != fPartitionWatchers.end (); ++it) {
130 void* info;
131 (*it)->AboutToCoalece (pm, &info);
132 infos->push_back (info);
133 }
134 }
135 inline void Partition::DoDidCoaleceCalls (const vector<void*>& infos) const noexcept
136 {
137 Assert (infos.size () == fPartitionWatchers.size ());
138 vector<void*>::const_iterator infoIt = infos.begin ();
139 for (auto it = fPartitionWatchers.begin (); it != fPartitionWatchers.end (); ++it) {
140 (*it)->DidCoalece (*infoIt);
141 ++infoIt;
142 }
143 }
144
145#if qStroika_Frameworks_Led_SupportGDI
146 // class PartitioningTextImager;
147 inline PartitioningTextImager::PartitionPtr PartitioningTextImager::GetPartition () const
148 {
149 return fPartition;
150 }
151 inline Partition::PartitionMarker* PartitioningTextImager::GetFirstPartitionMarker () const
152 {
153 Require (fPartition.get () != nullptr); // perhaps you've forgotten to call SpecifyTextStore or SetPartition ()?
154 return fPartition->GetFirstPartitionMarker ();
155 }
156 /*
157 @METHOD: PartitioningTextImager::GetPartitionMarkerContainingPosition
158 @DESCRIPTION: <p>Finds the @'PartitioningTextImager::PartitionMarker' which contains the given character#.
159 Note, the use of 'charPosition' rather than markerpos is to disambiguiate the case where we are at the boundary
160 between two partition elements.</p>
161 */
162 inline Partition::PartitionMarker* PartitioningTextImager::GetPartitionMarkerContainingPosition (size_t charPosition) const
163 {
164 return fPartition->GetPartitionMarkerContainingPosition (charPosition);
165 }
166 /*
167 @METHOD: PartitioningTextImager::GetStartOfPartitionContainingPosition
168 @DESCRIPTION: <p>Simple wrapper on @'PartitioningTextImager::GetPartitionMarkerContainingPosition'.</p>
169 */
170 inline size_t PartitioningTextImager::GetStartOfPartitionContainingPosition (size_t charPosition) const
171 {
172 return GetPartitionMarkerContainingPosition (charPosition)->GetStart ();
173 }
174 /*
175 @METHOD: PartitioningTextImager::GetEndOfPartitionContainingPosition
176 @DESCRIPTION: <p>Simple wrapper on @'PartitioningTextImager::GetPartitionMarkerContainingPosition'. Returns marker position
177 AFTER end of partition (same as START position of following partition - if any).</p>
178 */
179 inline size_t PartitioningTextImager::GetEndOfPartitionContainingPosition (size_t charPosition) const
180 {
181 return GetPartitionMarkerContainingPosition (charPosition)->GetEnd ();
182 }
183 inline void PartitioningTextImager::Invariant () const
184 {
185#if qStroika_Foundation_Debug_AssertionsChecked and qStroika_Frameworks_Led_HeavyDebugging
186 Invariant_ ();
187#endif
188 }
189
190#if qCacheTextMeasurementsForPM
191 // class PartitioningTextImager::MeasureTextCache
192 inline void PartitioningTextImager::MeasureTextCache::ClearAll ()
193 {
194 fCache.clear ();
195 }
196 inline PartitioningTextImager::MeasureTextCache::CacheElt
197 PartitioningTextImager::MeasureTextCache::LookupValue (PartitionMarker* pm, size_t rowStart,
198 const function<CacheElt (PartitionMarker*, size_t)>& valueFetcher)
199 {
200 RequireNotNull (pm);
201 using CacheElt = PartitioningTextImager::MeasureTextCache::CacheElt;
202 return fCache.LookupValue (CacheElt::COMPARE_ITEM (pm, rowStart),
203 [valueFetcher] (const CacheElt::COMPARE_ITEM& c) { return valueFetcher (c.fPM, c.fRowStartingAt); });
204 }
205
206 // class PartitioningTextImager::MeasureTextCache::CacheElt
207 inline PartitioningTextImager::MeasureTextCache::CacheElt::CacheElt ()
208 : fValidFor (nullptr, 0)
209 , fMeasurementsCache (0)
210 {
211 }
212 inline PartitioningTextImager::MeasureTextCache::CacheElt::CacheElt (const COMPARE_ITEM& ci)
213 : fValidFor{ci}
214 , fMeasurementsCache (0)
215 {
216 }
217#endif
218#endif
219
220}
#define EnsureNotNull(p)
Definition Assertions.h:340
#define RequireNotNull(p)
Definition Assertions.h:347
#define EnsureMember(p, c)
Definition Assertions.h:319