cairocanvas: fix printing stricked/underlined text, issue #26624

git-svn-id: trunk@46077 -
This commit is contained in:
jesus 2014-08-26 01:17:26 +00:00
parent 6cbf4971ee
commit 46c9fdc58b
3 changed files with 140 additions and 9 deletions

View File

@ -35,6 +35,7 @@ type
fFontDesc: PPangoFontDescription; fFontDesc: PPangoFontDescription;
fFontDescStr: string; fFontDescStr: string;
function StylesToStr(Styles: TFontStyles):string; function StylesToStr(Styles: TFontStyles):string;
procedure UpdatePangoLayout(Layout: PPangoLayout);
{$endif} {$endif}
procedure SelectFontEx(AStyle: TFontStyles; const AName: string; procedure SelectFontEx(AStyle: TFontStyles; const AName: string;
ASize: double); ASize: double);
@ -652,6 +653,40 @@ begin
if fsItalic in Styles then if fsItalic in Styles then
Result := Result + 'italic '; Result := Result + 'italic ';
end; end;
procedure TCairoPrinterCanvas.UpdatePangoLayout(Layout: PPangoLayout);
var
AttrListTemporary: Boolean;
AttrList: PPangoAttrList;
Attr: PPangoAttribute;
begin
if Font.Underline or Font.StrikeThrough then begin
AttrListTemporary := false;
AttrList := pango_layout_get_attributes(Layout);
if (AttrList = nil) then
begin
AttrList := pango_attr_list_new();
AttrListTemporary := True;
end;
if Font.Underline then
Attr := pango_attr_underline_new(PANGO_UNDERLINE_SINGLE)
else
Attr := pango_attr_underline_new(PANGO_UNDERLINE_NONE);
pango_attr_list_change(AttrList, Attr);
Attr := pango_attr_strikethrough_new(Font.StrikeThrough);
pango_attr_list_change(AttrList, Attr);
pango_layout_set_attributes(Layout, AttrList);
pango_cairo_update_layout(cr, Layout);
if AttrListTemporary then
pango_attr_list_unref(AttrList);
end;
end;
{$endif} {$endif}
procedure TCairoPrinterCanvas.FillAndStroke; procedure TCairoPrinterCanvas.FillAndStroke;
@ -941,6 +976,7 @@ begin
// use absolute font size sintax (px) // use absolute font size sintax (px)
Layout := Pango_Cairo_Create_Layout(cr); Layout := Pango_Cairo_Create_Layout(cr);
pango_layout_set_font_description(layout, fFontDesc); pango_layout_set_font_description(layout, fFontDesc);
UpdatePangoLayout(Layout);
{$endif} {$endif}
if Font.Orientation = 0 then if Font.Orientation = 0 then
begin begin
@ -1112,6 +1148,7 @@ begin
{$ifdef pangocairo} {$ifdef pangocairo}
Layout := Pango_Cairo_Create_Layout(cr); Layout := Pango_Cairo_Create_Layout(cr);
pango_layout_set_font_description(layout, fFontDesc); pango_layout_set_font_description(layout, fFontDesc);
UpdatePangolayout(Layout);
{$else} {$else}
cairo_font_extents(cr, @fe); cairo_font_extents(cr, @fe);
{$endif} {$endif}

View File

