Page 1 of 1

Text formatting color problem

Posted: Wed Sep 26, 2018 2:35 am
by wsy211
The novice consult.

How to achieve when encountering the string text color of the paragraph with the first letter "A:" is A color; When you encounter the string text color of the paragraph with the first letter of "B:", it changes to another color.
See rendering

How is the code implemented, thanks for your help

Re: Text formatting color problem

Posted: Thu Sep 27, 2018 10:37 am
by Sergey Tkachenko

Code: Select all

uses RVTypes;

type

  TTextColorPair = record
    Text: TRVUnicodeString;
    Color: TColor;
  end;

  TTextColorPairs = array of TTextColorPair;

// Returns color for Text from the rules listed in TextColorPairs
function GetColorForText(const Text: TRVUnicodeString;
  const TextColorPairs: TTextColorPairs): TColor;
var
  i: Integer;
begin
  Result := clNone;
  for i := Low(TextColorPairs) to High(TextColorPairs) do
    if Copy(Text, 1, Length(TextColorPairs[i].Text)) = TextColorPairs[i].Text then
    begin
      Result := TextColorPairs[i].Color;
      exit;
    end;
end;

// Returns index of in rvs.TextStyles of the style having all properties of
// rvs.TextStyles[StyleNo], but the specified color.
// If it does not exist, it is created
function GetStyleNoWithColor(rvs: TRVStyle; StyleNo: Integer; Color: TColor): Integer;
var
  TextStyle: TFontInfo;
begin
  if rvs.TextStyles[StyleNo].Color = Color then
  begin
    Result := StyleNo;
    exit;
  end;
  TextStyle := TFontInfo.Create(nil);
  TextStyle.Assign(rvs.TextStyles[StyleNo]);
  TextStyle.Color := Color;
  Result := rvs.FindTextStyle(TextStyle);
  TextStyle.Free;
end;

// Changes colors of text in rv basing on rules specified TextColorPairs
procedure ColorLines(rv: TCustomRichView; const TextColorPairs: TTextColorPairs);
var
  i: Integer;
  Color: TColor;
begin
  Color := clNone;
  for i := 0 to rv.ItemCount - 1 do
  begin
    if rv.IsParaStart(i) then
      if rv.GetItemStyle(i) >= 0 then
        Color := GetColorForText(rv.GetItemTextW(i), TextColorPairs)
      else
        Color := clNone;
    if (Color <> clNone) and (rv.GetItemStyle(i) >= 0) then
      rv.GetItem(i).StyleNo := GetStyleNoWithColor(rv.Style, rv.GetItemStyle(i), Color);
  end;
end;
How to use:

Code: Select all

var
  ColorRules: TTextColorPairs;
begin
  SetLength(ColorRules, 2);
  ColorRules[0].Text := 'A';
  ColorRules[0].Color := clRed;
  ColorRules[1].Text := 'B';
  ColorRules[1].Color := clBlue;
  ColorLines(RichViewEdit1, ColorRules);
  RichViewEdit1.Invalidate;
end;
This code changes color of all text in paragraphs. Probably, it makes sense to change only text having the default color (clWindowText).
In this case, ColorLines must be:

Code: Select all

procedure ColorLines(rv: TCustomRichView; const TextColorPairs: TTextColorPairs);
var
  i: Integer;
  Color: TColor;
begin
  Color := clNone;
  for i := 0 to rv.ItemCount - 1 do
  begin
    if rv.IsParaStart(i) then
      if rv.GetItemStyle(i) >= 0 then
        Color := GetColorForText(rv.GetItemTextW(i), TextColorPairs)
      else
        Color := clNone;
    if (Color <> clNone) and (rv.GetItemStyle(i) >= 0) and
      (rv.Style.TextStyles[rv.GetItemStyle(i)].Color = clWindowText) then
      rv.GetItem(i).StyleNo := GetStyleNoWithColor(rv.Style, rv.GetItemStyle(i), Color);
  end;
end;

Re: Text formatting color problem

Posted: Fri Sep 28, 2018 12:20 am
by wsy211
Sergey Tkachenko Thank you very much