fpvectorial: Finishes implementing support for reading both example formula files

git-svn-id: trunk@37758 -
This commit is contained in:
sekelsenmat 2012-06-24 10:09:34 +00:00
parent 491b602094
commit bfc74c2a43
2 changed files with 85 additions and 36 deletions

View File

@ -25,7 +25,7 @@ unit fpvectorial;
interface
uses
Classes, SysUtils, Math,
Classes, SysUtils, Math, TypInfo,
// FCL-Image
fpcanvas, fpimage,
// LCL
@ -412,9 +412,8 @@ type
fekFraction, // a division with Formula on the top and AdjacentFormula in the bottom
fekRoot, // A root. For example sqrt(something). Number gives the root, usually 2, and inside it goes a Formula
fekPower, // A Formula elevated to a AdjacentFormula, example: 2^5
fekParenteses,// This is utilized to group elements. Inside it goes a Formula
fekParentesesWithPower, // The same as parenteses, but elevated to the power of "Number"
fekSomatory // Sum of a variable given by Text from Number to AdjacentNumber
fekSubscript, // A Formula with a subscripted element AdjacentFormula, example: Xi
fekSomatory // Sum of a variable given by Text set by Formula in the bottom and going up to AdjacentFormula in the top
);
{ TvFormulaElement }
@ -424,7 +423,6 @@ type
Kind: TvFormulaElementKind;
Text: string;
Number: Double;
AdjacentNumber: Double;
Formula: TvFormula;
AdjacentFormula: TvFormula;
public
@ -1699,8 +1697,6 @@ begin
fekFraction: Result := 2.3;
fekRoot: Result := Formula.CalculateHeight(ADest);
fekPower: Result := 1.1;
//fekParenteses: Result,// This is utilized to group elements. Inside it goes a Formula
fekParentesesWithPower: Result := 1.1;
fekSomatory: Result := 1.5;
else
Result := 1.0;
@ -1724,8 +1720,6 @@ begin
// fekFraction: Result := 2.3;
fekRoot: Result := Formula.CalculateWidth(ADest) + 5;
fekPower: Result := Round(Result * 1.2);
fekParenteses: Result := Result + 6;
fekParentesesWithPower: Result := Result + 8;
fekSomatory: Result := 8;
else
end;
@ -1744,15 +1738,9 @@ begin
fekLessOrEqualThan: Result := '<=';
fekGreaterThan: Result := '>';
fekGreaterOrEqualThan: Result := '>=';
// More complex elements
fekFraction: Result := '[fekFraction]';
fekRoot: Result := '[fekRoot]';
fekPower: Result := '[fekPower]';
fekParenteses: Result := '[fekParenteses]';
fekParentesesWithPower: Result := '[fekParentesesWithPower]';
fekSomatory: Result := '[fekSomatory]';
// More complex elements
else
Result := '';
Result := Format('[%s]', [GetEnumName(TypeInfo(TvFormulaElementKind), integer(Kind))]);
end;
end;
@ -1792,23 +1780,17 @@ begin
lDBGItem := ADestRoutine(Self.AsText(), APageItem);
case Kind of
fekFraction:
fekFraction, fekPower, fekSubscript, fekSomatory:
begin
lDBGFormula := ADestRoutine('Formula', lDBGItem);
lDBGFormula := ADestRoutine('Main Formula', lDBGItem);
Formula.GenerateDebugTree(ADestRoutine, lDBGFormula);
lDBGFormulaBottom := ADestRoutine('Bottom Formula', lDBGItem);
if Kind in [fekPower, fekSomatory] then
lDBGFormulaBottom := ADestRoutine('Top Formula', lDBGItem)
else
lDBGFormulaBottom := ADestRoutine('Bottom Formula', lDBGItem);
AdjacentFormula.GenerateDebugTree(ADestRoutine, lDBGFormulaBottom);
end;
fekRoot: Formula.GenerateDebugTree(ADestRoutine, lDBGItem);
fekPower:
begin
lDBGFormula := ADestRoutine('Formula', lDBGItem);
Formula.GenerateDebugTree(ADestRoutine, lDBGFormula);
lDBGFormulaBottom := ADestRoutine('Top Formula', lDBGItem);
AdjacentFormula.GenerateDebugTree(ADestRoutine, lDBGFormulaBottom);
end;
//fekParenteses: Result,// This is utilized to group elements. Inside it goes a Formula
//fekParentesesWithPower: Result := 1.1;
//fekSomatory: Result := 1.5;
end;
end;
@ -1854,9 +1836,7 @@ end;
function TvFormula.AddElementWithKind(AKind: TvFormulaElementKind): TvFormulaElement;
begin
Result := TvFormulaElement.Create;
Result.Kind := AKind;
AddElement(Result);
AddElementWithKindAndText(AKind, '');
end;
function TvFormula.AddElementWithKindAndText(AKind: TvFormulaElementKind;
@ -1866,6 +1846,18 @@ begin
Result.Kind := AKind;
Result.Text := AText;
AddElement(Result);
case AKind of
fekFraction, fekPower, fekSubscript, fekSomatory:
begin
Result.Formula := TvFormula.Create;
Result.AdjacentFormula := TvFormula.Create;
end;
fekRoot:
begin
Result.Formula := TvFormula.Create;
end;
end;
end;
procedure TvFormula.Clear;

View File

@ -66,7 +66,8 @@ var
lSubNodeNameStr: DOMString;
begin
lNodeName := ANode.NodeName;
lNodeText := ANode.FirstChild.NodeValue;
if ANode.FirstChild <> nil then
lNodeText := ANode.FirstChild.NodeValue;
// mi - variables
// Examples:
// <mi>x</mi>
@ -154,8 +155,6 @@ begin
else if lNodeName = 'msup' then
begin
lFormElem := AFormula.AddElementWithKind(fekPower);
lFormElem.Formula := TvFormula.Create;
lFormElem.AdjacentFormula := TvFormula.Create;
// First read the bottom element
lMFracRow := ANode.FirstChild;
@ -165,11 +164,69 @@ begin
lMFracRow := lMFracRow.NextSibling;
AddNodeToFormula(lMFracRow, APage, lFormElem.AdjacentFormula);
end
{ msub - Subscript
Example: Xi
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mi>i</mi>
</mrow>
</msub>
}
else if lNodeName = 'msub' then
begin
lFormElem := AFormula.AddElementWithKind(fekSubscript);
// First read the main element
lMFracRow := ANode.FirstChild;
AddNodeToFormula(lMFracRow, APage, lFormElem.Formula);
// Now the subscripted element
lMFracRow := lMFracRow.NextSibling;
AddNodeToFormula(lMFracRow, APage, lFormElem.AdjacentFormula);
end
// mrow may appear where unnecessary, in this cases just keep reading further
else if lNodeName = 'mrow' then
begin
ReadFormulaFromNodeChildren(ANode, APage, AFormula);
end
// mstyle can be ignored
else if lNodeName = 'mstyle' then
begin
ReadFormulaFromNodeChildren(ANode, APage, AFormula);
end
{ Somatory
<munderover>
<mrow>
<mo>&#x2211;</mo>
</mrow>
<mrow>
<mi>i</mi>
<mo>=</mo>
<mn>1</mn>
</mrow>
<mrow>
<mi>N</mi>
</mrow>
</munderover>
}
else if lNodeName = 'munderover' then
begin
lFormElem := AFormula.AddElementWithKind(fekSomatory);
// The first element is just the symbol, ignore it
lMFracRow := ANode.FirstChild;
ReadFormulaFromNodeChildren(lMFracRow, APage, AFormula);
// Read the bottom element
lMFracRow := lMFracRow.NextSibling;
AddNodeToFormula(lMFracRow, APage, lFormElem.Formula);
// Now the top element
lMFracRow := lMFracRow.NextSibling;
AddNodeToFormula(lMFracRow, APage, lFormElem.AdjacentFormula);
end;
end;