diff options
author | Max Horn | 2008-07-23 09:02:47 +0000 |
---|---|---|
committer | Max Horn | 2008-07-23 09:02:47 +0000 |
commit | c441c5261ff3e6ad114c0384ef818b942655f3a6 (patch) | |
tree | 6563ef6632ec89f7db2bbb62ad42aea680b507e6 /engines/tinsel/text.cpp | |
parent | e7c1a88dd3bf024e87ef62ff0c851b6a551ae2a5 (diff) | |
download | scummvm-rg350-c441c5261ff3e6ad114c0384ef818b942655f3a6.tar.gz scummvm-rg350-c441c5261ff3e6ad114c0384ef818b942655f3a6.tar.bz2 scummvm-rg350-c441c5261ff3e6ad114c0384ef818b942655f3a6.zip |
Added Tinsel engine to main repos (no news item for it ON PURPOSE)
svn-id: r33230
Diffstat (limited to 'engines/tinsel/text.cpp')
-rw-r--r-- | engines/tinsel/text.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/engines/tinsel/text.cpp b/engines/tinsel/text.cpp new file mode 100644 index 0000000000..dab97f7fdf --- /dev/null +++ b/engines/tinsel/text.cpp @@ -0,0 +1,279 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + * Text utilities. + */ + +#include "tinsel/dw.h" +#include "tinsel/graphics.h" // object plotting +#include "tinsel/handle.h" +#include "tinsel/sched.h" // process scheduler defines +#include "tinsel/strres.h" // bMultiByte +#include "tinsel/text.h" // text defines + +namespace Tinsel { + +/** + * Returns the length of one line of a string in pixels. + * @param szStr String + * @param pFont Which font to use for dimensions + */ +int StringLengthPix(char *szStr, const FONT *pFont) { + int strLen; // accumulated length of string + byte c; + SCNHANDLE hImg; + + // while not end of string or end of line + for (strLen = 0; (c = *szStr) != EOS_CHAR && c != LF_CHAR; szStr++) { + if (bMultiByte) { + if (c & 0x80) + c = ((c & ~0x80) << 8) + *++szStr; + } + hImg = FROM_LE_32(pFont->fontDef[c]); + + if (hImg) { + // there is a IMAGE for this character + const IMAGE *pChar = (const IMAGE *)LockMem(hImg); + + // add width of font bitmap + strLen += FROM_LE_16(pChar->imgWidth); + } else + // use width of space character + strLen += FROM_LE_32(pFont->spaceSize); + + // finally add the inter-character spacing + strLen += FROM_LE_32(pFont->xSpacing); + } + + // return length of line in pixels - minus inter-char spacing for last character + strLen -= FROM_LE_32(pFont->xSpacing); + return (strLen > 0) ? strLen : 0; +} + +/** + * Returns the justified x start position of a line of text. + * @param szStr String to output + * @param xPos X position of string + * @param pFont Which font to use + * @param mode Mode flags for the string + */ +int JustifyText(char *szStr, int xPos, const FONT *pFont, int mode) { + if (mode & TXT_CENTRE) { + // centre justify the text + + // adjust x positioning by half the length of line in pixels + xPos -= StringLengthPix(szStr, pFont) / 2; + } else if (mode & TXT_RIGHT) { + // right justify the text + + // adjust x positioning by length of line in pixels + xPos -= StringLengthPix(szStr, pFont); + } + + // return text line x start position + return xPos; +} + +/** + * Main text outputting routine. If a object list is specified a + * multi-object is created for the whole text and a pointer to the head + * of the list is returned. + * @param pList Object list to add text to + * @param szStr String to output + * @param colour Colour for monochrome text + * @param xPos X position of string + * @param yPos Y position of string + * @param hFont Which font to use + * @param mode Mode flags for the string + */ +OBJECT *ObjectTextOut(OBJECT *pList, char *szStr, int colour, int xPos, int yPos, + SCNHANDLE hFont, int mode) { + int xJustify; // x position of text after justification + int yOffset; // offset to next line of text + OBJECT *pFirst; // head of multi-object text list + OBJECT *pChar = 0; // object ptr for the character + byte c; + SCNHANDLE hImg; + const IMAGE *pImg; + + // make sure there is a linked list to add text to + assert(pList); + + // get font pointer + const FONT *pFont = (const FONT *)LockMem(hFont); + + // init head of text list + pFirst = NULL; + + // get image for capital W + assert(pFont->fontDef[(int)'W']); + pImg = (const IMAGE *)LockMem(FROM_LE_32(pFont->fontDef[(int)'W'])); + + // get height of capital W for offset to next line + yOffset = FROM_LE_16(pImg->imgHeight); + + while (*szStr) { + // x justify the text according to the mode flags + xJustify = JustifyText(szStr, xPos, pFont, mode); + + // repeat until end of string or end of line + while ((c = *szStr) != EOS_CHAR && c != LF_CHAR) { + if (bMultiByte) { + if (c & 0x80) + c = ((c & ~0x80) << 8) + *++szStr; + } + hImg = FROM_LE_32(pFont->fontDef[c]); + + if (hImg == 0) { + // no image for this character + + // add font spacing for a space character + xJustify += FROM_LE_32(pFont->spaceSize); + } else { // printable character + + int aniX, aniY; // char image animation offsets + + OBJ_INIT oi; + oi.hObjImg = FROM_LE_32(pFont->fontInit.hObjImg); + oi.objFlags = FROM_LE_32(pFont->fontInit.objFlags); + oi.objID = FROM_LE_32(pFont->fontInit.objID); + oi.objX = FROM_LE_32(pFont->fontInit.objX); + oi.objY = FROM_LE_32(pFont->fontInit.objY); + oi.objZ = FROM_LE_32(pFont->fontInit.objZ); + + // allocate and init a character object + if (pFirst == NULL) + // first time - init head of list + pFirst = pChar = InitObject(&oi); // FIXME: endian issue using fontInit!!! + else + // chain to multi-char list + pChar = pChar->pSlave = InitObject(&oi); // FIXME: endian issue using fontInit!!! + + // convert image handle to pointer + pImg = (const IMAGE *)LockMem(hImg); + + // fill in character object + pChar->hImg = hImg; // image def + pChar->width = FROM_LE_16(pImg->imgWidth); // width of chars bitmap + pChar->height = FROM_LE_16(pImg->imgHeight); // height of chars bitmap + pChar->hBits = FROM_LE_32(pImg->hImgBits); // bitmap + + // check for absolute positioning + if (mode & TXT_ABSOLUTE) + pChar->flags |= DMA_ABS; + + // set characters colour - only effective for mono fonts + pChar->constant = colour; + + // get Y animation offset + GetAniOffset(hImg, pChar->flags, &aniX, &aniY); + + // set x position - ignore animation point + pChar->xPos = intToFrac(xJustify); + + // set y position - adjust for animation point + pChar->yPos = intToFrac(yPos - aniY); + + if (mode & TXT_SHADOW) { + // we want to shadow the character + OBJECT *pShad; + + // allocate a object for the shadow and chain to multi-char list + pShad = pChar->pSlave = AllocObject(); + + // copy the character for a shadow + CopyObject(pShad, pChar); + + // add shadow offsets to characters position + pShad->xPos += intToFrac(FROM_LE_32(pFont->xShadow)); + pShad->yPos += intToFrac(FROM_LE_32(pFont->yShadow)); + + // shadow is behind the character + pShad->zPos--; + + // shadow is always mono + pShad->flags = DMA_CNZ | DMA_CHANGED; + + // check for absolute positioning + if (mode & TXT_ABSOLUTE) + pShad->flags |= DMA_ABS; + + // shadow always uses first palette entry + // should really alloc a palette here also ???? + pShad->constant = 1; + + // add shadow to object list + InsertObject(pList, pShad); + } + + // add character to object list + InsertObject(pList, pChar); + + // move to end of list + if (pChar->pSlave) + pChar = pChar->pSlave; + + // add character spacing + xJustify += FROM_LE_16(pImg->imgWidth); + } + + // finally add the inter-character spacing + xJustify += FROM_LE_32(pFont->xSpacing); + + // next character in string + ++szStr; + } + + // adjust the text y position and add the inter-line spacing + yPos += yOffset + FROM_LE_32(pFont->ySpacing); + + // check for newline + if (c == LF_CHAR) + // next character in string + ++szStr; + } + + // return head of list + return pFirst; +} + +/** + * Is there an image for this character in this font? + * @param hFont which font to use + * @param c character to test + */ +bool IsCharImage(SCNHANDLE hFont, char c) { + byte c2 = (byte)c; + + // Inventory save game name editor needs to be more clever for + // multi-byte characters. This bodge will stop it erring. + if (bMultiByte && (c2 & 0x80)) + return false; + + // get font pointer + const FONT *pFont = (const FONT *)LockMem(hFont); + + return pFont->fontDef[c2] != 0; +} + +} // end of namespace Tinsel |