void CGUITTFont::draw(const core::stringw& text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip) { if (!Driver) return; // Clear the glyph pages of their render information. for (u32 i = 0; i < Glyph_Pages.size(); ++i) { Glyph_Pages[i]->render_positions.clear(); Glyph_Pages[i]->render_source_rects.clear(); } // Set up some variables. core::dimension2d<s32> textDimension; core::position2d<s32> offset = position.UpperLeftCorner; // Determine offset positions. if (hcenter || vcenter) { textDimension = getDimension(text.c_str()); if (hcenter) offset.X = ((position.getWidth() - textDimension.Width) >> 1) + offset.X; if (vcenter) offset.Y = ((position.getHeight() - textDimension.Height) >> 1) + offset.Y; }
//! constructor CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) : IGUIComboBox(environment, parent, id, rectangle), ListButton(0), SelectedText(0), ListBox(0), LastFocus(0), Selected(-1), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER), MaxSelectionRows(5), HasFocus(false), ActiveFont(0) { #ifdef _DEBUG setDebugName("CGUIComboBox"); #endif IGUISkin* skin = Environment->getSkin(); s32 width = 15; if (skin) width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); core::rect<s32> r; r.UpperLeftCorner.X = rectangle.getWidth() - width - 2; r.LowerRightCorner.X = rectangle.getWidth() - 2; r.UpperLeftCorner.Y = 2; r.LowerRightCorner.Y = rectangle.getHeight() - 2; ListButton = Environment->addButton(r, this, -1, L""); if (skin && skin->getSpriteBank()) { ListButton->setSpriteBank(skin->getSpriteBank()); ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); } ListButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); ListButton->setSubElement(true); ListButton->setTabStop(false); r.UpperLeftCorner.X = 2; r.UpperLeftCorner.Y = 2; r.LowerRightCorner.X = RelativeRect.getWidth() - (ListButton->getAbsolutePosition().getWidth() + 2); r.LowerRightCorner.Y = RelativeRect.getHeight() - 2; SelectedText = Environment->addStaticText(L"", r, false, false, this, -1, false); SelectedText->setSubElement(true); SelectedText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); SelectedText->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER); if (skin) SelectedText->setOverrideColor(skin->getColor(EGDC_BUTTON_TEXT)); SelectedText->enableOverrideColor(true); // this element can be tabbed to setTabStop(true); setTabOrder(-1); }
//! constructor CGUISpinBox::CGUISpinBox(const wchar_t* text, bool border,IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect<s32>& rectangle) : IGUISpinBox(environment, parent, id, rectangle), EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f), RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"), DecimalPlaces(-1) { #ifdef _DEBUG setDebugName("CGUISpinBox"); #endif s32 ButtonWidth = 16; IGUISpriteBank *sb = 0; if (environment && environment->getSkin()) { ButtonWidth = environment->getSkin()->getSize(EGDS_SCROLLBAR_SIZE); sb = environment->getSkin()->getSpriteBank(); } ButtonSpinDown = Environment->addButton( core::rect<s32>(rectangle.getWidth() - ButtonWidth, rectangle.getHeight()/2 +1, rectangle.getWidth(), rectangle.getHeight()), this); ButtonSpinDown->grab(); ButtonSpinDown->setSubElement(true); ButtonSpinDown->setTabStop(false); ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT); ButtonSpinUp = Environment->addButton( core::rect<s32>(rectangle.getWidth() - ButtonWidth, 0, rectangle.getWidth(), rectangle.getHeight()/2), this); ButtonSpinUp->grab(); ButtonSpinUp->setSubElement(true); ButtonSpinUp->setTabStop(false); ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER); if (sb) { IGUISkin *skin = environment->getSkin(); ButtonSpinDown->setSpriteBank(sb); ButtonSpinDown->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); ButtonSpinDown->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); ButtonSpinUp->setSpriteBank(sb); ButtonSpinUp->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL)); ButtonSpinUp->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL)); } else { ButtonSpinDown->setText(L"-"); ButtonSpinUp->setText(L"+"); } const core::rect<s32> rectEdit(0, 0, rectangle.getWidth() - ButtonWidth - 1, rectangle.getHeight()); EditBox = Environment->addEditBox(text, rectEdit, border, this, -1); EditBox->grab(); EditBox->setSubElement(true); EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); }
CGUIPanel::CGUIPanel( IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect<s32>& rectangle, bool border, E_SCROLL_BAR_MODE vMode, E_SCROLL_BAR_MODE hMode) : IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle), VScrollBar(0), HScrollBar(0), ClipPane(0), InnerPane(0), Border(border), VScrollBarMode(vMode), HScrollBarMode(hMode), NeedsUpdate(true) { #ifdef _DEBUG setDebugName("CGUIPanel"); #endif s32 width = rectangle.getWidth(); s32 height = rectangle.getHeight(); core::rect<s32> rct = core::rect<s32>(width - SCROLL_BAR_SIZE,0, width, height); VScrollBar = environment->addScrollBar( false, rct, 0, id ); VScrollBar->setSubElement(true); VScrollBar->setTabStop(false); VScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); VScrollBar->grab(); IGUIElement::addChild(VScrollBar); rct = core::rect<s32>(0,height - SCROLL_BAR_SIZE, width - SCROLL_BAR_SIZE,height ); HScrollBar = environment->addScrollBar( true, rct, 0, id ); HScrollBar->setSubElement(true); HScrollBar->setTabStop(false); HScrollBar->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); HScrollBar->grab(); IGUIElement::addChild(HScrollBar); rct = core::rect<s32>(0,0, width - SCROLL_BAR_SIZE, height - SCROLL_BAR_SIZE); ClipPane = environment->addTab( rct, 0, -1); ClipPane->setSubElement(true); ClipPane->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); ClipPane->grab(); IGUIElement::addChild(ClipPane); InnerPane = environment->addTab( rct, ClipPane, -1); InnerPane->setSubElement(true); InnerPane->grab(); calculateClientArea(); resizeInnerPane(); }
/* Replacement for driver->draw2DImage() that uses the high-quality pre-scaled * texture, if configured. */ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, const core::rect<s32> &destrect, const core::rect<s32> &srcrect, const core::rect<s32> *cliprect, const video::SColor *const colors, bool usealpha) { // Attempt to pre-scale image in software in high quality. video::ITexture *scaled = guiScalingResizeCached(driver, txr, srcrect, destrect); if (scaled == NULL) return; // Correct source rect based on scaled image. const core::rect<s32> mysrcrect = (scaled != txr) ? core::rect<s32>(0, 0, destrect.getWidth(), destrect.getHeight()) : srcrect; driver->draw2DImage(scaled, destrect, mysrcrect, cliprect, colors, usealpha); }
void GUITable::drawCell(const Cell *cell, video::SColor color, const core::rect<s32> &row_rect, const core::rect<s32> &client_clip) { if ((cell->content_type == COLUMN_TYPE_TEXT) || (cell->content_type == COLUMN_TYPE_TREE)) { core::rect<s32> text_rect = row_rect; text_rect.UpperLeftCorner.X = row_rect.UpperLeftCorner.X + cell->xpos; text_rect.LowerRightCorner.X = row_rect.UpperLeftCorner.X + cell->xmax; if (cell->color_defined) color = cell->color; if (m_font) { if (cell->content_type == COLUMN_TYPE_TEXT) m_font->draw(m_strings[cell->content_index], text_rect, color, false, true, &client_clip); else // tree m_font->draw(cell->content_index ? L"+" : L"-", text_rect, color, false, true, &client_clip); } } else if (cell->content_type == COLUMN_TYPE_IMAGE) { if (cell->content_index < 0) return; video::IVideoDriver *driver = Environment->getVideoDriver(); video::ITexture *image = m_images[cell->content_index]; if (image) { core::position2d<s32> dest_pos = row_rect.UpperLeftCorner; dest_pos.X += cell->xpos; core::rect<s32> source_rect( core::position2d<s32>(0, 0), image->getOriginalSize()); s32 imgh = source_rect.LowerRightCorner.Y; s32 rowh = row_rect.getHeight(); if (imgh < rowh) dest_pos.Y += (rowh - imgh) / 2; else source_rect.LowerRightCorner.Y = rowh; video::SColor color(255, 255, 255, 255); driver->draw2DImage(image, dest_pos, source_rect, &client_clip, color, true); } } }
//! constructor CGUIProfiler::CGUIProfiler(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle, IProfiler* profiler) : IGUIProfiler(environment, parent, id, rectangle, profiler) , Profiler(profiler) , DisplayTable(0), CurrentGroupIdx(0), CurrentGroupPage(0), NumGroupPages(1) , DrawBackground(false), Frozen(false), UnfreezeOnce(false), ShowGroupsTogether(false) , MinCalls(0), MinTimeSum(0), MinTimeAverage(0.f), MinTimeMax(0) { if ( !Profiler ) Profiler = &getProfiler(); core::recti r(0, 0, rectangle.getWidth(), rectangle.getHeight()); // Really just too lazy to code a complete new element for this. // If anyone can do this nicer he's welcome. DisplayTable = Environment->addTable(r, this, -1, DrawBackground); DisplayTable->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); DisplayTable->setSubElement(true); rebuildColumns(); }
//! draws an text and clips it to the specified rectangle if wanted void CGUIFont::draw(const wchar_t* text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip) { if (!Driver) return; core::dimension2d<s32> textDimension; core::position2d<s32> offset = position.UpperLeftCorner; core::rect<s32> pos; if (hcenter || vcenter) { textDimension = getDimension(text); if (hcenter) offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; if (vcenter) offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; }
void CImageGUISkin::drawHorizontalProgressBar( IGUIElement* element, const core::rect<s32>& rectangle, const core::rect<s32>* clip, f32 filledRatio, video::SColor fillColor ) { if ( !Config.ProgressBar.Texture || !Config.ProgressBarFilled.Texture ) { return; } // Draw empty progress bar drawElementStyle( Config.ProgressBar, rectangle, clip ); // Draw filled progress bar on top if ( filledRatio < 0.0f ) filledRatio = 0.0f; else if ( filledRatio > 1.0f ) filledRatio = 1.0f; if ( filledRatio > 0.0f ) { s32 filledPixels = (s32)( filledRatio * rectangle.getSize().Width ); s32 height = rectangle.getSize().Height; core::rect<s32> clipRect = clip? *clip:rectangle; if ( filledPixels < height ) { if ( clipRect.LowerRightCorner.X > rectangle.UpperLeftCorner.X + filledPixels ) clipRect.LowerRightCorner.X = rectangle.UpperLeftCorner.X + filledPixels; filledPixels = height; } core::rect<s32> filledRect = core::rect<s32>( rectangle.UpperLeftCorner.X, rectangle.UpperLeftCorner.Y, rectangle.UpperLeftCorner.X + filledPixels, rectangle.LowerRightCorner.Y ); drawElementStyle( Config.ProgressBarFilled, filledRect, &clipRect, &fillColor ); } }
//! constructor CGUISpinBox::CGUISpinBox(const wchar_t* text, bool border,IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect<s32>& rectangle) : IGUISpinBox(environment, parent, id, rectangle), EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f), RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"), DecimalPlaces(-1) { #ifdef _DEBUG setDebugName("CGUISpinBox"); #endif CurrentIconColor = video::SColor(255,255,255,255); s32 ButtonWidth = 16; IGUISpriteBank *sb = 0; if (environment && environment->getSkin()) { ButtonWidth = environment->getSkin()->getSize(EGDS_SCROLLBAR_SIZE); sb = environment->getSkin()->getSpriteBank(); } ButtonSpinDown = Environment->addButton( core::rect<s32>(rectangle.getWidth() - ButtonWidth, rectangle.getHeight()/2 +1, rectangle.getWidth(), rectangle.getHeight()), this); ButtonSpinDown->grab(); ButtonSpinDown->setSubElement(true); ButtonSpinDown->setTabStop(false); ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT); ButtonSpinUp = Environment->addButton( core::rect<s32>(rectangle.getWidth() - ButtonWidth, 0, rectangle.getWidth(), rectangle.getHeight()/2), this); ButtonSpinUp->grab(); ButtonSpinUp->setSubElement(true); ButtonSpinUp->setTabStop(false); ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER); const core::rect<s32> rectEdit(0, 0, rectangle.getWidth() - ButtonWidth - 1, rectangle.getHeight()); EditBox = Environment->addEditBox(text, rectEdit, border, this, -1); EditBox->grab(); EditBox->setSubElement(true); EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); refreshSprites(); }
//! draws some text and clips it to the specified rectangle if wanted void CGUIFont::draw(const wchar_t* text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip) { if (!Driver) return; core::dimension2d<s32> textDimension; core::position2d<s32> offset = position.UpperLeftCorner; core::rect<s32> pos; if (hcenter || vcenter || clip) textDimension = getDimension(text); if (hcenter) offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; if (vcenter) offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; if (clip) { core::rect<s32> clippedRect(offset, textDimension); clippedRect.clipAgainst(*clip); if (!clippedRect.isValid()) return; } while(*text) { SFontArea& area = Areas[getAreaFromCharacter(*text)]; offset.X += area.underhang; SpriteBank->draw2DSprite(area.spriteno, offset, clip, color); offset.X += area.width + area.overhang + GlobalKerningWidth; ++text; } }
//! draws an text and clips it to the specified rectangle if wanted void CGUITTFont::draw(const core::stringw& text_, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip) { const wchar_t* text = text_.c_str(); if (!Driver) return; core::dimension2d<u32> textDimension; core::position2d<s32> offset = position.UpperLeftCorner; video::SColor colors[4]; for (int i = 0;i < 4;i++){ colors[i] = color; } if (hcenter || vcenter) { textDimension = getDimension(text); if (hcenter) offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; if (vcenter) offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; }
//! constructor CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) : IGUIComboBox(environment, parent, id, rectangle), ListButton(0), ListBox(0), Selected(-1), HasFocus(false), LastFocus(0) { #ifdef _DEBUG setDebugName("CGUICheckBox"); #endif IGUISkin* skin = Environment->getSkin(); s32 width = 15; if (skin) width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); core::rect<s32> r; r.UpperLeftCorner.X = rectangle.getWidth() - width - 2; r.LowerRightCorner.X = rectangle.getWidth() - 2; r.UpperLeftCorner.Y = 2; r.LowerRightCorner.Y = rectangle.getHeight() - 2; ListButton = Environment->addButton(r, this, -1, L""); if (skin && skin->getSpriteBank()) { ListButton->setSpriteBank(skin->getSpriteBank()); ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); } ListButton->setSubElement(true); ListButton->setTabStop(false); // this element can be tabbed to setTabStop(true); setTabOrder(-1); }
void CImageGUISkin::drawElementStyle( const SImageGUIElementStyle& elem, const core::rect<s32>& rect, const core::rect<s32>* clip, video::SColor* pcolor ) { core::rect<s32> srcRect; core::rect<s32> dstRect; core::dimension2d< u32 > tsize = elem.Texture->getSize(); video::ITexture* texture = elem.Texture; video::SColor color = elem.Color; if ( pcolor ) color = *pcolor; video::SColor faceColor = getColor(EGDC_3D_FACE); color.setRed( (u8)(color.getRed() * faceColor.getRed() / 255) ); color.setGreen( (u8)(color.getGreen() * faceColor.getGreen() / 255) ); color.setBlue( (u8)(color.getBlue() * faceColor.getBlue() / 255) ); color.setAlpha( (u8)(color.getAlpha() * faceColor.getAlpha() / 255 ) ); video::SColor colors [4] = { color, color, color, color }; core::dimension2di dstSize = rect.getSize(); // Scale the border if there is insufficient room SImageGUIElementStyle::SBorder dst = elem.DstBorder; f32 scale = 1.0f; if ( dstSize.Width < dst.Left + dst.Right ) { scale = dstSize.Width / (f32)( dst.Left + dst.Right ); } if ( dstSize.Height < dst.Top + dst.Bottom ) { f32 x = dstSize.Height / (f32)( dst.Top + dst.Bottom ); if ( x < scale ) { scale = x; } } if ( scale < 1.0f ) { dst.Left = (s32)( dst.Left * scale ); dst.Right = (s32)( dst.Right * scale ); dst.Top = (s32)( dst.Top * scale ); dst.Bottom = (s32)( dst.Bottom * scale ); } const SImageGUIElementStyle::SBorder& src = elem.SrcBorder; // Draw the top left corner srcRect = core::rect<s32>( 0, 0, src.Left, src.Top ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X, rect.UpperLeftCorner.Y, rect.UpperLeftCorner.X+dst.Left, rect.UpperLeftCorner.Y+dst.Top ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the top right corner srcRect = core::rect<s32>( tsize.Width-src.Right, 0, tsize.Width, src.Top ); dstRect = core::rect<s32>( rect.LowerRightCorner.X-dst.Right, rect.UpperLeftCorner.Y, rect.LowerRightCorner.X, rect.UpperLeftCorner.Y+dst.Top ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the top border srcRect = core::rect<s32>( src.Left, 0, tsize.Width-src.Right, src.Top ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X+dst.Left, rect.UpperLeftCorner.Y, rect.LowerRightCorner.X-dst.Right, rect.UpperLeftCorner.Y+dst.Top ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the left border srcRect = core::rect<s32>( 0, src.Top, src.Left, tsize.Height-src.Bottom ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X, rect.UpperLeftCorner.Y+dst.Top, rect.UpperLeftCorner.X+dst.Left, rect.LowerRightCorner.Y-dst.Bottom ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the right border srcRect = core::rect<s32>( tsize.Width-src.Right, src.Top, tsize.Width, tsize.Height-src.Bottom ); dstRect = core::rect<s32>( rect.LowerRightCorner.X-dst.Right, rect.UpperLeftCorner.Y+dst.Top, rect.LowerRightCorner.X, rect.LowerRightCorner.Y-dst.Bottom ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the middle section srcRect = core::rect<s32>( src.Left, src.Top, tsize.Width-src.Right, tsize.Height-src.Bottom ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X+dst.Left, rect.UpperLeftCorner.Y+dst.Top, rect.LowerRightCorner.X-dst.Right, rect.LowerRightCorner.Y-dst.Bottom ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the bottom left corner srcRect = core::rect<s32>( 0, tsize.Height-src.Bottom, src.Left, tsize.Height ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X, rect.LowerRightCorner.Y-dst.Bottom, rect.UpperLeftCorner.X+dst.Left, rect.LowerRightCorner.Y ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the bottom right corner srcRect = core::rect<s32>( tsize.Width-src.Right, tsize.Height-src.Bottom, tsize.Width, tsize.Height ); dstRect = core::rect<s32>( rect.LowerRightCorner.X-dst.Right, rect.LowerRightCorner.Y-dst.Bottom, rect.LowerRightCorner.X, rect.LowerRightCorner.Y ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); // Draw the bottom border srcRect = core::rect<s32>( src.Left, tsize.Height-src.Bottom, tsize.Width-src.Right, tsize.Height ); dstRect = core::rect<s32>( rect.UpperLeftCorner.X+dst.Left, rect.LowerRightCorner.Y-dst.Bottom, rect.LowerRightCorner.X-dst.Right, rect.LowerRightCorner.Y ); if ( !clip || clipRects( dstRect, srcRect, *clip ) ) VideoDriver->draw2DImage( texture, dstRect, srcRect, clip, colors, true ); }
void ScalableFont::doDraw(const core::stringw& text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip, FontCharCollector* charCollector) { if (!m_video_driver) return; GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator(); if (m_shadow) { m_shadow = false; // avoid infinite recursion core::rect<s32> shadowpos = position; shadowpos.LowerRightCorner.X += 2; shadowpos.LowerRightCorner.Y += 2; draw(text, shadowpos, m_shadow_color, hcenter, vcenter, clip); m_shadow = true; // set back } core::position2d<s32> offset = position.UpperLeftCorner; core::dimension2d<s32> text_dimension; if (m_rtl || hcenter || vcenter || clip) { text_dimension = getDimension(text.c_str()); if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) / 2; else if (m_rtl) offset.X += (position.getWidth() - text_dimension.Width); if (vcenter) offset.Y += (position.getHeight() - text_dimension.Height) / 2; if (clip) { core::rect<s32> clippedRect(offset, text_dimension); clippedRect.clipAgainst(*clip); if (!clippedRect.isValid()) return; } } // ---- collect character locations const unsigned int text_size = text.size(); core::array<s32> indices(text_size); core::array<core::position2di> offsets(text_size); std::vector<bool> fallback(text_size); if (m_type == T_NORMAL || T_BOLD) //lazy load char, have to do this again { //because some text isn't drawn with getDimension for (u32 i = 0; i < text_size; i++) { wchar_t c = text[i]; if (c == L'\r' || c == L'\n' || c == L' ' || c < 32) continue; if (!GUIEngine::getFont()->hasThisChar(c)) gp_creator->insertChar(c); if (charCollector != NULL && m_type == T_NORMAL && m_spritebank->getSprites() [GUIEngine::getFont()->getSpriteNoFromChar(&c)].Frames[0].textureNumber == m_spritebank->getTextureCount() - 1) //Prevent overwriting texture used by billboard text { Log::debug("ScalableFont::doDraw", "Character used by billboard text is in the last " "glyph page of normal font. Create a new glyph " "page for new characters inserted later to prevent " "it from being removed."); GUIEngine::getFont()->forceNewPage(); } } if (gp_creator->getNewChar().size() > 0 && !m_is_hollow_copy && m_scale == 1) { Log::debug("ScalableFont::doDraw", "New character(s) %s discoverd, perform lazy loading", StringUtils::wideToUtf8(gp_creator->getNewChar()).c_str()); if (!GUIEngine::getFont()->lazyLoadChar()) Log::error("ScalableFont::lazyLoadChar", "Can't insert new char into glyph pages."); } } for (u32 i = 0; i < text_size; i++) { wchar_t c = text[i]; if (c == L'\r' || // Windows breaks c == L'\n' ) // Unix breaks { if(c==L'\r' && text[i+1]==L'\n') c = text[++i]; offset.Y += (int)(m_max_height*m_scale); offset.X = position.UpperLeftCorner.X; if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) >> 1; continue; } // if lineBreak bool use_fallback_font = false; const SFontArea &area = getAreaFromCharacter(c, &use_fallback_font); fallback[i] = use_fallback_font; if (charCollector == NULL) { //Try to use ceil to make offset calculate correctly when m_scale is smaller than 1 s32 glyph_offset_x = (s32)((float) area.bearingx* (fallback[i] ? m_scale*m_fallback_font_scale : m_scale)); s32 glyph_offset_y = (s32)ceil((float) area.offsety* (fallback[i] ? m_scale*m_fallback_font_scale : m_scale)); offset.X += glyph_offset_x; offset.Y += s32(glyph_offset_y + floor(m_type == T_DIGIT ? 20*m_scale : 0)); //Additional offset for digit text offsets.push_back(offset); offset.X -= glyph_offset_x; offset.Y -= s32(glyph_offset_y + floor(m_type == T_DIGIT ? 20*m_scale : 0)); } else //Billboard text specific { s32 glyph_offset_x = (s32)ceil((float) area.bearingx* (fallback[i] ? m_scale*m_fallback_font_scale : m_scale)); s32 glyph_offset_y = (s32)ceil((float) area.offsety_bt* (fallback[i] ? m_scale*m_fallback_font_scale : m_scale)); offset.X += glyph_offset_x; offset.Y += s32(glyph_offset_y + floor(m_type == T_DIGIT ? 20*m_scale : 0)); //Additional offset for digit text offsets.push_back(offset); offset.X -= glyph_offset_x; offset.Y -= s32(glyph_offset_y + floor(m_type == T_DIGIT ? 20*m_scale : 0)); } // Invisible character. add something to the array anyway so that // indices from the various arrays remain in sync indices.push_back(m_invisible.findFirst(c) < 0 ? area.spriteno : -1); offset.X += getCharWidth(area, fallback[i]); } // for i<text_size // ---- do the actual rendering const int indiceAmount = indices.size(); core::array< SGUISprite >& sprites = m_spritebank->getSprites(); core::array< core::rect<s32> >& positions = m_spritebank->getPositions(); core::array< SGUISprite >* fallback_sprites; core::array< core::rect<s32> >* fallback_positions; if (m_fallback_font != NULL) { fallback_sprites = &m_fallback_font->m_spritebank->getSprites(); fallback_positions = &m_fallback_font->m_spritebank->getPositions(); } else { fallback_sprites = NULL; fallback_positions = NULL; } const int spriteAmount = sprites.size(); if (m_black_border && charCollector == NULL) { //Draw black border first, to make it behind the real character //which make script language display better video::SColor black(color.getAlpha(),0,0,0); for (int n = 0; n < indiceAmount; n++) { const int spriteID = indices[n]; if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount)) continue; if (indices[n] == -1) continue; const int texID = (fallback[n] ? (*fallback_sprites)[spriteID].Frames[0].textureNumber : sprites[spriteID].Frames[0].textureNumber); core::rect<s32> source = (fallback[n] ? (*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] : positions[sprites[spriteID].Frames[0].rectNumber]); core::dimension2d<s32> size = source.getSize(); float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale); size.Width = (int)(size.Width * scale); size.Height = (int)(size.Height * scale); core::rect<s32> dest(offsets[n], size); video::ITexture* texture = (fallback[n] ? m_fallback_font->m_spritebank->getTexture(texID) : m_spritebank->getTexture(texID) ); for (int x_delta = -2; x_delta <= 2; x_delta++) { for (int y_delta = -2; y_delta <= 2; y_delta++) { if (x_delta == 0 || y_delta == 0) continue; draw2DImage(texture, dest + core::position2d<s32>(x_delta, y_delta), source, clip, black, true); } } } } for (int n = 0; n < indiceAmount; n++) { const int spriteID = indices[n]; if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount)) continue; if (indices[n] == -1) continue; //assert(sprites[spriteID].Frames.size() > 0); const int texID = (fallback[n] ? (*fallback_sprites)[spriteID].Frames[0].textureNumber : sprites[spriteID].Frames[0].textureNumber); core::rect<s32> source = (fallback[n] ? (*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] : positions[sprites[spriteID].Frames[0].rectNumber]); core::dimension2d<s32> size = source.getSize(); float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale); size.Width = (int)(size.Width * scale); size.Height = (int)(size.Height * scale); core::rect<s32> dest(offsets[n], size); video::ITexture* texture = (fallback[n] ? m_fallback_font->m_spritebank->getTexture(texID) : m_spritebank->getTexture(texID) ); /* if (fallback[n]) { Log::info("ScalableFont", "Using fallback font %s; source area is %d, %d; size %d, %d; dest = %d, %d", core::stringc(texture->getName()).c_str(), source.UpperLeftCorner.X, source.UpperLeftCorner.Y, source.getWidth(), source.getHeight(), offsets[n].X, offsets[n].Y); } */ #ifdef FONT_DEBUG GL32_draw2DRectangle(video::SColor(255, 255,0,0), dest,clip); #endif if (fallback[n] || m_type == T_BOLD) { video::SColor top = GUIEngine::getSkin()->getColor("font::top"); video::SColor bottom = GUIEngine::getSkin()->getColor("font::bottom"); top.setAlpha(color.getAlpha()); bottom.setAlpha(color.getAlpha()); video::SColor title_colors[] = {top, bottom, top, bottom}; if (charCollector != NULL) { charCollector->collectChar(texture, dest, source, title_colors); } else { draw2DImage(texture, dest, source, clip, title_colors, true); } } else { if (charCollector != NULL) { video::SColor colors[] = { color, color, color, color }; charCollector->collectChar(texture, dest, source, colors); } else { draw2DImage(texture, dest, source, clip, color, true); } } } }
//! draws some text and clips it to the specified rectangle if wanted void CGUIFont::draw(const core::stringw& text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip ) { if (!Driver) return; core::dimension2d<s32> textDimension; // NOTE: don't make this u32 or the >> later on can fail when the dimension width is < position width core::position2d<s32> offset = position.UpperLeftCorner; if (hcenter || vcenter || clip) textDimension = getDimension(text.c_str()); if (hcenter) offset.X += (position.getWidth() - textDimension.Width) >> 1; if (vcenter) offset.Y += (position.getHeight() - textDimension.Height) >> 1; if (clip) { core::rect<s32> clippedRect(offset, textDimension); clippedRect.clipAgainst(*clip); if (!clippedRect.isValid()) return; } core::array<u32> indices(text.size()); core::array<core::position2di> offsets(text.size()); for(u32 i = 0; i < text.size(); i++) { wchar_t c = text[i]; bool lineBreak=false; if ( c == L'\r') // Mac or Windows breaks { lineBreak = true; if ( text[i + 1] == L'\n') // Windows breaks c = text[++i]; } else if ( c == L'\n') // Unix breaks { lineBreak = true; } if (lineBreak) { offset.Y += MaxHeight; offset.X = position.UpperLeftCorner.X; if ( hcenter ) { offset.X += (position.getWidth() - textDimension.Width) >> 1; } continue; } SFontArea& area = Areas[getAreaFromCharacter(c)]; offset.X += area.underhang; if ( Invisible.findFirst ( c ) < 0 ) { indices.push_back(area.spriteno); offsets.push_back(offset); } offset.X += area.width + area.overhang + GlobalKerningWidth; } SpriteBank->draw2DSpriteBatch(indices, offsets, clip, color); }
void drawItemStack(video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, const core::rect<s32> &rect, const core::rect<s32> *clip, IGameDef *gamedef) { if(item.empty()) return; const ItemDefinition &def = item.getDefinition(gamedef->idef()); video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef); // Draw the inventory texture if(texture != NULL) { const video::SColor color(255,255,255,255); const video::SColor colors[] = {color,color,color,color}; driver->draw2DImage(texture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(texture->getOriginalSize())), clip, colors, true); } if(def.type == ITEM_TOOL && item.wear != 0) { // Draw a progressbar float barheight = rect.getHeight()/16; float barpad_x = rect.getWidth()/16; float barpad_y = rect.getHeight()/16; core::rect<s32> progressrect( rect.UpperLeftCorner.X + barpad_x, rect.LowerRightCorner.Y - barpad_y - barheight, rect.LowerRightCorner.X - barpad_x, rect.LowerRightCorner.Y - barpad_y); // Shrink progressrect by amount of tool damage float wear = item.wear / 65535.0; int progressmid = wear * progressrect.UpperLeftCorner.X + (1-wear) * progressrect.LowerRightCorner.X; // Compute progressbar color // wear = 0.0: green // wear = 0.5: yellow // wear = 1.0: red video::SColor color(255,255,255,255); int wear_i = MYMIN(floor(wear * 600), 511); wear_i = MYMIN(wear_i + 10, 511); if(wear_i <= 255) color.set(255, wear_i, 255, 0); else color.set(255, 255, 511-wear_i, 0); core::rect<s32> progressrect2 = progressrect; progressrect2.LowerRightCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); color = video::SColor(255,0,0,0); progressrect2 = progressrect; progressrect2.UpperLeftCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); } if(font != NULL && item.count >= 2) { // Get the item count as a string std::string text = itos(item.count); v2u32 dim = font->getDimension(narrow_to_wide(text).c_str()); v2s32 sdim(dim.X,dim.Y); core::rect<s32> rect2( /*rect.UpperLeftCorner, core::dimension2d<u32>(rect.getWidth(), 15)*/ rect.LowerRightCorner - sdim, sdim ); video::SColor bgcolor(128,0,0,0); driver->draw2DRectangle(bgcolor, rect2, clip); video::SColor color(255,255,255,255); font->draw(text.c_str(), rect2, color, false, false, clip); } }
// ---------------------------------------------------------------------------- void FontWithFace::render(const core::stringw& text, const core::rect<s32>& position, const video::SColor& color, bool hcenter, bool vcenter, const core::rect<s32>* clip, FontSettings* font_settings, FontCharCollector* char_collector) { const bool is_bold_face = dynamic_cast<BoldFace*>(this); const bool black_border = font_settings ? font_settings->useBlackBorder() : false; const bool rtl = font_settings ? font_settings->isRTL() : false; const float scale = font_settings ? font_settings->getScale() : 1.0f; const float shadow = font_settings ? font_settings->useShadow() : false; if (shadow) { assert(font_settings); // Avoid infinite recursion font_settings->setShadow(false); core::rect<s32> shadowpos = position; shadowpos.LowerRightCorner.X += 2; shadowpos.LowerRightCorner.Y += 2; render(text, shadowpos, font_settings->getShadowColor(), hcenter, vcenter, clip, font_settings); // Set back font_settings->setShadow(true); } core::position2d<float> offset(float(position.UpperLeftCorner.X), float(position.UpperLeftCorner.Y)); core::dimension2d<s32> text_dimension; if (rtl || hcenter || vcenter || clip) { text_dimension = getDimension(text.c_str(), font_settings); if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) / 2; else if (rtl) offset.X += (position.getWidth() - text_dimension.Width); if (vcenter) offset.Y += (position.getHeight() - text_dimension.Height) / 2; if (clip) { core::rect<s32> clippedRect(core::position2d<s32> (s32(offset.X), s32(offset.Y)), text_dimension); clippedRect.clipAgainst(*clip); if (!clippedRect.isValid()) return; } } // Collect character locations const unsigned int text_size = text.size(); core::array<s32> indices(text_size); core::array<core::position2d<float>> offsets(text_size); std::vector<bool> fallback(text_size); // Test again if lazy load char is needed, // as some text isn't drawn with getDimension insertCharacters(text.c_str()); updateCharactersList(); for (u32 i = 0; i < text_size; i++) { wchar_t c = text[i]; if (c == L'\r' || // Windows breaks c == L'\n' ) // Unix breaks { if (c==L'\r' && text[i+1]==L'\n') c = text[++i]; offset.Y += m_font_max_height * scale; offset.X = position.UpperLeftCorner.X; if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) >> 1; continue; } // if lineBreak bool use_fallback_font = false; const FontArea &area = getAreaFromCharacter(c, &use_fallback_font); fallback[i] = use_fallback_font; if (char_collector == NULL) { float glyph_offset_x = area.bearing_x * (fallback[i] ? m_fallback_font_scale : scale); float glyph_offset_y = area.offset_y * (fallback[i] ? m_fallback_font_scale : scale); offset.X += glyph_offset_x; offset.Y += glyph_offset_y; offsets.push_back(offset); offset.X -= glyph_offset_x; offset.Y -= glyph_offset_y; } else { // Prevent overwriting texture used by billboard text when // using lazy loading characters if (supportLazyLoadChar() && fallback[i]) { const int cur_texno = m_fallback_font->getSpriteBank() ->getSprites()[area.spriteno].Frames[0].textureNumber; if (cur_texno == int(m_fallback_font->getSpriteBank() ->getTextureCount() - 1)) { m_fallback_font->createNewGlyphPage(); } } else if (supportLazyLoadChar()) { const int cur_texno = m_spritebank ->getSprites()[area.spriteno].Frames[0].textureNumber; if (cur_texno == int(m_spritebank->getTextureCount() - 1)) { createNewGlyphPage(); } } // Billboard text specific, use offset_y_bt instead float glyph_offset_x = area.bearing_x * (fallback[i] ? m_fallback_font_scale : scale); float glyph_offset_y = area.offset_y_bt * (fallback[i] ? m_fallback_font_scale : scale); offset.X += glyph_offset_x; offset.Y += glyph_offset_y; offsets.push_back(offset); offset.X -= glyph_offset_x; offset.Y -= glyph_offset_y; } indices.push_back(area.spriteno); offset.X += getCharWidth(area, fallback[i], scale); } // for i < text_size // Do the actual rendering const int indice_amount = indices.size(); core::array<gui::SGUISprite>& sprites = m_spritebank->getSprites(); core::array<core::rect<s32>>& positions = m_spritebank->getPositions(); core::array<gui::SGUISprite>* fallback_sprites; core::array<core::rect<s32>>* fallback_positions; if (m_fallback_font != NULL) { fallback_sprites = &m_fallback_font->m_spritebank->getSprites(); fallback_positions = &m_fallback_font->m_spritebank->getPositions(); } else { fallback_sprites = NULL; fallback_positions = NULL; } const int sprite_amount = sprites.size(); if ((black_border || is_bold_face) && char_collector == NULL) { // Draw black border first, to make it behind the real character // which make script language display better video::SColor black(color.getAlpha(),0,0,0); for (int n = 0; n < indice_amount; n++) { const int sprite_id = indices[n]; if (!fallback[n] && (sprite_id < 0 || sprite_id >= sprite_amount)) continue; if (indices[n] == -1) continue; const int tex_id = (fallback[n] ? (*fallback_sprites)[sprite_id].Frames[0].textureNumber : sprites[sprite_id].Frames[0].textureNumber); core::rect<s32> source = (fallback[n] ? (*fallback_positions) [(*fallback_sprites)[sprite_id].Frames[0].rectNumber] : positions[sprites[sprite_id].Frames[0].rectNumber]); core::dimension2d<float> size(0.0f, 0.0f); float cur_scale = (fallback[n] ? m_fallback_font_scale : scale); size.Width = source.getSize().Width * cur_scale; size.Height = source.getSize().Height * cur_scale; core::rect<float> dest(offsets[n], size); video::ITexture* texture = (fallback[n] ? m_fallback_font->m_spritebank->getTexture(tex_id) : m_spritebank->getTexture(tex_id)); for (int x_delta = -2; x_delta <= 2; x_delta++) { for (int y_delta = -2; y_delta <= 2; y_delta++) { if (x_delta == 0 || y_delta == 0) continue; draw2DImage(texture, dest + core::position2d<float> (float(x_delta), float(y_delta)), source, clip, black, true); } } } } for (int n = 0; n < indice_amount; n++) { const int sprite_id = indices[n]; if (!fallback[n] && (sprite_id < 0 || sprite_id >= sprite_amount)) continue; if (indices[n] == -1) continue; const int tex_id = (fallback[n] ? (*fallback_sprites)[sprite_id].Frames[0].textureNumber : sprites[sprite_id].Frames[0].textureNumber); core::rect<s32> source = (fallback[n] ? (*fallback_positions)[(*fallback_sprites)[sprite_id].Frames[0] .rectNumber] : positions[sprites[sprite_id].Frames[0].rectNumber]); core::dimension2d<float> size(0.0f, 0.0f); float cur_scale = (fallback[n] ? m_fallback_font_scale : scale); size.Width = source.getSize().Width * cur_scale; size.Height = source.getSize().Height * cur_scale; core::rect<float> dest(offsets[n], size); video::ITexture* texture = (fallback[n] ? m_fallback_font->m_spritebank->getTexture(tex_id) : m_spritebank->getTexture(tex_id)); if (fallback[n] || is_bold_face) { video::SColor top = GUIEngine::getSkin()->getColor("font::top"); video::SColor bottom = GUIEngine::getSkin() ->getColor("font::bottom"); top.setAlpha(color.getAlpha()); bottom.setAlpha(color.getAlpha()); video::SColor title_colors[] = {top, bottom, top, bottom}; if (char_collector != NULL) { char_collector->collectChar(texture, dest, source, title_colors); } else { draw2DImage(texture, dest, source, clip, title_colors, true); } } else { if (char_collector != NULL) { video::SColor colors[] = {color, color, color, color}; char_collector->collectChar(texture, dest, source, colors); } else { draw2DImage(texture, dest, source, clip, color, true); } } } } // render
//! constructor CGUIPlot::CGUIPlot( scene::ISceneManager* smgr, IGUIEnvironment* env, IGUIElement* parent, s32 id, const core::rect<s32>& rectangle) : IGUIElement( EGUIET_ELEMENT, env, parent, id, rectangle) //, Viewport(0,0,0,0) , ZoomRect(-1,-4,10,5) , Plotrect(0,0,0,0) , IsDrawBackground(false) , BackgroundColor(video::SColor(255,255,255,255)) , TextColor(video::SColor(255,0,0,0)) , IsDrawGrid(true) , GridColor(video::SColor(255,200,200,200)) , SubGridColor(video::SColor(255,235,235,235)) , SceneManager(smgr) , Root(0) , Camera(0) { #ifdef _DEBUG setDebugName("CGUIPlot"); #endif // this element can be tabbed to setTabStop(false); setTabOrder(-1); IGUISkin *skin = 0; if (Environment) skin = Environment->getSkin(); //FrameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1; //FrameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; //FrameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1; //FrameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; // TextColor=skin->getColor(EGDC_HIGH_LIGHT_TEXT); s32 w = rectangle.getWidth(); // in pixels s32 h = rectangle.getHeight(); // in pixels s32 sb_size = 16; // in pixels core::recti r_canvas = makeRect(0,0, (u32)(w-sb_size-1), (u32)(h-sb_size-1) ); core::recti r_scrollH = makeRect(1,h-sb_size, (u32)(w-sb_size-1), (u32)sb_size ); core::recti r_scrollV = makeRect( w-sb_size, 1, (u32)sb_size, (u32)(h-sb_size-1) ); core::recti r_reset = makeRect( w-sb_size, h-sb_size, (u32)sb_size, (u32)sb_size ); Plotrect = r_canvas; //! visible ContentRect, Viewport is projected to this rect ScrollbarH = Environment->addScrollBar(true,r_scrollH,this,-1); ScrollbarH->setVisible(true); ScrollbarH->setSubElement(false); ScrollbarH->setTabStop(false); ScrollbarH->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); ScrollbarH->setSmallStep(3); ScrollbarH->setMin(0); ScrollbarH->setMax(100); ScrollbarH->setPos(0); ScrollbarV = Environment->addScrollBar(false,r_scrollV,this,-1); ScrollbarV->setVisible(true); ScrollbarV->setSubElement(false); ScrollbarV->setTabStop(false); ScrollbarV->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); ScrollbarV->setMin(0); ScrollbarV->setMax(100); ScrollbarV->setSmallStep(3); ScrollbarV->setPos(0); Environment->addButton( r_reset, this, -1, L"R", L"Reset Zoom Button"); BackgroundColor=skin->getColor(EGDC_WINDOW); ContentPane = 0; Environment->setFocus(this); // // SceneManager = new scene::CSceneManager( // Environment->getVideoDriver(), Environment->getFileSystem(), 0, 0, Environment); _IRR_DEBUG_BREAK_IF( !SceneManager ) // if (!SceneManager) // { // printf("CGUIPlot::Could not create SceneManager\n"); // return; // } Root = SceneManager->addEmptySceneNode( SceneManager->getRootSceneNode(), -1); _IRR_DEBUG_BREAK_IF( !Root ) Camera = SceneManager->addCameraSceneNode( Root, core::vector3df(0,0,-100), core::vector3df(0,0,100), -1, false); _IRR_DEBUG_BREAK_IF( !Camera ) Root->setVisible( false ); /// Prepare some SceneNodes for x,y Axis and Grid //scene::ISceneManager* SceneManager = SceneManager; gui::IGUIFont* font = Environment->getBuiltInFont(); scene::ITextSceneNode* textNode00 = SceneManager->addTextSceneNode( font, L"(0,0)", TextColor, SceneManager->getRootSceneNode(), core::vector3df(0,0,0) ); scene::ITextSceneNode* textNodeX = SceneManager->addTextSceneNode( font, L"X", TextColor, SceneManager->getRootSceneNode(), core::vector3df(ZoomRect.LowerRightCorner.X,0,0) ); scene::ITextSceneNode* textNodeY = SceneManager->addTextSceneNode( font, L"Y", TextColor, SceneManager->getRootSceneNode(), core::vector3df(0, ZoomRect.UpperLeftCorner.Y,0) ); addShape( textNode00, L"Ursprung" ); addShape( textNodeX, L"X-Axis" ); addShape( textNodeY, L"Y-Axis" ); }
//! draws some text and clips it to the specified rectangle if wanted void ScalableFont::doDraw(const core::stringw& text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip, FontCharCollector* charCollector) { if (!Driver) return; if (m_shadow) { m_shadow = false; // avoid infinite recursion core::rect<s32> shadowpos = position; shadowpos.LowerRightCorner.X += 2; shadowpos.LowerRightCorner.Y += 2; draw(text, shadowpos, m_shadow_color, hcenter, vcenter, clip); m_shadow = true; // set back } core::position2d<s32> offset = position.UpperLeftCorner; core::dimension2d<s32> text_dimension; if (m_rtl || hcenter || vcenter || clip) { text_dimension = getDimension(text.c_str()); if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) / 2; else if (m_rtl) offset.X += (position.getWidth() - text_dimension.Width); if (vcenter) offset.Y += (position.getHeight() - text_dimension.Height) / 2; if (clip) { core::rect<s32> clippedRect(offset, text_dimension); clippedRect.clipAgainst(*clip); if (!clippedRect.isValid()) return; } } // ---- collect character locations const unsigned int text_size = text.size(); core::array<s32> indices(text_size); core::array<core::position2di> offsets(text_size); std::vector<bool> fallback(text_size); for (u32 i = 0; i<text_size; i++) { wchar_t c = text[i]; if (c == L'\r' || // Windows breaks c == L'\n' ) // Unix breaks { if(c==L'\r' && text[i+1]==L'\n') c = text[++i]; offset.Y += (int)(MaxHeight*m_scale); offset.X = position.UpperLeftCorner.X; if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) >> 1; continue; } // if lineBreak bool use_fallback_font = false; const SFontArea &area = getAreaFromCharacter(c, &use_fallback_font); fallback[i] = use_fallback_font; offset.X += area.underhang; offsets.push_back(offset); // Invisible character. add something to the array anyway so that // indices from the various arrays remain in sync indices.push_back( Invisible.findFirst(c) < 0 ? area.spriteno : -1 ); offset.X += getCharWidth(area, fallback[i]); } // for i<text_size // ---- do the actual rendering const int indiceAmount = indices.size(); core::array< SGUISprite >& sprites = SpriteBank->getSprites(); core::array< core::rect<s32> >& positions = SpriteBank->getPositions(); core::array< SGUISprite >* fallback_sprites; core::array< core::rect<s32> >* fallback_positions; if(m_fallback_font!=NULL) { fallback_sprites = &m_fallback_font->SpriteBank->getSprites(); fallback_positions = &m_fallback_font->SpriteBank->getPositions(); } else { fallback_sprites = NULL; fallback_positions = NULL; } const int spriteAmount = sprites.size(); for (int n=0; n<indiceAmount; n++) { const int spriteID = indices[n]; if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount)) continue; if (indices[n] == -1) continue; //assert(sprites[spriteID].Frames.size() > 0); const int texID = (fallback[n] ? (*fallback_sprites)[spriteID].Frames[0].textureNumber : sprites[spriteID].Frames[0].textureNumber); core::rect<s32> source = (fallback[n] ? (*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] : positions[sprites[spriteID].Frames[0].rectNumber]); const TextureInfo& info = (fallback[n] ? (*(m_fallback_font->m_texture_files.find(texID))).second : (*(m_texture_files.find(texID))).second ); float char_scale = info.m_scale; core::dimension2d<s32> size = source.getSize(); float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale); size.Width = (int)(size.Width * scale * char_scale); size.Height = (int)(size.Height * scale * char_scale); // align vertically if character is smaller int y_shift = (size.Height < MaxHeight*m_scale ? (int)((MaxHeight*m_scale - size.Height)/2.0f) : 0); core::rect<s32> dest(offsets[n] + core::position2di(0, y_shift), size); video::ITexture* texture = (fallback[n] ? m_fallback_font->SpriteBank->getTexture(texID) : SpriteBank->getTexture(texID) ); /* if (fallback[n]) { Log::info("ScalableFont", "Using fallback font %s; source area is %d, %d; size %d, %d; dest = %d, %d", core::stringc(texture->getName()).c_str(), source.UpperLeftCorner.X, source.UpperLeftCorner.Y, source.getWidth(), source.getHeight(), offsets[n].X, offsets[n].Y); } */ if (texture == NULL) { // perform lazy loading if (fallback[n]) { m_fallback_font->lazyLoadTexture(texID); texture = m_fallback_font->SpriteBank->getTexture(texID); } else { lazyLoadTexture(texID); texture = SpriteBank->getTexture(texID); } if (texture == NULL) { Log::warn("ScalableFont", "Character not found in current font"); continue; // no such character } } if (m_black_border && charCollector == NULL) { // draw black border video::SColor black(color.getAlpha(),0,0,0); for (int x_delta=-2; x_delta<=2; x_delta++) { for (int y_delta=-2; y_delta<=2; y_delta++) { if (x_delta == 0 || y_delta == 0) continue; draw2DImage(texture, dest + core::position2d<s32>(x_delta, y_delta), source, clip, black, true); } } } if (fallback[n]) { // TODO: don't hardcode colors? video::SColor orange(color.getAlpha(), 255, 100, 0); video::SColor yellow(color.getAlpha(), 255, 220, 15); video::SColor title_colors[] = {orange, yellow, orange, yellow}; if (charCollector != NULL) { charCollector->collectChar(texture, dest, source, title_colors); } else { draw2DImage(texture, dest, source, clip, title_colors, true); } } else { if (charCollector != NULL) { video::SColor colors[] = { color, color, color, color }; charCollector->collectChar(texture, dest, source, colors); } else { draw2DImage(texture, dest, source, clip, color, true); } #ifdef FONT_DEBUG video::IVideoDriver* driver = GUIEngine::getDriver(); driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y), core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y), video::SColor(255, 255,0,0)); driver->draw2DLine(core::position2d<s32>(dest.LowerRightCorner.X, dest.LowerRightCorner.Y), core::position2d<s32>(dest.LowerRightCorner.X, dest.UpperLeftCorner.Y), video::SColor(255, 255,0,0)); driver->draw2DLine(core::position2d<s32>(dest.LowerRightCorner.X, dest.LowerRightCorner.Y), core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y), video::SColor(255, 255,0,0)); driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y), core::position2d<s32>(dest.LowerRightCorner.X, dest.UpperLeftCorner.Y), video::SColor(255, 255,0,0)); #endif } } }