@ -20,7 +20,7 @@ object Form1: TForm1
object btn24217: TButton object btn24217: TButton
Left = 548 Left = 548
Height = 25 Height = 25
Top = 36 Top = 32
Width = 75 Width = 75
Caption = 'btn24217' Caption = 'btn24217'
OnClick = btn24217Click OnClick = btn24217Click
@ -29,17 +29,17 @@ object Form1: TForm1
object btn19435: TButton object btn19435: TButton
Left = 548 Left = 548
Height = 25 Height = 25
Top = 68 Top = 64
Width = 75 Width = 75
Caption = 'btn19435' Caption = 'btn19435'
OnClick = btn19435Click OnClick = btn19435Click
TabOrder = 2 TabOrder = 2
end end
object chkTests: TCheckGroup object chkTests: TCheckGroup
Left = 526 Left = 520
Height = 80 Height = 88
Top = 144 Top = 144
Width = 97 Width = 103
AutoFill = True AutoFill = True
Caption = 'Paint or Print' Caption = 'Paint or Print'
ChildSizing.LeftRightSpacing = 6 ChildSizing.LeftRightSpacing = 6
@ -50,17 +50,18 @@ object Form1: TForm1
ChildSizing.ShrinkVertical = crsScaleChilds ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1 ChildSizing.ControlsPerLine = 1
ClientHeight = 57 ClientHeight = 65
ClientWidth = 93 ClientWidth = 99
Items.Strings = ( Items.Strings = (
'24217' '24217'
'19435' '19435'
'Other' 'Other'
'Underline'
) )
OnItemClick = chkTestsItemClick OnItemClick = chkTestsItemClick
TabOrder = 3 TabOrder = 3
Data = { Data = {
03000000020202 0400000002020202
} }
end end
object btnPrintAll: TButton object btnPrintAll: TButton
@ -75,7 +76,7 @@ object Form1: TForm1
object btnOther: TButton object btnOther: TButton
Left = 548 Left = 548
Height = 25 Height = 25
Top = 100 Top = 96
Width = 75 Width = 75
Caption = 'btnOther' Caption = 'btnOther'
OnClick = btnOtherClick OnClick = btnOtherClick
@ -139,6 +140,15 @@ object Form1: TForm1
) )
TabOrder = 7 TabOrder = 7
end end
object btnUnderline: TButton
Left = 548
Height = 25
Top = 124
Width = 75
Caption = 'btnUnderline'
OnClick = btnUnderlineClick
TabOrder = 8
end
object PrintDialog1: TPrintDialog object PrintDialog1: TPrintDialog
left = 129 left = 129
top = 28 top = 28

View File

