gpt4 book ai didi

delphi - 如何使用 AggPas 绘制埃 (Å)?

转载 作者:行者123 更新时间:2023-12-01 23:08:37 26 4
gpt4 key购买 nike

总结:

没有找到如何使用 AggPas 库输出埃符号。

==================================================

AggPas 库中的文本绘制函数采用 PAnsiChar 参数。我想知道如何使用 PAnsiChar 指向包含埃 (Å) 的文本?

  SetThreadLocale($0409);                                       // No difference.

ShowMessage(Chr(0197)); // Correct
ShowMessage(AnsiString(Chr(0197))); // Wrong - question mark
ShowMessage(PAnsiChar(Chr(0197))); // AV
ShowMessage(UTF8String(Chr(0197))); // Correct
ShowMessage(UTF8Encode(Chr(0197))); // Correct
ShowMessage(RawByteString(Chr(0197))); // Wrong - question mark

ShowMessage(AnsiString(UTF8String(Chr(0197)))); // Wrong - question mark
ShowMessage(AnsiString(UTF8Encode(Chr(0197)))); // Correct

ShowMessage(RawByteString(UTF8String(Chr(0197)))); // Wrong - question mark
ShowMessage(RawByteString(UTF8Encode(Chr(0197)))); // Correct

ShowMessage(PAnsiChar(AnsiString(UTF8Encode(Chr(0197))))); // Wrong - strange character
ShowMessage(PAnsiChar(RawByteString(UTF8Encode(Chr(0197))))); // Wrong - strange character

为方便起见,以下代码中的 DrawTextCenterAligned 过程无法输出埃字母。

    unit u2DRenderEngine_aggpas;

interface

uses
u2DRenderEngine, uMathVector3D,
agg_2D,
Graphics, IniFiles, Types;

type
T2DRenderEngine_aggpas = class;

T2DRenderEngine_aggpas = class(T2DRenderEngine)

private
fFontBMP: TBitmap;
fVG: Agg2D;

protected

function GetActualStringBoundingBox(aText: string; aFont: TFont)
: TRect; override;

public

constructor Create;
destructor Destroy; override;

procedure AttachBMP(aBMP: TBitmap; flip_y: Boolean);

procedure Flush; override;

procedure DrawLine(aP, bP: TPoint3D; aPen: TPen); override;
procedure DrawCircle(Center: TPoint3D; Radius: Extended;
R, G, B: Integer); override;
procedure FillCircle(Center: TPoint3D; Radius: Extended;
R, G, B: Integer); override;
procedure DrawPolygon(aPts: TAPoint3D; R, G, B: Integer); override;
procedure FillPolygon(aPts: TAPoint3D; R, G, B: Integer); override;

procedure DrawTextLeftAligned(aLeft: TPoint3D; aText: string; aFont: TFont;
clearBackground: Boolean); override;
procedure DrawTextCenterAligned(aCenter: TPoint3D; aText: string;
aFont: TFont; clearBackground: Boolean); override;

end;

implementation

uses
u2DUtils_Vcl, SysUtils, Math;

{ TRenderEngine_2D_aggpas }

constructor T2DRenderEngine_aggpas.Create;
begin
inherited;

fFontBMP := TBitmap.Create;
fFontBMP.Width := 2;
fFontBMP.Height := 2;

fVG.Construct;
end;

destructor T2DRenderEngine_aggpas.Destroy;
begin

inherited;
end;

procedure T2DRenderEngine_aggpas.AttachBMP(aBMP: TBitmap; flip_y: Boolean);
var
tmpBuffer: pointer;
tmpStride: Integer;
begin
if aBMP.Empty then
raise Exception.Create('AttachBMP: aBMP is Empty!');

if aBMP.PixelFormat <> pf32bit then
raise Exception.Create('AttachBMP: aBMP should be 32bit!');

tmpStride := Integer(aBMP.ScanLine[1]) - Integer(aBMP.ScanLine[0]);

if tmpStride < 0 then
tmpBuffer := aBMP.ScanLine[aBMP.Height - 1]
else
tmpBuffer := aBMP.ScanLine[0];

if flip_y then
tmpStride := tmpStride * -1;

fVG.attach(tmpBuffer, aBMP.Width, aBMP.Height, tmpStride);
end;

procedure T2DRenderEngine_aggpas.Flush;
begin
end;

procedure T2DRenderEngine_aggpas.DrawLine(aP, bP: TPoint3D; aPen: TPen);
begin
fVG.line(aP.X, aP.Y, bP.X, bP.Y);
end;

procedure T2DRenderEngine_aggpas.DrawCircle(Center: TPoint3D; Radius: Extended;
R, G, B: Integer);
begin
fVG.lineColor(R, G, B);
fVG.noFill;
fVG.ellipse(Center.X, Center.Y, Radius, Radius);
end;

procedure T2DRenderEngine_aggpas.FillCircle(Center: TPoint3D; Radius: Extended;
R, G, B: Integer);
begin
fVG.fillColor(R, G, B);
fVG.noLine;
fVG.ellipse(Center.X, Center.Y, Radius, Radius);
end;

procedure T2DRenderEngine_aggpas.DrawPolygon(aPts: TAPoint3D; R, G, B: Integer);
var
Len, I: Integer;
poly: array of double;
begin
Len := Length(aPts);

SetLength(poly, Len * 2);
for I := 0 to Len - 1 do
begin
poly[2 * I] := aPts[I].X;
poly[2 * I + 1] := aPts[I].Y;
end;

fVG.lineColor(R, G, B);
fVG.noFill;
fVG.polygon(@poly[0], 4);
end;

procedure T2DRenderEngine_aggpas.FillPolygon(aPts: TAPoint3D; R, G, B: Integer);
var
Len, I: Integer;
poly: array of double;
begin
Len := Length(aPts);

SetLength(poly, Len * 2);
for I := 0 to Len - 1 do
begin
poly[2 * I] := aPts[I].X;
poly[2 * I + 1] := aPts[I].Y;
end;

fVG.fillColor(R, G, B);
fVG.noLine;
fVG.polygon(@poly[0], 4);
end;

procedure T2DRenderEngine_aggpas.DrawTextLeftAligned(aLeft: TPoint3D;
aText: string; aFont: TFont; clearBackground: Boolean);
var
tmpRect: TRect;
tmpRectWidth, tmpRectHeight: Integer;
tmpPt: TPoint3D;
begin
tmpRect := GetActualStringBoundingBox(aText, aFont);
tmpRectWidth := tmpRect.Right - tmpRect.Left;
tmpRectHeight := tmpRect.Bottom - tmpRect.Top;
tmpPt.X := aLeft.X;
tmpPt.Y := aLeft.Y - tmpRectHeight;

if clearBackground then
begin
fVG.fillColor(255, 255, 255);
fVG.noLine;
fVG.Rectangle(tmpPt.X, tmpPt.Y, tmpPt.X + tmpRectWidth,
tmpPt.Y + tmpRectHeight);
end;

// Font & Colors
fVG.fillColor(0, 0, 0);
fVG.noLine;
fVG.TextHints(True);
if Agg2DUsesFreeType then
fVG.Font(PAnsiChar(AnsiString(UTF8Encode(LowerCase(aFont.Name) + '.ttf'))),
Abs(aFont.Height))
else
fVG.Font('Arial', 40.0);
// Text
fVG.Text(tmpPt.X, tmpPt.Y + tmpRectHeight, PAnsiChar(AnsiString(aText)));
end;

procedure T2DRenderEngine_aggpas.DrawTextCenterAligned(aCenter: TPoint3D;
aText: string; aFont: TFont; clearBackground: Boolean);
var
tmpRect: TRect;
tmpRectWidth, tmpRectHeight: Integer;
tmpPt: TPoint3D;
begin
tmpRect := GetActualStringBoundingBox(aText, aFont);
tmpRectWidth := tmpRect.Right - tmpRect.Left;
tmpRectHeight := tmpRect.Bottom - tmpRect.Top;
tmpPt.X := aCenter.X - tmpRectWidth / 2.0;
tmpPt.Y := aCenter.Y - tmpRectHeight / 2.0;

if clearBackground then
begin
fVG.fillColor(255, 255, 255);
fVG.noLine;
fVG.Rectangle(tmpPt.X, tmpPt.Y, tmpPt.X + tmpRectWidth,
tmpPt.Y + tmpRectHeight);
end;

// Font & Colors
fVG.fillColor(0, 0, 0);
fVG.noLine;
fVG.TextHints(True);
if Agg2DUsesFreeType then
fVG.Font(PAnsiChar(AnsiString(UTF8Encode(LowerCase(aFont.Name) + '.ttf'))),
Abs(aFont.Height))
else
fVG.Font('Arial', 40.0);
// Text
fVG.Text(tmpPt.X, tmpPt.Y + tmpRectHeight, PAnsiChar(AnsiString(aText)));
end;

function T2DRenderEngine_aggpas.GetActualStringBoundingBox(aText: string;
aFont: TFont): TRect;
var
tmpRectWidth, tmpRectHeight: Integer;
begin
Self.fFontBMP.Canvas.Font.Assign(aFont);
tmpRectWidth := Self.fFontBMP.Canvas.TextWidth(aText);
tmpRectHeight := Self.fFontBMP.Canvas.TextHeight(aText);

// 2011-03-07 hard-coded
tmpRectWidth := Ceil(tmpRectWidth * 1.05);
// 2011-03-07 hard-coded
tmpRectHeight := Ceil(tmpRectHeight * 0.70);

FillChar(Result, SizeOf(Result), 0);
Result.Right := tmpRectWidth;
Result.Bottom := tmpRectHeight;
end;

end.

最佳答案

如果设备将其输入视为 PAnsiChar,那么您就完蛋了。除非系统上的默认代码页可以对 Å 字符进行编码,否则根本无法将该信息放入 ANSI CHAR 中。如果这样的编码可用,那么现在显示问号的所有例程都将显示正确的字符。

<小时/>

稍长的信息:

Unicode正在编码大量的字符,包括所有书面语言的所有字符、特殊符号、音符,空间如此之大,竟然有克林贡字符的编码! Ansi 字符使用表查找进行编码,该表查找将可以在一个字节中编码的值映射到一组 Unicode 字符。

使用 AnsiString 时,一次只能使用少于 256 个 Unicode 字符。当您尝试将一个 Unicode 字符编码为一个 AnsiString 时,您实际上会在代码页表中进行查找,寻找指向原始 Unicode 字符的代码。如果没有这样的编码可用,您会得到著名的问号!

<小时/>

这是一个将字符串转换为 UTF8 字符串并将其作为 AnsiString 返回的例程(所有 UTF8 实际上都是有效的 - 但毫无意义 - AnsiString):

function Utf8AsAnsiString(s:string):AnsiString;
var utf8s:UTF8String;
begin
utf8s := UTF8String(s);
SetLength(Result, Length(utf8s));
if Length(utf8s) > 0 then
Move(utf8s[1], Result[1], Length(utf8s));
end;

您可以传递该函数的结果并希望该单元可以处理UTF8。祝你好运。

关于delphi - 如何使用 AggPas 绘制埃 (Å)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5251317/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com