📄 updftextwriter.pas
字号:
//Starts a new chapter/part of the documentation.
procedure WriteNewMainSection(const Title, LabelName: String;
OutlineEntry: POutlineEntry = nil);
//Starts a new section of the documentation.
procedure WriteNewSection(const Title, LabelName: String;
HelpContext: THelpContext = 0);
//Starts a new subsection of the documentation.
procedure WriteNewSubSection(const Title, LabelName: String;
HelpContext: THelpContext = 0);
//Starts a section of an item in the documentation.
procedure WriteNewItemSection(const Title, LabelName: String;
HelpContext: THelpContext = 0);
//Generates the first entry of the outline of the document.
function GenerateFirstOutlineEntry: POutlineEntry;
//Writes the table of contents.
procedure WriteTableOfContents(DetailLevel: TTableOfContentsDetailLevel;
TableOfContentsOutlineEntry: POutlineEntry);
//Adds the section numbers to the titles of the entries for the outline.
procedure AddOutlineSectionNumbers;
//Writes the outline of the documentation.
procedure WriteOutline;
//Resets the object to write a new document.
procedure Reset;
//Prepares the object to write a new document.
procedure Prepare;
// general set-up of the writer and the pages:
property PageWidth: TPDFValue read FPageWidth write FPageWidth;
property PageHeight: TPDFValue read FPageHeight write FPageHeight;
property LeftMargin: TPDFValue read FLeftMargin write FLeftMargin;
property RightMargin: TPDFValue read FRightMargin write FRightMargin;
property TopMargin: TPDFValue read FTopMargin write FTopMargin;
property BottomMargin: TPDFValue read FBottomMargin write FBottomMargin;
property NormalFontSize: TPDFValue read FNormalFontSize
write FNormalFontSize;
property LineDistanceScale: TPDFValue read FLineDistanceScale
write FLineDistanceScale;
property DefaultFontType: TPDFFontType read FDefaultFontType
write FDefaultFontType;
property PageFontType: TPDFFontType read FPageFontType write FPageFontType;
property PageFontStyle: TPDFFontStyles read FPageFontStyle
write FPageFontStyle;
property PageFontSize: TPDFValue read FPageFontSize write FPageFontSize;
property LinkColors: TLinkColors read FLinkColors;
property LinkColor: TColor read FLinkColors[ltThisDoc]
write FLinkColors[ltThisDoc];
property ExternLinkColor: TColor read FLinkColors[ltURI]
write FLinkColors[ltURI];
property FileLinkColor: TColor read FLinkColors[ltFile]
write FLinkColors[ltFile];
property GenerateHelpContextDestinations: Boolean
read FGenerateHelpContextDestinations
write FGenerateHelpContextDestinations;
// other properties
property Writer: TPDFWriter read FWriter write FWriter;
property OnImageLinks: TImageLinksCallBack read FOnImageLinks
write FOnImageLinks;
property PageRect: TPDFRect read FPageRect;
property LineWidth: TPDFValue read FLineWidth;
property Indention: TPDFValue read FIndention;
property LeftLineStart: TPDFValue read FLeftLineStart;
property YPos: TPDFValue read FYPos;
property WritingPageMarkings: Boolean read FWritingPageMarkings;
property WritingPageHeader: Boolean read FWritingPageHeader;
// settings while writing:
property CurrentPageNumber: Integer read FPage write FPage;
//number of the current chapter/part of the documentation
property MainSectionNumber: Integer
{read FMainSectionNumber} write FMainSectionNumber;
property Alignment: TTextAlignment read FAlignment;
property RomanPageNumber: Boolean read FRomanPageNumber
write FRomanPageNumber;
property SectionSamePage: Boolean read FSectionSamePage
write FSectionSamePage;
end;
implementation
uses SysUtils,
General,
UPDFGraphics;
//the colors for the different symbols
const SymbolColors: array[TSymbol] of TColor =
(clRed, $E000E0, clBlue, $00B800, $808000,
clRed, $00B800,
clBlue, //Yellow,
clRed,
clRed, clBlue, clYellow,
clBlack);
//the text in the PDF-file indicating scopes of identifiers
ScopeText = SymbolBullet; //'*'/'o'
//the text in the PDF-file indicating portability issues of identifiers
PortabilityText = 'B'; //#171#187
//the texts in the PDF-file of the symbols
SymbolTexts: array[TSymbol] of Char =
(ScopeText, ScopeText, ScopeText, ScopeText, ScopeText,
ScopeText, ScopeText,
'D', //'*'
'C', //#247
PortabilityText, PortabilityText, PortabilityText,
SymbolBullet);
//used to access the data in a pointer of ~[link TCharacterBreakable]s
//as an array
type TCharBreaksArray = array[0..High(Integer) div
SizeOf(TCharacterBreakable) - 1] of
TCharacterBreakable;
//used to access the data in a pointer of ~[link TCharacterBreakable]s
//as an array
PCharBreaksArray = ^TCharBreaksArray;
{Calculates where to wrap a paragraph at the end of a line.
~param StartIndex the first character in the paragraph to be written, the
first character of the current line or of the current cell
in the row of a table (1-based)
~param MaxIndex the last character of the paragraph to be written
currently, may be different from the total number of
characters in the paragraph in case it is a row of a
table, in that case it will be the index of the last
character in the current cell (1-based)
~param Width the available width in the current line or in the current
cell of a table
~param SumCharWidths the sum of the widths of the characters and all characters
preceding them in the paragraph
~param Breakable the kinds of the characters in the paragraph, used to
determine where to break it
~result the information where and how to wrap the text }
function CalculateWrapPoint(StartIndex, MaxIndex: Integer;
Width: TPDFValue; const SumCharWidths: TPDFValueArray;
Breakable: PCharBreaksArray): TWrapReturn;
{Returns the position of the word wrap only by the widths of the characters.
~param StartIndex, MaxIndex, Width, SumCharWidths the values specified for the
main function
~result the position of the word wrap }
function InitialFittingCharIndex(StartIndex, MaxIndex: Integer;
Width: TPDFValue;
const SumCharWidths: TPDFValueArray): Integer;
var TargetWidth :TPDFValue; //the width to be searched
begin
Result := StartIndex; //search fitting text
//calculate the width to be searched, the width fitting in the line
TargetWidth := Width + SumCharWidths[Pred(Result)];
//search the wrapping point fast
while (Result <= MaxIndex) and (SumCharWidths[Result] <= TargetWidth) do
Inc(Result, 10); //skip 10 characters, and try again
if Result > StartIndex then //some characters fit?
Dec(Result, 9); //too far, so go back again plus one
//now search exact wrapping point
while (Result <= MaxIndex) and (SumCharWidths[Result] <= TargetWidth) do
Inc(Result); //next character
if Result = StartIndex then //at least one character has to fit
Inc(Result);
end;
{Returns the index in the paragraph with white spaces trimmed on its left
side.
~param Index the index in the paragraph to trim
~param StartIndex, Breakable the values specified for the main function
~result the index before the white spaces }
function TrimParagraphLeft(Index, StartIndex: Integer;
Breakable: PCharBreaksArray): Integer;
begin
Result := Index; //start at the index
while (Result >= StartIndex) and //as long as after a white space
(Breakable[Result - 1] = cbSpace) do
Dec(Result); //trim it
end;
var Beginning :Integer; //beginning of the current word
BeginNoSpaces :Integer; //end of the previous "word"
WordEnd :Integer; //end of the current word
i :Integer; //index counter through the text
begin
Assert(Width > 0);
//calculate number of fitting characters as a start value
i := InitialFittingCharIndex(StartIndex, MaxIndex, Width, SumCharWidths);
Result.EndPoint := i - 1; //use the fitting text
Result.AddHyphen := False; //assume, no hyphen is needed
//don't show spaces at the end of the line
Result.EndPoint := TrimParagraphLeft(Result.EndPoint, StartIndex, Breakable);
//some (non-space) characters fit in this line?
if (Result.EndPoint >= StartIndex) and
//and is wrapping point is in a word?
(Result.EndPoint < MaxIndex) and
not (Breakable[Result.EndPoint] in [cbSpace, cbNoLetter]) and
not (Breakable[Result.EndPoint - 1] in [cbSpace, cbNoLetter]) then
begin
//get index of first character on the word
//(at least the first character that has not yet been written)
Beginning := Result.EndPoint;
while (Beginning > StartIndex) and
not (Breakable[Beginning - 2] in [cbSpace, cbNoLetter]) do
Dec(Beginning);
//don't show spaces at the end of the line
BeginNoSpaces := TrimParagraphLeft(Beginning - 1, StartIndex, Breakable);
//line is far from being filled?
if SumCharWidths[BeginNoSpaces] - SumCharWidths[Pred(StartIndex)] <
Width * 0.75 then
begin //try to add a hyphen
//get index of the last character of the word
WordEnd := Result.EndPoint + 2;
while (WordEnd <= MaxIndex) and
not (Breakable[WordEnd - 1] in [cbSpace, cbNoLetter]) do
Inc(WordEnd);
i := Result.EndPoint;
repeat
//search a capital letter as position for splitting the word
while (i > Beginning) and (Breakable[i - 1] <> cbCapital) do
Dec(i);
Dec(i);
//until end of the word is longer than 3 characters or no capital
until (i <= WordEnd - 3) or (i <= Beginning); //letter found
//at least three characters before and after the splitting?
if (i <= WordEnd - 3) and (i >= Beginning + 3) then
Result.EndPoint := i; //split the word before capital letter
//word is splitted, next character of word has to be written in the
Result.ResumePoint := Result.EndPoint + 1; //next line
Result.AddHyphen := True; //hyphen is needed
end //if line is far from being filled?
else
begin
Result.EndPoint := BeginNoSpaces; //write the previous word
Result.ResumePoint := Beginning; //skip the spaces before this word
end;
end //if is in a word?
else
begin
//skip all the white spaces at the end of the line and
Result.ResumePoint := Result.EndPoint + 1; //resume only after them
while (Result.ResumePoint <= MaxIndex) and
(Breakable[Result.ResumePoint - 1] = cbSpace) do
Inc(Result.ResumePoint);
end; //else is in a word?
Assert((Result.EndPoint = StartIndex) or
(SumCharWidths[Result.EndPoint] - SumCharWidths[Pred(StartIndex)] <=
Width + 0.1));
Assert(Result.ResumePoint > Result.EndPoint);
// Assert(SumCharWidths[Result.EndPoint] >= SumCharWidths[Pred(StartIndex)]);
end;
{ //just a test how the tables are shown in the documentation:
exports CalculateWrapPoint index 656 name 'wrapper' resident;
exports CalculateWrapPoint index 656 name 'wrapper' resident;
exports StrToInt index 56;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -