public static void DrawFormattedText(Graphics zGraphics, Deck zDeck, ProjectLayoutElement zElement, string sInput, Brush zBrush, Font zFont, Color colorFont)
{
// check the cache for this item
var zDataFormattedCache = zDeck.GetCachedMarkup(zElement.name);
if (null == zDataFormattedCache)
{
if (null == zFont) // default to something!
{
// font will show up in red if it's not yet set
zFont = s_zDefaultFont;
zBrush = Brushes.Red;
}
if (255 != zElement.opacity)
{
zBrush = new SolidBrush(Color.FromArgb(zElement.opacity, colorFont));
}
zDataFormattedCache = new FormattedTextDataCache();
var zFormattedData = new FormattedTextData(GetMarkups(sInput));
var zProcessData = new FormattedTextProcessData();
// set the initial font
zProcessData.FontBrush = zBrush;
zProcessData.SetFont(zFont, zGraphics);
var listPassMarkups = new List<MarkupBase>(); // only contains the markups that will be actively drawn (for caching)
// Pass 1:
// - Create rectangles
// - Configure per-markup settings based on state of markup stack
// - Generate list of markups to continue to process (those that are used in the next pass)
// - Specify Markup rectanlges
// - Generate markup rows
int nIdx;
MarkupBase zMarkup;
for (nIdx = 0; nIdx < zFormattedData.AllMarkups.Count; nIdx++)
{
zMarkup = zFormattedData.AllMarkups[nIdx];
if (zMarkup.ProcessMarkup(zElement, zFormattedData, zProcessData, zGraphics))
{
zMarkup.LineNumber = zProcessData.CurrentLine;
listPassMarkups.Add(zMarkup);
}
}
// Pass 2:
// - Trim spaces from line endings
if (listPassMarkups.Count > 0)
{
nIdx = listPassMarkups.Count - 1;
zMarkup = listPassMarkups[nIdx];
var currentLineNumber = zMarkup.LineNumber;
var bFindNextLine = false;
while (nIdx > -1)
{
zMarkup = listPassMarkups[nIdx];
if (zMarkup.LineNumber != currentLineNumber)
{
currentLineNumber = zMarkup.LineNumber;
bFindNextLine = false;
}
if (!bFindNextLine && zMarkup is SpaceMarkup && ((SpaceMarkup) zMarkup).Optional)
{
listPassMarkups.RemoveAt(nIdx);
}
else
{
bFindNextLine = true;
}
nIdx--;
}
}
// Pass 3:
// - Align lines (horizontal/vertical)
// Reprocess for align (before backgroundcolor is configured)
UpdateAlignment(zElement, listPassMarkups);
// Pass 4: process the remaining items
nIdx = 0;
while (nIdx < listPassMarkups.Count)
{
zMarkup = listPassMarkups[nIdx];
if (!zMarkup.PostProcessMarkupRectangle(zElement, listPassMarkups, nIdx))
{
listPassMarkups.RemoveAt(nIdx);
nIdx--;
}
else
{
zDataFormattedCache.AddMarkup(zMarkup);
}
nIdx++;
}
// update the cache
zDeck.AddCachedMarkup(zElement.name, zDataFormattedCache);
}
zDataFormattedCache.Render(zElement, zGraphics);
}