public BackgroundColorMarkup(string sVariable) { m_zBrush = new SolidBrush(ProjectLayoutElement.TranslateColorString(sVariable)); }
/// <summary> /// Gets a new brush based on the passed in element and color. /// </summary> /// <param name="zElement"></param> /// <param name="color"></param> /// <returns></returns> public static Brush GetElementOpacityBrush(ProjectLayoutElement zElement, Color color) { return(new SolidBrush(GetElementOpacityColor(zElement, color))); }
/// <summary> /// Gets the color based on the element opacity /// </summary> /// <param name="zElement"></param> /// <param name="color"></param> /// <returns></returns> public static Color GetElementOpacityColor(ProjectLayoutElement zElement, Color color) { return(255 != zElement.opacity ? Color.FromArgb(zElement.opacity, color) : color); }
protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { m_ePreviousStringAlignment = zProcessData.CurrentStringAlignment; zProcessData.CurrentStringAlignment = MarkupAlignment; return(false); }
public override void UpdateLineAlignment(int nFirst, int nLast, bool bLastLine, ProjectLayoutElement zElement, List <MarkupBase> listMarkups, float fVerticalOffset, IEnumerable <MarkupBase> listAllMarkups) { // detect if this is the last line of markups - if so don't bother with jusity alignment if (bLastLine) { base.UpdateLineAlignment(nFirst, nLast, bLastLine, zElement, listMarkups, fVerticalOffset, listAllMarkups); return; } // detect if this line is followed by a line break - if so don't bother with justify alignment on this line var lastLineMarkup = listMarkups[nLast]; var theBigList = listAllMarkups.ToList(); var lastLineMarkupIndex = theBigList.IndexOf(lastLineMarkup); for (var nIdx = lastLineMarkupIndex + 1; nIdx < theBigList.Count; nIdx++) { if (theBigList[nIdx] is NewlineMarkup) { // no justified alignment due to this line ending with an explicit line break base.UpdateLineAlignment(nFirst, nLast, bLastLine, zElement, listMarkups, fVerticalOffset, listAllMarkups); return; } if (theBigList[nIdx].Aligns) { // the next rendered thing aligns so treat this line as though it is part of a paragraph break; } // default to justify alignment } // TODO: the space markups are completely ignored by justified (who cares?) var listTextMarkups = listMarkups.GetRange(nFirst, (nLast - nFirst) + 1).Where(zMarkup => !(zMarkup is SpaceMarkup)).ToList(); var fTotalTextWidth = listTextMarkups.Sum(zMarkup => zMarkup.TargetRect.Width); var fDifference = (float)zElement.width - fTotalTextWidth; var fXOffset = fDifference / ((float)listTextMarkups.Count - 1); //Logger.AddLogLine("TotalTextWidth: {0} Difference: {1} SpaceSize: {2} listTextMarkups: {3}".FormatString(fTotalTextWidth, fDifference, fXOffset, listTextMarkups.Count)); var fCurrentPosition = listMarkups[nFirst].TargetRect.X; for (var nIdx = nFirst; nIdx <= nLast; nIdx++) { if (listMarkups[nIdx].Aligns && !(listMarkups[nIdx] is SpaceMarkup)) { var rectCurrent = listMarkups[nIdx].TargetRect; listMarkups[nIdx].TargetRect = new RectangleF(fCurrentPosition, rectCurrent.Y + fVerticalOffset, rectCurrent.Width, rectCurrent.Height); fCurrentPosition += listMarkups[nIdx].TargetRect.Width + fXOffset; } } }
public static void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string sInput, Brush zBrush, Font zFont, Color colorFont) { if (null == zFont) // default to something! { // font will show up in red if it's not yet set zFont = s_zDefaultFont; zBrush = Brushes.Red; } var zFormat = new StringFormat { LineAlignment = (StringAlignment)zElement.verticalalign, Alignment = (StringAlignment)zElement.horizontalalign }; if (255 != zElement.opacity) { zBrush = new SolidBrush(Color.FromArgb(zElement.opacity, colorFont)); } if (zElement.autoscalefont) { SizeF zSize = zGraphics.MeasureString(sInput, zFont, new SizeF(zElement.width, int.MaxValue), zFormat); if (zSize.Height > zElement.height || zSize.Width > zElement.width) { float newSizeRatio; if ((zSize.Height - zElement.height) > (zSize.Width - zElement.width)) { newSizeRatio = (float)zElement.height / (float)zSize.Height; } else { newSizeRatio = (float)zElement.width / (float)zSize.Width; } var scaledFont = new Font(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style); //Support.IO.Logger.AddLogLine(scaledFont.Size + " was [" + zFont.Size + "]"); zFont = scaledFont; #if true // the preprocessing above will get the font size close but not perfect, the slow code below further refines the size // slow mode - but perfect precision (well arguably with the Graphics.MeasureString) bool bUpscaled = false; if (0 < sInput.Trim().Length) { while (true) { zSize = zGraphics.MeasureString(sInput, zFont, new SizeF(zElement.width, int.MaxValue), zFormat); if (zSize.Height > zElement.height || zSize.Width > zElement.width) { if (zFont.Size == 1) { break; } zFont = new Font(zFont.FontFamily, zFont.Size - 1, zFont.Style); if (bUpscaled) { break; } } else { zFont = new Font(zFont.FontFamily, zFont.Size + 1, zFont.Style); bUpscaled = true; } } //Support.IO.Logger.AddLogLine("[" + zFont.Size + "]"); } #endif } // else -- font size is fine for this element } else { zFormat.Trimming = StringTrimming.EllipsisCharacter; } var arrayDrawLines = new string[] { sInput }; var nLineOffset = 0; // hackery -- would be nice if this was not used... (if words could be measured) var bAutoNewline = true; // configure line height (if specified) #if false if (!zElement.autoscalefont && 0 < zElement.lineheight && -1 != sInput.IndexOf(Environment.NewLine)) { bAutoNewline = false; arrayDrawLines = sInput.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); // if bottom aligned start the line offset however many y pixels up if (StringAlignment.Far == zFormat.LineAlignment) { nLineOffset = -(zElement.lineheight * (arrayDrawLines.Length - 1)); } } #endif var fEmSize = zFont.Size; switch (zFont.Unit) { case GraphicsUnit.Point: fEmSize = zGraphics.DpiY * (zFont.Size / 72f); break; default: Logger.AddLogLine("This font is using the Unit: {0} (not currently supported)".FormatString(zFont.Unit.ToString())); break; } foreach (var sLine in arrayDrawLines) { if (0 == zElement.outlinethickness) { try { zGraphics.DrawString(sLine, zFont, zBrush, new RectangleF(0, nLineOffset, bAutoNewline ? zElement.width : zElement.width * 100, zElement.height), zFormat); } catch (Exception) { Logger.AddLogLine("Unable to render text (font issue?)"); } } else { // prepare to draw text var zPath = new GraphicsPath(); try { zPath.AddString(sLine, zFont.FontFamily, (int)zFont.Style, fEmSize, new RectangleF(0, nLineOffset, bAutoNewline ? zElement.width : zElement.width * 100, zElement.height), zFormat); DrawOutline(zElement, zGraphics, zPath); } catch (Exception) { Logger.AddLogLine("Unable to render text (font issue?)"); } // fill in the outline zGraphics.FillPath(zBrush, zPath); } nLineOffset += zElement.lineheight; } }
private string GenerateListViewItemElementText(ProjectLayoutElement zElement) { return(zElement.name + (null != zElement.layoutreference && null != zElement.elementreference ? "*" : "")); }
/// <summary> /// Updates the position of the markups based on horizontal alignment /// </summary> /// <param name="nFirst">First index of the listMarkups in the line (start of line)</param> /// <param name="nLast">Last index of the listMarkups in the line (end of line) -- inclusive</param> /// <param name="bLastLine">Indicates this is the last line (specific to justified)</param> /// <param name="zElement">The element being rendered</param> /// <param name="listMarkups">List of Markups (all must have Aligns set to true)</param> /// <param name="fVerticalOffset">Any vertical offset to apply</param> /// <param name="listAllMarkups">List of all markups (even those with Aligns set to false) (specific to justified)</param> public virtual void UpdateLineAlignment(int nFirst, int nLast, bool bLastLine, ProjectLayoutElement zElement, List <MarkupBase> listMarkups, float fVerticalOffset, IEnumerable <MarkupBase> listAllMarkups) { var fHorizontalOffset = GetHorizontalOffset(zElement, listMarkups[nFirst].TargetRect, listMarkups[nLast].TargetRect); for (var nIdx = nFirst; nIdx <= nLast; nIdx++) { var rectCurrent = listMarkups[nIdx].TargetRect; listMarkups[nIdx].TargetRect = new RectangleF(rectCurrent.X + fHorizontalOffset, rectCurrent.Y + fVerticalOffset, rectCurrent.Width, rectCurrent.Height); } }
public virtual float GetHorizontalOffset(ProjectLayoutElement zElement, RectangleF rectFirst, RectangleF rectLast) { return(0f); }
public void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string sInput) { var zFont = zElement.GetElementFont(); var colorFont = zElement.GetElementColor(); if (null == zFont) // default to something! { // font will show up in red if it's not yet set zFont = FontLoader.DefaultFont; } var zBrush = 255 == zElement.opacity ? new SolidBrush(colorFont) : new SolidBrush(Color.FromArgb(zElement.opacity, colorFont)); TextFormatFlags zFormatFlags = TextFormatFlags.WordBreak | TextFormatFlags.NoClipping; switch (zElement.GetVerticalAlignment()) { case StringAlignment.Center: zFormatFlags |= TextFormatFlags.VerticalCenter; break; case StringAlignment.Far: zFormatFlags |= TextFormatFlags.Bottom; break; } switch (zElement.GetHorizontalAlignment()) { case StringAlignment.Center: zFormatFlags |= TextFormatFlags.HorizontalCenter; break; case StringAlignment.Far: zFormatFlags |= TextFormatFlags.Right; break; } #warning TextRenderer apparently does not support opactiy?! Bitmap zOpacityBitmap = null; if (255 != zElement.opacity) { zOpacityBitmap = new Bitmap(zElement.width, zElement.height, PixelFormat.Format32bppArgb); zOpacityBitmap.SetResolution(zGraphics.DpiY, zGraphics.DpiY); } if (zElement.autoscalefont) { var zSize = TextRenderer.MeasureText(sInput, zFont, new Size(zElement.width, int.MaxValue), zFormatFlags); if (zSize.Height > zElement.height || zSize.Width > zElement.width) { float newSizeRatio; if ((zSize.Height - zElement.height) > (zSize.Width - zElement.width)) { newSizeRatio = (float)zElement.height / (float)zSize.Height; } else { newSizeRatio = (float)zElement.width / (float)zSize.Width; } //var scaledFont = new Font(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style); var scaledFont = new Font(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style); //Logger.AddLogLine(scaledFont.Size + " was [" + zFont.Size + "]"); zFont = scaledFont; #if true // the preprocessing above will get the font size close but not perfect, the slow code below further refines the size // slow mode - but perfect precision (well arguably with the Graphics.MeasureString) bool bUpscaled = false; const float FONT_SCALE_ADJUST = 0.25f; if (0 < sInput.Trim().Length) { while (true) { zSize = TextRenderer.MeasureText(sInput, zFont, new Size(zElement.width, int.MaxValue), zFormatFlags); if (zSize.Height > zElement.height || zSize.Width > zElement.width) { if (zFont.Size <= 1) { break; } zFont = new Font(zFont.FontFamily, zFont.Size - FONT_SCALE_ADJUST, zFont.Style); //Logger.AddLogLine("ADJ A [" + zFont.Size + "]"); if (bUpscaled) { break; } } else { zFont = new Font(zFont.FontFamily, zFont.Size + FONT_SCALE_ADJUST, zFont.Style); //Logger.AddLogLine("ADJ B [" + zFont.Size + "]"); bUpscaled = true; } } } #endif } // else -- font size is fine for this element } else { zFormatFlags |= TextFormatFlags.EndEllipsis; } Logger.AddLogLine("[" + zFont.Size + "]"); var arrayDrawLines = new string[] { sInput }; var nLineOffset = 0; var fEmSize = zFont.Size; switch (zFont.Unit) { case GraphicsUnit.Point: fEmSize = zGraphics.DpiY * (zFont.Size / 72f); break; default: Logger.AddLogLine("This font is using the Unit: {0} (not currently supported)".FormatString(zFont.Unit.ToString())); break; } foreach (var sLine in arrayDrawLines) { if (0 == zElement.outlinethickness) { try { // https://stackoverflow.com/questions/849531/textrenderer-drawtext-in-bitmap-vs-onpaintbackground/1578056#1578056 if (null != zOpacityBitmap) { zFont = new Font("SkyScrappers Regular", zFont.Size); // TODO: https://stackoverflow.com/questions/18838037/drawing-text-to-a-bitmap-with-textrenderer #if false // too bad this makes the font look terrible var image = new Bitmap(zElement.width, zElement.height, PixelFormat.Format32bppArgb); // create memory buffer from desktop handle that supports alpha channel IntPtr dib; var memoryHdc = CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib); try { // create memory buffer graphics to use for HTML rendering using (var memoryGraphics = Graphics.FromHdc(memoryHdc)) { // must not be transparent background memoryGraphics.Clear(Color.White); TextRenderer.DrawText(memoryGraphics, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags); } // copy from memory buffer to image using (var imageGraphics = Graphics.FromImage(image)) { var imgHdc = imageGraphics.GetHdc(); BitBlt(imgHdc, 0, 0, image.Width, image.Height, memoryHdc, 0, 0, 0x00CC0020); imageGraphics.ReleaseHdc(imgHdc); } } finally { // release memory buffer DeleteObject(dib); DeleteDC(memoryHdc); } zGraphics.DrawImageUnscaled(image, 0, 0); #else #if false using (Bitmap buffer = new Bitmap(zElement.width, zElement.height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { using (Graphics graphics = Graphics.FromImage(buffer)) { graphics.FillRectangle(Brushes.Transparent, 0, 0, zElement.width, zElement.height); // Produces the result below //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // Produces clean text, but I'd really like ClearType! graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; TextRenderer.DrawText(graphics, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags); } zGraphics.DrawImageUnscaled(buffer, 0, 0); } #else var zGraphicsTemp = Graphics.FromImage(zOpacityBitmap); zGraphicsTemp.SmoothingMode = SmoothingMode.AntiAlias; zGraphicsTemp.TextRenderingHint = TextRenderingHint.AntiAlias; TextRenderer.DrawText(zGraphicsTemp, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags); var zColor = new ColorMatrix { Matrix33 = (float)zElement.opacity / 255.0f }; var zAttrib = new ImageAttributes(); zAttrib.SetColorMatrix(zColor); var zBitmap = new Bitmap(zOpacityBitmap.Width, zOpacityBitmap.Height); // target image var zGraphicsX = Graphics.FromImage(zBitmap); // draw the source image into the destination with the desired opacity zGraphicsX.DrawImage(zOpacityBitmap, new Rectangle(0, 0, zBitmap.Width, zBitmap.Height), 0, 0, zBitmap.Width, zBitmap.Height, GraphicsUnit.Pixel, zAttrib); /** * * var zImageAttributes = new ImageAttributes(); * if (255 != zElement.opacity) * { * var zColor = new ColorMatrix * { * Matrix33 = (float)zElement.opacity / 255.0f * }; * zImageAttributes.SetColorMatrix(zColor); * } * * zDestinationBitmap = new Bitmap(nTargetWidth, nTargetHeight); // target image * var zGraphics = Graphics.FromImage(zDestinationBitmap); * // draw the source image into the destination with the desired opacity * zGraphics.DrawImage(zSourceBitmap, new Rectangle(0, 0, nTargetWidth, nTargetHeight), 0, 0, zSourceBitmap.Width, zSourceBitmap.Height, GraphicsUnit.Pixel, * zImageAttributes); * */ zGraphics.DrawImageUnscaled(zBitmap, 0, 0); #endif #endif } else { TextRenderer.DrawText(zGraphics, sLine, zFont, new Rectangle((int)zGraphics.Transform.OffsetX, (int)zGraphics.Transform.OffsetY, zElement.width, zElement.height), colorFont, zFormatFlags); } } catch (Exception) { Logger.AddLogLine("Unable to render text (font issue?)"); } } else { // prepare to draw text var zPath = new GraphicsPath(); try { #warning is there a path based text renderer thing to use? var zFormat = new StringFormat { LineAlignment = zElement.GetVerticalAlignment(), Alignment = zElement.GetHorizontalAlignment(), Trimming = StringTrimming.None, FormatFlags = StringFormatFlags.NoClip }; zPath.AddString(sLine, zFont.FontFamily, (int)zFont.Style, fEmSize, new RectangleF(0, nLineOffset, zElement.width, zElement.height), zFormat); //CardRenderer.DrawElementPath(zElement, zGraphics, zPath); } catch (Exception) { Logger.AddLogLine("Unable to render text (font issue?)"); } // fill in the outline zGraphics.FillPath(zBrush, zPath); } nLineOffset += zElement.lineheight; } }
protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { m_colorPrevious = zProcessData.ImageColor; zProcessData.ImageColor = ProjectLayoutElement.TranslateColorString(m_sVariable, zElement.opacity); return(false); }
public override bool ProcessMarkup(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { m_zPreviousBrush = zProcessData.FontBrush; zProcessData.FontBrush = new SolidBrush(ProjectLayoutElement.TranslateColorString(m_sVariable, zElement.opacity)); return(false); }
public override float GetVerticalAlignOffset(ProjectLayoutElement zElement, List <MarkupBase> listMarkups) { return(0f); }
public override bool ProcessMarkup(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { return(true); }
public void Setup() { _testDeck = new TestDeck(); _testLine = new DeckLine(new List <string>()); _testElement = new ProjectLayoutElement("testElement"); }
public override bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, List <MarkupBase> listAllMarkups, int nMarkup) { // remove once hit during text size processing (this would always be after something used the information for the close tag) return(false); }
public void MoveToNextLine(ProjectLayoutElement zElement) { CurrentLine++; CurrentX = 0; CurrentY += zElement.lineheight; }
public override float GetHorizontalOffset(ProjectLayoutElement zElement, RectangleF rectFirst, RectangleF rectLast) { var fXOffset = -rectFirst.X + 1; return(fXOffset); }
public override bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, List <MarkupBase> listAllMarkups, int nMarkup) { return(true); }
protected abstract ElementString TranslateToElementString(Deck zDeck, string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement);
private void UpdateListViewItemText(ListViewItem zLvi, ProjectLayoutElement zElement) { //zLvi.BackColor = zElement.enabled ? Color.White : Color.Tomato; zLvi.SubItems[0].Text = zElement.enabled.ToString(); }
public ElementString TranslateString(Deck zDeck, string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement, string sCacheSuffix = "") { var sCacheKey = zElement.name + sCacheSuffix; // pull from translated string cache ElementString zCached; if (m_dictionaryElementStringCache.TryGetValue(sCacheKey, out zCached)) { return(zCached); } var zElementString = TranslateToElementString(zDeck, sRawString, nCardIndex, zDeckLine, zElement); if (zElementString.String.Contains("#nodraw")) { zElementString.DrawElement = false; } // all translators perform this post replacement operation switch ((ElementType)Enum.Parse(typeof(ElementType), zElement.type)) { case ElementType.Text: zElementString.String = zElementString.String.Replace("\\n", Environment.NewLine); zElementString.String = zElementString.String.Replace("\\q", "\""); zElementString.String = zElementString.String.Replace("\\c", ","); zElementString.String = zElementString.String.Replace(">", ">"); zElementString.String = zElementString.String.Replace("<", "<"); break; case ElementType.FormattedText: // NOTE: never convert \n => <br> here. This will affect file paths that include '\n' (ie. c:\newfile.png) zElementString.String = zElementString.String.Replace("<c>", ","); zElementString.String = zElementString.String.Replace("<q>", "\""); zElementString.String = zElementString.String.Replace(">", ">"); zElementString.String = zElementString.String.Replace("<", "<"); break; } AddStringToTranslationCache(sCacheKey, zElementString); return(zElementString); }
public void DrawGraphicFile(Graphics zGraphics, string sFile, ProjectLayoutElement zElement, int nXGraphicOffset = 0, int nYGraphicOffset = 0) { var sPath = sFile; if (string.IsNullOrEmpty(sFile) || sPath.Equals("none", StringComparison.CurrentCultureIgnoreCase)) { return; } if (sPath.StartsWith(APPLICATION_FOLDER_MARKER)) { sPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), sPath.Replace(APPLICATION_FOLDER_MARKER, string.Empty)); } if (!File.Exists(sPath)) { sPath = ProjectManager.Instance.ProjectPath + sFile; } if (!File.Exists(sPath)) { IssueManager.Instance.FireAddIssueEvent("Image file not found: " + sFile); return; } var zBmp = 255 != zElement.opacity ? ImageCache.LoadCustomImageFromCache(sPath, zElement) : ImageCache.LoadImageFromCache(sPath); var nWidth = zElement.width; var nHeight = zElement.height; // TODO: sub processor methods (at a minimum) if (!string.IsNullOrWhiteSpace(zElement.tilesize) && zElement.tilesize.Trim() != "-") { var zMatch = regexImageTile.Match(zElement.tilesize); if (zMatch.Success) { var nTileWidth = Math.Max(-1, ParseUtil.ParseDefault(zMatch.Groups[1].Value, -1)); var nTileHeight = Math.Max(-1, ParseUtil.ParseDefault(zMatch.Groups[3].Value, -1)); GetAspectRatioHeight(zBmp, nTileWidth, nTileHeight, out nTileWidth, out nTileHeight); // paranoia... nTileWidth = Math.Max(1, nTileWidth); nTileHeight = Math.Max(1, nTileHeight); zBmp = ImageCache.LoadCustomImageFromCache(sFile, zElement, nTileWidth, nTileHeight); } using (var zTextureBrush = new TextureBrush(zBmp, WrapMode.Tile)) { // backup the transform var zOriginalTransform = zGraphics.Transform; // need to translate so the tiling starts with a full image if offset zGraphics.TranslateTransform(nXGraphicOffset, nYGraphicOffset); zGraphics.FillRectangle(zTextureBrush, 0, 0, nWidth, nHeight); zGraphics.Transform = zOriginalTransform; } return; } if (zElement.keeporiginalsize) { DrawGraphicOriginalSize(zGraphics, zBmp, zElement); return; } if (zElement.lockaspect) { GetSizeFromAspectRatio((float)zBmp.Tag, nWidth, nHeight, out nWidth, out nHeight); } var nX = 0; var nY = 0; // standard alignment adjustment UpdateAlignmentValue(zElement.GetHorizontalAlignment(), ref nX, zElement.width, nWidth); UpdateAlignmentValue(zElement.GetVerticalAlignment(), ref nY, zElement.height, nHeight); zGraphics.DrawImage(zBmp, nX + nXGraphicOffset, nY + nYGraphicOffset, nWidth, nHeight); }
/// <summary> /// Translates the string representing the element. (also handles any nodraw text input) /// </summary> /// <param name="sRawString"></param> /// <param name="nCardIndex"></param> /// <param name="zDeckLine"></param> /// <param name="zElement"></param> /// <returns></returns> protected override ElementString TranslateToElementString(string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement) { List <string> listLine = zDeckLine.LineColumns; string sOutput = sRawString; sOutput = sOutput.Replace("#empty", string.Empty); var zElementString = new ElementString(); // Translate card variables (non-reference information // Groups // 1 2 3 4 5 // @"(.*)(!\[)(.+?)(\])(.*)" Match zMatch; while (s_regexCardVariable.IsMatch(sOutput)) { zMatch = s_regexCardVariable.Match(sOutput); string sDefineValue; var sKey = zMatch.Groups[3].ToString().ToLower(); // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup if (sKey.Equals("cardindex")) { sDefineValue = (nCardIndex + 1).ToString(); } else if (sKey.Equals("deckindex")) { sDefineValue = (zDeckLine.RowSubIndex + 1).ToString(); } else { IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey); sDefineValue = "[BAD NAME: " + sKey + "]"; } sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]; } // Translate named items (column names / defines) //Groups // 1 2 3 4 5 //@"(.*)(@\[)(.+?)(\])(.*)" while (s_regexColumnVariable.IsMatch(sOutput)) { zMatch = s_regexColumnVariable.Match(sOutput); int nIndex; string sDefineValue; var sKey = zMatch.Groups[3].ToString().ToLower(); // check the key for untranslated components var arrayParams = sKey.Split(new char[] { ',' }); if (arrayParams.Length > 1) { sKey = arrayParams[0]; } if (DictionaryDefines.TryGetValue(sKey, out sDefineValue)) { } else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex)) { sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim()); } else { IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey); sDefineValue = "[BAD NAME: " + sKey + "]"; } if (arrayParams.Length > 1) { for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++) { sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]); } } sOutput = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]; } // Translate card counter/index // Groups // 1 2 3 4 5 6 7 8 9 //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)"); while (s_regexCardCounter.IsMatch(sOutput)) { zMatch = s_regexCardCounter.Match(sOutput); var nStart = Int32.Parse(zMatch.Groups[3].ToString()); var nChange = Int32.Parse(zMatch.Groups[5].ToString()); var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString()); sOutput = zMatch.Groups[1] + // nIndex is left as is (not adding 1) (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') + zMatch.Groups[9]; } // Translate sub card counter/index // Groups // 1 2 3 4 5 6 7 8 9 //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)"); while (s_regexSubCardCounter.IsMatch(sOutput)) { zMatch = s_regexSubCardCounter.Match(sOutput); var nStart = Int32.Parse(zMatch.Groups[3].ToString()); var nChange = Int32.Parse(zMatch.Groups[5].ToString()); var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString()); var nIndex = zDeckLine.RowSubIndex; sOutput = zMatch.Groups[1] + // nIndex is left as is (not adding 1) (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') + zMatch.Groups[9]; } // Translate If Logic //Groups // 1 2 3 4 5 //@"(.*)(#\()(if.+)(\)#)(.*)"); while (s_regexIfLogic.IsMatch(sOutput)) { zMatch = s_regexIfLogic.Match(sOutput); string sLogicResult = TranslateIfLogic(zMatch.Groups[3].ToString()); sOutput = zMatch.Groups[1] + sLogicResult + zMatch.Groups[5]; } // Translate Switch Logic //Groups // 1 2 3 4 5 //@"(.*)(#\()(switch.+)(\)#)(.*)"); while (s_regexSwitchLogic.IsMatch(sOutput)) { zMatch = s_regexSwitchLogic.Match(sOutput); string sLogicResult = TranslateSwitchLogic(zMatch.Groups[3].ToString()); sOutput = zMatch.Groups[1] + sLogicResult + zMatch.Groups[5]; } zElementString.String = sOutput; return(zElementString); }
/// <summary> /// Translates the string representing the element. (also handles any nodraw text input) /// </summary> /// <param name="zDeck"></param> /// <param name="sRawString"></param> /// <param name="nCardIndex"></param> /// <param name="zDeckLine"></param> /// <param name="zElement"></param> /// <returns></returns> protected override ElementString TranslateToElementString(Deck zDeck, string sRawString, int nCardIndex, DeckLine zDeckLine, ProjectLayoutElement zElement) { #warning Investigate using method references instead of anonymous methods (optimization/code easier to read) var listLine = zDeckLine.LineColumns; var sOutput = sRawString; sOutput = sOutput.Replace("#empty", string.Empty); var zElementString = new ElementString(); // TODO: maybe move these into classes so this isn't one mammoth blob LogTranslation(zElement, sOutput); // Translate card variables (non-reference information // Groups // 1 2 3 4 5 // @"(.*)(!\[)(.+?)(\])(.*)" Func <Match, string> funcCardVariableProcessor = (zMatch => { string sDefineValue; var sKey = zMatch.Groups[3].ToString().ToLower(); // NOTE: if this expands into more variables move all this into some other method and use a dictionary lookup if (sKey.Equals("cardindex")) { sDefineValue = (nCardIndex + 1).ToString(); } else if (sKey.Equals("deckindex")) { sDefineValue = (zDeckLine.RowSubIndex + 1).ToString(); } else if (sKey.Equals("cardcount")) { sDefineValue = zDeck.CardCount.ToString(); } else if (sKey.Equals("elementname")) { sDefineValue = zElement.name; } else { IssueManager.Instance.FireAddIssueEvent("Bad card variable: " + sKey); sDefineValue = "[BAD NAME: " + sKey + "]"; } return(zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]); }); // Translate named items (column names / defines) //Groups // 1 2 3 4 5 //@"(.*)(@\[)(.+?)(\])(.*)" Func <Match, string> funcDefineProcessor = zMatch => { int nIndex; string sDefineValue; var sKey = zMatch.Groups[3].ToString(); // check the key for define parameters var arrayParams = sKey.Split(new char[] { ',' }); if (arrayParams.Length > 1) { sKey = arrayParams[0]; } sKey = sKey.ToLower(); if (DictionaryDefines.TryGetValue(sKey, out sDefineValue)) { } else if (DictionaryColumnNameToIndex.TryGetValue(sKey, out nIndex)) { sDefineValue = (nIndex >= listLine.Count ? string.Empty : (listLine[nIndex] ?? "").Trim()); } else { IssueManager.Instance.FireAddIssueEvent("Bad reference name: " + sKey); sDefineValue = "[BAD NAME: " + sKey + "]"; } if (arrayParams.Length > 1) { for (int nIdx = 1; nIdx < arrayParams.Length; nIdx++) { sDefineValue = sDefineValue.Replace("{" + nIdx + "}", arrayParams[nIdx]); } } var result = zMatch.Groups[1] + sDefineValue + zMatch.Groups[5]; // perform the #empty replace every time a define is unwrapped return(result.Replace("#empty", string.Empty)); }; // Translate substrings (column names / defines) //Groups // 1 2 3 4 5 6 7 8 9 //@"(.*)(%\[)(.+?)(,)(\d+)(,)(\d+)(\])(.*) Func <Match, string> funcDefineSubstringProcessor = zMatch => { var sValue = zMatch.Groups[3].ToString(); int nStartIdx; int nLength; if (!int.TryParse(zMatch.Groups[5].ToString(), out nStartIdx) || !int.TryParse(zMatch.Groups[7].ToString(), out nLength)) { sValue = "[Invalid substring parameters]"; } else { sValue = sValue.Length >= nStartIdx + nLength ? sValue.Substring(nStartIdx, nLength) : string.Empty; } var result = zMatch.Groups[1] + sValue + zMatch.Groups[9]; // perform the #empty replace every time a define is unwrapped return(result.Replace("#empty", string.Empty)); }; // define and define substring processing sOutput = LoopTranslationMatchMap(sOutput, zElement, new Dictionary <Regex, Func <Match, string> > { { s_regexColumnVariable, funcDefineProcessor }, { s_regexColumnVariableSubstring, funcDefineSubstringProcessor }, { s_regexCardVariable, funcCardVariableProcessor } }); // Translate card counter/index // Groups // 1 2 3 4 5 6 7 8 9 //(@"(.*)(##)(\d+)(;)(\d+)(;)(\d+)(#)(.*)"); sOutput = LoopTranslateRegex(s_regexCardCounter, sOutput, zElement, (zMatch => { var nStart = Int32.Parse(zMatch.Groups[3].ToString()); var nChange = Int32.Parse(zMatch.Groups[5].ToString()); var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString()); return(zMatch.Groups[1] + // nIndex is left as is (not adding 1) (nStart + (nCardIndex * nChange)).ToString(CultureInfo.InvariantCulture) .PadLeft(nLeftPad, '0') + zMatch.Groups[9]); })); // Translate sub card counter/index // Groups // 1 2 3 4 5 6 7 8 9 //(@"(.*)(#sc;)(\d+)(;)(\d+)(;)(\d+)(#)(.*)"); sOutput = LoopTranslateRegex(s_regexSubCardCounter, sOutput, zElement, (zMatch => { var nStart = Int32.Parse(zMatch.Groups[3].ToString()); var nChange = Int32.Parse(zMatch.Groups[5].ToString()); var nLeftPad = Int32.Parse(zMatch.Groups[7].ToString()); var nIndex = zDeckLine.RowSubIndex; return(zMatch.Groups[1] + // nIndex is left as is (not adding 1) (nStart + (nIndex * nChange)).ToString(CultureInfo.InvariantCulture).PadLeft(nLeftPad, '0') + zMatch.Groups[9]); })); // Translate random number // Groups // 1 2 3 4 5 6 7 //@"(.*)(#random;)(-?\d+)(;)(-?\d+)(#)(.*)" sOutput = LoopTranslateRegex(s_regexRandomNumber, sOutput, zElement, (zMatch => { int nMin; int nMax; if (!int.TryParse(zMatch.Groups[3].ToString(), out nMin) || !int.TryParse(zMatch.Groups[5].ToString(), out nMax)) { return("Failed to parse random min/max"); } if (nMin >= nMax) { return("Invalid random specified. Min >= Max"); } // max is not inclusive return(zMatch.Groups[1] + CardMakerInstance.Random.Next(nMin, nMax + 1).ToString() + zMatch.Groups[7]); })); // Translate math (float support) // https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings // Groups // 1 2 3 4 5 6 7 8 //@"(.*)(#math;)([+-]?[0-9]*[.,]?[0-9]+)([+\-*/%])([+-]?[0-9]*[.,]?[0-9]+)[;]?(.*?)(#)(.*)" sOutput = LoopTranslateRegex(s_regexMath, sOutput, zElement, (zMatch => { var sResult = ""; if (ParseUtil.ParseFloat(zMatch.Groups[3].ToString(), out var fAValue) && ParseUtil.ParseFloat(zMatch.Groups[5].ToString(), out var fBValue)) { try { var sFormat = zMatch.Groups[6].ToString(); var bUseFormat = !string.IsNullOrWhiteSpace(sFormat); float fResult = 0; switch (zMatch.Groups[4].ToString()[0]) { case '+': fResult = fAValue + fBValue; break; case '-': fResult = fAValue - fBValue; break; case '*': fResult = fAValue * fBValue; break; case '/': if (fBValue == 0) { throw new Exception("Cannot divide by zero."); } fResult = fAValue / fBValue; break; case '%': fResult = fAValue % fBValue; break; } sResult = bUseFormat ? fResult.ToString(sFormat) : fResult.ToString(); } catch (Exception e) { Logger.AddLogLine("Math float translator failed: {0}".FormatString(e)); } } return(zMatch.Groups[1] + sResult + zMatch.Groups[8]); })); // Translate repeat // Groups // 1 2 3 4 5 6 7 //@"(.*)(#repeat;)(\d+)(;)(.+?)(#)(.*)" sOutput = LoopTranslateRegex(s_regexRepeat, sOutput, zElement, (zMatch => { int nRepeatCount; var zBuilder = new StringBuilder(); if (int.TryParse(zMatch.Groups[3].ToString(), out nRepeatCount)) { for (var nIdx = 0; nIdx < nRepeatCount; nIdx++) { zBuilder.Append(zMatch.Groups[5].ToString()); } } else { Logger.AddLogLine("Unable to parse repeat count: " + zMatch.Groups[3].ToString()); } return(zMatch.Groups[1] + zBuilder.ToString() + zMatch.Groups[7]); })); // Translate If Logic //Groups // 1 2 3 4 5 //@"(.*)(#\()(if.+)(\)#)(.*)"); Func <Match, string> funcIfProcessor = (match => { var sLogicResult = TranslateIfLogic(match.Groups[3].ToString()); return(match.Groups[1] + sLogicResult + match.Groups[5]); }); // Translate Switch Logic //Groups // 1 2 3 4 5 //@"(.*)(#\()(switch.+)(\)#)(.*)"); Func <Match, string> funcSwitchProcessor = match => { var sLogicResult = TranslateSwitchLogic(match.Groups[3].ToString()); return(match.Groups[1] + sLogicResult + match.Groups[5]); }; // if / switch processor sOutput = LoopTranslationMatchMap(sOutput, zElement, new Dictionary <Regex, Func <Match, string> > { { s_regexIfLogic, funcIfProcessor }, { s_regexSwitchLogic, funcSwitchProcessor } }); var dictionaryOverrideFieldToValue = new Dictionary <string, string>(); // Override evaluation: // Translate card variables (non-reference information // Groups // 1 2 3 4 5 6 // @"(.*)(\$\[)(.+?):(.+?)(\])(.*) sOutput = LoopTranslateRegex(s_regexElementOverride, sOutput, zElement, (zMatch => { var sField = zMatch.Groups[3].ToString().ToLower(); var sValue = zMatch.Groups[4].ToString(); if (IsDisallowedOverrideField(sField)) { Logger.AddLogLine( "[{1}] override not allowed on element: [{0}]".FormatString(zElement.name, sField)); } // empty override values are discarded (matches reference overrides) else if (!string.IsNullOrWhiteSpace(sValue)) { dictionaryOverrideFieldToValue[sField] = sValue; } return(zMatch.Groups[1].Value + zMatch.Groups[6].Value); } )); zElementString.String = sOutput; zElementString.OverrideFieldToValueDictionary = dictionaryOverrideFieldToValue == null ? null : dictionaryOverrideFieldToValue; return(zElementString); }
public ElementEventArgs(ProjectLayoutElement zElement) : this(new List <ProjectLayoutElement>(new ProjectLayoutElement[] { zElement })) { }
/// <summary> /// Gets a new pen based on the passed in element, color, and thickness. /// </summary> /// <param name="zElement"></param> /// <param name="color"></param> /// <param name="nThickness"></param> /// <returns></returns> public static Pen GetElementOpacityPen(ProjectLayoutElement zElement, Color color, int nThickness) { return(new Pen(GetElementOpacityColor(zElement, color), nThickness)); }
public ElementRenamedEventArgs(ProjectLayoutElement zElement, string oldName) { Element = zElement; OldName = oldName; }
public void DrawCard(int nX, int nY, Graphics zGraphics, DeckLine zDeckLine, bool bExport, bool bDrawBackground) { List <string> listLine = zDeckLine.LineColumns; // Custom Graphics Setting zGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; zGraphics.SmoothingMode = SmoothingMode.AntiAlias; //zGraphics.SmoothingMode = SmoothingMode.HighQuality; var matrixOriginal = zGraphics.Transform; // Zoom does not apply to export if (!bExport) { zGraphics.ScaleTransform(ZoomLevel, ZoomLevel); // Custom Graphics Setting zGraphics.InterpolationMode = 1.0f != ZoomLevel ? InterpolationMode.NearestNeighbor : InterpolationMode.Bilinear; } //Logger.Clear(); ProjectLayoutElement zSelectedElement = null; if (!bExport) { zSelectedElement = ElementManager.Instance.GetSelectedElement(); } // draw the background if (bDrawBackground) { zGraphics.FillRectangle(Brushes.White, nX, nY, CurrentDeck.CardLayout.width, CurrentDeck.CardLayout.height); } // All drawing is handled in reverse element order if (null != CurrentDeck.CardLayout.Element) { for (var nIdx = CurrentDeck.CardLayout.Element.Length - 1; nIdx > -1; nIdx--) { var zElement = CurrentDeck.CardLayout.Element[nIdx]; if (zElement.enabled) // only add enabled items to draw { IssueManager.Instance.FireChangeElementEvent(zElement.name); // get override Element ProjectLayoutElement zOverrideElement = CurrentDeck.GetOverrideElement(zElement, listLine, zDeckLine, bExport); var zDrawElement = zOverrideElement; // translate any index values in the csv var zElementString = CurrentDeck.TranslateString(zDrawElement.variable, zDeckLine, zDrawElement, bExport); // enabled is re-checked due to possible override of the enabled value if (!zElementString.DrawElement || !zDrawElement.enabled) { continue; } var eType = DrawItem.GetElementType(zDrawElement.type); //NOTE: removed transform backup (draw element resets it anyway...) //if (!bExport) // backup is only necessary for zoomed canvas //{ //matrixPrevious = zGraphics.Transform; //} DrawItem.DrawElement(zGraphics, CurrentDeck, zDrawElement, eType, nX, nY, zElementString.String, bExport); if (!bExport) { //zGraphics.Transform = matrixPrevious; zGraphics.ScaleTransform(ZoomLevel, ZoomLevel); } } } if (!bExport) { // draw all selections and element borders after everything else for (var nIdx = CurrentDeck.CardLayout.Element.Length - 1; nIdx > -1; nIdx--) { ProjectLayoutElement zElement = CurrentDeck.CardLayout.Element[nIdx]; if (zElement.enabled) // only add enabled items to draw { var bDrawSelection = zSelectedElement == zElement; if (CardMakerInstance.DrawElementBorder) { var matrixPrevious = zGraphics.Transform; DrawItem.DrawElementDebugBorder(zGraphics, zElement, nX, nY, bDrawSelection); zGraphics.Transform = matrixPrevious; } } } } } // draw the card border if ((bExport && CardMakerSettings.PrintLayoutBorder) || (!bExport && CurrentDeck.CardLayout.drawBorder)) { // note that the border is inclusive in the width/height consuming 2 pixels (0 to total-1) zGraphics.DrawRectangle(Pens.Black, nX, nY, CurrentDeck.CardLayout.width - 1, CurrentDeck.CardLayout.height - 1); } zGraphics.Transform = matrixOriginal; }
public ProjectLayoutElement GetVariableOverrideElement(ProjectLayoutElement zElement, Dictionary <string, string> dictionaryOverrideFieldToValue) { return(m_zTranslator.GetVariableOverrideElement(zElement, dictionaryOverrideFieldToValue)); }