|
@@ -871,6 +871,8 @@ type
|
|
TPDFPageClass = class of TPDFPage;
|
|
TPDFPageClass = class of TPDFPage;
|
|
|
|
|
|
|
|
|
|
|
|
+ { TPDFSection }
|
|
|
|
+
|
|
TPDFSection = Class(TCollectionItem)
|
|
TPDFSection = Class(TCollectionItem)
|
|
private
|
|
private
|
|
FTitle: String;
|
|
FTitle: String;
|
|
@@ -886,6 +888,8 @@ type
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ { TPDFSectionList }
|
|
|
|
+
|
|
TPDFSectionList = Class(TCollection)
|
|
TPDFSectionList = Class(TCollection)
|
|
private
|
|
private
|
|
function GetS(AIndex : Integer): TPDFSection;
|
|
function GetS(AIndex : Integer): TPDFSection;
|
|
@@ -895,16 +899,19 @@ type
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ { TPDFFont }
|
|
|
|
+
|
|
TPDFFont = class(TCollectionItem)
|
|
TPDFFont = class(TCollectionItem)
|
|
private
|
|
private
|
|
FIsStdFont: boolean;
|
|
FIsStdFont: boolean;
|
|
FName: String;
|
|
FName: String;
|
|
FFontFilename: String;
|
|
FFontFilename: String;
|
|
|
|
+ FFontStream: TMemoryStream;
|
|
FTrueTypeFile: TTFFileInfo;
|
|
FTrueTypeFile: TTFFileInfo;
|
|
{ stores mapping of Char IDs to font Glyph IDs }
|
|
{ stores mapping of Char IDs to font Glyph IDs }
|
|
FTextMappingList: TTextMappingList;
|
|
FTextMappingList: TTextMappingList;
|
|
FSubsetFont: TStream;
|
|
FSubsetFont: TStream;
|
|
- procedure PrepareTextMapping;
|
|
|
|
|
|
+ procedure PrepareTextMapping(aStream: TStream = nil);
|
|
procedure SetFontFilename(const AValue: string);
|
|
procedure SetFontFilename(const AValue: string);
|
|
procedure GenerateSubsetFont;
|
|
procedure GenerateSubsetFont;
|
|
public
|
|
public
|
|
@@ -913,7 +920,9 @@ type
|
|
{ Returns a string where each character is replaced with a glyph index value instead. }
|
|
{ Returns a string where each character is replaced with a glyph index value instead. }
|
|
function GetGlyphIndices(const AText: UnicodeString): AnsiString;
|
|
function GetGlyphIndices(const AText: UnicodeString): AnsiString;
|
|
procedure AddTextToMappingList(const AText: UnicodeString);
|
|
procedure AddTextToMappingList(const AText: UnicodeString);
|
|
|
|
+ procedure LoadFromStream(aStream: TStream);
|
|
Property FontFile: string read FFontFilename write SetFontFilename;
|
|
Property FontFile: string read FFontFilename write SetFontFilename;
|
|
|
|
+ Property FontStream: TMemoryStream read FFontStream;
|
|
Property Name: String Read FName Write FName;
|
|
Property Name: String Read FName Write FName;
|
|
property TextMapping: TTextMappingList read FTextMappingList;
|
|
property TextMapping: TTextMappingList read FTextMappingList;
|
|
property IsStdFont: boolean read FIsStdFont write FIsStdFont;
|
|
property IsStdFont: boolean read FIsStdFont write FIsStdFont;
|
|
@@ -921,6 +930,8 @@ type
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ { TPDFTrueTypeCharWidths }
|
|
|
|
+
|
|
TPDFTrueTypeCharWidths = class(TPDFDocumentObject)
|
|
TPDFTrueTypeCharWidths = class(TPDFDocumentObject)
|
|
private
|
|
private
|
|
FEmbeddedFontNum: integer;
|
|
FEmbeddedFontNum: integer;
|
|
@@ -1234,6 +1245,7 @@ type
|
|
Function CreateImage(const ALeft, ABottom, AWidth, AHeight: TPDFFloat; ANumber: integer) : TPDFImage;
|
|
Function CreateImage(const ALeft, ABottom, AWidth, AHeight: TPDFFloat; ANumber: integer) : TPDFImage;
|
|
Function AddFont(AName : String) : Integer; overload;
|
|
Function AddFont(AName : String) : Integer; overload;
|
|
Function AddFont(AFontFile: String; AName : String) : Integer; overload;
|
|
Function AddFont(AFontFile: String; AName : String) : Integer; overload;
|
|
|
|
+ Function AddFont(AFontStream: TStream; AName : String) : Integer; overload;
|
|
Function AddLineStyleDef(ALineWidth : TPDFFloat; AColor : TARGBColor = clBlack; APenStyle : TPDFPenStyle = ppsSolid) : Integer;
|
|
Function AddLineStyleDef(ALineWidth : TPDFFloat; AColor : TARGBColor = clBlack; APenStyle : TPDFPenStyle = ppsSolid) : Integer;
|
|
function AddLineStyleDef(ALineWidth : TPDFFloat; AColor : TARGBColor = clBlack; ADashArray : TDashArray = []) : Integer;
|
|
function AddLineStyleDef(ALineWidth : TPDFFloat; AColor : TARGBColor = clBlack; ADashArray : TDashArray = []) : Integer;
|
|
procedure AddOutputIntent(const Subtype, OutputConditionIdentifier, Info: string; ICCProfile: TStream);
|
|
procedure AddOutputIntent(const Subtype, OutputConditionIdentifier, Info: string; ICCProfile: TStream);
|
|
@@ -1735,16 +1747,22 @@ end;
|
|
|
|
|
|
{ TPDFFont }
|
|
{ TPDFFont }
|
|
|
|
|
|
-procedure TPDFFont.PrepareTextMapping;
|
|
|
|
|
|
+procedure TPDFFont.PrepareTextMapping(aStream: TStream);
|
|
begin
|
|
begin
|
|
- if FFontFilename <> '' then
|
|
|
|
|
|
+ if (FFontFilename = '') and (FFontStream=nil) then
|
|
|
|
+ exit;
|
|
|
|
+ // only create objects when needed
|
|
|
|
+ if FTextMappingList<>nil then
|
|
|
|
+ Exception.Create('TPDFFont.PrepareTextMapping already created');
|
|
|
|
+ FTextMappingList := TTextMappingList.Create;
|
|
|
|
+ FTrueTypeFile := TTFFileInfo.Create;
|
|
|
|
+ if FFontStream<>nil then
|
|
begin
|
|
begin
|
|
- // only create objects when needed
|
|
|
|
- FTextMappingList := TTextMappingList.Create;
|
|
|
|
- FTrueTypeFile := TTFFileInfo.Create;
|
|
|
|
|
|
+ FFontStream.Position:=0;
|
|
|
|
+ FTrueTypeFile.LoadFromStream(FFontStream);
|
|
|
|
+ end else
|
|
FTrueTypeFile.LoadFromFile(FFontFilename);
|
|
FTrueTypeFile.LoadFromFile(FFontFilename);
|
|
- FTrueTypeFile.PrepareFontDefinition('cp1252', True);
|
|
|
|
- end;
|
|
|
|
|
|
+ FTrueTypeFile.PrepareFontDefinition('cp1252', True);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPDFFont.SetFontFilename(const AValue: string);
|
|
procedure TPDFFont.SetFontFilename(const AValue: string);
|
|
@@ -1787,9 +1805,10 @@ end;
|
|
|
|
|
|
destructor TPDFFont.Destroy;
|
|
destructor TPDFFont.Destroy;
|
|
begin
|
|
begin
|
|
- FTextMappingList.Free;
|
|
|
|
- FTrueTypeFile.Free;
|
|
|
|
- FSubSetFont.Free;
|
|
|
|
|
|
+ FreeAndNil(FFontStream);
|
|
|
|
+ FreeAndNil(FTextMappingList);
|
|
|
|
+ FreeAndNil(FTrueTypeFile);
|
|
|
|
+ FreeAndNil(FSubSetFont);
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1835,6 +1854,18 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPDFFont.LoadFromStream(aStream: TStream);
|
|
|
|
+begin
|
|
|
|
+ if FFontStream=aStream then Exit;
|
|
|
|
+ if FFontStream<>nil then
|
|
|
|
+ raise Exception.Create('TPDFFont.SetFontStream has already a stream');
|
|
|
|
+ if FFontFilename<>'' then
|
|
|
|
+ raise Exception.Create('TPDFFont.SetFontStream has already a file');
|
|
|
|
+ FFontStream:=TMemoryStream.Create;
|
|
|
|
+ FFontStream.CopyFrom(aStream,aStream.Size-aStream.Position);
|
|
|
|
+ PrepareTextMapping;
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TPDFTrueTypeCharWidths }
|
|
{ TPDFTrueTypeCharWidths }
|
|
|
|
|
|
// TODO: (optional improvement) CID -> Unicode mappings, use ranges to generate a smaller CMap
|
|
// TODO: (optional improvement) CID -> Unicode mappings, use ranges to generate a smaller CMap
|
|
@@ -3030,7 +3061,7 @@ begin
|
|
Raise EPDF.CreateFmt(rsErrInvalidSectionPage,[AIndex]);
|
|
Raise EPDF.CreateFmt(rsErrInvalidSectionPage,[AIndex]);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TPDFSection.GetP: INteger;
|
|
|
|
|
|
+function TPDFSection.GetP: Integer;
|
|
begin
|
|
begin
|
|
if Assigned(FPages) then
|
|
if Assigned(FPages) then
|
|
Result:=FPages.Count
|
|
Result:=FPages.Count
|
|
@@ -4795,6 +4826,7 @@ var
|
|
M, Buf : TMemoryStream;
|
|
M, Buf : TMemoryStream;
|
|
E : TPDFDictionaryItem;
|
|
E : TPDFDictionaryItem;
|
|
D : TPDFDictionary;
|
|
D : TPDFDictionary;
|
|
|
|
+ aFont: TPDFFont;
|
|
begin
|
|
begin
|
|
if GetE(0).FKey.Name='' then
|
|
if GetE(0).FKey.Name='' then
|
|
GetE(0).Write(AStream) // write a charwidth array of a font
|
|
GetE(0).Write(AStream) // write a charwidth array of a font
|
|
@@ -4849,6 +4881,7 @@ begin
|
|
begin
|
|
begin
|
|
Value:=E.FKey.Name;
|
|
Value:=E.FKey.Name;
|
|
NumFnt:=StrToInt(Copy(Value, Succ(Pos(' ', Value)), Length(Value) - Pos(' ', Value)));
|
|
NumFnt:=StrToInt(Copy(Value, Succ(Pos(' ', Value)), Length(Value) - Pos(' ', Value)));
|
|
|
|
+ aFont:=Document.Fonts[NumFnt];
|
|
if poSubsetFont in Document.Options then
|
|
if poSubsetFont in Document.Options then
|
|
begin
|
|
begin
|
|
|
|
|
|
@@ -4871,9 +4904,15 @@ begin
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- M:=TMemoryStream.Create;
|
|
|
|
|
|
+ if aFont.FontStream<>nil then
|
|
|
|
+ begin
|
|
|
|
+ M:=aFont.FontStream;
|
|
|
|
+ M.Position:=0;
|
|
|
|
+ end else
|
|
|
|
+ M:=TMemoryStream.Create;
|
|
try
|
|
try
|
|
- m.LoadFromFile(Document.FontFiles[NumFnt]);
|
|
|
|
|
|
+ if aFont.FontStream=nil then
|
|
|
|
+ m.LoadFromFile(Document.FontFiles[NumFnt]);
|
|
Buf := TMemoryStream.Create;
|
|
Buf := TMemoryStream.Create;
|
|
try
|
|
try
|
|
// write fontfile stream (could be compressed or not) to a temporary buffer so we can get the size
|
|
// write fontfile stream (could be compressed or not) to a temporary buffer so we can get the size
|
|
@@ -4890,7 +4929,8 @@ begin
|
|
Buf.Free;
|
|
Buf.Free;
|
|
end;
|
|
end;
|
|
finally
|
|
finally
|
|
- M.Free;
|
|
|
|
|
|
+ if aFont.FontStream=nil then
|
|
|
|
+ M.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -5691,6 +5731,9 @@ var
|
|
s: string;
|
|
s: string;
|
|
begin
|
|
begin
|
|
Result := False;
|
|
Result := False;
|
|
|
|
+ if AFont.TextMapping<>nil then
|
|
|
|
+ exit(true);
|
|
|
|
+
|
|
if ExtractFilePath(AFont.FontFile) <> '' then
|
|
if ExtractFilePath(AFont.FontFile) <> '' then
|
|
// assume AFont.FontFile is the full path to the TTF file
|
|
// assume AFont.FontFile is the full path to the TTF file
|
|
lFName := AFont.FontFile
|
|
lFName := AFont.FontFile
|
|
@@ -5713,6 +5756,8 @@ var
|
|
N: TPDFName;
|
|
N: TPDFName;
|
|
Arr: TPDFArray;
|
|
Arr: TPDFArray;
|
|
lFontXRef: integer;
|
|
lFontXRef: integer;
|
|
|
|
+ aFilename: String;
|
|
|
|
+ TTF: TTFFileInfo;
|
|
begin
|
|
begin
|
|
lFontXRef := GlobalXRefCount; // will be used a few lines down in AddFontNameToPages()
|
|
lFontXRef := GlobalXRefCount; // will be used a few lines down in AddFontNameToPages()
|
|
|
|
|
|
@@ -5743,7 +5788,20 @@ begin
|
|
FDict.AddReference('ToUnicode', GlobalXRefCount);
|
|
FDict.AddReference('ToUnicode', GlobalXRefCount);
|
|
CreateToUnicode(EmbeddedFontNum);
|
|
CreateToUnicode(EmbeddedFontNum);
|
|
end;
|
|
end;
|
|
- FontFiles.Add(Fonts[EmbeddedFontNum].FTrueTypeFile.Filename);
|
|
|
|
|
|
+ TTF:=Fonts[EmbeddedFontNum].FTrueTypeFile;
|
|
|
|
+ aFilename:=TTF.Filename;
|
|
|
|
+ if ExtractFilename(aFilename)='' then
|
|
|
|
+ begin
|
|
|
|
+ aFilename:='';
|
|
|
|
+ if TTF.Bold then
|
|
|
|
+ aFilename:=aFilename+'Bold';
|
|
|
|
+ if TTF.ItalicAngle<>0 then
|
|
|
|
+ aFilename:=aFilename+'Italic';
|
|
|
|
+ if aFilename='' then
|
|
|
|
+ aFilename:='Regular';
|
|
|
|
+ aFilename:=TTF.FamilyName+'-'+aFilename;
|
|
|
|
+ end;
|
|
|
|
+ FontFiles.Add(aFilename);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPDFDocument.CreateTTFDescendantFont(const EmbeddedFontNum: integer);
|
|
procedure TPDFDocument.CreateTTFDescendantFont(const EmbeddedFontNum: integer);
|
|
@@ -6534,9 +6592,8 @@ end;
|
|
function TPDFDocument.AddFont(AName: String): Integer;
|
|
function TPDFDocument.AddFont(AName: String): Integer;
|
|
var
|
|
var
|
|
F: TPDFFont;
|
|
F: TPDFFont;
|
|
- i: integer;
|
|
|
|
begin
|
|
begin
|
|
- { reuse existing font definition if it exists }
|
|
|
|
|
|
+ // reuse existing font definition if it exists
|
|
Result:=Fonts.FindFont(AName);
|
|
Result:=Fonts.FindFont(AName);
|
|
if Result>=0 then exit;
|
|
if Result>=0 then exit;
|
|
F := Fonts.AddFontDef;
|
|
F := Fonts.AddFontDef;
|
|
@@ -6548,10 +6605,9 @@ end;
|
|
function TPDFDocument.AddFont(AFontFile: String; AName: String): Integer;
|
|
function TPDFDocument.AddFont(AFontFile: String; AName: String): Integer;
|
|
var
|
|
var
|
|
F: TPDFFont;
|
|
F: TPDFFont;
|
|
- i: integer;
|
|
|
|
lFName: string;
|
|
lFName: string;
|
|
begin
|
|
begin
|
|
- { reuse existing font definition if it exists }
|
|
|
|
|
|
+ // reuse existing font definition if it exists
|
|
Result:=Fonts.FindFont(AName);
|
|
Result:=Fonts.FindFont(AName);
|
|
if Result>=0 then exit;
|
|
if Result>=0 then exit;
|
|
F := Fonts.AddFontDef;
|
|
F := Fonts.AddFontDef;
|
|
@@ -6567,6 +6623,20 @@ begin
|
|
Result := Fonts.Count-1;
|
|
Result := Fonts.Count-1;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TPDFDocument.AddFont(AFontStream: TStream; AName: String): Integer;
|
|
|
|
+var
|
|
|
|
+ F: TPDFFont;
|
|
|
|
+begin
|
|
|
|
+ // reuse existing font definition if it exists
|
|
|
|
+ Result:=Fonts.FindFont(AName);
|
|
|
|
+ if Result>=0 then exit;
|
|
|
|
+ F := Fonts.AddFontDef;
|
|
|
|
+ F.Name := AName;
|
|
|
|
+ F.IsStdFont := False;
|
|
|
|
+ F.LoadFromStream(AFontStream);
|
|
|
|
+ Result := Fonts.Count-1;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPDFDocument.AddLineStyleDef(ALineWidth: TPDFFloat; AColor: TARGBColor;
|
|
function TPDFDocument.AddLineStyleDef(ALineWidth: TPDFFloat; AColor: TARGBColor;
|
|
APenStyle: TPDFPenStyle): Integer;
|
|
APenStyle: TPDFPenStyle): Integer;
|
|
|
|
|