Skip to content

Commit edc83d0

Browse files
author
indexm
committed
Add Strikethrough to Font
1 parent 8b9076c commit edc83d0

File tree

8 files changed

+302
-2
lines changed

8 files changed

+302
-2
lines changed

MigraDocCore.DocumentObjectModel/MigraDoc.DocumentObjectModel/Font.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ internal void ApplyFont(Font font, Font refFont)
110110
if (!font.underline.IsNull && (refFont == null || font.Underline != refFont.Underline))
111111
this.Underline = font.Underline;
112112

113+
if (!font.strikethrough.IsNull && (refFont == null || font.Strikethrough != refFont.Strikethrough))
114+
this.Strikethrough = font.Strikethrough;
115+
113116
if (!font.color.IsNull && (refFont == null || font.Color.Argb != refFont.Color.Argb))
114117
this.Color = font.Color;
115118
}
@@ -142,6 +145,9 @@ public void ApplyFont(Font font)
142145
if (!font.underline.IsNull)
143146
this.Underline = font.Underline;
144147

148+
if (!font.strikethrough.IsNull)
149+
this.Strikethrough = font.Strikethrough;
150+
145151
if (!font.color.IsNull)
146152
this.Color = font.Color;
147153
}
@@ -244,6 +250,15 @@ public bool Subscript
244250
[DV]
245251
internal NBool subscript = NBool.NullValue;
246252

253+
254+
public Strikethrough Strikethrough
255+
{
256+
get { return (Strikethrough)this.strikethrough.Value; }
257+
set { this.strikethrough.Value = (int)value; }
258+
}
259+
[DV(Type = typeof(Strikethrough))]
260+
internal NEnum strikethrough = NEnum.NullValue(typeof(Strikethrough));
261+
247262
// + .Name = "Verdana"
248263
// + .Size = 8
249264
// + .Bold = False
@@ -362,6 +377,9 @@ internal void Serialize(Serializer serializer, Font font)
362377
if (!this.underline.IsNull)
363378
serializer.WriteSimpleAttribute("Underline", this.Underline);
364379

380+
if (!this.strikethrough.IsNull)
381+
serializer.WriteSimpleAttribute("Strikethrough", this.Strikethrough);
382+
365383
if (!this.superscript.IsNull)
366384
serializer.WriteSimpleAttribute("Superscript", this.Superscript);
367385

@@ -399,6 +417,9 @@ internal void Serialize(Serializer serializer, Font font)
399417
if (!underline.IsNull && (font == null || Underline != font.Underline || font.underline.IsNull))
400418
serializer.WriteSimpleAttribute("Underline", Underline);
401419

420+
if (!strikethrough.IsNull && (font == null || Strikethrough != font.Strikethrough || font.strikethrough.IsNull))
421+
serializer.WriteSimpleAttribute("Strikethrough", Strikethrough);
422+
402423
if (!superscript.IsNull && (font == null || Superscript != font.Superscript || font.superscript.IsNull))
403424
serializer.WriteSimpleAttribute("Superscript", Superscript);
404425

