Exemplo n.º 1
0
//----------------------------------------------------------------------------//
void FalagardEditbox::renderTextBidi(const WidgetLookFeel& wlf,
                                     const String& text,
                                     const Rectf& text_area,
                                     float text_offset)
{
#ifdef CEGUI_BIDI_SUPPORT
    const Font* const font = d_window->getFont();

    // setup initial rect for text formatting
    Rectf text_part_rect(text_area);
    // allow for scroll position
    text_part_rect.d_min.d_x += text_offset;
    // centre text vertically within the defined text area
    text_part_rect.d_min.d_y += (text_area.getHeight() - font->getFontHeight()) * 0.5f;

    ColourRect colours;
    const float alpha_comp = d_window->getEffectiveAlpha();
    // get unhighlighted text colour (saves accessing property twice)
    ColourRect unselectedColour;
    setColourRectToUnselectedTextColour(unselectedColour);
    // see if the editbox is active or inactive.
    Editbox* const w = static_cast<Editbox*>(d_window);
    const bool active = editboxIsFocussed();

    if (w->getSelectionLength() == 0)
    {
        // no highlighted text - we can draw the whole thing
        colours = unselectedColour;
        colours.modulateAlpha(alpha_comp);
        text_part_rect.d_min.d_x =
            font->drawText(w->getGeometryBuffer(), text,
                           text_part_rect.getPosition(), &text_area, colours);
    }
    else
    {
        // there is highlighted text - because of the Bidi support - the
        // highlighted area can be in some cases nonconsecutive.
        // So - we need to draw it char by char (I guess we can optimize it more
        // but this is not that big performance hit because it only happens if
        // we have highlighted text - not that common...)
        for (size_t i = 0 ; i < text.size() ; i++)
        {
            // get the char
            String currChar = text.substr(i, 1);
            size_t realPos = 0;

            // get he visual pos of the char
            if (w->getBidiVisualMapping()->getV2lMapping().size() > i)
            {
                realPos = w->getBidiVisualMapping()->getV2lMapping()[i];
            }

            // check if it is in the highlighted region
            bool highlighted =
                realPos >= w->getSelectionStartIndex() &&
                realPos < w->getSelectionStartIndex() + w->getSelectionLength();

            float charAdvance = font->getGlyphData(currChar[0])->getAdvance(1.0f);

            if (highlighted)
            {
                setColourRectToSelectedTextColour(colours);
                colours.modulateAlpha(alpha_comp);

                {

                    // calculate area for selection imagery.
                    Rectf hlarea(text_area);
                    hlarea.d_min.d_x = text_part_rect.d_min.d_x ;
                    hlarea.d_max.d_x = text_part_rect.d_min.d_x + charAdvance ;

                    // render the selection imagery.
                    wlf.getStateImagery(active ? "ActiveSelection" :
                                                 "InactiveSelection").
                        render(*w, hlarea, 0, &text_area);
                }

            }
            else
            {
                colours = unselectedColour;
                colours.modulateAlpha(alpha_comp);
            }
            font->drawText(w->getGeometryBuffer(), currChar,
                           text_part_rect.getPosition(), &text_area, colours);

            // adjust rect for next section
            text_part_rect.d_min.d_x += charAdvance;

        }
    }
#endif
}
Exemplo n.º 2
0
void FalagardMultiLineEditbox::cacheTextLines(const Rectf& dest_area)
{
    MultiLineEditbox* w = (MultiLineEditbox*)d_window;
    // text is already formatted, we just grab the lines and render them with the required alignment.
    Rectf drawArea(dest_area);
    float vertScrollPos = w->getVertScrollbar()->getScrollPosition();
    drawArea.offset(Vector2f(-w->getHorzScrollbar()->getScrollPosition(), -vertScrollPos));

    const Font* fnt = w->getFont();

    if (fnt)
    {
        // calculate final colours to use.
        ColourRect colours;
        const float alpha = w->getEffectiveAlpha();
        ColourRect normalTextCol;
        setColourRectToUnselectedTextColour(normalTextCol);
        normalTextCol.modulateAlpha(alpha);
        ColourRect selectTextCol;
        setColourRectToSelectedTextColour(selectTextCol);
        selectTextCol.modulateAlpha(alpha);
        ColourRect selectBrushCol;
        w->hasInputFocus() ? setColourRectToActiveSelectionColour(selectBrushCol) :
                             setColourRectToInactiveSelectionColour(selectBrushCol);
        selectBrushCol.modulateAlpha(alpha);

        const MultiLineEditbox::LineList& d_lines = w->getFormattedLines();
        const size_t numLines = d_lines.size();

        // calculate the range of visible lines
        size_t sidx,eidx;
        sidx = static_cast<size_t>(vertScrollPos / fnt->getLineSpacing());
        eidx = 1 + sidx + static_cast<size_t>(dest_area.getHeight() / fnt->getLineSpacing());
        eidx = ceguimin(eidx, numLines);
        drawArea.d_min.d_y += fnt->getLineSpacing()*static_cast<float>(sidx);

        // for each formatted line.
        for (size_t i = sidx; i < eidx; ++i)
        {
            Rectf lineRect(drawArea);
            const MultiLineEditbox::LineInfo& currLine = d_lines[i];
            String lineText(w->getTextVisual().substr(currLine.d_startIdx, currLine.d_length));

            // offset the font little down so that it's centered within its own spacing
            const float old_top = lineRect.top();
            lineRect.d_min.d_y += (fnt->getLineSpacing() - fnt->getFontHeight()) * 0.5f;

            // if it is a simple 'no selection area' case
            if ((currLine.d_startIdx >= w->getSelectionEndIndex()) ||
                ((currLine.d_startIdx + currLine.d_length) <= w->getSelectionStartIndex()) ||
                (w->getSelectionBrushImage() == 0))
            {
                colours = normalTextCol;
                // render the complete line.
                fnt->drawText(w->getGeometryBuffer(), lineText,
                                lineRect.getPosition(), &dest_area, colours);
            }
            // we have at least some selection highlighting to do
            else
            {
                // Start of actual rendering section.
                String sect;
                size_t sectIdx = 0, sectLen;
                float selStartOffset = 0.0f, selAreaWidth = 0.0f;

                // render any text prior to selected region of line.
                if (currLine.d_startIdx < w->getSelectionStartIndex())
                {
                    // calculate length of text section
                    sectLen = w->getSelectionStartIndex() - currLine.d_startIdx;

                    // get text for this section
                    sect = lineText.substr(sectIdx, sectLen);
                    sectIdx += sectLen;

                    // get the pixel offset to the beginning of the selection area highlight.
                    selStartOffset = fnt->getTextAdvance(sect);

                    // draw this portion of the text
                    colours = normalTextCol;
                    fnt->drawText(w->getGeometryBuffer(), sect,
                                    lineRect.getPosition(), &dest_area, colours);

                    // set position ready for next portion of text
                    lineRect.d_min.d_x += selStartOffset;
                }

                // calculate the length of the selected section
                sectLen = ceguimin(w->getSelectionEndIndex() - currLine.d_startIdx, currLine.d_length) - sectIdx;

                // get the text for this section
                sect = lineText.substr(sectIdx, sectLen);
                sectIdx += sectLen;

                // get the extent to use as the width of the selection area highlight
                selAreaWidth = fnt->getTextAdvance(sect);

                const float text_top = lineRect.top();
                lineRect.top(old_top);

                // calculate area for the selection brush on this line
                lineRect.left(drawArea.left() + selStartOffset);
                lineRect.right(lineRect.left() + selAreaWidth);
                lineRect.bottom(lineRect.top() + fnt->getLineSpacing());

                // render the selection area brush for this line
                colours = selectBrushCol;
                w->getSelectionBrushImage()->render(w->getGeometryBuffer(), lineRect, &dest_area, colours);

                // draw the text for this section
                colours = selectTextCol;
                fnt->drawText(w->getGeometryBuffer(), sect,
                                lineRect.getPosition(), &dest_area, colours);

                lineRect.top(text_top);

                // render any text beyond selected region of line
                if (sectIdx < currLine.d_length)
                {
                    // update render position to the end of the selected area.
                    lineRect.d_min.d_x += selAreaWidth;

                    // calculate length of this section
                    sectLen = currLine.d_length - sectIdx;

                    // get the text for this section
                    sect = lineText.substr(sectIdx, sectLen);

                    // render the text for this section.
                    colours = normalTextCol;
                    fnt->drawText(w->getGeometryBuffer(), sect,
                                    lineRect.getPosition(), &dest_area, colours);
                }
            }

            // update master position for next line in paragraph.
            drawArea.d_min.d_y += fnt->getLineSpacing();
        }
    }
}
Exemplo n.º 3
0
//----------------------------------------------------------------------------//
void FalagardEditbox::renderTextNoBidi(const WidgetLookFeel& wlf,
                                       const String& text,
                                       const Rectf& text_area,
                                       float text_offset)
{
    const Font* font = d_window->getFont();

    // setup initial rect for text formatting
    Rectf text_part_rect(text_area);
    // allow for scroll position
    text_part_rect.d_min.d_x += text_offset;
    // centre text vertically within the defined text area
    text_part_rect.d_min.d_y += (text_area.getHeight() - font->getFontHeight()) * 0.5f;

    ColourRect colours;
    const float alpha_comp = d_window->getEffectiveAlpha();
    // get unhighlighted text colour (saves accessing property twice)
    ColourRect unselectedColours;
    setColourRectToUnselectedTextColour(unselectedColours);
    // see if the editbox is active or inactive.
    Editbox* const w = static_cast<Editbox*>(d_window);
    const bool active = editboxIsFocussed();

    if (w->getSelectionLength() != 0)
    {
        // calculate required start and end offsets of selection imagery.
        float selStartOffset =
            font->getTextAdvance(text.substr(0, w->getSelectionStartIndex()));
        float selEndOffset =
            font->getTextAdvance(text.substr(0, w->getSelectionEndIndex()));

        // calculate area for selection imagery.
        Rectf hlarea(text_area);
        hlarea.d_min.d_x += text_offset + selStartOffset;
        hlarea.d_max.d_x = hlarea.d_min.d_x + (selEndOffset - selStartOffset);

        // render the selection imagery.
        wlf.getStateImagery(active ? "ActiveSelection" :
                                     "InactiveSelection").
            render(*w, hlarea, 0, &text_area);
    }

    // draw pre-highlight text
    String sect = text.substr(0, w->getSelectionStartIndex());
    colours = unselectedColours;
    colours.modulateAlpha(alpha_comp);
    text_part_rect.d_min.d_x =
        font->drawText(w->getGeometryBuffer(), sect,
                       text_part_rect.getPosition(), &text_area, colours);

    // draw highlight text
    sect = text.substr(w->getSelectionStartIndex(), w->getSelectionLength());
    setColourRectToSelectedTextColour(colours);
    colours.modulateAlpha(alpha_comp);
    text_part_rect.d_min.d_x =
        font->drawText(w->getGeometryBuffer(), sect,
                       text_part_rect.getPosition(), &text_area, colours);

    // draw post-highlight text
    sect = text.substr(w->getSelectionEndIndex());
    colours = unselectedColours;
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &text_area, colours);
}