Source Code (Use browser search to find items of interest.)

Class Index

kmahjongg'Tileset (./kdegames/kmahjongg/Tileset.h:7)

class Tileset {
   public:
     Tileset(bool scaled=false);	     
     ~Tileset();	

     bool loadTileset(const char *filesetPath, const bool isPreview = false);
     QRgb *createTile(short x, short y, QRgb *dst, QImage &src , QRgb *face);
     QRgb *copyTileImage(short tileX, short tileY, QRgb *to, QImage &from);  

     void setScaled(bool sc) {isScaled = sc; divisor = (sc) ? 2 : 1;};


     QRgb *tile(short tnum);
     QRgb *selectedTile(short tnum);
     short width(void) {return w/divisor;};
     short height(void) {return h/divisor;};
     short shadowSize(void) {return ss/divisor;};
     short size(void) {return s;};
     short qWidth(void) {return qw/divisor;};
     short qHeight(void) {return qh/divisor;};


     QPixmap *selectedPixmaps(int num) {
	if (!isScaled) 
		return &(selectedPix[num]);
	else
		return &(selectedMiniPix[num]);
	};

     QPixmap *unselectedPixmaps(int num) {
	if (!isScaled)
		return &(unselectedPix[num]);
	else
		return &(unselectedMiniPix[num]);
	};

     QPixmap *selectedShadowPixmaps(int num) {
	if (!isScaled) 
		return &(selectedShadowPix[num]);
	else
		return &(selectedShadowMiniPix[num]);
	};

     QPixmap *unselectedShadowPixmaps(int num) {
	if (!isScaled)
		return &(unselectedShadowPix[num]);
	else
		return &(unselectedShadowMiniPix[num]);
	};

  protected:

     static const int maxTiles=45;
  	void  createPixmap(QRgb *src, QPixmap &dest, bool scale, bool shadow);
  

  private:
    QBitmap maskBits;    // xbm mask for the tile
    QBitmap maskBitsMini;    // xbm mask for the tile
    QRgb* tiles;         // Buffer containing all tiles (unselected glyphs)
    QRgb* selectedTiles; // Buffer containing all tiles (selected glyphs)


    // in version 0.5 we have moved ftom using images and calculating
    // masks etc, to using pixmaps and letting the blt do the hard work,
    // in hardware. 
    QPixmap selectedPix[maxTiles]; // selected tiles
    QPixmap unselectedPix[maxTiles]; // unselected tiles
    QPixmap selectedMiniPix[maxTiles]; // selected tiles
    QPixmap unselectedMiniPix[maxTiles]; // unselected tiles

    QPixmap selectedShadowPix[maxTiles]; // selected tiles as above in shadow
    QPixmap unselectedShadowPix[maxTiles]; // unselected tiles
    QPixmap selectedShadowMiniPix[maxTiles]; // selected tiles
    QPixmap unselectedShadowMiniPix[maxTiles]; // unselected tiles




    QRgb* selectedFace;  // The tile background face for a selected tile
    QRgb* unselectedFace;// The tile background face for an unselected tile

    QRgb  tr;    // transparenct color for tile bg

    short ss;   // left/bottom shadow width
    short bs;   // width of the border around a tile
    short w;    // tile width ( +border +shadow)
    short h;    // tile height ( +border +shadow)
    short qw;   // quarter tile width used in 3d rendering
    short qh;   // quarter tile height used in 3d rendering
    short s;	// buffer size for tile (width*height)

    QString filename;  // cache the last file loaded to save reloading it
    bool isScaled;
    int divisor;
};


kmahjongg'Tileset::Tileset() (./kdegames/kmahjongg/Tileset.cpp:52)

Tileset::Tileset(bool scale): 
	maskBits(mask_width, mask_height, mask_bits, true),
	maskBitsMini(mini_width, mini_height, mini_bits, true)
{
	isScaled = scale;
	divisor =  (isScaled) ? 2 : 1; 

	// set up tile metrics (fixed for now)
	ss     = 4;    // left/bottom shadow width
	bs     = 1;    // tile boarder width 
	w      = 40;   // tile width (inc boarder & shadow)
	h      = 56;   // tile height (inc boarder and shadow)
	s      = w*h;  // RGBA's required per tile
	
	// Allocate memory for the 9*5 tile arrays
    	tiles         = new QRgb [9*5*s];
    	selectedTiles = new QRgb [9*5*s];

    	// allocate memory for single tile storage 
    	selectedFace   = new QRgb [s];
    	unselectedFace = new QRgb [s];

	// quarter widths are used as an offset when
	// overlaying tiles in 3 dimensions.
	qw  = ((w-ss)/2) ;    
	qh = ((h-ss)/2) ;	

	filename = "";
}


// ---------------------------------------------------------


kmahjongg'Tileset::~Tileset() (./kdegames/kmahjongg/Tileset.cpp:85)

Tileset::~Tileset() {
	
	// deallocate all memory 
    	delete [] tiles;         
    	delete [] selectedTiles; 
    	delete [] selectedFace;  
    	delete [] unselectedFace;
}

// ---------------------------------------------------------
// copy a tile from a qimage into a linear array of bytes. This
// method returns the address of the byte after the copied image
// and can be used to fill a larger array of tiles.


kmahjongg'Tileset::copyTileImage() (./kdegames/kmahjongg/Tileset.cpp:99)

