Problem with <font size> and <font color> tags

I use TCastleControl to build the interface of my program, and I needed to display text with texture tags for verification:

 "Using HTML tags to make <b>bold</b>, <i>italic and <b>bold and italic</b></i>.
Can also <font color=\"#6666ff\">change text color</font>
Can also <font size=\"-2\">change size</font>."

some tags are readable and some are not


This is how I create components:

var
  Form1: TForm1;
  HeaderImage: TCastleImageControl;
  FooterImage: TCastleImageControl;
  LeftImage: TCastleImageControl;
  ReadPostScrool: TCastleScrollView;
  ReadPostBack: TCastleImageControl;
  ReadPost: TCastleLabel;
  ReadPostFonts:TCastleFontFamily;
  ReadPostRegullar:TCastleFont;
  ReadPostItalic:TCastleFont;
  ReadPostBold:TCastleFont;
  ReadPostBoldItallic:TCastleFont;
  WindowDragAllowed:boolean=False;
  MouseXCoord: integer = 0;
  MouseYCoord: integer = 0;
  HTMLLoader:TStringList=nil;


...


procedure TForm1.FormCreate(Sender: TObject);
var
  testcontr:TInternalChildrenControls;
  WidthInsideScrollArea: Single;
begin

try
    HTMLLoader:=TStringList.Create;
    HTMLLoader.LoadFromFile('test2.txt');
    HeaderImage := TCastleImageControl.Create(Self);
    HeaderImage.URL:='data/Header.png';
    HeaderImage.Anchor(hpLeft, 0);
    HeaderImage.Anchor(vpTop, 0);
    HeaderImage.Width:=Browser.ClientWidth;
    HeaderImage.Height:=64;
    HeaderImage.Stretch:=True;
    HeaderImage.OnPress:=@HeaderPress;
    HeaderImage.OnRelease:=@HeaderRelease;
    Browser.Controls.InsertFront(HeaderImage);
    FooterImage := TCastleImageControl.Create(Self);
    FooterImage.URL:='data/Footer.png';
    FooterImage.Anchor(hpLeft, 0);
    FooterImage.Anchor(vpBottom, 0);
    FooterImage.Width:=Browser.ClientWidth;
    FooterImage.Height:=64;
    FooterImage.Stretch:=True;
    Browser.Controls.InsertFront(FooterImage);
    LeftImage := TCastleImageControl.Create(Self);
    LeftImage.URL:='data/LeftPanel.png';
    LeftImage.Anchor(hpLeft, 0);
    LeftImage.Anchor(vpTop, -64);
    LeftImage.Width:=384;
    LeftImage.Height:=Browser.ClientHeight-128;
    LeftImage.Stretch:=True;
    Browser.Controls.InsertFront(LeftImage);
    ReadPostScrool := TCastleScrollView.Create(Self);
    ReadPostScrool.Anchor(hpLeft, 384);
    ReadPostScrool.Anchor(vpTop, -64);
    ReadPostScrool.Width:=Browser.ClientWidth-384;
    ReadPostScrool.Height:=Browser.ClientHeight-128;    
     ReadPostBack := TCastleImageControl.Create(Self);
    ReadPostBack.URL:='data/LeftPanel.png';
    ReadPostBack.Anchor(hpLeft, 0);
    ReadPostBack.Anchor(vpTop, 0);
    ReadPostBack.Height:=Browser.ClientHeight-128;
    ReadPostBack.Stretch:=True;
    ReadPost := TCastleLabel.Create(self);
    ReadPostRegullar:=TCastleFont.Create(self);
    ReadPostRegullar.URL:='data/fonts/DejaVuSans.ttf';
    ReadPostItalic:=TCastleFont.Create(self);
    ReadPostItalic.URL:='data/fonts/DejaVuSans-Oblique.ttf';
    ReadPostBold:=TCastleFont.Create(self);
    ReadPostBold.URL:='data/fonts/DejaVuSans-Bold.ttf';
    ReadPostBoldItallic:=TCastleFont.Create(self);
    ReadPostBoldItallic.URL:='data/fonts/DejaVuSans-BoldOblique.ttf';
    ReadPostFonts:=TCastleFontFamily.Create(self);
    ReadPostFonts.Regular:=ReadPostRegullar;
    ReadPostFonts.Italic:=ReadPostItalic;
    ReadPostFonts.Bold:=ReadPostBold;
    ReadPostFonts.BoldItalic:=ReadPostBoldItallic;
    ReadPost.CustomFont:=ReadPostFonts;
    ReadPost.Html:=True;
    ReadPost.Color:= Black;
    ReadPost.Text.Assign(HTMLLoader);
   ReadPostScrool.ScrollArea.InsertFront(ReadPostBack);
     ReadPostScrool.ScrollArea.InsertFront(ReadPost);
     WidthInsideScrollArea := ReadPostScrool.EffectiveWidthForChildren
    - ReadPostScrool.EffectiveScrollBarWidth;
     ReadPostBack.Width := WidthInsideScrollArea;

     ReadPostBack.Height := ReadPost.EffectiveHeight;
     ReadPost.MaxWidth := WidthInsideScrollArea;
     ReadPostScrool.ScrollArea.Width := WidthInsideScrollArea;
     ReadPostScrool.ScrollArea.Height := ReadPost.EffectiveHeight;
    Browser.Controls.InsertFront(ReadPostScrool);
