4#include "Stroika/Frameworks/StroikaPreComp.h"
6#include "StandardStyledTextImager.h"
9using namespace Stroika::Frameworks;
10using namespace Stroika::Frameworks::Led;
17#if qStroika_Foundation_Debug_AssertionsChecked
18void AbstractStyleDatabaseRep::Invariant_ ()
const
28#if qStroika_Frameworks_Led_SupportGDI
29void StandardStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
size_t from,
30 size_t to,
const TextLayoutBlock& text,
const Led_Rect& drawInto,
const Led_Rect& ,
31 CoordinateType useBaseLine, DistanceType* pixelsDrawn)
34 imager->DrawSegment_ (tablet, fFontSpecification, from, to, text, drawInto, useBaseLine, pixelsDrawn);
37void StandardStyleMarker::MeasureSegmentWidth (
const StyledTextImager* imager,
const StyleRunElement& ,
size_t from,
38 size_t to,
const Led_tChar* text, DistanceType* distanceResults)
const
41 imager->MeasureSegmentWidth_ (fFontSpecification, from, to, text, distanceResults);
44DistanceType StandardStyleMarker::MeasureSegmentHeight (
const StyledTextImager* imager,
const StyleRunElement& ,
size_t from,
size_t to)
const
47 return (imager->MeasureSegmentHeight_ (fFontSpecification, from, to));
50DistanceType StandardStyleMarker::MeasureSegmentBaseLine (
const StyledTextImager* imager,
const StyleRunElement& ,
size_t from,
size_t to)
const
53 return (imager->MeasureSegmentBaseLine_ (fFontSpecification, from, to));
62StyleDatabaseRep::StyleDatabaseRep (TextStore& textStore)
63 : inheritedMC{textStore, GetStaticDefaultFont ()}
67vector<StyledInfoSummaryRecord> StyleDatabaseRep::GetStyleInfo (
size_t charAfterPos,
size_t nTCharsFollowing)
const
69 MarkerVector standardStyleMarkers = GetInfoMarkers (charAfterPos, nTCharsFollowing);
71 vector<StyledInfoSummaryRecord> result;
72 size_t tCharsSoFar = 0;
73 size_t nStandardStyleMarkers = standardStyleMarkers.size ();
74 for (
size_t i = 0; i < nStandardStyleMarkers; ++i) {
75 StandardStyleMarker* marker = standardStyleMarkers[i];
79 marker->GetRange (&markerStart, &markerEnd);
83 size_t length = markerEnd - markerStart;
85 Assert (charAfterPos >= markerStart);
86 Assert (charAfterPos - markerStart < length);
87 length -= (charAfterPos - markerStart);
89 if (i == nStandardStyleMarkers - 1) {
90 Assert (length >= nTCharsFollowing - tCharsSoFar);
91 length = nTCharsFollowing - tCharsSoFar;
93 Assert (length > 0 or nTCharsFollowing == 0);
94 Assert (length <= nTCharsFollowing);
95 result.push_back (StyledInfoSummaryRecord (marker->fFontSpecification, length));
96 tCharsSoFar += length;
98 Assert (tCharsSoFar == nTCharsFollowing);
102void StyleDatabaseRep::SetStyleInfo (
size_t charAfterPos,
size_t nTCharsFollowing,
const IncrementalFontSpecification& styleInfo)
104 SetInfo (charAfterPos, nTCharsFollowing, styleInfo);
107void StyleDatabaseRep::SetStyleInfo (
size_t charAfterPos,
size_t nTCharsFollowing,
size_t nStyleInfos,
const StyledInfoSummaryRecord* styleInfos)
109 size_t setAt = charAfterPos;
110 size_t lengthUsedSoFar = 0;
111 for (
size_t i = 0; i < nStyleInfos and lengthUsedSoFar < nTCharsFollowing; ++i) {
112 StyledInfoSummaryRecord isr = styleInfos[i];
113 size_t length = isr.fLength;
114 Assert (nTCharsFollowing >= lengthUsedSoFar);
115 length = min (nTCharsFollowing - lengthUsedSoFar, length);
116 SetStyleInfo (setAt, length, IncrementalFontSpecification{isr});
118 lengthUsedSoFar += length;
122#if qStroika_Foundation_Debug_AssertionsChecked
123void StyleDatabaseRep::Invariant_ ()
const
125 inheritedMC::Invariant_ ();
129#if qStroika_Frameworks_Led_SupportGDI
135void StandardStyledTextImager::HookLosingTextStore ()
137 inherited::HookLosingTextStore ();
138 HookLosingTextStore_ ();
141void StandardStyledTextImager::HookLosingTextStore_ ()
144 if (fICreatedDatabase) {
145 fICreatedDatabase =
false;
146 if (fStyleDatabase.get () !=
nullptr) {
147 fStyleDatabase =
nullptr;
148 HookStyleDatabaseChanged ();
153void StandardStyledTextImager::HookGainedNewTextStore ()
155 inherited::HookGainedNewTextStore ();
156 HookGainedNewTextStore_ ();
159void StandardStyledTextImager::HookGainedNewTextStore_ ()
161 if (fStyleDatabase ==
nullptr) {
162 fStyleDatabase = make_shared<StyleDatabaseRep> (GetTextStore ());
163 fICreatedDatabase =
true;
164 HookStyleDatabaseChanged ();
168void StandardStyledTextImager::SetStyleDatabase (
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
170 fStyleDatabase = styleDatabase;
171 fICreatedDatabase =
false;
172 if (fStyleDatabase ==
nullptr and PeekAtTextStore () !=
nullptr) {
173 fStyleDatabase = make_shared<StyleDatabaseRep> (GetTextStore ());
174 fICreatedDatabase =
true;
176 HookStyleDatabaseChanged ();
185void StandardStyledTextImager::HookStyleDatabaseChanged ()
189FontMetrics StandardStyledTextImager::GetFontMetricsAt (
size_t charAfterPos)
const
191 Tablet_Acquirer tablet (
this);
194 FontCacheInfoUpdater fontCacheUpdater (
this, tablet, GetStyleInfo (charAfterPos));
195 return (fontCacheUpdater.GetMetrics ());
204 vector<StyledInfoSummaryRecord> summaryInfo = GetStyleInfo (GetSelectionEnd (), 0);
205 Assert (summaryInfo.size () == 1);
206 return summaryInfo[0];
217IncrementalFontSpecification StandardStyledTextImager::GetContinuousStyleInfo (
size_t from,
size_t nTChars)
const
219 vector<StyledInfoSummaryRecord> summaryInfo = GetStyleInfo (from, nTChars);
220 return (GetContinuousStyleInfo_ (summaryInfo));
223IncrementalFontSpecification StandardStyledTextImager::GetContinuousStyleInfo_ (
const vector<StyledInfoSummaryRecord>& summaryInfo)
const
225 IncrementalFontSpecification fontSpec;
236 int countOfValidThings = 7 +
237#if qStroika_Foundation_Common_Platform_MacOS
239#elif qStroika_Foundation_Common_Platform_Windows
241#elif qStroika_FeatureSupported_XWindows
246 for (
size_t i = 0; i < summaryInfo.size (); ++i) {
248 fontSpec = IncrementalFontSpecification{summaryInfo[0]};
253 StyledInfoSummaryRecord isr = summaryInfo[i];
256 if (fontSpec.GetFontNameSpecifier_Valid () and fontSpec.GetFontNameSpecifier () != isr.GetFontNameSpecifier ()) {
257 fontSpec.InvalidateFontNameSpecifier ();
258 if (--countOfValidThings == 0) {
264 if (fontSpec.GetStyle_Bold_Valid () and fontSpec.GetStyle_Bold () != isr.GetStyle_Bold ()) {
265 fontSpec.InvalidateStyle_Bold ();
266 if (--countOfValidThings == 0) {
270 if (fontSpec.GetStyle_Italic_Valid () and fontSpec.GetStyle_Italic () != isr.GetStyle_Italic ()) {
271 fontSpec.InvalidateStyle_Italic ();
272 if (--countOfValidThings == 0) {
276 if (fontSpec.GetStyle_Underline_Valid () and fontSpec.GetStyle_Underline () != isr.GetStyle_Underline ()) {
277 fontSpec.InvalidateStyle_Underline ();
278 if (--countOfValidThings == 0) {
282 if (fontSpec.GetStyle_SubOrSuperScript_Valid () and fontSpec.GetStyle_SubOrSuperScript () != isr.GetStyle_SubOrSuperScript ()) {
283 fontSpec.InvalidateStyle_SubOrSuperScript ();
284 if (--countOfValidThings == 0) {
288#if qStroika_Foundation_Common_Platform_MacOS
289 if (fontSpec.GetStyle_Outline_Valid () and fontSpec.GetStyle_Outline () != isr.GetStyle_Outline ()) {
290 fontSpec.InvalidateStyle_Outline ();
291 if (--countOfValidThings == 0) {
295 if (fontSpec.GetStyle_Shadow_Valid () and fontSpec.GetStyle_Shadow () != isr.GetStyle_Shadow ()) {
296 fontSpec.InvalidateStyle_Shadow ();
297 if (--countOfValidThings == 0) {
301 if (fontSpec.GetStyle_Condensed_Valid () and fontSpec.GetStyle_Condensed () != isr.GetStyle_Condensed ()) {
302 fontSpec.InvalidateStyle_Condensed ();
303 if (--countOfValidThings == 0) {
307 if (fontSpec.GetStyle_Extended_Valid () and fontSpec.GetStyle_Extended () != isr.GetStyle_Extended ()) {
308 fontSpec.InvalidateStyle_Extended ();
309 if (--countOfValidThings == 0) {
313#elif qStroika_Foundation_Common_Platform_Windows
314 if (fontSpec.GetStyle_Strikeout_Valid () and fontSpec.GetStyle_Strikeout () != isr.GetStyle_Strikeout ()) {
315 fontSpec.InvalidateStyle_Strikeout ();
316 if (--countOfValidThings == 0) {
323 if (fontSpec.GetPointSize_Valid () and fontSpec.GetPointSize () != isr.GetPointSize ()) {
324 fontSpec.InvalidatePointSize ();
325 if (--countOfValidThings == 0) {
331 if (fontSpec.GetTextColor_Valid () and fontSpec.GetTextColor () != isr.GetTextColor ()) {
332 fontSpec.InvalidateTextColor ();
333 if (--countOfValidThings == 0) {
343#if qStroika_Foundation_Common_Platform_MacOS
344bool StandardStyledTextImager::DoContinuousStyle_Mac (
size_t from,
size_t nTChars,
short* mode, TextStyle* theStyle)
348 Require ((*mode & addSize) == 0);
351 unsigned int resultMode = *mode;
352 IncrementalFontSpecification resultSpec = GetContinuousStyleInfo (from, nTChars);
353 if (resultMode & doFont) {
354 resultSpec.GetOSRep (&theStyle->tsFont,
nullptr,
nullptr);
356 if (resultMode & doFace) {
357 resultSpec.GetOSRep (
nullptr,
nullptr, &theStyle->tsFace);
359 if (resultMode & doSize) {
360 resultSpec.GetOSRep (
nullptr, &theStyle->tsSize,
nullptr);
363 bool result = (resultMode != *mode);
368vector<StyledInfoSummaryRecord> StandardStyledTextImager::Convert (
const ScrpSTElement* teScrapFmt,
size_t nElts)
370 vector<StyledInfoSummaryRecord> result;
371 for (
size_t i = 0; i < nElts; ++i) {
372 IncrementalFontSpecification fsp;
373 fsp.SetOSRep (teScrapFmt[i].scrpFont, teScrapFmt[i].scrpSize, teScrapFmt[i].scrpFace);
374 size_t length = (i < (nElts - 1)) ? (teScrapFmt[i + 1].scrpStartChar - teScrapFmt[i].scrpStartChar) : 9999999;
375 StyledInfoSummaryRecord isr (fsp, length);
376 result.push_back (isr);
381void StandardStyledTextImager::Convert (
const vector<StyledInfoSummaryRecord>& fromLedStyleRuns, ScrpSTElement* teScrapFmt)
383 size_t nElts = fromLedStyleRuns.size ();
384 size_t startChar = 0;
386 GrafPtr oldPort = Led_GetCurrentGDIPort ();
388 CGrafPtr tmpPort = ::CreateNewPort ();
392 ::OpenCPort (&tmpPort);
395 for (
size_t i = 0; i < nElts; ++i) {
396 StyledInfoSummaryRecord isr = fromLedStyleRuns[i];
398 (void)::memset (&teScrapFmt[i], 0,
sizeof (teScrapFmt[i]));
399 teScrapFmt[i].scrpStartChar = startChar;
401 isr.GetOSRep (&teScrapFmt[i].scrpFont, &teScrapFmt[i].scrpSize, &teScrapFmt[i].scrpFace);
403 ::TextFont (teScrapFmt[i].scrpFont);
404 ::TextFace (teScrapFmt[i].scrpFace);
405 ::TextSize (teScrapFmt[i].scrpSize);
408 ::GetFontInfo (&info);
410 teScrapFmt[i].scrpHeight = info.ascent + info.descent + info.leading;
411 teScrapFmt[i].scrpAscent = info.ascent;
413 startChar += isr.fLength;
417 ::DisposePort (tmpPort);
419 ::CloseCPort (&tmpPort);
425#if qStroika_Foundation_Debug_AssertionsChecked
426void StandardStyledTextImager::Invariant_ ()
const
428 StyledTextImager::Invariant_ ();
429 if (fStyleDatabase.get () !=
nullptr) {
430 fStyleDatabase->Invariant ();
#define RequireNotNull(p)