Skip to content

Commit

Permalink
Fixed: some fonts are not justified #299
Browse files Browse the repository at this point in the history
- Cause: Some windows fonts do not define the Space character to use to insert additional pixels to justify the text.
- Fixed: TSection.Draw1.DrawTheText() justifies on its own now.
  • Loading branch information
BerndGabriel committed Jan 29, 2023
1 parent 7675171 commit 21688fa
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 31 deletions.
85 changes: 73 additions & 12 deletions source/HTMLSubs.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,6 @@ implementation
{$endif}
Htmlsbs1;


//-- BG ---------------------------------------------------------- 14.01.2012 --
function Sum(const Arr: TIntArray; StartIndex, EndIndex: Integer): Integer; overload;
{$ifdef UseInline} inline; {$endif}
Expand Down Expand Up @@ -12636,7 +12635,7 @@ function TSection.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight,
begin
Result := 0;
for I := 0 to NN - 2 do {-2 so as not to count end spaces}
if ((PStart + I)^ = ' ') or ((PStart + I)^ = #160) then
if ((PStart + I)^ = SpcChar) or ((PStart + I)^ = NbSpcChar) then
Inc(Result);
end;

Expand Down Expand Up @@ -13300,6 +13299,8 @@ function TSection.Draw1(Canvas: TCanvas; const ARect: TRect;
Start: PWideChar;
Cnt, Descent: Integer;
St: ThtString;
Dx: array of Integer;
pDx: PInteger;

function AddHyphen(P: PWideChar; N: Integer): ThtString;
var
Expand All @@ -13311,6 +13312,69 @@ function TSection.Draw1(Canvas: TCanvas; const ARect: TRect;
Result[N + 1] := ThtChar('-');
end;

function CharacterJustification(P: PWideChar; N: Integer): Integer;
var
Fit: Integer;
Size: TSize;
Ratio: Double;
Width: Integer;
Offset: Integer;
Extra: Integer;
Spaces: Integer;
Inserted: Integer;
PEnd: PWideChar;
begin
if (LR.Spaces = 0) or (LR.Extra = 0) then
begin
pDx := nil;
// TextExtent:
Result := GetTextExtent(Canvas.Handle, P, N).cx;
end
else
begin
SetLength(Dx, N);
pDx := @Dx[0];
GetTextExtentExPointW(Canvas.Handle, P, N, LR.DrawWidth, @Fit, pDx, Size);

// pDx, resp Dx contants the width of Fit partial strings. Dx[0] width of P[0], Dx[1] width of P[0] and P[1], ...
// To justify output in ExtTextOut it needs offsets from one character to the next one: Dx[0] is offset from P[0] to P[1], ...
Width := 0;
Spaces := 0;
Inserted := 0;
Ratio := LR.Extra / LR.Spaces;
PEnd := @P[N];
while P <> PEnd do
begin
Offset := pDx^ - Width; // remove length of previous partial string

// insert additional pixels at spaces
case P^ of
SpcChar,
NbSpcChar:
begin
Inc(Spaces);

// add rounded number of pixels:
Extra := Floor(Spaces * Ratio + 1E-6) - Inserted;
Inc(Inserted, Extra);
Inc(Offset, Extra);
end;
end;

Width := pDx^;
pDx^ := Offset;
Inc(pDx);
Inc(P);
end;

// Reset pDx for ExtTextOut().
pDx := @Dx[0];

// TextExtent:
Result := Size.cx + Inserted;
end;
end;

function ChkInversion(Start: PWideChar; out Count: Integer): Boolean;
var
LongCount, C: Integer;
Expand Down Expand Up @@ -13687,31 +13751,28 @@ function TSection.Draw1(Canvas: TCanvas; const ARect: TRect;
end
else
begin
if LR.Spaces = 0 then
SetTextJustification(Canvas.Handle, 0, 0)
else
SetTextJustification(Canvas.Handle, LR.Extra, LR.Spaces);
SetTextJustification(Canvas.Handle, 0, 0);
if not IsWin95 then {use TextOutW}
begin
if (Cnt - I <= 0) and LR.Shy then
begin
St := AddHyphen(Start, Tmp);
TextOutW(Canvas.Handle, CPx, CPy, PWideChar(St), Length(St));
CP1x := CPx + GetTextExtent(Canvas.Handle, PWideChar(St), Length(St)).cx;
CP1x := CPx + CharacterJustification(PWideChar(St), Length(St));
ExtTextOutW(Canvas.Handle, CPx, CPy, 0, nil, PWideChar(St), Length(St), pDx);
end
else
begin
TextOutW(Canvas.Handle, CPx, CPy, Start, Tmp);
CP1x := CPx + GetTextExtent(Canvas.Handle, Start, Tmp).cx;
CP1x := CPx + CharacterJustification(Start, Tmp);
ExtTextOutW(Canvas.Handle, CPx, CPy, 0, nil, Start, Tmp, pDx);
end
end
else
begin {Win95}
{Win95 has bug which extends text underline for proportional font in TextOutW.
Use clipping to clip the extra underline.}
CP1x := CPx + GetTextExtent(Canvas.Handle, Start, Tmp).cx;
CP1x := CPx + CharacterJustification(Start, Tmp);
ARect := Rect(CPx, Y - LR.LineHt - LR.SpaceBefore - YOffset, CP1x, Y - YOffset + 1);
ExtTextOutW(Canvas.Handle, CPx, CPy, ETO_CLIPPED, @ARect, Start, Tmp, nil)
ExtTextOutW(Canvas.Handle, CPx, CPy, ETO_CLIPPED, @ARect, Start, Tmp, pDx);
end;
end;
Document.Printed := True;
Expand Down
3 changes: 0 additions & 3 deletions source/HTMLUn2.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1277,9 +1277,6 @@ function GetTextExtent(DC: HDC; P: PWideChar; N: Integer): TSize;
var
Dummy: Integer;
begin
if not IsWin32Platform then
GetTextExtentExPointW(DC, P, N, 0, @Dummy, nil, Result)
else
GetTextExtentPoint32W(DC, P, N, Result); {win95, 98 ME}
end;

Expand Down
6 changes: 3 additions & 3 deletions source/HtmlBuffer.pas
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
HtmlViewer Version 11.7
Copyright (c) 2010-2016 by Bernd Gabriel
HtmlViewer Version 11.10
Copyright (c) 2010-2023 by Bernd Gabriel
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down Expand Up @@ -99,7 +99,7 @@ TBuffConverterClass = class of TBuffConverter;
// Although loading files via ThtStringList.LoadFromFile(FileName) produces WideChars,
// these WideChars may not be coded correctly, if the file is not a unicode file.
// For those cases you can apply a CodePage to the TBuffString versions of Convert()/Create().
// Or you can used the PByte versions with the InitialCodePage parameters and set InitialCodePage to CP_UTF16LE.
// Or you can use the PByte versions with the InitialCodePage parameters and set InitialCodePage to CP_UTF16LE.
//
// Avoid passing such raw ThtStringList.Text to HtmlViewer.
// HtmlViewer assumes correct unicode in ThtString.
Expand Down
26 changes: 14 additions & 12 deletions source/HtmlFonts.pas
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
Version 11.10
Copyright (c) 1995-2008 by L. David Baldwin
Copyright (c) 2008-2022 by HtmlViewer Team
Copyright (c) 2008-2023 by HtmlViewer Team
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down Expand Up @@ -143,20 +143,22 @@ procedure TFontInfoArray.Assign(Source: TFontInfoArray);
{----------------TMyFont.Assign}

procedure ThtFont.Assign(Source: TPersistent);
var
SourceFont: ThtFont absolute Source;
begin
if Source is ThtFont then
begin
PixelsPerInch := ThtFont(Source).PixelsPerInch;
bgColor := ThtFont(Source).bgColor;
tmHeight := ThtFont(Source).tmHeight;
tmDescent := ThtFont(Source).tmDescent;
tmExternalLeading := ThtFont(Source).tmExternalLeading;
tmAveCharWidth := ThtFont(Source).tmAveCharWidth;
tmMaxCharWidth := ThtFont(Source).tmMaxCharWidth;
tmCharset := ThtFont(Source).tmCharset;
CharExtra := ThtFont(Source).CharExtra;
EmSize := ThtFont(Source).EmSize;
ExSize := ThtFont(Source).ExSize;
PixelsPerInch := SourceFont.PixelsPerInch;
bgColor := SourceFont.bgColor;
tmHeight := SourceFont.tmHeight;
tmDescent := SourceFont.tmDescent;
tmExternalLeading := SourceFont.tmExternalLeading;
tmAveCharWidth := SourceFont.tmAveCharWidth;
tmMaxCharWidth := SourceFont.tmMaxCharWidth;
tmCharset := SourceFont.tmCharset;
CharExtra := SourceFont.CharExtra;
EmSize := SourceFont.EmSize;
ExSize := SourceFont.ExSize;
end;
inherited Assign(Source);
end;
Expand Down
3 changes: 2 additions & 1 deletion source/HtmlGlobals.pas
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ ThtBitmap = class(TBitmap)
FfChar = ThtChar(#12);
CrChar = ThtChar(#13);
SpcChar = ThtChar(' ');
NbSpcChar = ThtChar(#160); // Unbreakable Space, Unicode value for Html entity &nbsp;
DotChar = ThtChar('.');
LessChar = ThtChar('<');
MinusChar = ThtChar('-');
Expand Down Expand Up @@ -726,7 +727,7 @@ function FindSpaces(PStart : PWideChar; const ACount : Integer) : Integer;
begin
Result := 0;
for I := 0 to ACount - 2 do {-2 so as not to count end spaces}
if ((PStart + I)^ = ' ') or ((PStart + I)^ = #160) then
if ((PStart + I)^ = SpcChar) or ((PStart + I)^ = NbSpcChar) then
Inc(Result);
end;

Expand Down

0 comments on commit 21688fa

Please sign in to comment.