windows-nt/Source/XPSP1/NT/shell/osshell/accesory/terminal/chrpaint.c
2020-09-26 16:20:57 +08:00

388 lines
12 KiB
C

/*===========================================================================*/
/* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
/* Houston, Texas */
/*===========================================================================*/
#define NOLSTRING TRUE /* jtf win3 mod */
#include <windows.h>
#include <port1632.h>
#include "dcrc.h"
#include "dynacomm.h"
#include "video.h"
/*---------------------------------------------------------------------------*/
/* eraseColorRect() - use current attribute to erase area [jtf] */
/*---------------------------------------------------------------------------*/
VOID eraseColorRect(HDC hDC, LPRECT rect, BYTE cAttr)
{
HBRUSH hTmpBrush;
hTmpBrush = CreateSolidBrush(RGB(vidAttr[cAttr & AMASK].bkgd[VID_RED],
vidAttr[cAttr & AMASK].bkgd[VID_GREEN],
vidAttr[cAttr & AMASK].bkgd[VID_BLUE]));
FillRect(hDC, (LPRECT) rect, (HBRUSH) hTmpBrush);
DeleteObject((HBRUSH) hTmpBrush);
}
/*---------------------------------------------------------------------------*/
/* reDrawTermScreen() - [mbb] */
/*---------------------------------------------------------------------------*/
VOID reDrawTermScreen(INT nStart, INT nCount, INT nOffset)
{
while(nStart < nCount)
reDrawTermLine((nStart++) + nOffset, 0, maxChars);
}
/*---------------------------------------------------------------------------*/
/* reDrawTermLine() - Reslap some lines back up on the terminal. [scf] */
/*---------------------------------------------------------------------------*/
VOID reDrawTermLine(INT lin, INT col, INT len)
{
LPBYTE lpText;
if(lin < 0)
{
getPort();
hideTermCursor();
if((lpText = GlobalLock(hTE.hText)) != NULL)
{
drawTermLine(lpText + ((savTopLine + lin) * (maxChars + 2)) + col,
len, lin, col + len, LNORMAL, 0);
GlobalUnlock(hTE.hText);
}
showTermCursor();
releasePort();
}
else if(lin <= (maxScreenLine+1)) /* mbbx 2.00.06: jtf disp2 */
{
attrib[lin][LFLAGS] = (LCLEAR | LDIRTY);
updateLine(lin);
}
}
/*---------------------------------------------------------------------------*/
/* updateLine() - */
/*---------------------------------------------------------------------------*/
VOID updateLine(INT line)
{
BOOL bStatusLine; /* mbbx 2.00.06: jtf disp2 */
LPBYTE txt;
BYTE *attr;
INT col1, col2, len, txtLen; // sdj: unref variable was- bottom;
BYTE cAttr;
BOOL anyway;
/* mbbx 2.00.06: dont overwrite xferCtrls... */
if((bStatusLine = (line == maxScreenLine+1)) && (xferFlag > XFRNONE))
return;
getPort();
hideTermCursor();
if(!bStatusLine)
{
clipRect(&hTE.viewRect); /* jtf 3.Final */
txt = (LPBYTE)GlobalLock(hTE.hText) + (savTopLine + line) * (maxChars + 2);
}
else
{
clipRect(&statusRect); /* rjs bugs 019 */
txt = (LPBYTE) line25;
}
attr = attrib[line];
anyway = (attr[LFLAGS] == (LCLEAR | LDIRTY));
for(col1 = 0; col1 < maxChars; col1 = col2)
{
cAttr = attr[col1];
for (col2 = col1+1; col2 < maxChars; col2++)
{
attr[col2-1] &= ~ADIRTY;
if (cAttr != attr[col2])
break;
}
len = col2 - col1;
txtLen = len;
if((cAttr & ADIRTY) || anyway)
drawTermLine(txt, txtLen, line, col1 + txtLen, attr[LATTRIB], cAttr);
txt += len;
}
attr[col2-1] &= ~ADIRTY;
attr[LFLAGS] = 0;
if(!bStatusLine)
GlobalUnlock(hTE.hText);
showTermCursor();
releasePort();
}
/*---------------------------------------------------------------------------*/
/* drawTermLine() - */
/*---------------------------------------------------------------------------*/
VOID drawTermLine(LPBYTE txtPtr, INT len, INT lin, INT col, BYTE lAttr, BYTE cAttr)
{
BOOL bStatusLine;
HDC savePort;
HBITMAP hBitMap;
RECT srcRect, dstRect, tmpRect;
INT ndx;
BYTE grSave[132], grChar[132];
HPEN newPen, oldPen;
INT grLeft, grWidth2, grHeight2;
BOOL bhBitMapValid;
bhBitMapValid = FALSE; //sdj: there is a chance that hbitmap maynot
//sdj: be valid and still deleteobject(hbitmap)
//sdj: is called, and this may delete some random
//sdj: object, who knows, so lets delete it only
//sdj: if you create one
if(!(bStatusLine = (lin == maxScreenLine+1)))
{
if(((lin += (savTopLine - curTopLine)) < 0) || (lin > visScreenLine))
return;
}
if(lAttr != LNORMAL)
{
thePort = CreateCompatibleDC(savePort = thePort);
hBitMap = CreateCompatibleBitmap(thePort, chrWidth * maxChars, chrHeight);
bhBitMapValid = TRUE;
SelectObject(thePort, hBitMap);
SelectObject(thePort, hTE.hFont);
/* srcRect : rect to draw chars in (memory DC) */
srcRect.left = 0;
srcRect.right = len * chrWidth;
srcRect.top = 0;
srcRect.bottom = chrHeight;
/* dstRect : rect to copy bits to (stretchBlt) */
dstRect.right = col*chrWidth*2 - curLeftCol*chrWidth;
dstRect.left = dstRect.right - len*chrWidth*2;
dstRect.top = lin * chrHeight;
if(lAttr == LHIGHBOTTOM)
dstRect.top -= chrHeight;
if((dstRect.bottom = dstRect.top + chrHeight) >= statusRect.top)
dstRect.bottom = statusRect.top-1; /* mbbx 2.00.06: wont this look FUNKY ??? */
if(lAttr != LWIDE)
dstRect.bottom += chrHeight;
tmpRect = dstRect;
eraseColorRect((HDC) thePort, (LPRECT) &tmpRect, (BYTE) cAttr);
}
else
{
srcRect.right = (col - curLeftCol) * chrWidth;
srcRect.left = srcRect.right - (len * chrWidth);
/* mbbx 2.00.06: jtf disp2... */
srcRect.top = !bStatusLine ? (lin * chrHeight) : statusRect.top + (STATUSRECTBORDER / 2);
srcRect.bottom = srcRect.top + chrHeight;
}
if(cAttr & AGRAPHICS)
{
lmovmem(txtPtr, (LPSTR) grSave, len); /* mbbx 2.00.06: save actual buffer data */
for(ndx = 0; ndx < len; ndx += 1)
{
if((txtPtr[ndx] >= 0x40) && (txtPtr[ndx] <= 0x7F))
{
grChar[ndx] = vidGraphChars[txtPtr[ndx] - 0x40].display;
txtPtr[ndx] = vidGraphChars[txtPtr[ndx] - 0x40].buffer;
}
else
grChar[ndx] = 0;
}
}
ndx = 0;
if(!(vidAttr[cAttr & AMASK].flags & VID_UNDERLINE) && !bStatusLine) /* mbbx 2.00.06: jtf disp2... */
{
while((txtPtr[ndx] == ' ') && (ndx < len))
ndx += 1;
}
if(ndx > 0)
{
CopyRect((LPRECT) &tmpRect, (LPRECT) &srcRect);
tmpRect.right = tmpRect.left + (ndx * chrWidth);
if(tmpRect.bottom >= statusRect.top) /* mbbx 2.00.06: jtf disp2 - dont overwrite statusRect... */
tmpRect.bottom = statusRect.top-1;
eraseColorRect((HDC) thePort, (LPRECT) &tmpRect, (BYTE) cAttr);
}
if((len - ndx) > 0)
{
setAttrib(cAttr);
ExtTextOut(thePort, srcRect.left + (ndx * chrWidth), srcRect.top, ETO_CLIPPED, (LPRECT) &srcRect,
(LPSTR) &txtPtr[ndx], len-ndx, (LPINT) vidCharWidths);
}
if(cAttr & AGRAPHICS)
{
newPen = CreatePen(0, 1, RGB(vidAttr[cAttr & AMASK].text[VID_RED],
vidAttr[cAttr & AMASK].text[VID_GREEN],
vidAttr[cAttr & AMASK].text[VID_BLUE]));
oldPen = SelectObject(thePort, (HPEN) newPen);
grLeft = srcRect.left;
grWidth2 = chrWidth / 2;
grHeight2 = chrHeight / 2;
for(ndx = 0; ndx < len; ndx += 1)
{
if(grChar[ndx] & VID_DRAW_LEFT)
{
MMoveTo(thePort, grLeft, srcRect.top + grHeight2);
LineTo(thePort, grLeft + grWidth2, srcRect.top + grHeight2);
}
if(grChar[ndx] & VID_DRAW_RIGHT)
{
MMoveTo(thePort, grLeft + grWidth2, srcRect.top + grHeight2);
LineTo(thePort, grLeft + chrWidth, srcRect.top + grHeight2);
}
if(grChar[ndx] & VID_DRAW_TOP)
{
MMoveTo(thePort, grLeft + grWidth2, srcRect.top);
LineTo(thePort, grLeft + grWidth2, srcRect.top + grHeight2);
}
if(grChar[ndx] & VID_DRAW_BOTTOM)
{
MMoveTo(thePort, grLeft + grWidth2, srcRect.top + grHeight2);
LineTo(thePort, grLeft + grWidth2, srcRect.top + chrHeight);
}
if(grChar[ndx] & VID_DRAW_SCAN1)
{
MMoveTo(thePort, grLeft, srcRect.top);
LineTo(thePort, grLeft + chrWidth, srcRect.top);
}
if(grChar[ndx] & VID_DRAW_SCAN3)
{
MMoveTo(thePort, grLeft, srcRect.top + (chrHeight / 4));
LineTo(thePort, grLeft + chrWidth, srcRect.top + (chrHeight/4));
}
if(grChar[ndx] & VID_DRAW_SCAN7)
{
MMoveTo(thePort, grLeft, srcRect.top + (3 * (chrHeight / 4)));
LineTo(thePort, grLeft + chrWidth, srcRect.top + (3 * (chrHeight/4)));
}
if(grChar[ndx] & VID_DRAW_SCAN9)
{
MMoveTo(thePort, grLeft, srcRect.top + (chrHeight-1));
LineTo(thePort, grLeft + chrWidth, srcRect.top + (chrHeight-1));
}
grLeft += chrWidth;
}
SelectObject(thePort, (HPEN) oldPen);
DeleteObject((HPEN) newPen);
lmovmem((LPSTR) grSave, txtPtr, len); /* mbbx 2.00.06: restore actual buffer data */
}
if(vidAttr[cAttr & AMASK].flags & VID_REVERSE)
InvertRect(thePort, (LPRECT) &srcRect);
if(lAttr != LNORMAL)
{
/* mbbx 2.00: font selection... */
StretchBlt(savePort, dstRect.left, dstRect.top,
dstRect.right - dstRect.left, dstRect.bottom - dstRect.top,
thePort, srcRect.left, srcRect.top,
srcRect.right - srcRect.left, chrHeight, SRCCOPY);
DeleteDC(thePort);
if (bhBitMapValid) //sdj: check if valid, only then call delete
DeleteObject(hBitMap);
thePort = savePort;
}
if(vidAttr[cAttr & AMASK].flags & (VID_BOLD | VID_ITALIC | VID_UNDERLINE | VID_STRIKEOUT))
SelectObject(thePort, hTE.hFont);
}
/*--------------------------------------------------------------------------*/
/* setAttrib() - [jtf] */
/*--------------------------------------------------------------------------*/
VOID setAttrib(BYTE cAttr)
{
INT ndx;
LOGFONT logFont;
HFONT hFont;
cAttr &= AMASK;
SetTextColor(thePort, RGB(vidAttr[cAttr].text[VID_RED],
vidAttr[cAttr].text[VID_GREEN], vidAttr[cAttr].text[VID_BLUE]));
SetBkColor(thePort, RGB(vidAttr[cAttr].bkgd[VID_RED],
vidAttr[cAttr].bkgd[VID_GREEN], vidAttr[cAttr].bkgd[VID_BLUE]));
if(vidAttr[cAttr].flags & (VID_BOLD | VID_ITALIC | VID_UNDERLINE | VID_STRIKEOUT))
{
for(ndx = 0; ndx < VID_MAXFONTCACHE; ndx += 1)
{
if(vidFontCache[ndx].hFont == NULL)
break;
if(vidFontCache[ndx].flags == (vidAttr[cAttr].flags & VID_MASK))
{
SelectObject(thePort, vidFontCache[ndx].hFont);
return;
}
}
GetObject(hTE.hFont, sizeof(LOGFONT), (LPSTR) &logFont);
if(vidAttr[cAttr].flags & VID_BOLD)
logFont.lfWeight = 700;
logFont.lfUnderline = (vidAttr[cAttr].flags & VID_UNDERLINE) ? TRUE : FALSE;
logFont.lfStrikeOut = (vidAttr[cAttr].flags & VID_STRIKEOUT) ? TRUE : FALSE;
logFont.lfItalic = (vidAttr[cAttr].flags & VID_ITALIC) ? TRUE : FALSE;
hFont = CreateFontIndirect((LPLOGFONT) &logFont);
if(ndx == VID_MAXFONTCACHE)
{
DeleteObject(vidFontCache[0].hFont);
for(ndx = 0; ndx < VID_MAXFONTCACHE-1; ndx += 1)
{
vidFontCache[ndx].hFont = vidFontCache[ndx+1].hFont;
vidFontCache[ndx].flags = vidFontCache[ndx+1].flags;
}
}
vidFontCache[ndx].hFont = hFont;
vidFontCache[ndx].flags = (vidAttr[cAttr].flags & VID_MASK);
SelectObject(thePort, hFont);
}
}