@ -13,6 +13,7 @@ type
{ TForm1 } { TForm1 }
TForm1 = class(TForm) TForm1 = class(TForm)
btnUnderline: TButton;
Button1: TButton; Button1: TButton;
btn24217: TButton; btn24217: TButton;
btn19435: TButton; btn19435: TButton;
@ -25,6 +26,7 @@ type
procedure btn19435Click(Sender: TObject); procedure btn19435Click(Sender: TObject);
procedure btnOtherClick(Sender: TObject); procedure btnOtherClick(Sender: TObject);
procedure btnPrintAllClick(Sender: TObject); procedure btnPrintAllClick(Sender: TObject);
procedure btnUnderlineClick(Sender: TObject);
procedure Button1Click(Sender: TObject); procedure Button1Click(Sender: TObject);
procedure btn24217Click(Sender: TObject); procedure btn24217Click(Sender: TObject);
procedure chkTestsItemClick(Sender: TObject; Index: integer); procedure chkTestsItemClick(Sender: TObject; Index: integer);
@ -33,10 +35,12 @@ type
procedure Draw19435(cnv: TCanvas; XDPI,YDPI: Integer); procedure Draw19435(cnv: TCanvas; XDPI,YDPI: Integer);
procedure Draw24217(cnv: TCanvas; XDPI,YDPI: Integer); procedure Draw24217(cnv: TCanvas; XDPI,YDPI: Integer);
procedure DrawOther(cnv: TCanvas; XDPI,YDPI: Integer); procedure DrawOther(cnv: TCanvas; XDPI,YDPI: Integer);
procedure DrawUnderline(cnv: TCanvas; XDPI,YDPI: Integer);
function GetOtherAlignment:TAlignment; function GetOtherAlignment:TAlignment;
function GetOtherLayout:TTextLayout; function GetOtherLayout:TTextLayout;
procedure GetReferencePoint(const r: TRect; cnv:TCanvas; out x, y: Integer); procedure GetReferencePoint(const r: TRect; cnv:TCanvas; out x, y: Integer);
procedure PrintOther(aFileName: string = 'other'; aBackend: TCairoBackend = cbPDF); procedure PrintOther(aFileName: string = 'other'; aBackend: TCairoBackend = cbPDF);
procedure PrintUnderline(aFileName: string = 'underline'; aBackend: TCairoBackend = cbPDF);
public public
{ public declarations } { public declarations }
end; end;
@ -131,6 +135,11 @@ begin
end; end;
end; end;
procedure TForm1.btnUnderlineClick(Sender: TObject);
begin
PrintUnderline;
end;
procedure TForm1.btn24217Click(Sender: TObject); procedure TForm1.btn24217Click(Sender: TObject);
var var
CairoPrinter: TCairoFilePrinter; CairoPrinter: TCairoFilePrinter;
@ -160,6 +169,7 @@ begin
if chkTests.Checked[0] then Draw24217(Canvas, ResX, ResY); if chkTests.Checked[0] then Draw24217(Canvas, ResX, ResY);
if chkTests.Checked[1] then Draw19435(Canvas, ResX, ResY); if chkTests.Checked[1] then Draw19435(Canvas, ResX, ResY);
if chkTests.Checked[2] then DrawOther(Canvas, ResX, ResY); if chkTests.Checked[2] then DrawOther(Canvas, ResX, ResY);
if chkTests.Checked[3] then DrawUnderline(Canvas, ResX, ResY);
end; end;
procedure TForm1.Draw19435(cnv: TCanvas; XDPI, YDPI: Integer); procedure TForm1.Draw19435(cnv: TCanvas; XDPI, YDPI: Integer);
@ -375,6 +385,65 @@ begin
format('Alignment: "%s" Layout: "%s" Orientation: %d° ',[sA, sL, radOtherAngle.ItemIndex * 90])); format('Alignment: "%s" Layout: "%s" Orientation: %d° ',[sA, sL, radOtherAngle.ItemIndex * 90]));
end; end;
procedure TForm1.DrawUnderline(cnv: TCanvas; XDPI, YDPI: Integer);
const
STEXT = 'Pájaro';
var
y: Integer;
sz: TSize;
R: TRect;
begin
// using TextOut
R := Rect(XDPI, YDPI, 0, 0);
cnv.Font.Name := 'Arial';
cnv.Font.Size := 40;
cnv.Font.Color := clBlue;
cnv.Font.Orientation:=0;
cnv.Font.Underline := false;
y := R.Top;
cnv.TextOut(R.Left, y, STEXT);
cnv.Font.Underline := true;
sz := cnv.TextExtent(STEXT);
inc(y, sz.cy);
cnv.TextOut(XDPI, y, STEXT);
cnv.Font.Underline := false;
cnv.Font.StrikeThrough := true;
inc(y, sz.cy);
cnv.TextOut(XDPI, y, STEXT);
cnv.Font.Underline := true;
cnv.Font.StrikeThrough := true;
inc(y, sz.cy);
cnv.TextOut(XDPI, y, STEXT);
// using TextRect
cnv.Font.Color:= clRed;
cnv.Font.Underline := false;
cnv.Font.StrikeThrough := false;
OffsetRect(R, 2*XDPI, 0);
R.Right := R.Left + sz.cx;
R.Bottom := R.Top + sz.cy;
cnv.TextRect(R, R.Left, R.Top, STEXT);
OffsetRect(R, 0, sz.cy);
cnv.Font.Underline := true;
cnv.Font.StrikeThrough := false;
cnv.TextRect(R, R.Left, R.Top, STEXT);
OffsetRect(R, 0, sz.cy);
cnv.Font.Underline := false;
cnv.Font.StrikeThrough := true;
cnv.TextRect(R, R.Left, R.Top, STEXT);
OffsetRect(R, 0, sz.cy);
cnv.Font.Underline := true;
cnv.Font.StrikeThrough := true;
cnv.TextRect(R, R.Left, R.Top, STEXT);
end;
function TForm1.GetOtherAlignment: TAlignment; function TForm1.GetOtherAlignment: TAlignment;
begin begin
case radOtherAlign.ItemIndex of case radOtherAlign.ItemIndex of
@ -438,5 +507,20 @@ begin
CairoPrinter.Free; CairoPrinter.Free;
end; end;
procedure TForm1.PrintUnderline(aFileName: string = 'underline'; aBackend: TCairoBackend = cbPDF);
var
CairoPrinter: TCairoFilePrinter;
begin
CairoPrinter := TCairoFilePrinter.create;
//CairoPrinter.CairoBackend:=cbPS;
CairoPrinter.CairoBackend:=aBackend;
CairoPrinter.FileName:=aFileName;
CairoPrinter.BeginDoc;
with CairoPrinter do
DrawUnderline(Canvas, XDPI, YDPI);
CairoPrinter.EndDoc;
CairoPrinter.Free;
end;
end. end.