MigraDocCore.DocumentObjectModel/MigraDoc.DocumentObjectModel/Styles.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ internal void SetupStyles()
228228
style.Font.Color = Colors.Black;
229229
style.Font.Subscript = false;
230230
style.Font.Superscript = false;
231+
style.Font.Strikethrough = Strikethrough.None;
231232
style.ParagraphFormat.Alignment = ParagraphAlignment.Left;
232233
style.ParagraphFormat.FirstLineIndent = 0;
233234
style.ParagraphFormat.LeftIndent = 0;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#region MigraDoc - Creating Documents on the Fly
2+
//
3+
// Authors:
4+
// Stefan Lange (mailto:Stefan.Lange@PdfSharpCore.com)
5+
// Klaus Potzesny (mailto:Klaus.Potzesny@PdfSharpCore.com)
6+
// David Stephensen (mailto:David.Stephensen@PdfSharpCore.com)
7+
//
8+
// Copyright (c) 2001-2009 empira Software GmbH, Cologne (Germany)
9+
//
10+
// http://www.PdfSharpCore.com
11+
// http://www.migradoc.com
12+
// http://sourceforge.net/projects/pdfsharp
13+
//
14+
// Permission is hereby granted, free of charge, to any person obtaining a
15+
// copy of this software and associated documentation files (the "Software"),
16+
// to deal in the Software without restriction, including without limitation
17+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18+
// and/or sell copies of the Software, and to permit persons to whom the
19+
// Software is furnished to do so, subject to the following conditions:
20+
//
21+
// The above copyright notice and this permission notice shall be included
22+
// in all copies or substantial portions of the Software.
23+
//
24+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27+
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30+
// DEALINGS IN THE SOFTWARE.
31+
#endregion
32+
33+
using System;
34+
using System.Collections.Generic;
35+
using System.Text;
36+
37+
namespace MigraDocCore.DocumentObjectModel
38+
{
39+
/// <summary>
40+
/// Specify the strike out type for font
41+
/// </summary>
42+
public enum Strikethrough
43+
{
44+
None,
45+
Single,
46+
Words,
47+
Dotted,
48+
Dash,
49+
DotDash,
50+
DotDotDash,
51+
52+
/* --- unsupported ---
53+
Double = 3,
54+
Thick = 6,
55+
Wavy = 11,
56+
WavyHeavy = 27,
57+
DottedHeavy = 20,
58+
DashHeavy = 23,
59+
DotDashHeavy = 25,
60+
DotDotDashHeavy = 26,
61+
DashLong = 39,
62+
DashLongHeavy = 55,
63+
WavyDouble = 43
64+
*/
65+
}
66+
}

MigraDocCore.Rendering/MigraDoc.Rendering.ChartMapper/FontMapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void MapObject(Font font, DocumentObjectModel.Font domFont)
6060
font.Size = domFont.Size.Point;
6161
font.Subscript = domFont.Subscript;
6262
font.Superscript = domFont.Superscript;
63+
font.Strikethrough = (Strikethrough)domFont.Strikethrough;
6364
font.Underline = (Underline)domFont.Underline;
6465
}
6566

MigraDocCore.Rendering/MigraDoc.Rendering.UnitTest/TestParagraphRenderer.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static void Formatted(string pdfOutputFile)
4848

