home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/rastport.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
-
-
- struct RastPort *AllocRastPort(UWORD, UWORD, UWORD);
- struct RastPort *FreeRastPort(struct RastPort *);
- void Rotate(struct RastPort *, struct RastPort *);
-
- /* Function to write Text vertically. Function allocates
- two temporary rastports with bitmaps sized to fit the
- text string using the source rastport's font. Next, it
- calls Text() to write the string into tempRP then rotates
- the text 90 degrees into vertRP. Finally,it uses ClipBlit
- to place the text back into the source rastport at the
- current position. Works with colorfonts and proportional
- fonts. No guarantee it is bug free, or if it will work at
- all ("it works here").
-
- Its arguments are the RastPort, the string, and the stringlength.
- */
-
- void VertText(struct RastPort *r, UBYTE *s, LONG l)
- {
- struct TextExtent txex;
- struct RastPort *tempRP;
- struct RastPort *vertRP;
- UWORD d, w, h;
-
- TextExtent( r, s, l, &txex);
-
- w = txex.te_Width + 8; /* add 1 byte to be sure it fits */
- h = txex.te_Height;
- d = r->BitMap->Depth;
-
- tempRP = AllocRastPort( d, w, h);
- vertRP = AllocRastPort( d, h, w);
-
- if ( tempRP && vertRP )
- {
- SetRast( tempRP, 0);
- SetRast( vertRP, 0);
-
- SetFont( tempRP, r->Font);
- SetAPen( tempRP, r->FgPen);
-
- Move( tempRP, 0, tempRP->Font->tf_Baseline);
- Text( tempRP, s, l);
-
- Rotate( tempRP, vertRP);
-
- ClipBlit(vertRP, 0, 0, r, r->cp_x - r->Font->tf_Baseline, r->cp_y - w, h, w, 0xCC);
-
- }
- if (vertRP) FreeRastPort( vertRP );
- if (tempRP) FreeRastPort( tempRP );
- }
- /* Allocates and initializes a rastport. Must be freed
- by call to FreeRastPort.
- */
- struct RastPort *AllocRastPort( UWORD depth, UWORD width, UWORD height)
- {
- WORD i;
-
- struct BitMap *b;
- struct RastPort *r;
-
- b = (struct BitMap *) AllocMem(sizeof(struct BitMap), MEMF_CLEAR|MEMF_CHIP);
- if (b == NULL) return(NULL);
-
- r = (struct RastPort *) AllocMem(sizeof(struct RastPort), MEMF_CLEAR);
- if (r == NULL) goto cleanup;
-
- if (width & 0x7) width = (width & 0xFFF8) + 8;
-
- InitBitMap(b, depth, width, height);
-
- for (i = 0; i < depth; i++)
- {
- b->Planes[i] = (PLANEPTR) AllocRaster( width, height);
- if (b->Planes[i] == NULL) goto cleanup;
- }
-
- InitRastPort(r);
- r->BitMap = b;
-
- return(r);
-
- cleanup:
- if (b) {
- width = b->BytesPerRow << 3;
- height = b->Rows;
-
- for (i = 0; i < depth; i++)
- if (b->Planes[i]) FreeRaster(b->Planes[i], width, height);
-
- FreeMem(b, sizeof(struct BitMap));
- }
- if (r) FreeMem(r, sizeof(struct RastPort));
-
- return(NULL);
- }
-
- /*
- This function frees a RastPort allocated by AllocRastPort()
- */
- struct RastPort *FreeRastPort(struct RastPort *r)
- {
- struct BitMap *b;
- UWORD width, height;
- WORD i;
-
- if (r == NULL) return(NULL);
-
- if (b = r->BitMap)
- {
- width = b->BytesPerRow << 3;
- height = b->Rows;
- for (i = 0; i < (int) b->Depth; i++)
- if (b->Planes[i]) FreeRaster(b->Planes[i], width, height);
- FreeMem(b, sizeof(struct BitMap));
- }
- FreeMem(r, sizeof(struct RastPort));
-
- return(NULL);
- }
- /* Rotates bitmap in source rastport (srp) 90 degrees and places result
- in destination bitmap (drp). Both bitmaps should be allocated by call
- to AllocRastPort(). Destination bitmap should be allocated with the
- width and height reversed. This function does not check for this and
- the results will be very unpredicatable if this is not the case.
- This function splits up source bitmap into blocks of 8*8 bits and
- rotates each block then writes them to the correct block in the
- destination bitmap.
- */
- void Rotate(struct RastPort *srp, struct RastPort *drp)
- {
- static UWORD cbits[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-
- UBYTE *sptr, *dptr, *ptr;
- UBYTE nbits[8];
- UWORD bits;
- WORD i, j, k, l, m, n;
- UWORD drxbp, dblkc;
-
- /* offset to start of lower left block of destination bitmap */
- drxbp = (drp->BitMap->Rows - 8) * drp->BitMap->BytesPerRow;
-
- /* destination block decrement */
- dblkc = drp->BitMap->BytesPerRow << 3;
-
- for (i = 0; i < srp->BitMap->Depth; i++)
- {
- sptr = (UBYTE *) srp->BitMap->Planes[i];
- dptr = (UBYTE *) drp->BitMap->Planes[i];
-
- for (j = 0; j < drp->BitMap->BytesPerRow; j++)
- {
- n = srp->BitMap->BytesPerRow * j<<3;
-
- for (k = drxbp + j; k >= j; k -= dblkc)
- {
- for (l = 0; l < 8; l++) nbits[l] = 0;
-
- ptr = &sptr[n];
- for (l = 0; l < 8; l++)
- {
- bits = ptr[0];
- for (m = 0; m < 8; m++)
- {
- if (bits & cbits[m]) nbits[7 - m] |= cbits[l];
- }
- ptr += srp->BitMap->BytesPerRow;
- }
-
- ptr = &dptr[k];
- for (l = 0; l < 8; l++)
- {
- ptr[0] = nbits[l];
- ptr += drp->BitMap->BytesPerRow;
- }
-
- n++; /* increment source block key */
- }
- }
- }
-
- return;
- }
-