⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.cpp

📁 zhcon最新版本0.2.4
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// vi:ts=4:shiftwidth=4:expandtab/***************************************************************************                          window.cpp  -  description                             -------------------    begin                : Sun Mar 18 2001    copyright            : (C) 2001 by huyong    email                : ccpaging@online.sh.cn ***************************************************************************//*************************************************************************** *                                                                         * *   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 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include <cassert>#include <algorithm>#include <sys/time.h>#include <algorithm>#include "global.h"#include "debug.h"#include "window.h"//static members for all the windowsWindow* Window::mpConsole = NULL;char* Window::mpOverlaps = NULL;Window::Window(int x1, int y1, int x2, int y2, int type): mCol(0), mRow(0),mCursorEnabled(false), mCursorVisible(false), mCursorIntevel(350000),mFgColor(7), mBgColor(0) {    mX1 = x1;    mX2 = x2;    mY1 = y1;    mY2 = y2;    mType = type;    mpText = NULL;    mpAttr = NULL;    mpFlag = NULL;    SetBuf();    if (!(type & WS_CHILD)) { // can only be called once!        if (mpConsole != NULL) {            throw "Window() can not called more than once!";        }        int size = mMaxCols * mMaxRows;        mpConsole = this;        mpOverlaps = new char[size];        memset(mpOverlaps, 0, size);    }    SetCursorType(CUR_DEF);    mVisible = false;}void Window::SetBuf() {    int FramePixs = 0;    if (mType & WS_FRAMETHIN) {        FramePixs = 2;    } else if (mType & WS_FRAMETHICK) {        FramePixs = 3;    } else;    mTextX0 = mTextY0 = 0;    if (FramePixs > 0) {        mTextX0 = FramePixs + ((Width() - 2 * FramePixs) % gpScreen->BlockWidth()) / 2;        mTextY0 = FramePixs + ((Height() - 2 * FramePixs) % gpScreen->BlockHeight()) / 2;    }    mMaxCols = (Width() - 2 * FramePixs) / gpScreen->BlockWidth();    mMaxRows = (Height() - 2 * FramePixs) / gpScreen->BlockHeight();    mEndCol = mMaxCols - 1;    mEndRow = mMaxRows - 1;    int size = mMaxCols * mMaxRows;    delete[] mpText;    delete[] mpAttr;    delete[] mpFlag;    mpText = new char[size];    mpAttr = new char[size];    mpFlag = new char[size];}Window::~Window() {    if (this == mpConsole) {        delete[] mpOverlaps;        mpConsole = NULL;    }    delete[] mpText;    delete[] mpAttr;    delete[] mpFlag;}void Window::SetCursorType(int CurType) {    this->CursorRestore();    switch (CurType) {        case CUR_NONE:            mCursorStart = gpScreen->BlockHeight() - 1;            mCursorEnd = gpScreen->BlockHeight() - 1;        case CUR_UNDERLINE:            if (gpScreen->mBlankLineHeight > 0)                mCursorStart = gpScreen->BlockHeight() - gpScreen->mBlankLineHeight;            else                mCursorStart = gpScreen->BlockHeight() - gpScreen->mBlankLineHeight - 1;            mCursorEnd = gpScreen->BlockHeight() - 1;            break;        case CUR_LOWER_THIRD:            mCursorStart = gpScreen->BlockHeight()/3;            mCursorEnd = gpScreen->BlockHeight() - 1;            break;        case CUR_LOWER_HALF:            mCursorStart = gpScreen->BlockHeight()/2;            mCursorEnd = gpScreen->BlockHeight() - 1;            break;        case CUR_TWO_THIRDS:            mCursorStart = gpScreen->BlockHeight()*2/3;            mCursorEnd = gpScreen->BlockHeight() - 1;            break;        default:  // CUR_DEF, CUR_BLOCK            mCursorStart = 0;            mCursorEnd = gpScreen->BlockHeight() - 1;            break;    }}int Window::ColsOvered() {    int cols = Width() / gpScreen->BlockWidth();    if (Width() % gpScreen->BlockWidth())        cols++;    return cols;}int Window::RowsOvered() {    int rows = Height() / gpScreen->BlockHeight();    if (Height() % gpScreen->BlockHeight())        rows++;    return rows;}void Window::OutChar(int col, int row, int fg, int bg, char c) {    if (!mVisible)        return;    if (this == mpConsole && mpOverlaps[Index(col, row)] > 0)        return;    gpScreen->OutChar(mX1 + mTextX0 + col * gpScreen->BlockWidth(),                      mY1 + mTextY0 + row * gpScreen->BlockHeight(),                      fg, bg, c);}void Window::OutChar(int col, int row, int fg, int bg, char c1, char c2) {    if (!mVisible)        return;    if (this != mpConsole) {        gpScreen->OutChar(mX1 + mTextX0 + col * gpScreen->BlockWidth(),                          mY1 + mTextY0 + row * gpScreen->BlockHeight(),                          fg, bg, c1, c2);        return;    }    int idx = Index(col, row);    if (mpOverlaps[idx] == 0 && mpOverlaps[idx+1] == 0 ) {        gpScreen->OutChar(mX1 + mTextX0 + col * gpScreen->BlockWidth(),                          mY1 + mTextY0 + row * gpScreen->BlockHeight(),                          fg, bg, c1, c2);        return;    }    if (mpOverlaps[idx] > 0) {        if (mpOverlaps[idx+1] == 0) {            // left is overlapped, draw right            gpScreen->OutChar(mX1 + mTextX0 + (col+1) * gpScreen->BlockWidth(),                              mY1 + mTextY0 + row * gpScreen->BlockHeight(),                              fg, bg, c2);        }        // whole chinese is in overlaped        return;    }    // left is not overlaped    if (mpOverlaps[idx+1] > 0) {        // right is overlapped, draw left        gpScreen->OutChar(mX1 + mTextX0 + col * gpScreen->BlockWidth(),                          mY1 + mTextY0 + row * gpScreen->BlockHeight(),                          fg, bg, c1);    }    // both left & right are not overlapped}//put c into inner text buffer col and row are relative positionvoid Window::PutChar(char attr,char flag,char c){    int i = Index(mCol, mRow);    mpText[i] = c;    mpAttr[i] = attr;    mpFlag[i] = flag;}//put a dbl charvoid Window::PutChar(char attr,char flag,char c1,char c2){    int i = Index(mCol, mRow);    mpText[i] = c1;    mpAttr[i] = attr;    mpFlag[i++] = flag;    mpText[i] = c2;    mpAttr[i] = attr;    mpFlag[i] = flag;}//return index of (r,c) in mpText,mpAttr,mpFlagint Window::Index(int c, int r) {    return c + r * mMaxCols;}//do Hanzi recognize then update screen//if isUpdateAll is true then update all screenvoid Window::Redraw(bool isUpdateAll) {    CursorRestore();    //then we update console    int row, indexCol;    for (row = 0, indexCol = 0; row < mMaxRows; row++) {        RedrawRow(row, mpText + indexCol, mpAttr + indexCol,            mpFlag + indexCol, isUpdateAll);        indexCol += mMaxCols;    }    CursorSet();}//DrawRow for Consolevoid Window::RedrawRow(int row, char *pText, char *pAttr, char *pFlag, bool isUpdateAll) {    for (int col = 0; col < mMaxCols; pText++, pAttr++, pFlag++, col++) {        if (isUpdateAll == false && !(*pFlag & txtUpdated))            continue;        *pFlag &= ~txtUpdated;        if ((!(*pFlag & txtPrimary) || (*pFlag & txtASCII))) {            OutChar(col, row, FgColor(*pAttr), BgColor(*pAttr), *pText);            continue;        }        if (*pFlag & txtDblCode) {            *pFlag &= ~txtDblCode;            if (col == 0) {                if (gpDecoder->IsCode1(*pText)) {                    *pFlag |= txtDblCode1;                } else {                    *pFlag |= txtASCII;                }            }            else if (*(pFlag - 1) & txtDblCode1) {                *pFlag |= txtDblCode2;            }                          // prev char is ASCII or double code2            else {                if (gpDecoder->IsCode1(*pText)) {                    *pFlag |= txtDblCode1;                } else {                    *pFlag |= txtASCII;                }            }            // txtDblCode may convert to txtASCII, special in BIG5            if (*pFlag & txtASCII) {                OutChar(col, row, FgColor(*pAttr), BgColor(*pAttr), *pText);                continue;            }        }        if (*pFlag & txtDblCode1) {            // absolate double code 1 at last col            if (col >= mMaxCols - 1) {                OutChar(col, row, FgColor(*pAttr), BgColor(*pAttr), *pText);                continue;            }            if ( (*(pFlag + 1) & txtASCII) || !(*(pFlag + 1) & txtPrimary)                || (*(pFlag + 1) & txtDblCode1)                || !gpDecoder->IsCode2(*(pText + 1)) ) {                // absolate double code 1                OutChar(col, row, FgColor(*pAttr), BgColor(*pAttr), *pText);                continue;            }            // if next char is not set to txtDblCode            if (*(pFlag + 1) & txtDblCode) {                *(pFlag + 1) &= ~txtDblCode;                *(pFlag + 1) |= txtDblCode2;            }            // next char is or was txtDblCode2            OutChar(col, row, FgColor(*pAttr), BgColor(*pAttr), *pText, *(pText + 1));            pText++;            pAttr++;            pFlag++;            col++;            continue;        }        if ( (*pFlag & txtDblCode2) && isUpdateAll == false            && col != 0 && (*(pFlag-1) & txtDblCode1) ) {            OutChar(col - 1, row, FgColor(*pAttr), BgColor(*pAttr), *(pText-1), *pText);        }    }}void Window::RedrawChar(int col, int row) {    assert(col >= 0 && col <= mEndCol && row >= 0 && row <= mEndRow);    int idx = Index(col, row);    mpFlag[idx] &= ~txtUpdated;    if ((mpFlag[idx] & txtDblCode1) && col < mpConsole->MaxCols() - 1        && (mpFlag[idx + 1] & txtDblCode2) ) {        //full hz out        OutChar(col, row, FgColor(mpAttr[idx]), BgColor(mpAttr[idx]),                mpText[idx], mpText[idx + 1]);        return;    }    if ((mpFlag[idx] & txtDblCode2) && col > 0        && (mpFlag[idx - 1] & txtDblCode1) ) {        //full hz out        OutChar(col-1, row, FgColor(mpAttr[idx]), BgColor(mpAttr[idx]),                mpText[idx-1], mpText[idx]);        return;    }        //ascii or single double code    OutChar(col, row, FgColor(mpAttr[idx]), BgColor(mpAttr[idx]),            mpText[idx]);}//implement blink attribute on consolevoid Window::UpdateBlinkAttr(bool show) {    int size = mpConsole->MaxCols() * mpConsole->MaxRows();    char *pFlag = mpConsole->mpFlag;    char *pAttr = mpConsole->mpAttr;    char *pText = mpConsole->mpText;    int r, c;    for (int i = 0; i < size; i++) {        if (mpOverlaps[i] == 0 && pAttr[i] & 0x80)            continue;        r = i / mpConsole->MaxCols();        c = i % mpConsole->MaxCols();        if (show) {            if ((pFlag[i] & txtDblCode1) && c < mpConsole->MaxCols() - 1                && (pFlag[i + 1] & txtDblCode2) ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -