Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
GradientFormatter.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 namespace Lucene.Net.Search.Highlight
21 {
22  /// <summary>
23  /// Formats text with different color intensity depending on the score of the term.
24  /// </summary>
26  {
27  private float maxScore;
28 
29  protected internal int fgRMin, fgGMin, fgBMin;
30  protected internal int fgRMax, fgGMax, fgBMax;
31  protected bool highlightForeground;
32  protected internal int bgRMin, bgGMin, bgBMin;
33  protected internal int bgRMax, bgGMax, bgBMax;
34  protected bool highlightBackground;
35 
36  /// <summary> Sets the color range for the IDF scores</summary>
37  /// <param name="maxScore">
38  /// The score (and above) displayed as maxColor (See QueryScorer.getMaxWeight
39  /// which can be used to callibrate scoring scale)
40  /// </param>
41  /// <param name="minForegroundColor">
42  /// The hex color used for representing IDF scores of zero eg
43  /// #FFFFFF (white) or null if no foreground color required
44  /// </param>
45  /// <param name="maxForegroundColor">
46  /// The largest hex color used for representing IDF scores eg
47  /// #000000 (black) or null if no foreground color required
48  /// </param>
49  /// <param name="minBackgroundColor">
50  /// The hex color used for representing IDF scores of zero eg
51  /// #FFFFFF (white) or null if no background color required
52  /// </param>
53  /// <param name="maxBackgroundColor">
54  /// The largest hex color used for representing IDF scores eg
55  /// #000000 (black) or null if no background color required
56  /// </param>
57  public GradientFormatter(float maxScore, string minForegroundColor, string maxForegroundColor, string minBackgroundColor, string maxBackgroundColor)
58  {
59  highlightForeground = (minForegroundColor != null) && (maxForegroundColor != null);
60 
61  if (highlightForeground)
62  {
63  if (minForegroundColor.Length != 7)
64  {
65  throw new ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF");
66  }
67  if (maxForegroundColor.Length != 7)
68  {
69  throw new ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF");
70  }
71  fgRMin = HexToInt(minForegroundColor.Substring(1, 2));
72  fgGMin = HexToInt(minForegroundColor.Substring(3, 2));
73  fgBMin = HexToInt(minForegroundColor.Substring(5, 2));
74 
75  fgRMax = HexToInt(maxForegroundColor.Substring(1, 2));
76  fgGMax = HexToInt(maxForegroundColor.Substring(3, 2));
77  fgBMax = HexToInt(maxForegroundColor.Substring(5, 2));
78  }
79 
80  highlightBackground = (minBackgroundColor != null) && (maxBackgroundColor != null);
81  if (highlightBackground)
82  {
83  if (minBackgroundColor.Length != 7)
84  {
85  throw new System.ArgumentException("minBackgroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF");
86  }
87  if (maxBackgroundColor.Length != 7)
88  {
89  throw new System.ArgumentException("minBackgroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF");
90  }
91  bgRMin = HexToInt(minBackgroundColor.Substring(1, 2));
92  bgGMin = HexToInt(minBackgroundColor.Substring(3, 2));
93  bgBMin = HexToInt(minBackgroundColor.Substring(5, 2));
94 
95  bgRMax = HexToInt(maxBackgroundColor.Substring(1, 2));
96  bgGMax = HexToInt(maxBackgroundColor.Substring(3, 2));
97  bgBMax = HexToInt(maxBackgroundColor.Substring(5, 2));
98  }
99  // this.corpusReader = corpusReader;
100  this.maxScore = maxScore;
101  // totalNumDocs = corpusReader.numDocs();
102  }
103 
104  public virtual string HighlightTerm(string originalText, TokenGroup tokenGroup)
105  {
106  if (tokenGroup.TotalScore == 0)
107  return originalText;
108  float score = tokenGroup.TotalScore;
109  if (score == 0)
110  {
111  return originalText;
112  }
113 
114  var sb = new System.Text.StringBuilder();
115  sb.Append("<font ");
116  if (highlightForeground)
117  {
118  sb.Append("color=\"");
119  sb.Append(GetForegroundColorString(score));
120  sb.Append("\" ");
121  }
122  if (highlightBackground)
123  {
124  sb.Append("bgcolor=\"");
125  sb.Append(GetBackgroundColorString(score));
126  sb.Append("\" ");
127  }
128  sb.Append(">");
129  sb.Append(originalText);
130  sb.Append("</font>");
131  return sb.ToString();
132  }
133 
134  protected internal virtual string GetForegroundColorString(float score)
135  {
136  int rVal = GetColorVal(fgRMin, fgRMax, score);
137  int gVal = GetColorVal(fgGMin, fgGMax, score);
138  int bVal = GetColorVal(fgBMin, fgBMax, score);
139  var sb = new System.Text.StringBuilder();
140  sb.Append("#");
141  sb.Append(IntToHex(rVal));
142  sb.Append(IntToHex(gVal));
143  sb.Append(IntToHex(bVal));
144  return sb.ToString();
145  }
146 
147  protected internal virtual string GetBackgroundColorString(float score)
148  {
149  int rVal = GetColorVal(bgRMin, bgRMax, score);
150  int gVal = GetColorVal(bgGMin, bgGMax, score);
151  int bVal = GetColorVal(bgBMin, bgBMax, score);
152  var sb = new System.Text.StringBuilder();
153  sb.Append("#");
154  sb.Append(IntToHex(rVal));
155  sb.Append(IntToHex(gVal));
156  sb.Append(IntToHex(bVal));
157  return sb.ToString();
158  }
159 
160  private int GetColorVal(int colorMin, int colorMax, float score)
161  {
162  if (colorMin == colorMax)
163  {
164  return colorMin;
165  }
166  float scale = Math.Abs(colorMin - colorMax);
167  float relScorePercent = Math.Min(maxScore, score) / maxScore;
168  float colScore = scale * relScorePercent;
169  return Math.Min(colorMin, colorMax) + (int) colScore;
170  }
171 
172  private static char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
173 
174  private static string IntToHex(int i)
175  {
176  return "" + hexDigits[(i & 0xF0) >> 4] + hexDigits[i & 0x0F];
177  }
178 
179  /// <summary> Converts a hex string into an int. Integer.parseInt(hex, 16) assumes the
180  /// input is nonnegative unless there is a preceding minus sign. This method
181  /// reads the input as twos complement instead, so if the input is 8 bytes
182  /// long, it will correctly restore a negative int produced by
183  /// Integer.toHexString() but not neccesarily one produced by
184  /// Integer.toString(x,16) since that method will produce a string like '-FF'
185  /// for negative integer values.
186  ///
187  /// </summary>
188  /// <param name="hex">
189  /// A string in capital or lower case hex, of no more then 16
190  /// characters.
191  /// </param>
192  /// <exception cref="FormatException">if the string is more than 16 characters long, or if any
193  /// character is not in the set [0-9a-fA-f]</exception>
194  public static int HexToInt(string hex)
195  {
196  int len = hex.Length;
197  if (len > 16)
198  throw new FormatException();
199 
200  int l = 0;
201  for (int i = 0; i < len; i++)
202  {
203  l <<= 4;
204  int c = (int) System.Char.GetNumericValue(hex[i]);
205  if (c < 0)
206  throw new FormatException();
207  l |= c;
208  }
209  return l;
210  }
211  }
212 }