using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.Drawing;
namespace GraphicText
{
#region "structures"
public struct classWordImageLine
{
public classWordImage[] Word;
public int intWidth;
public int intHeight;
public int intBottomEdgePos;
public bool bolHasSubscript;
public bool bolHasSuperscript;
}
public struct udtChemSymbols
{
public string[] Symbols;
}
#endregion
#region "enumerated types"
public enum enuWordPositionRelativeToPreviousWord { right, NL }
#endregion
public class classGraphicText
{
#region "variables"
classMyFont Font_Normal;
static classWordImage WordImage_BinTree;
static udtChemSymbols[] udrChemSymbols;
static public int intHTab = 40;
static public int intVTab = 25;
static public string strAlpha = "aàáâãäåbcçdÐeèéêëfghiìíîïjklmnñoðòóôõöpqrsštuùúûüvwxyýÿzžAÀÁÂÃÄÅBCÇDÐEÈÉÊËFGHIÌÍÎÏJKLMNÑOÐÒÓÔÕÖPQRSŠTUÙÚÛÜVWXYÝŸZŽĀĒĪŌŪāēīōū";
static public Color clrBackground = Color.White;
static classWordImageLine[] udrLines = new classWordImageLine[0];
#endregion
#region "object"
static Bitmap bmpSizer = new Bitmap(10, 10);
static Graphics g = Graphics.FromImage(bmpSizer);
#endregion
public classGraphicText()
{
udrChemSymbols = new udtChemSymbols[2];
string[] strTemp0 = { "B", "C", "D", "F", "H", "I", "K", "N", "O", "P", "S", "U", "V", "W", "Y" };
udrChemSymbols[0].Symbols = strTemp0;
string[] strTemp1 = { "Ac", "Ag", "Al", "Am", "Ar", "As", "At", "Au", "Ba", "Be", "Bh", "Bi", "Bk", "Br", "Ca", "Cd", "Ce", "Cf", "Cl", "Cm", "Co", "Cp", "Cr", "Cs", "Cu", "Db", "Ds", "Dy", "Er", "Es", "Eu", "Fe", "Fm", "Fr", "Ga", "Gd", "Ge", "He", "Hf", "Hg", "Ho", "Hs", "In", "Ir", "Kr", "La", "Li", "Lr", "Lu", "Md", "Mg", "Mn", "Mo", "Mt", "Na", "Nb", "Nd", "Ne", "Ni", "No", "Np", "Os", "Pa", "Pb", "Pd", "Pm", "Po", "Pr", "Pt", "Pu", "Ra", "Rb", "Re", "Rf", "Rg", "Rh", "Rn", "Ru", "Sb", "Sc", "Se", "Sg", "Si", "Sm", "Sn", "Sr", "Ta", "Tb", "Tc", "Te", "Th", "Ti", "Tl", "Tm", "Xe", "Yb", "Zn", "Zr" };
udrChemSymbols[1].Symbols = strTemp1;
Font_Normal = new classMyFont(new Font("Ms sans-serif", 10, FontStyle.Regular), Color.Black);
}
public classWordImage getWordUnderMouse(Point ptMouse, classWordImage[] cWordArray)
{
int intLineIndex = 0;
while (intLineIndex < udrLines.Length && udrLines[intLineIndex].intBottomEdgePos < ptMouse.Y)
intLineIndex++;
if (intLineIndex >= 0
&& intLineIndex < udrLines.Length
&& udrLines.Length > 0)
{
for (int intWordCounter = 0; intWordCounter < udrLines[intLineIndex].Word.Length; intWordCounter++)
{
classWordImage cWord = udrLines[intLineIndex].Word[intWordCounter];
if (cWord.strText != null
&& cWord.pt.Y <= ptMouse.Y
&& cWord.pt.Y + cWord.bmp.Height >= ptMouse.Y
&& cWord.pt.X <= ptMouse.X
&& cWord.pt.X + cWord.bmp.Width >= ptMouse.X)
return udrLines[intLineIndex].Word[intWordCounter];
}
}
return null;
}
/// <summary>
/// returns the classWordImage located beneath the current mousepointer on the picbox's image
/// </summary>
/// <returns>classWordImage beneath the mouse or null if none found</returns>
///
public classWordImage getWordUnderMouse_old(Point ptMouse, classWordImage[] cWordArray)
{
int intStepSize = cWordArray.Length;
int intIndex = 0;
while (intStepSize > 1 && intIndex < cWordArray.Length && intIndex >= 0)
{
intStepSize = (int)Math.Ceiling((double)intStepSize / 2);
if (ptMouse.Y > cWordArray[intIndex].intLine)
{
if (intIndex + intStepSize >= cWordArray.Length)
intIndex = cWordArray.Length - 1;
else
intIndex += intStepSize;
}
else if (ptMouse.Y < cWordArray[intIndex].intLine - wordSize(cWordArray[intIndex]).Height)
{
if (intIndex - intStepSize < 0)
intIndex = 0;
else
intIndex -= intStepSize;
}
else
break;
}
int intDir = -1;
if (intIndex >= 0 && intIndex < cWordArray.Length)
{
if (ptMouse.X > cWordArray[intIndex].pt.X)
intDir = 1;
int intThisDir = 0;
while (intIndex >= 0
&& intIndex < cWordArray.Length)
{
Size szWord = wordSize(cWordArray[intIndex]);
if (ptMouse.X > cWordArray[intIndex].pt.X + szWord.Width
|| cWordArray[intIndex].eWordImageType == enuWordImageType.vTab )
intThisDir = 1;
else if (ptMouse.X < cWordArray[intIndex].pt.X)
intThisDir = -1;
else
{
if (ptMouse.X > cWordArray[intIndex].pt.X
&& ptMouse.X < cWordArray[intIndex].pt.X + szWord.Width
&& ptMouse.Y > cWordArray[intIndex].pt.Y
&& ptMouse.Y < cWordArray[intIndex].pt.Y + szWord.Height)
{
return cWordArray[intIndex];
}
}
if (intDir != intThisDir)
return null;
else
intIndex += intThisDir;
}
}
return null;
}
public Color TextBackGroundColor
{
set
{
clrBackground = value;
}
get
{
return clrBackground;
}
}
static public Size wordSize(classWordImage cWord)
{
switch (cWord.eWordImageType)
{
case enuWordImageType.vTab:
case enuWordImageType.hTab:
return new Size(intHTab, intVTab);
default:
return cWord.bmp.Size;
}
}
/// <chform>
/// plain, Chemical formula. The letters are plain font,
/// numbers but the numbers are subscript. This is mostly
/// subscript useful as a functional mark to pinpoint
/// chemicals.
public enum enuChemElementType { init, symbol, number }
/// <summary>
/// converts a string into classWordImage element with a single bitmap graphically depicting the formula and then appends the referenced classWordImage[] array
/// </summary>
/// <param name="udrWordImageArray">array to which the resultant image is appended</param>
/// <param name="strChemFormula">input string describing a chemical formula</param>
/// <param name="fntDefault">font used to display Chemical symbols</param>
static public void appendWordImage_ChemicalFormula(ref classWordImage[] udrWordImageArray, string strChemFormula, classMyFont fntDefault)
{
appendWordImage_ChemicalFormula(ref udrWordImageArray, strChemFormula, fntDefault, false);
}
static public void appendWordImage_ChemicalFormula(ref classWordImage[] udrWordImageArray, string strChemFormula, classMyFont fntDefault, bool bolRecurse)
{
/// create an empty classWordImage[] array to hold all the image which comprise the output image
classWordImage[] udrChemSymbols = new classWordImage[0];
int intCurrentChar = 0;
enuScript script = enuScript.normal;
/// - scan the string and cut off characters grouping them into symbols or numbers
/// - for each symbol collection e.g. 'Na' 'H' or unbroken number collection '2', '12'
/// create a classWordImage element appending it to the udrChemSymbols[] array
/// and setting the 'script' to 'normal' for symbols and 'sub'(subscript) for numbers
/// - when the entire formula has been scanned assemble them into one image
/// - create a new classWordImage element
/// - set its bitmap to the new image created by combining all symbol/number images
/// - append new classWordImage element to input parameter reference array & quit
while (intCurrentChar < strChemFormula.Length)
{
string strThisElement = "";
classMyFont fntNew = null;
if (intCurrentChar < strChemFormula.Length - 1
&& isAlpha(strChemFormula[intCurrentChar])
&& isAlpha(strChemFormula[intCurrentChar + 1])
&& isLowerCaseAlpha(strChemFormula[intCurrentChar + 1])
&& isChemSymbol(strChemFormula.Substring(intCurrentChar, 2)))
{
strThisElement = strChemFormula.Substring(intCurrentChar, 2);
script = enuScript.normal;
intCurrentChar += 2;
fntNew = fntDefault;
}
else if (isAlpha(strChemFormula[intCurrentChar])
&& isChemSymbol(strChemFormula.Substring(intCurrentChar, 1)))
{
strThisElement = strChemFormula.Substring(intCurrentChar, 1);
script = enuScript.normal;
intCurrentChar += 1;
fntNew = fntDefault;
}
else if (isANumber(strChemFormula[intCurrentChar]))
{
strThisElement = "";
while (intCurrentChar < strChemFormula.Length && isANumber(strChemFormula[intCurrentChar]))
{
strThisElement += strChemFormula.Substring(intCurrentChar, 1);
script = enuScript.sub;
intCurrentChar += 1;
}
int intNewSize = (int)((double)fntDefault.fnt.Size / 2.0);
if (intNewSize < 8)
intNewSize = 8;
fntNew = new classMyFont(new Font(fntDefault.fnt.FontFamily, intNewSize, fntDefault.fnt.Style), fntDefault.foreColor);
}
else if (strChemFormula[intCurrentChar] == '(')
{
int intNumOpen = 1, intNumClose = 0;
int intOpenChar = intCurrentChar;
while (intNumOpen != intNumClose && intCurrentChar < strChemFormula.Length)
{
intCurrentChar++;
if (strChemFormula[intCurrentChar] == '(') intNumOpen++;
if (strChemFormula[intCurrentChar] == ')') intNumClose++;
}
int intCloseChar = intCurrentChar;
if (intCloseChar > intOpenChar + 2)
{
appendArrayWordImage(ref udrChemSymbols, "(", fntDefault, enuWordPositionRelativeToPreviousWord.right, enuScript.normal, enuWordImageType.plain);
string strSubFormula = strChemFormula.Substring(intOpenChar + 1, intCloseChar - intOpenChar - 1);
classWordImage[] udrSubChemSymbols = new classWordImage[0];
appendWordImage_ChemicalFormula(ref udrSubChemSymbols, strSubFormula, fntDefault, true);
setWordImage(ref udrSubChemSymbols[0]);
udrSubChemSymbols[0].myPosRelToPrev = enuWordPositionRelativeToPreviousWord.right;
List<classWordImage> lWordImage = udrChemSymbols.ToList();
List<classWordImage> lSubWordImage = udrSubChemSymbols.ToList();
lWordImage.AddRange(lSubWordImage);
udrChemSymbols = lWordImage.ToArray();
//udrChemSymbols[udrChemSymbols.Length - 2].bmp.Save("c:\\temp\\formula.bmp");
appendArrayWordImage(ref udrChemSymbols, ")", fntDefault, enuWordPositionRelativeToPreviousWord.right, enuScript.normal, enuWordImageType.plain);
}
intCurrentChar++;
}
else
{
strThisElement = "";
}
if (strThisElement.Length > 0) appendArrayWordImage(ref udrChemSymbols, strThisElement, fntNew, enuWordPositionRelativeToPreviousWord.right, script, enuWordImageType.plain);
}
for (int intChemSymbolCounter = 0; intChemSymbolCounter < udrChemSymbols.Length; intChemSymbolCounter++)
{
setWordImage(ref udrChemSymbols[intChemSymbolCounter]);
}
udrChemSymbols[0].myPosRelToPrev = enuWordPositionRelativeToPreviousWord.NL;
Array.Resize<classWordImage>(ref udrWordImageArray, udrWordImageArray.Length + 1);
udrWordImageArray[udrWordImageArray.Length - 1] = new classWordImage();
udrWordImageArray[udrWordImageArray.Length - 1].strText = strChemFormula;
udrWordImageArray[udrWordImageArray.Length - 1].myPosRelToPrev = enuWordPositionRelativeToPreviousWord.right;
udrWordImageArray[udrWordImageArray.Length - 1].fnt = fntDefault;
udrWordImageArray[udrWordImageArray.Length - 1].script = enuScript.normal;
SizeF szf = g.MeasureString(strChemFormula, fntDefault.fnt);
Bitmap bmpSource = putImageArrayOntoBitmap((int)(szf.Width*1.5), udrChemSymbols);
int intClipTop = 7
+ (bolRecurse
? 2
: 0);
int intHeight = 27;
int intWidth = bmpSource.Width - 5;
Bitmap bmpFormula = new Bitmap(intWidth, intHeight);
using (Graphics gFormula = Graphics.FromImage(bmpFormula))
{
Rectangle recSrc = new Rectangle(0, intClipTop, bmpFormula.Width, bmpFormula.Height);
Rectangle recDest = new Rectangle(0, 0, bmpFormula.Width, bmpFormula.Height);
gFormula.DrawImage(bmpSource, recDest, recSrc, GraphicsUnit.Pixel);
}
udrWordImageArray[udrWordImageArray.Length - 1].bmp = bmpFormula;
//udrWordImageArray[udrWordImageArray.Length - 1].bmp.Save("c:\\temp\\formula.bmp");
udrWordImageArray[udrWordImageArray.Length - 1].bmp.MakeTransparent(udrWordImageArray[udrWordImageArray.Length - 1].bmp.GetPixel(0, 0));
szf = g.MeasureString("H", fntDefault.fnt);
udrWordImageArray[udrWordImageArray.Length - 1].intBaseline = (int)szf.Height;
}
static public Bitmap getImageChemicalFormula(string strFormula, Font fnt, Color clr) { return getImageChemicalFormula(strFormula, new classMyFont(fnt, clr)); }
static public Bitmap getImageChemicalFormula(string strFormula, classMyFont cFnt)
{
classWordImage[] udrWordImage = new classWordImage[0];
appendWordImage_ChemicalFormula(ref udrWordImage, strFormula, cFnt);
return udrWordImage[0].bmp;
}
static public bool isChemSymbol(string strCS)
{
/// udrChemSymbols as two arrays of strings
/// [0] has all one character chemical symbols
/// [1] has all two character chemical symbols
/// -> use the array which corresponds to the size of the input string 'strCS'
string[] strSymbols = udrChemSymbols[strCS.Length - 1].Symbols;
/// chemical symbols are ordered alphabetically
/// jump up/down the list halfing the distance last jumped(intStepSize = intStepSize/2) as long as intStepSize >1
int intStepSize = strSymbols.Length;
int intIndex = 0;
int intCompareResult = 0;
while (intStepSize > 1)
{
intStepSize = (int)Math.Floor((double)intStepSize / 2);
intCompareResult = strCS.CompareTo(strSymbols[intIndex]);
if (intCompareResult > 0)
intIndex += intStepSize;
else if (intCompareResult < 0)
intIndex -= intStepSize;
else
return true;
}
// step by one in appropriate direction until find or quit
if (intCompareResult > 0)
{
while (intCompareResult > 0 && intIndex >= 0)
{
intCompareResult = strCS.CompareTo(strSymbols[intIndex]);
if (intCompareResult > 0)
intIndex += intStepSize;
else if (intCompareResult < 0)
intIndex -= intStepSize;
else
return true;
}
}
else
{
while (intCompareResult < 0 && intIndex < strSymbols.Length)
{
intCompareResult = strCS.CompareTo(strSymbols[intIndex]);
if (intCompareResult > 0)
intIndex += intStepSize;
else if (intCompareResult < 0)
intIndex -= intStepSize;
else
return true;
}
}
return false;
}
static public bool isANumber(char c) { return (c >= '0' && c <= '9'); }
static public bool isAlpha(char c) { return (strAlpha.Contains(c)); }
static public bool isLowerCaseAlpha(char c) { return (strAlpha.Substring(0, strAlpha.Length / 2).Contains(c)); }
/// <summary>
/// creates new WordImage element, inserts it into empty array and returns result
/// </summary>
/// <param name="strText">text for new element</param>
/// <param name="fnt">font for new element</param>
/// <param name="script">script of new element</param>
/// <returns>classWordImage element</returns>
static public classWordImage[] getWordImageArray(string strText, classMyFont fnt, enuScript script)
{
classWordImage[] udrRetVal = new classWordImage[0];
return getWordImageArray(ref udrRetVal, strText, fnt, script);
}
/// <summary>
/// creates a new classWordImage element and appends it to referenced array then returns referenced array
/// </summary>
/// <param name="udrWordImageArray">array to which new element will be appended</param>
/// <param name="strText">text of new element</param>
/// <param name="fnt">font of new element</param>
/// <param name="script">script of new element</param>
/// <returns>input reference array with new element appended to it</returns>
static public classWordImage[] getWordImageArray(ref classWordImage[] udrWordImageArray, string strText, classMyFont fnt, enuScript script)
{
appendArrayWordImage(ref udrWordImageArray, strText, fnt, enuWordPositionRelativeToPreviousWord.NL, script, enuWordImageType.plain);
return udrWordImageArray;
}
/// <summary>
/// creates a new classWordImage element and appends it to referenced array then returns referenced array
/// </summary>
/// <param name="udrWordImageArray">array to which new element will be appended</param>
/// <param name="strText">text of new element</param>
/// <param name="fnt">font of new element</param>
/// <param name="PosFirstWordRelToPrev">position of new element relative to the previous</param>
/// <param name="script">script of new element</param>
static public void appendArrayWordImage(ref classWordImage[] udrWordImages, string strText, classMyFont fnt, enuWordPositionRelativeToPreviousWord PosFirstWordRelToPrev, enuScript script, enuWordImageType wordTypeForEntireString)
{ appendArrayWordImage(ref udrWordImages, strText, fnt, PosFirstWordRelToPrev, script, wordTypeForEntireString, ""); }
/// <summary>
/// creates a new classWordImage element and appends it to referenced array then returns referenced array
/// </summary>
/// <param name="udrWordImageArray">array to which new element will be appended</param>
/// <param name="strText">text of new element</param>
/// <param name="fnt">font of new element</param>
/// <param name="PosFirstWordRelToPrev">position of new element relative to the previous</param>
/// <param name="script">script of new element</param>
/// <param name="strAddress">only necessary if the wordTypeForEntireString is 'link'</param>
static public void appendArrayWordImage(ref classWordImage[] udrWordImages, string strText, classMyFont fnt, enuWordPositionRelativeToPreviousWord PosFirstWordRelToPrev, enuScript script, enuWordImageType wordTypeForEntireString, string strAddress)
{
string[] strParagraphs = strText.Split("\r\n".ToCharArray());
if (strText.Length == 0)
return;
foreach (string strParagraph in strParagraphs)
{
string[] strWords = divideStringIntoWords(strParagraph);
for (int intWordCounter = 0; intWordCounter < strWords.Length; intWordCounter++)
{
if (strWords != null
&& intWordCounter < strWords.Length
&& strWords[intWordCounter] != null
&& strWords[intWordCounter][0] == '\t')
{
Array.Resize<classWordImage>(ref udrWordImages, udrWordImages.Length + 1);
udrWordImages[udrWordImages.Length - 1] = new classWordImage();
udrWordImages[udrWordImages.Length - 1].myPosRelToPrev = enuWordPositionRelativeToPreviousWord.right;
udrWordImages[udrWordImages.Length - 1].eWordImageType = enuWordImageType.hTab;
setWordImage(ref udrWordImages[udrWordImages.Length - 1]);
}
else if (strWords[intWordCounter] != null)
{
Array.Resize<classWordImage>(ref udrWordImages, udrWordImages.Length + 1);
udrWordImages[udrWordImages.Length - 1] = new classWordImage();
udrWordImages[udrWordImages.Length - 1].strText = strWords[intWordCounter];
udrWordImages[udrWordImages.Length - 1].myPosRelToPrev = (intWordCounter == 0) ? PosFirstWordRelToPrev : enuWordPositionRelativeToPreviousWord.right;
udrWordImages[udrWordImages.Length - 1].fnt = fnt;
udrWordImages[udrWordImages.Length - 1].script = script;
udrWordImages[udrWordImages.Length - 1].eWordImageType = wordTypeForEntireString;
if (wordTypeForEntireString == enuWordImageType.link
|| wordTypeForEntireString == enuWordImageType.solution
|| wordTypeForEntireString == enuWordImageType.flash)
udrWordImages[udrWordImages.Length - 1].strAddress = strAddress;
setWordImage(ref udrWordImages[udrWordImages.Length - 1]);
}
}
}
}
static public void appendArrayWordImage_withImage(ref classWordImage[] udrWordImages, Bitmap bmpSourceImage, string strText)
{
Array.Resize<classWordImage>(ref udrWordImages, udrWordImages.Length + 1);
udrWordImages[udrWordImages.Length - 1] = new classWordImage();
udrWordImages[udrWordImages.Length - 1].strText = strText;
udrWordImages[udrWordImages.Length - 1].myPosRelToPrev = enuWordPositionRelativeToPreviousWord.NL;
udrWordImages[udrWordImages.Length - 1].bmp = bmpSourceImage;
udrWordImages[udrWordImages.Length - 1].eWordImageType = enuWordImageType.image;
setWordImage(ref udrWordImages[udrWordImages.Length - 1]);
}
#region "get image for word"
static public Bitmap getWordImage(string strWord, Font fnt, Color clr) { return getWordImage(strWord, new classMyFont(fnt, clr)); }
static public Bitmap getWordImage(string strWord, classMyFont cgrFont)
{
classWordImage cWordImage = new classWordImage();
cWordImage.strText = strWord;
cWordImage.fnt = cgrFont;
setWordImage(ref cWordImage);
return cWordImage.bmp;
}
static public void setWordImage(ref classWordImage udrWordImage)
{
if (udrWordImage.bmp != null)
return;
if (udrWordImage.strText == null || udrWordImage.strText.Length == 0) return;
// rectangle for quote
if(false && (udrWordImage.strText == null || udrWordImage.strText.Length == 0))
{
udrWordImage.bmp = new Bitmap(1, 1);
return;
}
if (false && WordSetInBinTree(ref udrWordImage))
return;
SizeF szf = g.MeasureString(udrWordImage.strText, udrWordImage.fnt.fnt);
Rectangle quoteRect = new Rectangle(0,
0,
(int)szf.Width
+ (int)(udrWordImage.fnt.fnt.Height * .5)
+ (udrWordImage.fnt.fnt.Italic ? (int)(udrWordImage.fnt.fnt.Height * .3) : 0)
+ (udrWordImage.fnt.fnt.Bold ? (int)(udrWordImage.fnt.fnt.Height * .2) : 0),
(int)(szf.Height * 1.3));
// create a new bitmap that contains both the quote and the author text
Bitmap bmpTemp = new Bitmap(quoteRect.Width, quoteRect.Height);
using (Graphics gText = Graphics.FromImage(bmpTemp))
{
// set the text rendering characteristics
gText.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gText.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
// draw the text
TextRenderer.DrawText(gText,
udrWordImage.strText,
udrWordImage.fnt.fnt,
new Point(quoteRect.X + 5,
quoteRect.Y),
udrWordImage.fnt.foreColor,
Color.White,
TextFormatFlags.Default | TextFormatFlags.NoPrefix);
}
bmpTemp.MakeTransparent(Color.White);
int intLeftCut = 7;
int intWidth = bmpTemp.Width - intLeftCut;
if (intWidth <= 0)
intWidth = 1;
udrWordImage.bmp = new Bitmap(intWidth, bmpTemp.Height);
using (Graphics gText = Graphics.FromImage(udrWordImage.bmp))
{
Rectangle rectDest = new Rectangle(0, 0, wordSize(udrWordImage).Width , udrWordImage.bmp.Height);
Rectangle rectSrc = new Rectangle(intLeftCut, 0, wordSize(udrWordImage).Width, udrWordImage.bmp.Height);
gText.DrawImage(bmpTemp, rectDest, rectSrc, GraphicsUnit.Pixel);
}
udrWordImage.intBaseline = udrWordImage.bmp.Height;
}
/// <summary>
/// tests if the word's image at required font, and forecolor exists in the wordimage_BinTree
/// creates a pointer to input referenced wordImage element including it into the tree if there is none
/// - word images found in the tree are used instead of rebuilding them
/// - when images are not found here the calling function creates new images which the binary-tree already points to and can later return for reuse
/// </summary>
/// <param name="wordImage">referenced classWordImage element before a bitmap has been created</param>
/// <returns>true if an image already exists, false if a new image needs to be created</returns>
static public bool WordSetInBinTree(ref classWordImage wordImage)
{
//return false;
classWordImage wiThis = WordImage_BinTree;
if (wiThis == null)
{
WordImage_BinTree = wordImage;
return false;
}
else
{
while (true)
{
if (wordImage.strText.CompareTo(wiThis.strText) > 0)
{
if (wiThis.Search.right != null)
wiThis = wiThis.Search.right;
else
{
wiThis.Search.right = wordImage;
return false;
}
}
else if (wordImage.strText.CompareTo(wiThis.strText) < 0)
{
if (wiThis.Search.left != null)
wiThis = wiThis.Search.left;
else
{
wiThis.Search.left = wordImage;
return false;
}
}
else
{
while (true)
{
if (FontsAreTheSame(wiThis, wordImage))
{
wordImage.bmp = wiThis.bmp;
wordImage.intBaseline = wiThis.intBaseline;
return true;
}
else
{
if (wiThis.Search.next != null)
wiThis = wiThis.Search.next;
else
{
wiThis.Search.next = wordImage;
wordImage.intBaseline = wiThis.intBaseline;
return false;
}
}
}
}
}
}
}
static public bool FontsAreTheSame(classWordImage WI_A, classWordImage WI_B)
{
return (WI_A.fnt.fnt.Style == WI_B.fnt.fnt.Style
&& WI_A.fnt.fnt.Size == WI_B.fnt.fnt.Size
&& WI_A.fnt.fnt.FontFamily == WI_B.fnt.fnt.FontFamily
&& WI_A.fnt.foreColor == WI_B.fnt.foreColor
&& WI_A.eWordImageType == WI_B.eWordImageType);
}
#endregion
/// <summary>
/// takes input string and returns an array of strings keeping punctuation marks and non-alphabetical characters at the end of series of alphabetical characters
/// </summary>
/// <param name="strText">input text to be parsed into 'words'</param>
/// <returns>array of 'words' with punctuation after alpha-characters, all words start with alpha and may or may not have punctuations at end including spaces</returns>
static public string[] divideStringIntoWords(string strText)
{
string[] strRetVal = new string[1];
string strText_LowerCase = strText.ToLower()
.Replace("'", "A")
.Replace(".", "A")
.Replace("\"", "A")
.Replace("\\", "A")
.Replace("/", "A")
.Replace("?", "A")
.Replace("!", "A")
.Replace("$", "A")
.Replace("%", "A")
.Replace("(", "A")
.Replace(")", "A")
.Replace("[", "A")
.Replace("]", "A")
.Replace("{", "A")
.Replace("}", "A")
.Replace(",", "A")
.Replace("-", "A"); // the chars replaced will be force-drawn at end of word
bool bolFoundPunctuation = false;
bool bolThisCharPunctuation = false;
for (int intCharCounter = 0; intCharCounter < strText.Length; intCharCounter++)
{
if (strText_LowerCase[intCharCounter] == '\t')
{
strRetVal[strRetVal.Length - 1] = '\t'.ToString();
Array.Resize<string>(ref strRetVal, strRetVal.Length + 1);
bolFoundPunctuation = false;
}
else
{
bolThisCharPunctuation = !strAlpha.Contains(strText_LowerCase[intCharCounter]);
bolFoundPunctuation = bolFoundPunctuation || bolThisCharPunctuation;
if (bolFoundPunctuation && !bolThisCharPunctuation)
{
// new word
Array.Resize<string>(ref strRetVal, strRetVal.Length + 1);
bolFoundPunctuation = false;
}
strRetVal[strRetVal.Length - 1] += strText[intCharCounter];
}
}
return strRetVal;
}
/// <summary>
/// given the width of output image and an array of classWordImage[]s, this function juxtaposes all the input images into the shortest bitmap with prescribed input width
/// </summary>
/// <param name="intWidth">width of output image</param>
/// <param name="cWordArray">array of classWordImage elements to be drawn onto a single bitmap</param>
/// <returns>a bitmap comprised of images in input classWordImage[] array</returns>
static public Bitmap putImageArrayOntoBitmap(int intWidth, classWordImage[] cWordArray)
{
udrLines = new classWordImageLine[0];
return putImageArrayOntoBitmap(intWidth, cWordArray, ref udrLines);
}
static public Bitmap putImageArrayOntoBitmap(int intWidth, classWordImage[] cWordArray, ref classWordImageLine[] udrLines) { return putImageArrayOntoBitmap(intWidth, cWordArray, ref udrLines, false); }
static public Bitmap putImageArrayOntoBitmap(int intWidth, classWordImage[] cWordArray, ref classWordImageLine[] udrLines, bool bolSingleLine)
{
if (intWidth < 10 && !bolSingleLine)
return null ;
if (bolSingleLine) intWidth = Screen.PrimaryScreen.WorkingArea.Width;
/// - measure height or required return bitmap
/// - scan list
/// - all images on same height from top of bitmap will be placed on a line common to each word bitmap's bottom edge
/// - measure width of sum of word images that fit onto a single line
/// - for each line, keep track of the tallest word-image
/// vars:
/// int bottomedge of previous line
/// int tallest word-image on this line
/// -> bottomedge of this line = bottomEdgeOfPrevLine + tallestWordImageOnThisLine
/// - draw words onto bmp
///
if (cWordArray == null || cWordArray.Length == 0)
return null;
int intVerticalLineGap = 5;
int intMeasuredWidth = 0;
bool bolLastWordVtab = false;
for (int intWordCounter = 0; intWordCounter < cWordArray.Length; intWordCounter++)
{
if (udrLines.Length > 0)
{
if (udrLines[udrLines.Length - 1].intWidth + 20 > intMeasuredWidth)
intMeasuredWidth = udrLines[udrLines.Length - 1].intWidth + 20;
}
if (cWordArray[intWordCounter].eWordImageType == enuWordImageType.vTab )
{
bolLastWordVtab = true;
Array.Resize<classWordImageLine>(ref udrLines, udrLines.Length + 1);
udrLines[udrLines.Length - 1] = new classWordImageLine();
udrLines[udrLines.Length - 1].Word = new classWordImage[1];
udrLines[udrLines.Length - 1].Word[0] = cWordArray[intWordCounter];
udrLines[udrLines.Length - 1].intWidth = 0;
udrLines[udrLines.Length - 1].intBottomEdgePos = udrLines[udrLines.Length - 1].intHeight = (udrLines.Length > 1) ? udrLines[udrLines.Length - 2].intBottomEdgePos + intVTab : intVTab;
}
else if((cWordArray[intWordCounter].myPosRelToPrev == enuWordPositionRelativeToPreviousWord.NL
&& (!bolLastWordVtab
|| cWordArray[intWordCounter].eWordImageType == enuWordImageType.image))
|| (udrLines != null
&& udrLines.Length > 0
&& udrLines[udrLines.Length - 1].intWidth
+ wordSize(cWordArray[intWordCounter]).Width
> intWidth))
{ // create a new line
bolLastWordVtab = false;
Array.Resize<classWordImageLine>(ref udrLines, udrLines.Length + 1);
udrLines[udrLines.Length - 1] = new classWordImageLine();
udrLines[udrLines.Length - 1].Word = new classWordImage[1];
udrLines[udrLines.Length - 1].Word[0] = cWordArray[intWordCounter];
if (cWordArray[intWordCounter].eWordImageType == enuWordImageType.image)
{
double dblAspectRatio = (double)cWordArray[intWordCounter].bmp.Height / (double)wordSize( cWordArray[intWordCounter]).Width;
udrLines[udrLines.Length -1].intWidth = (intWidth - 10 >wordSize( cWordArray[intWordCounter]).Width) ?wordSize( cWordArray[intWordCounter]).Width : intWidth - 10;
// create image for caption given the width of the image when displayed on this form.
classWordImage[] cCaptionArray = new classWordImage[0];
appendArrayWordImage(ref cCaptionArray,
cWordArray[intWordCounter].strText,
new classMyFont(new Font("ms sans-serif", 10), Color.Gray),
enuWordPositionRelativeToPreviousWord.NL,
enuScript.normal,
enuWordImageType.plain);
classWordImageLine[] udrCaptionLines = new classWordImageLine[0];
cWordArray[intWordCounter].bmpCaption = putImageArrayOntoBitmap(udrLines[udrLines.Length - 1].intWidth, cCaptionArray, ref udrCaptionLines);
udrLines[udrLines.Length - 1].intHeight = (int)(udrLines[udrLines.Length - 1].intWidth * dblAspectRatio)
+ cWordArray[intWordCounter].bmpCaption.Height
+ intVerticalLineGap;
cWordArray[intWordCounter].intBaseline = udrLines[udrLines.Length - 1].intHeight;
udrLines[udrLines.Length - 1].intBottomEdgePos = (udrLines.Length > 1 ?
udrLines[udrLines.Length - 2].intBottomEdgePos + udrLines[udrLines.Length - 1].intHeight
:
udrLines[udrLines.Length - 1].intHeight);
// debug-here -> line width of next line is in error after an image
Array.Resize<classWordImageLine>(ref udrLines, udrLines.Length + 1);
udrLines[udrLines.Length - 1] = new classWordImageLine();
udrLines[udrLines.Length - 1].Word = new classWordImage[0];
udrLines[udrLines.Length - 1].intBottomEdgePos = (udrLines.Length > 1 ?
udrLines[udrLines.Length - 2].intBottomEdgePos + udrLines[udrLines.Length - 1].intHeight
:
udrLines[udrLines.Length - 1].intHeight);
}
else
{
udrLines[udrLines.Length - 1].intWidth =wordSize( cWordArray[intWordCounter]).Width;
udrLines[udrLines.Length - 1].intHeight = cWordArray[intWordCounter].intBaseline + intVerticalLineGap;
udrLines[udrLines.Length - 1].intBottomEdgePos = (udrLines.Length > 1 ?
udrLines[udrLines.Length - 2].intBottomEdgePos
:
0)
+ udrLines[udrLines.Length - 1].intHeight;
}
}
else
{ // add this word to the current line
bolLastWordVtab = false;
if (udrLines.Length ==0)
{
udrLines = new classWordImageLine[1];
udrLines[0] = new classWordImageLine();
udrLines[0].Word = new classWordImage[0];
}
udrLines[udrLines.Length - 1].intWidth += wordSize(cWordArray[intWordCounter]).Width;
if (udrLines[udrLines.Length - 1].intHeight + intVerticalLineGap < cWordArray[intWordCounter].intBaseline)
{
udrLines[udrLines.Length - 1].intHeight = cWordArray[intWordCounter].intBaseline + intVerticalLineGap;
udrLines[udrLines.Length - 1].intBottomEdgePos = (udrLines.Length > 1 ? udrLines[udrLines.Length - 2].intBottomEdgePos : 0)
+ udrLines[udrLines.Length - 1].intHeight;
}
udrLines[udrLines.Length - 1].bolHasSubscript = udrLines[udrLines.Length - 1].bolHasSubscript || (cWordArray[intWordCounter].script == enuScript.sub);
udrLines[udrLines.Length - 1].bolHasSuperscript = udrLines[udrLines.Length - 1].bolHasSuperscript || (cWordArray[intWordCounter].script == enuScript.super);
Array.Resize<classWordImage>(ref udrLines[udrLines.Length - 1].Word, udrLines[udrLines.Length - 1].Word.Length + 1);
udrLines[udrLines.Length - 1].Word[udrLines[udrLines.Length - 1].Word.Length - 1] = cWordArray[intWordCounter];
}
}
if (bolSingleLine) intWidth = intMeasuredWidth;
Bitmap bmp = new Bitmap(intWidth,
udrLines[udrLines.Length - 1].intBottomEdgePos
+ (udrLines[udrLines.Length - 1].bolHasSubscript ? (int)(udrLines[udrLines.Length - 1].intHeight * .3) : 0)
+ (udrLines[udrLines.Length - 1].bolHasSubscript ? (int)(udrLines[udrLines.Length - 1].intHeight * .3) : 0)
+ 25);
using (Graphics g = Graphics.FromImage(bmp))
{
g.FillRectangle(new SolidBrush(clrBackground), new Rectangle(0, 0, bmp.Width, bmp.Height));
for (int intLineCounter = 0; intLineCounter < udrLines.Length; intLineCounter++)
{
int intLeftNextWord = 0;
for (int intWordCounter = 0; intWordCounter < udrLines[intLineCounter].Word.Length; intWordCounter++)
{
int intDestTop = udrLines[intLineCounter].intBottomEdgePos - udrLines[intLineCounter].Word[intWordCounter].intBaseline;
udrLines[intLineCounter].Word[intWordCounter].intLine = udrLines[intLineCounter].intBottomEdgePos;
if (udrLines[intLineCounter].Word[intWordCounter].eWordImageType == enuWordImageType.image)
{
Size szWord = wordSize(udrLines[intLineCounter].Word[intWordCounter]);
double dblAspectRatio = (double)szWord.Height / (double)szWord.Width;
int intImageWidth = (bmp.Width -10 >szWord.Width)? szWord.Width : bmp.Width - 10;
udrLines[intLineCounter].Word[intWordCounter].pt = new Point((bmp.Width - intImageWidth )/2, intDestTop);
int intImageHeight = (int)(intImageWidth * dblAspectRatio);
Rectangle rectDest = new Rectangle(udrLines[intLineCounter].Word[intWordCounter].pt.X, udrLines[intLineCounter].Word[intWordCounter].pt.Y, intImageWidth, intImageHeight);
Rectangle rectSrc = new Rectangle(0, 0, szWord.Width , szWord.Height);
g.DrawImage(udrLines[intLineCounter].Word[intWordCounter].bmp,
rectDest,
rectSrc,
GraphicsUnit.Pixel);
rectDest = new Rectangle(udrLines[intLineCounter].Word[intWordCounter].pt.X,
udrLines[intLineCounter].Word[intWordCounter].pt.Y + intImageHeight,
udrLines[intLineCounter].Word[intWordCounter].bmpCaption.Width,
udrLines[intLineCounter].Word[intWordCounter].bmpCaption.Height);
rectSrc = new Rectangle(0,
0,
udrLines[intLineCounter].Word[intWordCounter].bmpCaption.Width,
udrLines[intLineCounter].Word[intWordCounter].bmpCaption.Height);
g.DrawImage(udrLines[intLineCounter].Word[intWordCounter].bmpCaption,
rectDest,
rectSrc,
GraphicsUnit.Pixel);
intDestTop = udrLines[intLineCounter].Word[intWordCounter].pt.Y + intImageHeight + rectDest.Height;
}
else
{
switch (udrLines[intLineCounter].Word[intWordCounter].script)
{
case enuScript.super:
if (intWordCounter > 0)
intDestTop = udrLines[intLineCounter].intBottomEdgePos
- udrLines[intLineCounter].Word[intWordCounter - 1].bmp.Height
- (int)(udrLines[intLineCounter].Word[intWordCounter].bmp.Height * .5);
break;
case enuScript.sub:
intDestTop = udrLines[intLineCounter].intBottomEdgePos
- (int)(udrLines[intLineCounter].Word[intWordCounter].fnt.fnt.Size * 1.5);
break;
}
if (udrLines[intLineCounter].Word[intWordCounter].eWordImageType == enuWordImageType.hTab)
{
intLeftNextWord += intHTab;
udrLines[intLineCounter].Word[intWordCounter].pt = new Point(intLeftNextWord, intDestTop);
}
else if (udrLines[intLineCounter].Word[intWordCounter].eWordImageType == enuWordImageType.vTab)
{
udrLines[intLineCounter].Word[intWordCounter].pt = new Point(intLeftNextWord, intDestTop);
udrLines[intLineCounter].intBottomEdgePos = (intLineCounter > 0) ? udrLines[intLineCounter - 1].intBottomEdgePos + intVTab : intVTab;
}
else
{
Rectangle rectDest = new Rectangle(intLeftNextWord, intDestTop, udrLines[intLineCounter].Word[intWordCounter].bmp.Width, udrLines[intLineCounter].Word[intWordCounter].bmp.Height);
Rectangle rectSrc = new Rectangle(0, 0, udrLines[intLineCounter].Word[intWordCounter].bmp.Width, udrLines[intLineCounter].Word[intWordCounter].bmp.Height);
g.DrawImage(udrLines[intLineCounter].Word[intWordCounter].bmp,
rectDest,
rectSrc,
GraphicsUnit.Pixel);
udrLines[intLineCounter].Word[intWordCounter].pt = rectDest.Location;
int intItalicLeftShift = udrLines[intLineCounter].Word[intWordCounter].fnt.fnt.Italic
? (int)((double)udrLines[intLineCounter].Word[intWordCounter].fnt.fnt.Size * .5)
: 0;
intLeftNextWord += udrLines[intLineCounter].Word[intWordCounter].bmp.Width - intItalicLeftShift;
}
}
}
}
}
return bmp;
}
}
public enum enuScript { normal, super, sub }
public struct udtWordImageSearchData
{
public classWordImage right;
public classWordImage left;
public classWordImage next;
}
/// <summary>
/// word image description including text, position relative to previous word on page, font, and pt (the image's location on final bitmap used by getWordUnderMouse())
/// </summary>
public enum enuWordImageType {
plain, //
link, // underlined text causes mouse cursor to change -> linked to strAddress controlled by main form
image, // flexible image size, takes up its own line, maintains aspect-ratio but grows to fit containing panel
solution, // like a link but pops up 'strAddress' as text
flash,
vTab,
hTab
}
public class classWordImage
{
public Bitmap bmp;
public Bitmap bmpCaption;
public enuWordImageType eWordImageType;
public enuWordPositionRelativeToPreviousWord myPosRelToPrev;
public classMyFont fnt;
public string strText;
public string strAddress;
public int intBaseline; // top of image relative to the horizontal line common to all images on the same line of text on output bitmap
public int intLine; // y-component on which 'bottom line edge' is common to every word on this line pt.y = intBottomEdgePos - intBaseline
public enuScript script;
public udtWordImageSearchData Search; // bin-tree search fields
public Point pt; // position of this word's bitmap on the output image
static int intUniqueIDCounter = 0;
public int intUniqueID;
public classWordImage()
{
intUniqueID = intUniqueIDCounter++;
}
}
/// <summary>
/// font with forecolor variable
/// </summary>
public class classMyFont
{
public Font fnt;
public Color foreColor;
public classMyFont(Font fntNew, Color clr)
{
fnt = fntNew;
foreColor = clr;
}
}
/// <summary>
/// panel with image controlled by vertical scroll bar
/// </summary>
public class Panel_GraphicText : Panel
{
public VScrollBar vsb = new VScrollBar();
int intOverHead = 5;
public PictureBox pic = new PictureBox();
classGraphicText cLibGrText;
public classWordImage[] cWordArray;
public string strTitle = "Search Results : ";
public Point ptMouse;
public bool bolQuitOnEscape = false;
public TextBox txtControls = new TextBox();
int intPicWidth_Narrow = 0;
int intPicWidth_Wide = 0;
public Panel_GraphicText()
{
Controls.Add(pic);
pic.Visible = true;
pic.Location = new Point(0, 0);
BackColor = Color.White;
Controls.Add(vsb);
vsb.Maximum = 1000;
Controls.Add(txtControls);
txtControls.Top = -100;
txtControls.KeyDown += new KeyEventHandler(txtControls_KeyDown);
txtControls.MouseWheel += new MouseEventHandler(_MouseWheel);
pic.GotFocus += new EventHandler(pic_GotFocus);
cWordArray = new classWordImage[0];
intPicWidth_Wide = Width -5;
intPicWidth_Narrow = intPicWidth_Wide - vsb.Width;
vsb.ValueChanged += new EventHandler(vsb_ValueChanged);
SizeChanged += new EventHandler(Form_GraphicText_SizeChanged);
MouseWheel += new MouseEventHandler(_MouseWheel);
pic.MouseWheel += new MouseEventHandler(_MouseWheel);
pic.MouseMove += new MouseEventHandler(pic_MouseMove);
Text = strTitle;
cLibGrText = new classGraphicText();
}
void pic_GotFocus(object sender, EventArgs e)
{
txtControls.Focus();
}
void txtControls_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Escape:
break;
}
}
public Color textBackGround
{
get
{
return GraphicText.classGraphicText.clrBackground;
}
set
{
GraphicText.classGraphicText.clrBackground = value;
}
}
void pic_MouseMove(object sender, MouseEventArgs e)
{
ptMouse = new Point(e.X, e.Y);
}
/// <summary>
/// returns the classWordImage located beneath the current mousepointer on the picbox's image
/// </summary>
/// <returns>classWordImage beneath the mouse or null if none found</returns>
public classWordImage getWordUnderMouse()
{
int intStepSize = cWordArray.Length;
int intIndex = 0;
while (intStepSize > 1 && intIndex < cWordArray.Length && intIndex >= 0)
{
intStepSize = (int)Math.Ceiling((double)intStepSize / 2);
if (ptMouse.Y > cWordArray[intIndex].pt.Y + cWordArray[intIndex].intBaseline)
intIndex += intStepSize;
else if (ptMouse.Y < cWordArray[intIndex].pt.Y)
intIndex -= intStepSize;
else
break;
}
int intDir = -1;
if (intIndex >= 0 && intIndex < cWordArray.Length)
{
if (ptMouse.X > cWordArray[intIndex].pt.X)
intDir = 1;
int intThisDir = 0;
while (intIndex >= 0
&& intIndex < cWordArray.Length)
{
if (ptMouse.X > cWordArray[intIndex].pt.X + cWordArray[intIndex].bmp.Width)
intThisDir = 1;
else if (ptMouse.X < cWordArray[intIndex].pt.X)
intThisDir = -1;
else
{
if (ptMouse.X > cWordArray[intIndex].pt.X
&& ptMouse.X < cWordArray[intIndex].pt.X + cWordArray[intIndex].bmp.Width
&& ptMouse.Y > cWordArray[intIndex].pt.Y
&& ptMouse.Y < cWordArray[intIndex].pt.Y + cWordArray[intIndex].bmp.Height)
{
return cWordArray[intIndex];
}
}
if (intDir != intThisDir)
return null;
else
intIndex += intThisDir;
}
}
return null;
}
public void _MouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta > 0)
{
if (vsb.Value - vsb.SmallChange >= vsb.Minimum)
vsb.Value -= vsb.SmallChange;
else
vsb.Value = vsb.Minimum;
}
else
{
if (vsb.Value + vsb.SmallChange <= vsb.Maximum - vsb.LargeChange)
vsb.Value += vsb.SmallChange;
else
vsb.Value = vsb.Maximum - vsb.LargeChange;
}
}
public void setTitle(string strText)
{
Text = strTitle + "\"" + strText + "\"";
}
public void Form_GraphicText_SizeChanged(object sender, EventArgs e)
{
setVSB();
intPicWidth_Wide = Width - 5;
intPicWidth_Narrow = vsb.Left;
if (vsb.Visible)
pic.Width = intPicWidth_Narrow;
else
pic.Width = intPicWidth_Wide;
putWordArrayToScreen();
}
void setVSB()
{
vsb.Height = Height - vsb.Top - intOverHead;
if (vsb.Height < 1)
return;
try
{
vsb.Top = 5;
vsb.Left = Width - vsb.Width;
vsb.Visible = (pic.Height > Height - intOverHead);
vsb.LargeChange = (int)(((double)(Height - intOverHead) / (double)pic.Height) * 1000.0);
if (vsb.LargeChange > vsb.Maximum)
vsb.LargeChange = vsb.Maximum;
vsb.SmallChange = (int)Math.Ceiling((double)vsb.LargeChange / 8.0);
vsb.Value = 0;
}
catch (Exception) { }
}
void vsb_ValueChanged(object sender, EventArgs e)
{
int intHighest = Height - intOverHead - pic.Height;
int intLowest = 0;
int intDifference = (intHighest - intLowest);
if (vsb.Maximum == vsb.LargeChange)
pic.Top = 0;
else
{
double dblRatio = (double)vsb.Value / (double)(vsb.Maximum - vsb.LargeChange);
pic.Top = (int)((double)intDifference * dblRatio);
}
}
public void putWordArrayToScreen()
{
int intWidthPic = intPicWidth_Wide;
startPutWordArrayToScreen:
Bitmap bmp = GraphicText.classGraphicText.putImageArrayOntoBitmap(intWidthPic, cWordArray);
if (bmp != null)
{
pic.Size = bmp.Size;
pic.Image = bmp;
pic.BringToFront();
pic.Visible = true;
setVSB();
if (vsb.Visible && pic.Width == intPicWidth_Wide)
{
intWidthPic = intPicWidth_Narrow;
goto startPutWordArrayToScreen;
}
}
Visible = true;
vsb.Value = 0;
BringToFront();
}
}
/// <summary>
/// form with panel_graphic_text, image & vertical scroll bar
/// </summary>
public class Form_GraphicText : Form
{
bool bolInit = false;
public Panel_GraphicText pnl;
public bool bolQuitOnEscape = false;
public Form_GraphicText()
{
Visible = false;
pnl = new Panel_GraphicText();
Controls.Add(pnl);
pnl.Dock = DockStyle.Fill;
bolQuitOnEscape = true;
Activated += new EventHandler(Form_GraphicText_Activated);
KeyDown += new KeyEventHandler(Form_GraphicText_KeyDown);
Opacity = 1.0;
}
void Form_GraphicText_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Enter:
break;
case Keys.Escape:
if (bolQuitOnEscape)
Dispose();
break;
}
}
void Form_GraphicText_Activated(object sender, EventArgs e)
{
if (!bolInit)
{
bolInit = true;
Size = new Size(400, 600);
Location = new Point(0, 0);
}
}
}
}