bool Text::doRender() { // Font-Resource locken. FontResource *fontPtr = lockFontResource(); if (!fontPtr) return false; // Charactermap-Resource locken. ResourceManager *rmPtr = getResourceManager(); BitmapResource *charMapPtr; { Resource *pResource = rmPtr->requestResource(fontPtr->getCharactermapFileName()); if (!pResource) { BS_LOG_ERRORLN("Could not request resource \"%s\".", fontPtr->getCharactermapFileName().c_str()); return false; } if (pResource->getType() != Resource::TYPE_BITMAP) { BS_LOG_ERRORLN("Requested resource \"%s\" is not a bitmap.", fontPtr->getCharactermapFileName().c_str()); return false; } charMapPtr = static_cast<BitmapResource *>(pResource); } // Framebufferobjekt holen. GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx(); BS_ASSERT(gfxPtr); bool result = true; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { // Feststellen, ob überhaupt Buchstaben der aktuellen Zeile vom Update betroffen sind. Common::Rect checkRect = (*iter).bbox; checkRect.translate(_absoluteX, _absoluteY); // Jeden Buchstaben einzeln Rendern. int curX = _absoluteX + (*iter).bbox.left; int curY = _absoluteY + (*iter).bbox.top; for (uint i = 0; i < (*iter).text.size(); ++i) { Common::Rect curRect = fontPtr->getCharacterRect((byte)(*iter).text[i]); Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height()); int renderX = curX + (renderRect.left - renderRect.left); int renderY = curY + (renderRect.top - renderRect.top); renderRect.translate(curRect.left - curX, curRect.top - curY); result = charMapPtr->blit(renderX, renderY, Image::FLIP_NONE, &renderRect, _modulationColor); if (!result) break; curX += curRect.width() + fontPtr->getGapWidth(); } } // Charactermap-Resource freigeben. charMapPtr->release(); // Font-Resource freigeben. fontPtr->release(); return result; }
bool Text::doRender(RectangleList *updateRects) { // lock Font Resource FontResource *fontPtr = lockFontResource(); if (!fontPtr) return false; // lock Character map resource ResourceManager *rmPtr = getResourceManager(); BitmapResource *charMapPtr; { Resource *pResource = rmPtr->requestResource(fontPtr->getCharactermapFileName()); if (!pResource) { warning("Could not request resource \"%s\".", fontPtr->getCharactermapFileName().c_str()); return false; } if (pResource->getType() != Resource::TYPE_BITMAP) { error("Requested resource \"%s\" is not a bitmap.", fontPtr->getCharactermapFileName().c_str()); return false; } charMapPtr = static_cast<BitmapResource *>(pResource); } // Getting frame buffer object GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx(); assert(gfxPtr); bool result = true; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { // Determine whether any letters of the current line are affected by the update. Common::Rect checkRect = (*iter).bbox; checkRect.translate(_absoluteX, _absoluteY); // Render each letter individually. int curX = _absoluteX + (*iter).bbox.left; int curY = _absoluteY + (*iter).bbox.top; for (uint i = 0; i < (*iter).text.size(); ++i) { Common::Rect curRect = fontPtr->getCharacterRect((byte)(*iter).text[i]); Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height()); renderRect.translate(curRect.left - curX, curRect.top - curY); result = charMapPtr->blit(curX, curY, Graphics::FLIP_NONE, &renderRect, _modulationColor, -1, -1, updateRects); if (!result) break; curX += curRect.width() + fontPtr->getGapWidth(); } } // Free Character map resource charMapPtr->release(); // Free Font resource fontPtr->release(); return result; }
void Text::updateFormat() { FontResource *fontPtr = lockFontResource(); assert(fontPtr); updateMetrics(*fontPtr); _lines.resize(1); if (_autoWrap && (uint) _width >= _autoWrapThreshold && _text.size() >= 2) { _width = 0; uint curLineWidth = 0; uint curLineHeight = 0; uint curLine = 0; uint tempLineWidth = 0; uint lastSpace = 0; // we need at least 1 space character to start a new line... _lines[0].text = ""; for (uint i = 0; i < _text.size(); ++i) { uint j; tempLineWidth = 0; lastSpace = 0; for (j = i; j < _text.size(); ++j) { if ((byte)_text[j] == ' ') lastSpace = j; const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]); tempLineWidth += curCharRect.width(); tempLineWidth += fontPtr->getGapWidth(); if ((tempLineWidth >= _autoWrapThreshold) && (lastSpace > 0)) break; } if (j == _text.size()) // everything in 1 line. lastSpace = _text.size(); curLineWidth = 0; curLineHeight = 0; for (j = i; j < lastSpace; ++j) { _lines[curLine].text += _text[j]; const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]); curLineWidth += curCharRect.width(); curLineWidth += fontPtr->getGapWidth(); if ((uint)curCharRect.height() > curLineHeight) curLineHeight = curCharRect.height(); } _lines[curLine].bbox.right = curLineWidth; _lines[curLine].bbox.bottom = curLineHeight; if ((uint)_width < curLineWidth) _width = curLineWidth; if (lastSpace < _text.size()) { ++curLine; assert(curLine == _lines.size()); _lines.resize(curLine + 1); _lines[curLine].text = ""; } i = lastSpace; } // Bounding box of each line relative to the first set (center aligned). _height = 0; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { Common::Rect &bbox = (*iter).bbox; bbox.left = (_width - bbox.right) / 2; bbox.right = bbox.left + bbox.right; bbox.top = (iter - _lines.begin()) * fontPtr->getLineHeight(); bbox.bottom = bbox.top + bbox.bottom; _height += bbox.height(); } } else { // No auto format, so all the text is copied to a single line. _lines[0].text = _text; _lines[0].bbox = Common::Rect(0, 0, _width, _height); } fontPtr->release(); }
void Text::updateFormat() { FontResource *fontPtr = lockFontResource(); BS_ASSERT(fontPtr); updateMetrics(*fontPtr); _lines.resize(1); if (_autoWrap && (uint) _width >= _autoWrapThreshold && _text.size() >= 2) { _width = 0; uint curLineWidth = 0; uint curLineHeight = 0; uint curLine = 0; uint tempLineWidth = 0; uint lastSpace = 0; // we need at least 1 space character to start a new line... _lines[0].text = ""; for (uint i = 0; i < _text.size(); ++i) { uint j; tempLineWidth = 0; lastSpace = 0; for (j = i; j < _text.size(); ++j) { if ((byte)_text[j] == ' ') lastSpace = j; const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]); tempLineWidth += curCharRect.width(); tempLineWidth += fontPtr->getGapWidth(); if ((tempLineWidth >= _autoWrapThreshold) && (lastSpace > 0)) break; } if (j == _text.size()) // everything in 1 line. lastSpace = _text.size(); curLineWidth = 0; curLineHeight = 0; for (j = i; j < lastSpace; ++j) { _lines[curLine].text += _text[j]; const Common::Rect &curCharRect = fontPtr->getCharacterRect((byte)_text[j]); curLineWidth += curCharRect.width(); curLineWidth += fontPtr->getGapWidth(); if ((uint)curCharRect.height() > curLineHeight) curLineHeight = curCharRect.height(); } _lines[curLine].bbox.right = curLineWidth; _lines[curLine].bbox.bottom = curLineHeight; if ((uint)_width < curLineWidth) _width = curLineWidth; if (lastSpace < _text.size()) { ++curLine; BS_ASSERT(curLine == _lines.size()); _lines.resize(curLine + 1); _lines[curLine].text = ""; } i = lastSpace; } // Bounding-Box der einzelnen Zeilen relativ zur ersten festlegen (vor allem zentrieren). _height = 0; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { Common::Rect &bbox = (*iter).bbox; bbox.left = (_width - bbox.right) / 2; bbox.right = bbox.left + bbox.right; bbox.top = (iter - _lines.begin()) * fontPtr->getLineHeight(); bbox.bottom = bbox.top + bbox.bottom; _height += bbox.height(); } } else { // Keine automatische Formatierung, also wird der gesamte Text in nur eine Zeile kopiert. _lines[0].text = _text; _lines[0].bbox = Common::Rect(0, 0, _width, _height); } fontPtr->release(); }