Word Wrap Textbox

Takes the text box with name 'textBoxName' (or for textBoxName="", all textboxes in a graph or all selected textboxes in a layout) in the top window or in window 'windowName', and adds deletes carriage returns to wrap lines to achieve a width of 'wrapWidth'. Adapted from the WordWrapControlText package created by Adam Light.

Function/S WordWrapTextBox(textBoxName,wrapWidth[,windowName])
    String textBoxName
    Variable wrapWidth
    String windowName
   
    if(ParamIsDefault(windowName))
        windowName=WinName(0,5)
    endif
    Variable layout_=(WinType(windowName)==3)
    if(!strlen(textBoxName))
        String annotations=AnnotationList(windowName)
        Variable i,textboxes
        for(i=0;i<ItemsInList(annotations);i+=1)
            String info=AnnotationInfo(windowName,textBoxName,1)
            String type=StringByKey("TYPE",info)
            if(StringMatch(type,"Textbox")) // Apply word wrapping to textboxes is graphs and layouts.  
                textboxName=StringFromList(i,annotations)
                if(layout_) // Layout
                    String layout_info=LayoutInfo(windowName,textboxName)
                    Variable selected=NumberByKey("SELECTED",layout_info)
                    if(!selected)
                        continue // Only apply word wrapping to selected textboxes in layouts.  
                    endif
                endif
                String result=WordWrapTextBox(textboxName,wrapWidth,windowName=windowName)
                textboxes+=1
            endif
        endfor
        if(textboxes==0)
            return ""
        else
            return result
        endif
    endif
   
    Variable currentLineNum = 0
    // determine the dimensions of the textbox where this text will be placed.  
   
    info=AnnotationInfo(windowName,textBoxName,1)
    if(strlen(info))       
        String textStr=StringByKey("TEXT",info)
        String rect=StringByKey("RECT",info)
        Variable left,top,right,bottom
        sscanf rect,"%f,%f,%f,%f",left,top,right,bottom
        Variable textHeight=bottom-top
    else                        // Textbox doesn't exist.
        return ""              
    endif
   
    // Protect double carriage returns and carriage returns followed by tabs.  
    textStr=ReplaceString("\r\r",textStr,"<|r>")
    textStr=ReplaceString("\r\t",textStr,"<|t>")
    // Kill old carriage returns.  
    textStr=ReplaceString("\r",textStr,"")
    // Bring back protected characters.  
    textStr=ReplaceString("<|r>",textStr,"\r\r")
    textStr=ReplaceString("<|t>",textStr,"\r\t")

    Make /o/T/n=0 outputTextWave
    String returnTextStr=""
    Variable firstLineNum=0

    // get the font information for the default font used in this panel
    if(layout_)
        DefaultGuiFont all
    else
        DefaultGuiFont/W=$(windowName) all
    endif
    String defaultFontName = S_name
    Variable defaultTextFontSize = V_value
    Variable defaultTextFontStyle = V_flag

    // now read information from title control to see if
    // a non-default font size, style, or name is being used   
    Variable textFontSize=NaN, textFontStyle=NaN
    String fontName, escapedFontName
    sscanf textStr,"\Z%d",textfontSize
    if (numtype(textFontSize) != 0)     // default font size is used
        textFontSize = defaultTextFontSize
        if (numtype(textFontSize) != 0)
            textFontSize = 12
        endif
    endif
    sscanf textStr,"\f%d",textfontStyle
    if (numtype(textFontStyle) != 0)        // default font style is used
        textFontStyle = defaultTextFontStyle
        if (numtype(textFontStyle) != 0)
            textFontStyle = 0
        endif
    endif      
    sscanf textStr,"\S'%[A-Za-z]'",fontName
    if (cmpstr(fontName, "") == 0)  // no font name found
        fontName = defaultFontName
        if (cmpstr(fontName, "") == 0)      // will be true if S_name above is ""
            fontName = GetDefaultFont(windowName)
        endif
    endif
   
    // Determine the height, in pixels, of a line of text
    Variable lineHeight = FontSizeHeight(fontName, textFontSize, textFontStyle)
    Variable maxNumLines = Inf//floor(textHeight / lineHeight)

    // search for spaces, check length of string up to that point + length of new text, and decide whether
    // to add the new word or add a line break
    Variable sourceStringPos = 0
    Variable nextSpacePos, nextCRPos, nextBreakPos
    Variable currentTextWidth, newTextWidth
    Variable breakIsCR = 0
    String nextWordString = ""
    String currentLineString = ""

    do
        nextSpacePos = strsearch(textStr, " ", sourceStringPos)
        nextSpacePos = nextSpacePos >= 0 ? nextSpacePos : inf       // set to inf if space is not found
        nextCRPos = strsearch(textStr, "\r", sourceStringPos)
        nextCRPos = nextCRPos >= 0 ? nextCRPos : inf        // set to inf if \r is not found
        if (nextCRPos >= 0 && nextCRPos < nextSpacePos)
            breakIsCR = 1
        else
            breakIsCR = 0
        endif
        nextBreakPos = min(nextSpacePos, nextCRPos)

        if (numtype(nextBreakPos) == 1)     // nextBreakPos == inf means there are no more spaces or \r
            if (strlen(textStr) == sourceStringPos) // at the end of the string
                returnTextStr += currentLineString 
                break
            else
                nextWordString = textStr[sourceStringPos, inf]
                sourceStringPos = strlen(textStr)
            endif
        else
            nextWordString = textStr[sourceStringPos, nextBreakPos]
        endif
        currentTextWidth = FontSizeStringWidth(fontName, textFontSize, textFontStyle, currentLineString)
        newTextWidth = FontSizeStringWidth(fontName, textFontSize, textFontStyle, nextWordString)
        if ((currentTextWidth + newTextWidth + 5) <= wrapWidth)     // add this word        // leave 5px padding
            currentLineString += nextWordString
            if (numtype(nextBreakPos) == 1)
                break
            elseif (breakIsCR)
                sourceStringPos = nextBreakPos + 1
                returnTextStr += currentLineString
                Redimension/N=(currentLineNum + 1) outputTextWave
                outputTextWave[currentLineNum] = currentLineString
                currentLineString = ""
                currentLineNum += 1
            else
                sourceStringPos = nextBreakPos + 1
            endif
        else                                                    // add a new line and then add this word
            returnTextStr += currentLineString
            returnTextStr += "\r"
            Redimension/N=(currentLineNum + 1) outputTextWave
            outputTextWave[currentLineNum] = currentLineString + "\r"
            currentLineNum += 1
            currentLineString = nextWordString
            if (numtype(nextBreakPos) == 1)
                break
            else
                sourceStringPos = nextBreakPos + 1
            endif
        endif
    while(sourceStringPos < strlen(textStr) - 1)
    returnTextStr += currentLineString      // add last part of string to return string
    Redimension/N=(currentLineNum + 1) outputTextWave
    outputTextWave[currentLineNum] = currentLineString + "\r"
   
    Variable n
    String finalOutputString = ""
    Variable numLinesToReturn = min(DimSize(outputTextWave, 0), maxNumLines + firstLineNum)
    For (n=firstLineNum; n<numLinesToReturn; n+=1)
        finalOutputString += outputTextWave[n]
    EndFor
    finalOutputString=RemoveEnding(finalOutputString,"\r")
   
    KillWaves /Z outputTextWave
    Textbox /W=$windowName /C/N=$textboxName finalOutputString
    return finalOutputString
End
I just added in the proper tags to make the Igor code readable.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More