4#include "Stroika/Frameworks/StroikaPreComp.h"
6#include "Stroika/Foundation/DataExchange/BadFormatException.h"
7#if qStroika_Platform_Windows
8#include "Stroika/Foundation/Memory/Platform/Windows/Handle.h"
11#include "Stroika/Frameworks/Led/StandardStyledTextImager.h"
13#include "StyledTextEmbeddedObjects.h"
16using namespace Stroika::Frameworks;
17using namespace Stroika::Frameworks::Led;
19#if qStroika_Frameworks_Led_SupportGDI
23static struct FooBarBlatzRegistryCleanupHack {
24 ~FooBarBlatzRegistryCleanupHack ()
26 delete EmbeddedObjectCreatorRegistry::sThe;
27 EmbeddedObjectCreatorRegistry::sThe =
nullptr;
31#if qStroika_Platform_Windows
32static void MacPictureDrawSegment (StandardMacPictureStyleMarker::PictureHandle pictureHandle, Tablet* tablet,
Color foreColor,
33 Color backColor,
const Led_Rect& drawInto, CoordinateType useBaseLine, DistanceType* pixelsDrawn,
34 const Led_Size& imageSize,
const Led_Size& margin = kDefaultEmbeddingMargin)
noexcept;
36static void DIBDrawSegment (
const Led_DIB* dib, Tablet* tablet,
Color foreColor,
Color backColor,
const Led_Rect& drawInto, CoordinateType useBaseLine,
37 DistanceType* pixelsDrawn,
const Led_Size& imageSize,
const Led_Size& margin = kDefaultEmbeddingMargin)
noexcept;
39struct UnsupportedFormat {};
42 using StackBasedHandleLocker = Memory::Platform::Windows::StackBasedHandleLocker;
50EmbeddedObjectCreatorRegistry* EmbeddedObjectCreatorRegistry::sThe =
nullptr;
52void EmbeddedObjectCreatorRegistry::AddStandardTypes ()
54#if qStroika_Platform_Windows
55 AddAssoc (StandardMacPictureStyleMarker::kClipFormat, StandardMacPictureStyleMarker::kEmbeddingTag, &StandardMacPictureStyleMarker::mk,
56 &StandardMacPictureStyleMarker::mk);
57 AddAssoc (StandardDIBStyleMarker::kClipFormat, StandardDIBStyleMarker::kEmbeddingTag, &StandardDIBStyleMarker::mk, &StandardDIBStyleMarker::mk);
60 AddAssoc (StandardURLStyleMarker::kURLDClipFormat, StandardURLStyleMarker::kEmbeddingTag, &StandardURLStyleMarker::mk, &StandardURLStyleMarker::mk);
61#if qStroika_Platform_Windows
62 AddAssoc (StandardURLStyleMarker::kWin32URLClipFormat, StandardURLStyleMarker::kEmbeddingTag, &StandardURLStyleMarker::mk,
63 &StandardURLStyleMarker::mk);
66#if qStroika_Platform_Windows
67 AddAssoc (StandardMacPictureWithURLStyleMarker::kClipFormats, StandardMacPictureWithURLStyleMarker::kClipFormatCount,
68 StandardMacPictureWithURLStyleMarker::kEmbeddingTag, &StandardMacPictureWithURLStyleMarker::mk,
69 &StandardMacPictureWithURLStyleMarker::mk);
70 AddAssoc (StandardMacPictureWithURLStyleMarker::kOld1EmbeddingTag, &StandardMacPictureWithURLStyleMarker::mk);
71 AddAssoc (StandardDIBWithURLStyleMarker::kClipFormats, StandardDIBWithURLStyleMarker::kClipFormatCount,
72 StandardDIBWithURLStyleMarker::kEmbeddingTag, &StandardDIBWithURLStyleMarker::mk, &StandardDIBWithURLStyleMarker::mk);
76bool EmbeddedObjectCreatorRegistry::Lookup (
const char* embeddingTag, Assoc* result)
const
80 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = GetAssocList ();
81 for (
size_t i = 0; i < types.size (); ++i) {
82 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
83 if (memcmp (assoc.fEmbeddingTag, embeddingTag, sizeof (assoc.fEmbeddingTag)) == 0) {
96SimpleEmbeddedObjectStyleMarker::CommandNames SimpleEmbeddedObjectStyleMarker::sCommandNames =
97 SimpleEmbeddedObjectStyleMarker::MakeDefaultCommandNames ();
99int SimpleEmbeddedObjectStyleMarker::GetPriority ()
const
101 return eEmbeddedObjectPriority;
104DistanceType SimpleEmbeddedObjectStyleMarker::MeasureSegmentBaseLine (
const StyledTextImager* imager,
const StyleRunElement& runElement,
105 size_t from,
size_t to)
const
108 Require (from + 1 == to);
109 return (MeasureSegmentHeight (imager, runElement, from, to) - 1 * kDefaultEmbeddingMargin.v);
112void SimpleEmbeddedObjectStyleMarker::DidUpdateText (
const MarkerOwner::UpdateInfo& updateInfo)
noexcept
116 size_t newLength = GetLength ();
117 if (newLength == 0) {
118 GetOwner ()->PeekAtTextStore ()->RemoveMarker (
this);
121 else if (newLength == 1) {
122 inherited::DidUpdateText (updateInfo);
125 Assert (GetEnd () > 0);
126 GetOwner ()->PeekAtTextStore ()->SetMarkerStart (
this, GetEnd () - 1);
127 inherited::DidUpdateText (updateInfo);
135bool SimpleEmbeddedObjectStyleMarker::HandleClick (Led_Point ,
unsigned clickCount)
137 if (clickCount == 2) {
138 return HandleOpen ();
143bool SimpleEmbeddedObjectStyleMarker::HandleOpen ()
154vector<SimpleEmbeddedObjectStyleMarker::PrivateCmdNumber> SimpleEmbeddedObjectStyleMarker::GetCmdNumbers ()
const
156 return vector<PrivateCmdNumber> ();
164bool SimpleEmbeddedObjectStyleMarker::IsCmdEnabled (PrivateCmdNumber )
const
174SDKString SimpleEmbeddedObjectStyleMarker::GetCmdText (PrivateCmdNumber cmd)
178 return GetCommandNames ().fOpenCommandName;
193void SimpleEmbeddedObjectStyleMarker::DoCommand (PrivateCmdNumber cmd)
205SimpleEmbeddedObjectStyleMarker::CommandNames SimpleEmbeddedObjectStyleMarker::MakeDefaultCommandNames ()
207 SimpleEmbeddedObjectStyleMarker::CommandNames cmdNames;
208 cmdNames.fOpenCommandName = Led_SDK_TCHAROF (
"Open Embedding");
212#if qStroika_Platform_Windows
218#if qStroika_Platform_Windows
223const Led_ClipFormat StandardMacPictureStyleMarker::kClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (_T (
"Mac PICT Format")));
225constexpr Led_PrivateEmbeddingTag StandardMacPictureStyleMarker::kEmbeddingTag =
"Pict2";
227#if qStroika_Platform_Windows
228const Led_DIB* StandardMacPictureStyleMarker::sUnsupportedFormatPict =
nullptr;
231StandardMacPictureStyleMarker::StandardMacPictureStyleMarker (
const Led_Picture* pictData,
size_t picSize)
232 : SimpleEmbeddedObjectStyleMarker ()
233 , fPictureHandle (nullptr)
234#if qStroika_Platform_Windows
239#if qStroika_Platform_Windows
242#if qStroika_Platform_Windows
243 fPictureSize = picSize;
244 fPictureHandle = ::GlobalAlloc (GMEM_MOVEABLE, picSize);
245 Execution::ThrowIfNull (fPictureHandle);
247 StackBasedHandleLocker locker (GetPictureHandle ());
248 memcpy (locker.GetPointer (), pictData, picSize);
251StandardMacPictureStyleMarker::~StandardMacPictureStyleMarker ()
254 ::GlobalFree (fPictureHandle);
257SimpleEmbeddedObjectStyleMarker* StandardMacPictureStyleMarker::mk ([[maybe_unused]]
const char* embeddingTag,
const void* data,
size_t len)
259 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0);
260 return (
new StandardMacPictureStyleMarker ((Led_Picture*)data, len));
263SimpleEmbeddedObjectStyleMarker* StandardMacPictureStyleMarker::mk (
ReaderFlavorPackage& flavorPackage)
267 length = flavorPackage.ReadFlavorData (kClipFormat, length, buf.data ());
268 return (mk (kEmbeddingTag, buf.data (), length));
271void StandardMacPictureStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
272 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
273 [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
274 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
276 Assert (from + 1 == to);
277 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
278 StackBasedHandleLocker locker (GetPictureHandle ());
279 MacPictureDrawSegment (GetPictureHandle (), tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
280 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
281 drawInto - Led_Point (0, imager->GetHScrollPos ()), useBaseLine, pixelsDrawn,
282 Led_GetMacPictSize ((Led_Picture*)locker.GetPointer ()));
285void StandardMacPictureStyleMarker::MeasureSegmentWidth ([[maybe_unused]]
const StyledTextImager* imager,
286 [[maybe_unused]]
const StyleRunElement& runElement, [[maybe_unused]]
size_t from,
287 [[maybe_unused]]
size_t to, [[maybe_unused]]
const Led_tChar* text,
288 DistanceType* distanceResults)
const
290 Assert (from + 1 == to);
303 StackBasedHandleLocker locker (GetPictureHandle ());
304 distanceResults[0] = Led_GetMacPictWidth ((Led_Picture*)locker.GetPointer ()) + 2 * kDefaultEmbeddingMargin.h;
307DistanceType StandardMacPictureStyleMarker::MeasureSegmentHeight ([[maybe_unused]]
const StyledTextImager* imager,
308 [[maybe_unused]]
const StyleRunElement& runElement,
309 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
311 Assert (from + 1 == to);
312 StackBasedHandleLocker locker (GetPictureHandle ());
313 return (Led_GetMacPictHeight ((Led_Picture*)locker.GetPointer ()) + 2 * kDefaultEmbeddingMargin.v);
316void StandardMacPictureStyleMarker::Write (SinkStream& sink)
318 StackBasedHandleLocker locker (GetPictureHandle ());
319 sink.write (locker.GetPointer (), GetPictureByteSize ());
324 StackBasedHandleLocker locker (GetPictureHandle ());
325 flavorPackage.AddFlavorData (kClipFormat, GetPictureByteSize (), (Led_Picture*)locker.GetPointer ());
328const char* StandardMacPictureStyleMarker::GetTag ()
const
330 return kEmbeddingTag;
339#if qStroika_Platform_Windows
340const Led_ClipFormat StandardDIBStyleMarker::kClipFormat = CF_DIB;
342constexpr Led_PrivateEmbeddingTag StandardDIBStyleMarker::kEmbeddingTag =
"DIB";
344StandardDIBStyleMarker::StandardDIBStyleMarker (
const Led_DIB* pictData)
345 : SimpleEmbeddedObjectStyleMarker ()
349 fDIBData = Led_CloneDIB (pictData);
352StandardDIBStyleMarker::~StandardDIBStyleMarker ()
358SimpleEmbeddedObjectStyleMarker* StandardDIBStyleMarker::mk ([[maybe_unused]]
const char* embeddingTag,
const void* data,
size_t len)
360 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0);
363 Execution::Throw (DataExchange::BadFormatException::kThe);
366 size_t picSize = Led_GetDIBImageByteCount ((Led_DIB*)data);
370 if (len != picSize) {
374 Execution::Throw (DataExchange::BadFormatException::kThe);
380 return (
new StandardDIBStyleMarker ((Led_DIB*)data));
383SimpleEmbeddedObjectStyleMarker* StandardDIBStyleMarker::mk (
ReaderFlavorPackage& flavorPackage)
387 length = flavorPackage.ReadFlavorData (kClipFormat, length, buf.data ());
388 return mk (kEmbeddingTag, buf.data (), length);
391void StandardDIBStyleMarker::DrawSegment (
const StyledTextImager* imager, [[maybe_unused]]
const StyleRunElement& runElement,
392 Tablet* tablet, [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
393 [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
394 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
396 Assert (from + 1 == to);
397 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
398 DIBDrawSegment (fDIBData, tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
399 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
400 drawInto - Led_Point (0, imager->GetHScrollPos ()), useBaseLine, pixelsDrawn, Led_GetDIBImageSize (fDIBData));
403void StandardDIBStyleMarker::MeasureSegmentWidth (
const StyledTextImager* ,
const StyleRunElement& ,
404 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
405 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
407 Assert (from + 1 == to);
420 distanceResults[0] = Led_GetDIBImageSize (GetDIBData ()).h + 2 * kDefaultEmbeddingMargin.h;
423DistanceType StandardDIBStyleMarker::MeasureSegmentHeight (
const StyledTextImager* ,
const StyleRunElement& ,
424 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
426 Assert (from + 1 == to);
427 return (Led_GetDIBImageSize (GetDIBData ()).v + 2 * kDefaultEmbeddingMargin.v);
430void StandardDIBStyleMarker::Write (SinkStream& sink)
432 const Led_DIB* dib = GetDIBData ();
433 size_t dibSize = Led_GetDIBImageByteCount (dib);
434 sink.write (dib, dibSize);
439 const Led_DIB* dib = GetDIBData ();
440 size_t dibSize = Led_GetDIBImageByteCount (dib);
441 flavorPackage.AddFlavorData (kClipFormat, dibSize, dib);
444const char* StandardDIBStyleMarker::GetTag ()
const
446 return kEmbeddingTag;
454#if qStroika_Platform_Windows
458const Led_ClipFormat StandardURLStyleMarker::kURLDClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (_T (
"Netscape Bookmark")));
459const Led_ClipFormat StandardURLStyleMarker::kWin32URLClipFormat =
460 static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (_T (
"UniformResourceLocator")));
463constexpr Led_PrivateEmbeddingTag StandardURLStyleMarker::kEmbeddingTag =
"URL";
465StandardURLStyleMarker::StandardURLStyleMarker (
const Led_URLD& urlData)
466 : SimpleEmbeddedObjectStyleMarker ()
471StandardURLStyleMarker::~StandardURLStyleMarker ()
475SimpleEmbeddedObjectStyleMarker* StandardURLStyleMarker::mk ([[maybe_unused]]
const char* embeddingTag,
const void* data,
size_t len)
477 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0);
478 return (
new StandardURLStyleMarker (Led_URLD (data, len)));
481SimpleEmbeddedObjectStyleMarker* StandardURLStyleMarker::mk (
ReaderFlavorPackage& flavorPackage)
486 if (flavorPackage.GetFlavorAvailable (kURLDClipFormat)) {
487 size_t length = flavorPackage.
GetFlavorSize (kURLDClipFormat);
489 length = flavorPackage.ReadFlavorData (kURLDClipFormat, length, buf.data ());
490 return (mk (kEmbeddingTag, buf.data (), length));
492#if qStroika_Platform_Windows
493 if (flavorPackage.GetFlavorAvailable (kWin32URLClipFormat)) {
494 size_t length = flavorPackage.
GetFlavorSize (kWin32URLClipFormat);
496 length = flavorPackage.ReadFlavorData (kWin32URLClipFormat, length, buf.data ());
500 return (mk (kEmbeddingTag, buf.data (), length));
503 Execution::Throw (DataExchange::BadFormatException::kThe);
508void StandardURLStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& runElement, Tablet* tablet,
size_t from,
509 [[maybe_unused]]
size_t to, [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
510 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
515 Led_tString displayText = GetDisplayString ();
516 imager->DrawSegment_ (tablet, fsp, from, from + displayText.length (),
517 TextLayoutBlock_Basic (displayText.c_str (), displayText.c_str () + displayText.length ()), drawInto, useBaseLine, pixelsDrawn);
520void StandardURLStyleMarker::MeasureSegmentWidth (
const StyledTextImager* imager,
const StyleRunElement& runElement, [[maybe_unused]]
size_t from,
521 [[maybe_unused]]
size_t to, [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
523 Assert (from + 1 == to);
538 Led_tString displayText = GetDisplayString ();
539 if (displayText.empty ()) {
540 distanceResults[0] = 0;
544 imager->MeasureSegmentWidth_ (fsp, from, from + displayText.length (), displayText.c_str (), distRes.data ());
545 distanceResults[0] = distRes[displayText.length () - 1];
549DistanceType StandardURLStyleMarker::MeasureSegmentHeight (
const StyledTextImager* imager,
const StyleRunElement& runElement,
550 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
552 Assert (from + 1 == to);
555 Led_tString displayText = GetDisplayString ();
556 return imager->MeasureSegmentHeight_ (fsp, from, from + displayText.length ());
559void StandardURLStyleMarker::Write (SinkStream& sink)
561 sink.write (fURLData.PeekAtURLD (), fURLData.GetURLDLength ());
566 flavorPackage.AddFlavorData (kURLDClipFormat, fURLData.GetURLDLength (), fURLData.PeekAtURLD ());
567#if qStroika_Platform_Windows
568 size_t len = fURLData.GetURLLength () + 1;
570 memcpy (hackBuf.data (), fURLData.PeekAtURL (), len - 1);
572 flavorPackage.AddFlavorData (kWin32URLClipFormat, len, hackBuf.data ());
576const char* StandardURLStyleMarker::GetTag ()
const
578 return kEmbeddingTag;
581bool StandardURLStyleMarker::HandleOpen ()
583 Led_URLManager::Get ().Open (fURLData.GetURL ());
588vector<StandardURLStyleMarker::PrivateCmdNumber> StandardURLStyleMarker::GetCmdNumbers ()
const
590 vector<PrivateCmdNumber> x;
591 x.push_back (eOpenCmdNum);
595bool StandardURLStyleMarker::IsCmdEnabled (PrivateCmdNumber cmd)
const
601 return inherited::IsCmdEnabled (cmd);
605const Led_URLD& StandardURLStyleMarker::GetURLData ()
const
610void StandardURLStyleMarker::SetURLData (
const Led_URLD& urlData)
615Led_tString StandardURLStyleMarker::GetDisplayString ()
const
617 string displayText = fURLData.GetTitle ();
618 if (displayText.empty ()) {
619 displayText = fURLData.GetURL ();
625 for (
auto i = displayText.begin (); i != displayText.end (); ++i) {
630 return Led_ANSIString2tString (displayText);
633FontSpecification StandardURLStyleMarker::GetDisplayFont (
const StyleRunElement& runElement)
const
636 if (
dynamic_cast<StandardStyleMarker*
> (runElement.fMarker) !=
nullptr) {
637 StandardStyleMarker* sm =
dynamic_cast<StandardStyleMarker*
> (runElement.fMarker);
638 fsp = sm->fFontSpecification;
641 for (
auto i = runElement.fSupercededMarkers.begin (); i != runElement.fSupercededMarkers.end (); ++i) {
642 StandardStyleMarker* sm =
dynamic_cast<StandardStyleMarker*
> (*i);
644 fsp = sm->fFontSpecification;
649 fsp.SetPointSize (
static_cast<unsigned short> (fsp.GetPointSize () * 1.05));
650 fsp.SetTextColor (Color::kBlue);
651 fsp.SetStyle_Underline (
true);
655#if qStroika_Platform_Windows
661const Led_ClipFormat StandardMacPictureWithURLStyleMarker::kClipFormats[] = {kPICTClipFormat, StandardURLStyleMarker::kURLDClipFormat};
662const size_t StandardMacPictureWithURLStyleMarker::kClipFormatCount =
sizeof (kClipFormats) /
sizeof (kClipFormats[0]);
663constexpr Led_PrivateEmbeddingTag StandardMacPictureWithURLStyleMarker::kEmbeddingTag =
"Pict&URL";
664constexpr Led_PrivateEmbeddingTag StandardMacPictureWithURLStyleMarker::kOld1EmbeddingTag =
"PictWEmbd";
666StandardMacPictureWithURLStyleMarker::StandardMacPictureWithURLStyleMarker (
const Led_Picture* pictData,
size_t picSize,
const Led_URLD& urlData)
667 : SimpleEmbeddedObjectStyleMarker ()
668 , fPictureHandle (nullptr)
670#if qStroika_Platform_Windows
677#if qStroika_Platform_Windows
678 fPictureSize = picSize;
679 fPictureHandle = ::GlobalAlloc (GMEM_MOVEABLE, picSize);
680 Execution::ThrowIfNull (fPictureHandle);
683 StackBasedHandleLocker locker (GetPictureHandle ());
684 memcpy (locker.GetPointer (), pictData, picSize);
688StandardMacPictureWithURLStyleMarker::~StandardMacPictureWithURLStyleMarker ()
691#if qStroika_Platform_Windows
692 ::GlobalFree (fPictureHandle);
696SimpleEmbeddedObjectStyleMarker* StandardMacPictureWithURLStyleMarker::mk (
const char* embeddingTag,
const void* data,
size_t len)
698 Require (memcmp (embeddingTag, kOld1EmbeddingTag,
sizeof (kOld1EmbeddingTag)) == 0 or
699 memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0);
701 if (memcmp (embeddingTag, kOld1EmbeddingTag,
sizeof (kOld1EmbeddingTag)) == 0) {
702 Led_Picture* picBuf = (Led_Picture*)data;
703 size_t picSize = Led_ByteSwapFromMac (picBuf->picSize);
705 if (picSize >= len) {
706 Execution::Throw (DataExchange::BadFormatException::kThe);
708 const char* url = ((
char*)data) + picSize;
709 size_t urlSize = len - picSize;
710 Assert (urlSize > 0);
712 return new StandardMacPictureWithURLStyleMarker (picBuf, Led_ByteSwapFromMac (picBuf->picSize), Led_URLD (url, urlSize));
715 if (len < 4 + 1 +
sizeof (Led_Picture)) {
716 Execution::Throw (DataExchange::BadFormatException::kThe);
719 uint32_t picSize = *(uint32_t*)data;
720 picSize = BufToUInt32 (&picSize);
722 Led_Picture* picBuf = (Led_Picture*)((
char*)data + 4);
724 if (picSize + 4 >= len) {
725 Execution::Throw (DataExchange::BadFormatException::kThe);
727 const char* url = ((
char*)picBuf) + picSize;
728 size_t urlSize = len - 4 - picSize;
729 Assert (urlSize > 0);
731 return new StandardMacPictureWithURLStyleMarker (picBuf, picSize, Led_URLD (url, urlSize));
735SimpleEmbeddedObjectStyleMarker* StandardMacPictureWithURLStyleMarker::mk (
ReaderFlavorPackage& flavorPackage)
737 size_t pictLength = flavorPackage.
GetFlavorSize (kPICTClipFormat);
739 pictLength = flavorPackage.ReadFlavorData (kPICTClipFormat, pictLength, buf1.data ());
740 Led_Picture* picBuf = (Led_Picture*)(
char*)buf1;
742 size_t urlSize = flavorPackage.
GetFlavorSize (StandardURLStyleMarker::kURLDClipFormat);
744 urlSize = flavorPackage.ReadFlavorData (StandardURLStyleMarker::kURLDClipFormat, urlSize, buf2.data ());
745 return new StandardMacPictureWithURLStyleMarker{picBuf, pictLength, Led_URLD{buf2.data (), urlSize}};
748void StandardMacPictureWithURLStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& ,
749 Tablet* tablet, [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
750 [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
751 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
753 Assert (from + 1 == to);
754 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
755 StackBasedHandleLocker locker (GetPictureHandle ());
756 MacPictureDrawSegment (GetPictureHandle (), tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
757 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
758 drawInto - Led_Point{0, imager->GetHScrollPos ()}, useBaseLine, pixelsDrawn,
759 Led_GetMacPictSize ((Led_Picture*)locker.GetPointer ()));
762void StandardMacPictureWithURLStyleMarker::MeasureSegmentWidth (
const StyledTextImager* ,
const StyleRunElement& ,
763 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
764 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
766 Assert (from + 1 == to);
779 StackBasedHandleLocker locker (GetPictureHandle ());
780 distanceResults[0] = Led_GetMacPictWidth ((Led_Picture*)locker.GetPointer ()) + 2 * kDefaultEmbeddingMargin.h;
783DistanceType StandardMacPictureWithURLStyleMarker::MeasureSegmentHeight (
const StyledTextImager* ,
const StyleRunElement& ,
784 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
786 Assert (from + 1 == to);
787 StackBasedHandleLocker locker (GetPictureHandle ());
788 return (Led_GetMacPictHeight ((Led_Picture*)locker.GetPointer ()) + 2 * kDefaultEmbeddingMargin.v);
791void StandardMacPictureWithURLStyleMarker::Write (SinkStream& sink)
794 uint32_t picSize =
static_cast<uint32_t
> (GetPictureByteSize ());
795 UInt32ToBuf (picSize, &picSize);
796 Assert (
sizeof (picSize) == 4);
797 sink.write (&picSize,
sizeof (picSize));
799 StackBasedHandleLocker locker (GetPictureHandle ());
800 sink.write ((Led_Picture*)locker.GetPointer (), GetPictureByteSize ());
801 sink.write (fURLData.PeekAtURLD (), fURLData.GetURLDLength ());
804void StandardMacPictureWithURLStyleMarker::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage)
806 StackBasedHandleLocker locker (GetPictureHandle ());
807 flavorPackage.AddFlavorData (StandardMacPictureStyleMarker::kClipFormat, GetPictureByteSize (), (Led_Picture*)locker.GetPointer ());
808 flavorPackage.AddFlavorData (StandardURLStyleMarker::kURLDClipFormat, fURLData.GetURLDLength (), fURLData.PeekAtURLD ());
811bool StandardMacPictureWithURLStyleMarker::HandleOpen ()
813 Led_URLManager::Get ().Open (fURLData.GetURL ());
817vector<StandardMacPictureWithURLStyleMarker::PrivateCmdNumber> StandardMacPictureWithURLStyleMarker::GetCmdNumbers ()
const
819 vector<PrivateCmdNumber> x;
820 x.push_back (eOpenCmdNum);
824bool StandardMacPictureWithURLStyleMarker::IsCmdEnabled (PrivateCmdNumber cmd)
const
830 return inherited::IsCmdEnabled (cmd);
834const Led_URLD& StandardMacPictureWithURLStyleMarker::GetURLData ()
const
839void StandardMacPictureWithURLStyleMarker::SetURLData (
const Led_URLD& urlData)
844const char* StandardMacPictureWithURLStyleMarker::GetTag ()
const
846 return kEmbeddingTag;
855const Led_ClipFormat StandardDIBWithURLStyleMarker::kClipFormats[] = {StandardDIBStyleMarker::kClipFormat, StandardURLStyleMarker::kURLDClipFormat};
856const size_t StandardDIBWithURLStyleMarker::kClipFormatCount =
sizeof (kClipFormats) /
sizeof (kClipFormats[0]);
857const Led_PrivateEmbeddingTag StandardDIBWithURLStyleMarker::kEmbeddingTag =
"DIB&URL";
859StandardDIBWithURLStyleMarker::StandardDIBWithURLStyleMarker (
const Led_DIB* dibData,
const Led_URLD& urlData)
860 : SimpleEmbeddedObjectStyleMarker ()
865 fDIBData = Led_CloneDIB (dibData);
868StandardDIBWithURLStyleMarker::~StandardDIBWithURLStyleMarker ()
874SimpleEmbeddedObjectStyleMarker* StandardDIBWithURLStyleMarker::mk ([[maybe_unused]]
const char* embeddingTag,
const void* data,
size_t len)
876 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0);
880 Execution::Throw (DataExchange::BadFormatException::kThe);
883 uint32_t picSize = *(uint32_t*)data;
884 picSize = BufToUInt32 (&picSize);
886 Led_DIB* picBuf = (Led_DIB*)((
char*)data + 4);
889 Execution::Throw (DataExchange::BadFormatException::kThe);
892 if (picSize + 4 >= len) {
893 Execution::Throw (DataExchange::BadFormatException::kThe);
895 const char* url = ((
char*)picBuf) + picSize;
896 size_t urlSize = len - 4 - picSize;
897 Assert (urlSize > 0);
899 return new StandardDIBWithURLStyleMarker (picBuf, Led_URLD (url, urlSize));
902SimpleEmbeddedObjectStyleMarker* StandardDIBWithURLStyleMarker::mk (
ReaderFlavorPackage& flavorPackage)
904 size_t length = flavorPackage.
GetFlavorSize (StandardDIBStyleMarker::kClipFormat);
906 length = flavorPackage.ReadFlavorData (StandardDIBStyleMarker::kClipFormat, length, buf.data ());
909 Execution::Throw (DataExchange::BadFormatException::kThe);
912 size_t picSize = Led_GetDIBImageByteCount ((Led_DIB*)(
char*)buf);
916 if (length != picSize) {
918 if (length < picSize) {
920 Execution::Throw (DataExchange::BadFormatException::kThe);
927 size_t urlSize = flavorPackage.
GetFlavorSize (StandardURLStyleMarker::kURLDClipFormat);
929 urlSize = flavorPackage.ReadFlavorData (StandardURLStyleMarker::kURLDClipFormat, urlSize, buf2.data ());
931 return new StandardDIBWithURLStyleMarker{(
const Led_DIB*)(
char*)buf, Led_URLD{buf2.data (), urlSize}};
934void StandardDIBWithURLStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
935 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
936 [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
937 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
939 Assert (from + 1 == to);
940 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
941 DIBDrawSegment (fDIBData, tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
942 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
943 drawInto - Led_Point (0, imager->GetHScrollPos ()), useBaseLine, pixelsDrawn, Led_GetDIBImageSize (fDIBData));
946void StandardDIBWithURLStyleMarker::MeasureSegmentWidth (
const StyledTextImager* ,
const StyleRunElement& ,
947 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
948 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
950 Assert (from + 1 == to);
963 distanceResults[0] = Led_GetDIBImageSize (GetDIBData ()).h + 2 * kDefaultEmbeddingMargin.h;
966DistanceType StandardDIBWithURLStyleMarker::MeasureSegmentHeight (
const StyledTextImager* ,
const StyleRunElement& ,
967 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
969 Assert (from + 1 == to);
970 return (Led_GetDIBImageSize (GetDIBData ()).v + 2 * kDefaultEmbeddingMargin.v);
973void StandardDIBWithURLStyleMarker::Write (SinkStream& sink)
975 const Led_DIB* dib = GetDIBData ();
977 uint32_t dibSize =
static_cast<uint32_t
> (Led_GetDIBImageByteCount (dib));
978 UInt32ToBuf (dibSize, &dibSize);
979 Assert (
sizeof (dibSize) == 4);
980 sink.write (&dibSize,
sizeof (dibSize));
982 sink.write (dib, Led_GetDIBImageByteCount (dib));
983 sink.write (fURLData.PeekAtURLD (), fURLData.GetURLDLength ());
988 const Led_DIB* dib = GetDIBData ();
989 size_t dibSize = Led_GetDIBImageByteCount (dib);
990 flavorPackage.AddFlavorData (StandardDIBStyleMarker::kClipFormat, dibSize, dib);
991 flavorPackage.AddFlavorData (StandardURLStyleMarker::kURLDClipFormat, fURLData.GetURLDLength (), fURLData.PeekAtURLD ());
994bool StandardDIBWithURLStyleMarker::HandleOpen ()
996 Led_URLManager::Get ().Open (fURLData.GetURL ());
1000vector<StandardDIBWithURLStyleMarker::PrivateCmdNumber> StandardDIBWithURLStyleMarker::GetCmdNumbers ()
const
1002 vector<PrivateCmdNumber> x;
1003 x.push_back (eOpenCmdNum);
1007bool StandardDIBWithURLStyleMarker::IsCmdEnabled (PrivateCmdNumber cmd)
const
1013 return inherited::IsCmdEnabled (cmd);
1017const Led_URLD& StandardDIBWithURLStyleMarker::GetURLData ()
const
1022void StandardDIBWithURLStyleMarker::SetURLData (
const Led_URLD& urlData)
1027const char* StandardDIBWithURLStyleMarker::GetTag ()
const
1029 return kEmbeddingTag;
1037#if qStroika_Platform_Windows
1038const Led_DIB* StandardUnknownTypeStyleMarker::sUnknownPict =
nullptr;
1040const Led_PrivateEmbeddingTag StandardUnknownTypeStyleMarker::kDefaultEmbeddingTag =
"UnknwnDlf";
1042StandardUnknownTypeStyleMarker::StandardUnknownTypeStyleMarker (Led_ClipFormat format,
const char* embeddingTag,
1043 const void* unknownTypeData,
size_t nBytes,
const Led_DIB* dib)
1044 : SimpleEmbeddedObjectStyleMarker ()
1055 memcpy (fEmbeddingTag, embeddingTag,
sizeof (fEmbeddingTag));
1056#if qStroika_Platform_Windows
1059 fData =
new char[nBytes];
1060 memcpy (fData, unknownTypeData, nBytes);
1062 if (dib !=
nullptr) {
1063 fDisplayDIB = unique_ptr<Led_DIB> (Led_CloneDIB (dib));
1065 fShownSize = CalcDefaultShownSize ();
1068StandardUnknownTypeStyleMarker::~StandardUnknownTypeStyleMarker ()
1070 delete[] (
char*)fData;
1081void StandardUnknownTypeStyleMarker::SetShownSize (TWIPS_Point size)
1092TWIPS_Point StandardUnknownTypeStyleMarker::CalcDefaultShownSize ()
1094 if (fDisplayDIB.get () !=
nullptr) {
1095 Led_Size pixelSize = Led_GetDIBImageSize (fDisplayDIB.get ());
1096 return TWIPS_Point (Led_CvtScreenPixelsToTWIPSV (pixelSize.v), Led_CvtScreenPixelsToTWIPSH (pixelSize.h));
1098 return CalcStaticDefaultShownSize ();
1101TWIPS_Point StandardUnknownTypeStyleMarker::CalcStaticDefaultShownSize ()
1103#if qStroika_Platform_Windows
1105 Led_Size pixelSize = Led_GetDIBImageSize (sUnknownPict);
1108 return TWIPS_Point (Led_CvtScreenPixelsToTWIPSV (pixelSize.v), Led_CvtScreenPixelsToTWIPSH (pixelSize.h));
1111void StandardUnknownTypeStyleMarker::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
1112 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
1113 [[maybe_unused]]
const TextLayoutBlock& text,
const Led_Rect& drawInto,
1114 const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
1116 Assert (from + 1 == to);
1117 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
1118 Led_Size shownPixelSize = Led_Size (tablet->CvtFromTWIPSV (fShownSize.v), tablet->CvtFromTWIPSH (fShownSize.h));
1120 if (fDisplayDIB.get () !=
nullptr) {
1121 DIBDrawSegment (fDisplayDIB.get (), tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
1122 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
1123 drawInto - Led_Point (0, imager->GetHScrollPos ()), useBaseLine, pixelsDrawn, shownPixelSize);
1126#if qStroika_Platform_Windows
1127 DIBDrawSegment (sUnknownPict, tablet, imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor),
1128 imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor),
1129 drawInto - Led_Point (0, imager->GetHScrollPos ()), useBaseLine, pixelsDrawn, shownPixelSize);
1133void StandardUnknownTypeStyleMarker::MeasureSegmentWidth (
const StyledTextImager* imager,
const StyleRunElement& ,
1134 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
1135 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
1137 Assert (from + 1 == to);
1150 if (fDisplayDIB.get () !=
nullptr) {
1151 distanceResults[0] = Led_GetDIBImageSize (fDisplayDIB.get ()).h + 2 * kDefaultEmbeddingMargin.h;
1154 TextInteractor::Tablet_Acquirer tablet_{imager};
1155 Tablet* tablet = tablet_;
1156 distanceResults[0] = tablet->CvtFromTWIPSH (fShownSize.h) + 2 * kDefaultEmbeddingMargin.h;
1159DistanceType StandardUnknownTypeStyleMarker::MeasureSegmentHeight (
const StyledTextImager* imager,
const StyleRunElement& ,
1160 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
1162 Assert (from + 1 == to);
1163 if (fDisplayDIB.get () !=
nullptr) {
1164 return (Led_GetDIBImageSize (fDisplayDIB.get ()).v + 2 * kDefaultEmbeddingMargin.v);
1166 TextInteractor::Tablet_Acquirer tablet_ (imager);
1167 Tablet* tablet = tablet_;
1168 return tablet->CvtFromTWIPSV (fShownSize.v) + 2 * kDefaultEmbeddingMargin.v;
1171void StandardUnknownTypeStyleMarker::Write (SinkStream& sink)
1173 sink.write (fData, fLength);
1176void StandardUnknownTypeStyleMarker::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage)
1178 flavorPackage.AddFlavorData (fFormat, fLength, fData);
1181const char* StandardUnknownTypeStyleMarker::GetTag ()
const
1183 return fEmbeddingTag;
1191void Led::InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding, TextStore& textStore,
size_t insertAt,
MarkerOwner* ownerForEmbedding)
1195 TextStore::SimpleUpdater updater (textStore, insertAt, insertAt + 1);
1196 textStore.AddMarker (embedding, insertAt, 1, ownerForEmbedding);
1204void Led::AddEmbedding (SimpleEmbeddedObjectStyleMarker* embedding, TextStore& textStore,
size_t insertAt,
MarkerOwner* ownerForEmbedding)
1208 textStore.Replace (insertAt, insertAt, &kEmbeddingSentinelChar, 1);
1209 InsertEmbeddingForExistingSentinel (embedding, textStore, insertAt, ownerForEmbedding);
1212#if qStroika_Platform_Windows
1218static void MacPictureDrawSegment (StandardMacPictureStyleMarker::PictureHandle pictureHandle, Tablet* tablet,
Color foreColor,
1219 Color backColor,
const Led_Rect& drawInto, CoordinateType useBaseLine, DistanceType* pixelsDrawn,
1220 const Led_Size& imageSize,
const Led_Size& margin)
noexcept
1224 StackBasedHandleLocker locker (pictureHandle);
1226#if qStroika_Platform_Windows
1227 Tablet* dc = tablet;
1230 Led_Size pictSize = imageSize;
1232 Led_Rect ourBoundsRect = drawInto;
1233 ourBoundsRect.SetRight (ourBoundsRect.GetLeft () + pictSize.h + 2 * margin.h);
1234 CoordinateType embedBottom = useBaseLine;
1235 CoordinateType embedTop = embedBottom - pictSize.v;
1236 Assert (embedTop >= drawInto.top);
1237 Assert (embedBottom <= drawInto.bottom);
1238 Led_Rect innerBoundsRect = Led_Rect (Led_Point (embedTop, drawInto.GetLeft () + margin.h), pictSize);
1240#if qStroika_Platform_Windows
1241 dc->SetTextColor (foreColor.GetOSRep ());
1242 dc->SetBkColor (backColor.GetOSRep ());
1244 if (pixelsDrawn !=
nullptr) {
1245 *pixelsDrawn = ourBoundsRect.GetWidth ();
1250static void DIBDrawSegment (
const Led_DIB* dib, Tablet* tablet, [[maybe_unused]]
Color foreColor, [[maybe_unused]]
Color backColor,
1251 const Led_Rect& drawInto, CoordinateType useBaseLine, DistanceType* pixelsDrawn,
const Led_Size& imageSize,
1252 const Led_Size& margin)
noexcept
1257#if qStroika_Platform_Windows
1258 Tablet* dc = tablet;
1261 Led_Size dibImageSize = imageSize;
1263 Led_Rect ourBoundsRect = drawInto;
1264 ourBoundsRect.right = ourBoundsRect.left + dibImageSize.h + 2 * margin.h;
1265 CoordinateType embedBottom = useBaseLine;
1266 CoordinateType embedTop = embedBottom - dibImageSize.v;
1267 Assert (embedTop >= drawInto.GetTop ());
1268 Assert (embedBottom <= drawInto.GetBottom ());
1269 Led_Rect innerBoundsRect = Led_Rect (Led_Point (embedTop, drawInto.GetLeft () + margin.h), dibImageSize);
1271 if (pixelsDrawn !=
nullptr) {
1272 *pixelsDrawn = ourBoundsRect.GetWidth ();
1275#if qStroika_Platform_Windows
1276 dc->SetTextColor (foreColor.GetOSRep ());
1277 dc->SetBkColor (backColor.GetOSRep ());
1280#if qStroika_Platform_Windows
1282 const void* lpBits = Led_GetDIBBitsPointer (dib);
1284 ::StretchDIBits (dc->m_hDC, innerBoundsRect.left, innerBoundsRect.top, innerBoundsRect.GetWidth (), innerBoundsRect.GetHeight (), 0, 0,
1285 dibImageSize.h, dibImageSize.v, lpBits, dib, DIB_RGB_COLORS, SRCCOPY);
#define RequireNotNull(p)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
virtual size_t GetFlavorSize(Led_ClipFormat clipFormat) const =0
basic_string< SDKChar > SDKString