mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 21:39:11 +02:00
fpvectorial: Some fixes in wmf reader (rounded rectangle, text positioning)
git-svn-id: trunk@52824 -
This commit is contained in:
parent
c0b60cfaa4
commit
fb89d63113
@ -86,8 +86,8 @@ type
|
|||||||
procedure ReadPolygon(APage: TvVectorialPage; const AParams: TParamArray;
|
procedure ReadPolygon(APage: TvVectorialPage; const AParams: TParamArray;
|
||||||
AFilled: boolean);
|
AFilled: boolean);
|
||||||
procedure ReadPolyPolygon(APage: TvVectorialPage; const AParams: TParamArray);
|
procedure ReadPolyPolygon(APage: TvVectorialPage; const AParams: TParamArray);
|
||||||
procedure ReadRectangle(APage: TvVectorialPage; const AParams: TParamArray);
|
procedure ReadRectangle(APage: TvVectorialPage; const AParams: TParamArray;
|
||||||
procedure ReadRoundRect(APage: TvVectorialPage; const AParams: TParamArray);
|
IsRounded: Boolean);
|
||||||
procedure ReadStretchDIB(AStream: TStream; APage: TvVectorialPage;
|
procedure ReadStretchDIB(AStream: TStream; APage: TvVectorialPage;
|
||||||
const AParams: TParamArray);
|
const AParams: TParamArray);
|
||||||
function ReadString(const AParams: TParamArray;
|
function ReadString(const AParams: TParamArray;
|
||||||
@ -272,19 +272,28 @@ function TvWMFVectorialReader.CreateFont(const AParams: TParamArray): Integer;
|
|||||||
var
|
var
|
||||||
wmfFont: TWMFFont;
|
wmfFont: TWMFFont;
|
||||||
fontRec: PWMFFontRecord;
|
fontRec: PWMFFontRecord;
|
||||||
|
fntName: String;
|
||||||
|
idx: Integer;
|
||||||
begin
|
begin
|
||||||
|
idx := Length(Aparams);
|
||||||
wmfFont := TWMFFont.Create;
|
wmfFont := TWMFFont.Create;
|
||||||
fontRec := PWMFFontRecord(@AParams[0]);
|
fontRec := PWMFFontRecord(@AParams[0]);
|
||||||
|
|
||||||
wmfFont.Font.Name := ISO_8859_1ToUTF8(fontRec^.FaceName);
|
// Get font name
|
||||||
|
SetLength(fntName, 32);
|
||||||
|
idx := SizeOf(TWMFFontRecord) div SizeOf(word);
|
||||||
|
Move(AParams[idx], fntName[1], 32);
|
||||||
|
SetLength(fntName, StrLen(PChar(@fntName)));
|
||||||
|
|
||||||
|
wmfFont.Font.Name := ISO_8859_1ToUTF8(fntName);
|
||||||
wmfFont.Font.Size := round(ScaleSizeY(fontRec^.Height));
|
wmfFont.Font.Size := round(ScaleSizeY(fontRec^.Height));
|
||||||
wmfFont.Font.Color := colBlack; // to be replaced by FCurrTextColor
|
wmfFont.Font.Color := colBlack; // to be replaced by FCurrTextColor
|
||||||
wmfFont.Font.Bold := fontRec^.Weight >= 700;
|
wmfFont.Font.Bold := fontRec^.Weight >= 700;
|
||||||
wmfFont.Font.Italic := fontRec^.Italic <> 0; //Escapement <> 0;
|
wmfFont.Font.Italic := fontRec^.Italic <> 0;
|
||||||
wmfFont.Font.Underline := fontRec^.UnderLine <> 0;
|
wmfFont.Font.Underline := fontRec^.UnderLine <> 0;
|
||||||
wmfFont.Font.StrikeThrough := fontRec^.Strikeout <> 0;
|
wmfFont.Font.StrikeThrough := fontRec^.Strikeout <> 0;
|
||||||
wmfFont.Font.Orientation := fontRec^.Orientation div 10;
|
wmfFont.Font.Orientation := fontRec^.Orientation div 10;
|
||||||
wmfFont.RawHeight := fontRec^.Height;
|
wmfFont.RawHeight := fontRec^.Height; //* 6 div 5; // Rough correction for y position
|
||||||
|
|
||||||
// add to WMF object list
|
// add to WMF object list
|
||||||
Result := FObjList.Add(wmfFont);
|
Result := FObjList.Add(wmfFont);
|
||||||
@ -465,6 +474,7 @@ var
|
|||||||
R: TRect;
|
R: TRect;
|
||||||
s: String;
|
s: String;
|
||||||
txt: TvText;
|
txt: TvText;
|
||||||
|
angle: Double;
|
||||||
begin
|
begin
|
||||||
y := SmallInt(AParams[0]); // signed int
|
y := SmallInt(AParams[0]); // signed int
|
||||||
x := SmallInt(AParams[1]);
|
x := SmallInt(AParams[1]);
|
||||||
@ -482,19 +492,17 @@ begin
|
|||||||
|
|
||||||
// Correct text position which is at baseline in case of fpvectorial, but
|
// Correct text position which is at baseline in case of fpvectorial, but
|
||||||
// may be different depending on bits in the CurrTextAlign value.
|
// may be different depending on bits in the CurrTextAlign value.
|
||||||
case FCurrTextAlign and (TA_BOTTOM + TA_BASELINE) of
|
|
||||||
0 :
|
// TO DO: More testing of text positioning
|
||||||
{ In this case, the text should be top-aligned, but fpvectorial draws
|
angle := DegToRad(FCurrFont.Orientation);
|
||||||
the text at the baseline --> move it down (and take care of text
|
case FCurrTextAlign and $0018 of
|
||||||
rotation!) }
|
0:
|
||||||
offs := Rotate2DPoint(Point(0, FCurrRawFontHeight), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
offs := Point(0, 0); //Rotate2DPoint(Point(0, +FCurrRawFontHeight), Point(0, 0), angle);
|
||||||
TA_BASELINE:
|
TA_BASELINE:
|
||||||
{ This is the way how fpvectorial draws the text --> nothing to do }
|
// offs := Rotate2DPoint(Point(0, -FCurrRawFontHeight*6 div 5), Point(0, 0), angle);
|
||||||
offs := Point(0, 0);
|
offs := Rotate2DPoint(Point(0, +FCurrRawFontHeight), Point(0, 0), angle);
|
||||||
TA_BOTTOM:
|
TA_BOTTOM:
|
||||||
{ Unfortunately we don't know the descender of the font here. Lets
|
offs := Rotate2DPoint(Point(0, -FCurrRawFontHeight*7 div 5), Point(0, 0), angle);
|
||||||
assume it to be 1/5th of the font size. Move text up. }
|
|
||||||
offs := Rotate2DPoint(Point(0, -FCurrRawFontHeight div 5), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Pass text to fpvectorial
|
// Pass text to fpvectorial
|
||||||
@ -502,7 +510,7 @@ begin
|
|||||||
// Select the font
|
// Select the font
|
||||||
txt.Font := FCurrFont;
|
txt.Font := FCurrFont;
|
||||||
// Set horizontal text alignment.
|
// Set horizontal text alignment.
|
||||||
case FCurrTextAlign and (TA_RIGHT + TA_CENTER) of
|
case FCurrTextAlign and (TA_RIGHT or TA_CENTER) of
|
||||||
TA_RIGHT : txt.TextAnchor := vtaEnd;
|
TA_RIGHT : txt.TextAnchor := vtaEnd;
|
||||||
TA_CENTER : txt.TextAnchor := vtaMiddle;
|
TA_CENTER : txt.TextAnchor := vtaMiddle;
|
||||||
else txt.TextAnchor := vtaStart;
|
else txt.TextAnchor := vtaStart;
|
||||||
@ -556,7 +564,7 @@ begin
|
|||||||
// Test if file begins with a placeable meta file header
|
// Test if file begins with a placeable meta file header
|
||||||
FHasPlaceableMetaHeader := false;
|
FHasPlaceableMetaHeader := false;
|
||||||
AStream.ReadBuffer(buf, SizeOf(TPlaceableMetaHeader));
|
AStream.ReadBuffer(buf, SizeOf(TPlaceableMetaHeader));
|
||||||
if placeableMetaHdr.Key = $9AC6CDD7 then begin // yes!
|
if placeableMetaHdr.Key = WMF_MAGIC_NUMBER then begin // yes!
|
||||||
FHasPlaceableMetaHeader := true;
|
FHasPlaceableMetaHeader := true;
|
||||||
FBBox.Left := placeableMetaHdr.Left;
|
FBBox.Left := placeableMetaHdr.Left;
|
||||||
FBBox.Top := placeableMetaHdr.Top;
|
FBBox.Top := placeableMetaHdr.Top;
|
||||||
@ -663,8 +671,10 @@ begin
|
|||||||
poly.Pen := FCurrPen;
|
poly.Pen := FCurrPen;
|
||||||
if AFilled then
|
if AFilled then
|
||||||
poly.Brush := FCurrBrush
|
poly.Brush := FCurrBrush
|
||||||
else
|
else begin
|
||||||
poly.Brush.Style := bsClear;
|
poly.Brush.Style := bsClear;
|
||||||
|
poly.Brush.Kind := bkSimpleBrush;
|
||||||
|
end;
|
||||||
case FCurrPolyFillMode of
|
case FCurrPolyFillMode of
|
||||||
ALTERNATE : poly.WindingRule := vcmEvenOddRule;
|
ALTERNATE : poly.WindingRule := vcmEvenOddRule;
|
||||||
WINDING : poly.WindingRule := vcmNonZeroWindingRule;
|
WINDING : poly.WindingRule := vcmNonZeroWindingRule;
|
||||||
@ -808,9 +818,9 @@ begin
|
|||||||
META_POLYPOLYGON:
|
META_POLYPOLYGON:
|
||||||
ReadPolyPolygon(page, params);
|
ReadPolyPolygon(page, params);
|
||||||
META_RECTANGLE:
|
META_RECTANGLE:
|
||||||
ReadRectangle(page, params);
|
ReadRectangle(page, params, false);
|
||||||
META_ROUNDRECT:
|
META_ROUNDRECT:
|
||||||
ReadRectangle(page, params);
|
ReadRectangle(page, params, true);
|
||||||
META_SETPIXEL:
|
META_SETPIXEL:
|
||||||
;
|
;
|
||||||
META_TEXTOUT:
|
META_TEXTOUT:
|
||||||
@ -919,7 +929,7 @@ begin
|
|||||||
|
|
||||||
SetLength(params, 0);
|
SetLength(params, 0);
|
||||||
end;
|
end;
|
||||||
|
(*
|
||||||
procedure TvWMFVectorialReader.ReadRectangle(APage: TvVectorialPage;
|
procedure TvWMFVectorialReader.ReadRectangle(APage: TvVectorialPage;
|
||||||
const AParams: TParamArray);
|
const AParams: TParamArray);
|
||||||
// To do: not tested, having not test file
|
// To do: not tested, having not test file
|
||||||
@ -943,25 +953,29 @@ begin
|
|||||||
poly.Brush := FCurrBrush;
|
poly.Brush := FCurrBrush;
|
||||||
APage.AddEntity(poly);
|
APage.AddEntity(poly);
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
procedure TvWMFVectorialReader.ReadRoundRect(APage: TvVectorialPage;
|
procedure TvWMFVectorialReader.ReadRectangle(APage: TvVectorialPage;
|
||||||
const AParams: TParamArray);
|
const AParams: TParamArray; IsRounded: Boolean);
|
||||||
// To do: not tested, having no test file
|
|
||||||
var
|
var
|
||||||
rectRec: PWMFRectRecord; // coordinates are SmallInt
|
rectRec: PWMFRectRecord; // coordinates are SmallInt
|
||||||
rx, ry: SmallInt;
|
rx, ry: SmallInt;
|
||||||
rect: TvRectangle;
|
rect: TvRectangle;
|
||||||
begin
|
begin
|
||||||
ry := AParams[0];
|
if IsRounded then begin
|
||||||
rx := AParams[1];
|
ry := AParams[0];
|
||||||
|
rx := AParams[1];
|
||||||
rectRec := PWMFRectRecord(@AParams[4]);
|
rectRec := PWMFRectRecord(@AParams[2]);
|
||||||
|
end else begin
|
||||||
|
rectRec := PWMFRectRecord(@AParams[0]);
|
||||||
|
rx := 0;
|
||||||
|
ry := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
rect := TvRectangle.Create(APage);
|
rect := TvRectangle.Create(APage);
|
||||||
rect.X := ScaleX(rectRec^.Left);
|
rect.X := ScaleX(rectRec^.Left);
|
||||||
rect.Y := ScaleY(rectRec^.Top);
|
rect.Y := ScaleY(rectRec^.Bottom); // since the axis goes down bottom and top are interchanged!
|
||||||
rect.CX := ScaleSizeX(rectRec^.Right - rectRec^.Left);
|
rect.CX := ScaleSizeX(rectRec^.Right - rectRec^.Left);
|
||||||
rect.CY := ScaleSizeY(rectRec^.Bottom - rectRec^.Top);
|
rect.CY := ScaleSizeY(rectRec^.Bottom - rectRec^.Top); // wmf: Top < Bottom!
|
||||||
rect.RX := ScaleSizeX(rx);
|
rect.RX := ScaleSizeX(rx);
|
||||||
rect.RY := ScaleSizeY(ry);
|
rect.RY := ScaleSizeY(ry);
|
||||||
rect.Pen := FCurrPen;
|
rect.Pen := FCurrPen;
|
||||||
@ -1090,37 +1104,41 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
txt: TvText;
|
txt: TvText;
|
||||||
offs: TPoint;
|
offs: TPoint;
|
||||||
|
txtHeight: Integer;
|
||||||
begin
|
begin
|
||||||
|
{ Record layout:
|
||||||
|
word - String length
|
||||||
|
even number of bytes - String, no trailing zero
|
||||||
|
smallInt - yStart
|
||||||
|
smallInt - xStart }
|
||||||
|
|
||||||
len := AParams[0];
|
len := AParams[0];
|
||||||
i := 1;
|
i := 1;
|
||||||
s := ReadString(AParams, i, len);
|
s := ReadString(AParams, i, len);
|
||||||
inc(i, len);
|
if odd(len) then inc(len);
|
||||||
if odd(len) then inc(i);
|
inc(i, len div 2);
|
||||||
y := SmallInt(AParams[i]); // signed int!
|
y := SmallInt(AParams[i]); // signed int!
|
||||||
x := SmallInt(AParams[i + 1]);
|
x := SmallInt(AParams[i + 1]);
|
||||||
|
|
||||||
// Correct text position which is at baseline in case of fpvectorial, but
|
// Correct text position which is at baseline in case of fpvectorial, but
|
||||||
// may be different depending on bits in the CurrTextAlign value.
|
// may be different depending on bits in the CurrTextAlign value.
|
||||||
case FCurrTextAlign and (TA_BOTTOM + TA_BASELINE) of
|
|
||||||
0 :
|
// TO DO: More testing of text positioning.
|
||||||
{ In this case, the text should be top-aligned, but fpvectorial draws it
|
case FCurrTextAlign and $0018 of
|
||||||
at the baseline --> move it down (and respect text rotation!) }
|
0:
|
||||||
offs := Rotate2DPoint(Point(0, FCurrRawFontHeight), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
|
||||||
TA_BASELINE:
|
|
||||||
{ This is the way how fpvectorial draws the text --> nothing to do }
|
|
||||||
offs := Point(0, 0);
|
offs := Point(0, 0);
|
||||||
|
TA_BASELINE:
|
||||||
|
offs := Rotate2DPoint(Point(0, FCurrRawFontHeight), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
||||||
TA_BOTTOM:
|
TA_BOTTOM:
|
||||||
{ Unfortunately we don't know the descender of the font here. Lets
|
offs := Rotate2DPoint(Point(0, -FCurrRawFontHeight*7 div 5), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
||||||
assume it to be 1/5th of the font size. Move text up. }
|
|
||||||
offs := Rotate2DPoint(Point(0, -FCurrRawFontHeight div 5), Point(0, 0), DegToRad(FCurrFont.Orientation));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Pass the text to fpvectorial
|
// Pass the text to fpvectorial
|
||||||
txt := APage.AddText(x + offs.x, y + offs.y, s);
|
txt := APage.AddText(ScaleX(x + offs.x), ScaleY(y + offs.y), s);
|
||||||
// Select the font
|
// Select the font
|
||||||
txt.Font := FCurrFont;
|
txt.Font := FCurrFont;
|
||||||
// Set horizontal text alignment.
|
// Set horizontal text alignment.
|
||||||
case FCurrTextAlign and (TA_RIGHT + TA_CENTER) of
|
case FCurrTextAlign and (TA_RIGHT or TA_CENTER) of
|
||||||
TA_RIGHT : txt.TextAnchor := vtaEnd;
|
TA_RIGHT : txt.TextAnchor := vtaEnd;
|
||||||
TA_CENTER : txt.TextAnchor := vtaMiddle;
|
TA_CENTER : txt.TextAnchor := vtaMiddle;
|
||||||
else txt.TextAnchor := vtaStart;
|
else txt.TextAnchor := vtaStart;
|
||||||
@ -1203,6 +1221,7 @@ end;
|
|||||||
function TvWMFVectorialReader.ScaleY(y: Integer): Double;
|
function TvWMFVectorialReader.ScaleY(y: Integer): Double;
|
||||||
begin
|
begin
|
||||||
Result := ScaleSizeY(y - FWindowOrigin.Y); // there is probably an issue with y direction
|
Result := ScaleSizeY(y - FWindowOrigin.Y); // there is probably an issue with y direction
|
||||||
|
// Result := FPageHeight - ScaleSizeY(y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvWMFVectorialReader.ScaleSizeX(x: Integer): Double;
|
function TvWMFVectorialReader.ScaleSizeX(x: Integer): Double;
|
||||||
|
Loading…
Reference in New Issue
Block a user