Hi !
I needed to shade a word inside a paragraph, so I've made some changes...
Felt like sharing
First things first, I added a Shading property to the FormattedText class (MigraDocLite\MigraDoc.DocumentObjectModel\MigraDoc.DocumentObjectModel\FormattedText.cs) :
Code:
/// <summary>
/// Gets the shading object.
/// </summary>
public Shading Shading
{
get
{
if (this.shading == null)
this.shading = new Shading(this);
return this.shading;
}
set
{
SetParent(value);
this.shading = value;
}
}
[DV]
internal Shading shading;
Then I've adapted the DeepCopy() method :
Code:
/// <summary>
/// Implements the deep copy of the object.
/// </summary>
protected override object DeepCopy()
{
FormattedText formattedText = (FormattedText)base.DeepCopy();
if (formattedText.font != null)
{
formattedText.font = formattedText.font.Clone();
formattedText.font.parent = formattedText;
}
if (formattedText.shading != null)
{
formattedText.shading = formattedText.shading.Clone();
formattedText.shading.parent = formattedText;
}
if (formattedText.elements != null)
{
formattedText.elements = formattedText.elements.Clone();
formattedText.elements.parent = formattedText;
}
return formattedText;
}
And the Serialize() one as well (I admit, I'm quite not sure of what I've done in this one
) :
Code:
/// <summary>
/// Converts FormattedText into DDL.
/// </summary>
internal override void Serialize(Serializer serializer)
{
bool isFormatted = false;
if (!this.IsNull("Font"))
{
this.Font.Serialize(serializer);
isFormatted = true;
}
else
{
if (!this.style.IsNull)
{
serializer.Write("\\font(\"" + this.Style + "\")");
isFormatted = true;
}
}
if (!this.IsNull("Shading"))
this.shading.Serialize(serializer);
if (isFormatted)
serializer.Write("{");
if (!this.IsNull("Elements"))
this.Elements.Serialize(serializer);
if (isFormatted)
serializer.Write("}");
}
Now that FormattedText supports shading.. we need to render it
Next changes are in the ParagraphRender class (MigraDocLite\MigraDoc.Rendering\MigraDoc.Rendering\ParagraphRenderer.cs) :
First, a GetShading() method based on GetHyperlink() (lazy me
) :
Code:
Shading GetShading()
{
DocumentObject parent = DocumentRelations.GetParent(this.currentLeaf.Current);
parent = DocumentRelations.GetParent(parent);
if (parent is FormattedText)
{
FormattedText text;
text = ((FormattedText)parent);
if (text.IsNull("Shading"))
return null;
else
return text.Shading;
}
else
return null;
}
Next is a new RealizeShading() method (there's already a RenderShading here...) :
Code:
void RealizeShading(XUnit width)
{
Shading shading = GetShading();
if (shading != null)
{
ShadingRenderer shadingRenderer = new ShadingRenderer(this.gfx, shading);
shadingRenderer.Render(this.currentXPosition, this.currentYPosition, width, this.currentVerticalInfo.height);
}
}
Now, we juste need to call this one everytime it's necessary...
...In RenderImage(), RenderTab(), RenderBlank(), RenderWord() and RenderLinebreak()
Code:
void RenderImage(Image image)
{
RenderInfo renderInfo = this.CurrentImageRenderInfo;
XUnit top = this.CurrentBaselinePosition;
Area contentArea = renderInfo.LayoutInfo.ContentArea;
top -= contentArea.Height;
RealizeShading(contentArea.Width);
RenderByInfos(this.currentXPosition, top, new RenderInfo[] { renderInfo });
RenderUnderline(contentArea.Width, true);
RealizeHyperlink(contentArea.Width);
this.currentXPosition += contentArea.Width;
}
Code:
void RenderTab()
{
TabOffset tabOffset = NextTabOffset();
RealizeShading(tabOffset.offset);
RenderUnderline(tabOffset.offset, false);
RenderTabLeader(tabOffset);
RealizeHyperlink(tabOffset.offset);
this.currentXPosition += tabOffset.offset;
}
Code:
void RenderBlank()
{
if (!IgnoreBlank())
{
XUnit wordDistance = this.CurrentWordDistance;
RealizeShading(wordDistance);
RenderUnderline(wordDistance, false);
RealizeHyperlink(wordDistance);
this.currentXPosition += wordDistance;
}
else
{
// RealizeShading(0); Useless !
RenderUnderline(0, false);
RealizeHyperlink(0);
}
}
Code:
void RenderWord(string word)
{
Font font = this.CurrentDomFont;
XFont xFont = CurrentFont;
if (font.Subscript || font.Superscript)
xFont = FontHandler.ToSubSuperFont(xFont);
XUnit wordWidth = MeasureString(word);
RealizeShading(wordWidth);
this.gfx.DrawString(word, xFont, CurrentBrush, this.currentXPosition, this.CurrentBaselinePosition);
RenderUnderline(wordWidth, true);
RealizeHyperlink(wordWidth);
this.currentXPosition += wordWidth;
}
Code:
void RenderLinebreak()
{
//this.RealizeShading(0); useless !
this.RenderUnderline(0, false);
this.RealizeHyperlink(0);
}
Some calls are in comments 'cuz there're kind of useless when with the width is null
I've not tested all the cases, but it's seems to be working
Have a nice day !