Пример #1
0
    void ImagerySection::render(Window& srcWindow, const Rectf& baseRect, const CEGUI::ColourRect* modColours, const Rectf* clipper, bool clipToDisplay) const
    {
        // decide what to do as far as colours go
        ColourRect finalCols;
        initMasterColourRect(srcWindow, finalCols);

        if (modColours)
            finalCols *= *modColours;

        ColourRect* finalColsPtr = (finalCols.isMonochromatic() && finalCols.d_top_left.getARGB() == 0xFFFFFFFF) ? 0 : &finalCols;

        // render all frame components in this section
        for(FrameList::const_iterator frame = d_frames.begin(); frame != d_frames.end(); ++frame)
        {
            (*frame).render(srcWindow, baseRect, finalColsPtr, clipper, clipToDisplay);
        }
        // render all image components in this section
        for(ImageryList::const_iterator image = d_images.begin(); image != d_images.end(); ++image)
        {
            (*image).render(srcWindow, baseRect, finalColsPtr, clipper, clipToDisplay);
        }
        // render all text components in this section
        for(TextList::const_iterator text = d_texts.begin(); text != d_texts.end(); ++text)
        {
            (*text).render(srcWindow, baseRect, finalColsPtr, clipper, clipToDisplay);
        }
    }
    void SectionSpecification::render(Window& srcWindow, float base_z, const ColourRect* modcols, const Rect* clipper, bool clipToDisplay) const
    {
        // see if we need to bother rendering
        if (d_renderControlProperty.empty() ||
            PropertyHelper::stringToBool(srcWindow.getProperty(d_renderControlProperty)))
        {
            try
            {
                // get the imagery section object with the name we're set up to use
                const ImagerySection* sect =
                    &WidgetLookManager::getSingleton().getWidgetLook(d_owner).getImagerySection(d_sectionName);

                // decide what colours are to be used
                ColourRect finalColours;
                initColourRectForOverride(srcWindow, finalColours);
                finalColours.modulateAlpha(srcWindow.getEffectiveAlpha());

                if (modcols)
                    finalColours *= *modcols;

                // render the imagery section
                sect->render(srcWindow, base_z, &finalColours, clipper, clipToDisplay);
            }
            // do nothing here, errors are non-faltal and are logged for debugging purposes.
            catch (Exception&)
            {}
        }
    }
