void VisualExplodingImage::ExplosionUnit::setColor(uint32 color, const Graphics::PixelFormat &format) { _mainColor = color; byte a, r, g, b; format.colorToARGB(color, a, r, g, b); r >>= 1; g >>= 1; b >>= 1; _darkColor = format.ARGBToColor(a, r, g, b); }
SaveDataWidget::SaveDataWidget(int slot, Gfx::Driver *gfx, SaveLoadMenuScreen *screen) : StaticLocationWidget(nullptr, nullptr, nullptr), _slot(slot), _screen(screen), _thumbWidth(StarkUserInterface->kThumbnailWidth), _thumbHeight(StarkUserInterface->kThumbnailHeight), _texture(gfx->createTexture()), _outline(gfx->createTexture()), _surfaceRenderer(gfx->createSurfaceRenderer()), _textDesc(gfx), _textTime(gfx), _isMouseHovered(false), _hasSave(false), _name() { // Load from the save data loadSaveDataElements(); _textDesc.setColor(_textColor); _textDesc.setFont(FontProvider::kCustomFont, 3); _textTime.setColor(_textColor); _textTime.setFont(FontProvider::kCustomFont, 3); Graphics::PixelFormat pixelFormat = Gfx::Driver::getRGBAPixelFormat(); uint32 outlineColor = pixelFormat.ARGBToColor( _outlineColor.a, _outlineColor.r, _outlineColor.g, _outlineColor.b ); // Create the outline texture Graphics::Surface lineSurface; lineSurface.create(_thumbWidth, _thumbHeight, pixelFormat); lineSurface.drawThickLine(0, 0, _thumbWidth - 1, 0, 2, 2, outlineColor); lineSurface.drawThickLine(0, 0, 0, _thumbHeight - 1, 2, 2, outlineColor); lineSurface.drawThickLine(_thumbWidth - 2, 0, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor); lineSurface.drawThickLine(0, _thumbHeight - 2, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor); _outline->update(&lineSurface); lineSurface.free(); // Set the position _thumbPos.x = 41 + (_slot % SaveLoadMenuScreen::_slotPerRow) * (_thumbWidth + 39); _thumbPos.y = 61 + (_slot % SaveLoadMenuScreen::_slotPerPage / SaveLoadMenuScreen::_slotPerColumn) * (_thumbHeight + 38); _textDescPos.x = _thumbPos.x; _textDescPos.y = _thumbPos.y + _thumbHeight + 2; _textTimePos.x = _thumbPos.x; _textTimePos.y = _textDescPos.y + 12; }
BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) { //TextLineList lines; // TODO: Use WideString-conversion here. //WrapText(text, width, maxHeight, lines); Common::Array<WideString> lines; _font->wordWrapText(text, width, lines); while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) { lines.pop_back(); } if (lines.size() == 0) { return nullptr; } Graphics::TextAlign alignment = Graphics::kTextAlignInvalid; if (align == TAL_LEFT) { alignment = Graphics::kTextAlignLeft; } else if (align == TAL_CENTER) { alignment = Graphics::kTextAlignCenter; } else if (align == TAL_RIGHT) { alignment = Graphics::kTextAlignRight; } // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array. //debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color)); // void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const; Graphics::Surface *surface = new Graphics::Surface(); surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat()); uint32 useColor = 0xffffffff; Common::Array<WideString>::iterator it; int heightOffset = 0; for (it = lines.begin(); it != lines.end(); ++it) { _font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment); heightOffset += (int)_lineHeight; } BaseSurface *retSurface = _gameRef->_renderer->createSurface(); if (_deletableFont) { // Reconstruct the alpha channel of the font. // Since we painted it with color 0xFFFFFFFF onto a black background, // the alpha channel is gone, but the color value of each pixel corresponds // to its original alpha value. Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); uint32 *pixels = (uint32 *)surface->getPixels(); // This is a Surface we created ourselves, so no empty space between rows. for (int i = 0; i < surface->w * surface->h; ++i) { uint8 a, r, g, b; format.colorToRGB(*pixels, r, g, b); a = r; *pixels++ = format.ARGBToColor(a, r, g, b); } } retSurface->putSurface(*surface, true); surface->free(); delete surface; return retSurface; // TODO: _isUnderline, _isBold, _isItalic, _isStriked }
bool UIWindow::display(int offsetX, int offsetY) { // go exclusive if (_mode == WINDOW_EXCLUSIVE || _mode == WINDOW_SYSTEM_EXCLUSIVE) { if (!_shieldWindow) { _shieldWindow = new UIWindow(_gameRef); } if (_shieldWindow) { _shieldWindow->_posX = _shieldWindow->_posY = 0; _shieldWindow->_width = _gameRef->_renderer->getWidth(); _shieldWindow->_height = _gameRef->_renderer->getHeight(); _shieldWindow->display(); } } else if (_isMenu) { if (!_shieldButton) { _shieldButton = new UIButton(_gameRef); _shieldButton->setName("close"); _shieldButton->setListener(this, _shieldButton, 0); _shieldButton->_parent = this; } if (_shieldButton) { _shieldButton->_posX = _shieldButton->_posY = 0; _shieldButton->setWidth(_gameRef->_renderer->getWidth()); _shieldButton->setHeight(_gameRef->_renderer->getHeight()); _shieldButton->display(); } } if (!_visible) { return STATUS_OK; } if (_fadeBackground) { Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); byte fadeR, fadeG, fadeB, fadeA; // First convert from the internal format to the screen-format uint32 fadeColor = format.ARGBToColor(RGBCOLGetA(_fadeColor), RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor)); // Then get components format.colorToARGB(fadeColor, fadeA, fadeR, fadeG, fadeB); _gameRef->_renderer->fadeToColor(fadeR, fadeG, fadeB, fadeA); } if (_dragging) { _posX += (_gameRef->_mousePos.x - _dragFrom.x); _posY += (_gameRef->_mousePos.y - _dragFrom.y); _dragFrom.x = _gameRef->_mousePos.x; _dragFrom.y = _gameRef->_mousePos.y; } if (!_focusedWidget || (!_focusedWidget->canFocus() || _focusedWidget->isDisabled() || !_focusedWidget->isVisible())) { moveFocus(); } bool popViewport = false; if (_clipContents) { if (!_viewport) { _viewport = new BaseViewport(_gameRef); } if (_viewport) { _viewport->setRect(_posX + offsetX, _posY + offsetY, _posX + _width + offsetX, _posY + _height + offsetY); _gameRef->pushViewport(_viewport); popViewport = true; } } UITiledImage *back = _back; BaseSprite *image = _image; BaseFont *font = _font; if (!isFocused()) { if (_backInactive) { back = _backInactive; } if (_imageInactive) { image = _imageInactive; } if (_fontInactive) { font = _fontInactive; } } if (_alphaColor != 0) { _gameRef->_renderer->_forceAlphaColor = _alphaColor; } if (back) { back->display(_posX + offsetX, _posY + offsetY, _width, _height); } if (image) { image->draw(_posX + offsetX, _posY + offsetY, _transparent ? nullptr : this); } if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) { font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top); } if (!_transparent && !image) { _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, nullptr, _posX + offsetX, _posY + offsetY, _width, _height, 100, 100, false)); } for (uint32 i = 0; i < _widgets.size(); i++) { _widgets[i]->display(_posX + offsetX, _posY + offsetY); } if (_alphaColor != 0) { _gameRef->_renderer->_forceAlphaColor = 0; } if (popViewport) { _gameRef->popViewport(); } return STATUS_OK; }
// Function to blit a rect from one color format to another bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch, int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) { // Error out if conversion is impossible if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1) || (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel) || (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel)) return false; // Don't perform unnecessary conversion if (srcFmt == dstFmt) { if (dst == src) return true; if (dstpitch == srcpitch && ((w * dstFmt.bytesPerPixel) == dstpitch)) { memcpy(dst,src,dstpitch * h); return true; } else { for (int i = 0; i < h; i++) { memcpy(dst,src,w * dstFmt.bytesPerPixel); dst += dstpitch; src += srcpitch; } return true; } } // Faster, but larger, to provide optimized handling for each case. int srcDelta, dstDelta; srcDelta = (srcpitch - w * srcFmt.bytesPerPixel); dstDelta = (dstpitch - w * dstFmt.bytesPerPixel); // TODO: optimized cases for dstDelta of 0 uint8 r, g, b, a; if (dstFmt.bytesPerPixel == 2) { uint16 color; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 2, dst += 2) { color = *(const uint16 *)src; srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); *(uint16 *)dst = color; } src += srcDelta; dst += dstDelta; } } else if (dstFmt.bytesPerPixel == 3) { uint32 color; uint8 *col = (uint8 *) &color; #ifdef SCUMM_BIG_ENDIAN col++; #endif if (srcFmt.bytesPerPixel == 2) { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 2, dst += 3) { color = *(const uint16 *)src; srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); memcpy(dst, col, 3); } src += srcDelta; dst += dstDelta; } } else { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 3, dst += 3) { memcpy(col, src, 3); srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); memcpy(dst, col, 3); } src += srcDelta; dst += dstDelta; } } } else if (dstFmt.bytesPerPixel == 4) { uint32 color; if (srcFmt.bytesPerPixel == 2) { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 2, dst += 4) { color = *(const uint16 *)src; srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); *(uint32 *)dst = color; } src += srcDelta; dst += dstDelta; } } else if (srcFmt.bytesPerPixel == 3) { uint8 *col = (uint8 *)&color; #ifdef SCUMM_BIG_ENDIAN col++; #endif for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 2, dst += 4) { memcpy(col, src, 3); srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); *(uint32 *)dst = color; } src += srcDelta; dst += dstDelta; } } else { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++, src += 4, dst += 4) { color = *(const uint32 *)src; srcFmt.colorToARGB(color, a, r, g, b); color = dstFmt.ARGBToColor(a, r, g, b); *(uint32 *)dst = color; } src += srcDelta; dst += dstDelta; } } } else { return false; } return true; }