void Surface::shadeRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color, uint8 strength) { if (_bpp == 1) { // We can't properly shade in paletted mode, fill the rect instead fillRect(left, top, right, bottom, color); return; } // Just in case those are swapped if (left > right) SWAP(left, right); if (top > bottom) SWAP(top, bottom); if ((left >= _width) || (top >= _height)) // Nothing to do return; // Area to actually shade uint16 width = CLIP<int32>(right - left + 1, 0, _width - left); uint16 height = CLIP<int32>(bottom - top + 1, 0, _height - top); if ((width == 0) || (height == 0)) // Nothing to do return; Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); uint8 cR, cG, cB; pixelFormat.colorToRGB(color, cR, cG, cB); int shadeR = cR * (16 - strength); int shadeG = cG * (16 - strength); int shadeB = cB * (16 - strength); Pixel p = get(left, top); while (height-- > 0) { for (uint16 i = 0; i < width; i++, ++p) { uint8 r, g, b; pixelFormat.colorToRGB(p.get(), r, g, b); r = CLIP<int>((shadeR + strength * r) >> 4, 0, 255); g = CLIP<int>((shadeG + strength * g) >> 4, 0, 255); b = CLIP<int>((shadeB + strength * b) >> 4, 0, 255); p.set(pixelFormat.RGBToColor(r, g, b)); } p += _width - width; } }
bool SavePartSprite::readSprite(const Surface &sprite) { // The sprite's dimensions have to fit if (((uint32)sprite.getWidth()) != _width) return false; if (((uint32)sprite.getHeight()) != _height) return false; if (_trueColor) { if (sprite.getBPP() <= 1) return false; Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); byte *data = _dataSprite; ConstPixel pixel = sprite.get(); for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3) pixelFormat.colorToRGB(pixel.get(), data[0], data[1], data[2]); } else { if (sprite.getBPP() != 1) return false; memcpy(_dataSprite, sprite.getData(), _width * _height); } return true; }
/** * Copies the current screen contents to a new surface, using RGB565 format. * WARNING: surf->free() must be called by the user to avoid leaking. * * @param surf the surface to store the data in it */ static bool grabScreen565(Graphics::Surface *surf) { Graphics::Surface *screen = g_system->lockScreen(); if (!screen) return false; assert(screen->format.bytesPerPixel == 1 || screen->format.bytesPerPixel == 2); assert(screen->getPixels() != 0); Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); surf->create(screen->w, screen->h, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); byte *palette = 0; if (screenFormat.bytesPerPixel == 1) { palette = new byte[256 * 3]; assert(palette); g_system->getPaletteManager()->grabPalette(palette, 0, 256); } for (uint y = 0; y < screen->h; ++y) { for (uint x = 0; x < screen->w; ++x) { byte r = 0, g = 0, b = 0; if (screenFormat.bytesPerPixel == 1) { uint8 pixel = *(uint8 *)screen->getBasePtr(x, y); r = palette[pixel * 3 + 0]; g = palette[pixel * 3 + 1]; b = palette[pixel * 3 + 2]; } else if (screenFormat.bytesPerPixel == 2) { uint16 col = READ_UINT16(screen->getBasePtr(x, y)); screenFormat.colorToRGB(col, r, g, b); } *((uint16 *)surf->getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b); } } delete[] palette; g_system->unlockScreen(); return true; }
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 }