Ваш вопрос вызвал у меня любопытство, поэтому я попробовал, и вот результат:
Рисование цветных шрифтов в целом
Очевидно, FMX поддерживает это из коробки позже.версии, но не в Сиэтле, который у меня случается.Я не знаю, если VCL также поддерживает его из коробки в вашей версии, но если нет, вы можете добиться с помощью Direct2D.Хитрость заключается в рисовании текста с использованием опции D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
.
В Сиэтле (10) эта константа не определена и, к сожалению, не используется в функциях, совместимых с TCanvas по умолчанию.Но вы можете вызвать DrawText
или одну из других функций самостоятельно и указать опцию.
Общая структура основана на этой документации Embarcadero .Остальное взято из TDirect2DCanvas в сочетании с DrawText документацией .
uses Vcl.Direct2D, Winapi.D2D1;
{$R *.dfm}
procedure TForm1.FormPaint(Sender: TObject);
const
str: string = 'xyz???????????';
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT = 4;
var
c: TDirect2DCanvas;
r: D2D_RECT_F;
begin
c := TDirect2DCanvas.Create(Canvas.Handle, Rect(0, 0, 100, 100));
c.BeginDraw;
try
r.left := 0;
r.top := 0;
r.right := 100;
r.bottom := 50;
// Brush determines the font color.
c.Brush.Color := clBlack;
c.RenderTarget.DrawText(
PWideChar(str), Length(Str), c.Font.Handle, r, c.Brush.Handle,
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
finally
c.EndDraw;
c.Free;
end;
end;
Этот маленький кусочек кода работает довольно уродливо (с точки зрения позиционирования текста), но выМожно также заглянуть в TDirect2DCanvas и скопировать реализацию одного из его текстовых методов, чтобы создать функцию для вывода текста определенным способом, который вы хотите.И после этого должно быть довольно легко применить это к вашему собственному потомку TGraphicControl или TCustomControl для создания ярлыка, поддерживающего эмодзи.
Выполнение этого в TEdit
Для управленияэто в TEdit сложнее, так как рисование текста (и смайликов) обрабатывается самим элементом управления.Должна быть возможность создать потомка TEdit и / или подключить его к сообщению WM_PAINT и закрасить текст, используя тот же трюк, но я не уверен, насколько хорошо это будет работать.
Я сделал быстрый снимок, но он не очень хорошо работает, особенно при редактировании.Итак, я сделал этого потомка TEdit.Когда он сфокусирован, он рисует текст обычным способом, и цветные эмодзи будут черно-белыми и разделятся на два символа (эмодзи и символ сочетания цветов).Когда редактирование теряет фокус, пользовательский код рисования вступает во владение, что хорошо работает в этом сценарии.Может быть, вы можете попытаться отшлифовать его, чтобы он работал и во время редактирования, но тогда вам нужно принять во внимание прокрутку, расположение каретки и другие вещи.Для потомка TMemo это будет еще сложнее.Я надеюсь, что вы довольны только цветным дисплеем.: -)
type
TMyEdit = class(Vcl.StdCtrls.TEdit)
protected
procedure PaintWindow(DC: HDC); override;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
uses Vcl.Direct2D, Winapi.D2D1;
{$R *.dfm}
const
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT = 4;
constructor TMyEdit.Create(AOwner: TComponent);
begin
inherited;
DoubleBuffered := True;
end;
procedure TMyEdit.PaintWindow(DC: HDC);
var
c: TDirect2DCanvas;
r: D2D_RECT_F;
begin
// Default drawing when focused. Otherwise do the custom draw.
if Focused then
begin
Inherited;
Exit;
end;
c := TDirect2DCanvas.Create(dc, ClientRect);
c.BeginDraw;
try
r.left := ClientRect.Left;
r.top := ClientRect.Top;
r.right := ClientRect.Right;
r.bottom := ClientRect.Bottom;
// Basic font properties
c.Font.Assign(Font);
// Brush determines the font color.
c.Brush.Color := Font.Color;
c.RenderTarget.DrawText(
PWideChar(Text), Length(Text), c.Font.Handle, r, c.Brush.Handle,
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
finally
c.EndDraw;
c.Free;
end;
end;