4

I have a small Delphi 10.3.3 app that has some text editing functions, using a TMemo where the user type the text.

I'm trying to include some formatting options, something as this site provides :

http://qaz.wtf/u/convert.cgi?text=How%20do%20it%20on%20Delphi

When i copy the 'circled' text from the site above and paste on my memo, it works, appears 'circled'. But i want to give my user the ability to apply the formatting inside my app.

For instance, i want to have a speedbutton to apply the 'circle' formatting to the current TMemo selected text : the user selects a text , click on this speedbutton and then the selected text gets the 'circled' formatting.

enter image description here

delphirules
  • 5,259
  • 13
  • 43
  • 87

1 Answers1

4

This is rather easy. If you look at the Unicode chart for the enclosed alphanumerics, you realise that the following mapping is valid:

function EncircleChr(AChr: Char): Char;
begin
  case AChr of
    '0':
      Result := Chr($24EA);
    '1'..'9':
      Result := Chr($2460 + Ord(AChr) - Ord('1'));
    'a'..'z':
      Result := Chr($24D0 + Ord(AChr) - Ord('a'));
    'A'..'Z':
      Result := Chr($24B6 + Ord(AChr) - Ord('A'));
  else
    Result := AChr;
  end;
end;

Hence, with

function Encircle(const S: string): string;
var
  i: Integer;
begin
  SetLength(Result, S.Length);
  for i := 1 to S.Length do
    Result[i] := EncircleChr(S[i]);
end;

and

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.SelText := Encircle(Memo1.SelText);
end;

you get the desired behaviour:

Screenshot of a TMemo with letters and digits transformed into their encircled versions.

Andreas Rejbrand
  • 95,177
  • 8
  • 253
  • 351
  • 1
    @delphirules: Great! And of course you can do the same thing for the other types of decorations. – Andreas Rejbrand Aug 22 '20 at 18:04
  • Sure, will do that ! Thanks again , have a nice weekend ! – delphirules Aug 22 '20 at 18:18
  • I'm trying to do the same approach for another decorations but somehow it's not working. For instance, i'm trying to apply negative circle and getting the codes here : https://www.compart.com/en/unicode/search?q=negative#characters . It works for codes with 4 digits (like $278A), but not with 5 digits (like $1F150) ; in this case crazy chars appears. Do you know why ? :) i – delphirules Aug 22 '20 at 20:19
  • 2
    @delphirules: Delphi's character type is two bytes wide (=four hexadecimal digits), and so it only supports the [BMP](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane). Personally, I try to avoid characters outside the BMP, because they are not as easy to work with. In addition, few fonts have glyphs for characters outside the BMP anyway... – Andreas Rejbrand Aug 22 '20 at 20:26
  • I understood, thank you for the info ! I could workaround it by creating a vector with all negative circled and manually mapping it to the result – delphirules Aug 22 '20 at 20:29
  • 5
    @delphirules: A character beyond the BMP is represented as two Delphi characters (surrogate pairs). Hence, you need a Delphi string to represent such a character. You get get such a string by doing e.g. `Char.ConvertFromUtf32($1F17F)`. – Andreas Rejbrand Aug 22 '20 at 20:35