예제 #1
0
파일: block.c 프로젝트: smorimura/ne
static	void	bstack_paste()
{
	char	buf[MAXEDITLINE+1], buf_a[MAXEDITLINE+1];
	const	char	*q;
	EditLine	*ed,*edn;

	if (bstack_nums==0)
		return;

	q=bstack[bstack_nums-1].s;
	csr_leupdate();

	if (bstack[bstack_nums-1].blkm==BLKM_y)
		{
		 edn=ed=GetList(GetLineOffset()-1);
		 for(;;)
		 	{
		 	 q=str_paste(buf, q);
		 	 if (q==NULL)
		 	 	break;
		 	 InsertLine(ed, MakeLine(buf));
		 	 ed=ed->next;
		 	}
		 csrse.ed = edn -> next;
		} else
		{
		 ed=GetList(GetLineOffset());
		 strcpy(buf, ed->buffer);
		 buf[GetBufferOffset()]='\0';
		 strcpy(buf_a, ed->buffer+GetBufferOffset());

		 q=str_paste(buf+GetBufferOffset(), q);
		 if (q==NULL)
		 	{
		 	 strcat(buf, buf_a);
		 	 Realloc(ed, buf);
		 	} else
		 	{
		 	 Realloc(ed, buf);

			 for(;;)
			 	{
		 	 	 q=str_paste(buf, q);
		 	 	 if (q==NULL)
		 	 	 	break;
		 	 	 InsertLine(ed, MakeLine(buf));
		 	 	 ed=ed->next;
		 	 	}
		 	 strcat(buf, buf_a);
		 	 InsertLine(ed, MakeLine(buf));
		 	}
		}

	SetFileChangeFlag();

	csr_lenew();
	OffsetSetByColumn();
}
예제 #2
0
파일: block.c 프로젝트: smorimura/ne
SHELL	void	op_block_start()
{
	csr_leupdate();

	if (blck.blkm!=BLKM_none)
		BlockInit(); else
		{
		 blck.blkm= BLKM_x;
		 blck.y_st= GetLineOffset();
		 blck.y_ed= GetLineOffset();
		 blck.x_st= csrle.lx;
		 blck.x_ed= csrle.lx;
		}
}
예제 #3
0
파일: block.c 프로젝트: smorimura/ne
void	block_cmove()
{
	if (blck.blkm==BLKM_none)
		return;

	if (blck.y_ed != GetLineOffset())
		blck.blkm= BLKM_y; else
		{
		 if (blck.x_ed != GetBufferOffset())
		 	blck.blkm= BLKM_x;
		}

	blck.x_ed= GetBufferOffset();
	blck.y_ed= GetLineOffset();
}
예제 #4
0
파일: block.c 프로젝트: smorimura/ne
static	void	block_cut()
{
	EditLine	*ed,*ed_next;
	int 	x_st, x_ed;
	char	buf[MAXEDITLINE+1];

	if (bkm.blkm==BLKM_y && bkm.y_st<GetLastNumber())
		lists_delete(bkm.y_st, bkm.y_ed-1);else
		{
		 ed=GetList(bkm.y_st);
		 block_range(bkm.y_st, &bkm, &x_st, &x_ed);
		 strcpy(buf, ed->buffer);
		 buf[x_st]='\0';

		 ed_next=GetList(bkm.y_ed);
		 block_range(bkm.y_ed, &bkm, &x_st, &x_ed);
		 strcat(buf, ed_next->buffer+x_ed);

		 Realloc(ed, buf);

		 if (bkm.y_st+1<=bkm.y_ed)
		 	lists_delete(bkm.y_st+1, bkm.y_ed);
		}

	SetFileChangeFlag();
	csr_lenew();

	csr_setdy(GetRow()+bkm.y_st-GetLineOffset());
	csr_setly(bkm.y_st);

	if (bkm.blkm==BLKM_x)
		csr_setlx(bkm.x_st);
}
예제 #5
0
void WebEditBox::LineUp (void)
{
	if (miCurrentLine == 0)
	{
		return;
	}

	long iColumn = miCursorPos - GetLineOffset(miCurrentLine);
	long iIndex = iColumn + GetLineOffset(miCurrentLine - 1);

	if (iIndex >= GetLineOffset(miCurrentLine))
	{
		iIndex = GetLineOffset(miCurrentLine) - 1;
	}

	SetCursorPosition(iIndex);
}
예제 #6
0
static inline
void DrawTriangle2(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
	float y1 = v1.y;
	float y2 = v2.y;
	float y3 = v3.y;

	float x1 = v1.x;
	float x2 = v2.x;
	float x3 = v3.x;

	// Deltas
	float Dx12 = x1 - x2;
	float Dx23 = x2 - x3;
	float Dx31 = x3 - x1;

	float Dy12 = y1 - y2;
	float Dy23 = y2 - y3;
	float Dy31 = y3 - y1;

	// Bounding rectangle
	int minx = (int)min(x1, x2, x3);
	int maxx = (int)max(x1, x2, x3);
	int miny = (int)min(y1, y2, y3);
	int maxy = (int)max(y1, y2, y3);

	pixel_t* colorBuffer = GetPixelPtr(0, miny);

	// Constant part of half-edge functions
	float C1 = Dy12 * x1 - Dx12 * y1;
	float C2 = Dy23 * x2 - Dx23 * y2;
	float C3 = Dy31 * x3 - Dx31 * y3;

	float Cy1 = C1 + Dx12 * miny - Dy12 * minx;
	float Cy2 = C2 + Dx23 * miny - Dy23 * minx;
	float Cy3 = C3 + Dx31 * miny - Dy31 * minx;

	// Scan through bounding rectangle
	for (int y = miny; y < maxy; y++) {
		// Start value for horizontal scan
		float Cx1 = Cy1;
		float Cx2 = Cy2;
		float Cx3 = Cy3;
		for (int x = minx; x < maxx; x++) {
			if (Cx1 > 0 && Cx2 > 0 && Cx3 > 0) {
				colorBuffer[x] = 0x00FFFFFF;	// White
			}
			Cx1 -= Dy12;
			Cx2 -= Dy23;
			Cx3 -= Dy31;
		}
		Cy1 += Dx12;
		Cy2 += Dx23;
		Cy3 += Dx31;
		OffsetPtr(colorBuffer, GetLineOffset());
	}
	
}
예제 #7
0
void WebEditBox::LineDown (void)
{
	if (miCurrentLine == miNumLines - 1)
	{
		return;
	}

	long iColumn = miCursorPos - GetLineOffset(miCurrentLine);
	long iIndex = iColumn + GetLineOffset(miCurrentLine + 1);

	if (miCurrentLine < miNumLines - 2)
	{
		if (iIndex >= GetLineOffset(miCurrentLine + 2))
		{
			iIndex = GetLineOffset(miCurrentLine + 2) - 1;
		}
	}

	SetCursorPosition(iIndex);
}
예제 #8
0
void WebEditBox::LineEnd (void)
{
	if (miCurrentLine == (miNumLines - 1))
	{
		End();
	}
	else
	{
		SetCursorPosition(GetLineOffset(miCurrentLine+1)-1);
	}
}
예제 #9
0
파일: block.c 프로젝트: smorimura/ne
static	bool	BlockCommand()		/* ブロックコマンドの準備用 */
{
	csr_leupdate();

	block_set(&bkm);
	if (blck.blkm!=BLKM_none)
		blck.blkm= BLKM_none; else
		{
		 bkm.y_st=GetLineOffset();
		 bkm.y_ed=bkm.y_st+1;

		 if (bkm.y_st != GetLastNumber())
		 	bkm.blkm= BLKM_y; else
		 	{
		 	 bkm.blkm= BLKM_x;
		 	 --bkm.y_ed;
		 	 bkm.x_st=0;
		 	 bkm.x_ed=strlen(GetList(GetLineOffset())->buffer);
		 	}
		}

	return block_size(&bkm)>0;
}
예제 #10
0
void WebEditBox::EnsureCursorVisible (void)
{
	WebGraphics *gc = GetGraphics();
	WebFont font = mFont.GetFont();

	if (gc && font && mpText)
	{
		DISPLAY_INT cursorX = gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) - miXOffset;
		DISPLAY_INT cursorY = WEB_FONT_HEIGHT(font)*miCurrentLine - miYOffset;
		WebRect box;

		GetTextRect(&box);

		cursorX += box.left;
		cursorY += box.top;

		if (cursorY < box.top)
		{
			miYOffset -= (box.top - cursorY);
		}
		else if ((cursorY + WEB_FONT_HEIGHT(font)) > box.bottom)
		{
			miYOffset += (cursorY + WEB_FONT_HEIGHT(font)) - box.bottom;
		}

		if (cursorX > box.right)
		{
			// overshoot by a bit
			miXOffset += cursorX - box.right + 10;
		}
		else if (cursorX < box.left)
		{
			miXOffset -= (box.left - cursorX);
		}

		if (mpVScroll)
		{
			mpVScroll->SetPosition(miYOffset);
		}

		if (mpHScroll)
		{
			mpHScroll->SetPosition(miXOffset);
		}

		mEditFlags &= ~EDIT_FLAG_ENSURE_CURSOR_VISIBLE;
	}
}
예제 #11
0
WEBC_BOOL WebEditBox::GetFocusRect (WebRect* rect)
{
	WebGraphics *gc = GetGraphics();
	WebFont font = mFont.GetFont();

	if (gc && font && mpText && (mEditFlags & EDIT_FLAG_ENSURE_CURSOR_VISIBLE))
	{
		EnsureCursorVisible();

		DISPLAY_INT cursorX = gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) - miXOffset;
		DISPLAY_INT cursorY = WEB_FONT_HEIGHT(font)*miCurrentLine - miYOffset;

		GetTextRect(rect);
		rect->Shift(cursorX, cursorY);
		rect->SizeTo(5, WEB_FONT_HEIGHT(font));

		return WEBC_TRUE;
	}

	return WEBC_FALSE;
}
예제 #12
0
파일: block.c 프로젝트: smorimura/ne
SHELL	void	op_block_chlast()
{
	long	a;
	int 	b;
	blkm_t	blkm;

	if (blck.blkm!=BLKM_none)
		{
		 a=blck.y_st;
		 blck.y_st=GetLineOffset();

		 b=blck.x_st;
		 blck.x_st=GetBufferOffset();

		 blkm=blck.blkm;

		 csr_setly(a);
		 csr_setlx(b);

		 blck.blkm=blkm;
		}
}
예제 #13
0
void DrawTriangle3(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
	// 28.4 fixed-point coordinates
	const int Y1 = iround(16.0f * v1.y);
	const int Y2 = iround(16.0f * v2.y);
	const int Y3 = iround(16.0f * v3.y);

	const int X1 = iround(16.0f * v1.x);
	const int X2 = iround(16.0f * v2.x);
	const int X3 = iround(16.0f * v3.x);

	// Deltas
	const int DX12 = X1 - X2;
	const int DX23 = X2 - X3;
	const int DX31 = X3 - X1;

	const int DY12 = Y1 - Y2;
	const int DY23 = Y2 - Y3;
	const int DY31 = Y3 - Y1;

	// Fixed-point deltas
	const int FDX12 = DX12 << 4;
	const int FDX23 = DX23 << 4;
	const int FDX31 = DX31 << 4;

	const int FDY12 = DY12 << 4;
	const int FDY23 = DY23 << 4;
	const int FDY31 = DY31 << 4;

	// Bounding rectangle
	int minx = (min(X1, X2, X3) + 0xF) >> 4;
	int maxx = (max(X1, X2, X3) + 0xF) >> 4;
	int miny = (min(Y1, Y2, Y3) + 0xF) >> 4;
	int maxy = (max(Y1, Y2, Y3) + 0xF) >> 4;

	pixel_t* colorBuffer = GetPixelPtr(0, miny);

	// Half-edge constants
	int C1 = DY12 * X1 - DX12 * Y1;
	int C2 = DY23 * X2 - DX23 * Y2;
	int C3 = DY31 * X3 - DX31 * Y3;

	// Correct for fill convention
	if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++;
	if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
	if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;

	int CY1 = C1 + DX12 * (miny << 4) - DY12 * (minx << 4);
	int CY2 = C2 + DX23 * (miny << 4) - DY23 * (minx << 4);
	int CY3 = C3 + DX31 * (miny << 4) - DY31 * (minx << 4);

	for (int y = miny; y < maxy; y++) {
		int CX1 = CY1;
		int CX2 = CY2;
		int CX3 = CY3;
		for (int x = minx; x < maxx; x++) {
			if (CX1 > 0 && CX2 > 0 && CX3 > 0) {
				colorBuffer[x] = 0x00FFFFFF;
			}
			CX1 -= FDY12;
			CX2 -= FDY23;
			CX3 -= FDY31;
		}
		CY1 += FDX12;
		CY2 += FDX23;
		CY3 += FDX31;
		OffsetPtr(colorBuffer, GetLineOffset());
	}
	
}
예제 #14
0
void WebEditBox::LineHome (void)
{
	SetCursorPosition(GetLineOffset(miCurrentLine));
}
예제 #15
0
void DrawTriangle5(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
	// 28.4 fixed-point coordinates
	const int Y1 = iround(16.0f * v1.y);
	const int Y2 = iround(16.0f * v2.y);
	const int Y3 = iround(16.0f * v3.y);

	const int X1 = iround(16.0f * v1.x);
	const int X2 = iround(16.0f * v2.x);
	const int X3 = iround(16.0f * v3.x);
	// Deltas
/*
  This was really easy. I fit 6 words into XMMs and could do all the
  subtraction and shifting.
*/
	const int DX12 = X1 - X2;
	const int DX23 = X2 - X3;
	const int DX31 = X3 - X1;

	const int DY12 = Y1 - Y2;
	const int DY23 = Y2 - Y3;
	const int DY31 = Y3 - Y1;

	// Fixed-point deltas
	const int FDX12 = DX12 << 4;
	const int FDX23 = DX23 << 4;
	const int FDX31 = DX31 << 4;
	const int FDY12 = DY12 << 4;
	const int FDY23 = DY23 << 4;
	const int FDY31 = DY31 << 4;

	// Bounding rectangle
/*
  These four went in 2 clock cycles :)
*/
	int minx = (min(X1, X2, X3) + 0xF) >> 4;
	int maxx = (max(X1, X2, X3) + 0xF) >> 4;
	int miny = (min(Y1, Y2, Y3) + 0xF) >> 4;
	int maxy = (max(Y1, Y2, Y3) + 0xF) >> 4;

	// Block size, standard 8x8 (must be power of two)
	const int q = 8;
/*
  I found out this to be very interesting dynamically. There were situations
  where 4 or 16 was better. Imagine triangles from 4x4px bounding in size
  upto 500x500 in size...
*/
	// Start in corner of 8x8 block
	minx &= ~(q - 1); // This and later is all in 64-bit x86 ASM without SSE
	miny &= ~(q - 1);

	pixel_t* colorBuffer = GetPixelPtr(0, miny);
	// Half-edge constants
	int C1 = DY12 * X1 - DX12 * Y1; // SSE only has instructions for WORDs
	int C2 = DY23 * X2 - DX23 * Y2; // but this needs at least DWORDs and
	int C3 = DY31 * X3 - DX31 * Y3; // doing 6 multiplys with IMUL is faster
	// than converting it to SSE and doing 2*3 MULUDQs with additional sign-
	// checking because UDQ is UNsigned :(

	// Correct for fill convention
	if(DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++;
	if(DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
	if(DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
	// Loop through blocks
	for(int y = miny; y < maxy; y += q)
	{
		for(int x = minx; x < maxx; x += q)
		{
			// Corners of block
			int x0 = x << 4;
			int x1 = (x + q - 1) << 4;
			int y0 = y << 4;
			int y1 = (y + q - 1) << 4;

			// Evaluate half-space functions
/*
  This one here is very painful and even in case of a right triangle sitting in
  one half of the bounding box it takes 24 IMULs for every 8x8 pixel region
  empty or not. One or two optimizations are possible, though. You cast these
  bools to ints here, but actually you could just add these results without
  shifting (a00+a10+a01+a11) because you only check whether its all 0 or
  all 1. Then it becomes 0 or 4. Only loss is that you don't know which ones
  where 1 and which ones 0 (may be necessary with masking). The definite
  one optimization is that you don't have to wait until c to check for 0, but
  you can to it after every four bools. Bail out of the loop quickly after a==0
  so you will cut off these painful 16 IMULs, 16 ADDs/SUBs, 8 CMPs, 4 SHLs
  and 4 ORs. That on average will improve throughput by 10-35% depending
  on the triangles.
*/
			bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
			bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
			bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
			bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
			int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
	
			bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
			bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
			bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
			bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
			int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
	
			bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
			bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
			bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
			bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
			int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);

			// Skip block when outside an edge
/*
  This one can be cleverly done with
  #define has_nullbyte_(x) ((x - 0x01010101) & ~x & 0x80808080)
  hint: search for "null" at
  http://www.azillionmonkeys.com/qed/asmexample.html
  but I didn't need it at all because of the optimizations above
*/
			if(a == 0x0 || b == 0x0 || c == 0x0) continue;
			pixel_t* buffer = colorBuffer;

			// Accept whole block when totally covered
/*
  By fusing a,b,c together earlier I could make here only one test which is
  if(c==0xFFF) - that is when c=a<<8|b<<4|c
*/
			if(a == 0xF && b == 0xF && c == 0xF)
			{
				for(int iy = 0; iy < q; iy++)
				{
					for(int ix = x; ix < x + q; ix++)
					{
						buffer[ix] = 0x00007F00; // Green
/*
  This part here gave a really good boost. I switched to SSE for a second
  here and shuffled the color to all parts of the 128-bit register. It could
  write 16 bytes per clock and with some macro magic, I made it calculate
  from the q how much of these it needed. The inner loop is too tight to use
  it at all so I left it out :)
*/
					}
					OffsetPtr(buffer, GetLineOffset());
				}
			}
			else // Partially covered block
			{
				int CY1 = C1 + DX12 * y0 - DY12 * x0;
				int CY2 = C2 + DX23 * y0 - DY23 * x0;
				int CY3 = C3 + DX31 * y0 - DY31 * x0;

				for(int iy = y; iy < y + q; iy++)
				{
					int CX1 = CY1;
					int CX2 = CY2;
					int CX3 = CY3;

					for(int ix = x; ix < x + q; ix++)
					{
						if(CX1 > 0 && CX2 > 0 && CX3 > 0)
						{
							buffer[ix] = 0x0000007F; // Blue
						}

						CX1 -= FDY12;
						CX2 -= FDY23;
						CX3 -= FDY31;
					}

					CY1 += FDX12;
					CY2 += FDX23;
					CY3 += FDX31;
					OffsetPtr(buffer, GetLineOffset());
				}
			}
		}
		OffsetPtr(colorBuffer, q * GetLineOffset());
	}

}
예제 #16
0
    bool Do(const KEY_EVENT_RECORD& ker, Screen& screen, const EditScheme& scheme)
    {
        bool cont = true;
        if (ker.bKeyDown)
        {
            const bool readOnly = fileInfo.isreadonly();

            switch (ker.wVirtualKeyCode)
            {
            case VK_F1:
                {
                    wchar_t* pWData = nullptr;
                    {
                        HMODULE hModule = NULL;
                        Memory mem = GetResource(hModule, IDR_TEXT);
                        const char* pData = static_cast<const char*>(mem.data);

                        pWData = new wchar_t[mem.size + 1];
                        for (DWORD i = 0; i < mem.size; ++i)
                        {
                            switch (pData[i])
                            {
                            case '\r':
                                pWData[i] = L' ';
                                break;
                            case '\n':
                                pWData[i] = L'\0';
                                break;
                            default:
                                pWData[i] = pData[i];
                                break;
                            }
                        }
                        pWData[mem.size] = L'\0';
                    }

                    ModeInfoBox mmb(this, _COORD(4, 4), pWData);
                    DoMode(mmb, screen, scheme);

                    delete[] pWData;
                    me.invalid = true;
                }
                break;

            case VK_F3:
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    if (me.Selection().empty())
                    {
                        size_t p = MoveWordBegin(me.Chars(), me.Selection().end);

                        if (iswblank(me.Chars()[p])) // TODO Use locale?
                            break;  // Don't search

                        me.MoveCursor(p, false);
                        me.MoveCursor(MoveWordEnd(me.Chars(), me.Selection().end), true);
                    }

                    if (!me.Selection().empty())
                    {
                        mf.setFind(me.GetSelectedText());
                        mf.visible = true;
                        me.invalid = true;
                    }
                    Find(true, true);
                    break;

                case 0:
                    Find(true, true);
                    break;

                case SHIFT_PRESSED:
                    Find(false, true);
                    break;
                }
                break;

            case 'F':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    // TODO Set focus to find window to edit search text
                    mf.visible = true;
                    DoMode(mf, screen, scheme);
                    me.invalid = true;
                    break;
                }
                break;

            case 'G':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    {
                        ModePromptInteger mpi(this, ms.buffer, ms.pos, L"Goto line?");
                        DoMode(mpi, screen, scheme);
                        int line = mpi.Ret();
                        if (line > 0)
                        {
                            me.MoveCursor(GetLineOffset(me.Chars(), line), false);
                        }
                        me.invalid = true;
                    }
                    break;
                }
                break;

            case 'I':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    mf.ToggleCaseSensitive();
                    Find(true, false);
                    break;
                }
                break;

            case 'R':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    me.Revert(fileInfo, l);
                    break;
                }
                break;

            case 'S':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_CTRL_PRESSED:
                case LEFT_CTRL_PRESSED:
                    if (!readOnly)
                    {
                        try
                        {
                            me.Save(fileInfo, l);
                            ms.message = L"Saved";
                        }
                        catch (const std::exception& e)
                        {
                            ms.error = convert(e.what(), l);
                            me.invalid = true;
                        }
                    }
                    else
                        Beep();
                    break;
                }
                break;

            case 'X':
                switch (ker.dwControlKeyState & 0x1F)
                {
                case RIGHT_ALT_PRESSED:
                case LEFT_ALT_PRESSED:
                    {
                        if (me.isEdited())
                        {
                            ModePromptYesNo mpyn(this, ms.buffer, ms.pos, L"Save?");
                            DoMode(mpyn, screen, scheme);
                            WORD key = mpyn.Ret();
                            me.invalid = true;
                            if (key == L'Y')
                                me.Save(fileInfo, l);
                            if (key != 0)
                                cont = false;
                        }
                        else
                            cont = false;

                    }
                    break;
                }
                break;
            }
        }

        if (cont)
            cont = me.Do(ker, screen, scheme);

        return cont;
    }