4949
internal static void FillFormattedParagraph(Paragraph par)
5050
{
51-
for (int idx = 0; idx <= 140; ++idx)
51+
for (int idx = 0; idx <= 200; ++idx)
5252
{
5353
if (idx < 60)
5454
{
@@ -61,12 +61,42 @@ internal static void FillFormattedParagraph(Paragraph par)
6161
par.AddText((idx).ToString());
6262
par.AddText(" ");
6363
}
64-
else
64+
else if (idx < 140)
6565
{
6666
FormattedText formText = par.AddFormattedText((idx).ToString(), TextFormat.Italic);
6767
formText.Font.Size = 6;
6868
formText.AddText(" ");
6969
}
70+
// Strikethrough tests
71+
else if (idx < 150)
72+
{
73+
FormattedText formText = par.AddFormattedText((idx).ToString());
74+
formText.Font.Size = 16;
75+
formText.Font.Strikethrough = Strikethrough.Single;
76+
formText.AddText(" ");
77+
}
78+
else if (idx < 160)
79+
{
80+
FormattedText formText = par.AddFormattedText((idx).ToString());
81+
formText.Font.Size = 8;
82+
formText.Font.Strikethrough = Strikethrough.DotDash;
83+
formText.AddText(" ");
84+
}
85+
else if (idx < 170)
86+
{
87+
FormattedText formText = par.AddFormattedText((idx).ToString());
88+
formText.Font.Size = 14;
89+
formText.Font.Strikethrough = Strikethrough.DotDotDash;
90+
formText.AddText(" ");
91+
}
92+
else if (idx < 180)
93+
{
94+
FormattedText formText = par.AddFormattedText((idx).ToString());
95+
formText.Font.Size = 20;
96+
formText.Font.Strikethrough = Strikethrough.Dotted;
97+
formText.AddText(" ");
98+
}
99+
70100
if (idx % 50 == 0)
71101
par.AddLineBreak();
72102
}

MigraDocCore.Rendering/MigraDoc.Rendering/ParagraphRenderer.cs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ void RenderImage(Image image)
869869
RenderByInfos(this.currentXPosition, top, new RenderInfo[] { renderInfo });
870870

871871
RenderUnderline(contentArea.Width, true);
872+
RenderStrikethrough(contentArea.Width, true);
872873
RealizeHyperlink(contentArea.Width);
873874

874875
this.currentXPosition += contentArea.Width;
@@ -907,6 +908,7 @@ void RenderSectionPagesField(SectionPagesField sectionPagesField)
907908
void RenderBookmarkField()
908909
{
909910
RenderUnderline(0, false);
911+
RenderStrikethrough(0, false);
910912
}
911913

912914
void RenderPageRefField(PageRefField pageRefField)
@@ -946,6 +948,7 @@ void RenderSpace(Character character)
946948
void RenderLinebreak()
947949
{
948950
this.RenderUnderline(0, false);
951+
this.RenderStrikethrough(0, false);
949952
this.RealizeHyperlink(0);
950953
}
951954

@@ -963,6 +966,7 @@ void RenderTab()
963966
{
964967
TabOffset tabOffset = NextTabOffset();
965968
RenderUnderline(tabOffset.offset, false);
969+
RenderStrikethrough(tabOffset.offset, false);
966970
RenderTabLeader(tabOffset);
967971
RealizeHyperlink(tabOffset.offset);
968972
this.currentXPosition += tabOffset.offset;
@@ -1065,12 +1069,14 @@ void RenderBlank()
10651069
{
10661070
XUnit wordDistance = this.CurrentWordDistance;
10671071
RenderUnderline(wordDistance, false);
1072+
RenderStrikethrough(wordDistance, false);
10681073
RealizeHyperlink(wordDistance);
10691074
this.currentXPosition += wordDistance;
10701075
}
10711076
else
10721077
{
10731078
RenderUnderline(0, false);
1079+
RenderStrikethrough(0, false);
10741080
RealizeHyperlink(0);
10751081
}
10761082
}
@@ -1096,6 +1102,7 @@ void RenderWord(string word)
10961102
this.gfx.DrawString(word, xFont, CurrentBrush, this.currentXPosition, CurrentBaselinePosition);
10971103
XUnit wordWidth = MeasureString(word);
10981104
RenderUnderline(wordWidth, true);
1105+
RenderStrikethrough(wordWidth, true);
10991106
RealizeHyperlink(wordWidth);
11001107
this.currentXPosition += wordWidth;
11011108
}
@@ -2410,6 +2417,66 @@ bool UnderlinePenChanged(XPen pen)
24102417
return pen.Width != this.currentUnderlinePen.Width;
24112418
}
24122419

