/// <summary> /// Measures the location of an arbritrary # of words within a string /// </summary> private WordStartFinish[] MeasureString(string s, Graphics g, Font drawFont, StringFormat drawFormat, CharacterRange[] cra) { if (cra.Length <= MEASUREMAX) // handle the simple case of < MEASUREMAX words return MeasureString32(s, g, drawFont, drawFormat, cra); // Need to compensate for SetMeasurableCharacterRanges limitation of 32 (MEASUREMAX) int mcra = (cra.Length / MEASUREMAX); // # of full 32 arrays we need int ip = cra.Length % MEASUREMAX; // # of partial entries needed for last array (if any) WordStartFinish[] sz = new WordStartFinish[cra.Length]; // this is the final result; float startPos=0; CharacterRange[] cra32 = new CharacterRange[MEASUREMAX]; // fill out int icra=0; // index thru the cra for (int i=0; i < mcra; i++) { // fill out the new array int ticra = icra; for (int j=0; j < cra32.Length; j++) { cra32[j] = cra[ticra++]; cra32[j].First -= cra[icra].First; // adjust relative offsets of strings } // measure the word locations (in the new string) // ???? should I put a blank in front of it?? string ts = s.Substring(cra[icra].First, cra[icra + cra32.Length-1].First + cra[icra + cra32.Length-1].Length - cra[icra].First); WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32); // copy the values adding in the new starting positions for (int j = 0; j < pos.Length; j++) { sz[icra].start = pos[j].start + startPos; sz[icra++].end = pos[j].end + startPos; } startPos = sz[icra-1].end; // reset the start position for the next line } // handle the remaining character if (ip > 0) { // resize the range array cra32 = new CharacterRange[ip]; // fill out the new array int ticra = icra; for (int j=0; j < cra32.Length; j++) { cra32[j] = cra[ticra++]; cra32[j].First -= cra[icra].First; // adjust relative offsets of strings } // measure the word locations (in the new string) // ???? should I put a blank in front of it?? string ts = s.Substring(cra[icra].First, cra[icra + cra32.Length-1].First + cra[icra + cra32.Length-1].Length - cra[icra].First); WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32); // copy the values adding in the new starting positions for (int j = 0; j < pos.Length; j++) { sz[icra].start = pos[j].start + startPos; sz[icra++].end = pos[j].end + startPos; } } return sz; }
/// <summary> /// Measures the location of words within a string; limited by .Net 1.1 to 32 words /// MEASUREMAX is a constant that defines that limit /// </summary> /// <param name="s"></param> /// <param name="g"></param> /// <param name="drawFont"></param> /// <param name="drawFormat"></param> /// <param name="cra"></param> /// <returns></returns> private WordStartFinish[] MeasureString32(string s, Graphics g, Font drawFont, StringFormat drawFormat, CharacterRange[] cra) { if (s == null || s.Length == 0) return null; drawFormat.SetMeasurableCharacterRanges(cra); Region[] rs = new Region[cra.Length]; rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue), drawFormat); WordStartFinish[] sz = new WordStartFinish[cra.Length]; int isz = 0; foreach (Region r in rs) { RectangleF mr = r.GetBounds(g); sz[isz].start = RSize.PointsFromPixels(g, mr.Left); sz[isz].end = RSize.PointsFromPixels(g, mr.Right); isz++; } return sz; }
/// <summary> /// Measures the location of an arbritrary # of words within a string /// </summary> private static WordStartFinish[] MeasureString(string s, Graphics g, System.Drawing.Font drawFont, StringFormat drawFormat, CharacterRange[] cra) { if (cra.Length <= MEASUREMAX) // handle the simple case of < MEASUREMAX words { return(MeasureString32(s, g, drawFont, drawFormat, cra)); } // Need to compensate for SetMeasurableCharacterRanges limitation of 32 (MEASUREMAX) int mcra = (cra.Length / MEASUREMAX); // # of full 32 arrays we need int ip = cra.Length % MEASUREMAX; // # of partial entries needed for last array (if any) WordStartFinish[] sz = new WordStartFinish[cra.Length]; // this is the final result; float startPos = 0; CharacterRange[] cra32 = new CharacterRange[MEASUREMAX]; // fill out int icra = 0; // index thru the cra for (int i = 0; i < mcra; i++) { // fill out the new array int ticra = icra; for (int j = 0; j < cra32.Length; j++) { cra32[j] = cra[ticra++]; cra32[j].First -= cra[icra].First; // adjust relative offsets of strings } // measure the word locations (in the new string) // ???? should I put a blank in front of it?? string ts = s.Substring(cra[icra].First, cra[icra + cra32.Length - 1].First + cra[icra + cra32.Length - 1].Length - cra[icra].First); WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32); // copy the values adding in the new starting positions for (int j = 0; j < pos.Length; j++) { sz[icra].start = pos[j].start + startPos; sz[icra++].end = pos[j].end + startPos; } startPos = sz[icra - 1].end; // reset the start position for the next line } // handle the remaining character if (ip > 0) { // resize the range array cra32 = new CharacterRange[ip]; // fill out the new array int ticra = icra; for (int j = 0; j < cra32.Length; j++) { cra32[j] = cra[ticra++]; cra32[j].First -= cra[icra].First; // adjust relative offsets of strings } // measure the word locations (in the new string) // ???? should I put a blank in front of it?? string ts = s.Substring(cra[icra].First, cra[icra + cra32.Length - 1].First + cra[icra + cra32.Length - 1].Length - cra[icra].First); WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32); // copy the values adding in the new starting positions for (int j = 0; j < pos.Length; j++) { sz[icra].start = pos[j].start + startPos; sz[icra++].end = pos[j].end + startPos; } } return(sz); }