예제 #17
0
void DrawTriangle4(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
	// 28.4 fixed-point coordinates
	const int Y1 = iround(16.0f * v1.y);
	const int Y2 = iround(16.0f * v2.y);
	const int Y3 = iround(16.0f * v3.y);
	const int X1 = iround(16.0f * v1.x);
	const int X2 = iround(16.0f * v2.x);
	const int X3 = iround(16.0f * v3.x);
	// Deltas
	const int DX12 = X1 - X2;
	const int DX23 = X2 - X3;
	const int DX31 = X3 - X1;
	const int DY12 = Y1 - Y2;
	const int DY23 = Y2 - Y3;
	const int DY31 = Y3 - Y1;
	// Fixed-point deltas
	const int FDX12 = DX12 << 4;
	const int FDX23 = DX23 << 4;
	const int FDX31 = DX31 << 4;
	const int FDY12 = DY12 << 4;
	const int FDY23 = DY23 << 4;
	const int FDY31 = DY31 << 4;
	// Bounding rectangle
	int minx = (min(X1, X2, X3) + 0xF) >> 4;
	int maxx = (max(X1, X2, X3) + 0xF) >> 4;
	int miny = (min(Y1, Y2, Y3) + 0xF) >> 4;
	int maxy = (max(Y1, Y2, Y3) + 0xF) >> 4;
	// Block size, standard 8x8 (must be power of two)
	const int q = 8;
	// Start in corner of 8x8 block
	minx &= ~(q - 1);
	miny &= ~(q - 1);
	pixel_t* colorBuffer = GetPixelPtr(0, miny);
	// Half-edge constants
	int C1 = DY12 * X1 - DX12 * Y1;
	int C2 = DY23 * X2 - DX23 * Y2;
	int C3 = DY31 * X3 - DX31 * Y3;
	// Correct for fill convention
	if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++;
	if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
	if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
	// Loop through blocks
	for (int y = miny; y < maxy; y += q) {
		for (int x = minx; x < maxx; x += q) {
			// Corners of block
			int x0 = x << 4;
			int x1 = (x + q - 1) << 4;
			int y0 = y << 4;
			int y1 = (y + q - 1) << 4;
			// Evaluate half-space functions
			bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
			bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
			bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
			bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
			int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
			bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
			bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
			bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
			bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
			int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
			bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
			bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
			bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
			bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
			int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);
			// Skip block when outside an edge
			if (a == 0x0 || b == 0x0 || c == 0x0) continue;
			pixel_t* buffer = colorBuffer;
			// Accept whole block when totally covered
			if (a == 0xF && b == 0xF && c == 0xF) {
				for (int iy = 0; iy < q; iy++) {
					for (int ix = x; ix < x + q; ix++) {
						buffer[ix] = 0x00007F00; // Green
					}
					OffsetPtr(buffer, GetLineOffset());
				}
			}else {// Partially covered block
				int CY1 = C1 + DX12 * y0 - DY12 * x0;
				int CY2 = C2 + DX23 * y0 - DY23 * x0;
				int CY3 = C3 + DX31 * y0 - DY31 * x0;
				for (int iy = y; iy < y + q; iy++) {
					int CX1 = CY1;
					int CX2 = CY2;
					int CX3 = CY3;
					for (int ix = x; ix < x + q; ix++) {
						if (CX1 > 0 && CX2 > 0 && CX3 > 0) {
							buffer[ix] = 0x0000007F; // Blue
						}
						CX1 -= FDY12;
						CX2 -= FDY23;
						CX3 -= FDY31;
					}
					CY1 += FDX12;
					CY2 += FDX23;
					CY3 += FDX31;
					OffsetPtr(buffer, GetLineOffset());
				}
			}
		}
		OffsetPtr(colorBuffer, q*GetLineOffset());
	}
}
예제 #18
0
void WebEditBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	WebChar c;
	long line;

	WebRect box;
	GetFrameRect(&box);
	box.Shift(x,y);

//	gc->StartBuffer();                      // begin buffering graphics commands
	gc->Rectangle(&box, GetBgColor(gc), GetBgColor(gc), 1);	// draw background
	DrawFrame(&box, gc);

	// save the current graphics context clip rectangle and set clipping to the
	//  text display region of the widget
	GetTextRect(&box);
	box.Shift(x,y);
	WebRect clipSave;
	gc->GetClip(&clipSave);
	if (clipSave.Overlaps(&box))
	{
		WebRect clip(box);
		clip.And(&clipSave);
		gc->SetClip(&clip);

		miXOffset = (mpHScroll)? mpHScroll->GetPosition() : 0;
		miYOffset = (mpVScroll)? mpVScroll->GetPosition() : 0;

		// render our text
		WebFont font = mFont.GetFont();
		if (mpText && font)
		{
			// this loop draws up to the last line
			for (line=0; line<(miNumLines-1); line++)
			{
				c = mpText[GetLineOffset(line+1)];
				mpText[GetLineOffset(line+1)] = 0;
				DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line * WEB_FONT_HEIGHT(font)),
				         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);
				mpText[GetLineOffset(line+1)] = c;
			}

			// now draw the last line of text.
			DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
			         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);

			// if we have the focus, draw the cursor
			if ((mFlags & DISPLAY_FLAG_FOCUS) && !(mFlags & DISPLAY_FLAG_DISABLED))
			{
				// now render the selected portion in reverse video (if we have one)
				if (mEditFlags & EDIT_FLAG_HAS_SELECTION)
				{
					long begin = EBSMIN(miCursorPos, miSelectBegin);
					long end = EBSMAX(miCursorPos, miSelectBegin);
					long beginLine = FindLine(begin), endLine = FindLine(end);
					DISPLAY_INT textLeft;
					long currentBegin, currentEnd;

					for (line=beginLine; line<=endLine; line++)
					{
						currentBegin = EBSMAX(begin, GetLineOffset(line));
						if (line == endLine)
						{
							currentEnd = end;
						}
						else
						{
							currentEnd = EBSMIN(end, GetLineOffset(line+1));
						}
						textLeft = gc->TextWidthLen(mpText + GetLineOffset(line), font, EBSMAX(0, begin - GetLineOffset(line)));

						c = mpText[currentEnd];
						mpText[currentEnd] = 0;
						DrawText(gc, box.left - miXOffset + textLeft,
						             box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
						             mpText + currentBegin, GetBgColor(gc), GetSelectColor(gc), 1, font);
						mpText[currentEnd] = c;
					}
				}

				DISPLAY_INT cursorX = box.left - miXOffset +
					gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) ;
				box.Set(cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*miCurrentLine,
				        cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*(miCurrentLine+1));
				gc->Rectangle(&box, GetSelectColor(gc), GetSelectColor(gc), 1);
			}

		}

		gc->SetClip(&clipSave);	 // restore the clip rectangle
	} // if clip overlaps

/*	if (mpVScroll && mpHScroll)
	{
		GetCornerRect(&box);
		box.Shift(x,y);
		gc->Rectangle(&box, LIGHTGRAY, LIGHTGRAY, 1);
	}*/

//	gc->EndBuffer();	     // send all buffered commands to the display

}