/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace Lucene.Net.Search.Highlight { /// /// Formats text with different color intensity depending on the score of the term. /// public class GradientFormatter : IFormatter { private float maxScore; protected internal int fgRMin, fgGMin, fgBMin; protected internal int fgRMax, fgGMax, fgBMax; protected bool highlightForeground; protected internal int bgRMin, bgGMin, bgBMin; protected internal int bgRMax, bgGMax, bgBMax; protected bool highlightBackground; /// Sets the color range for the IDF scores /// /// The score (and above) displayed as maxColor (See QueryScorer.getMaxWeight /// which can be used to callibrate scoring scale) /// /// /// The hex color used for representing IDF scores of zero eg /// #FFFFFF (white) or null if no foreground color required /// /// /// The largest hex color used for representing IDF scores eg /// #000000 (black) or null if no foreground color required /// /// /// The hex color used for representing IDF scores of zero eg /// #FFFFFF (white) or null if no background color required /// /// /// The largest hex color used for representing IDF scores eg /// #000000 (black) or null if no background color required /// public GradientFormatter(float maxScore, string minForegroundColor, string maxForegroundColor, string minBackgroundColor, string maxBackgroundColor) { highlightForeground = (minForegroundColor != null) && (maxForegroundColor != null); if (highlightForeground) { if (minForegroundColor.Length != 7) { throw new ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } if (maxForegroundColor.Length != 7) { throw new ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } fgRMin = HexToInt(minForegroundColor.Substring(1, 2)); fgGMin = HexToInt(minForegroundColor.Substring(3, 2)); fgBMin = HexToInt(minForegroundColor.Substring(5, 2)); fgRMax = HexToInt(maxForegroundColor.Substring(1, 2)); fgGMax = HexToInt(maxForegroundColor.Substring(3, 2)); fgBMax = HexToInt(maxForegroundColor.Substring(5, 2)); } highlightBackground = (minBackgroundColor != null) && (maxBackgroundColor != null); if (highlightBackground) { if (minBackgroundColor.Length != 7) { throw new System.ArgumentException("minBackgroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } if (maxBackgroundColor.Length != 7) { throw new System.ArgumentException("minBackgroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } bgRMin = HexToInt(minBackgroundColor.Substring(1, 2)); bgGMin = HexToInt(minBackgroundColor.Substring(3, 2)); bgBMin = HexToInt(minBackgroundColor.Substring(5, 2)); bgRMax = HexToInt(maxBackgroundColor.Substring(1, 2)); bgGMax = HexToInt(maxBackgroundColor.Substring(3, 2)); bgBMax = HexToInt(maxBackgroundColor.Substring(5, 2)); } // this.corpusReader = corpusReader; this.maxScore = maxScore; // totalNumDocs = corpusReader.numDocs(); } public virtual string HighlightTerm(string originalText, TokenGroup tokenGroup) { if (tokenGroup.TotalScore == 0) return originalText; float score = tokenGroup.TotalScore; if (score == 0) { return originalText; } var sb = new System.Text.StringBuilder(); sb.Append(""); sb.Append(originalText); sb.Append(""); return sb.ToString(); } protected internal virtual string GetForegroundColorString(float score) { int rVal = GetColorVal(fgRMin, fgRMax, score); int gVal = GetColorVal(fgGMin, fgGMax, score); int bVal = GetColorVal(fgBMin, fgBMax, score); var sb = new System.Text.StringBuilder(); sb.Append("#"); sb.Append(IntToHex(rVal)); sb.Append(IntToHex(gVal)); sb.Append(IntToHex(bVal)); return sb.ToString(); } protected internal virtual string GetBackgroundColorString(float score) { int rVal = GetColorVal(bgRMin, bgRMax, score); int gVal = GetColorVal(bgGMin, bgGMax, score); int bVal = GetColorVal(bgBMin, bgBMax, score); var sb = new System.Text.StringBuilder(); sb.Append("#"); sb.Append(IntToHex(rVal)); sb.Append(IntToHex(gVal)); sb.Append(IntToHex(bVal)); return sb.ToString(); } private int GetColorVal(int colorMin, int colorMax, float score) { if (colorMin == colorMax) { return colorMin; } float scale = Math.Abs(colorMin - colorMax); float relScorePercent = Math.Min(maxScore, score) / maxScore; float colScore = scale * relScorePercent; return Math.Min(colorMin, colorMax) + (int) colScore; } private static char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private static string IntToHex(int i) { return "" + hexDigits[(i & 0xF0) >> 4] + hexDigits[i & 0x0F]; } /// Converts a hex string into an int. Integer.parseInt(hex, 16) assumes the /// input is nonnegative unless there is a preceding minus sign. This method /// reads the input as twos complement instead, so if the input is 8 bytes /// long, it will correctly restore a negative int produced by /// Integer.toHexString() but not neccesarily one produced by /// Integer.toString(x,16) since that method will produce a string like '-FF' /// for negative integer values. /// /// /// /// A string in capital or lower case hex, of no more then 16 /// characters. /// /// if the string is more than 16 characters long, or if any /// character is not in the set [0-9a-fA-f] public static int HexToInt(string hex) { int len = hex.Length; if (len > 16) throw new FormatException(); int l = 0; for (int i = 0; i < len; i++) { l <<= 4; int c = (int) System.Char.GetNumericValue(hex[i]); if (c < 0) throw new FormatException(); l |= c; } return l; } } }