git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@55 05c56307-c608-d34a-929d-697000501d7a
1068 lines
38 KiB
ObjectPascal
1068 lines
38 KiB
ObjectPascal
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressPrinting System COMPONENT SUITE }
|
|
{ }
|
|
{ Copyright (C) 1998-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
|
|
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
|
|
{ EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxPSPDFFonts;
|
|
|
|
interface
|
|
|
|
{$I cxVer.inc}
|
|
|
|
uses
|
|
Windows, SysUtils, Classes, Graphics, cxClasses, dxCore,
|
|
dxPSPDFExportCore, dxPSPDFStrings, dxPSTrueTypeFont;
|
|
|
|
type
|
|
TdxPSPDFCIDFont = class;
|
|
TdxPSPDFCIDFontConversionTable = class;
|
|
TdxPSPDFFontDescriptor = class;
|
|
|
|
{ TdxPSPDFFontInfo }
|
|
|
|
TdxPSPDFFontInfo = class(TdxPSPDFObject)
|
|
private
|
|
FOwner: TdxPSPDFCustomFont;
|
|
public
|
|
constructor Create(AOwner: TdxPSPDFCustomFont); virtual;
|
|
//
|
|
property Owner: TdxPSPDFCustomFont read FOwner;
|
|
end;
|
|
|
|
{ TdxPSPDFFontFile }
|
|
|
|
TdxPSPDFFontFile = class(TdxPSPDFFontInfo)
|
|
private
|
|
FFontData: TMemoryStream;
|
|
function GetFontDataValid: Boolean;
|
|
protected
|
|
procedure FontDataNeeded; virtual;
|
|
function GetContentStreamType(out AType: TdxPSPDFStreamType): Boolean; override;
|
|
procedure WriteContentStream(AWriter: TdxPSPDFWriter); override;
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
destructor Destroy; override;
|
|
//
|
|
property FontData: TMemoryStream read FFontData;
|
|
property FontDataValid: Boolean read GetFontDataValid;
|
|
end;
|
|
|
|
{ TdxPSPDFFontDescriptor }
|
|
|
|
TdxPSPDFFontDescriptor = class(TdxPSPDFFontInfo)
|
|
private
|
|
FAscent: Integer;
|
|
FAveCharWidth: Integer;
|
|
FCapHeight: Integer;
|
|
FCharWidths: array[Byte] of Word;
|
|
FDescent: Integer;
|
|
FFirstChar: Byte;
|
|
FFontBox: TRect;
|
|
FFontFile: TdxPSPDFFontFile;
|
|
FFontFlags: Cardinal;
|
|
FItalicAngle: Integer;
|
|
FLastChar: Byte;
|
|
FLeading: Integer;
|
|
FMaxCharWidth: Integer;
|
|
FMetricValid: Boolean;
|
|
FStemVertical: Integer;
|
|
protected
|
|
class function GetType: string; override;
|
|
function CalculateFontFlags(const APanose: TPanose): Integer; virtual;
|
|
function CreateFontFile: TdxPSPDFFontFile; virtual;
|
|
function GetCharWidth(AIndex: Byte): Word;
|
|
procedure CalculateMetric(DC: HDC; const AMetric: TOutlineTextmetricA); virtual;
|
|
procedure MetricNeeded; virtual;
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure PopulateExportList(AList: TdxPSPDFObjectList); override;
|
|
//
|
|
property Ascent: Integer read FAscent;
|
|
property AveCharWidth: Integer read FAveCharWidth;
|
|
property CapHeight: Integer read FCapHeight;
|
|
property CharWidth[Index: Byte]: Word read GetCharWidth;
|
|
property Descent: Integer read FDescent;
|
|
property FirstChar: Byte read FFirstChar;
|
|
property FontBox: TRect read FFontBox;
|
|
property FontFile: TdxPSPDFFontFile read FFontFile;
|
|
property FontFlags: Cardinal read FFontFlags;
|
|
property ItalicAngle: Integer read FItalicAngle;
|
|
property LastChar: Byte read FLastChar;
|
|
property MaxCharWidth: Integer read FMaxCharWidth;
|
|
property MetricValid: Boolean read FMetricValid;
|
|
property StemVertical: Integer read FStemVertical;
|
|
end;
|
|
|
|
{ TdxPSPDFTrueTypeFontEncoding }
|
|
|
|
TdxPSPDFTrueTypeFontEncoding = class(TdxPSPDFFontInfo)
|
|
private
|
|
function GetCharset: Integer;
|
|
protected
|
|
class function GetType: string; override;
|
|
procedure WriteEncodingTable(AWriter: TdxPSPDFWriter);
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
property Charset: Integer read GetCharset;
|
|
end;
|
|
|
|
{ TdxPSPDFTrueTypeFont }
|
|
|
|
TdxPSPDFTrueTypeFont = class(TdxPSPDFCustomFont)
|
|
private
|
|
FDescriptor: TdxPSPDFFontDescriptor;
|
|
FEncoding: TdxPSPDFTrueTypeFontEncoding;
|
|
protected
|
|
function ConvertToAnsiString(const AText: WideString): AnsiString;
|
|
class function GetSubType: string; override;
|
|
procedure WriteCharWidths(AWriter: TdxPSPDFWriter);
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
constructor Create(AOwner: TdxPSPDFFontList; AEmbed: Boolean; AFont: TFont); override;
|
|
destructor Destroy; override;
|
|
function EncodeText(const S: WideString): AnsiString; override;
|
|
function TextWidth(const S: WideString): Integer; override;
|
|
procedure PopulateExportList(AList: TdxPSPDFObjectList); override;
|
|
//
|
|
property Descriptor: TdxPSPDFFontDescriptor read FDescriptor;
|
|
property Encoding: TdxPSPDFTrueTypeFontEncoding read FEncoding;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDSystemInfo }
|
|
|
|
TdxPSPDFCIDSystemInfo = class(TObject)
|
|
private
|
|
FOrdering: string;
|
|
FRegistry: string;
|
|
FSupplement: Integer;
|
|
public
|
|
constructor Create(const AOrdering: string); virtual;
|
|
procedure Write(AWriter: TdxPSPDFWriter); virtual;
|
|
//
|
|
property Ordering: string read FOrdering write FOrdering;
|
|
property Registry: string read FRegistry write FRegistry;
|
|
property Supplement: Integer read FSupplement write FSupplement;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontInfo }
|
|
|
|
TdxPSPDFCIDFontInfo = class(TdxPSPDFFontInfo)
|
|
private
|
|
FDescriptor: TdxPSPDFFontDescriptor;
|
|
FSystemInfo: TdxPSPDFCIDSystemInfo;
|
|
function GetCharCache: TdxPSTTFCharCacheList;
|
|
function GetGlyphIndexWidth(Index: Word): Integer;
|
|
function GetOwner: TdxPSPDFCIDFont;
|
|
protected
|
|
class function GetSubType: string; override;
|
|
class function GetType: string; override;
|
|
procedure WriteCharWidths(AWriter: TdxPSPDFWriter); virtual;
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
constructor Create(AOwner: TdxPSPDFCustomFont); override;
|
|
destructor Destroy; override;
|
|
procedure PopulateExportList(AList: TdxPSPDFObjectList); override;
|
|
//
|
|
property CharCache: TdxPSTTFCharCacheList read GetCharCache;
|
|
property Descriptor: TdxPSPDFFontDescriptor read FDescriptor;
|
|
property GlyphIndexWidth[Index: Word]: Integer read GetGlyphIndexWidth;
|
|
property Owner: TdxPSPDFCIDFont read GetOwner;
|
|
property SystemInfo: TdxPSPDFCIDSystemInfo read FSystemInfo;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontFile }
|
|
|
|
TdxPSPDFCIDFontFile = class(TdxPSPDFFontFile)
|
|
private
|
|
function CanRebuildFont: Boolean;
|
|
function GetOwner: TdxPSPDFCIDFont;
|
|
function GetTTFFile: TdxPSTTFFile;
|
|
protected
|
|
procedure FontDataNeeded; override;
|
|
public
|
|
property Owner: TdxPSPDFCIDFont read GetOwner;
|
|
property TTFFile: TdxPSTTFFile read GetTTFFile;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontDescriptor }
|
|
|
|
TdxPSPDFCIDFontDescriptor = class(TdxPSPDFFontDescriptor)
|
|
protected
|
|
function CreateFontFile: TdxPSPDFFontFile; override;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFont }
|
|
|
|
TdxPSPDFCIDFont = class(TdxPSPDFCustomFont)
|
|
private
|
|
FCharCache: TdxPSTTFCharCacheList;
|
|
FConversionTable: TdxPSPDFCIDFontConversionTable;
|
|
FFontInfo: TdxPSPDFCIDFontInfo;
|
|
FTTFFile: TdxPSTTFFile;
|
|
protected
|
|
class function GetSubType: string; override;
|
|
procedure WriteHeader(AWriter: TdxPSPDFWriter); override;
|
|
public
|
|
constructor Create(AOwner: TdxPSPDFFontList; AEmbed: Boolean; AFont: TFont); override;
|
|
destructor Destroy; override;
|
|
function EncodeFontName: string; override;
|
|
function EncodeText(const S: WideString): AnsiString; override;
|
|
function TextWidth(const S: WideString): Integer; override;
|
|
procedure PopulateExportList(AList: TdxPSPDFObjectList); override;
|
|
//
|
|
property CharCache: TdxPSTTFCharCacheList read FCharCache;
|
|
property ConversionTable: TdxPSPDFCIDFontConversionTable read FConversionTable;
|
|
property FontInfo: TdxPSPDFCIDFontInfo read FFontInfo;
|
|
property TTFFile: TdxPSTTFFile read FTTFFile;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontConversionTable }
|
|
|
|
TdxPSPDFCIDFontConversionTable = class(TdxPSPDFFontInfo)
|
|
private
|
|
FSystemInfo: TdxPSPDFCIDSystemInfo;
|
|
function GetCharCache: TdxPSTTFCharCacheList;
|
|
function GetCMapName: string;
|
|
function GetGlyphIndex(ACharCode: Word): Integer;
|
|
function GetOwner: TdxPSPDFCIDFont;
|
|
protected
|
|
function GetContentStreamType(out AType: TdxPSPDFStreamType): Boolean; override;
|
|
procedure WriteContentStream(AWriter: TdxPSPDFWriter); override;
|
|
procedure WriteConversionTable(AWriter: TdxPSPDFWriter);
|
|
public
|
|
constructor Create(AOwner: TdxPSPDFCustomFont); override;
|
|
destructor Destroy; override;
|
|
//
|
|
property CharCache: TdxPSTTFCharCacheList read GetCharCache;
|
|
property CMapName: string read GetCMapName;
|
|
property GlyphIndex[CharCode: Word]: Integer read GetGlyphIndex;
|
|
property Owner: TdxPSPDFCIDFont read GetOwner;
|
|
property SystemInfo: TdxPSPDFCIDSystemInfo read FSystemInfo;
|
|
end;
|
|
|
|
function dxPDFCanCreateCIDFont(AFont: TFont): Boolean;
|
|
function dxPDFCanEmbedFont(AFont: TFont): Boolean;
|
|
implementation
|
|
|
|
const
|
|
dxPDF_FONT_FIXEDWIDTH = $2;
|
|
dxPDF_FONT_SERIF = $4;
|
|
dxPDF_FONT_SYMBOLIC = $8;
|
|
dxPDF_FONT_SCRIPT = $10;
|
|
dxPDF_FONT_USE_ADOBE_STD_CHARSET = $20;
|
|
dxPDF_FONT_ITALIC = $40;
|
|
dxPDF_FONT_ALLCAPFONT = $10000;
|
|
dxPDF_FONT_SMALL_CAP = $20000;
|
|
dxPDF_FONT_FORCE_BOLD_AT_SMALL_TEXT_SIZE = $40000;
|
|
|
|
const
|
|
sdxArabicEncoding = '128/Euro/afii57506/quotesinglbase/florin/quotedblbase' +
|
|
'/ellipsis/dagger/daggerdbl/circumflex/perthousand/afii57511/guilsinglleft' +
|
|
'/OE/afii57507/afii57508 144 /afii57509/quoteleft/quoteright/quotedblleft' +
|
|
'/quotedblright/bullet/endash/emdash 153 /trademark/afii57513/guilsinglright' +
|
|
'/oe/afii61664/afii301/afii57514 161 /afii57388 186 /afii57403 191 /afii57407' +
|
|
' 193 /afii57409/afii57410/afii57411/afii57412/afii57413/afii57414/afii57415' +
|
|
'/afii57416/afii57417/afii57418/afii57419/afii57420/afii57421/afii57422' +
|
|
'/afii57423/afii57424/afii57425/afii57426/afii57427/afii57428/afii57429' +
|
|
'/afii57430 216 /afii57431/afii57432/afii57433/afii57434/afii57440/afii57441' +
|
|
'/afii57442/afii57443/afii57444 227 /afii57445/afii57446/afii57470/afii57448' +
|
|
'/afii57449/afii57450 240 /afii57451/afii57452/afii57453/afii57454/afii57455' +
|
|
'/afii57456 248 /afii57457 250 /afii57458 253 /afii299/afii300/afii57519';
|
|
|
|
sdxBalticEncoding = '128/Euro/space/quotesinglbase/space/quotedblbase' +
|
|
'/ellipsis/dagger/daggerdbl/space/perthousand/space/guilsinglleft/space' +
|
|
'/dieresis/caron/cedilla/space/quoteleft/quoteright/quotedblleft/quotedblright' +
|
|
'/bullet/endash/emdash/space/trademark/space/guilsinglright/space/macron' +
|
|
'/ogonek/space 170/Rcommaaccent 175 /AE 184/oslash 186/rcommaaccent 191 /ae' +
|
|
'/Aogonek/Iogonek/Amacron/Cacute 198/Eogonek/Emacron/Ccaron 202/Zacute' +
|
|
'/Edotaccent/Gcommaaccent/Kcommaaccent/Imacron/Lcommaaccent/Scaron/Nacute' +
|
|
'/Ncommaaccent/trademark/Omacron 216/Uogonek/Lslash/Sacute/Umacron 221' +
|
|
'/Zdotaccent/Zcaron 224/aogonek/iogonek/amacron/cacute 230/eogonek/emacron' +
|
|
'/ccaron 234/zacute/edotaccent/gcommaaccent/kcommaaccent/imacron/lcommaaccent' +
|
|
'/scaron/nacute/ncommaaccent 244/omacron 248/uogonek/lslash/OE/umacron 253' +
|
|
'/zdotaccent/zcaron/dotaccent';
|
|
|
|
sdxEastEuropeEncoding = '128 /Euro 140/Sacute/Tcaron/Zcaron/Zacute 156' +
|
|
'/sacute/tcaron/zcaron/zacute 161/caron/breve/Lslash 165/Aogonek 170' +
|
|
'/Scedilla 175/Zdotaccent 178/ogonek/lslash 185/aogonek/scedilla 188' +
|
|
'/Lcaron/hungarumlaut/lcaron/zdotaccent/Racute 195/Abreve 197/Lacute' +
|
|
'/Cacute 200/Ccaron 202/Eogonek 204/Ecaron 207/Dcaron/Dslash 209/Nacute' +
|
|
'/Ncaron/Oacute 213/Ohungarumlaut 216/Rcaron/Uring 219/Uhungarumlaut 222' +
|
|
'/Tcedilla 224/racute 227/abreve 229/lacute/cacute/ccedilla/ccaron 234' +
|
|
'/eogonek 236/ecaron 239/dcaron/dmacron/nacute/ncaron 245/ohungarumlaut 248' +
|
|
'/rcaron/uring 251/uhungarumlaut 254/tcedilla/dotaccent';
|
|
|
|
sdxGreekEncoding = '128/Euro 160/quoteleft/quoteright 175/afii00208 180/tonos' +
|
|
'/dieresistonos/Alphatonos 184/Epsilontonos/Etatonos/Iotatonos 188' +
|
|
'/Omicrontonos 190/Upsilontonos/Omegatonos/iotadieresistonos/Alpha/Beta' +
|
|
'/Gamma/Delta/Epsilon/Zeta/Eta/Theta/Iota/Kappa/Lambda/Mu/Nu/Xi/Omicron' +
|
|
'/Pi/Rho 211/Sigma/Tau/Upsilon/Phi/Chi/Psi/Omega/Iotadieresis' +
|
|
'/Upsilondieresis/alphatonos/epsilontonos/etatonos/iotatonos' +
|
|
'/upsilondieresistonos/alpha/beta/gamma/delta/epsilon/zeta/eta/theta' +
|
|
'/iota/kappa/lambda/mu/nu/xi/omicron/pi/rho/sigma1/sigma/tau/upsilon' +
|
|
'/phi/chi/psi/omega/iotadieresis/upsilondieresis/omicrontonos/upsilontonos' +
|
|
'/omegatonos';
|
|
|
|
sdxHebrewEncoding = '128/Euro 130/quotesinglbase/florin/quotedblbase/ellipsis' +
|
|
'/dagger/daggerdbl/circumflex/perthousand139/guilsinglleft 145/quoteleft' +
|
|
'/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde' +
|
|
'/trademark 155/perthousand 164/afii57636 170/multiply186/divide 192' +
|
|
'/afii57799/afii57801/afii57800/afii57802/afii57793/afii57794/afii57795' +
|
|
'/afii57798/afii57797/afii57806 203/afii57796/afii57807/afii57839' +
|
|
'/afii57645/afii57841/afii57842/afii57804/afii57803/afii57658/afii57716' +
|
|
'/afii57717/afii57718 224/afii57664/afii57665/afii57666/afii57667' +
|
|
'/afii57668/afii57669/afii57670/afii57671/afii57672/afii57673/afii57674' +
|
|
'/afii57675/afii57676/afii57677/afii57678/afii57679/afii57680/afii57681' +
|
|
'/afii57682/afii57683/afii57684/afii57685/afii57686/afii57687/afii57688' +
|
|
'/afii57689/afii57690253/afii299/afii300';
|
|
|
|
sdxRussianEncoding = '129 /afii10052/quotesinglbase/afii10100/quotedblbase' +
|
|
'/ellipsis/dagger/daggerdbl/Euro/perthousand/afii10058/guilsinglleft' +
|
|
'/afii10059/afii10061/afii10060/afii10145/afii10099/quoteleft/quoteright' +
|
|
'/quotedblleft/quotedblright/bullet/endash/emdash/space/trademark/afii10106' +
|
|
'/guilsinglright/afii10107/afii10109/afii10108/afii10193/space/afii10062' +
|
|
'/afii10110/afii10057/currency/afii10050/brokenbar/section/afii10023' +
|
|
'/copyright/afii10053/guillemotleft/logicalnot/hyphen/registered/afii10056' +
|
|
'/degree/plusminus/afii10055/afii10103/afii10098/mu/paragraph/periodcentered' +
|
|
'/afii10071/afii61352/afii10101/guillemotright/afii10105/afii10054/afii10102' +
|
|
'/afii10104/afii10017/afii10018/afii10019/afii10020/afii10021/afii10022' +
|
|
'/afii10024/afii10025/afii10026/afii10027/afii10028/afii10029/afii10030' +
|
|
'/afii10031/afii10032/afii10033/afii10034/afii10035/afii10036/afii10037' +
|
|
'/afii10038/afii10039/afii10040/afii10041/afii10042/afii10043/afii10044' +
|
|
'/afii10045/afii10046/afii10047/afii10048/afii10049/afii10065/afii10066' +
|
|
'/afii10067/afii10068/afii10069/afii10070/afii10072/afii10073/afii10074' +
|
|
'/afii10075/afii10076/afii10077/afii10078/afii10079/afii10080/afii10081' +
|
|
'/afii10082/afii10083/afii10084/afii10085/afii10086/afii10087/afii10088' +
|
|
'/afii10089/afii10090/afii10091/afii10092/afii10093/afii10094/afii10095' +
|
|
'/afii10096/afii10097/space';
|
|
|
|
sdxThaiEncoding = '128/Euro 133/ellipsis 145/quoteleft/quoteright/quotedblleft' +
|
|
'/quotedblright/bullet/endash/emdash 160/space/kokaithai/khokhaithai/khokhuatthai' +
|
|
'/khokhwaithai/khokhonthai/khorakhangthai/ngonguthai/chochanthai/chochingthai' +
|
|
'/chochangthai/sosothai/chochoethai/yoyingthai/dochadathai/topatakthai' +
|
|
'/thothanthai/thonangmonthothai/thophuthaothai/nonenthai/dodekthai/totaothai' +
|
|
'/thothungthai/thothahanthai/thothongthai/nonuthai/bobaimaithai/poplathai' +
|
|
'/phophungthai/fofathai/phophanthai/fofanthai/phosamphaothai/momathai' +
|
|
'/yoyakthai/roruathai/ruthai/lolingthai/luthai/wowaenthai/sosalathai' +
|
|
'/sorusithai/sosuathai/hohipthai/lochulathai/oangthai/honokhukthai' +
|
|
'/paiyannoithai/saraathai/maihanakatthai/saraaathai/saraamthai/saraithai' +
|
|
'/saraiithai/sarauethai/saraueethai/sarauthai/sarauuthai/phinthuthai 223' +
|
|
'/bahtthai/saraethai/saraaethai/saraothai/saraaimaimuanthai/saraaimaimalaithai' +
|
|
'/lakkhangyaothai/maiyamokthai/maitaikhuthai/maiekthai/maithothai/maitrithai' +
|
|
'/maichattawathai/thanthakhatthai/nikhahitthai/yamakkanthai/fongmanthai' +
|
|
'/zerothai/onethai/twothai/threethai/fourthai/fivethai/sixthai/seventhai' +
|
|
'/eightthai/ninethai/angkhankhuthai/khomutthai';
|
|
|
|
sdxTurkishEncoding = '128/Euro 130/quotesinglbase/florin/quotedblbase/ellipsis' +
|
|
'/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 145' +
|
|
'/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash' +
|
|
'/tilde/trademark/scaron/guilsinglright/oe 159/Ydieresis 208/Gbreve 221' +
|
|
'/Idotaccent/Scedilla 240/gbreve 253/dotlessi/scedilla';
|
|
|
|
sdxVietnameseEncoding = '128 /Euro 130/quotesinglbase/florin/quotedblbase/ellipsis' +
|
|
'/dagger/daggerdbl/circumflex/perthousand 139/guilsinglleft/OE 145/quoteleft' +
|
|
'/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark 155' +
|
|
'/guilsinglright/oe 159/Ydieresis/space/exclamdown/cent/sterling/currency' +
|
|
'/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot' +
|
|
'/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu' +
|
|
'/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright' +
|
|
'/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex' +
|
|
'/Abreve/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis' +
|
|
'/gravetonecmb /Iacute /Icircumflex /Idieresis/Dcroat/Ntilde/hookabovecomb' +
|
|
'/Oacute/Ocircumflex/Ohorn/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex' +
|
|
'/Udieresis/Uhorn/tildecomb/germandbls/agrave/aacute/acircumflex/abreve' +
|
|
'/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/acutetonecmb' +
|
|
'/iacute/icircumflex/idieresis/dcroat/ntilde/dotbelowcomb/oacute/ocircumflex' +
|
|
'/ohorn/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/uhorn' +
|
|
'/dong/ydieresis';
|
|
|
|
function dxPDFCanCreateCIDFont(AFont: TFont): Boolean;
|
|
begin
|
|
Result := dxPDFCanEmbedFont(AFont);
|
|
end;
|
|
|
|
function dxPDFCanEmbedFont(AFont: TFont): Boolean;
|
|
begin
|
|
Result := (AFont.Charset <> SYMBOL_CHARSET) and dxPSGetFontData(nil, AFont);
|
|
end;
|
|
|
|
function GetABCWidth(const ABC: TABC): Integer;
|
|
begin
|
|
Result := ABC.abcA + Integer(ABC.abcB) + ABC.abcC;
|
|
end;
|
|
|
|
{ TdxPSPDFTrueTypeFont }
|
|
|
|
constructor TdxPSPDFTrueTypeFont.Create(
|
|
AOwner: TdxPSPDFFontList; AEmbed: Boolean; AFont: TFont);
|
|
begin
|
|
inherited Create(AOwner, AEmbed, AFont);
|
|
FEncoding := TdxPSPDFTrueTypeFontEncoding.Create(Self);
|
|
FDescriptor := TdxPSPDFFontDescriptor.Create(Self);
|
|
end;
|
|
|
|
destructor TdxPSPDFTrueTypeFont.Destroy;
|
|
begin
|
|
FreeAndNil(FDescriptor);
|
|
FreeAndNil(FEncoding);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSPDFTrueTypeFont.ConvertToAnsiString(const AText: WideString): AnsiString;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Charset <> SYMBOL_CHARSET then
|
|
Result := dxWideStringToAnsiString(AText, CodePage)
|
|
else
|
|
begin
|
|
SetLength(Result, Length(AText));
|
|
for I := 1 to Length(AText) do
|
|
Result[I] := AnsiChar(Word(AText[I]) and not $F000);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSPDFTrueTypeFont.EncodeText(const S: WideString): AnsiString;
|
|
begin
|
|
Result := '(' + ConvertToAnsiString(S) + ')';
|
|
end;
|
|
|
|
class function TdxPSPDFTrueTypeFont.GetSubType: string;
|
|
begin
|
|
Result := sdxPDFSubTypeFontTrueType;
|
|
end;
|
|
|
|
function TdxPSPDFTrueTypeFont.TextWidth(const S: WideString): Integer;
|
|
var
|
|
ATempStr: AnsiString;
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
ATempStr := ConvertToAnsiString(S);
|
|
for I := 1 to Length(ATempStr) do
|
|
Inc(Result, Descriptor.CharWidth[Ord(ATempStr[I])]);
|
|
end;
|
|
|
|
procedure TdxPSPDFTrueTypeFont.PopulateExportList(AList: TdxPSPDFObjectList);
|
|
begin
|
|
inherited PopulateExportList(AList);
|
|
Encoding.PopulateExportList(AList);
|
|
Descriptor.PopulateExportList(AList);
|
|
end;
|
|
|
|
procedure TdxPSPDFTrueTypeFont.WriteCharWidths(AWriter: TdxPSPDFWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Descriptor.MetricNeeded;
|
|
AWriter.WriteString(sdxPDFFirstChar + sdxPDFSpace + IntToStr(Descriptor.FirstChar));
|
|
AWriter.WriteString(sdxPDFLastChar + sdxPDFSpace + IntToStr(Descriptor.LastChar));
|
|
AWriter.WriteString(sdxPDFWidths + '[', False);
|
|
for I := Descriptor.FirstChar to Descriptor.LastChar do
|
|
AWriter.WriteString(IntToStr(Descriptor.CharWidth[I]) + sdxPDFSpace, False);
|
|
AWriter.WriteString(']');
|
|
end;
|
|
|
|
procedure TdxPSPDFTrueTypeFont.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
inherited WriteHeader(AWriter);
|
|
AWriter.WriteString(sdxPDFEncoding + sdxPDFSpace + AWriter.MakeLinkToObject(Encoding));
|
|
AWriter.WriteString(sdxPDFFontDescriptor + sdxPDFSpace + AWriter.MakeLinkToObject(Descriptor));
|
|
WriteCharWidths(AWriter);
|
|
end;
|
|
|
|
{ TdxPSPDFTrueTypeFontEncoding }
|
|
|
|
function TdxPSPDFTrueTypeFontEncoding.GetCharset: Integer;
|
|
begin
|
|
Result := Owner.Charset;
|
|
end;
|
|
|
|
class function TdxPSPDFTrueTypeFontEncoding.GetType: string;
|
|
begin
|
|
Result := sdxPDFEncoding;
|
|
end;
|
|
|
|
procedure TdxPSPDFTrueTypeFontEncoding.WriteEncodingTable(AWriter: TdxPSPDFWriter);
|
|
var
|
|
AEncodingTable: string;
|
|
begin
|
|
case Charset of
|
|
ARABIC_CHARSET:
|
|
AEncodingTable := sdxArabicEncoding;
|
|
BALTIC_CHARSET:
|
|
AEncodingTable := sdxBalticEncoding;
|
|
EASTEUROPE_CHARSET:
|
|
AEncodingTable := sdxEastEuropeEncoding;
|
|
HEBREW_CHARSET:
|
|
AEncodingTable := sdxHebrewEncoding;
|
|
GREEK_CHARSET:
|
|
AEncodingTable := sdxGreekEncoding;
|
|
RUSSIAN_CHARSET:
|
|
AEncodingTable := sdxRussianEncoding;
|
|
THAI_CHARSET:
|
|
AEncodingTable := sdxThaiEncoding;
|
|
TURKISH_CHARSET:
|
|
AEncodingTable := sdxTurkishEncoding;
|
|
VIETNAMESE_CHARSET:
|
|
AEncodingTable := sdxVietnameseEncoding;
|
|
else
|
|
Exit;
|
|
end;
|
|
AWriter.WriteString(sdxPDFDifferences + ' [' + AEncodingTable + ']', False);
|
|
end;
|
|
|
|
procedure TdxPSPDFTrueTypeFontEncoding.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
const
|
|
BaseEncodingMap: array[Boolean] of string = (
|
|
sdxPDFEncodingWinAnsi, sdxPDFEncodingMacRoman
|
|
);
|
|
begin
|
|
inherited WriteHeader(AWriter);
|
|
AWriter.WriteString(sdxPDFBaseEncoding + BaseEncodingMap[Charset = SYMBOL_CHARSET]);
|
|
WriteEncodingTable(AWriter);
|
|
end;
|
|
|
|
{ TdxPSPDFFontDescriptor }
|
|
|
|
destructor TdxPSPDFFontDescriptor.Destroy;
|
|
begin
|
|
FreeAndNil(FFontFile);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxPSPDFFontDescriptor.CalculateMetric(
|
|
DC: HDC; const AMetric: TOutlineTextmetricA);
|
|
var
|
|
AABC: TdxPSPDFABCArray;
|
|
I: Integer;
|
|
begin
|
|
ZeroMemory(@FCharWidths[0], SizeOf(FCharWidths));
|
|
FAscent := AMetric.otmAscent;
|
|
FAveCharWidth := AMetric.otmTextMetrics.tmAveCharWidth;
|
|
FCapHeight := AMetric.otmTextMetrics.tmHeight;
|
|
FDescent := AMetric.otmDescent;
|
|
FFontBox := AMetric.otmrcFontBox;
|
|
FFontFlags := CalculateFontFlags(AMetric.otmPanoseNumber);
|
|
FItalicAngle := AMetric.otmItalicAngle;
|
|
FMaxCharWidth := AMetric.otmTextMetrics.tmMaxCharWidth;
|
|
FStemVertical := 50 + Round(Sqr(AMetric.otmTextMetrics.tmWeight / 65));
|
|
FLastChar := Ord(AMetric.otmTextMetrics.tmLastChar);
|
|
FFirstChar := Ord(AMetric.otmTextMetrics.tmFirstChar);
|
|
FLeading := AMetric.otmTextMetrics.tmInternalLeading;
|
|
GetCharABCWidths(DC, FFirstChar, FLastChar, AABC);
|
|
for I := 0 to LastChar - FirstChar do
|
|
begin
|
|
if AMetric.otmTextMetrics.tmPitchAndFamily and TMPF_FIXED_PITCH = 0 then
|
|
FCharWidths[FirstChar + I] := GetABCWidth(AABC[0])
|
|
else
|
|
FCharWidths[FirstChar + I] := GetABCWidth(AABC[I]);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPDFFontDescriptor.MetricNeeded;
|
|
var
|
|
AFont: TFont;
|
|
AMetric: POutlineTextmetricA;
|
|
AMetricLength: Integer;
|
|
AOldFont: HFONT;
|
|
DC: HDC;
|
|
begin
|
|
if not FMetricValid then
|
|
begin
|
|
FMetricValid := True;
|
|
AFont := Owner.CreateFont;
|
|
try
|
|
DC := GetDC(0);
|
|
AFont.PixelsPerInch := 96;
|
|
AFont.Size := 750;
|
|
AOldFont := SelectObject(DC, AFont.Handle);
|
|
AMetricLength := GetOutlineTextMetricsA(DC, 0, nil);
|
|
if AMetricLength > 0 then
|
|
begin
|
|
AMetric := AllocMem(AMetricLength);
|
|
try
|
|
AMetric^.otmSize := SizeOf(AMetric^);
|
|
GetOutlineTextMetricsA(DC, AMetricLength, AMetric);
|
|
CalculateMetric(DC, AMetric^);
|
|
finally
|
|
FreeMem(AMetric);
|
|
end;
|
|
end;
|
|
SelectObject(DC, AOldFont);
|
|
ReleaseDC(0, DC);
|
|
finally
|
|
AFont.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPDFFontDescriptor.PopulateExportList(AList: TdxPSPDFObjectList);
|
|
begin
|
|
inherited PopulateExportList(AList);
|
|
if (FontFile = nil) and Owner.Embed then
|
|
FFontFile := CreateFontFile;
|
|
if Assigned(FontFile) then
|
|
FontFile.PopulateExportList(AList);
|
|
end;
|
|
|
|
function TdxPSPDFFontDescriptor.CalculateFontFlags(const APanose: TPanose): Integer;
|
|
begin
|
|
Result := dxPDF_FONT_USE_ADOBE_STD_CHARSET;
|
|
if APanose.bProportion = 9 then
|
|
Result := Result or dxPDF_FONT_FIXEDWIDTH;
|
|
if (APanose.bSerifStyle < 11) or (APanose.bSerifStyle > 13) then
|
|
Result := Result or dxPDF_FONT_SERIF;
|
|
if APanose.bFamilyType = 3 then
|
|
Result := Result or dxPDF_FONT_SCRIPT;
|
|
end;
|
|
|
|
function TdxPSPDFFontDescriptor.CreateFontFile: TdxPSPDFFontFile;
|
|
begin
|
|
Result := TdxPSPDFFontFile.Create(Owner);
|
|
end;
|
|
|
|
function TdxPSPDFFontDescriptor.GetCharWidth(AIndex: Byte): Word;
|
|
begin
|
|
MetricNeeded;
|
|
Result := FCharWidths[AIndex];
|
|
end;
|
|
|
|
class function TdxPSPDFFontDescriptor.GetType: string;
|
|
begin
|
|
Result := sdxPDFFontDescriptor;
|
|
end;
|
|
|
|
procedure TdxPSPDFFontDescriptor.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
inherited WriteHeader(AWriter);
|
|
MetricNeeded;
|
|
AWriter.WriteString(sdxPDFFontName + '/' + Owner.EncodeFontName);
|
|
AWriter.WriteString(sdxPDFFontFlags + sdxPDFSpace + IntToStr(FFontFlags));
|
|
AWriter.WriteString(sdxPDFItalicAngle + sdxPDFSpace + IntToStr(FItalicAngle));
|
|
AWriter.WriteString(sdxPDFAscent + sdxPDFSpace + IntToStr(FAscent));
|
|
AWriter.WriteString(sdxPDFDescent + sdxPDFSpace + IntToStr(FDescent));
|
|
AWriter.WriteString(sdxPDFCapHeight + sdxPDFSpace + IntToStr(FCapHeight));
|
|
AWriter.WriteString(sdxPDFStemV + sdxPDFSpace + IntToStr(FStemVertical));
|
|
AWriter.WriteString(sdxPDFAvgWidth + sdxPDFSpace + IntToStr(FAveCharWidth));
|
|
AWriter.WriteString(sdxPDFMaxWidth+ sdxPDFSpace + IntToStr(FMaxCharWidth));
|
|
AWriter.WriteString(sdxPDFMissingWidth + sdxPDFSpace + IntToStr(FAveCharWidth));
|
|
AWriter.WriteString(sdxPDFLeading + sdxPDFSpace + IntToStr(FLeading));
|
|
AWriter.WriteString(Format(sdxPDFFontBox + ' [%d %d %d %d]',
|
|
[FontBox.Left, FontBox.Bottom, FontBox.Right, FontBox.Top]));
|
|
if Assigned(FontFile) then
|
|
AWriter.WriteString(sdxPDFFontFile + sdxPDFSpace + AWriter.MakeLinkToObject(FontFile));
|
|
end;
|
|
|
|
{ TdxPSPDFFontInfo }
|
|
|
|
constructor TdxPSPDFFontInfo.Create(AOwner: TdxPSPDFCustomFont);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFont }
|
|
|
|
constructor TdxPSPDFCIDFont.Create(
|
|
AOwner: TdxPSPDFFontList; AEmbed: Boolean; AFont: TFont);
|
|
begin
|
|
inherited Create(AOwner, True, AFont);
|
|
FTTFFile := TdxPSTTFFile.Create(AFont);
|
|
FCharCache := TdxPSTTFCharCacheList.Create;
|
|
FFontInfo := TdxPSPDFCIDFontInfo.Create(Self);
|
|
FConversionTable := TdxPSPDFCIDFontConversionTable.Create(Self);
|
|
end;
|
|
|
|
destructor TdxPSPDFCIDFont.Destroy;
|
|
begin
|
|
FreeAndNil(FConversionTable);
|
|
FreeAndNil(FTTFFile);
|
|
FreeAndNil(FFontInfo);
|
|
FreeAndNil(FCharCache);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFont.EncodeFontName: string;
|
|
begin
|
|
Result := 'DX+' + inherited EncodeFontName;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFont.EncodeText(const S: WideString): AnsiString;
|
|
|
|
function WideEncodeText(const S: WideString): AnsiString;
|
|
var
|
|
AChar: Word;
|
|
AGlyphIndex: Word;
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 1 to Length(S) do
|
|
begin
|
|
AChar := Word(S[I]);
|
|
AGlyphIndex := TTFFile.GlyphIndex[AChar];
|
|
CharCache.Add(AChar, AGlyphIndex);
|
|
Result := Result + dxStringToAnsiString(IntToHex(AGlyphIndex, 4));
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := '<' + WideEncodeText(S) + '>';
|
|
end;
|
|
|
|
function TdxPSPDFCIDFont.TextWidth(const S: WideString): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result:= 0;
|
|
for I := 1 to Length(S) do
|
|
Inc(Result, TTFFile.CharWidthByCode[Word(S[I])]);
|
|
end;
|
|
|
|
class function TdxPSPDFCIDFont.GetSubType: string;
|
|
begin
|
|
Result := sdxPDFSubTypeFontType0;
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFont.PopulateExportList(AList: TdxPSPDFObjectList);
|
|
begin
|
|
inherited PopulateExportList(AList);
|
|
FontInfo.PopulateExportList(AList);
|
|
ConversionTable.PopulateExportList(AList);
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFont.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
inherited WriteHeader(AWriter);
|
|
AWriter.WriteString(sdxPDFEncoding + sdxPDFSpace + sdxPDFEncodingIdentityH);
|
|
AWriter.WriteString(sdxPDFDescendantFonts +
|
|
' [' + AWriter.MakeLinkToObject(FontInfo) + ']');
|
|
AWriter.WriteString(sdxPDFToUnicode + sdxPDFSpace + AWriter.MakeLinkToObject(ConversionTable));
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontInfo }
|
|
|
|
constructor TdxPSPDFCIDFontInfo.Create(AOwner: TdxPSPDFCustomFont);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FDescriptor := TdxPSPDFCIDFontDescriptor.Create(AOwner);
|
|
FSystemInfo := TdxPSPDFCIDSystemInfo.Create('Identity');
|
|
end;
|
|
|
|
destructor TdxPSPDFCIDFontInfo.Destroy;
|
|
begin
|
|
FreeAndNil(FSystemInfo);
|
|
FreeAndNil(FDescriptor);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
class function TdxPSPDFCIDFontInfo.GetSubType: string;
|
|
begin
|
|
Result := sdxPDFSubTypeFontTypeCID;
|
|
end;
|
|
|
|
class function TdxPSPDFCIDFontInfo.GetType: string;
|
|
begin
|
|
Result := sdxPDFFont;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontInfo.GetCharCache: TdxPSTTFCharCacheList;
|
|
begin
|
|
Result := Owner.CharCache;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontInfo.GetGlyphIndexWidth(Index: Word): Integer;
|
|
begin
|
|
Result := Owner.TTFFile.CharWidthByGlyphIndex[Index];
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontInfo.GetOwner: TdxPSPDFCIDFont;
|
|
begin
|
|
Result := TdxPSPDFCIDFont(inherited Owner);
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontInfo.PopulateExportList(AList: TdxPSPDFObjectList);
|
|
begin
|
|
inherited PopulateExportList(AList);
|
|
Descriptor.PopulateExportList(AList);
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontInfo.WriteCharWidths(AWriter: TdxPSPDFWriter);
|
|
|
|
procedure WriteConsecutiveWidths(AGlyphIndex, AConsecutiveLength: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if AConsecutiveLength > 0 then
|
|
begin
|
|
AWriter.WriteString(IntToStr(AGlyphIndex) + ' [', False);
|
|
for I := AGlyphIndex to AGlyphIndex + AConsecutiveLength - 1 do
|
|
begin
|
|
AWriter.WriteString(IntToStr(GlyphIndexWidth[I]), False);
|
|
if I + 1 - AGlyphIndex < AConsecutiveLength then
|
|
AWriter.WriteString(sdxPDFSpace, False);
|
|
end;
|
|
AWriter.WriteString(']');
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AConsecutiveLength: Integer;
|
|
AOldGlyphIndex: Integer;
|
|
AStartsFromGlyphIndex: Integer;
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteString('/W [');
|
|
try
|
|
AOldGlyphIndex := 0;
|
|
AConsecutiveLength := 1;
|
|
AStartsFromGlyphIndex := 0;
|
|
CharCache.SortByGlyphIndex;
|
|
for I := 0 to CharCache.Count - 1 do
|
|
begin
|
|
if CharCache.CacheItem[I].GlyphIndex <> AOldGlyphIndex + 1 then
|
|
begin
|
|
WriteConsecutiveWidths(AStartsFromGlyphIndex, AConsecutiveLength);
|
|
AStartsFromGlyphIndex := CharCache.CacheItem[I].GlyphIndex;
|
|
AConsecutiveLength := 0;
|
|
end;
|
|
AOldGlyphIndex := CharCache.CacheItem[I].GlyphIndex;
|
|
Inc(AConsecutiveLength);
|
|
end;
|
|
WriteConsecutiveWidths(AStartsFromGlyphIndex, AConsecutiveLength);
|
|
finally
|
|
AWriter.WriteString(']');
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontInfo.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
inherited WriteHeader(AWriter);
|
|
AWriter.WriteString(sdxPDFCharSet + sdxPDFSpace + IntToStr(Owner.Charset));
|
|
AWriter.WriteString(sdxPDFBaseFont + sdxPDFSpace + '/' + Owner.EncodeFontName);
|
|
AWriter.WriteString(sdxPDFFontDescriptor + sdxPDFSpace + AWriter.MakeLinkToObject(Descriptor));
|
|
SystemInfo.Write(AWriter);
|
|
WriteCharWidths(AWriter);
|
|
end;
|
|
|
|
{ TdxPSPDFCIDSystemInfo }
|
|
|
|
constructor TdxPSPDFCIDSystemInfo.Create(const AOrdering: string);
|
|
begin
|
|
inherited Create;
|
|
FRegistry := 'Adobe';
|
|
FOrdering := AOrdering;
|
|
FSupplement := 0;
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDSystemInfo.Write(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
AWriter.WriteString(sdxPDFCIDSystemInfo);
|
|
AWriter.BeginParamsSet;
|
|
try
|
|
AWriter.WriteString(sdxPDFRegistry + ' (' + Registry + ')');
|
|
AWriter.WriteString(sdxPDFOrdering + ' (' + Ordering + ')');
|
|
AWriter.WriteString(sdxPDFSupplement + sdxPDFSpace + IntToStr(Supplement));
|
|
finally
|
|
AWriter.EndParamsSet;
|
|
end;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontConversionTable }
|
|
|
|
constructor TdxPSPDFCIDFontConversionTable.Create(AOwner: TdxPSPDFCustomFont);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FSystemInfo := TdxPSPDFCIDSystemInfo.Create(CMapName);
|
|
end;
|
|
|
|
destructor TdxPSPDFCIDFontConversionTable.Destroy;
|
|
begin
|
|
FreeAndNil(FSystemInfo);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontConversionTable.GetContentStreamType(out AType: TdxPSPDFStreamType): Boolean;
|
|
begin
|
|
AType := pstText;
|
|
Result := True;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontConversionTable.GetGlyphIndex(ACharCode: Word): Integer;
|
|
begin
|
|
Result := Owner.TTFFile.GlyphIndex[ACharCode];
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontConversionTable.GetOwner: TdxPSPDFCIDFont;
|
|
begin
|
|
Result := TdxPSPDFCIDFont(inherited Owner);
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontConversionTable.GetCharCache: TdxPSTTFCharCacheList;
|
|
begin
|
|
Result := Owner.CharCache;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontConversionTable.GetCMapName: string;
|
|
begin
|
|
Result := sdxPDFCIDFontPrefix + '+' + Owner.Name;
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontConversionTable.WriteContentStream(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
SystemInfo.Ordering := CMapName;
|
|
AWriter.WriteString('/CIDInit /ProcSet findresource begin');
|
|
AWriter.WriteString('12 dict begin');
|
|
AWriter.WriteString('begincmap');
|
|
SystemInfo.Write(AWriter);
|
|
AWriter.WriteString('def');
|
|
AWriter.WriteString(sdxPDFCMapName + ' /' + CMapName + ' def');
|
|
AWriter.WriteString(sdxPDFCMapType + ' 2 def');
|
|
AWriter.WriteString('1 begincodespacerange');
|
|
AWriter.WriteString('<0000> <FFFF>');
|
|
AWriter.WriteString('endcodespacerange');
|
|
WriteConversionTable(AWriter);
|
|
AWriter.WriteString('endcmap');
|
|
AWriter.WriteString('CMapName currentdict /CMap defineresource pop');
|
|
AWriter.WriteString('end');
|
|
AWriter.WriteString('end', False);
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontConversionTable.WriteConversionTable(AWriter: TdxPSPDFWriter);
|
|
var
|
|
ACacheItem: TdxPSTTFCharCacheListItem;
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteString(IntToStr(CharCache.Count) + ' beginbfchar');
|
|
for I := 0 to CharCache.Count - 1 do
|
|
begin
|
|
ACacheItem := CharCache.CacheItem[I];
|
|
AWriter.WriteString('<' + IntToHex(ACacheItem.GlyphIndex, 4) + '>' +
|
|
sdxPDFSpace + '<' + IntToHex(ACacheItem.CharCode , 4) + '>');
|
|
end;
|
|
AWriter.WriteString('endbfchar');
|
|
end;
|
|
|
|
{ TdxPSPDFFontFile }
|
|
|
|
destructor TdxPSPDFFontFile.Destroy;
|
|
begin
|
|
FreeAndNil(FFontData);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSPDFFontFile.GetContentStreamType(out AType: TdxPSPDFStreamType): Boolean;
|
|
begin
|
|
AType := pstText;
|
|
Result := True;
|
|
end;
|
|
|
|
function TdxPSPDFFontFile.GetFontDataValid: Boolean;
|
|
begin
|
|
Result := Assigned(FontData);
|
|
end;
|
|
|
|
procedure TdxPSPDFFontFile.FontDataNeeded;
|
|
var
|
|
AFont: TFont;
|
|
begin
|
|
if not FontDataValid then
|
|
begin
|
|
FreeAndNil(FFontData);
|
|
AFont := Owner.CreateFont;
|
|
try
|
|
FFontData := TMemoryStream.Create;
|
|
dxPSGetFontData(FFontData, AFont);
|
|
finally
|
|
AFont.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPDFFontFile.WriteContentStream(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
FontDataNeeded;
|
|
AWriter.WriteStream(FontData);
|
|
end;
|
|
|
|
procedure TdxPSPDFFontFile.WriteHeader(AWriter: TdxPSPDFWriter);
|
|
begin
|
|
FontDataNeeded;
|
|
inherited WriteHeader(AWriter);
|
|
AWriter.WriteString(sdxPDFLength + '1' + sdxPDFSpace + IntToStr(FontData.Size));
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontFile }
|
|
|
|
function TdxPSPDFCIDFontFile.CanRebuildFont: Boolean;
|
|
begin
|
|
Result := TTFFile.OS2Section.FamilyClass <> 5;
|
|
end;
|
|
|
|
procedure TdxPSPDFCIDFontFile.FontDataNeeded;
|
|
begin
|
|
if not FontDataValid then
|
|
begin
|
|
if CanRebuildFont then
|
|
begin
|
|
FreeAndNil(FFontData);
|
|
FFontData := TMemoryStream.Create;
|
|
TTFFile.Rebuild(Owner.CharCache);
|
|
TTFFile.SaveToStream(FontData);
|
|
FFontData.Position := 0;
|
|
end
|
|
else
|
|
inherited FontDataNeeded;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontFile.GetOwner: TdxPSPDFCIDFont;
|
|
begin
|
|
Result := TdxPSPDFCIDFont(inherited Owner);
|
|
end;
|
|
|
|
function TdxPSPDFCIDFontFile.GetTTFFile: TdxPSTTFFile;
|
|
begin
|
|
Result := Owner.TTFFile;
|
|
end;
|
|
|
|
{ TdxPSPDFCIDFontDescriptor }
|
|
|
|
function TdxPSPDFCIDFontDescriptor.CreateFontFile: TdxPSPDFFontFile;
|
|
begin
|
|
Result := TdxPSPDFCIDFontFile.Create(Owner);
|
|
end;
|
|
|
|
end.
|