Category : Files from Magazines
Archive   : MAR93.ZIP
Filename : RGNOBJ.ASC

 
Output of file : RGNOBJ.ASC contained in archive : MAR93.ZIP
_UNDOCUMENTED CORNER_
edited by Andrew Schulman

[LISTING ONE]

WORD GetGDIsegment(void)
{
HRGN (FAR PASCAL * A)(int, int, int, int);
unsigned short far * B;
WORD GDIseg; /* GDI segment */
A = CreateRectRgn;
B = (unsigned short far *)A; /* function prolog: MOV AX,DGROUP */
((char far *) B)++;
GDIseg = *B;
return GDIseg;
}


[LISTING TWO]


#include
WORD GetGDISegment(void)
{
SYSHEAPINFO info;
info.dwSize = sizeof(info);
SystemHeapInfo(&info);
return info.hGDISegment;
}


[LISTING THREE]

#include
static unsigned short far * ConvertRegionToAddress(HRGN region)
{
WORD GDIseg;
unsigned short far * * p; /* pointer to GDI segment */
unsigned short far * pv; /* pointer to region data */
GDIseg = GetGDIsegment();
FP_SEG(p) = GDIseg;
FP_OFF(p) = handle;
pv = (unsigned short far *) *p;
FP_SEG(pv) = GDIseg;
return pv;
}



[LISTING FOUR]

static tFixed ToFixed(int value)
{
return ((tFixed) value) << 16;
}


[LISTING FIVE]

static tFixed tFixMul(tFixed num1, tFixed num2)
{
tFixed result;
int negated = false;
unsigned short int2;
unsigned short frac2;

/* 'negated' is the sign of the result. We in effect store
the sign bits. This will fail if we give it -32768.0000 */
num1 = ((long) num1 < 0) ? negated = !negated, -num1 : num1;
num2 = ((long) num2 < 0) ? negated = !negated, -num2 : num2;

/* Extract the highword (integer part) and lowword (fraction
part) of the second operand */
int2 = (unsigned long) num2 >> 16;
frac2 = (unsigned long) num2 & 0xFFFF;

result=(((unsigned long) num1*frac2) >> 16)+((unsigned long) num1*int2);
return (negated ? -result : result);
}


[LISTING SIX]

static tFixed tFixRatio(int num, int denom)
{
tFixed result;
result = ((long) num << 16) / (long) denom;

return result;
}


[LISTING SEVEN]

static short tFixRound(tFixed num)
{
int negated = ((long) num < 0);
short result = negated ? (-num) >> 16 : num >> 16;
unsigned short low = negated ? (-num) & 0xFFFF : num & 0xFFFF;
if (negated)
return -result - (low > 0x7FFF ? 1 : 0);
else
return result + (low > 0x7FFF ? 1 : 0);
}



[LISTING EIGHT]

HRGN outer = CreateRectRgn(100,200,300,400);
HRGN inner = CreateRectRgn(110,210,290,390);
HRGN hollow = CreateRectRgn(0,0,0,0);
CombineRgn(hollow, outer, NULL, RGN_COPY);
CombineRgn(hollow, hollow, inner, RGN_DIFF);


[LISTING NINE]

static short MapScalar(short value, short srcOffset, short dstOffset,
tFixed scale)
{
return tFixRound(tFixMul(scale, ToFixed(value-srcOffset))) + dstOffset;
}
void MapRgn(HRGN rgn, RECT * srcRect, RECT * dstRect)
{
register short srcX = srcRect->left;
register short srcY = srcRect->top;
register short dstX = dstRect->left;
register short dstY = dstRect->top;
/* Compute the X-scale and Y-scale as the ratio of the
length of the source and destination width and height */
tFixed scaleX = tFixRatio( (dstRect->right - dstX),
(srcRect->right - srcX));
tFixed scaleY = tFixRatio( (dstRect->bottom - dstY),
(srcRect->bottom - srcY));
short ySpans; // number of Y-spans in the region
short yspan; // current Y-span being processed
short xSpans; // number of X-spans in this Y-span
short xspan; // current X-span being processed
short RgnLength; // length of region, in words
short * regionbase; // base of region data
short * scanC; // current region word

regionbase = ConvertRegionToAddress(rgn); // Point to beginning of region
scanC = regionbase; // start at base of region
scanC += 5; // skip GDI header, point to region length
if (GetSystemMetrics(SM_DEBUG) && (GetVersion() != 3))
scanC += 2; // adjust for 3.1+ Debug version!!
RgnLength = *scanC++; // word 5: region length
ySpans = *scanC++; // word 6: number of Y-spans
scanC += 1; // Skip to bounding box.

// Map bounding box for the region
*scanC++ = MapScalar(*scanC, srcX, dstX, scaleX); // left
*scanC++ = MapScalar(*scanC, srcY, dstY, scaleY); // top
*scanC++ = MapScalar(*scanC, srcX, dstX, scaleX); // right
*scanC++ = MapScalar(*scanC, srcY, dstY, scaleY); // bottom
for (yspan = 0; yspan < ySpans; yspan++)
{ /* foreach y-span */
xSpans = *scanC++ / 2;

// Now we are pointing to the y start and y end points. Scale them.
*scanC = MapScalar(*scanC, srcY, dstY, scaleY); // startY
scanC++;
*scanC = MapScalar(*scanC, srcY, dstY, scaleY); // endY
scanC++;
// We are pointing to the x limit pairs for this y-span.
// Iterate down these, scaling each of them
for (xspan = 0; xspan < xSpans; xspan++)
{ /* foreach x-span */
// now we are pointing to the x start and end points. Scale them
*scanC = MapScalar(*scanC, srcX, dstX, scaleX); // startX
scanC++;
*scanC = MapScalar(*scanC, srcX, dstX, scaleX); // endX
scanC++;
} /* foreach x-span */
// The next word is the second copy of the number of X spans * 2.
// Ignore it.
scanC++;
} /* foreach y-span */

}



  3 Responses to “Category : Files from Magazines
Archive   : MAR93.ZIP
Filename : RGNOBJ.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/