QRgb *Tileset::copyTileImage(short tileX, short tileY, QRgb *to, QImage &from) {
    QRgb *dest = to;
    QRgb *src;

    src = (QRgb *) from.scanLine(tileY * h)
             +(tileX * w);
    for (short pos=0; pos < h; pos++) {
	memcpy(dest, src, w*sizeof(QRgb));
	dest+=w;
	src += from.width();
    }
    return(dest);
}

// ----------------------------------------------------------
// Create a tile. Take a specified tile background a tile face
// (specified as an x,y coord) and a destination buffer (location
// in which is calculated from the x,y) and copy in the
// tile background, overlaying the foreground with transparency
// (the foregrounds top/left pixel is taken as the transparent
// color).



kmahjongg'Tileset::createTile() (./kdegames/kmahjongg/Tileset.cpp:122)

QRgb *Tileset::createTile(short x, short y, 
		QRgb *det, QImage &allTiles , QRgb *face) {
  QRgb *image ;
  QRgb *to = det;

  // Alloc the space
  image = new QRgb[s];

  // copy in the background
  memcpy(to, face, s*sizeof(QRgb)); 
  
  // get the tile gylph
  copyTileImage(x, y , image, allTiles); 

  // copy the image over the background using the
  // top left colour as the transparency. We step over
  // the shadow and the boarder
  
  QRgb* src =  image+                        // image
    ss+             // past the left shadow
    bs+             // then the tile border
    (bs  * w);      // then step past the top border


  to += (((ss+bs))+(bs*w));


  QRgb trans = *src;

  // start after the top border rows and go through all rows
  for( short YP=0; YP < h-ss - (2*bs); YP++) {
    // start after the shadow and border and iterate over x
    for (short xpos=0; xpos < w-ss -(2*bs) ; xpos++) {
      // skip transparent pixels
      if (*src != trans)
	*to = *src;
      src++;
      to++;  
    }
    // step over the border to get to the next row
    src  += ss + (2 * bs);
    to += ss + (2 * bs);
    }
 
  // Free allocated space
  delete [] image;
 
  // calculate the address of the next tile
  return(det+s);
}

// --------------------------------------------------------
// create a pixmap for a tile. Optionally create a scalled
// version, which can be used for mini tile requirements.
// this gives us a small tile for previews and showing
// removed tiles.

kmahjongg'Tileset::createPixmap() (./kdegames/kmahjongg/Tileset.cpp:178)

void  Tileset::createPixmap(QRgb *src, QPixmap &dest, bool scale, bool shadow)
{

    QImage buff;
    QRgb   *line;

    buff.create(w, h, 32);

    for (int y=0; y<h; y++) {
	line = (QRgb *) buff.scanLine(y);
	memcpy( line, src, w*sizeof(QRgb));

	if (shadow) {
	  for (int spos=0; spos <w; spos++) {
	    line[spos] = QColor(line[spos]).dark(133).rgb();
	  }
	}

	src += w;
    }	


    // create the pixmap and initialise the drawing mask
    if (!scale) {
    	dest.convertFromImage(buff);
    	dest.setMask(maskBits);
    } else {
    	dest.convertFromImage(buff.smoothScale(w/2, h/2));
    	dest.setMask(maskBitsMini);
    }

}


// ---------------------------------------------------------

kmahjongg'Tileset::loadTileset() (./kdegames/kmahjongg/Tileset.cpp:213)

bool Tileset::loadTileset( const char* tilesetPath, const bool isPreview)
{

    QImage qiTiles;
    QRgb *unsel;
    QRgb *sel;
    QRgb *nextSel=0;
    QRgb *nextUnsel=0;

    if (filename == tilesetPath) {
	return true;
    }


    // try to load it
    if( ! qiTiles.load( tilesetPath) )
        return( false );



    // we deal only with 32 bit images
    if (qiTiles.depth() != 32)
      qiTiles = qiTiles.convertDepth(32);



    // Read in the unselected and selected tile backgrounds
    copyTileImage(7, 4 , unselectedFace, qiTiles); 
    copyTileImage(8, 4, selectedFace, qiTiles); 



    // Read in the 9*5 tiles. Each tile is overlayed onto
    // the selected and unselected tile backgrounds and
    // stored.
    sel = selectedTiles;
    unsel = tiles;
    for (short atY=0; atY<5; atY++) {
	for (short atX=0; atX<9; atX++) {


	  nextUnsel = createTile(atX, atY, unsel , qiTiles, unselectedFace);

	  // for the preview dialog we do not create selected tiles
	  if (!isPreview)
	      nextSel = createTile(atX, atY, sel , qiTiles, selectedFace);
	  int pixNo = atX+(atY*9);

	  // for the preview dialog we only create the unselected mini pix
	  if (!isPreview) {
	      createPixmap(sel, selectedPix[pixNo], false, false);
	      createPixmap(unsel, unselectedPix[pixNo], false, false);
	      createPixmap(sel, selectedMiniPix[pixNo], true, false);

	      createPixmap(sel, selectedShadowPix[pixNo], false, true);
	      createPixmap(unsel, unselectedShadowPix[pixNo], false, true);
	      createPixmap(sel, selectedShadowMiniPix[pixNo], true, true);
	      createPixmap(unsel, unselectedShadowMiniPix[pixNo], true, true);
	  }

	  createPixmap(unsel, unselectedMiniPix[pixNo], true, false);
	  sel = nextSel;
	  unsel= nextUnsel;
	}
    }

    filename = tilesetPath;
    return( true );
}