/// <summary> /// Defines this pattern using the string obtained from a style file. /// </summary> /// <param name="entry">The entry that defines the pattern</param> /// <returns>True if parsed ok. False if something looks bad.</returns> internal bool Create(StyleEntry entry) { // The entry takes the form <name> = <pattern>, so if there's no "=" character // (or it's right at the very start), the entry is no good string token = entry.DashToken; int index = token.IndexOf('='); if (index <= 0) { return(false); } // Pick up the name for the pattern m_Name = token.Substring(0, index).Trim(); if (m_Name.Length == 0) { return(false); } // Pick up the definition of the dashes and the intervening spaces string rest = token.Substring(index + 1).Trim(); if (rest.Length == 0) { return(false); } // There has to be at least one comma if (rest.IndexOf(',') <= 0) { return(false); } // Parse the values string[] pats = rest.Split(','); m_Pattern = new float[pats.Length]; for (int i = 0; i < pats.Length; i++) { float f; if (!Single.TryParse(pats[i], out f)) { return(false); } // All values must be greater than 1mm on the ground. // This is basically a sanity check that's meant to // catch confusion about the units in which the dash // pattern is defined. if (f < 0.001F) { return(false); } m_Pattern[i] = f; } return(true); // SS 18-FEB-2008: The following was commented out in the old CEdit implementation, // not sure if it has any continuing relevance... // If the very first element is a space, prepend a dash // that has no length. This is meant to accommodate the // fact that CPen::CreatePen expects the first value to // relate to a dash, then a space, etc. // Be more restrictive and force the first value to be // a dash. When I tried inserting a leading zero, it // looked like the width of the 0.1m dash was twice what // it should be. It's possible that MFC gets confused by // the zero (or possibly the fact that there were an odd // number of elements in the pattern). //if ( m_Pattern[0] > 0.0 ) //{ // FLOAT4* array = new FLOAT4[m_NumElement+1]; // array[0] = 0.0; // memcpy(&array[1],m_Pattern,m_NumElement*sizeof(FLOAT4)); // delete [] m_Pattern; // m_NumElement++; // m_Pattern = array; //} //// Ensure they're all positive numbers //for ( i=0; i<m_NumElement; i++ ) //{ // m_Pattern[i] = fabs(m_Pattern[i]); //} //if ( ok ) //{ // CString msg; // msg.Format("%s=",m_Name); // for ( i=0; i<m_NumElement; i++ ) // { // if ( i>0 ) msg+=","; // CString extra; // extra.Format("%g",m_Pattern[i]); // msg += extra; // } // AfxMessageBox(msg); //} return ok; }
/// <summary> /// Defines this pattern using the string obtained from a style file. /// </summary> /// <param name="entry">The entry that defines the pattern</param> /// <returns>True if parsed ok. False if something looks bad.</returns> internal bool Create(StyleEntry entry) { // The entry takes the form <name> = <pattern>, so if there's no "=" character // (or it's right at the very start), the entry is no good string token = entry.DashToken; int index = token.IndexOf('='); if (index<=0) return false; // Pick up the name for the pattern m_Name = token.Substring(0, index).Trim(); if (m_Name.Length==0) return false; // Pick up the definition of the dashes and the intervening spaces string rest = token.Substring(index+1).Trim(); if (rest.Length==0) return false; // There has to be at least one comma if (rest.IndexOf(',')<=0) return false; // Parse the values string[] pats = rest.Split(','); m_Pattern = new float[pats.Length]; for (int i=0; i<pats.Length; i++) { float f; if (!Single.TryParse(pats[i], out f)) return false; // All values must be greater than 1mm on the ground. // This is basically a sanity check that's meant to // catch confusion about the units in which the dash // pattern is defined. if (f < 0.001F) return false; m_Pattern[i] = f; } return true; // SS 18-FEB-2008: The following was commented out in the old CEdit implementation, // not sure if it has any continuing relevance... // If the very first element is a space, prepend a dash // that has no length. This is meant to accommodate the // fact that CPen::CreatePen expects the first value to // relate to a dash, then a space, etc. // Be more restrictive and force the first value to be // a dash. When I tried inserting a leading zero, it // looked like the width of the 0.1m dash was twice what // it should be. It's possible that MFC gets confused by // the zero (or possibly the fact that there were an odd // number of elements in the pattern). //if ( m_Pattern[0] > 0.0 ) //{ // FLOAT4* array = new FLOAT4[m_NumElement+1]; // array[0] = 0.0; // memcpy(&array[1],m_Pattern,m_NumElement*sizeof(FLOAT4)); // delete [] m_Pattern; // m_NumElement++; // m_Pattern = array; //} //// Ensure they're all positive numbers //for ( i=0; i<m_NumElement; i++ ) //{ // m_Pattern[i] = fabs(m_Pattern[i]); //} //if ( ok ) //{ // CString msg; // msg.Format("%s=",m_Name); // for ( i=0; i<m_NumElement; i++ ) // { // if ( i>0 ) msg+=","; // CString extra; // extra.Format("%g",m_Pattern[i]); // msg += extra; // } // AfxMessageBox(msg); //} return ok; }
/// <summary> /// Initialize this style file object with the content of a file. /// </summary> /// <param name="file">The file to read the definition from.</param> /// <returns>The number of styles that were loaded.</returns> int Create(StreamReader file) { // If we previously created stuff, get rid of it. ResetContents(); // Load an index for standard colour names Dictionary <string, Color> colors = LoadColors(); // Create the index of entity and/or layer name vs it's style m_StyleLookup = new Dictionary <string, Style>(100); string line; StyleEntry entry = new StyleEntry(); StringBuilder errors = new StringBuilder(1000); List <DashPattern> dashPatterns = new List <DashPattern>(100); List <Style> styles = new List <Style>(100); while ((line = file.ReadLine()) != null) { int nToken = entry.Parse(line); if (nToken == 0) { continue; } if (nToken < 0) { errors.AppendLine(String.Format("Invalid style entry: {0}", line)); continue; } // If we've got the definition of a dash style, // parse it and add to the list of styles if (entry.IsDashStyle) { DashPattern dp = new DashPattern(); if (dp.Create(entry)) { dashPatterns.Add(dp); } else { errors.AppendLine(String.Format("Cannot parse style definition: {0}", line)); } } else { // Only entity & layer entries are currently supported string itemName; if (entry.IsEntityEntry) { itemName = entry.EntityToken; } else if (entry.IsLayerEntry) { itemName = entry.LayerToken; } else { continue; } // Both entity & layer entries should have some sort of colour (either a // named colour, or an RGB value) Color col = Color.Black; bool colDefined = false; string colName = entry.ColToken; if (colName.Length == 0) { string rgb = entry.RGBToken; colDefined = TryParseRGB(rgb, out col); } else { string fmtcol = FormatColorName(colName); colDefined = colors.ContainsKey(fmtcol); if (colDefined) { col = colors[fmtcol]; } } if (!colDefined) { errors.AppendLine(String.Format("Invalid colour in: {0}", line)); continue; } // Get any line pattern DashPattern dp = null; string pat = entry.DashToken; if (pat.Length > 0) { dp = dashPatterns.Find(d => d.Name == pat); if (dp == null) { errors.AppendLine(String.Format("Cannot find dash pattern for: {0}", line)); continue; } } // Get any line weight (sanity check forces it // to be in the range (0.01,10.0)) float fwt = -1.0F; string wt = entry.WtToken; if (wt.Length > 0) { if (!Single.TryParse(wt, out fwt) || fwt < 0.01F || fwt > 10.0F) { errors.AppendLine(String.Format("Invalid line weight: {0}", line)); continue; } } // Create a suitable style Style style; if (fwt < 0.01F && dp == null) { style = new Style(col); } else { style = new LineStyle(col, fwt, dp); } // If we already have an identical style, use that instead Style prevStyle = styles.Find(s => style.IsMatch(s)); if (prevStyle != null) { m_StyleLookup[itemName] = prevStyle; } else { styles.Add(style); m_StyleLookup[itemName] = style; } } } m_DashPatterns = dashPatterns.ToArray(); m_Styles = styles.ToArray(); if (errors.Length > 0) { throw new Exception(errors.ToString()); } // Return the number of styles that we loaded. return(m_Styles.Length); }
/// <summary> /// Initialize this style file object with the content of a file. /// </summary> /// <param name="file">The file to read the definition from.</param> /// <returns>The number of styles that were loaded.</returns> int Create(StreamReader file) { // If we previously created stuff, get rid of it. ResetContents(); // Load an index for standard colour names Dictionary<string, Color> colors = LoadColors(); // Create the index of entity and/or layer name vs it's style m_StyleLookup = new Dictionary<string, Style>(100); string line; StyleEntry entry = new StyleEntry(); StringBuilder errors = new StringBuilder(1000); List<DashPattern> dashPatterns = new List<DashPattern>(100); List<Style> styles = new List<Style>(100); while ((line=file.ReadLine())!=null) { int nToken = entry.Parse(line); if (nToken == 0) continue; if (nToken < 0) { errors.AppendLine(String.Format("Invalid style entry: {0}", line)); continue; } // If we've got the definition of a dash style, // parse it and add to the list of styles if (entry.IsDashStyle) { DashPattern dp = new DashPattern(); if (dp.Create(entry)) dashPatterns.Add(dp); else errors.AppendLine(String.Format("Cannot parse style definition: {0}", line)); } else { // Only entity & layer entries are currently supported string itemName; if (entry.IsEntityEntry) itemName = entry.EntityToken; else if (entry.IsLayerEntry) itemName = entry.LayerToken; else continue; // Both entity & layer entries should have some sort of colour (either a // named colour, or an RGB value) Color col = Color.Black; bool colDefined = false; string colName = entry.ColToken; if (colName.Length==0) { string rgb = entry.RGBToken; colDefined = TryParseRGB(rgb, out col); } else { string fmtcol = FormatColorName(colName); colDefined = colors.ContainsKey(fmtcol); if (colDefined) col = colors[fmtcol]; } if (!colDefined) { errors.AppendLine(String.Format("Invalid colour in: {0}", line)); continue; } // Get any line pattern DashPattern dp = null; string pat = entry.DashToken; if (pat.Length > 0) { dp = dashPatterns.Find(d => d.Name==pat); if (dp==null) { errors.AppendLine(String.Format("Cannot find dash pattern for: {0}", line)); continue; } } // Get any line weight (sanity check forces it // to be in the range (0.01,10.0)) float fwt = -1.0F; string wt = entry.WtToken; if (wt.Length>0) { if (!Single.TryParse(wt, out fwt) || fwt<0.01F || fwt>10.0F) { errors.AppendLine(String.Format("Invalid line weight: {0}", line)); continue; } } // Create a suitable style Style style; if (fwt < 0.01F && dp==null) style = new Style(col); else style = new LineStyle(col, fwt, dp); // If we already have an identical style, use that instead Style prevStyle = styles.Find(s => style.IsMatch(s)); if (prevStyle!=null) m_StyleLookup[itemName] = prevStyle; else { styles.Add(style); m_StyleLookup[itemName] = style; } } } m_DashPatterns = dashPatterns.ToArray(); m_Styles = styles.ToArray(); if (errors.Length>0) throw new Exception(errors.ToString()); // Return the number of styles that we loaded. return m_Styles.Length; }