Точное вычисление ширины текста в метрических единицах - PullRequest
5 голосов
/ 17 февраля 2012

Я хочу вычислить точную ширину текста в метрических единицах данной строки. Мой псевдокод выглядит так:

Bitmap.Canvas.Assign(Font);
PixelWidth := Bitmap.Canvas.TextWidth(Font)
MetricWidth := PtToMM * (PixelWidth * 72.0 / GetScreenDPI);

PtToMM - это константа, которая определяется как 0.352777778. Это довольно точно для некоторых шрифтов и размеров шрифта, но для других оно либо слишком мало, либо слишком велико. Я много экспериментировал с другими возможностями, такими как GetCharWidth32 и GetCharABCWidths, также с режимом отображения MM_LOMETRIC, но я просто не могу заставить его работать. Эта проблема преследует меня, поэтому, пожалуйста, кто-нибудь может помочь и показать мне, где я не прав. Большое спасибо!

РЕДАКТИРОВАТЬ Я проверил одну строку: метрическая ширина вычисляется как 4,17 см, ширина фактической распечатки (измеряется на бумаге) составляет 4,4 см (шрифт Times New Roman, размер 12).

1 Ответ

0 голосов
/ 17 февраля 2012

Я не тестировал его всесторонне, но, похоже, он дает правильные результаты.Результат - ширина текста в тысячных миллиметра.Эта функция не поддерживает перенос слов и другие специальные соображения.

Также обратите внимание, что при работе с принтером неправильная регистрация печати может «растянуть» текст.

Также обратите внимание, что для принтеранапример, изменение разрешения печати с 300 до 1200 страниц в секунду также изменит результат.

uses
  ConvUtils, stdConvs ;

function CalcRequiredTextWidth(aDC : HDC; aFont : TFont; const asText: string): Double;
var vCanvas : TCanvas;
    iPixelsWidth : Integer;
    dInchWidth : Double;
    iFontSize : Integer;
begin
  vCanvas := TCanvas.Create;
  try
    vCanvas.Handle := aDC;

    vCanvas.Font.Assign(aFont);
    iFontSize := vCanvas.Font.Size;
    vCanvas.Font.PixelsPerInch := GetDeviceCaps(aDC, LOGPIXELSY);
    vCanvas.Font.Size := iFontSize;

    iPixelsWidth := vCanvas.TextExtent(asText).cx;

    dInchWidth := iPixelsWidth / GetDeviceCaps(vCanvas.Handle, LOGPIXELSX);

    Result := Convert(dInchWidth, duInches, duMicrons);

  finally
    vCanvas.Free;
  end;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...