2420+
2421+
void RenderStrikethrough(XUnit width, bool isWord)
2422+
{
2423+
XPen pen = GetStrikethroughPen(isWord);
2424+
2425+
bool penChanged = StrikethroughPenChanged(pen);
2426+
if (penChanged)
2427+
{
2428+
if (this.currentStrikethroughPen != null)
2429+
EndStrikethrough(this.currentStrikethroughPen, this.currentXPosition);
2430+
2431+
if (pen != null)
2432+
StartStrikethrough(this.currentXPosition);
2433+
2434+
this.currentStrikethroughPen = pen;
2435+
}
2436+
2437+
if (this.currentLeaf.Current == this.endLeaf.Current)
2438+
{
2439+
if (this.currentStrikethroughPen != null)
2440+
EndStrikethrough(this.currentStrikethroughPen, this.currentXPosition + width);
2441+
2442+
this.currentStrikethroughPen = null;
2443+
}
2444+
}
2445+
2446+
void StartStrikethrough(XUnit xPosition)
2447+
{
2448+
this.strikethroughStartPos = xPosition;
2449+
}
2450+
2451+
void EndStrikethrough(XPen pen, XUnit xPosition)
2452+
{
2453+
XUnit yPosition = CurrentBaselinePosition;
2454+
yPosition -= pen.Width / 2;
2455+
yPosition -= this.currentVerticalInfo.descent;
2456+
2457+
this.gfx.DrawLine(pen, this.strikethroughStartPos, yPosition, xPosition, yPosition);
2458+
}
2459+
2460+
XPen currentStrikethroughPen = null;
2461+
XUnit strikethroughStartPos;
2462+
2463+
bool StrikethroughPenChanged(XPen pen)
2464+
{
2465+
if (pen == null && this.currentStrikethroughPen == null)
2466+
return false;
2467+
2468+
if (pen == null && this.currentStrikethroughPen != null)
2469+
return true;
2470+
2471+
if (pen != null && this.currentStrikethroughPen == null)
2472+
return true;
2473+
2474+
if (pen.Color != this.currentStrikethroughPen.Color)
2475+
return true;
2476+
2477+
return pen.Width != this.currentStrikethroughPen.Width;
2478+
}
2479+
24132480
RenderInfo CurrentImageRenderInfo
24142481
{
24152482
get
@@ -2474,6 +2541,47 @@ XPen GetUnderlinePen(bool isWord)
24742541
return pen;
24752542
}
24762543

2544+
XPen GetStrikethroughPen(bool isWord)
2545+
{
2546+
Font font = CurrentDomFont;
2547+
Strikethrough strikethroughType = font.Strikethrough;
2548+
if (strikethroughType == Strikethrough.None)
2549+
return null;
2550+
2551+
if (strikethroughType == Strikethrough.Words && !isWord)
2552+
return null;
2553+
2554+
#if noCMYK
2555+
XPen pen = new XPen(XColor.FromArgb(font.Color.Argb), font.Size / 16);
2556+
#else
2557+
XPen pen = new XPen(ColorHelper.ToXColor(font.Color, this.paragraph.Document.UseCmykColor), font.Size / 16);
2558+
#endif
2559+
switch (font.Strikethrough)
2560+
{
2561+
case Strikethrough.DotDash:
2562+
pen.DashStyle = XDashStyle.DashDot;
2563+
break;
2564+
2565+
case Strikethrough.DotDotDash:
2566+
pen.DashStyle = XDashStyle.DashDotDot;
2567+
break;
2568+
2569+
case Strikethrough.Dash:
2570+
pen.DashStyle = XDashStyle.Dash;
2571+
break;
2572+
2573+
case Strikethrough.Dotted:
2574+
pen.DashStyle = XDashStyle.Dot;
2575+
break;
2576+
2577+
case Strikethrough.Single:
2578+
default:
2579+
pen.DashStyle = XDashStyle.Solid;
2580+
break;
2581+
}
2582+
return pen;
2583+
}
2584+
24772585
private static XStringFormat StringFormat
24782586
{
24792587
get

PdfSharpCore.Charting/PdfSharp.Charting/Font.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,16 @@ public Underline Underline
122122
}
123123
internal Underline underline;
124124

125+
/// <summary>
126+
/// Gets or sets the strikethrough property.
127+
/// </summary>
128+
public Strikethrough Strikethrough
129+
{
130+
get { return this.strikethrough; }
131+
set { this.strikethrough = value; }
132+
}
133+
internal Strikethrough strikethrough;
134+
125135
/// <summary>
126136
/// Gets or sets the color property.
127137
/// </summary>

0 commit comments

Comments
 (0)