📄 pdfjpfonts.pas
字号:
PdfJpCMap;
{ TPdfType0Font }
// SetData
procedure TPdfType0Font.SetData(AData: TPdfDictionary);
var
DescendantFonts: TPdfArray;
DescendantFont: TPdfDictionary;
Discriptor: TPdfDictionary;
CIDWidthItem: TPdfCIDWidthItem;
i, j: integer;
WidthsRoot, Widths: TPdfArray;
TmpCID: integer;
begin
inherited SetData(AData);
// set font attributes from specified font data.
DescendantFonts := Data.PdfArrayByName('DescendantFonts');
DescendantFont := TPdfDictionary(DescendantFonts.Items[0]);
FDW := DescendantFont.PdfNumberByName('DW').Value;
Discriptor := DescendantFont.PdfDictionaryByName('FontDescriptor');
FMissingWidth := Discriptor.PdfNumberByName('MissingWidth').Value;
FArray := TList.Create;
WidthsRoot := DescendantFont.PdfArrayByName('W');
// create widths array from "W"attribute.
i := 0;
while i < WidthsRoot.ItemCount do
begin
// "W"attribute constst of forrowing data format.
// type1. <CID of first char> <CID if last char> <char width>
// type2. <CID od first char> "["<array of char widths>"]"
if not (WidthsRoot.Items[i] is TPdfNumber) then
raise EPdfInvalidValue.Create('invalid W array start pos..');
TmpCID := TPdfNumber(WidthsRoot.Items[i]).Value;
inc(i);
if i >= WidthsRoot.ItemCount then Break;
if (WidthsRoot.Items[i] is TPdfNumber) then
begin
// type1 data format.
CIDWidthItem := TPdfCIDWidthItem.Create;
CIDWidthItem.StrCID := TmpCID;
inc(i);
if not (WidthsRoot.Items[i] is TPdfNumber) then
raise EPdfInvalidValue.Create('invalid W array end pos..')
else
CIDWidthItem.EndCID := TPdfNumber(WidthsRoot.Items[i]).Value;
end
else
begin
if not (WidthsRoot.Items[i] is TPdfArray) then
raise EPdfInvalidValue.Create('invalid W array value..');
// type2 data format.
Widths := TPdfArray(WidthsRoot.Items[i]);
for j := 0 to Widths.ItemCount - 1 do
begin
CIDWidthItem := TPdfCIDWidthItem.Create;
CIDWidthItem.StrCID := TmpCID;
CIDWidthItem.EndCID := TmpCID;
CIDWidthItem.Width := TPdfNumber(Widths.Items[j]).Value;
FArray.Add(CIDWidthItem);
inc(TmpCID);
end;
end;
inc(i);
end;
end;
// CidWidth
function TPdfType0Font.CidWidth(CID: integer): Word;
var
i: integer;
CIDWidthItem: TPdfCIDWidthItem;
begin
result := 0;
for i := 0 to FArray.Count - 1 do
begin
CIDWidthItem := TPdfCIDWidthItem(FArray.Items[i]);
if CIDWidthItem.EndCID >= CID then
if CIDWidthItem.StrCID <= CID then
begin
result := CIDWidthItem.Width;
Break;
end
else
Break;
end;
end;
// GetCharWidth
function TPdfType0Font.GetCharWidth(AText: string; APos: integer): integer;
var
CID: integer;
begin
result := 0;
CID := FCharToCMap(AText, APos);
if CID = -1 then Exit;
result := CidWidth(CID);
if result = 0 then
if ByteType(AText, APos) = mbSingleByte then
result := FMissingWidth
else
result := FDW;
end;
// Destroy
destructor TPdfType0Font.Destroy;
var
i: integer;
begin
if FArray <> nil then
begin
for i := FArray.Count - 1 downto 0 do
TObject(FArray.Items[i]).Free;
FArray.Free;
end;
inherited;
end;
// SetCharToCMap
procedure TPdfType0Font.SetCharToCMap(AFunc: TCharToCMap);
begin
FCharToCMap := AFunc;
end;
{ TPdfJpFont }
// AddDescriptorItem
procedure TPdfJpFont.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
begin
end;
// GetFontName
function TPdfJpFont.GetFontName: string;
begin
result := '';
end;
// .AddDescendantFontItem
procedure TPdfJpFont.AddDescendantFontItem(ADescendantFont: TPdfDictionary);
begin
end;
// Create
constructor TPdfJpFont.Create(AXref: TPdfXref; AName: string);
var
FFontDescriptor: TPdfDictionary;
FFont: TPdfDictionary;
FDescendantFont: TPdfDictionary;
FDescendantFontArray: TPdfArray;
FCIDSystemInfo: TPdfDictionary;
begin
inherited Create(AXref, AName);
FFont := TPdfDictionary.CreateDictionary(AXref);
AXref.AddObject(FFont);
FFont.AddNameItem('BaseFont', GetFontName);
// create descendant font.
FDescendantFont := TPdfDictionary.CreateDictionary(AXref);
AXref.AddObject(FDescendantFont);
FDescendantFontArray := TPdfArray.CreateArray(AXref);
FDescendantFontArray.AddItem(FDescendantFont);
FFont.AddItem('DescendantFonts', FDescendantFontArray);
AddStrElements(FDescendantFont, CIDTYPE2_JP_FONT_STR_TABLE);
FDescendantFont.AddNameItem('BaseFont', GetFontName);
FCIDSystemInfo := TPdfDictionary.CreateDictionary(AXref);
with FCIDSystemInfo do
begin
AddItem('Registry', TPdfText.CreateText('Adobe'));
AddItem('Ordering', TPdfText.CreateText('Japan1'));
AddItem('Supplement', TPdfNumber.CreateNumber(2));
end;
with FDescendantFont do
begin
AddItem('CIDSystemInfo', FCIDSystemInfo);
AddNumberItem('DW', CIDTYPE2_JP_FONT_DEFAULT_WIDTH);
end;
AddDescendantFontItem(FDescendantFont);
// create font descriptor.
FFontDescriptor := TPdfDictionary.CreateDictionary(AXref);
AXref.AddObject(FFontDescriptor);
FFontDescriptor.AddNameItem('Type', 'FontDescriptor');
FFontDescriptor.AddNameItem('BaseFont', GetFontName);
AddIntElements(FFontDescriptor, CIDTYPE2_JP_FONT_DISC_INT_TABLE);
AddDescriptorItem(FFontDescriptor);
FFontDescriptor.AddItem('FontBBox',
TPdfArray.CreateNumArray(AXref, CIDTYPE2_JP_FONT_BBOX));
FDescendantFont.AddItem('FontDescriptor', FFontDescriptor);
SetData(FFont);
end;
// AddDescendantFontItem
procedure TPdfJpFixedFont.AddDescendantFontItem(ADescendantFont: TPdfDictionary);
var
FWidths: TPdfArray;
begin
FWidths := TPdfArray.CreateNumArray(nil, CIDTYPE2_JP_FONT_WIDTH_ARRAY);
ADescendantFont.AddItem('W', FWidths);
end;
constructor TPdfJpFixedFont.Create(AXref: TPdfXref; AName: string);
begin
inherited Create(AXref, AName);
AddStrElements(Data, TYPE0_JP_FONT_STR_TABLE);
SetCharToCMap(@CharToCMap_90MS_RKSJ_H);
end;
{ TPdfGothic }
procedure TPdfGothic.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', 0);
AddNumberItem('StemV', 78);
end;
end;
function TPdfGothic.GetFontName: string;
begin
result := 'Gothic';
end;
{ TPdfGothicBold }
procedure TPdfGothicBold.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH +
PDF_FONT_FOURCE_BOLD;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', 0);
AddNumberItem('StemV', 156);
end;
end;
function TPdfGothicBold.GetFontName: string;
begin
result := 'Gothic,Bold';
end;
{ TPdfGothicItalic }
// AddDescriptorItem
procedure TPdfGothicItalic.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', -11);
AddNumberItem('StemV', 78);
end;
end;
// GetFontName
function TPdfGothicItalic.GetFontName: string;
begin
result := 'Gothic,Italic';
end;
{ TPdfGothicBoldItalic }
// AddDescriptorItem
procedure TPdfGothicBoldItalic.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH +
PDF_FONT_FOURCE_BOLD;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', -11);
AddNumberItem('StemV', 156);
end;
end;
// GetFontName
function TPdfGothicBoldItalic.GetFontName: string;
begin
result := 'Gothic,BoldItalic';
end;
{ TPdfMincyo }
// AddDescriptorItem
procedure TPdfMincyo.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH +
PDF_FONT_SERIF;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', 0);
AddNumberItem('StemV', 78);
end;
end;
function TPdfMincyo.GetFontName: string;
begin
result := 'Mincyo';
end;
{ TPdfMincyoBold }
// AddDescriptorItem
procedure TPdfMincyoBold.AddDescriptorItem(AFontDescriptor: TPdfDictionary);
var
Flags: integer;
begin
with AFontDescriptor do
begin
Flags := PDF_FONT_SYMBOLIC +
PDF_FONT_FIXED_WIDTH +
PDF_FONT_FOURCE_BOLD +
PDF_FONT_SERIF;
AddNumberItem('Flags', Flags);
AddNumberItem('ItalicAngle', 0);
AddNumberItem('StemV', 156);
end;
end;
// GetFontName
function TPdfMincyoBold.GetFontName: string;
begin
result := 'Mincyo,Bold';
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -