Initial commit
This commit is contained in:
1125
engines/bagel/spacebar/boflib/gfx/bitmap.cpp
Normal file
1125
engines/bagel/spacebar/boflib/gfx/bitmap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
446
engines/bagel/spacebar/boflib/gfx/bitmap.h
Normal file
446
engines/bagel/spacebar/boflib/gfx/bitmap.h
Normal file
@@ -0,0 +1,446 @@
|
||||
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GFX_BMP_H
|
||||
#define BAGEL_BOFLIB_GFX_BMP_H
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
#include "bagel/boflib/cache.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/object.h"
|
||||
#include "bagel/boflib/point.h"
|
||||
#include "bagel/boflib/rect.h"
|
||||
#include "bagel/boflib/size.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Color constants
|
||||
//
|
||||
enum {
|
||||
NOT_TRANSPARENT = -1,
|
||||
COLOR_WHITE = 255,
|
||||
COLOR_BLACK = 0
|
||||
};
|
||||
|
||||
#define CBMP_FADE_SPEED 10
|
||||
#define CBMP_FADE_SIZE 4
|
||||
|
||||
#define CBMP_CURT_SPEED 8 // Must be a power of 2
|
||||
|
||||
#define CBMP_LINE_SPEED 32 // Should be a power of 4
|
||||
|
||||
// forward declare CBofWindow
|
||||
class CBofWindow;
|
||||
|
||||
class CBofBitmap : public CBofError, public CBofObject, public CCache {
|
||||
protected:
|
||||
/**
|
||||
* Does the actual allocation for this bitmap
|
||||
* @return true is this bitmap was successfully loaded into the cache
|
||||
*/
|
||||
bool alloc() override;
|
||||
|
||||
/**
|
||||
* Frees the data used by this bitmap (removes from cache)
|
||||
*/
|
||||
void free() override;
|
||||
|
||||
//
|
||||
// data members
|
||||
//
|
||||
static bool _bUseBackdrop;
|
||||
|
||||
char _szFileName[MAX_FNAME];
|
||||
|
||||
Graphics::ManagedSurface _bitmap;
|
||||
|
||||
byte *_pBits = nullptr;
|
||||
|
||||
CBofPalette *_pPalette = nullptr;
|
||||
|
||||
int _nScanDX = 0;
|
||||
int _nDX = 0;
|
||||
int _nDY = 0;
|
||||
bool _bTopDown = false;
|
||||
|
||||
bool _bOwnPalette = false;
|
||||
bool _bReadOnly = false;
|
||||
bool _bInitialized = false;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
CBofBitmap();
|
||||
|
||||
/**
|
||||
* Constructs a CBofBitmap
|
||||
* @param dx Width of new bitmap
|
||||
* @param dy Height of new bitmap
|
||||
* @param pPalette Palette to use for this bitmap
|
||||
* @param bOwnPalette true if destructor should delete palette
|
||||
* @param pPrivateBuff
|
||||
*/
|
||||
CBofBitmap(int dx, int dy, CBofPalette *pPalette, bool bOwnPalette = false, byte *pPrivateBuff = nullptr);
|
||||
|
||||
/**
|
||||
* Constructs a CBofBitmap
|
||||
* @param pszFileName Path and Filename for Bitmap on disk
|
||||
* @param pPalette Palette to use for this bitmap
|
||||
* @param bOwnPalette true if destructor should delete palette
|
||||
*/
|
||||
CBofBitmap(const char *pszFileName, CBofPalette *pPalette = nullptr, bool bOwnPalette = false);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CBofBitmap();
|
||||
|
||||
/**
|
||||
* Allocates the structures needed for a CBofBitmap
|
||||
* @param pPalette Palette to be assigned into this bitmap
|
||||
*/
|
||||
ErrorCode buildBitmap(CBofPalette *pPalette);
|
||||
|
||||
/**
|
||||
* Loads the specified bitmap from disk
|
||||
* @param pszFileName Filename
|
||||
* @param pPalette Palette
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode loadBitmap(const char *pszFileName, CBofPalette *pPalette);
|
||||
|
||||
/**
|
||||
* Frees the data used by this bitmap
|
||||
*/
|
||||
void releaseBitmap();
|
||||
|
||||
//
|
||||
// Palette routines
|
||||
//
|
||||
|
||||
/**
|
||||
* Assigns specified palette to this bitmap
|
||||
* @param pPalette Pointer to CBofPalette to be assigned
|
||||
* @param bOwnPalette true if bitmap is to own this palette
|
||||
*/
|
||||
void setPalette(CBofPalette *pPalette, bool bOwnPalette = false);
|
||||
|
||||
CBofPalette *getPalette() {
|
||||
return _pPalette;
|
||||
}
|
||||
|
||||
void setIsOwnPalette(bool own) {
|
||||
_bOwnPalette = own;
|
||||
}
|
||||
|
||||
//
|
||||
// Misc routines
|
||||
//
|
||||
|
||||
/**
|
||||
* Returns the bit address of the (x, y) location in this bmp
|
||||
* @param x Column in _pBits
|
||||
* @param y Row in _pBits
|
||||
* @return Address of (x,y) in bitmap surface
|
||||
*/
|
||||
byte *getPixelAddress(int x, int y);
|
||||
byte *getPixelAddress(CBofPoint *pPoint) {
|
||||
return getPixelAddress(pPoint->x, pPoint->y);
|
||||
}
|
||||
|
||||
CBofSize getSize() {
|
||||
return CBofSize(_nDX, _nDY);
|
||||
}
|
||||
|
||||
CBofRect getRect() {
|
||||
return CBofRect(0, 0, _nDX - 1, _nDY - 1);
|
||||
}
|
||||
|
||||
void setReadOnly(bool bReadOnly) {
|
||||
_bReadOnly = bReadOnly;
|
||||
}
|
||||
|
||||
bool getReadOnly() {
|
||||
return _bReadOnly;
|
||||
}
|
||||
|
||||
bool isTopDown() {
|
||||
return _bTopDown;
|
||||
}
|
||||
|
||||
int width() {
|
||||
return _nDX;
|
||||
}
|
||||
|
||||
int widthBytes() {
|
||||
return _nScanDX;
|
||||
}
|
||||
|
||||
int height() {
|
||||
return _nDY;
|
||||
}
|
||||
|
||||
operator Graphics::ManagedSurface &() {
|
||||
return _bitmap;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface getSurface();
|
||||
|
||||
/**
|
||||
* Returns current bitmap's filename (if any)
|
||||
* @return Pointer to bitmap's filename
|
||||
*/
|
||||
const char *getFileName();
|
||||
|
||||
//
|
||||
// Drawing routines
|
||||
//
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pWnd Destination device for painting
|
||||
* @param x Destination column
|
||||
* @param y Destination row
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nMaskColor Transparency color
|
||||
* @return error return code
|
||||
*/
|
||||
ErrorCode paint(CBofWindow *pWnd, int x, int y, CBofRect *pSrcRect = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pWnd Destination Device to paint to
|
||||
* @param pDstRect Destination rectangle (for stretching)
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nMaskColor transparency color
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paint(CBofWindow *pWnd, CBofRect *pDstRect = nullptr, CBofRect *pSrcRect = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pWnd Destination Device to paint to
|
||||
* @param pDstRect Destination rectangle (for stretching)
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nMaskColor Transparency color
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paintMaskBackdrop(CBofWindow *pWnd, CBofRect *pDstRect = nullptr, CBofRect *pSrcRect = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pBmp Destination bitmap to paint to
|
||||
* @param x Destination column
|
||||
* @param y Destination row
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nMaskColor Transparency color
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paint(CBofBitmap *pBmp, int x, int y, CBofRect *pSrcRect = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pBmp Destination bitmap to paint to
|
||||
* @param pDstRect Destination rectangle (for stretching)
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nMaskColor Transparency color
|
||||
* @return Error return code.
|
||||
*/
|
||||
ErrorCode paint(CBofBitmap *pBmp, CBofRect *pDstRect = nullptr, CBofRect *pSrcRect = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
//
|
||||
// Special Paint routines Optimized for specific tasks
|
||||
//
|
||||
|
||||
// Stretches 4 pixel wide
|
||||
/**
|
||||
* Stretches 4 pixel wide strips from source to destination
|
||||
* @brief The Destination rectangle MUST be divisible by 4.
|
||||
* Both bitmaps must be Bottom-Up. The Source must be smaller than the Destination.
|
||||
*
|
||||
* @param pBmp Destination bitmap to paint to
|
||||
* @param pDstRect Destination rectangle (for stretching)
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paintStretch4(CBofBitmap *pBmp, CBofRect *pDstRect, CBofRect *pSrcRect);
|
||||
|
||||
/**
|
||||
* Stretches a multiple of 4 pixel wide strips from source to destination
|
||||
* @param pBmp Destination bitmap to paint to
|
||||
* @param pDstRect Destination rectangle (for stretching)
|
||||
* @param pSrcRect Source rectangle from bitmap
|
||||
* @param nOptSize
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paintStretchOpt(CBofBitmap *pBmp, CBofRect *pDstRect, CBofRect *pSrcRect, int nOptSize);
|
||||
|
||||
/**
|
||||
* Paints some or all of the bitmap directly to the screen
|
||||
* @param pBmp Destination bitmap to paint to
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paint1To1(CBofBitmap *pBmp);
|
||||
|
||||
/** Copy specified section of screen (or window) to bitmap.
|
||||
* @param pWnd Window to capture
|
||||
* @param pSrcRect Source rectangle in window
|
||||
* @param pDstRect Destination area to copy image to
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode captureScreen(CBofWindow *pWnd, CBofRect *pSrcRect, CBofRect *pDstRect = nullptr);
|
||||
|
||||
/**
|
||||
* Performs a "Fade" onto the specified window
|
||||
* @param pWnd Pointer to window to fade into
|
||||
* @param x Fade upper left X
|
||||
* @param y Fade upper left Y
|
||||
* @param nMaskColor Transparency color (if any)
|
||||
* @param nBlockSize Size of Fade Blocks
|
||||
* @param nSpeed Speed for fade (not implemented yet)
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode fadeIn(CBofWindow *pWnd, int x = 0, int y = 0, int nMaskColor = NOT_TRANSPARENT, int nBlockSize = CBMP_FADE_SIZE, int nSpeed = CBMP_FADE_SPEED);
|
||||
|
||||
ErrorCode curtain(CBofWindow *pWnd, int nSpeed = CBMP_CURT_SPEED, int nMaskColor = NOT_TRANSPARENT);
|
||||
ErrorCode fadeLines(CBofWindow *pWnd, int nSpeed = CBMP_LINE_SPEED, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
/**
|
||||
* Returns the color at the (x, y) location in this bmp
|
||||
* @param x X position
|
||||
* @param y Y position
|
||||
* @return Color Index of specified (x,y) location in _pBits
|
||||
*/
|
||||
byte readPixel(int x, int y);
|
||||
|
||||
/**
|
||||
* Assigns the specified color to the (x, y) location
|
||||
* @param x X position
|
||||
* @param y Y position
|
||||
* @param iColor Pixel value
|
||||
*/
|
||||
void writePixel(int x, int y, byte iColor);
|
||||
|
||||
/**
|
||||
* Writes a circle into this bitmap
|
||||
* @param x X center position
|
||||
* @param y Y center position
|
||||
* @param nRadius Radius of circle
|
||||
* @param iColor Pixel value
|
||||
*/
|
||||
void circle(int x, int y, uint16 nRadius, byte iColor);
|
||||
|
||||
/**
|
||||
* Writes a line into this bitmap
|
||||
* @param nSrcX Endpoint 1 x
|
||||
* @param nSrcY Endpoint 1 y
|
||||
* @param nDstX Endpoint 2 x
|
||||
* @param nDstY Endpoint 2 y
|
||||
* @param iColor Pixel value
|
||||
*/
|
||||
void line(int nSrcX, int nSrcY, int nDstX, int nDstY, byte iColor);
|
||||
|
||||
/**
|
||||
* Writes a line into this bitmap
|
||||
* @param pSrc Endpoint 1
|
||||
* @param pDest Endpoint 2
|
||||
* @param iColor Pixel value
|
||||
*/
|
||||
void line(CBofPoint *pSrc, CBofPoint *pDest, byte iColor);
|
||||
|
||||
/**
|
||||
* Writes a Rectangle into this bitmap
|
||||
* @param cRect Pointer to rectangle Coordinates
|
||||
* @param iColor Color of rectangle
|
||||
*/
|
||||
void drawRect(CBofRect *cRect, byte iColor);
|
||||
|
||||
/**
|
||||
* Writes a filled in Rectangle to this bitmap
|
||||
* @param cRect Pointer to rectangle Coordinates
|
||||
* @param iColor Color of rectangle
|
||||
*/
|
||||
void fillRect(CBofRect *cRect, byte iColor);
|
||||
|
||||
/**
|
||||
* Scrolls current bitmap horizontally
|
||||
* @param nPixels Number of pixels to scroll by
|
||||
* @param pRect Section of bitmap to scroll
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode scrollRight(int nPixels, CBofRect *pRect = nullptr);
|
||||
|
||||
|
||||
ErrorCode scrollLeft(int nPixels, CBofRect *pRect = nullptr) {
|
||||
return scrollRight(-nPixels, pRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls current bitmap vertically
|
||||
* @param nPixels Number of pixels to scroll by
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode scrollUp(int nPixels);
|
||||
|
||||
static void setUseBackdrop(bool b) {
|
||||
_bUseBackdrop = b;
|
||||
}
|
||||
static bool getUseBackdrop() {
|
||||
return _bUseBackdrop;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc graphics routines
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Loads specified bitmap (and possibly re-maps to palette)
|
||||
* @param pszFileName Bitmap to open
|
||||
* @param pPalette Palette for re-mapping
|
||||
* @param bSharedPal Shared palette flag
|
||||
* @return Pointer to bitmap
|
||||
*/
|
||||
extern CBofBitmap *loadBitmap(const char *pszFileName, CBofPalette *pPalette = nullptr, bool bSharedPal = false);
|
||||
|
||||
/**
|
||||
* Paints specified bitmap to specified window
|
||||
* @param pWindow Window to paint to
|
||||
* @param pszFileName Bitmap filename
|
||||
* @param pDstRect Destination area to paint to
|
||||
* @param pSrcRect Source area to paint from
|
||||
* @param pPalette Optional palette to re-map with
|
||||
* @param nMaskColor Optional transparent color
|
||||
* @return Error return code
|
||||
*/
|
||||
extern ErrorCode paintBitmap(CBofWindow *pWindow, const char *pszFileName, CBofRect *pDstRect = nullptr,
|
||||
CBofRect *pSrcRect = nullptr, CBofPalette *pPalette = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
72
engines/bagel/spacebar/boflib/gfx/cursor.cpp
Normal file
72
engines/bagel/spacebar/boflib/gfx/cursor.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
#include "bagel/spacebar/boflib/gfx/cursor.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
void CBofCursor::initialize() {
|
||||
show();
|
||||
}
|
||||
|
||||
CBofCursor::~CBofCursor() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
unLoad();
|
||||
}
|
||||
|
||||
ErrorCode CBofCursor::load() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// kill any previous cursor
|
||||
unLoad();
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofCursor::unLoad() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofCursor::set() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
// TODO: This controlled the "Windows cursor" in the original game
|
||||
// ScummVM doesn't have one, so just show the arrow cursor or
|
||||
// use CursorMan accordingly
|
||||
void CBofCursor::hide() {
|
||||
//CursorMan.showMouse(false);
|
||||
}
|
||||
|
||||
void CBofCursor::show() {
|
||||
CursorMan.showMouse(true);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
51
engines/bagel/spacebar/boflib/gfx/cursor.h
Normal file
51
engines/bagel/spacebar/boflib/gfx/cursor.h
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GFX_CURSOR_H
|
||||
#define BAGEL_BOFLIB_GFX_CURSOR_H
|
||||
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBofCursor : public CBofObject, public CBofError {
|
||||
public:
|
||||
CBofCursor() {
|
||||
}
|
||||
~CBofCursor();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode load();
|
||||
ErrorCode unLoad();
|
||||
|
||||
ErrorCode set();
|
||||
|
||||
static void show();
|
||||
static void hide();
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
729
engines/bagel/spacebar/boflib/gfx/sprite.cpp
Normal file
729
engines/bagel/spacebar/boflib/gfx/sprite.cpp
Normal file
@@ -0,0 +1,729 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
#include "bagel/boflib/misc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBofRect *CBofSprite::_cDirtyRect;
|
||||
CBofSprite *CBofSprite::_pSpriteChain = nullptr; // Pointer to chain of linked sprites
|
||||
CBofSprite *CBofSprite::_pTouchedSprite = nullptr; // Pointer to sprite overlapped during painting
|
||||
CBofBitmap *CBofSprite::_pWorkBmp = nullptr; // Offscreen work area
|
||||
CBofPalette *CBofSprite::_pSharedPalette = nullptr; // Shared palette for ALL sprites
|
||||
int CBofSprite::_nWorkDX = 0;
|
||||
int CBofSprite::_nWorkDY = 0;
|
||||
|
||||
void CBofSprite::initialize() {
|
||||
_cDirtyRect = new CBofRect();
|
||||
_pSpriteChain = nullptr;
|
||||
_pTouchedSprite = nullptr;
|
||||
_pWorkBmp = nullptr;
|
||||
_pSharedPalette = nullptr;
|
||||
_nWorkDX = 0;
|
||||
_nWorkDY = 0;
|
||||
}
|
||||
|
||||
void CBofSprite::shutdown() {
|
||||
delete _cDirtyRect;
|
||||
}
|
||||
|
||||
void CBofSprite::openLibrary(CBofPalette *pPal) {
|
||||
// Must have a valid palette to do any sprite related stuff
|
||||
assert(pPal != nullptr);
|
||||
|
||||
clearDirtyRect();
|
||||
setSharedPalette(pPal);
|
||||
|
||||
// Set up a default work area
|
||||
setupWorkArea(200, 200);
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::closeLibrary() {
|
||||
flushSpriteChain();
|
||||
tearDownWorkArea();
|
||||
|
||||
_pSharedPalette = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CBofSprite::CBofSprite() {
|
||||
_pImage = nullptr; // No initial bitmap image for the sprite
|
||||
|
||||
_cSize = CBofSize(0, 0); // There is no size to the sprite image
|
||||
_cRect.setRectEmpty(); // Rectangular bounds not yet defined
|
||||
|
||||
_cImageRect = _cRect; // Image rectangle starts same as display bounds
|
||||
_cPosition = CBofPoint(0, 0); // Default position to upper left corner of display
|
||||
_bPositioned = false; // Not yet positioned
|
||||
_bDuplicated = false; // Not sharing resources with other sprites
|
||||
_nZOrder = SPRITE_TOPMOST; // Default to top most in fore/back ground order
|
||||
_nCelCount = 1; // Number of frames in animated cel strip
|
||||
_nCelID = _nCelCount - 1; // Cel identifier not pointing at a cel
|
||||
_bAnimated = false; // Not initially animated
|
||||
_bLinked = false; // Not initially linked into the sprite chain
|
||||
|
||||
_nMaskColor = NOT_TRANSPARENT; // Default to NO transparency
|
||||
_bReadOnly = true;
|
||||
|
||||
setBlockAdvance(false); // Default always advance next sprite
|
||||
}
|
||||
|
||||
|
||||
CBofSprite::~CBofSprite() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
unlinkSprite();
|
||||
clearImage(); // Clear the sprite image bitmap and context
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::linkSprite() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!_bLinked) {
|
||||
// Set for linked into chain
|
||||
_bLinked = true;
|
||||
|
||||
if (_pSpriteChain != nullptr) {
|
||||
switch (_nZOrder) {
|
||||
case SPRITE_TOPMOST:
|
||||
_pSpriteChain->addToTail(this);
|
||||
break;
|
||||
|
||||
case SPRITE_HINDMOST:
|
||||
_pSpriteChain->addToHead(this);
|
||||
_pSpriteChain = this;
|
||||
break;
|
||||
|
||||
default: {
|
||||
CBofSprite *pSprite;
|
||||
CBofSprite *pLastSprite = pSprite = _pSpriteChain;
|
||||
while (pSprite != nullptr && pSprite->_nZOrder > _nZOrder) {
|
||||
pLastSprite = pSprite;
|
||||
pSprite = (CBofSprite *)pSprite->_pNext;
|
||||
}
|
||||
pLastSprite->Insert(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
_pSpriteChain = this;
|
||||
}
|
||||
|
||||
// _pSpriteChain must always point to the head of the linked list
|
||||
assert(_pSpriteChain == (CBofSprite *)_pSpriteChain->getHead());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::unlinkSprite() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_bLinked) {
|
||||
// Set for not linked into chain
|
||||
_bLinked = false;
|
||||
|
||||
if (_pSpriteChain == this)
|
||||
_pSpriteChain = (CBofSprite *)_pNext;
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::flushSpriteChain() {
|
||||
CBofSprite *pSprite = getSpriteChain();
|
||||
|
||||
// Cycle getting head of chain, un-linking it and then deleting it
|
||||
while (pSprite != nullptr) {
|
||||
pSprite->unlinkSprite();
|
||||
delete pSprite;
|
||||
pSprite = getSpriteChain();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::setupWorkArea(int dx, int dy) {
|
||||
// Do we already have a work area?
|
||||
if (_pWorkBmp != nullptr) {
|
||||
// Yes, so lets tear it down before we start a new one
|
||||
tearDownWorkArea();
|
||||
}
|
||||
|
||||
// Create an offscreen bitmap where we do all the work;
|
||||
_pWorkBmp = new CBofBitmap(dx, dy, _pSharedPalette);
|
||||
_nWorkDX = dx;
|
||||
_nWorkDY = dy;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::tearDownWorkArea() {
|
||||
delete _pWorkBmp;
|
||||
_pWorkBmp = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CBofSprite *CBofSprite::duplicateSprite() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Create an object for the sprite
|
||||
CBofSprite *pSprite = new CBofSprite;
|
||||
duplicateSprite(pSprite);
|
||||
|
||||
return pSprite;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::duplicateSprite(CBofSprite *pSprite) {
|
||||
if (!isValidObject(this) || (pSprite == nullptr))
|
||||
error("duplicateSprite - Invalid source or destination sprite");
|
||||
|
||||
pSprite->_pImage = _pImage;
|
||||
pSprite->_cRect = _cRect;
|
||||
pSprite->_cImageRect = _cImageRect;
|
||||
pSprite->_cSize = _cSize;
|
||||
pSprite->_cPosition = _cPosition;
|
||||
pSprite->_nZOrder = _nZOrder;
|
||||
pSprite->_nCelID = _nCelID;
|
||||
pSprite->_nCelCount = _nCelCount;
|
||||
pSprite->_bAnimated = _bAnimated;
|
||||
pSprite->_nMaskColor = _nMaskColor;
|
||||
|
||||
pSprite->_bDuplicated = true; // Mark it as a sprite with shared resources
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::loadSprite(const char *pszPathName, int nCels) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszPathName != nullptr);
|
||||
assert(nCels >= 1);
|
||||
|
||||
// Create an object for the sprite's image
|
||||
CBofBitmap *pBitmap = new CBofBitmap(pszPathName, _pSharedPalette);
|
||||
return loadSprite(pBitmap, nCels);
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::loadSprite(CBofBitmap *pBitmap, int nCels) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Can't load an invalid bitmap
|
||||
assert(pBitmap != nullptr);
|
||||
assert(nCels >= 1);
|
||||
|
||||
clearImage(); // Clear out any/all existing bitmaps, palettes,
|
||||
|
||||
_pImage = pBitmap; // Save pointer to bitmap
|
||||
|
||||
pBitmap->setReadOnly(_bReadOnly);
|
||||
|
||||
_cSize = pBitmap->getSize();
|
||||
|
||||
_cRect.setRect(0, 0, _cSize.cx - 1, _cSize.cy - 1);
|
||||
_cImageRect.setRect(0, 0, _cSize.cx - 1, _cSize.cy - 1);
|
||||
_nCelCount = 1;
|
||||
_nCelID = _nCelCount - 1;
|
||||
|
||||
if (nCels != 1) {
|
||||
setupCels(nCels);
|
||||
|
||||
// Assume it's animated
|
||||
_bAnimated = true;
|
||||
}
|
||||
|
||||
return true; // Return success
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::setupCels(const int nCels) {
|
||||
assert(isValidObject(this));
|
||||
assert(nCels > 0);
|
||||
|
||||
_nCelCount = nCels; // Set cel count
|
||||
_nCelID = _nCelCount - 1; // No current cel
|
||||
int nStripWidth = _cSize.cx; // Temp place toRetain cell strip pixel length
|
||||
_cSize.cx /= nCels; // Calculate width of a cel
|
||||
|
||||
if (_cSize.cx * nCels == nStripWidth) { // Verify we have an even multiple
|
||||
_cRect.right = _cRect.left + _cSize.cx; // Reset sprite rectangular bounds
|
||||
_cRect.bottom = _cRect.top + _cSize.cy; // ... based on cel dimensions
|
||||
_cImageRect.setRect(0, 0, _cSize.cx - 1, _cSize.cy - 1); // Set bounds for first cel in strip
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::nextCel() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// verify old cel id
|
||||
assert(_nCelID >= 0 && _nCelID < _nCelCount);
|
||||
|
||||
if (getBlockAdvance() == false) {
|
||||
if (++_nCelID >= _nCelCount)
|
||||
_nCelID = 0;
|
||||
|
||||
setCel(_nCelID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::prevCel() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// verify old cel id
|
||||
assert(_nCelID >= 0 && _nCelID < _nCelCount);
|
||||
|
||||
if (--_nCelID < 0)
|
||||
_nCelID = _nCelCount - 1;
|
||||
|
||||
setCel(_nCelID);
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::paintSprite(CBofWindow *pWnd, const int x, const int y) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Can't paint to a non-existent window
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
// The window MUST have a backdrop
|
||||
assert(pWnd->getBackdrop() != nullptr);
|
||||
|
||||
batchPaint(x, y);
|
||||
|
||||
updateDirtyRect(pWnd, this);
|
||||
|
||||
return !errorOccurred();
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::paintSprite(CBofBitmap *pBmp, const int x, const int y) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Can't paint to a non-existent window
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
batchPaint(x, y);
|
||||
updateDirtyRect(pBmp, this);
|
||||
|
||||
return !errorOccurred();
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::paintCel(CBofWindow *pWnd, int nCelId, const int x, const int y) {
|
||||
setCel(nCelId - 1);
|
||||
return paintSprite(pWnd, x, y);
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::paintCel(CBofBitmap *pBmp, int nCelId, const int x, const int y) {
|
||||
setCel(nCelId - 1);
|
||||
return paintSprite(pBmp, x, y);
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::batchPaint(const int x, const int y) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofRect cDstRect;
|
||||
|
||||
// Default to no sprite being overlapped by this painting operation
|
||||
_pTouchedSprite = nullptr;
|
||||
|
||||
// Calculate destination rectangle
|
||||
cDstRect.setRect(x, y, x + _cSize.cx - 1, y + _cSize.cy - 1);
|
||||
|
||||
// Add the destination position to the dirty rectangle list
|
||||
addToDirtyRect(&cDstRect);
|
||||
|
||||
// If the sprite is already on screen, then we must also add it's old
|
||||
// current location to the dirty rect list so that it is erase properly
|
||||
if (_bPositioned) {
|
||||
addToDirtyRect(&_cRect);
|
||||
}
|
||||
|
||||
// Now establish the sprite's new position
|
||||
setPosition(x, y);
|
||||
|
||||
if (_bAnimated && (_nCelCount > 1))
|
||||
// Advance to the next cel in the strip
|
||||
nextCel();
|
||||
}
|
||||
|
||||
bool CBofSprite::updateDirtyRect(CBofWindow *pWnd, CBofSprite *pPrimarySprite) {
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
// The window MUST have a backdrop associated with it. If that's not feasible, then
|
||||
// use CSprites instead of CBofSprites
|
||||
assert(pWnd->getBackdrop() != nullptr);
|
||||
|
||||
//
|
||||
// Repaint the contents of the specified rectangle
|
||||
//
|
||||
|
||||
CBofBitmap *pBackdrop = pWnd->getBackdrop();
|
||||
if (pBackdrop != nullptr) {
|
||||
|
||||
CBofRect *pRect = _cDirtyRect;
|
||||
if (pRect->width() != 0 && pRect->height() != 0) {
|
||||
// Need a work area
|
||||
CBofBitmap *pWork = _pWorkBmp;
|
||||
int dx = pRect->width();
|
||||
int dy = pRect->height();
|
||||
|
||||
bool bTempWorkArea = false;
|
||||
if ((pWork == nullptr) || (dx > _nWorkDX) || (dy > _nWorkDY)) {
|
||||
|
||||
bTempWorkArea = true;
|
||||
pWork = new CBofBitmap(dx, dy, _pSharedPalette);
|
||||
}
|
||||
pWork->lock();
|
||||
|
||||
// Paint the background into the work area
|
||||
pBackdrop->paint(pWork, 0, 0, pRect);
|
||||
|
||||
// Only need to search the sprite list if current sprite is linked
|
||||
CBofSprite *pSprite = pPrimarySprite;
|
||||
if (pPrimarySprite == nullptr || pPrimarySprite->_bLinked) {
|
||||
pSprite = _pSpriteChain;
|
||||
}
|
||||
|
||||
CBofRect cRect, cSrcRect;
|
||||
// Run through the sprite list
|
||||
while (pSprite != nullptr) {
|
||||
// and paint each partial sprite overlap to the work area
|
||||
if (pSprite->_bPositioned && cRect.intersectRect(&pSprite->_cRect, pRect)) {
|
||||
if (pPrimarySprite != pSprite)
|
||||
_pTouchedSprite = pSprite;
|
||||
|
||||
cSrcRect = cRect - pSprite->_cRect.topLeft();
|
||||
cSrcRect += pSprite->_cImageRect.topLeft();
|
||||
cRect -= pRect->topLeft();
|
||||
|
||||
pSprite->_pImage->paint(pWork, &cRect, &cSrcRect, pSprite->_nMaskColor);
|
||||
}
|
||||
pSprite = (CBofSprite *)pSprite->_pNext;
|
||||
}
|
||||
|
||||
// Paint final outcome to the screen
|
||||
cSrcRect.setRect(0, 0, pRect->width() - 1, pRect->height() - 1);
|
||||
pWork->paint(pWnd, pRect, &cSrcRect);
|
||||
|
||||
pWork->unlock();
|
||||
|
||||
if (bTempWorkArea) {
|
||||
delete pWork;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearDirtyRect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::updateDirtyRect(CBofBitmap *pBmp, CBofSprite *pPrimarySprite) {
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
//
|
||||
// Repaint the contents of the specified rectangle
|
||||
//
|
||||
CBofRect *pRect = getDirtyRect();
|
||||
|
||||
// Only need to search the sprite list if current sprite is linked
|
||||
CBofSprite *pSprite = pPrimarySprite;
|
||||
if (pPrimarySprite == nullptr || pPrimarySprite->_bLinked) {
|
||||
pSprite = _pSpriteChain;
|
||||
}
|
||||
|
||||
CBofRect cRect;
|
||||
// Run through the sprite list
|
||||
while (pSprite != nullptr) {
|
||||
// and paint each partial sprite overlap to the work area
|
||||
if (pSprite->_bPositioned && cRect.intersectRect(&pSprite->_cRect, pRect)) {
|
||||
|
||||
if (pPrimarySprite != pSprite)
|
||||
_pTouchedSprite = pSprite;
|
||||
|
||||
CBofRect cSrcRect = cRect - pSprite->_cRect.topLeft();
|
||||
cSrcRect += pSprite->_cImageRect.topLeft();
|
||||
|
||||
pSprite->_pImage->paint(pBmp, &cRect, &cSrcRect, pSprite->_nMaskColor);
|
||||
}
|
||||
pSprite = (CBofSprite *)pSprite->_pNext;
|
||||
}
|
||||
|
||||
clearDirtyRect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::addToDirtyRect(CBofRect *pRect) {
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofRect cRect;
|
||||
|
||||
if (_cDirtyRect->isRectEmpty()) {
|
||||
cRect = *pRect;
|
||||
} else {
|
||||
cRect.unionRect(_cDirtyRect, pRect);
|
||||
}
|
||||
*_cDirtyRect = cRect;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::setCel(const int nCelID) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// All sprites must have at least 1 frame
|
||||
assert(_nCelCount > 0);
|
||||
|
||||
if (_nCelID != nCelID) {
|
||||
_nCelID = nCelID % _nCelCount;
|
||||
if ((_nCelID != 0) && (nCelID < 0)) {
|
||||
_nCelID = _nCelCount + _nCelID;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify new cel id
|
||||
assert(_nCelID >= 0 && _nCelID < _nCelCount);
|
||||
|
||||
_cImageRect.left = _nCelID * _cSize.cx;
|
||||
_cImageRect.right = _cImageRect.left + _cSize.cx;
|
||||
}
|
||||
|
||||
bool CBofSprite::eraseSprite(CBofWindow *pWnd) {
|
||||
assert(isValidObject(this));
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
batchErase();
|
||||
updateDirtyRect(pWnd);
|
||||
|
||||
return !errorOccurred();
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::batchErase() {
|
||||
if (_bPositioned) {
|
||||
_bPositioned = false;
|
||||
|
||||
addToDirtyRect(&_cRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::testInterception(CBofSprite *pTestSprite, CBofPoint *pPoint) {
|
||||
assert(isValidObject(this));
|
||||
assert(pTestSprite != nullptr);
|
||||
|
||||
// Punt if no interception allowed
|
||||
if (pTestSprite != nullptr) {
|
||||
// be sure to not test against ourself
|
||||
if (this != pTestSprite) {
|
||||
|
||||
CBofRect overlapRect; // Area of overlap between rectangles
|
||||
// Use simple rectangle screening first
|
||||
if (overlapRect.intersectRect(&_cRect, &pTestSprite->_cRect)) {
|
||||
// ... and if that succeeds, see if we
|
||||
// ... have image masks that overlap
|
||||
if ((_nMaskColor == NOT_TRANSPARENT) || (pTestSprite->_nMaskColor == NOT_TRANSPARENT) || spritesOverlap(pTestSprite, pPoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CBofSprite *CBofSprite::interception(CBofRect *pNewRect, CBofSprite *pTestSprite) {
|
||||
assert(isValidObject(this));
|
||||
assert(pNewRect != nullptr);
|
||||
|
||||
// Get first sprite to be tested
|
||||
CBofSprite *pSprite = pTestSprite;
|
||||
|
||||
// Thumb through the sprite chain
|
||||
while (pSprite != nullptr) {
|
||||
// be sure to not test against ourself
|
||||
// ... and only test against overlapping sprites
|
||||
if (this != pSprite) {
|
||||
CBofRect overlapRect; // Area of overlap between rectangles
|
||||
// Sprites touch if their rectangles intersect.
|
||||
// does our sprite overlap another?
|
||||
if (overlapRect.intersectRect(pNewRect, &pSprite->_cRect))
|
||||
// ... if so return a pointer to it
|
||||
return pSprite;
|
||||
}
|
||||
|
||||
// Fetch next sprite in chain for testing
|
||||
pSprite = (CBofSprite *)pSprite->_pNext;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
CBofSprite *CBofSprite::interception(CBofSprite *pTestSprite) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofSprite *pSprite = pTestSprite; // Get first sprite to be tested
|
||||
|
||||
while (pSprite != nullptr) { // Thumb through the entire sprite collection
|
||||
|
||||
if (testInterception(pSprite, nullptr)) // ... testing against each sprite in turn
|
||||
return pSprite; // found an interception
|
||||
|
||||
pSprite = (CBofSprite *)pSprite->_pNext; // fetch next sprite in chain for testing
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool CBofSprite::spritesOverlap(CBofSprite *pSprite, CBofPoint *pPoint) {
|
||||
assert(isValidObject(this));
|
||||
assert(pSprite != nullptr);
|
||||
|
||||
// Assume no overlap
|
||||
bool bHit = false;
|
||||
|
||||
// If the sprite's rectangles overlap
|
||||
CBofRect overlapRect;
|
||||
if (overlapRect.intersectRect(&_cRect, &pSprite->_cRect)) {
|
||||
int32 dx = overlapRect.width();
|
||||
int32 dy = overlapRect.height();
|
||||
|
||||
int32 x1 = overlapRect.left - _cRect.left + _cImageRect.left;
|
||||
int32 y1 = overlapRect.top - _cRect.top + _cImageRect.top;
|
||||
|
||||
int32 x2 = overlapRect.left - pSprite->_cRect.left + pSprite->_cImageRect.left;
|
||||
int32 y2 = overlapRect.top - pSprite->_cRect.top + pSprite->_cImageRect.top;
|
||||
|
||||
int32 dx1 = _pImage->widthBytes();
|
||||
int32 dx2 = pSprite->_pImage->widthBytes();
|
||||
|
||||
byte m1 = (byte)_nMaskColor;
|
||||
byte m2 = (byte)pSprite->_nMaskColor;
|
||||
|
||||
// Lock down these bitmaps
|
||||
_pImage->lock();
|
||||
pSprite->_pImage->lock();
|
||||
|
||||
byte *pDib1 = (byte *)_pImage->getPixelAddress((int)x1, (int)y1);
|
||||
byte *pDib2 = (byte *)pSprite->_pImage->getPixelAddress((int)x2, (int)y2);
|
||||
|
||||
if (!_pImage->isTopDown()) {
|
||||
dx1 = -dx1;
|
||||
}
|
||||
|
||||
if (!pSprite->_pImage->isTopDown()) {
|
||||
dx2 = -dx2;
|
||||
}
|
||||
|
||||
for (int32 y = 0; y < dy; y++) {
|
||||
byte *pPtr1 = pDib1;
|
||||
byte *pPtr2 = pDib2;
|
||||
|
||||
for (int32 x = 0; x < dx; x++) {
|
||||
if ((*pPtr1 != m1) && (*pPtr2 != m2)) {
|
||||
if (pPoint != nullptr) {
|
||||
pPoint->x = (int)x;
|
||||
pPoint->y = (int)y;
|
||||
}
|
||||
|
||||
bHit = true;
|
||||
goto endroutine;
|
||||
}
|
||||
|
||||
pPtr1++;
|
||||
pPtr2++;
|
||||
}
|
||||
|
||||
pDib1 += dx1;
|
||||
pDib2 += dx2;
|
||||
}
|
||||
}
|
||||
|
||||
endroutine:
|
||||
// Don't need access to these bitmaps any more
|
||||
pSprite->_pImage->unlock();
|
||||
_pImage->unlock();
|
||||
|
||||
return bHit;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::setPosition(int x, int y) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Now have a real location establish the new location of the sprite
|
||||
// and setup the bitmap's bounding rectangle
|
||||
_bPositioned = true;
|
||||
_cPosition.x = x;
|
||||
_cPosition.y = y;
|
||||
_cRect.setRect(_cPosition.x, _cPosition.y, _cPosition.x + _cSize.cx - 1, _cPosition.y + _cSize.cy - 1);
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::clearImage() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!_bDuplicated && (_pImage != nullptr)) {
|
||||
delete _pImage;
|
||||
}
|
||||
|
||||
_pImage = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBofSprite::setSharedPalette(CBofPalette *pPal) {
|
||||
assert(pPal != nullptr);
|
||||
|
||||
_pSharedPalette = pPal;
|
||||
}
|
||||
|
||||
void CBofSprite::setZOrder(int nValue) {
|
||||
assert(isValidObject(this));
|
||||
assert(nValue >= SPRITE_TOPMOST && nValue <= SPRITE_HINDMOST);
|
||||
|
||||
_nZOrder = nValue;
|
||||
|
||||
// Relinking this sprite after setting it's new Z-Order will
|
||||
// add the sprite to the correct Z-Order sorted location (Insertion Sort)
|
||||
if (_bLinked) {
|
||||
unlinkSprite();
|
||||
linkSprite();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
237
engines/bagel/spacebar/boflib/gfx/sprite.h
Normal file
237
engines/bagel/spacebar/boflib/gfx/sprite.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GFX_SPRITE_H
|
||||
#define BAGEL_BOFLIB_GFX_SPRITE_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/object.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define SPRITE_TOPMOST 0
|
||||
#define SPRITE_FOREGROUND 64
|
||||
#define SPRITE_MIDDLE 128
|
||||
#define SPRITE_BACKGROUND 192
|
||||
#define SPRITE_HINDMOST 255
|
||||
|
||||
class CBofSprite : public CBofError, public CBofObject, public CLList {
|
||||
public:
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
// Constructors
|
||||
CBofSprite();
|
||||
|
||||
// Destructors
|
||||
virtual ~CBofSprite();
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
// Implementation
|
||||
CBofSprite *duplicateSprite();
|
||||
void duplicateSprite(CBofSprite *pSprite);
|
||||
|
||||
bool loadSprite(const char *pszPathName, int nCels = 1);
|
||||
bool loadSprite(CBofBitmap *pBitmap, int nCels = 1);
|
||||
|
||||
bool paintSprite(CBofBitmap *pBmp, int x, int y);
|
||||
bool paintSprite(CBofBitmap *pBmp, CBofPoint point) {
|
||||
return paintSprite(pBmp, point.x, point.y);
|
||||
}
|
||||
|
||||
bool paintSprite(CBofWindow *pWnd, int x, int y);
|
||||
bool paintSprite(CBofWindow *pWnd, CBofPoint point) {
|
||||
return paintSprite(pWnd, point.x, point.y);
|
||||
}
|
||||
|
||||
bool paintCel(CBofWindow *pWnd, int nCelId, int x, int y);
|
||||
bool paintCel(CBofBitmap *pBmp, int nCelId, int x, int y);
|
||||
|
||||
void batchPaint(int, int y);
|
||||
void batchErase();
|
||||
|
||||
bool setupCels(int nCels);
|
||||
void setCel(int nCelID);
|
||||
|
||||
void nextCel();
|
||||
void prevCel();
|
||||
|
||||
bool refreshSprite(CBofBitmap *pBmp) {
|
||||
return paintSprite(pBmp, _cPosition.x, _cPosition.y);
|
||||
}
|
||||
|
||||
bool refreshSprite(CBofWindow *pWnd) {
|
||||
return paintSprite(pWnd, _cPosition.x, _cPosition.y);
|
||||
}
|
||||
|
||||
bool eraseSprite(CBofWindow *pWnd);
|
||||
|
||||
// Notice how there is no eraseSprite for a CBofBitmap - that's because
|
||||
// sprites no longer retain their background, so there would be no way
|
||||
// to restore the background, and that's all eraseSprite does.
|
||||
|
||||
CBofSprite *interception(CBofRect *newRect, CBofSprite *pTestSprite);
|
||||
CBofSprite *interception(CBofSprite *pTestSprite);
|
||||
|
||||
CBofSprite *interception() {
|
||||
return interception(_pSpriteChain);
|
||||
}
|
||||
|
||||
CBofSprite *interception(CBofRect *newRect) {
|
||||
return interception(newRect, _pSpriteChain);
|
||||
}
|
||||
|
||||
bool testInterception(CBofSprite *pTestSprite, CBofPoint *pPoint = nullptr);
|
||||
|
||||
void setPosition(int x, int y);
|
||||
|
||||
CBofPoint getPosition() const {
|
||||
return _cPosition;
|
||||
}
|
||||
|
||||
CBofSize getSize() const {
|
||||
return _cSize;
|
||||
}
|
||||
|
||||
CBofRect getRect() const {
|
||||
return _cRect;
|
||||
}
|
||||
|
||||
int height() const {
|
||||
return _cRect.height();
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return _cRect.width();
|
||||
}
|
||||
|
||||
void setMaskColor(int nColor) {
|
||||
_nMaskColor = nColor;
|
||||
}
|
||||
|
||||
int getMaskColor() const {
|
||||
return _nMaskColor;
|
||||
}
|
||||
|
||||
byte readPixel(int x, int y) const {
|
||||
return _pImage->readPixel(x, y);
|
||||
}
|
||||
|
||||
void setZOrder(int nValue);
|
||||
|
||||
int getCelCount() const {
|
||||
return _nCelCount;
|
||||
}
|
||||
int getCelIndex() const {
|
||||
return _nCelID;
|
||||
}
|
||||
|
||||
void setAnimated(bool bAnimated) {
|
||||
_bAnimated = bAnimated;
|
||||
}
|
||||
bool getAnimated() const {
|
||||
return _bAnimated;
|
||||
}
|
||||
|
||||
void linkSprite();
|
||||
void unlinkSprite();
|
||||
|
||||
const char *getFileName() const {
|
||||
return _pImage->getFileName();
|
||||
}
|
||||
|
||||
static void openLibrary(CBofPalette *pPal);
|
||||
static void closeLibrary();
|
||||
|
||||
static void setSharedPalette(CBofPalette *pPalette);
|
||||
|
||||
static CBofSprite *getSpriteChain() {
|
||||
return _pSpriteChain;
|
||||
}
|
||||
|
||||
static bool updateDirtyRect(CBofWindow *pWnd, CBofSprite *pPrimarySprite = nullptr);
|
||||
static bool updateDirtyRect(CBofBitmap *pBmp, CBofSprite *pPrimarySprite = nullptr);
|
||||
static void addToDirtyRect(CBofRect *pRect);
|
||||
static void clearDirtyRect() {
|
||||
_cDirtyRect->setRectEmpty();
|
||||
}
|
||||
|
||||
static CBofRect *getDirtyRect() {
|
||||
return _cDirtyRect;
|
||||
}
|
||||
|
||||
static void flushSpriteChain();
|
||||
|
||||
static void setupWorkArea(int dx, int dy);
|
||||
static void tearDownWorkArea();
|
||||
|
||||
// Add a method for allowing callers of this object to block
|
||||
// next cell advancement
|
||||
|
||||
void setBlockAdvance(bool b = true) {
|
||||
_bBlockAdvance = b;
|
||||
}
|
||||
bool getBlockAdvance() const {
|
||||
return _bBlockAdvance;
|
||||
}
|
||||
|
||||
private:
|
||||
void clearImage();
|
||||
|
||||
bool spritesOverlap(CBofSprite *pSprite, CBofPoint *pPoint = nullptr);
|
||||
bool _bBlockAdvance; // Allow block next cell.
|
||||
public:
|
||||
CBofBitmap *_pImage; // Bitmap for the sprite
|
||||
|
||||
protected:
|
||||
CBofPoint _cPosition; // Upper left corner of sprite on display
|
||||
CBofSize _cSize; // dx/dy size of the sprite bitmap
|
||||
CBofRect _cRect; // Bounding rectangle on display
|
||||
CBofRect _cImageRect; // Bounding rectangle within image bitmap
|
||||
|
||||
int _nMaskColor; // Transparent color index for this sprite
|
||||
int _nZOrder; // Foreground / background order
|
||||
int _nCelID; // Index of current cel image
|
||||
int _nCelCount; // Number of cels in the animation strip
|
||||
|
||||
bool _bDuplicated : 1; // Shares bitmaps with some other sprite
|
||||
bool _bPositioned : 1; // Whether sprite has been positioned yet
|
||||
bool _bAnimated : 1; // Whether cel advance occurs when painting
|
||||
bool _bLinked : 1; // Whether sprite is linked into the chain
|
||||
bool _bReadOnly : 1; // Whether image is read only or not
|
||||
|
||||
static CBofRect *_cDirtyRect;
|
||||
static CBofSprite *_pSpriteChain; // Pointer to linked chain of sprites
|
||||
static CBofSprite *_pTouchedSprite; // Sprite touched during painting operation
|
||||
static CBofBitmap *_pWorkBmp; // Offscreen work area
|
||||
static CBofPalette *_pSharedPalette; // Shared palette for ALL sprites
|
||||
static int _nWorkDX;
|
||||
static int _nWorkDY;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
476
engines/bagel/spacebar/boflib/gfx/text.cpp
Normal file
476
engines/bagel/spacebar/boflib/gfx/text.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "graphics/fonts/ttf.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define START_SIZE 8
|
||||
#define MONO_FONT "LiberationMono-Regular.ttf"
|
||||
#define SERIF_FONT_REGULAR "LiberationSans-Regular.ttf"
|
||||
#define SERIF_FONT_BOLD "LiberationSans-Bold.ttf"
|
||||
#define TAB_SIZE 50
|
||||
|
||||
int CBofText::_tabStop;
|
||||
bool CBofText::_initialized;
|
||||
Graphics::Font *CBofText::_defaultFonts[NUM_POINT_SIZES];
|
||||
Graphics::Font *CBofText::_fixedFonts[NUM_POINT_SIZES];
|
||||
|
||||
|
||||
ErrorCode CBofText::initialize() {
|
||||
_initialized = true;
|
||||
_tabStop = 20; // tabstops every 20 pixels
|
||||
Common::fill(_defaultFonts, _defaultFonts + NUM_POINT_SIZES,
|
||||
(Graphics::Font *)nullptr);
|
||||
Common::fill(_fixedFonts, _fixedFonts + NUM_POINT_SIZES,
|
||||
(Graphics::Font *)nullptr);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::shutdown() {
|
||||
for (int i = 0; i < NUM_POINT_SIZES; i++) {
|
||||
delete _defaultFonts[i];
|
||||
delete _fixedFonts[i];
|
||||
}
|
||||
|
||||
_initialized = false;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
CBofText::CBofText() {
|
||||
initializeFields(); // Initialize stuff
|
||||
}
|
||||
|
||||
CBofText::CBofText(const CBofRect *pRect, int nJustify, uint32 nFormatFlags) {
|
||||
// Can't access null pointers
|
||||
assert(pRect != nullptr);
|
||||
|
||||
// Initialize stuff
|
||||
initializeFields();
|
||||
|
||||
// Build the work areas
|
||||
setupText(pRect, nJustify, nFormatFlags);
|
||||
}
|
||||
|
||||
CBofText::~CBofText() {
|
||||
delete _pWork;
|
||||
_pWork = nullptr;
|
||||
|
||||
delete _pBackground;
|
||||
_pBackground = nullptr;
|
||||
}
|
||||
|
||||
void CBofText::initializeFields() {
|
||||
_pBackground = nullptr;
|
||||
_pWork = nullptr;
|
||||
_bSaved = false;
|
||||
|
||||
_cPosition = CBofPoint(0, 0);
|
||||
_cSize = CBofSize(0, 0);
|
||||
_cRect.setRect(0, 0, 0, 0);
|
||||
|
||||
_cShadowColor = RGB(0, 0, 0);
|
||||
_nShadow_DX = 0;
|
||||
_nShadow_DY = 0;
|
||||
|
||||
_nJustify = JUSTIFY_LEFT;
|
||||
|
||||
_nFormatFlags = FORMAT_DEFAULT;
|
||||
_bMultiLine = false;
|
||||
|
||||
_nCurSize = 10;
|
||||
_nCurWeight = TEXT_DONTCARE;
|
||||
_cTextColor = CTEXT_COLOR;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::setupText(const CBofRect *pRect, int nJustify, uint32 nFormatFlags) {
|
||||
// Can't access null pointers
|
||||
assert(pRect != nullptr);
|
||||
|
||||
_nJustify = nJustify;
|
||||
|
||||
// Setup the fields for location and size of the text area
|
||||
_cRect = *pRect;
|
||||
_cSize.cx = _cRect.width();
|
||||
_cSize.cy = _cRect.height();
|
||||
|
||||
delete _pWork;
|
||||
_pWork = nullptr;
|
||||
|
||||
delete _pBackground;
|
||||
_pBackground = nullptr;
|
||||
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
// Create a bitmap to serve as our work area as we output text
|
||||
_pWork = new CBofBitmap(_cSize.cx, _cSize.cy, pPalette);
|
||||
|
||||
// Create a bitmap to hold the background we overwrite
|
||||
_pBackground = new CBofBitmap(_cSize.cx, _cSize.cy, pPalette);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::setupTextOpt(const CBofRect *pRect, int nJustify, uint32 nFormatFlags) {
|
||||
// Can't access null pointers
|
||||
assert(pRect != nullptr);
|
||||
|
||||
_nJustify = nJustify;
|
||||
_nFormatFlags = nFormatFlags;
|
||||
|
||||
// Setup the fields for location and size of the text area
|
||||
_cRect = *pRect;
|
||||
_cSize.cx = _cRect.width();
|
||||
_cSize.cy = _cRect.height();
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::erase(CBofWindow *pWnd) {
|
||||
// Can't access null pointers
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
if (_pBackground != nullptr && _bSaved) {
|
||||
// Simply splat the background art back where it came from
|
||||
_errCode = _pBackground->paint(pWnd, &_cRect);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::erase(CBofBitmap *pBmp) {
|
||||
// Can't access null pointers
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
if (_pBackground != nullptr && _bSaved) {
|
||||
// Simply splat the background art back where it came from
|
||||
_errCode = _pBackground->paint(pBmp, &_cRect);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::display(CBofWindow *pWnd, const char *pszText, const int nSize, const int nWeight, const COLORREF cColor, int nFont) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Can't access null pointers
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
_cTextColor = cColor;
|
||||
|
||||
return displayText(pWnd, pszText, &_cRect, nSize, nWeight, false, nFont);
|
||||
}
|
||||
|
||||
ErrorCode CBofText::display(CBofWindow *pWnd) {
|
||||
assert(isValidObject(this));
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
return display(pWnd, _cCurString, _nCurSize, _nCurWeight, _cTextColor);
|
||||
}
|
||||
|
||||
ErrorCode CBofText::display(CBofBitmap *pBmp) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
return display(pBmp, _cCurString, _nCurSize, _nCurWeight, _cTextColor);
|
||||
}
|
||||
|
||||
ErrorCode CBofText::display(CBofBitmap *pBmp, const char *pszText, const int nSize, const int nWeight, const COLORREF cColor, int nFont) {
|
||||
// Can't access null pointers
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
_cTextColor = cColor;
|
||||
|
||||
return displayText(pBmp, pszText, &_cRect, nSize, nWeight, false, nFont);
|
||||
}
|
||||
|
||||
ErrorCode CBofText::displayShadowed(CBofWindow *pWnd, const char *pszText, const int nSize, const int nWeight, const COLORREF cColor, const COLORREF cShadow, const int nDX, const int nDY, int nFont) {
|
||||
// Can't access null pointers
|
||||
assert(pWnd != nullptr);
|
||||
|
||||
_cTextColor = cColor;
|
||||
_cShadowColor = cShadow;
|
||||
_nShadow_DX = nDX;
|
||||
_nShadow_DY = nDY;
|
||||
|
||||
return displayText(pWnd, pszText, &_cRect, nSize, nWeight, true, nFont);
|
||||
}
|
||||
|
||||
ErrorCode CBofText::displayText(CBofWindow *pWnd, const char *pszText, CBofRect *pRect, const int nSize, const int nWeight, const bool bShadowed, int nFont) {
|
||||
assert(isValidObject(this));
|
||||
assert(pWnd != nullptr);
|
||||
assert(pszText != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofRect cRect(0, 0, pRect->width() - 1, pRect->height() - 1);
|
||||
|
||||
assert(_pBackground != nullptr);
|
||||
assert(_pWork != nullptr);
|
||||
|
||||
if (!_bSaved) {
|
||||
CBofBitmap::setUseBackdrop(true);
|
||||
_pBackground->captureScreen(pWnd, pRect);
|
||||
CBofBitmap::setUseBackdrop(false);
|
||||
_bSaved = true;
|
||||
}
|
||||
|
||||
_pBackground->paint(_pWork, 0, 0);
|
||||
|
||||
displayTextEx(_pWork, pszText, &cRect, nSize, nWeight, bShadowed, nFont);
|
||||
|
||||
_pWork->paint(pWnd, pRect);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::displayText(CBofBitmap *pBmp, const char *pszText, CBofRect *pRect, const int nSize, const int nWeight, const bool bShadowed, int nFont) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBmp != nullptr);
|
||||
assert(pszText != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofRect cRect(0, 0, pRect->width() - 1, pRect->height() - 1);
|
||||
|
||||
assert(_pWork != nullptr);
|
||||
|
||||
assert(_pBackground != nullptr);
|
||||
|
||||
if (!_bSaved) {
|
||||
CBofRect r = _pBackground->getRect();
|
||||
pBmp->paint(_pBackground, &r, pRect);
|
||||
_bSaved = true;
|
||||
}
|
||||
|
||||
_pBackground->paint(_pWork, 0, 0);
|
||||
|
||||
displayTextEx(_pWork, pszText, &cRect, nSize, nWeight, bShadowed, nFont);
|
||||
|
||||
_pWork->paint(pBmp, pRect);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
Graphics::Font *CBofText::getFont(int nFont, int nSize, int nWeight) {
|
||||
Graphics::Font *font;
|
||||
|
||||
// Attempt to use one of the fonts that we pre-allocated
|
||||
if (nFont != FONT_MONO) {
|
||||
font = _defaultFonts[nSize - START_SIZE];
|
||||
} else {
|
||||
font = _fixedFonts[nSize - START_SIZE];
|
||||
}
|
||||
|
||||
// Last resort - create the font now
|
||||
if (font == nullptr) {
|
||||
if (nFont != FONT_MONO) {
|
||||
font = Graphics::loadTTFFontFromArchive(SERIF_FONT_REGULAR, nSize, Graphics::kTTFSizeModeCell);
|
||||
_defaultFonts[nSize - START_SIZE] = font;
|
||||
} else {
|
||||
font = Graphics::loadTTFFontFromArchive(MONO_FONT, nSize, Graphics::kTTFSizeModeCell);
|
||||
_fixedFonts[nSize - START_SIZE] = font;
|
||||
}
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
ErrorCode CBofText::displayTextEx(CBofBitmap *pBmp, const char *pszText, CBofRect *pRect, const int nSize, const int nWeight, const bool bShadowed, int nFont) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// can't access null pointers
|
||||
assert(pBmp != nullptr);
|
||||
assert(pszText != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
Graphics::ManagedSurface surface = pBmp->getSurface();
|
||||
Graphics::Font *font = getFont(nFont, nSize, nWeight);
|
||||
int color;
|
||||
|
||||
// Split lines
|
||||
Common::U32StringArray lines;
|
||||
font->wordWrapText(Common::U32String(pszText, Common::kWindows1252), pRect->width(), lines);
|
||||
|
||||
// Iterate the lines to get the maximum width
|
||||
int maxWidth = 0;
|
||||
for (uint i = 0; i < lines.size(); ++i)
|
||||
maxWidth = MAX(maxWidth, font->getStringWidth(lines[i]));
|
||||
Common::Point textInfo(maxWidth, (int)lines.size() * font->getFontHeight());
|
||||
|
||||
_cPosition.y = (_cSize.cy - textInfo.y) >> 1;
|
||||
|
||||
Graphics::TextAlign align = Graphics::kTextAlignLeft;
|
||||
switch (_nJustify) {
|
||||
case JUSTIFY_CENTER:
|
||||
_cPosition.x = (_cSize.cx - textInfo.x) >> 1;
|
||||
align = Graphics::kTextAlignCenter;
|
||||
break;
|
||||
|
||||
case JUSTIFY_LEFT:
|
||||
// align left
|
||||
_cPosition.x = 0;
|
||||
break;
|
||||
|
||||
case JUSTIFY_RIGHT:
|
||||
_cPosition.x = _cSize.cx - textInfo.x;
|
||||
align = Graphics::kTextAlignRight;
|
||||
break;
|
||||
|
||||
case JUSTIFY_WRAP:
|
||||
// Align left
|
||||
_bMultiLine = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// text starts relative to area for painting
|
||||
_cPosition += pRect->topLeft();
|
||||
|
||||
// Note: Under ScummVM, even single line drawing uses the multiLine code
|
||||
Common::Rect newRect = *pRect;
|
||||
|
||||
if ((_nFormatFlags & FORMAT_TOP_CENTER) == FORMAT_TOP_CENTER) {
|
||||
int h = lines.size() * font->getFontHeight();
|
||||
newRect.top = (newRect.top + newRect.bottom) / 2 - h / 2;
|
||||
newRect.bottom = newRect.top + h;
|
||||
}
|
||||
|
||||
Common::Rect shadowRect = newRect;
|
||||
shadowRect.translate(_nShadow_DX, _nShadow_DY);
|
||||
|
||||
for (uint i = 0; i < lines.size(); ++i) {
|
||||
const Common::U32String &line = lines[i];
|
||||
|
||||
if (bShadowed) {
|
||||
color = CBofApp::getApp()->getPalette()->getNearestIndex(_cShadowColor);
|
||||
displayLine(font, surface, line, shadowRect.left, shadowRect.top,
|
||||
shadowRect.width(), color, align);
|
||||
}
|
||||
|
||||
color = CBofApp::getApp()->getPalette()->getNearestIndex(_cTextColor);
|
||||
displayLine(font, surface, line, newRect.left, newRect.top,
|
||||
newRect.width(), color, align);
|
||||
|
||||
newRect.top += font->getFontHeight();
|
||||
shadowRect.top += font->getFontHeight();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBofText::displayLine(Graphics::Font *font, Graphics::ManagedSurface &surface,
|
||||
const Common::U32String &line, int left, int top, int width, int color, Graphics::TextAlign align) {
|
||||
if (!line.contains('\t')) {
|
||||
font->drawString(&surface, line, left, top, width, color, align);
|
||||
|
||||
} else {
|
||||
// Special rendering of tabbed text
|
||||
Common::U32String str = line;
|
||||
|
||||
while (!str.empty()) {
|
||||
if (str[0] == '\t') {
|
||||
// Move to next tab stop
|
||||
left = (left + TAB_SIZE) / TAB_SIZE * TAB_SIZE;
|
||||
str.deleteChar(0);
|
||||
|
||||
} else {
|
||||
Common::U32String fragment;
|
||||
size_t tab = str.findFirstOf('\t');
|
||||
if (tab == Common::U32String::npos) {
|
||||
fragment = str;
|
||||
str.clear();
|
||||
} else {
|
||||
fragment = Common::U32String(str.c_str(), str.c_str() + tab);
|
||||
str = Common::U32String(str.c_str() + tab);
|
||||
}
|
||||
|
||||
int fragmentWidth = font->getStringWidth(fragment);
|
||||
font->drawString(&surface, fragment, left, top, width, color, align);
|
||||
|
||||
left += fragmentWidth;
|
||||
width -= fragmentWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode paintText(CBofWindow *pWnd, CBofRect *pRect, const char *pszString, const int nSize, const int nWeight, const COLORREF cColor, int nJustify, uint32 nFormatFlags, int nFont) {
|
||||
assert(pWnd != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofText cText(pRect, nJustify, nFormatFlags);
|
||||
return cText.display(pWnd, pszString, nSize, nWeight, cColor, nFont);
|
||||
}
|
||||
|
||||
ErrorCode paintText(CBofBitmap *pBmp, CBofRect *pRect, const char *pszString, const int nSize, const int nWeight, const COLORREF cColor, int nJustify, uint32 nFormatFlags, int nFont) {
|
||||
assert(pBmp != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofText cText;
|
||||
cText.setupTextOpt(pRect, nJustify, nFormatFlags);
|
||||
|
||||
cText.setColor(cColor);
|
||||
|
||||
return cText.displayTextEx(pBmp, pszString, pRect, nSize, nWeight, false, nFont);
|
||||
}
|
||||
|
||||
ErrorCode paintShadowedText(CBofBitmap *pBmp, CBofRect *pRect, const char *pszString, const int nSize, const int nWeight, const COLORREF cColor, int nJustify, uint32 nFormatFlags, int nFont) {
|
||||
assert(pBmp != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
CBofText cText;
|
||||
cText.setupTextOpt(pRect, nJustify, nFormatFlags);
|
||||
|
||||
cText.setColor(cColor);
|
||||
cText.setShadowColor(CTEXT_SHADOW_COLOR);
|
||||
cText.setShadowSize(CTEXT_SHADOW_DX, CTEXT_SHADOW_DY);
|
||||
|
||||
return cText.displayTextEx(pBmp, pszString, pRect, nSize, nWeight, true, nFont);
|
||||
}
|
||||
|
||||
CBofRect calculateTextRect(CBofWindow *pWnd, const CBofString *pStr, int nSize, int nFont) {
|
||||
return calculateTextRect(pWnd->getRect(), pStr, nSize, nFont);
|
||||
}
|
||||
|
||||
CBofRect calculateTextRect(CBofRect rect, const CBofString *pStr, int nSize, int nFont) {
|
||||
// Get the font to use
|
||||
Graphics::Font *font = CBofText::getFont(nFont, nSize, TEXT_NORMAL);
|
||||
|
||||
// Wrap the text as necessary
|
||||
Common::U32StringArray lines;
|
||||
font->wordWrapText(Common::U32String(pStr->getBuffer(), Common::kWindows1252), rect.width(), lines);
|
||||
|
||||
// Iterate the lines to get the maximum width
|
||||
int maxWidth = 0;
|
||||
for (uint i = 0; i < lines.size(); ++i)
|
||||
maxWidth = MAX(maxWidth, font->getStringWidth(lines[i]));
|
||||
|
||||
return CBofRect(0, 0, maxWidth, (int)lines.size() * font->getFontHeight());
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
340
engines/bagel/spacebar/boflib/gfx/text.h
Normal file
340
engines/bagel/spacebar/boflib/gfx/text.h
Normal file
@@ -0,0 +1,340 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GFX_TEXT_H
|
||||
#define BAGEL_BOFLIB_GFX_TEXT_H
|
||||
|
||||
#include "graphics/font.h"
|
||||
#include "bagel/boflib/object.h"
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define NUM_POINT_SIZES 32
|
||||
|
||||
// Text color and offset definitions
|
||||
#define CTEXT_COLOR RGB(0,0,0)
|
||||
#define CTEXT_SHADOW_COLOR RGB(0,0,0)
|
||||
#define CTEXT_YELLOW RGB(255, 255, 0)
|
||||
#define CTEXT_WHITE RGB(255, 255, 255)
|
||||
|
||||
#define CTEXT_SHADOW_DX 2
|
||||
#define CTEXT_SHADOW_DY 2
|
||||
|
||||
// Text justification definitions
|
||||
enum {
|
||||
JUSTIFY_CENTER = 0,
|
||||
JUSTIFY_LEFT = 1,
|
||||
JUSTIFY_RIGHT = 2,
|
||||
JUSTIFY_WRAP = 3
|
||||
};
|
||||
|
||||
// Text weight definitions
|
||||
//
|
||||
|
||||
/*
|
||||
* DrawText Format Flags
|
||||
*/
|
||||
#define DT_TOP 0x00000000
|
||||
#define DT_LEFT 0x00000000
|
||||
#define DT_CENTER 0x00000001
|
||||
#define DT_RIGHT 0x00000002
|
||||
#define DT_VCENTER 0x00000004
|
||||
#define DT_BOTTOM 0x00000008
|
||||
#define DT_WORDBREAK 0x00000010
|
||||
#define DT_SINGLELINE 0x00000020
|
||||
#define DT_EXPANDTABS 0x00000040
|
||||
#define DT_TABSTOP 0x00000080
|
||||
#define DT_NOCLIP 0x00000100
|
||||
#define DT_EXTERNALLEADING 0x00000200
|
||||
#define DT_CALCRECT 0x00000400
|
||||
#define DT_NOPREFIX 0x00000800
|
||||
#define DT_intERNAL 0x00001000
|
||||
|
||||
|
||||
enum {
|
||||
FW_NORMAL,
|
||||
FW_BOLD,
|
||||
FW_MEDIUM,
|
||||
};
|
||||
|
||||
#define FONT_DEFAULT 0
|
||||
#define FONT_MONO 1
|
||||
|
||||
#define TEXT_DONTCARE 0
|
||||
#define TEXT_THIN FW_THIN
|
||||
#define TEXT_EXTRALIGHT FW_EXTRALIGHT
|
||||
#define TEXT_ULTRALIGHT FW_ULTRALIGHT
|
||||
#define TEXT_LIGHT FW_LIGHT
|
||||
#define TEXT_NORMAL FW_NORMAL
|
||||
#define TEXT_REGULAR FW_REGULAR
|
||||
#define TEXT_MEDIUM FW_MEDIUM
|
||||
#define TEXT_SEMIBOLD FW_SEMIBOLD
|
||||
#define TEXT_DEMIBOLD FW_DEMIBOLD
|
||||
#define TEXT_BOLD FW_BOLD
|
||||
#define TEXT_EXTRABOLD FW_EXTRABOLD
|
||||
#define TEXT_ULTRABOLD FW_ULTRABOLD
|
||||
#define TEXT_BLACK FW_BLACK
|
||||
#define TEXT_HEAVY FW_HEAVY
|
||||
|
||||
#define FORMAT_TOP_LEFT ( DT_TOP | DT_LEFT )
|
||||
#define FORMAT_TOP_RIGHT ( DT_TOP | DT_RIGHT )
|
||||
#define FORMAT_TOP_CENTER ( DT_TOP | DT_CENTER )
|
||||
#define FORMAT_BOT_LEFT ( DT_BOTTOM | DT_LEFT )
|
||||
#define FORMAT_BOT_RIGHT ( DT_BOTTOM | DT_RIGHT )
|
||||
#define FORMAT_BOT_CENTER ( DT_BOTTOM | DT_CENTER )
|
||||
#define FORMAT_CENTER_LEFT ( DT_VCENTER | DT_LEFT )
|
||||
#define FORMAT_CENTER_RIGHT ( DT_VCENTER | DT_RIGHT )
|
||||
#define FORMAT_CENTER_CENTER ( DT_VCENTER | DT_CENTER )
|
||||
#define FORMAT_SINGLE_LINE DT_SINGLELINE
|
||||
#define FORMAT_MULTI_LINE DT_WORDBREAK
|
||||
#define FORMAT_DEFAULT ( FORMAT_TOP_LEFT | FORMAT_MULTI_LINE )
|
||||
|
||||
#define FONT_DEFAULT_SIZE (-14)
|
||||
#define FONT_8POINT 8
|
||||
#define FONT_10POINT 10
|
||||
#define FONT_12POINT 12
|
||||
#define FONT_14POINT 14
|
||||
#define FONT_15POINT 15
|
||||
#define FONT_18POINT 18
|
||||
#define FONT_20POINT 20
|
||||
#define TEXT_DEFAULT_FACE TEXT_BOLD
|
||||
|
||||
|
||||
class CBofText : public CBofObject, public CBofError {
|
||||
public:
|
||||
// Constructors
|
||||
CBofText();
|
||||
CBofText(const CBofRect *pRect, int nJustify = JUSTIFY_CENTER, uint32 nFormatFlags = FORMAT_DEFAULT);
|
||||
virtual ~CBofText();
|
||||
|
||||
// Implementation
|
||||
//
|
||||
|
||||
/**
|
||||
* Build primary data objects and work areas; text will be displayed
|
||||
* centered within the defined rectangular area, hence it is up to
|
||||
* the caller to ensure that the text fits (excess is cropped).
|
||||
* @param pRect Rectangular area encompassed by the text object
|
||||
* @param nJustify Alignment of text in the rectangle
|
||||
* @param nFormatFlags Format flag
|
||||
*/
|
||||
ErrorCode setupText(const CBofRect *pRect, int nJustify = JUSTIFY_CENTER, uint32 nFormatFlags = FORMAT_DEFAULT);
|
||||
ErrorCode setupTextOpt(const CBofRect *pRect, int nJustify = JUSTIFY_CENTER, uint32 nFormatFlags = FORMAT_DEFAULT);
|
||||
|
||||
void setText(const CBofString &cString) {
|
||||
_cCurString = cString;
|
||||
}
|
||||
void setColor(const COLORREF cColor) {
|
||||
_cTextColor = cColor;
|
||||
}
|
||||
void SetSize(const int nSize) {
|
||||
_nCurSize = nSize;
|
||||
}
|
||||
void setWeight(const int nWeight) {
|
||||
_nCurWeight = nWeight;
|
||||
}
|
||||
|
||||
void setShadowColor(const COLORREF cColor) {
|
||||
_cShadowColor = cColor;
|
||||
}
|
||||
void setShadowSize(int nDX, int nDY) {
|
||||
_nShadow_DX = nDX;
|
||||
_nShadow_DY = nDY;
|
||||
}
|
||||
|
||||
CBofString getText() const {
|
||||
return _cCurString;
|
||||
}
|
||||
COLORREF getColor() const {
|
||||
return _cTextColor;
|
||||
}
|
||||
int getSize() const {
|
||||
return _nCurSize;
|
||||
}
|
||||
int getWeight() const {
|
||||
return _nCurWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the background behind current text on screen
|
||||
* @param pWnd Window to erase text from
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode erase(CBofWindow *pWnd);
|
||||
|
||||
/**
|
||||
* Restores the background behind current text offscreen
|
||||
* @param pBmp Offscreen bitmap to erase text from
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode erase(CBofBitmap *pBmp);
|
||||
|
||||
/**
|
||||
* Re-displays current text, formatted with current attribs
|
||||
* @param pWnd Window to paint into
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode display(CBofWindow *pWnd);
|
||||
|
||||
/**
|
||||
* Re-displays current text, formatted with current attribs
|
||||
* @param pBmp Bitmap to paint into
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode display(CBofBitmap *pBmp);
|
||||
|
||||
/**
|
||||
* Display a text string, formatted in the current text area
|
||||
* @param pWnd Window to paint into
|
||||
* @param pszText Point to text string to be displayed
|
||||
* @param nSize Point size of the text to be used
|
||||
* @param nWeight Weighting of the font (FW_ identifier)
|
||||
* @param cColor Color that the text will be
|
||||
* @param nFont Font used (default or mono)
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode display(CBofWindow *pWnd, const char *pszText, int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nFont = FONT_DEFAULT);
|
||||
|
||||
/**
|
||||
* Display a text string, formatted in the current text area
|
||||
* @param pBmp Bitmap to paint into
|
||||
* @param pszText Point to text string to be displayed
|
||||
* @param nSize Point size of the text to be used
|
||||
* @param nWeight Weighting of the font (FW_ identifier)
|
||||
* @param cColor Color that the text will be
|
||||
* @param nFont Font used (default or mono)
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode display(CBofBitmap *pBmp, const char *pszText, int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nFont = FONT_DEFAULT);
|
||||
|
||||
/**
|
||||
* Display a shadowed text string into the current text area
|
||||
* @param pWnd Window to paint into
|
||||
* @param pszText Point to text string to be displayed
|
||||
* @param nSize Point size of the text to be used
|
||||
* @param nWeight Weighting of the font (FW_ identifier)
|
||||
* @param cColor Color that the text will be
|
||||
* @param cShadow Color that the text's shadow will be
|
||||
* @param nDX Shadow DX
|
||||
* @param nDY Shadow DY
|
||||
* @param nFont Font used (default or mono)
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode displayShadowed(CBofWindow *pWnd, const char *pszText, int nSize,
|
||||
int nWeight, COLORREF cColor, COLORREF cShadow = CTEXT_SHADOW_COLOR,
|
||||
int nDX = CTEXT_SHADOW_DX, int nDY = CTEXT_SHADOW_DY, int nFont = FONT_DEFAULT);
|
||||
|
||||
|
||||
void flushBackground() {
|
||||
_bSaved = false;
|
||||
}
|
||||
|
||||
static ErrorCode initialize();
|
||||
static ErrorCode shutdown();
|
||||
|
||||
/**
|
||||
* Displays specified text onto specified bitmap
|
||||
* @param pBmp Bitmap to paint text onto
|
||||
* @param pszText Pointer to text string to be displayed
|
||||
* @param pRect Area to paint text to
|
||||
* @param nSize Point size of the text to be used
|
||||
* @param nWeight Weighting of the font (FW_ identifier)
|
||||
* @param bShadowed Whether the text is shadowed
|
||||
* @param nFont Font used (default or mono)
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode displayTextEx(CBofBitmap *pBmp, const char *pszText, CBofRect *pRect, int nSize, int nWeight, bool bShadowed, int nFont = FONT_DEFAULT);
|
||||
|
||||
static Graphics::Font *getFont(int nFont, int nSize, int nWeight);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initializes key fields to zero or nullptr states.
|
||||
*/
|
||||
void initializeFields();
|
||||
|
||||
/**
|
||||
* Displays specified text onto specified bitmap
|
||||
* @param pWnd Window to paint text onto
|
||||
* @param pszText Pointer to text string to be displayed
|
||||
* @param pRect Area to paint text to
|
||||
* @param nSize Point size of the text to be used
|
||||
* @param nWeight Weighting of the font (FW_ identifier)
|
||||
* @param bShadowed Whether the text is shadowed
|
||||
* @param nFont Font used (default or mono)
|
||||
* @return Error return Code
|
||||
*/
|
||||
ErrorCode displayText(CBofWindow *pWnd, const char *pszText, CBofRect *pRect, int nSize, int nWeight, bool bShadowed, int nFont = FONT_DEFAULT);
|
||||
ErrorCode displayText(CBofBitmap *pBmp, const char *pszText, CBofRect *pRect, int nSize, int nWeight, bool bShadowed, int nFont = FONT_DEFAULT);
|
||||
|
||||
void displayLine(Graphics::Font *font, Graphics::ManagedSurface &surface, const Common::U32String &line,
|
||||
int left, int top, int width, int color, Graphics::TextAlign align);
|
||||
|
||||
protected:
|
||||
CBofString _cCurString; // text to be displayed
|
||||
CBofRect _cRect; // bounding rectangle of text area
|
||||
CBofPoint _cPosition; // upper left corner of text displayed
|
||||
CBofSize _cSize; // dx/dy size of the text bitmap
|
||||
COLORREF _cTextColor; // color to use for the text itself
|
||||
COLORREF _cShadowColor; // color to use for the text's shadow
|
||||
CBofBitmap *_pBackground; // bitmap for the text's background
|
||||
CBofBitmap *_pWork; // bitmap for the work area
|
||||
|
||||
int _nCurSize; // point size of current text
|
||||
int _nCurWeight; // style of current text
|
||||
|
||||
int _nJustify; // positioning within the rectangle
|
||||
int _nShadow_DX; // horizontal offset for shadow
|
||||
int _nShadow_DY; // vertical offset for shadow
|
||||
uint32 _nFormatFlags; // multi line formatting flags
|
||||
bool _bMultiLine; // multi vs single line formatting
|
||||
bool _bSaved;
|
||||
|
||||
static Graphics::Font *_defaultFonts[NUM_POINT_SIZES];
|
||||
static Graphics::Font *_fixedFonts[NUM_POINT_SIZES];
|
||||
|
||||
static bool _initialized;
|
||||
|
||||
static int _tabStop; // tabstop table
|
||||
};
|
||||
|
||||
// Global text functions
|
||||
//
|
||||
ErrorCode paintText(CBofWindow *pWnd, CBofRect *pRect, const char *, int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nJustify = JUSTIFY_CENTER, uint32 nFormat = FORMAT_DEFAULT, int nFont = FONT_DEFAULT);
|
||||
ErrorCode paintText(CBofBitmap *pBmp, CBofRect *pRect, const char *, int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nJustify = JUSTIFY_CENTER, uint32 nFormat = FORMAT_DEFAULT, int nFont = FONT_DEFAULT);
|
||||
|
||||
ErrorCode paintShadowedText(CBofBitmap *, CBofRect *pRect, const char *, int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nJustify = JUSTIFY_CENTER, uint32 n = FORMAT_DEFAULT, int nFont = FONT_DEFAULT);
|
||||
|
||||
/**
|
||||
* Utility routine that will calculate the rectangle that a text string
|
||||
* will fit in, given point size and font.
|
||||
*/
|
||||
CBofRect calculateTextRect(CBofWindow *pWnd, const CBofString *pStr, int nSize, int nFont);
|
||||
CBofRect calculateTextRect(CBofRect rect, const CBofString *pStr, int nSize, int nFont);
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user