lazarus linux下使用powerPDF控件中文乱码及英文和中文等宽的解决方法


      lazarus linux下使用powerPDF中文乱码按网上的修改方法还是存在出现乱码问题,经跟踪powerpdf源码,除启用PRreort.pas {$DEFINE USE_GBFONTS}外,还要修改pdfdoc.pas TPdfCanvas.ShowText(const s: string),并添加LConvEncoding单元,使用UTF8ToCP936将UTF8转为CP936。

pdfdoc.pas:
procedure
TPdfCanvas.ShowText(const s: string); var FString: string; begin if _HasMultiByteString(s) then FString := '<' + _StrToHex(s) + '>'; else FString := '(' + _EscapeText(s) + ')'; WriteString(FString + ' Tj'#10); end;

改为:

uses LConvEncoding;//添加这个单元

procedure
TPdfCanvas.ShowText(const s: string); var FString: string; begin FString := '<' + _StrToHex(LConvEncoding.UTF8ToCP936(s,true)) + '>'; WriteString(FString + ' Tj'#10); end;

       按上面的方法就可以解决中文乱码的问题,但存在英文和中文字体等宽的问题,要解决英文宽度和中文等宽的问题还需在pdfGBFonts.pas增加英文字符宽度定义及procedure TPdfGBFixedFont.AddDescendantFontItem(ADescendantFont: TPdfDictionary)修改为:

const
//2022-04-06 LBZ 增加字符宽度定义,解决英文和中文等宽的问题

FIXED_GB_W_ARRAY: array[32..200] of Integer = (
600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
600,600,600,600,600,600,600,600,600,600,600);

 
procedure TPdfGBFixedFont.AddDescendantFontItem(ADescendantFont: TPdfDictionary);
var
  FWidths,FWidthsRoot: TPdfArray;
begin
  FWidths := TPdfArray.CreateNumArray(nil, CIDTYPE2_GB_FONT_WIDTH_ARRAY);
  ADescendantFont.AddItem('W', FWidths);
 //以下是修正英文字体宽度 2022.04.06 LBZ

   FWidthsRoot := TPdfArray.CreateArray(nil);
   FWidthsRoot.AddItem(TPdfNumber.CreateNumber(780));
   FWidths := TPdfArray.CreateNumArray(nil,FIXED_GB_W_ARRAY);
   FWidthsRoot.AddItem(FWidths);
   ADescendantFont.AddItem('W', FWidthsRoot);
   //以上是修正英文字体宽度 2022.04.06 LBZ

end;

   修改后的powerpdf在windows和linux都可以正确保存含中文的pdf,也解决了英文宽度和中文等宽的问题。

 解决英文与中文等宽后的PDF:

修改后的PowerPDF下载链接:

https://pan.baidu.com/s/1UzmzyAB1mqegyzUasSiLtg
提取码: vvqn