Thanks, Parnell. When I was looking through the forum I found an old post of yours
I know no JavaScript whatsoever, so many of the contributions submitted, however much appreciated, were really over my head. But I took to heart your idea to just stay within the Xojo framework and work with a canvas and draw strings there.
Your suggestion to put a rectangle behind the text to be highlighted with a background color was also key. I would note that my idea of an invisible canvas (to capture the MouseDown event) over the HTMLViewer was actually working. Parnell said bluntly that was a bad idea, but did not elaborate. I am curious why it is considered a bad idea.
I ultimately created a subclass of Canvas. The subclass has three properties:
lengthHighlight (the length of the word which was to be highlighted - 7 in the example)
startHighlight (the position in the string where the highlighted word started - 27 in the example)
theString (the string that was to be displayed -Maloney in the example)
This is what the Canvas displays:
Now that it is a simple Canvas, rather than an HTMLViewer, I can capture the MouseDown event
For future me and others who might like to see the implementation, I include the code that is in the paint event of the Canvas. The exact position of the highlight rectangle has to be adjusted to deal with descenders. the “bottom” of text is at the level of the bottom of characters that do not have descenders. The background rectangle has to be pushed down a little to highlight the descenders. I apologize in advance for any coding clumsiness.
The part of the string that is to be highlighted is shown in a slightly larger font size and with a background color as seen in the image.
[code]Var theString As String = Me.theString
Var theStart As Integer = Me.startHighlight
Var theLength As Integer = Me.lenghHighlight
Var lengthEntire As Integer = theString.Length
// to do anything, these values have to be consistent and describe something to highlight
If lengthEntire < theStart + theLength Then Return
If theStart <= 0 Then Return
If theLength <= 0 Then Return
Const FONT_DISPLAY As String = “Andale Mono”
Const FONT_SIZE_BEGIN_END As Integer = 18
Const FONT_SIZE_MIDDLE As Integer = 24
Const PAD As Integer = 8
Var COLOR_BACKGROUND As Color = RGB(256, 215, 0) // Gold
Const DESCENDER_FRACTION As Double = .25// descenders are roughly 1/4 the height of the string
Const START_TEXT_X As Integer = 10 // where the left edge of the text is in the Canvas
Const START_TEXT_Y As Integer = 30 // where the bottom of text is to be placed in the Canvas ignoring descenders
Var str1 As String // before highlight
Var str2 As String // to be highlighted
Var str3 As String // after highlight
Var widthstr1, widthstr2, widthstr3 As Double
// TextHeight is calculated as the maximum height for the font itself and not the actual height of the text. Actual text irrelevant
// For example, with “a” vs. “A”, both return the same TextHeight even though “A” has a greater height than “a”.
Var heightstr1_3, heightstr2 As Double
Var descenderProblem2 As Double
str1 = theString.Left(theStart)
str2 = theString.Middle(theStart, theLength)
str3 = theString.Right(lengthEntire - (theStart + theLength))
// figure out the height and width of the parts of the string
g.TextFont = FONT_DISPLAY
g.TextSize = FONT_SIZE_BEGIN_END
widthstr1 = g.TextWidth(str1)
heightstr1_3 = g.TextHeight()
widthstr3 = g.TextWidth(str3)
g.TextSize = FONT_SIZE_MIDDLE
widthstr2 = g.TextWidth(str2)
heightstr2 = g.TextHeight()
descenderProblem2 = heightstr2 * DESCENDER_FRACTION
// draw the text before the highlight
g.TextSize = FONT_SIZE_BEGIN_END
g.DrawingColor = Color.Black
g.DrawString(str1, START_TEXT_X, START_TEXT_Y)
// highlight background rectangle
Var startRectX As Integer
Var widthRectX As Integer
g.DrawingColor = COLOR_BACKGROUND
startRectX = START_TEXT_X + widthstr1 + PAD
widthRectX = widthstr2
g.FillRectangle(startRectX, START_TEXT_Y - heightstr2 + descenderProblem2, widthstr2, heightstr2) // upper left X, upper left Y, width, height
// draw the highlighted text
g.DrawingColor = Color.Black
g.TextSize = FONT_SIZE_MIDDLE
g.DrawString(str2, (START_TEXT_X + widthstr1 + PAD), START_TEXT_Y)
// draw the text after the highlight
g.TextSize = FONT_SIZE_BEGIN_END
g.DrawingColor = Color.Black
g.DrawString(str3, (START_TEXT_X + widthstr1 + PAD + widthstr2 + PAD), START_TEXT_Y)[/code]