/* * 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.Highlight { /// Formats text with different color intensity depending on the score of the /// term. /// /// /// maharwood /// public class GradientFormatter : Formatter { private float maxScore; internal int fgRMin, fgGMin, fgBMin; internal int fgRMax, fgGMax, fgBMax; protected internal bool highlightForeground; internal int bgRMin, bgGMin, bgBMin; internal int bgRMax, bgGMax, bgBMax; protected internal bool highlightBackground; /// Sets the color range for the IDF scores /// /// /// maxScore /// The score (and above) displayed as maxColor (See QueryScorer.getMaxWeight /// which can be used to callibrate scoring scale) /// /// minForegroundColor /// The hex color used for representing IDF scores of zero eg /// #FFFFFF (white) or null if no foreground color required /// /// maxForegroundColor /// The largest hex color used for representing IDF scores eg /// #000000 (black) or null if no foreground color required /// /// minBackgroundColor /// The hex color used for representing IDF scores of zero eg /// #FFFFFF (white) or null if no background color required /// /// maxBackgroundColor /// The largest hex color used for representing IDF scores eg /// #000000 (black) or null if no background color required /// public GradientFormatter(float maxScore, System.String minForegroundColor, System.String maxForegroundColor, System.String minBackgroundColor, System.String maxBackgroundColor) { highlightForeground = (minForegroundColor != null) && (maxForegroundColor != null); if (highlightForeground) { if (minForegroundColor.Length != 7) { throw new System.ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } if (maxForegroundColor.Length != 7) { throw new System.ArgumentException("minForegroundColor is not 7 bytes long eg a hex " + "RGB value such as #FFFFFF"); } fgRMin = HexToInt(minForegroundColor.Substring(1, (3) - (1))); fgGMin = HexToInt(minForegroundColor.Substring(3, (5) - (3))); fgBMin = HexToInt(minForegroundColor.Substring(5, (7) - (5))); fgRMax = HexToInt(maxForegroundColor.Substring(1, (3) - (1))); fgGMax = HexToInt(maxForegroundColor.Substring(3, (5) - (3))); fgBMax = HexToInt(maxForegroundColor.Substring(5, (7) - (5))); } 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, (3) - (1))); bgGMin = HexToInt(minBackgroundColor.Substring(3, (5) - (3))); bgBMin = HexToInt(minBackgroundColor.Substring(5, (7) - (5))); bgRMax = HexToInt(maxBackgroundColor.Substring(1, (3) - (1))); bgGMax = HexToInt(maxBackgroundColor.Substring(3, (5) - (3))); bgBMax = HexToInt(maxBackgroundColor.Substring(5, (7) - (5))); } // this.corpusReader = corpusReader; this.maxScore = maxScore; // totalNumDocs = corpusReader.numDocs(); } public virtual System.String HighlightTerm(System.String originalText, TokenGroup tokenGroup) { if (tokenGroup.GetTotalScore() == 0) return originalText; float score = tokenGroup.GetTotalScore(); if (score == 0) { return originalText; } System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(""); sb.Append(originalText); sb.Append(""); return sb.ToString(); } protected internal virtual System.String GetForegroundColorString(float score) { int rVal = GetColorVal(fgRMin, fgRMax, score); int gVal = GetColorVal(fgGMin, fgGMax, score); int bVal = GetColorVal(fgBMin, fgBMax, score); System.Text.StringBuilder 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 System.String GetBackgroundColorString(float score) { int rVal = GetColorVal(bgRMin, bgRMax, score); int gVal = GetColorVal(bgGMin, bgGMax, score); int bVal = GetColorVal(bgBMin, bgBMax, score); System.Text.StringBuilder 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 = System.Math.Abs(colorMin - colorMax); float relScorePercent = System.Math.Min(maxScore, score) / maxScore; float colScore = scale * relScorePercent; return System.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 System.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. /// /// /// hex /// A string in capital or lower case hex, of no more then 16 /// characters. /// /// NumberFormatException /// 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(System.String hex) { int len = hex.Length; if (len > 16) throw new System.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 System.FormatException(); l |= c; } return l; } } }