Текст, нарисованный на стекле, становится размытым при уменьшении альфа-канала

Я делаю несколько обновлений компонента TIceTabSet (Chrome tabs ). Одним из таких изменений является добавление прозрачности. Все работает нормально, кроме текста. По мере того, как альфа-канал фона становится ниже, текст становится все более и более размытым. Вот скриншот.

enter image description here

Вот код, который рисует вкладки. Большая часть этого исходного кода TIceTabSet. Я просто добавил несколько изменений, чтобы сделать вкладки прозрачными. Код также был немного изменен для скриншота примера. Команда DrawText внизу — это место, где текст рисуется на холсте.

procedure TIceTabSet.InnerDraw(Canvas: TCanvas; TabRect: TRect; Item: TIceTab);
var
  graphics : TGPGraphics;
  Pen: TGPPen;
  Brush: TGPSolidBrush;
  path, linePath: TGPGraphicsPath;
  linGrBrush: TGPLinearGradientBrush;
  font: TGPFont;
  solidBrush: TGPSolidBrush;
  rectF: TGPRectF;
  stringFormat: TGPStringFormat;
  DC: HDC;
  marginRight: integer;
  iconY, iconX: integer;
  textStart: Extended;
  startColor, EndColor, textColor, borderColor: cardinal;
  borderWidth: Integer;
  TabProperties: TIceTabProperties;
  Alpha: Byte;
begin
  DC := Canvas.Handle;

  TabProperties := GetTabProperties(Item);

  Alpha := Item.Index * 50;

  startColor := MakeGDIPColor(TabProperties.TabStyle.StartColor, Alpha);// TabProperties.TabStyle.Alpha);
  endColor := MakeGDIPColor(TabProperties.TabStyle.StopColor, Alpha); //TabProperties.TabStyle.Alpha);
  textColor := MakeGDIPColor(TabProperties.Font.Color, 255); //TabProperties.TabStyle.Alpha);
  borderColor := MakeGDIPColor(TabProperties.BorderColor, TabProperties.TabStyle.Alpha);
  borderWidth := TabProperties.BorderWidth;

  graphics := TGPGraphics.Create(DC);
  Brush := TGPSolidBrush.Create(borderColor);
  Pen:= TGPPen.Create(borderColor);
  Font := GetGDIPFont(Canvas, FTabActive.Font); //TabProperties.Font);
  try
    graphics.SetSmoothingMode(SmoothingModeHighQuality);

    pen.SetWidth(borderWidth);

    path := TGPGraphicsPath.Create();
    try
      path.AddBezier(TabRect.Left, TabRect.Bottom, TabRect.Left + FTabShape.LeftEdgeWidth / 2, TabRect.Bottom, TabRect.Left + FTabShape.LeftEdgeWidth / 2, TabRect.Top, TabRect.Left + FTabShape.LeftEdgeWidth, TabRect.Top);
      path.AddLine(TabRect.Left + FTabShape.LeftEdgeWidth, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top);
      path.AddBezier(TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth / 2, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth / 2, TabRect.Bottom, TabRect.Right, TabRect.Bottom);

      linePath := TGPGraphicsPath.Create;
      try
        linePath.AddPath(path, false);
        path.AddLine(TabRect.Right, TabRect.Bottom, TabRect.Left, TabRect.Bottom);

        linGrBrush := TGPLinearGradientBrush.Create(
          MakePoint(0, TabRect.Top),
          MakePoint(0, TabRect.Bottom),
          startColor,
          endColor);
        try
          graphics.DrawPath(pen, linePath);

          graphics.FillPath(linGrBrush, path);
        finally
          linGrBrush.Free;
        end;
      finally
        linePath.Free;
      end;
    finally
      path.Free;
    end;

    marginRight := 0;

    if TabDisplaysCloseButton(Item) then
    begin
      if (HighLightTabClose = Item) and
         (FTabCloseButton.ShowCircle) then
      begin
        pen.SetWidth(1);

        pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorHotTrack, 255));
        brush.SetColor(MakeGDIPColor(FTabCloseButton.CircleColorHotTrack, 255));

        graphics.FillEllipse(brush, TabRect.Right - FTabShape.RightEdgeWidth - 7 - 2,
                                    TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2) - 3,
                                    (TabRect.Right - FTabShape.RightEdgeWidth) - (TabRect.Right - FTabShape.RightEdgeWidth - 7) + 6,
                                    (TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2)) - (TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2)) + 6);

        graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth - 5, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 5) div 2),
                               TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 5) div 2));

        graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 5) div 2),
                               TabRect.Right - FTabShape.RightEdgeWidth - 5, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 5) div 2));
      end
      else
      begin
        pen.SetWidth(2);

        if HighlightTabClose = Item then
          pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorHotTrack, 255))
        else
          pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorNormal, 255));

        graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth - 7, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2),
                               TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2));

        graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2),
                               TabRect.Right - FTabShape.RightEdgeWidth - 7, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2));
      end;

      marginRight := 10;
    end;

    solidBrush:= TGPSolidBrush.Create(MakeGDIPColor(textColor, 255));

    stringFormat:= TGPStringFormat.Create;
    stringFormat.SetAlignment(StringAlignmentNear);
    stringFormat.SetLineAlignment(StringAlignmentCenter);
    stringFormat.SetTrimming(StringTrimmingEllipsisCharacter);
    stringFormat.SetFormatFlags(StringFormatFlagsNoWrap);

    SelectClipRgn(Canvas.Handle, 0);
    textStart := TabRect.Left + FTabShape.LeftEdgeWidth;
    iconX := 0;
    iconY := 0;

    if Assigned(Images) and (Item.ImageIndex <> -1) then
    begin
      iconY := TabRect.Top + ((TabRect.Bottom - TabRect.Top - Images.Height) div 2);
      iconX := Round(textStart);
      textStart := textStart + Images.Width + 4;
    end;

    rectF := MakeRect(textStart, TabRect.Top, TabRect.Right - textStart - FTabShape.RightEdgeWidth - marginRight,
      TabRect.Bottom - TabRect.Top);

    // ****** Text is drawn here *******
    if rectF.Width > 10 then
      graphics.DrawString(format('Alpha: %d', [Alpha]), -1, font, rectF, stringFormat, solidBrush);
    // *********************************

  finally
    font.Free;
    solidBrush.Free;
    Pen.Free;
    graphics.Free;
  end;

  if Assigned(Images) and
    (Item.ImageIndex <> -1) then
    Images.Draw(Canvas, iconX, iconY, Item.ImageIndex, true);
end;

Скачать полный исходник можно здесь . Пожалуйста, имейте в виду, что это незавершенная работа. Исходный текст будет отправлен обратно автору оригинала, когда он будет завершен.

Обновление 1

Изменение кода, предложенное TLama, безусловно, помогает, но не решает проблему полностью.Вот как теперь выглядит текст:

enter image description here

...вот как выглядит Google Chrome:

enter image description here

Обновление 2

Вот как это выглядит с TextRenderingHintSingleBitPerPixelGridFit .

enter image description here

Я пробовал все варианты, и TextRenderingHintAntiAlias ​​дает наилучшие результаты.

10
задан norgepaul 3 July 2012 в 13:27
поделиться