Example #1
0
	bool console::ReadOutput(matrix<FAR_CHAR_INFO>& Buffer, COORD BufferCoord, const SMALL_RECT& ReadRegionRelative) const
	{
		if (ExternalConsole.Imports.pReadOutput)
		{
			const COORD SizeCoord = { static_cast<SHORT>(Buffer.width()), static_cast<SHORT>(Buffer.height()) };
			auto ReadRegion = ReadRegionRelative;
			return ExternalConsole.Imports.pReadOutput(Buffer.data(), SizeCoord, BufferCoord, &ReadRegion) != FALSE;
		}

		const int Delta = sWindowMode? GetDelta() : 0;
		auto ReadRegion = ReadRegionRelative;
		ReadRegion.Top += Delta;
		ReadRegion.Bottom += Delta;

		const rectangle SubRect{ BufferCoord.X, BufferCoord.Y, BufferCoord.X + (ReadRegion.Right - ReadRegion.Left + 1) - 1, BufferCoord.Y + (ReadRegion.Bottom - ReadRegion.Top + 1) - 1 };

		std::vector<CHAR_INFO> ConsoleBuffer(SubRect.width() * SubRect.height());

		const COORD BufferSize{ static_cast<SHORT>(SubRect.width()), static_cast<SHORT>(SubRect.height()) };

		if (BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO) > MAXSIZE)
		{
			const auto HeightStep = std::max(MAXSIZE / (BufferSize.X * sizeof(CHAR_INFO)), size_t(1));

			const size_t Height = ReadRegion.Bottom - ReadRegion.Top + 1;

			for (size_t i = 0; i < Height; i += HeightStep)
			{
				auto PartialReadRegion = ReadRegion;
				PartialReadRegion.Top += static_cast<SHORT>(i);
				PartialReadRegion.Bottom = std::min(ReadRegion.Bottom, static_cast<SHORT>(PartialReadRegion.Top + HeightStep - 1));
				const COORD PartialBufferSize{ BufferSize.X, static_cast<SHORT>(PartialReadRegion.Bottom - PartialReadRegion.Top + 1) };
				if (!ReadOutputImpl(ConsoleBuffer.data() + i * PartialBufferSize.X, PartialBufferSize, PartialReadRegion))
					return false;
			}
		}
		else
		{
			auto ReadRegionCopy = ReadRegion;
			if (!ReadOutputImpl(ConsoleBuffer.data(), BufferSize, ReadRegionCopy))
				return false;
		}

		auto ConsoleBufferIterator = ConsoleBuffer.cbegin();
		for_submatrix(Buffer, SubRect, [&](FAR_CHAR_INFO& i)
		{
			const auto& Cell = *ConsoleBufferIterator++;
			i = { Cell.Char.UnicodeChar, colors::ConsoleColorToFarColor(Cell.Attributes) };
		});

		return true;
	}
virtual bool ReadOutput(matrix<FAR_CHAR_INFO>& Buffer, COORD BufferCoord, SMALL_RECT& ReadRegion) const override
{
	bool Result=false;
	int Delta=Global->Opt->WindowMode?GetDelta():0;
	ReadRegion.Top+=Delta;
	ReadRegion.Bottom+=Delta;

	COORD BufferSize = { static_cast<SHORT>(Buffer.width()), static_cast<SHORT>(Buffer.height()) };

	// skip unused region
	const size_t Offset = BufferCoord.Y * BufferSize.X;
	matrix<CHAR_INFO> ConsoleBuffer(BufferSize.Y - BufferCoord.Y, BufferSize.X);
	
	BufferSize.Y-=BufferCoord.Y;
	BufferCoord.Y=0;

	if(BufferSize.X*BufferSize.Y*sizeof(CHAR_INFO)>MAXSIZE)
	{
		auto SavedY = BufferSize.Y;
		BufferSize.Y = std::max(static_cast<int>(MAXSIZE/(BufferSize.X*sizeof(CHAR_INFO))),1);
		size_t Height = ReadRegion.Bottom - ReadRegion.Top + 1;
		int Start=ReadRegion.Top;
		SMALL_RECT SavedReadRegion=ReadRegion;
		for(size_t i = 0; i < Height; i += BufferSize.Y)
		{
			ReadRegion=SavedReadRegion;
			ReadRegion.Top = static_cast<SHORT>(Start+i);
			Result = ReadConsoleOutput(GetOutputHandle(), ConsoleBuffer[i].data(), BufferSize, BufferCoord, &ReadRegion) != FALSE;
		}
		BufferSize.Y = SavedY;
	}
	else
	{
		Result=ReadConsoleOutput(GetOutputHandle(), ConsoleBuffer.data(), BufferSize, BufferCoord, &ReadRegion)!=FALSE;
	}

	auto& ConsoleBufferVector = ConsoleBuffer.vector();
	std::transform(ConsoleBufferVector.cbegin(), ConsoleBufferVector.cend(), Buffer.data() + Offset, [](CONST_REFERENCE(ConsoleBufferVector) i)
	{
		return FAR_CHAR_INFO::make(i.Char.UnicodeChar, colors::ConsoleColorToFarColor(i.Attributes));
	});