except
  on e:Exception do
  begin
    WriteLn('error: '+e.Message);
  end;
end;

Please tell me what I’m doing wrong?

Hi!

It seems you have added additional backslashes inside a string, your text and screenshots show:

...<font color=\"#6666ff\">...

These backslashes are not valid in HTML. Just write

...<font color="#6666ff">...

and HTML tags will be recognized OK. Looking at your code, you load text from test2.txt file, so you should remove backslashes from there.

( Maybe you wrote the backslashes because they have been present in the JSON contents in examples/fonts/html_text/data/gameviewmain.castle-user-interface ? If yes, then the explanation is that the backslashes are present in JSON because strings in JSON are surrounded by double quotes, so in JSON encoding backslashes are added when one wants to have a literal double quote in the output. But these backslashes are then stripped when reading JSON into a string (like Pascal string) in memory. )

P.S. As an unrelated suggestion: your code defines a lot of components using Pascal. I would suggest to define them instead using CGE editor, and just load the design from Pascal. Designing such components in CGE editor will allow to experiment with their properties much faster.

Thanks a lot! I’ll try later…

I thought about it, but in the future all resources will be loaded from a single file via TStream, can I somehow transfer configuration data without specifying the url?

All things in CGE can be loaded from an arbitrary TStream (not just from a URL). There are methods like LoadFromStream or overloads (like TSerializedComponent.Create) to take a TStream instead of an URL, always.

If you find something that’s missing such capability, please report :slight_smile: It is our design goal to always allow loading from TStream.

Thank you for your hard work! I will definitely tell you if I notice something :wink:, but first I need to study the engine :sweat_smile:

1 Like

Yes, thank you, the initial question has been resolved, but
I’m sorry, just so as not to create unnecessary posts, a couple more questions

  1. is the tag supported?
  2. how difficult will it be to write an inheritor class for TCastleLabel with the ability to edit?

Note that we generally recommend creating new threads for new questions. A separate question deserves a separate thread, so that people searching the forum can see it better, and so that talk about it can go in parallel to unrelated questions.

You meant TComponent.Tag? Yes. All CGE components descend from standard FPC/Delphi TComponent, so they have Tag property.

We have a dedicated TCastleEdit :slight_smile: It does not descend from TCastleLabel, since editing necessarily means somewhat different logic that only display (e.g. editing has cursor, and a frame typically).

Though if you want to dynamically change the label to edit, you can, just have 2 controls (TCastleLabel and TCastleEdit), synchronize their text (MyLabel.Caption and MyEdit.Text) and make only one of them Exists at given time.

Note that we don’t yet have multi-line editing, i.e. we don’t have TCastleMemo. It’s a TODO. Our TCastleEdit only handles single-line editing for now.

I’m sorry, I meant the <img src> tag

Ah! In this case the answer is no, I’m afraid – we do not support <img...> inside the label text. The HTML elements/attributes supported by TCastleLabel.Html are rather limited, see API docs here: Castle Game Engine: CastleFonts: Class TCastleAbstractFont .

To have images between text, you could just add TCastleVerticalGroup, and add TCastleLabel, then TCastleImageControl, then another TCastleLabel.

Note: If you want to have “real” HTML renderer, there are bigger projects that provide this for Pascal and embed some “real” www browser engine. Like: GitHub - salvadordf/CEF4Delphi: CEF4Delphi is an open source project to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows, Linux and MacOS. . But that’s something bigger, and you can place it on LCL / FMX / VCL form (the engine rendering would then have to be done by TCastleControl on the form, Engine on a form (VCL, FMX, LCL) using TCastleControl | Manual | Castle Game Engine ).

Our TCastleLabel.Html will likely stay somewhat limited – it’s an easy way to tweak text in the middle, but I am afraid of trying to implement there a “real” full-featured HTML renderer :slight_smile:

Good evening, no, I don’t need full html rendering, I thought CastleLabel is an analogue of TextView from android studio, it has such a spanned text class. In general, I’m writing an application that will download news, and some other data from the server, and so that the text is not completely dry, I want to add tags to the text :grinning: