📄 aafont.pas
字号:
p1.x := Round(-wCos + hSin); // 左下
p1.y := Round(-wSin - hCos);
p2.x := Round(wCos + hSin); // 右下
p2.y := Round(wSin - hCos);
p3.x := Round(-wCos - hSin); // 左上
p3.y := Round(-wSin + hCos);
p4.x := Round(wCos - hSin); // 右上
p4.y := Round(wSin + hCos);
// 计算包含矩形
Rect.Left := MinIntValue([p1.x, p2.x, p3.x, p4.x]);
Rect.Right := MaxIntValue([p1.x, p2.x, p3.x, p4.x]);
Rect.Top := MinIntValue([p1.y, p2.y, p3.y, p4.y]);
Rect.Bottom := MaxIntValue([p1.y, p2.y, p3.y, p4.y]);
Result.cx := Rect.Right - Rect.Left;
Result.cy := Rect.Bottom - Rect.Top;
StartPoint.x := p1.x + Result.cx div 2;
StartPoint.y := p1.y + Result.cy div 2;
end;
//文本高、宽,旋转后起始位置
function TAAMask.TextExtentEx(s: string; var Point: TPoint): TSize;
var
LogFont: TLogFont;
TempFont, SaveFont: HFONT;
DC: HDC;
Beta: Double;
begin
Result.cx := 0;
Result.cy := 0;
if (AAFont = nil) or (AAFont.Canvas = nil) then
Exit;
DC := GetDC(0);
try
GetObject(AAFont.Canvas.Font.Handle, SizeOf(TLogFont), @LogFont);
with LogFont do
begin
lfHeight := lfHeight * Scale;
lfWidth := lfWidth * Scale;
Beta := lfEscapement * Pi / 1800;
end;
TempFont := CreateFontIndirect(LogFont);
try
SaveFont := SelectObject(DC, TempFont);
GetTextExtentPoint32(DC, PChar(s), Length(s), Result);
Result.cx := (Result.cx + Scale - 1) div Scale;
Result.cy := (Result.cy + Scale - 1) div Scale;
if (fsItalic in AAFont.Canvas.Font.Style) and (Length(s) > 0) then
Result.cx := Result.cx + Round(Result.cx / Length(s) * ItalicAdjust);
SelectObject(DC, SaveFont);
if Beta <> 0 then
begin
Result := GetRotateSize(Result, Beta, Point);
end;
finally
DeleteObject(TempFont);
end;
finally
ReleaseDC(0, DC);
end;
end;
//文本高、宽
function TAAMask.TextExtent(s: string): TSize;
var
Point: TPoint;
begin
Result := TextExtentEx(s, Point);
end;
//文本高度
function TAAMask.TextHeight(s: string): Integer;
begin
Result := TextExtent(s).cy;
end;
//文本宽度
function TAAMask.TextWidth(s: string): Integer;
begin
Result := TextExtent(s).cx;
end;
{ TAABlend }
//--------------------------------------------------------//
//前景背景蒙板混合类 //
//--------------------------------------------------------//
//初始化
constructor TAABlend.Create(AOwner: TAAFont);
begin
AAFont := AOwner;
FForeBmp := TBitmap.Create;
FForeBmp.PixelFormat := pf24bit;
RGBBmp := TBitmap.Create;
RGBBmp.PixelFormat := pf24bit;
end;
//释放
destructor TAABlend.Destroy;
begin
ForeBmp.Free;
RGBBmp.Free;
inherited;
end;
//赋值
procedure TAABlend.Assign(Source: TPersistent);
begin
if Source is TAABlend then
ForeBmp.Assign(TAABlend(Source).ForeBmp)
else
inherited Assign(Source);
end;
//文本按前景色与背景混合
procedure TAABlend.Blend(x, y: Integer; AColor: TColor; Alpha: TAlpha;
Mask: TAAMask);
var
r, b, g: Byte;
AAlpha: DWORD;
pMask: PByteArray;
pRGB: PRGBArray;
Weight: Byte;
i, j: Integer;
Color: TColor;
begin
if (AAFont = nil) or (AAFont.Canvas = nil) then
Exit;
RGBBmp.Width := Mask.Width;
RGBBmp.Height := Mask.Height;
Color := ColorToRGB(AColor); //实际前景色
r := GetRValue(Color); //色彩分量
g := GetGValue(Color);
b := GetBValue(Color);
AAlpha := Alpha * $100 div 100; //透明度
RGBBmp.Canvas.Brush.Assign(AAFont.Canvas.Brush);
if RGBBmp.Canvas.Brush.Style <> bsSolid then
Bitblt(RGBBmp.Canvas.Handle, 0, 0, RGBBmp.Width, RGBBmp.Height,
AAFont.Canvas.Handle, x, y, SRCCOPY) //透明
else
FillRect(RGBBmp.Canvas.Handle, Bounds(0, 0, RGBBmp.Width, RGBBmp.Height), 0);
for j := 0 to RGBBmp.Height - 1 do
begin
pMask := Mask.ScanLine(j);
pRGB := RGBBmp.ScanLine[j];
for i := 0 to RGBBmp.Width - 1 do
begin
Weight := pMask^[i] * AAlpha shr 8; //混合系数
if Weight <> 0 then
begin
if Weight = 255 then
begin //前景色
pRGB^[i].rgbtBlue := b;
pRGB^[i].rgbtGreen := g;
pRGB^[i].rgbtRed := r;
end
else
begin //混合
Inc(pRGB^[i].rgbtBlue, Weight * (b - pRGB^[i].rgbtBlue) shr 8);
Inc(pRGB^[i].rgbtGreen, Weight * (g - pRGB^[i].rgbtGreen) shr 8);
Inc(pRGB^[i].rgbtRed, Weight * (r - pRGB^[i].rgbtRed) shr 8);
end;
end;
end;
end;
Bitblt(AAFont.Canvas.Handle, x, y, RGBBmp.Width, RGBBmp.Height,
RGBBmp.Canvas.Handle, 0, 0, SRCCOPY); //输出
end;
//文本按纹理与背景混合
procedure TAABlend.BlendEx(x, y: Integer; Alpha: TAlpha; Mask: TAAMask);
var
AAlpha: WORD;
pMask: PByteArray;
pRGB: PRGBArray;
pFore: PRGBArray;
Weight: Byte;
i, j: Integer;
begin
if (AAFont = nil) or (AAFont.Canvas = nil) then
Exit;
if (ForeBmp.Width <> Mask.Width) or (ForeBmp.Height <> Mask.Height)
or (ForeBmp.PixelFormat <> pf24bit) then
begin //错误的纹理图
raise EInvalidForeBmp.Create('Invalid foreground bitmap!');
Exit;
end;
RGBBmp.Width := Mask.Width;
RGBBmp.Height := Mask.Height;
AAlpha := Alpha * $100 div 100; //透明度
RGBBmp.Canvas.Brush.Assign(AAFont.Canvas.Brush);
if RGBBmp.Canvas.Brush.Style <> bsSolid then
Bitblt(RGBBmp.Canvas.Handle, 0, 0, RGBBmp.Width, RGBBmp.Height,
AAFont.Canvas.Handle, x, y, SRCCOPY) //透明
else
FillRect(RGBBmp.Canvas.Handle, Bounds(0, 0, RGBBmp.Width, RGBBmp.Height), 0);
for j := 0 to RGBBmp.Height - 1 do
begin
pMask := Mask.ScanLine(j);
pRGB := RGBBmp.ScanLine[j];
pFore := ForeBmp.ScanLine[j];
for i := 0 to RGBBmp.Width - 1 do
begin
Weight := pMask^[i] * AAlpha shr 8; //混合系数
if Weight = 255 then
begin
pRGB^[i].rgbtBlue := pFore^[i].rgbtBlue;
pRGB^[i].rgbtGreen := pFore^[i].rgbtGreen;
pRGB^[i].rgbtRed := pFore^[i].rgbtRed;
end
else if Weight <> 0 then //混合
begin
Inc(pRGB^[i].rgbtBlue, Weight * (pFore^[i].rgbtBlue - pRGB^[i].rgbtBlue) shr
8);
Inc(pRGB^[i].rgbtGreen, Weight * (pFore^[i].rgbtGreen - pRGB^[i].rgbtGreen) shr
8);
Inc(pRGB^[i].rgbtRed, Weight * (pFore^[i].rgbtRed - pRGB^[i].rgbtRed) shr 8);
end;
end;
end;
Bitblt(AAFont.Canvas.Handle, x, y, RGBBmp.Width, RGBBmp.Height,
RGBBmp.Canvas.Handle, 0, 0, SRCCOPY); //输出
end;
//设置前景纹理图
procedure TAABlend.SetForeBmp(const Value: TBitmap);
begin
FForeBmp.Assign(Value);
end;
{ TAAFont }
//--------------------------------------------------------//
//平滑字体类 //
//--------------------------------------------------------//
//初始化
constructor TAAFont.Create(ACanvas: TCanvas);
begin
FCanvas := ACanvas;
Mask := TAAMask.Create(Self);
Blend := TAABlend.Create(Self);
end;
//释放
destructor TAAFont.Destroy;
begin
Mask.Free;
Blend.Free;
inherited;
end;
//取显示精度
function TAAFont.GetQuality: TAAQuality;
begin
Result := Mask.Quality;
end;
//设置显示精度
procedure TAAFont.SetQuality(const Value: TAAQuality);
begin
Mask.Quality := Value;
end;
//文本高、宽
function TAAFont.TextExtent(s: string): TSize;
begin
Result := Mask.TextExtent(s);
end;
//文本高度
function TAAFont.TextHeight(s: string): Integer;
begin
Result := TextExtent(s).cy;
end;
//文本宽度
function TAAFont.TextWidth(s: string): Integer;
begin
Result := TextExtent(s).cx;
end;
//平滑文本输出
procedure TAAFont.TextOut(x, y: Integer; s: string; Alpha: TAlpha;
Blur: TBlurStrength);
begin
if (Canvas = nil) or (s = '') then
Exit;
Mask.DrawMask(s); //创建字体蒙板
if Blur > 0 then
Mask.Blur(Blur); //模糊
Blend.Blend(x, y, Canvas.Font.Color, Alpha, Mask); //与前景色混合
end;
{ TAAFontEx }
//--------------------------------------------------------//
//增强平滑字体类 //
//--------------------------------------------------------//
//初始化
constructor TAAFontEx.Create(ACanvas: TCanvas);
begin
inherited Create(ACanvas);
FEffect := TAAEffect.Create(nil);
end;
//释放
destructor TAAFontEx.Destroy;
begin
FEffect.Free;
inherited;
end;
//设置显示风格
procedure TAAFontEx.SetEffect(const Value: TAAEffect);
begin
FEffect.Assign(Value);
end;
//计算阴影偏移
function TAAFontEx.GetShadowPoint: TPoint;
begin
if Effect.Shadow.Enabled then
begin
if Effect.Shadow.OffsetX > 0 then
Result.x := Effect.Shadow.OffsetX
else
Result.x := 0;
if Effect.Shadow.OffsetY > 0 then
Result.y := Effect.Shadow.OffsetY
else
Result.y := 0;
end
else
begin
Result.x := 0;
Result.y := 0;
end;
end;
//计算文本偏移
function TAAFontEx.GetTextPoint: TPoint;
begin
if Effect.Shadow.Enabled then
begin
if Effect.Shadow.OffsetX < 0 then
Result.x := Abs(Effect.Shadow.OffsetX)
else
Result.x := 0;
if Effect.Shadow.OffsetY < 0 then
Result.y := Abs(Effect.Shadow.OffsetY)
else
Result.y := 0;
end
else
begin
Result.x := 0;
Result.y := 0;
end;
end;
//文本高、宽
function TAAFontEx.TextExtent(s: string): TSize;
var
LogFont: TLogFont;
TempFont: HFONT;
SaveFont: TFont;
begin
if Effect.Angle <> 0 then
begin
GetObject(Canvas.Font.Handle, SizeOf(TLogFont), @LogFont);
LogFont.lfEscapement := Effect.Angle * 10;
SaveFont := TFont.Create;
try
SaveFont.Assign(Canvas.Font);
TempFont := CreateFontIndirect(LogFont);
Canvas.Font.Handle := TempFont;
Result := inherited TextExtent(s);
Canvas.Font.Assign(SaveFont);
DeleteObject(TempFont);
finally
SaveFont.Free;
end;
end
else
Result := inherited TextExtent(s);
if Effect.Shadow.Enabled then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -