1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2001, Sven2
6 * Copyright (c) 2017-2022, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// markup tags for fonts
19
20#pragma once
21
22#include <Standard.h>
23#include <StdBuf.h>
24
25#include <format>
26
27class CBltTransform;
28
29// one markup tag
30class CMarkupTag
31{
32public:
33 CMarkupTag *pPrev{}, *pNext{};
34
35 CMarkupTag() {}
36 virtual ~CMarkupTag() {}
37
38 virtual void Apply(CBltTransform &rBltTrf, bool fDoClr, uint32_t &dwClr) = 0; // assign markup
39 virtual const char *TagName() = 0; // get character string for this tag
40 virtual std::string ToMarkup() { return std::format(fmt: "<{}>", args: TagName()); }
41};
42
43// markup tag for italic text
44class CMarkupTagItalic : public CMarkupTag
45{
46public:
47 CMarkupTagItalic() : CMarkupTag() {}
48
49 virtual void Apply(CBltTransform &rBltTrf, bool fDoClr, uint32_t &dwClr) override; // assign markup
50 virtual const char *TagName() override { return "i"; }
51};
52
53// markup tag for colored text
54class CMarkupTagColor : public CMarkupTag
55{
56private:
57 uint32_t dwClr; // color
58
59public:
60 CMarkupTagColor(uint32_t dwClr) : CMarkupTag(), dwClr(dwClr) {}
61
62 virtual void Apply(CBltTransform &rBltTrf, bool fDoClr, uint32_t &dwClr) override; // assign markup
63 virtual const char *TagName() override { return "c"; }
64 virtual std::string ToMarkup() override { return std::format(fmt: "<{} {:x}>", args: TagName(), args&: dwClr); }
65};
66
67// markup rendering functionality for text
68class CMarkup
69{
70private:
71 CMarkupTag *pTags, *pLast; // tag list; single linked
72 bool fDoClr; // set if color changes should be made (not in text shadow!)
73
74 void Push(CMarkupTag *pTag)
75 {
76 if ((pTag->pPrev = pLast)) pLast->pNext = pTag; else pTags = pTag; pLast = pTag;
77 }
78
79 CMarkupTag *Pop()
80 {
81 CMarkupTag *pL = pLast; if (!pL) return nullptr; if ((pLast = pL->pPrev)) pLast->pNext = nullptr; else pTags = nullptr; return pL;
82 }
83
84public:
85 CMarkup(bool fDoClr) { pTags = pLast = nullptr; this->fDoClr = fDoClr; }
86
87 ~CMarkup()
88 {
89 CMarkupTag *pTag = pTags, *pNext; while (pTag) { pNext = pTag->pNext; delete pTag; pTag = pNext; }
90 }
91
92 bool Read(const char **ppText, bool fSkip = false); // get markup from text
93 bool SkipTags(const char **ppText); // extract markup from text; return whether end is reached
94
95 void Apply(CBltTransform &rBltTrf, uint32_t &dwClr) // assign markup to vertices
96 {
97 for (CMarkupTag *pTag = pTags; pTag; pTag = pTag->pNext) pTag->Apply(rBltTrf, fDoClr, dwClr);
98 }
99
100 std::string ToMarkup();
101 std::string ToCloseMarkup();
102
103 bool Clean() { return !pTags; } // empty?
104
105 static bool StripMarkup(char *szText); // strip any markup codes from given text buffer
106 static bool StripMarkup(class StdStrBuf *sText); // strip any markup codes from given text buffer
107};
108