Пример #3
0
//----------------------------------------------------------------------------//
void FalagardEditbox::setColourRectToOptionalPropertyColour(
    const String& propertyName,
    ColourRect& colour_rect) const
{
    if (d_window->isPropertyPresent(propertyName))
        colour_rect = PropertyHelper<ColourRect>::fromString(
            d_window->getProperty(propertyName));
    else
        colour_rect.setColours(0);
}
Пример #4
0
//----------------------------------------------------------------------------//
void FalagardMultiLineEditbox::setColourRectToOptionalPropertyColour(
                                                const String& propertyName,
                                                ColourRect& colour_rect) const
{
    if (d_window->isPropertyPresent(propertyName))
        colour_rect = 
            d_window->getProperty<ColourRect>(propertyName);
    else
        colour_rect.setColours(0);
}
Пример #5
0
    void FalagardEditbox::populateRenderCache()
    {
        const StateImagery* imagery;

        // draw container etc
        // get WidgetLookFeel for the assigned look.
        const WidgetLookFeel& wlf = WidgetLookManager::getSingleton().getWidgetLook(d_lookName);
        // try and get imagery for the approprite state.
        imagery = &wlf.getStateImagery(isDisabled() ? "Disabled" : (isReadOnly() ? "ReadOnly" : "Enabled"));

        // peform the rendering operation for the container.
        imagery->render(*this);

        // get destination area for text
        const Rect textArea(wlf.getNamedArea("TextArea").getArea().getPixelRect(*this));

        //
        // Required preliminary work for text rendering operations
        //
        const Font* font = getFont();

        // no font == no more rendering
        if (!font)
            return;

        // This will point to the final string to be used for rendering.  Useful because it means we
        // do not have to have duplicate code or be copying d_text for handling masked/unmasked text.
        String* editText;

        // Create a 'masked' version of the string if needed.
        String maskedText;
        if (isTextMasked())
        {
            maskedText.insert(0, d_text.length(), getMaskCodePoint());
            editText = &maskedText;
        }
        // text not masked to editText will be the windows d_text String.
        else
        {
            editText = &d_text;
        }

        // calculate best position to render text to ensure carat is always visible
        float textOffset;
        float extentToCarat = font->getTextExtent(editText->substr(0, getCaratIndex()));

        // get carat imagery
        const ImagerySection& caratImagery = wlf.getImagerySection("Carat");
        // store carat width
        float caratWidth = caratImagery.getBoundingRect(*this, textArea).getWidth();

        // if box is inactive
        if (!hasInputFocus())
        {
            textOffset = d_lastTextOffset;
        }
        // if carat is to the left of the box
        else if ((d_lastTextOffset + extentToCarat) < 0)
        {
            textOffset = -extentToCarat;
        }
        // if carat is off to the right.
        else if ((d_lastTextOffset + extentToCarat) >= (textArea.getWidth() - caratWidth))
        {
            textOffset = textArea.getWidth() - extentToCarat - caratWidth;
        }
        // else carat is already within the box
        else
        {
            textOffset = d_lastTextOffset;
        }

        ColourRect colours;
        float alpha_comp = getEffectiveAlpha();

        //
        // Draw label text
        //
        // setup initial rect for text formatting
        Rect text_part_rect(textArea);
        // allow for scroll position
        text_part_rect.d_left += textOffset;
        // centre text vertically within the defined text area
        text_part_rect.d_top += (textArea.getHeight() - font->getLineSpacing()) * 0.5f;

        // draw pre-highlight text
        String sect = editText->substr(0, getSelectionStartIndex());
        colours.setColours(d_normalTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(sect);

        // draw highlight text
        sect = editText->substr(getSelectionStartIndex(), getSelectionLength());
        colours.setColours(d_selectTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(sect);

        // draw post-highlight text
        sect = editText->substr(getSelectionEndIndex());
        colours.setColours(d_normalTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // remember this for next time.
        d_lastTextOffset = textOffset;

        // see if the editbox is active or inactive.
        bool active = (!isReadOnly()) && hasInputFocus();

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

            // calculate area for selection imagery.
            Rect hlarea(textArea);
            hlarea.d_left += textOffset + selStartOffset;
            hlarea.d_right = hlarea.d_left + (selEndOffset - selStartOffset);

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

        //
        // Render carat
        //
        if (active)
        {
            Rect caratRect(textArea);
            caratRect.d_left += extentToCarat + textOffset;

            caratImagery.render(*this, caratRect, 0, 0, &textArea);
        }
    }
Пример #6
0
/*************************************************************************
	Render text lines.	
*************************************************************************/
void MultiLineEditbox::cacheTextLines(const Rect& dest_area)
{
    // text is already formatted, we just grab the lines and render them with the required alignment.
    Rect drawArea(dest_area);
    drawArea.offset(Point(-d_horzScrollbar->getScrollPosition(), -d_vertScrollbar->getScrollPosition()));

    Renderer* renderer = System::getSingleton().getRenderer();
    const Font* fnt = getFont();

    if (fnt)
    {
        // get layers to use for rendering
        float textZ = renderer->getZLayer(4) - renderer->getCurrentZ();
        float selZ  = renderer->getZLayer(3) - renderer->getCurrentZ();

        // calculate final colours to use.
        ColourRect colours;
        float alpha = getEffectiveAlpha();
        colour normalTextCol = d_normalTextColour;
        normalTextCol.setAlpha(normalTextCol.getAlpha() * alpha);
        colour selectTextCol = d_selectTextColour;
        selectTextCol.setAlpha(selectTextCol.getAlpha() * alpha);
        colour selectBrushCol = hasInputFocus() ? d_selectBrushColour : d_inactiveSelectBrushColour;
        selectBrushCol.setAlpha(selectBrushCol.getAlpha() * alpha);

        // Cache font info
        const float fLineSpacing = fnt->getLineSpacing ();

        // for each formatted line.
        for (size_t i = 0; i < d_lines.size(); ++i)
        {
            Rect lineRect(drawArea);
            // Check line is within the dest_area
            if ( lineRect.d_top < dest_area.d_bottom && lineRect.d_top + fLineSpacing > dest_area.d_top )
            {
                const LineInfo& currLine = d_lines[i];
                String lineText(d_text.substr(currLine.d_startIdx, currLine.d_length));

                // if it is a simple 'no selection area' case
                if ((currLine.d_startIdx >= d_selectionEnd) ||
                    ((currLine.d_startIdx + currLine.d_length) <= d_selectionStart) ||
                    (d_selectionBrush == NULL))
                {
                    colours.setColours(normalTextCol);
                    // render the complete line.
                    d_renderCache.cacheText(lineText, fnt, LeftAligned, lineRect, textZ, colours, &dest_area);
                }
                // 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 < d_selectionStart)
                    {
                        // calculate length of text section
                        sectLen = d_selectionStart - 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->getTextExtent(sect);

                        // draw this portion of the text
                        colours.setColours(normalTextCol);
                        d_renderCache.cacheText(sect, fnt, LeftAligned, lineRect, textZ, colours, &dest_area);

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

                    // calculate the length of the selected section
                    sectLen = ceguimin(d_selectionEnd - 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->getTextExtent(sect);

                    // draw the text for this section
                    colours.setColours(selectTextCol);
                    d_renderCache.cacheText(sect, fnt, LeftAligned, lineRect, textZ, colours, &dest_area);

                    // 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_left += 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.setColours(normalTextCol);
                        d_renderCache.cacheText(sect, fnt, LeftAligned, lineRect, textZ, colours, &dest_area);
                    }

                    // calculate area for the selection brush on this line
                    lineRect.d_left = drawArea.d_left + selStartOffset;
                    lineRect.d_right = lineRect.d_left + selAreaWidth;
                    lineRect.d_bottom = lineRect.d_top + fLineSpacing;

                    // render the selection area brush for this line
                    colours.setColours(selectBrushCol);
                    d_renderCache.cacheImage(*d_selectionBrush, lineRect, selZ, colours, &dest_area);
                }
            }

            // update master position for next line in paragraph.
            drawArea.d_top += fLineSpacing;
        }
    }
}
Пример #7
0
    void FrameComponent::render_impl(Window& srcWindow, Rect& destRect, float base_z, const CEGUI::ColourRect* modColours, const Rect* clipper, bool clipToDisplay) const
    {
        Rect backgroundRect(destRect);
        Rect finalRect;
        Size imageSize;
        ColourRect imageColours;
        float leftfactor, rightfactor, topfactor, bottomfactor;
        bool calcColoursPerImage;

        // vars we use to track what to do with the side pieces.
        float topOffset = 0, bottomOffset = 0, leftOffset = 0, rightOffset = 0;
        float topWidth, bottomWidth, leftHeight, rightHeight;
        topWidth = bottomWidth = destRect.getWidth();
        leftHeight = rightHeight = destRect.getHeight();

        // calculate final overall colours to be used
        ColourRect finalColours;
        initColoursRect(srcWindow, modColours, finalColours);

        if (finalColours.isMonochromatic())
        {
            calcColoursPerImage = false;
            imageColours = finalColours;
        }
        else
        {
            calcColoursPerImage = true;
        }

        // top-left image
        if (d_frameImages[FIC_TOP_LEFT_CORNER])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_TOP_LEFT_CORNER]->getSize();
            finalRect.d_left = destRect.d_left;
            finalRect.d_top  = destRect.d_top;
            finalRect.setSize(imageSize);

            // update adjustments required to edges do to presence of this element.
            topOffset  += imageSize.d_width;
            leftOffset += imageSize.d_height;
            topWidth   -= topOffset;
            leftHeight -= leftOffset;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_TOP_LEFT_CORNER]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_TOP_LEFT_CORNER]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_LEFT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // top-right image
        if (d_frameImages[FIC_TOP_RIGHT_CORNER])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_TOP_RIGHT_CORNER]->getSize();
            finalRect.d_left = destRect.d_right - imageSize.d_width;
            finalRect.d_top  = destRect.d_top;
            finalRect.setSize(imageSize);

            // update adjustments required to edges do to presence of this element.
            rightOffset += imageSize.d_height;
            topWidth    -= imageSize.d_width;
            rightHeight -= rightOffset;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_TOP_RIGHT_CORNER]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_TOP_RIGHT_CORNER]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_RIGHT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // bottom-left image
        if (d_frameImages[FIC_BOTTOM_LEFT_CORNER])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getSize();
            finalRect.d_left = destRect.d_left;
            finalRect.d_top  = destRect.d_bottom - imageSize.d_height;
            finalRect.setSize(imageSize);

            // update adjustments required to edges do to presence of this element.
            bottomOffset += imageSize.d_width;
            bottomWidth  -= bottomOffset;
            leftHeight   -= imageSize.d_height;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_BOTTOM_LEFT_CORNER]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_LEFT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // bottom-right image
        if (d_frameImages[FIC_BOTTOM_RIGHT_CORNER])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getSize();
            finalRect.d_left = destRect.d_right - imageSize.d_width;
            finalRect.d_top  = destRect.d_bottom - imageSize.d_height;
            finalRect.setSize(imageSize);

            // update adjustments required to edges do to presence of this element.
            bottomWidth -= imageSize.d_width;
            rightHeight -= imageSize.d_height;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_BOTTOM_RIGHT_CORNER]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_RIGHT_CORNER], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // top image
        if (d_frameImages[FIC_TOP_EDGE])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_TOP_EDGE]->getSize();
            finalRect.d_left   = destRect.d_left + topOffset;
            finalRect.d_right  = finalRect.d_left + topWidth;
            finalRect.d_top    = destRect.d_top;
            finalRect.d_bottom = finalRect.d_top + imageSize.d_height;

            // adjust background area to miss this edge
            backgroundRect.d_top += imageSize.d_height + d_frameImages[FIC_TOP_EDGE]->getOffsetY();;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_TOP_EDGE]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_TOP_EDGE]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_TOP_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // bottom image
        if (d_frameImages[FIC_BOTTOM_EDGE])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_BOTTOM_EDGE]->getSize();
            finalRect.d_left   = destRect.d_left + bottomOffset;
            finalRect.d_right  = finalRect.d_left + bottomWidth;
            finalRect.d_bottom = destRect.d_bottom;
            finalRect.d_top    = finalRect.d_bottom - imageSize.d_height;

            // adjust background area to miss this edge
            backgroundRect.d_bottom -= imageSize.d_height - d_frameImages[FIC_BOTTOM_EDGE]->getOffsetY();;

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_BOTTOM_EDGE]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_BOTTOM_EDGE]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_BOTTOM_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // left image
        if (d_frameImages[FIC_LEFT_EDGE])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_LEFT_EDGE]->getSize();
            finalRect.d_left   = destRect.d_left;
            finalRect.d_right  = finalRect.d_left + imageSize.d_width;
            finalRect.d_top    = destRect.d_top + leftOffset;
            finalRect.d_bottom = finalRect.d_top + leftHeight;

            // adjust background area to miss this edge
            backgroundRect.d_left += imageSize.d_width + d_frameImages[FIC_LEFT_EDGE]->getOffsetX();

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_LEFT_EDGE]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_LEFT_EDGE]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_LEFT_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        // right image
        if (d_frameImages[FIC_RIGHT_EDGE])
        {
            // calculate final destination area
            imageSize = d_frameImages[FIC_RIGHT_EDGE]->getSize();
            finalRect.d_top    = destRect.d_top + rightOffset;
            finalRect.d_bottom = finalRect.d_top + rightHeight;
            finalRect.d_right  = destRect.d_right;
            finalRect.d_left   = finalRect.d_right - imageSize.d_width;

            // adjust background area to miss this edge
            backgroundRect.d_right -= imageSize.d_width - d_frameImages[FIC_RIGHT_EDGE]->getOffsetX();

            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (finalRect.d_left + d_frameImages[FIC_RIGHT_EDGE]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
                topfactor    = (finalRect.d_top + d_frameImages[FIC_RIGHT_EDGE]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // draw this element.
            srcWindow.getRenderCache().cacheImage(*d_frameImages[FIC_RIGHT_EDGE], finalRect, base_z, imageColours, 0, clipToDisplay);
        }

        if (d_frameImages[FIC_BACKGROUND])
        {
            // calculate colours that are to be used to this component image
            if (calcColoursPerImage)
            {
                leftfactor   = (backgroundRect.d_left + d_frameImages[FIC_BACKGROUND]->getOffsetX()) / destRect.getWidth();
                rightfactor  = leftfactor + backgroundRect.getWidth() / destRect.getWidth();
                topfactor    = (backgroundRect.d_top + d_frameImages[FIC_BACKGROUND]->getOffsetY()) / destRect.getHeight();
                bottomfactor = topfactor + backgroundRect.getHeight() / destRect.getHeight();

                imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
            }

            // render background image.
            doBackgroundRender(srcWindow, backgroundRect, base_z, imageColours, clipper, clipToDisplay);
        }
    }
Пример #8
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();
        }
    }
}
Пример #9
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
}
Пример #10
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);
}
//----------------------------------------------------------------------------//
void FrameComponent::render_impl(Window& srcWindow, Rectf& destRect,
                                 const CEGUI::ColourRect* modColours,
                                 const Rectf* clipper, bool clipToDisplay) const
{
    Rectf backgroundRect(destRect);
    Rectf finalRect;
    Sizef imageSize;
    Vector2f imageOffsets;
    ColourRect imageColours;
    float leftfactor, rightfactor, topfactor, bottomfactor;
    bool calcColoursPerImage;

    // vars we use to track what to do with the side pieces.
    float topOffset = 0, bottomOffset = 0, leftOffset = 0, rightOffset = 0;
    float topWidth, bottomWidth, leftHeight, rightHeight;
    topWidth = bottomWidth = destRect.getWidth();
    leftHeight = rightHeight = destRect.getHeight();

    // calculate final overall colours to be used
    ColourRect finalColours;
    initColoursRect(srcWindow, modColours, finalColours);

    if (finalColours.isMonochromatic())
    {
        calcColoursPerImage = false;
        imageColours = finalColours;
    }
    else
    {
        calcColoursPerImage = true;
    }
    
    // top-left image
    if (const Image* const componentImage = getImage(FIC_TOP_LEFT_CORNER, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        imageOffsets = componentImage->getRenderedOffset();
        finalRect.d_min = destRect.d_min;
        finalRect.setSize(imageSize);
        finalRect = destRect.getIntersection(finalRect);

        // update adjustments required to edges do to presence of this element.
        topOffset  += imageSize.d_width + imageOffsets.d_x;
        leftOffset += imageSize.d_height + imageOffsets.d_y;
        topWidth   -= topOffset;
        leftHeight -= leftOffset;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + imageOffsets.d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + imageOffsets.d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        componentImage->render(srcWindow.getGeometryBuffer(), finalRect, clipper, imageColours);
    }

    // top-right image
    if (const Image* const componentImage = getImage(FIC_TOP_RIGHT_CORNER, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        imageOffsets = componentImage->getRenderedOffset();
        finalRect.left(destRect.right() - imageSize.d_width);
        finalRect.top(destRect.top());
        finalRect.setSize(imageSize);
        finalRect = destRect.getIntersection(finalRect);

        // update adjustments required to edges do to presence of this element.
        rightOffset += imageSize.d_height + imageOffsets.d_y;
        topWidth    -= imageSize.d_width - imageOffsets.d_x;
        rightHeight -= rightOffset;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + imageOffsets.d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + imageOffsets.d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle(leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        componentImage->render(srcWindow.getGeometryBuffer(), finalRect, clipper, imageColours);
    }

    // bottom-left image
    if (const Image* const componentImage = getImage(FIC_BOTTOM_LEFT_CORNER, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        imageOffsets = componentImage->getRenderedOffset();
        finalRect.left(destRect.left());
        finalRect.top(destRect.bottom() - imageSize.d_height);
        finalRect.setSize(imageSize);
        finalRect = destRect.getIntersection(finalRect);

        // update adjustments required to edges do to presence of this element.
        bottomOffset += imageSize.d_width + imageOffsets.d_x;
        bottomWidth  -= bottomOffset;
        leftHeight   -= imageSize.d_height - imageOffsets.d_y;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + imageOffsets.d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + imageOffsets.d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle(leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        componentImage->render(srcWindow.getGeometryBuffer(), finalRect, clipper, imageColours);
    }

    // bottom-right image
    if (const Image* const componentImage = getImage(FIC_BOTTOM_RIGHT_CORNER, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        imageOffsets = componentImage->getRenderedOffset();
        finalRect.left(destRect.right() - imageSize.d_width);
        finalRect.top(destRect.bottom() - imageSize.d_height);
        finalRect.setSize(imageSize);
        finalRect = destRect.getIntersection(finalRect);

        // update adjustments required to edges do to presence of this element.
        bottomWidth -= imageSize.d_width - imageOffsets.d_x;
        rightHeight -= imageSize.d_height - imageOffsets.d_y;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        componentImage->render(srcWindow.getGeometryBuffer(), finalRect, clipper, imageColours);
    }

    // top image
    if (const Image* const componentImage = getImage(FIC_TOP_EDGE, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        finalRect.left(destRect.left() + topOffset);
        finalRect.right(finalRect.left() + topWidth);
        finalRect.top(destRect.top());
        finalRect.bottom(finalRect.top() + imageSize.d_height);
        finalRect = destRect.getIntersection(finalRect);

        // adjust background area to miss this edge
        backgroundRect.d_min.d_y += imageSize.d_height + componentImage->getRenderedOffset().d_y;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        renderImage(srcWindow.getGeometryBuffer(), componentImage,
                    VF_TOP_ALIGNED, d_topEdgeFormatting.get(srcWindow),
                    finalRect, imageColours, clipper, clipToDisplay);
    }

    // bottom image
    if (const Image* const componentImage = getImage(FIC_BOTTOM_EDGE, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        finalRect.left(destRect.left() + bottomOffset);
        finalRect.right(finalRect.left() + bottomWidth);
        finalRect.bottom(destRect.bottom());
        finalRect.top(finalRect.bottom() - imageSize.d_height);
        finalRect = destRect.getIntersection (finalRect);

        // adjust background area to miss this edge
        backgroundRect.d_max.d_y -= imageSize.d_height - componentImage->getRenderedOffset().d_y;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle(leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        renderImage(srcWindow.getGeometryBuffer(), componentImage,
                    VF_BOTTOM_ALIGNED, d_bottomEdgeFormatting.get(srcWindow),
                    finalRect, imageColours, clipper, clipToDisplay);
    }

    // left image
    if (const Image* const componentImage = getImage(FIC_LEFT_EDGE, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        finalRect.left(destRect.left());
        finalRect.right(finalRect.left() + imageSize.d_width);
        finalRect.top(destRect.top() + leftOffset);
        finalRect.bottom(finalRect.top() + leftHeight);
        finalRect = destRect.getIntersection(finalRect);

        // adjust background area to miss this edge
        backgroundRect.d_min.d_x += imageSize.d_width + componentImage->getRenderedOffset().d_x;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        renderImage(srcWindow.getGeometryBuffer(), componentImage,
                    d_leftEdgeFormatting.get(srcWindow), HF_LEFT_ALIGNED,
                    finalRect, imageColours, clipper, clipToDisplay);
    }

    // right image
    if (const Image* const componentImage = getImage(FIC_RIGHT_EDGE, srcWindow))
    {
        // calculate final destination area
        imageSize = componentImage->getRenderedSize();
        finalRect.top(destRect.top() + rightOffset);
        finalRect.bottom(finalRect.top() + rightHeight);
        finalRect.right(destRect.right());
        finalRect.left(finalRect.right() - imageSize.d_width);
        finalRect = destRect.getIntersection (finalRect);

        // adjust background area to miss this edge
        backgroundRect.d_max.d_x -= imageSize.d_width - componentImage->getRenderedOffset().d_x;

        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (finalRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + finalRect.getWidth() / destRect.getWidth();
            topfactor    = (finalRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + finalRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        // draw this element.
        renderImage(srcWindow.getGeometryBuffer(), componentImage,
                    d_rightEdgeFormatting.get(srcWindow), HF_RIGHT_ALIGNED,
                    finalRect, imageColours, clipper, clipToDisplay);
    }

    if (const Image* const componentImage = getImage(FIC_BACKGROUND, srcWindow))
    {
        // calculate colours that are to be used to this component image
        if (calcColoursPerImage)
        {
            leftfactor   = (backgroundRect.left() + componentImage->getRenderedOffset().d_x) / destRect.getWidth();
            rightfactor  = leftfactor + backgroundRect.getWidth() / destRect.getWidth();
            topfactor    = (backgroundRect.top() + componentImage->getRenderedOffset().d_y) / destRect.getHeight();
            bottomfactor = topfactor + backgroundRect.getHeight() / destRect.getHeight();

            imageColours = finalColours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor);
        }

        const HorizontalFormatting horzFormatting =
            d_backgroundHorzFormatting.get(srcWindow);

        const VerticalFormatting vertFormatting =
            d_backgroundVertFormatting.get(srcWindow);

        renderImage(srcWindow.getGeometryBuffer(), componentImage,
                    vertFormatting, horzFormatting,
                    backgroundRect, imageColours, clipper, clipToDisplay);
    }
}
Пример #12
0
//----------------------------------------------------------------------------//
void FalagardEditbox::render()
{
    Editbox* w = static_cast<Editbox*>(d_window);
    const StateImagery* imagery;

    // draw container etc
    // get WidgetLookFeel for the assigned look.
    const WidgetLookFeel& wlf = getLookNFeel();
    // try and get imagery for the approprite state.
    imagery = &wlf.getStateImagery(
        w->isDisabled() ? "Disabled" : (w->isReadOnly() ? "ReadOnly" : "Enabled"));

    // peform the rendering operation for the container.
    imagery->render(*w);

    // get destination area for text
    const Rect textArea(wlf.getNamedArea("TextArea").getArea().getPixelRect(*w));

    //
    // Required preliminary work for text rendering operations
    //
    Font* font = w->getFont();

    // no font == no more rendering
    if (!font)
        return;

    // This will point to the final string to be used for rendering.  Useful
    // because it means we do not have to have duplicate code or be copying
    // getText() for handling masked/unmasked text.
    String* editText;

    // Create a 'masked' version of the string if needed.
    String maskedText, windowText;
    if (w->isTextMasked())
    {
        maskedText.insert(0, w->getText().length(), w->getMaskCodePoint());
        editText = &maskedText;
    }
    // text not masked to editText will be the windows getText() String.
    else
    {
        windowText = w->getTextVisual();
        editText = &windowText;
    }

    // calculate best position to render text to ensure carat is always visible
    float textOffset;
    size_t cartIndex = w->getCaratIndex();

#ifdef CEGUI_BIDI_SUPPORT
    // the char before the cart bidi type
    bool currCharIsRtl = false;
    if ((editText->size() > 0) && (cartIndex > 0))
    {
        size_t curCartIndex = w->getCaratIndex();
        BidiCharType charBeforeCartType = w->getBiDiVisualMapping()->
            getBidiCharType((*editText)[curCartIndex - 1]);
        // for neutral chars you decide by the char after
        for (; BCT_NEUTRAL == charBeforeCartType &&
               (editText->size() > curCartIndex); curCartIndex++)
        {
            charBeforeCartType = w->getBiDiVisualMapping()->
                getBidiCharType((*editText)[curCartIndex - 1]);
        }

        currCharIsRtl  = (BCT_RIGHT_TO_LEFT == charBeforeCartType);
    }

    bool isFirstChar = cartIndex == 0;

    // the pos is by the char before
    if (!isFirstChar)
        cartIndex--;

    // we need to find the cart pos by the logical to visual map
    if (w->getBiDiVisualMapping()->getV2lMapping().size() > cartIndex)
        cartIndex = w->getBiDiVisualMapping()->getL2vMapping()[cartIndex];

    // for non RTL char - the cart pos is after the char
    if (!currCharIsRtl)
        cartIndex++;

    // if first char is not rtl - we need to stand at the start of the line
    if (isFirstChar)
    {
        bool firstCharRtl =
            (editText->size() > 0) &&
            (BCT_RIGHT_TO_LEFT == w->getBiDiVisualMapping()->
                getBidiCharType((*editText)[0]));

        if (!firstCharRtl)
            cartIndex--;
    }
#endif

    float extentToCarat = font->getTextExtent(editText->substr(0, cartIndex));

    // get carat imagery
    const ImagerySection& caratImagery = wlf.getImagerySection("Carat");
    // store carat width
    float caratWidth = caratImagery.getBoundingRect(*w, textArea).getWidth();

    // if box is inactive
    if (!w->hasInputFocus())
        textOffset = d_lastTextOffset;
    // if carat is to the left of the box
    else if ((d_lastTextOffset + extentToCarat) < 0)
        textOffset = -extentToCarat;
    // if carat is off to the right.
    else if ((d_lastTextOffset + extentToCarat) >= (textArea.getWidth() - caratWidth))
        textOffset = textArea.getWidth() - extentToCarat - caratWidth;
    // else carat is already within the box
    else
        textOffset = d_lastTextOffset;

    ColourRect colours;
    float alpha_comp = w->getEffectiveAlpha();

    //
    // Draw label text
    //
    // setup initial rect for text formatting
    Rect text_part_rect(textArea);
    // allow for scroll position
    text_part_rect.d_left += textOffset;
    // centre text vertically within the defined text area
    text_part_rect.d_top += (textArea.getHeight() - font->getFontHeight()) * 0.5f;

    // get unhighlighted text colour (saves accessing property twice)
    colour unselectedColour(getUnselectedTextColour());

    // see if the editbox is active or inactive.
    bool active = (!w->isReadOnly()) && w->hasInputFocus();

#ifdef CEGUI_BIDI_SUPPORT
    if (w->getSelectionLength() == 0)
    {
        // no highlighted text - we can draw the whole thing
        colours.setColours(unselectedColour);
        colours.modulateAlpha(alpha_comp);
        font->drawText(w->getGeometryBuffer(), *editText,
                       text_part_rect.getPosition(), &textArea, colours);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(*editText);

    }
    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 < editText->size() ; i++)
        {
            // get the char
            String currChar = editText->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)
            {
                colours.setColours(getSelectedTextColour());
                colours.modulateAlpha(alpha_comp);

                {

                    // calculate area for selection imagery.
                    Rect hlarea(textArea);
                    hlarea.d_left = text_part_rect.d_left ;
                    hlarea.d_right = text_part_rect.d_left + charAdvance ;

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

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

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

        }
    }
#else
    //
    // Render selection imagery.
    //
    if (w->getSelectionLength() != 0)
    {
        // calculate required start and end offsets of selection imagery.
        float selStartOffset =
            font->getTextExtent(editText->substr(0, w->getSelectionStartIndex()));
        float selEndOffset =
            font->getTextExtent(editText->substr(0, w->getSelectionEndIndex()));

        // calculate area for selection imagery.
        Rect hlarea(textArea);
        hlarea.d_left += textOffset + selStartOffset;
        hlarea.d_right = hlarea.d_left + (selEndOffset - selStartOffset);

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

    // draw pre-highlight text
    String sect = editText->substr(0, w->getSelectionStartIndex());
    colours.setColours(unselectedColour);
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // adjust rect for next section
    text_part_rect.d_left += font->getTextExtent(sect);

    // draw highlight text
    sect = editText->substr(w->getSelectionStartIndex(), w->getSelectionLength());
    colours.setColours(getSelectedTextColour());
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // adjust rect for next section
    text_part_rect.d_left += font->getTextExtent(sect);

    // draw post-highlight text
    sect = editText->substr(w->getSelectionEndIndex());
    colours.setColours(unselectedColour);
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // remember this for next time.
    d_lastTextOffset = textOffset;
#endif

    //
    // Render carat
    //
    if (active && (!d_blinkCaret || d_showCaret))
    {
        Rect caratRect(textArea);
        caratRect.d_left += extentToCarat + textOffset;

        caratImagery.render(*w, caratRect, 0, &textArea);
    }
}