<commit_before>#include "math/Polygon.h"

#include "math/mathdef.h"

using fei::Polygon;

int fei::Polygon::getDataSize() const
{
	return _data.size();
}

const float* Polygon::getDataPtr() const
{
	if (!_data.empty()) {
		return &_data[0].x;
	}
	return nullptr;
}

float Polygon::getArea() const
{
	float area = 0.0f;
	if (!isValid()) {
		return area;
	}
	auto lastVec = getVertex(1) - getVertex(0);
	for (int i = 2; i < static_cast<int>(_data.size()); i++) {
		auto curVec = getVertex(i) - getVertex(0);
		area += lastVec.cross(curVec);
		lastVec = curVec;
	}
	area *= 0.5f;
	return area;
}

bool Polygon::isCCW() const
{
	return getArea() > 0.0f;
}

void Polygon::setVertices(int vertexNumber, float* dataPtr)
{
	_data.resize(vertexNumber);
	for (int i = 0; i < vertexNumber; i++) {
		_data[i] = fei::Vec2(dataPtr[i << 1], dataPtr[i << 1 | 1]);
	}
}

void Polygon::insertVertex(const fei::Vec2& p, int index)
{
	//TODO: assertion
	_data.insert(_data.begin() + index, p);
}

void Polygon::insertVertexOnClosestSegment(const Vec2& p)
{
	int loc = closestWhichSegment(p);
	loc = indexNormalize(loc + 1);
	insertVertex(p, loc);
}

void Polygon::deleteVertex(int index)
{
	//TODO: assertion
	_data.erase(_data.begin() + index);
}

void Polygon::moveVertices(const fei::Vec2& v)
{
	for (auto& vertex : _data) {
		vertex.add(v);
	}
}

void Polygon::reverseVertices()
{
	std::reverse(_data.begin(), _data.end());
}

void Polygon::zoom(float f)
{
	for (auto& vertex : _data) {
		vertex.zoom(f);
	}
}

const std::vector<Polygon> Polygon::cut(int index) const
{
	std::vector<Polygon> result;
	int best = getBestCutVertexIndex(index);
	if (best != -1) {
		result = cut(index, best);
	} else {
		int prev = indexNormalize(index - 1);
		bool isConcave = isConcaveVertex(index);
		auto leftVec = -getVector(prev);
		auto rightVec = getVector(index);
		auto middleVec = (leftVec.normalized() + rightVec.normalized()).normalized();
		if (isConcave) {
			middleVec *= -1.0f;
		}
		auto pl = collideRay(getVertex(index), middleVec);
		if (!pl.empty()) {
			Polygon polyCopy(*this);
			int segIndex = polyCopy.closestWhichSegment(pl[0]);
			int insertLoc = polyCopy.indexNormalize(segIndex + 1);
			polyCopy.insertVertex(pl[0], insertLoc);
			if (insertLoc <= index) {
				index = polyCopy.indexNormalize(index + 1);
			}
			result = polyCopy.cut(index, insertLoc);
		}
	}
	return result;
}

const std::vector<Polygon> Polygon::cut(int a, int b) const
{
	int curVertex;
	std::vector<Polygon> result;
	Polygon tmpPoly = *this;
	tmpPoly.clearVertex();

	curVertex = b;
	tmpPoly.pushVertex(getVertex(a));
	do {
		tmpPoly.pushVertex(getVertex(curVertex));
		curVertex = indexNormalize(curVertex + 1);
	} while(curVertex != a);
	result.push_back(tmpPoly);

	tmpPoly.clearVertex();

	curVertex = a;
	tmpPoly.pushVertex(getVertex(b));
	do {
		tmpPoly.pushVertex(getVertex(curVertex));
		curVertex = indexNormalize(curVertex + 1);
	} while(curVertex != b);
	result.push_back(tmpPoly);

	return result;
}

int Polygon::closestWhichSegment(const fei::Vec2& p) const
{
	int ans = -1;
	float minR = 1e32f;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto seg = getSegment(i);
		float curRatio = std::abs(((p - seg.a).getLength() + (p - seg.b).getLength()) / seg.getLength() - 1.0f);
		if (curRatio <= minR) {
			minR = curRatio;
			ans = i;
		}
	}
	return ans;
}

int Polygon::onWhichSegment(const fei::Vec2& p) const
{
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		if (getSegment(i).collidePoint(p)) {
			return i;
		}
	}
	return -1;
}

int Polygon::collideVertex(const fei::Vec2& p, float radius) const
{
	float rSq = radius * radius;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		if ((getVertex(i) - p).getLengthSq() <= rSq) {
			return i;
		}
	}
	return -1;
}

static bool cmpLength(const fei::Vec2& a, const fei::Vec2& b)
{
	return a.getLengthSq() < b.getLengthSq();
}

const std::vector<fei::Vec2> Polygon::rawCollideRay(const fei::Vec2& src, const fei::Vec2& drct) const
{
	std::vector<fei::Vec2> result;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto seg = getSegment(i);
		fei::Vec2 tmp;
		if (seg.collideRay(tmp, src, drct)) {
			result.push_back(tmp - src);
		}
	}
	return result;
}

const std::vector<fei::Vec2> Polygon::collideRay(const fei::Vec2& src, const fei::Vec2& drct) const
{
	std::vector<fei::Vec2> result = rawCollideRay(src, drct);
	std::vector<fei::Vec2> uniqueResult;
	std::sort(result.begin(), result.end(), cmpLength);
	for (int i = 0; i < static_cast<int>(result.size()); i++) {
		if (result[i].getLengthSq() < 0.01f) continue;
		if (i == 0 || result[i] != result[i - 1]) {
			uniqueResult.push_back(result[i] + src);
		}
	}
	return uniqueResult;
}

void Polygon::normalize()
{
	std::vector<fei::Vec2> nData;
	int sz = _data.size();
	for (int i = 0; i < sz; i++) {
		int prev = indexNormalize(i - 1);
		if ((getVector(prev).getLengthSq() >= 0.01f)
		   && (getVector(i).normalized() != getVector(prev).normalized())) {
			nData.push_back(getVertex(i));
		}
	}
	setDataVector(nData);
	if (!isCCW()) {
		reverseVertices();
	}
}

const Polygon Polygon::normalized() const
{
	Polygon poly(*this);
	poly.normalize();
	return poly;
}

bool Polygon::isConcaveVertex(int index) const
{
	//TODO: assertion
	int prevIndex = indexNormalize(index - 1);
	auto prev = getVector(prevIndex);
	auto cur = getVector(index);
	float cp = prev.cross(cur);
	return cp < 0;
}

int Polygon::getOneConcaveVertex() const
{
	int sz = static_cast<int>(_data.size());
	for (int i = 0; i < sz; i++) {
		if (isConcaveVertex(i)) {
			return i;
		}
	}
	return -1;
}

typedef struct CutStruct
{
	CutStruct(const Polygon* pp, int ii, int xx)
	: poly(pp), index(ii), x(xx)
	{
	}

	bool operator>(const CutStruct& rhs) const
	{
		int ai = x;
		int bi = rhs.x;
		int sz = poly->getDataSize();
		bool aConcave = poly->isConcaveVertex(ai);
		bool bConcave = poly->isConcaveVertex(bi);
		if (aConcave == bConcave) {
			int disIA = std::abs(index - ai);
			if (sz - disIA < disIA) {
				disIA = sz - disIA;
			}
			int disIB = std::abs(index - bi);
			if (sz - disIB < disIB) {
				disIB = sz - disIB;
			}
			return disIA > disIB;
		} else {
			return aConcave;
		}
	}

	const Polygon* poly;
	int index;
	int x;
} PolyCutPair;

int Polygon::getBestCutVertexIndex(int index) const
{
	int ans = -1;
	auto iList = getVisibleVerticesIndex(index);

	std::vector<PolyCutPair> uList;
	if (isConcaveVertex(index)) {
		auto left = getSegment(index);
		auto right = getSegment(indexNormalize(index - 1));
		right.swapAB();
		left.b = left.a - left.getVector();
		right.b = right.a - right.getVector();
		for (int vertex : iList) {
			auto p = getVertex(vertex);
			if (left.onLeftOrRight(p) == 1
				 && right.onLeftOrRight(p) == -1) {
				auto pl = collideRay(getVertex(index), p - getVertex(index));
				if (pl.size() == 0 || pl[0] == p) {
					uList.push_back(PolyCutPair(this, index, vertex));
				}
			}
		}
	} else {
		for (int vertex : iList) {
			uList.push_back(PolyCutPair(this, index, vertex));
		}
	}
	if (!uList.empty()) {
		auto maxPcp = uList[0];
		for (auto& pcp : uList) {
			if (pcp > maxPcp) {
				maxPcp = pcp;
			}
		}
		ans = maxPcp.x;
	}
	return ans;
}

std::vector<int> Polygon::getVisibleVerticesIndex(int index) const
{
	std::vector<int> result;
	int left = indexNormalize(index - 1);
	int right = indexNormalize(index + 1);
	bool isConcave = isConcaveVertex(index);
	auto leftSeg = getSegment(left);
	auto rightSeg = getSegment(index);
	leftSeg.swapAB();
	if (isConcave) {
		auto tmp = leftSeg;
		leftSeg = rightSeg;
		rightSeg = tmp;
	}
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto p = getVertex(i);
		if (i == index || i == left || i == right ||
		   (leftSeg.onLeftOrRight(p) == 1 && rightSeg.onLeftOrRight(p) == -1) == isConcave) {
			continue;
		}
		auto vertexList = collideRay(getVertex(index), p - getVertex(index));
		if (vertexList.size() == 0 || vertexList[0] == p) {
			result.push_back(i);
		}
	}
	return result;
}

bool Polygon::isConvex() const
{
	return getOneConcaveVertex() < 0;
}

const std::vector<Polygon> Polygon::convexDecomposition() const
{
	std::vector<Polygon> result;
	std::queue<Polygon> processQueue;
	processQueue.push(normalized());
	while(!processQueue.empty()) {
		auto currentPoly = processQueue.front();
		processQueue.pop();
		if (currentPoly.isValid()) {
			int concavePoint = currentPoly.getOneConcaveVertex();
			if (concavePoint == -1) {
				result.push_back(currentPoly);
			} else {
				auto twoPoly = currentPoly.cut(concavePoint);
				for (auto& poly : twoPoly) {
					poly.normalize();
					if (poly.isValid()) {
						processQueue.push(poly);
					}
				}
			}
		}
		if (result.size() > 100 || processQueue.size() > 100) {
			break;
		}
	}
	return result;
}

const std::vector<Polygon> Polygon::box2dDecomposition() const
{
	std::vector<Polygon> result;
	std::queue<Polygon> processQueue;
	auto convexList = convexDecomposition();
	for (auto& poly : convexList) {
		processQueue.push(poly);
	}
	while(!processQueue.empty()) {
		auto currentPoly = processQueue.front();
		processQueue.pop();
		if (currentPoly.isValid()) {
			if (currentPoly.getDataSize() <= 8) {
				result.push_back(currentPoly);
			} else {
				auto twoPoly = currentPoly.cut(0);
				for (auto& poly : twoPoly) {
					poly.normalize();
					if (poly.isValid() && (poly.getArea() > fei::epsf)) {
						processQueue.push(poly);
					}
				}
			}
		}
		if (result.size() > 100 || processQueue.size() > 100) {
			break;
		}
	}
	return result;
}

bool Polygon::collide(const fei::Shape* shape) const
{
	bool result = false;
	switch (shape->getType()) {
	//TODO: implement cases
	//case fei::Shape::Type::CIRCLE:
	//case fei::Shape::Type::POLYGON:
	//case fei::Shape::Type::RECT:
	//case fei::Shape::Type::SEGMENT:
	}
	return result;
}

bool Polygon::collidePoint(const fei::Vec2& p) const
{
	auto points = rawCollideRay(p, fei::Vec2(1.0f, 0.001f));
	return (points.size() & 1) == 1;
}

const Polygon Polygon::makeRegularPolygon(int edgeNum, float radius, float offset)
{
	Polygon polygon;
	for (int i = 0; i < edgeNum; i++) {
		float angle = static_cast<float>(2.0 * fei::pi / edgeNum * i + fei::D2R(offset));
		polygon.pushVertex(fei::Vec2(std::cos(angle), std::sin(angle)) * radius);
	}
	return polygon;
}

<commit_msg>namespace fix<commit_after>#include "math/Polygon.h"

#include "math/mathdef.h"

using fei::Polygon;

int fei::Polygon::getDataSize() const
{
	return _data.size();
}

const float* Polygon::getDataPtr() const
{
	if (!_data.empty()) {
		return &_data[0].x;
	}
	return nullptr;
}

float Polygon::getArea() const
{
	float area = 0.0f;
	if (!isValid()) {
		return area;
	}
	auto lastVec = getVertex(1) - getVertex(0);
	for (int i = 2; i < static_cast<int>(_data.size()); i++) {
		auto curVec = getVertex(i) - getVertex(0);
		area += lastVec.cross(curVec);
		lastVec = curVec;
	}
	area *= 0.5f;
	return area;
}

bool Polygon::isCCW() const
{
	return getArea() > 0.0f;
}

void Polygon::setVertices(int vertexNumber, float* dataPtr)
{
	_data.resize(vertexNumber);
	for (int i = 0; i < vertexNumber; i++) {
		_data[i] = fei::Vec2(dataPtr[i << 1], dataPtr[i << 1 | 1]);
	}
}

void Polygon::insertVertex(const fei::Vec2& p, int index)
{
	//TODO: assertion
	_data.insert(_data.begin() + index, p);
}

void Polygon::insertVertexOnClosestSegment(const fei::Vec2& p)
{
	int loc = closestWhichSegment(p);
	loc = indexNormalize(loc + 1);
	insertVertex(p, loc);
}

void Polygon::deleteVertex(int index)
{
	//TODO: assertion
	_data.erase(_data.begin() + index);
}

void Polygon::moveVertices(const fei::Vec2& v)
{
	for (auto& vertex : _data) {
		vertex.add(v);
	}
}

void Polygon::reverseVertices()
{
	std::reverse(_data.begin(), _data.end());
}

void Polygon::zoom(float f)
{
	for (auto& vertex : _data) {
		vertex.zoom(f);
	}
}

const std::vector<Polygon> Polygon::cut(int index) const
{
	std::vector<Polygon> result;
	int best = getBestCutVertexIndex(index);
	if (best != -1) {
		result = cut(index, best);
	} else {
		int prev = indexNormalize(index - 1);
		bool isConcave = isConcaveVertex(index);
		auto leftVec = -getVector(prev);
		auto rightVec = getVector(index);
		auto middleVec = (leftVec.normalized() + rightVec.normalized()).normalized();
		if (isConcave) {
			middleVec *= -1.0f;
		}
		auto pl = collideRay(getVertex(index), middleVec);
		if (!pl.empty()) {
			Polygon polyCopy(*this);
			int segIndex = polyCopy.closestWhichSegment(pl[0]);
			int insertLoc = polyCopy.indexNormalize(segIndex + 1);
			polyCopy.insertVertex(pl[0], insertLoc);
			if (insertLoc <= index) {
				index = polyCopy.indexNormalize(index + 1);
			}
			result = polyCopy.cut(index, insertLoc);
		}
	}
	return result;
}

const std::vector<Polygon> Polygon::cut(int a, int b) const
{
	int curVertex;
	std::vector<Polygon> result;
	Polygon tmpPoly = *this;
	tmpPoly.clearVertex();

	curVertex = b;
	tmpPoly.pushVertex(getVertex(a));
	do {
		tmpPoly.pushVertex(getVertex(curVertex));
		curVertex = indexNormalize(curVertex + 1);
	} while(curVertex != a);
	result.push_back(tmpPoly);

	tmpPoly.clearVertex();

	curVertex = a;
	tmpPoly.pushVertex(getVertex(b));
	do {
		tmpPoly.pushVertex(getVertex(curVertex));
		curVertex = indexNormalize(curVertex + 1);
	} while(curVertex != b);
	result.push_back(tmpPoly);

	return result;
}

int Polygon::closestWhichSegment(const fei::Vec2& p) const
{
	int ans = -1;
	float minR = 1e32f;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto seg = getSegment(i);
		float curRatio = std::abs(((p - seg.a).getLength() + (p - seg.b).getLength()) / seg.getLength() - 1.0f);
		if (curRatio <= minR) {
			minR = curRatio;
			ans = i;
		}
	}
	return ans;
}

int Polygon::onWhichSegment(const fei::Vec2& p) const
{
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		if (getSegment(i).collidePoint(p)) {
			return i;
		}
	}
	return -1;
}

int Polygon::collideVertex(const fei::Vec2& p, float radius) const
{
	float rSq = radius * radius;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		if ((getVertex(i) - p).getLengthSq() <= rSq) {
			return i;
		}
	}
	return -1;
}

static bool cmpLength(const fei::Vec2& a, const fei::Vec2& b)
{
	return a.getLengthSq() < b.getLengthSq();
}

const std::vector<fei::Vec2> Polygon::rawCollideRay(const fei::Vec2& src, const fei::Vec2& drct) const
{
	std::vector<fei::Vec2> result;
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto seg = getSegment(i);
		fei::Vec2 tmp;
		if (seg.collideRay(tmp, src, drct)) {
			result.push_back(tmp - src);
		}
	}
	return result;
}

const std::vector<fei::Vec2> Polygon::collideRay(const fei::Vec2& src, const fei::Vec2& drct) const
{
	std::vector<fei::Vec2> result = rawCollideRay(src, drct);
	std::vector<fei::Vec2> uniqueResult;
	std::sort(result.begin(), result.end(), cmpLength);
	for (int i = 0; i < static_cast<int>(result.size()); i++) {
		if (result[i].getLengthSq() < 0.01f) continue;
		if (i == 0 || result[i] != result[i - 1]) {
			uniqueResult.push_back(result[i] + src);
		}
	}
	return uniqueResult;
}

void Polygon::normalize()
{
	std::vector<fei::Vec2> nData;
	int sz = _data.size();
	for (int i = 0; i < sz; i++) {
		int prev = indexNormalize(i - 1);
		if ((getVector(prev).getLengthSq() >= 0.01f)
		   && (getVector(i).normalized() != getVector(prev).normalized())) {
			nData.push_back(getVertex(i));
		}
	}
	setDataVector(nData);
	if (!isCCW()) {
		reverseVertices();
	}
}

const Polygon Polygon::normalized() const
{
	Polygon poly(*this);
	poly.normalize();
	return poly;
}

bool Polygon::isConcaveVertex(int index) const
{
	//TODO: assertion
	int prevIndex = indexNormalize(index - 1);
	auto prev = getVector(prevIndex);
	auto cur = getVector(index);
	float cp = prev.cross(cur);
	return cp < 0;
}

int Polygon::getOneConcaveVertex() const
{
	int sz = static_cast<int>(_data.size());
	for (int i = 0; i < sz; i++) {
		if (isConcaveVertex(i)) {
			return i;
		}
	}
	return -1;
}

typedef struct CutStruct
{
	CutStruct(const Polygon* pp, int ii, int xx)
	: poly(pp), index(ii), x(xx)
	{
	}

	bool operator>(const CutStruct& rhs) const
	{
		int ai = x;
		int bi = rhs.x;
		int sz = poly->getDataSize();
		bool aConcave = poly->isConcaveVertex(ai);
		bool bConcave = poly->isConcaveVertex(bi);
		if (aConcave == bConcave) {
			int disIA = std::abs(index - ai);
			if (sz - disIA < disIA) {
				disIA = sz - disIA;
			}
			int disIB = std::abs(index - bi);
			if (sz - disIB < disIB) {
				disIB = sz - disIB;
			}
			return disIA > disIB;
		} else {
			return aConcave;
		}
	}

	const Polygon* poly;
	int index;
	int x;
} PolyCutPair;

int Polygon::getBestCutVertexIndex(int index) const
{
	int ans = -1;
	auto iList = getVisibleVerticesIndex(index);

	std::vector<PolyCutPair> uList;
	if (isConcaveVertex(index)) {
		auto left = getSegment(index);
		auto right = getSegment(indexNormalize(index - 1));
		right.swapAB();
		left.b = left.a - left.getVector();
		right.b = right.a - right.getVector();
		for (int vertex : iList) {
			auto p = getVertex(vertex);
			if (left.onLeftOrRight(p) == 1
				 && right.onLeftOrRight(p) == -1) {
				auto pl = collideRay(getVertex(index), p - getVertex(index));
				if (pl.size() == 0 || pl[0] == p) {
					uList.push_back(PolyCutPair(this, index, vertex));
				}
			}
		}
	} else {
		for (int vertex : iList) {
			uList.push_back(PolyCutPair(this, index, vertex));
		}
	}
	if (!uList.empty()) {
		auto maxPcp = uList[0];
		for (auto& pcp : uList) {
			if (pcp > maxPcp) {
				maxPcp = pcp;
			}
		}
		ans = maxPcp.x;
	}
	return ans;
}

std::vector<int> Polygon::getVisibleVerticesIndex(int index) const
{
	std::vector<int> result;
	int left = indexNormalize(index - 1);
	int right = indexNormalize(index + 1);
	bool isConcave = isConcaveVertex(index);
	auto leftSeg = getSegment(left);
	auto rightSeg = getSegment(index);
	leftSeg.swapAB();
	if (isConcave) {
		auto tmp = leftSeg;
		leftSeg = rightSeg;
		rightSeg = tmp;
	}
	for (int i = 0; i < static_cast<int>(_data.size()); i++) {
		auto p = getVertex(i);
		if (i == index || i == left || i == right ||
		   (leftSeg.onLeftOrRight(p) == 1 && rightSeg.onLeftOrRight(p) == -1) == isConcave) {
			continue;
		}
		auto vertexList = collideRay(getVertex(index), p - getVertex(index));
		if (vertexList.size() == 0 || vertexList[0] == p) {
			result.push_back(i);
		}
	}
	return result;
}

bool Polygon::isConvex() const
{
	return getOneConcaveVertex() < 0;
}

const std::vector<Polygon> Polygon::convexDecomposition() const
{
	std::vector<Polygon> result;
	std::queue<Polygon> processQueue;
	processQueue.push(normalized());
	while(!processQueue.empty()) {
		auto currentPoly = processQueue.front();
		processQueue.pop();
		if (currentPoly.isValid()) {
			int concavePoint = currentPoly.getOneConcaveVertex();
			if (concavePoint == -1) {
				result.push_back(currentPoly);
			} else {
				auto twoPoly = currentPoly.cut(concavePoint);
				for (auto& poly : twoPoly) {
					poly.normalize();
					if (poly.isValid()) {
						processQueue.push(poly);
					}
				}
			}
		}
		if (result.size() > 100 || processQueue.size() > 100) {
			break;
		}
	}
	return result;
}

const std::vector<Polygon> Polygon::box2dDecomposition() const
{
	std::vector<Polygon> result;
	std::queue<Polygon> processQueue;
	auto convexList = convexDecomposition();
	for (auto& poly : convexList) {
		processQueue.push(poly);
	}
	while(!processQueue.empty()) {
		auto currentPoly = processQueue.front();
		processQueue.pop();
		if (currentPoly.isValid()) {
			if (currentPoly.getDataSize() <= 8) {
				result.push_back(currentPoly);
			} else {
				auto twoPoly = currentPoly.cut(0);
				for (auto& poly : twoPoly) {
					poly.normalize();
					if (poly.isValid() && (poly.getArea() > fei::epsf)) {
						processQueue.push(poly);
					}
				}
			}
		}
		if (result.size() > 100 || processQueue.size() > 100) {
			break;
		}
	}
	return result;
}

bool Polygon::collide(const fei::Shape* shape) const
{
	bool result = false;
	switch (shape->getType()) {
	//TODO: implement cases
	//case fei::Shape::Type::CIRCLE:
	//case fei::Shape::Type::POLYGON:
	//case fei::Shape::Type::RECT:
	//case fei::Shape::Type::SEGMENT:
	}
	return result;
}

bool Polygon::collidePoint(const fei::Vec2& p) const
{
	auto points = rawCollideRay(p, fei::Vec2(1.0f, 0.001f));
	return (points.size() & 1) == 1;
}

const Polygon Polygon::makeRegularPolygon(int edgeNum, float radius, float offset)
{
	Polygon polygon;
	for (int i = 0; i < edgeNum; i++) {
		float angle = static_cast<float>(2.0 * fei::pi / edgeNum * i + fei::D2R(offset));
		polygon.pushVertex(fei::Vec2(std::cos(angle), std::sin(angle)) * radius);
	}
	return polygon;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fontsubs.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 16:35:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_FONT_SUBSTITUTION_HXX
#define _SVX_FONT_SUBSTITUTION_HXX

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SVX_SIMPTABL_HXX //autogen
#include "simptabl.hxx"
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif
#ifndef _CTRLBOX_HXX //autogen
#include <svtools/ctrlbox.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class SvxFontSubstCheckListBox ------------------------------------------

class SvxFontSubstCheckListBox : public SvxSimpleTable
{
    friend class SvxFontSubstTabPage;

    protected:
        virtual void    SetTabs();
        virtual void    KeyInput( const KeyEvent& rKEvt );

    public:
        SvxFontSubstCheckListBox(Window* pParent, const ResId& rResId ) :
            SvxSimpleTable( pParent, rResId ){}

        inline void     *GetUserData(ULONG nPos) { return GetEntry(nPos)->GetUserData(); }
        inline void     SetUserData(ULONG nPos, void *pData ) { GetEntry(nPos)->SetUserData(pData); }

        BOOL            IsChecked(ULONG nPos, USHORT nCol = 0);
        BOOL            IsChecked(SvLBoxEntry* pEntry, USHORT nCol = 0);
        void            CheckEntryPos(ULONG nPos, USHORT nCol, BOOL bChecked);
        void            CheckEntry(SvLBoxEntry* pEntry, USHORT nCol, BOOL bChecked);
        SvButtonState   GetCheckButtonState( SvLBoxEntry*, USHORT nCol ) const;
        void            SetCheckButtonState( SvLBoxEntry*, USHORT nCol, SvButtonState );
};

// class SvxFontSubstTabPage ----------------------------------------------------
class SvtFontSubstConfig;
namespace svt {class SourceViewConfig;}
class SVX_DLLPUBLIC SvxFontSubstTabPage : public SfxTabPage
{
    CheckBox                    aUseTableCB;
    FixedText                   aFont1FT;
    FontNameBox                 aFont1CB;
    FixedText                   aFont2FT;
    FontNameBox                 aFont2CB;
    ToolBox                     aNewDelTBX;
    SvxFontSubstCheckListBox    aCheckLB;

    FixedLine                   aSourceViewFontsFL;
    FixedText                   aFontNameFT;
    ListBox                     aFontNameLB;
    CheckBox                    aNonPropFontsOnlyCB;
    FixedText                   aFontHeightFT;
    ListBox                     aFontHeightLB;

    ImageList                   aImageList;
    String                      sAutomatic;

    SvtFontSubstConfig*         pConfig;
    svt::SourceViewConfig*      pSourceViewConfig;

    String          sHeader1;
    String          sHeader2;
    String          sHeader3;
    String          sHeader4;

    Bitmap          aChkunBmp;
    Bitmap          aChkchBmp;
    Bitmap          aChkchhiBmp;
    Bitmap          aChkunhiBmp;
    Bitmap          aChktriBmp;
    Bitmap          aChktrihiBmp;
    Color           aTextColor;
    ByteString      sFontGroup;

    SvLBoxButtonData*   pCheckButtonData;

    DECL_LINK(SelectHdl, Window *pWin = 0);
    DECL_LINK(NonPropFontsHdl, CheckBox* pBox);

    SvLBoxEntry*    CreateEntry(String& rFont1, String& rFont2);
    void            CheckEnable();

    SvxFontSubstTabPage( Window* pParent, const SfxItemSet& rSet );
    ~SvxFontSubstTabPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
};

#endif // _SVX_FONT_SUBSTITUTION_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.430); FILE MERGED 2005/09/05 14:19:28 rt 1.3.430.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fontsubs.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:06:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SVX_FONT_SUBSTITUTION_HXX
#define _SVX_FONT_SUBSTITUTION_HXX

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SVX_SIMPTABL_HXX //autogen
#include "simptabl.hxx"
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif
#ifndef _CTRLBOX_HXX //autogen
#include <svtools/ctrlbox.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class SvxFontSubstCheckListBox ------------------------------------------

class SvxFontSubstCheckListBox : public SvxSimpleTable
{
    friend class SvxFontSubstTabPage;

    protected:
        virtual void    SetTabs();
        virtual void    KeyInput( const KeyEvent& rKEvt );

    public:
        SvxFontSubstCheckListBox(Window* pParent, const ResId& rResId ) :
            SvxSimpleTable( pParent, rResId ){}

        inline void     *GetUserData(ULONG nPos) { return GetEntry(nPos)->GetUserData(); }
        inline void     SetUserData(ULONG nPos, void *pData ) { GetEntry(nPos)->SetUserData(pData); }

        BOOL            IsChecked(ULONG nPos, USHORT nCol = 0);
        BOOL            IsChecked(SvLBoxEntry* pEntry, USHORT nCol = 0);
        void            CheckEntryPos(ULONG nPos, USHORT nCol, BOOL bChecked);
        void            CheckEntry(SvLBoxEntry* pEntry, USHORT nCol, BOOL bChecked);
        SvButtonState   GetCheckButtonState( SvLBoxEntry*, USHORT nCol ) const;
        void            SetCheckButtonState( SvLBoxEntry*, USHORT nCol, SvButtonState );
};

// class SvxFontSubstTabPage ----------------------------------------------------
class SvtFontSubstConfig;
namespace svt {class SourceViewConfig;}
class SVX_DLLPUBLIC SvxFontSubstTabPage : public SfxTabPage
{
    CheckBox                    aUseTableCB;
    FixedText                   aFont1FT;
    FontNameBox                 aFont1CB;
    FixedText                   aFont2FT;
    FontNameBox                 aFont2CB;
    ToolBox                     aNewDelTBX;
    SvxFontSubstCheckListBox    aCheckLB;

    FixedLine                   aSourceViewFontsFL;
    FixedText                   aFontNameFT;
    ListBox                     aFontNameLB;
    CheckBox                    aNonPropFontsOnlyCB;
    FixedText                   aFontHeightFT;
    ListBox                     aFontHeightLB;

    ImageList                   aImageList;
    String                      sAutomatic;

    SvtFontSubstConfig*         pConfig;
    svt::SourceViewConfig*      pSourceViewConfig;

    String          sHeader1;
    String          sHeader2;
    String          sHeader3;
    String          sHeader4;

    Bitmap          aChkunBmp;
    Bitmap          aChkchBmp;
    Bitmap          aChkchhiBmp;
    Bitmap          aChkunhiBmp;
    Bitmap          aChktriBmp;
    Bitmap          aChktrihiBmp;
    Color           aTextColor;
    ByteString      sFontGroup;

    SvLBoxButtonData*   pCheckButtonData;

    DECL_LINK(SelectHdl, Window *pWin = 0);
    DECL_LINK(NonPropFontsHdl, CheckBox* pBox);

    SvLBoxEntry*    CreateEntry(String& rFont1, String& rFont2);
    void            CheckEnable();

    SvxFontSubstTabPage( Window* pParent, const SfxItemSet& rSet );
    ~SvxFontSubstTabPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
};

#endif // _SVX_FONT_SUBSTITUTION_HXX

<|endoftext|>


<commit_before>#include "videotargetfactory.h"
#ifdef USE_OPENCV
#include "opencv_video_target.h"
#endif
#ifdef USE_FFMPEG
#include "ffmpeg_video_target.h"
#endif

namespace gg
{

VideoTargetFactory::VideoTargetFactory()
{
    // nop
}

VideoTargetFactory::~VideoTargetFactory()
{
    // nop
}

VideoTargetFactory & VideoTargetFactory::get_instance()
{
    static VideoTargetFactory _factory_singleton;
    return _factory_singleton;
}

IVideoTarget * VideoTargetFactory::create_file_writer(enum Codec codec,
                                                      const std::string filename,
                                                      const float frame_rate)
{
    IVideoTarget * target = nullptr;
    switch (codec)
    {
    case Xvid:
#ifdef USE_OPENCV
        target = new VideoTargetOpenCV("XVID", filename, frame_rate);
        break;
#endif
    case HEVC:
#ifdef USE_FFMPEG
        target = new VideoTargetFFmpeg("HEVC", filename, frame_rate);
        break;
#endif
    case VP9:
#ifdef USE_FFMPEG
        target = new VideoTargetFFmpeg("VP9", filename, frame_rate);
        break;
#endif
    default:
        std::string msg;
        msg.append("Video target codec ")
           .append(std::to_string(codec))
           .append(" not supported");
        throw VideoTargetError(msg);
    }

    return target;
}

}
<commit_msg>Issue #19: revised static var name in VideoTargetFactory::get_instance for clarity<commit_after>#include "videotargetfactory.h"
#ifdef USE_OPENCV
#include "opencv_video_target.h"
#endif
#ifdef USE_FFMPEG
#include "ffmpeg_video_target.h"
#endif

namespace gg
{

VideoTargetFactory::VideoTargetFactory()
{
    // nop
}

VideoTargetFactory::~VideoTargetFactory()
{
    // nop
}

VideoTargetFactory & VideoTargetFactory::get_instance()
{
    static VideoTargetFactory _video_target_factory_singleton;
    return _video_target_factory_singleton;
}

IVideoTarget * VideoTargetFactory::create_file_writer(enum Codec codec,
                                                      const std::string filename,
                                                      const float frame_rate)
{
    IVideoTarget * target = nullptr;
    switch (codec)
    {
    case Xvid:
#ifdef USE_OPENCV
        target = new VideoTargetOpenCV("XVID", filename, frame_rate);
        break;
#endif
    case HEVC:
#ifdef USE_FFMPEG
        target = new VideoTargetFFmpeg("HEVC", filename, frame_rate);
        break;
#endif
    case VP9:
#ifdef USE_FFMPEG
        target = new VideoTargetFFmpeg("VP9", filename, frame_rate);
        break;
#endif
    default:
        std::string msg;
        msg.append("Video target codec ")
           .append(std::to_string(codec))
           .append(" not supported");
        throw VideoTargetError(msg);
    }

    return target;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SpellDialog.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-23 11:04:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_SPELLDDIALOG_HXX
#define _SVX_SPELLDDIALOG_HXX

// include ---------------------------------------------------------------

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _STDCTRL_HXX //autogen
#include <svtools/stdctrl.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#ifndef _MENUBTN_HXX //autogen
#include <vcl/menubtn.hxx>
#endif

#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif

#ifndef _SV_DECOVIEW_HXX //autogen
#include <vcl/decoview.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _SVX_BOX_HXX //autogen
#include "svxbox.hxx"
#endif
#ifndef _SVX_LANGBOX_HXX
#include <langbox.hxx>
#endif
#include <memory>
#ifndef _SVEDIT_HXX
#include <svtools/svmedit.hxx>
#endif
#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif

#ifndef _XTEXTEDT_HXX //autogen
#include <svtools/xtextedt.hxx>
#endif
#ifndef SVX_SPELL_PORTIONS_HXX
#include <SpellPortions.hxx>
#endif

class ScrollBar;
class TextEngine;
class ExtTextView;
namespace svx{ class SpellUndoAction_Impl;}

// forward ---------------------------------------------------------------

struct SpellDialog_Impl;

namespace com{namespace sun{namespace star{
namespace linguistic2{
    class XSpellChecker1;
}}}}
namespace svx{
class SpellDialog;
// ------------------------------------------------------------------
class SentenceEditWindow_Impl : public MultiLineEdit/*, public SfxListener*/
{
private:
    USHORT          m_nErrorStart;
    USHORT          m_nErrorEnd;
    bool            m_bIsUndoEditMode;

    Link                    m_aModifyLink;

    void            CallModifyLink() {m_aModifyLink.Call(this);}

    SpellDialog*    GetSpellDialog() const {return (SpellDialog*)GetParent();}
protected:
    virtual long    PreNotify( NotifyEvent& rNEvt );

public:
                    SentenceEditWindow_Impl( SpellDialog* pParent, const ResId& rResId );
                    ~SentenceEditWindow_Impl();

    void            SetModifyHdl(const Link& rLink) { m_aModifyLink = rLink;}

    void            SetAttrib( const TextAttrib& rAttr, ULONG nPara, USHORT nStart, USHORT nEnd );
    void            SetText( const String& rStr );

    bool            MarkNextError();
    void            ChangeMarkedWord(const String& rNewWord, LanguageType eLanguage);
    void            MoveErrorMarkTo(USHORT nErrorStart, USHORT nErrorEnd);
    String          GetErrorText() const;
    void            RestoreCurrentError();

    com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellAlternatives> GetAlternatives();
    void            SetAlternatives(
                        com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellAlternatives> );

    void            ResetModified()   { GetTextEngine()->SetModified(FALSE); m_bIsUndoEditMode = false;}
    BOOL            IsModified() const              { return GetTextEngine()->IsModified(); }

    bool            IsUndoEditMode() const { return m_bIsUndoEditMode;}
    void            SetUndoEditMode(bool bSet);

    svx::SpellPortions  CreateSpellPortions() const;

    void            ResetUndo();
    void            Undo();
    void            AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg=FALSE );
    USHORT          GetUndoActionCount();
    void            UndoActionStart( USHORT nId );
    void            UndoActionEnd( USHORT nId );

    void            MoveErrorEnd(long nOffset);
};

// class SvxSpellDialog ---------------------------------------------
class SpellDialogChildWindow;
class SpellDialog : public SfxModelessDialog
{
    friend class SentenceEditWindow_Impl;
private:
    FixedText           aNotInDictFT;
    SentenceEditWindow_Impl  aSentenceED;

    FixedText       aSuggestionFT;
    ListBox         aSuggestionLB;

    FixedText       aLanguageFT;
    SvxLanguageBox  aLanguageLB;

    PushButton      aIgnorePB;
    PushButton      aIgnoreAllPB;
    MenuButton      aAddToDictMB;

    PushButton      aChangePB;
    PushButton      aChangeAllPB;
    PushButton      aAutoCorrPB;

    PushButton      aOptionsPB;
    HelpButton      aHelpPB;
    PushButton      aUndoPB;
    PushButton      aClosePB;

    GroupBox        aBackgroundGB;

    String          aTitel;
    String          aResumeST;
    String          aIgnoreOnceST;
    String          aNoSuggestionsST;

    Size            aOldWordEDSize;
    Link            aDialogUndoLink;

    bool            bModified;
    bool            bFocusLocked;

    svx::SpellDialogChildWindow& rParent;
    svx::SpellPortions           m_aSavedSentence;

    SpellDialog_Impl* pImpl;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellChecker1 >     xSpell;
    String              aOldWord;
    LanguageType        nOldLang;

    DECL_LINK( ChangeHdl, Button * );
    DECL_LINK( ChangeAllHdl, Button * );
    DECL_LINK( IgnoreAllHdl, Button * );
    DECL_LINK( IgnoreHdl, Button * );
    DECL_LINK( ExtClickHdl, Button * );
    DECL_LINK( CancelHdl, Button * );
    DECL_LINK( ModifyHdl, SentenceEditWindow_Impl *);
    DECL_LINK( UndoHdl, Button * );
    DECL_LINK( AddToDictionaryHdl, MenuButton* );
    DECL_LINK( LanguageSelectHdl, SvxLanguageBox* );
    DECL_LINK( DialogUndoHdl, SpellUndoAction_Impl* );

    DECL_STATIC_LINK( SpellDialog, InitHdl, SpellDialog * );

    void            StartSpellOptDlg_Impl();
    void            InitUserDicts();
    void            UpdateBoxes_Impl();
    void            Init_Impl();
    void            SpellContinue_Impl(bool UseSavedSentence = false);
    void            LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}

    void            SetSelectedLang_Impl( LanguageType nLang );
    LanguageType    GetSelectedLang_Impl() const;

    /** Retrieves the next sentence.
     */
    bool            GetNextSentence_Impl(bool bUseSavedSentence);
    /** Corrects all errors that have been selected to be changed always
     */
    bool            ApplyChangeAllList_Impl(SpellPortions& rSentence, bool& bHasReplaced);

protected:
    virtual void    Paint( const Rectangle& rRect );
    virtual long    Notify( NotifyEvent& rNEvt );

public:
    SpellDialog(
        svx::SpellDialogChildWindow* pChildWindow,
        Window * pParent,
        SfxBindings* pBindings);
    ~SpellDialog();

    void            SetLanguage( sal_uInt16 nLang );
    virtual sal_Bool    Close();

    void            Invalidate();
};
} //namespace svx

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.252); FILE MERGED 2005/09/05 14:24:59 rt 1.3.252.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SpellDialog.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 23:10:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SVX_SPELLDDIALOG_HXX
#define _SVX_SPELLDDIALOG_HXX

// include ---------------------------------------------------------------

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _STDCTRL_HXX //autogen
#include <svtools/stdctrl.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#ifndef _MENUBTN_HXX //autogen
#include <vcl/menubtn.hxx>
#endif

#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif

#ifndef _SV_DECOVIEW_HXX //autogen
#include <vcl/decoview.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _SVX_BOX_HXX //autogen
#include "svxbox.hxx"
#endif
#ifndef _SVX_LANGBOX_HXX
#include <langbox.hxx>
#endif
#include <memory>
#ifndef _SVEDIT_HXX
#include <svtools/svmedit.hxx>
#endif
#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif

#ifndef _XTEXTEDT_HXX //autogen
#include <svtools/xtextedt.hxx>
#endif
#ifndef SVX_SPELL_PORTIONS_HXX
#include <SpellPortions.hxx>
#endif

class ScrollBar;
class TextEngine;
class ExtTextView;
namespace svx{ class SpellUndoAction_Impl;}

// forward ---------------------------------------------------------------

struct SpellDialog_Impl;

namespace com{namespace sun{namespace star{
namespace linguistic2{
    class XSpellChecker1;
}}}}
namespace svx{
class SpellDialog;
// ------------------------------------------------------------------
class SentenceEditWindow_Impl : public MultiLineEdit/*, public SfxListener*/
{
private:
    USHORT          m_nErrorStart;
    USHORT          m_nErrorEnd;
    bool            m_bIsUndoEditMode;

    Link                    m_aModifyLink;

    void            CallModifyLink() {m_aModifyLink.Call(this);}

    SpellDialog*    GetSpellDialog() const {return (SpellDialog*)GetParent();}
protected:
    virtual long    PreNotify( NotifyEvent& rNEvt );

public:
                    SentenceEditWindow_Impl( SpellDialog* pParent, const ResId& rResId );
                    ~SentenceEditWindow_Impl();

    void            SetModifyHdl(const Link& rLink) { m_aModifyLink = rLink;}

    void            SetAttrib( const TextAttrib& rAttr, ULONG nPara, USHORT nStart, USHORT nEnd );
    void            SetText( const String& rStr );

    bool            MarkNextError();
    void            ChangeMarkedWord(const String& rNewWord, LanguageType eLanguage);
    void            MoveErrorMarkTo(USHORT nErrorStart, USHORT nErrorEnd);
    String          GetErrorText() const;
    void            RestoreCurrentError();

    com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellAlternatives> GetAlternatives();
    void            SetAlternatives(
                        com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellAlternatives> );

    void            ResetModified()   { GetTextEngine()->SetModified(FALSE); m_bIsUndoEditMode = false;}
    BOOL            IsModified() const              { return GetTextEngine()->IsModified(); }

    bool            IsUndoEditMode() const { return m_bIsUndoEditMode;}
    void            SetUndoEditMode(bool bSet);

    svx::SpellPortions  CreateSpellPortions() const;

    void            ResetUndo();
    void            Undo();
    void            AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg=FALSE );
    USHORT          GetUndoActionCount();
    void            UndoActionStart( USHORT nId );
    void            UndoActionEnd( USHORT nId );

    void            MoveErrorEnd(long nOffset);
};

// class SvxSpellDialog ---------------------------------------------
class SpellDialogChildWindow;
class SpellDialog : public SfxModelessDialog
{
    friend class SentenceEditWindow_Impl;
private:
    FixedText           aNotInDictFT;
    SentenceEditWindow_Impl  aSentenceED;

    FixedText       aSuggestionFT;
    ListBox         aSuggestionLB;

    FixedText       aLanguageFT;
    SvxLanguageBox  aLanguageLB;

    PushButton      aIgnorePB;
    PushButton      aIgnoreAllPB;
    MenuButton      aAddToDictMB;

    PushButton      aChangePB;
    PushButton      aChangeAllPB;
    PushButton      aAutoCorrPB;

    PushButton      aOptionsPB;
    HelpButton      aHelpPB;
    PushButton      aUndoPB;
    PushButton      aClosePB;

    GroupBox        aBackgroundGB;

    String          aTitel;
    String          aResumeST;
    String          aIgnoreOnceST;
    String          aNoSuggestionsST;

    Size            aOldWordEDSize;
    Link            aDialogUndoLink;

    bool            bModified;
    bool            bFocusLocked;

    svx::SpellDialogChildWindow& rParent;
    svx::SpellPortions           m_aSavedSentence;

    SpellDialog_Impl* pImpl;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellChecker1 >     xSpell;
    String              aOldWord;
    LanguageType        nOldLang;

    DECL_LINK( ChangeHdl, Button * );
    DECL_LINK( ChangeAllHdl, Button * );
    DECL_LINK( IgnoreAllHdl, Button * );
    DECL_LINK( IgnoreHdl, Button * );
    DECL_LINK( ExtClickHdl, Button * );
    DECL_LINK( CancelHdl, Button * );
    DECL_LINK( ModifyHdl, SentenceEditWindow_Impl *);
    DECL_LINK( UndoHdl, Button * );
    DECL_LINK( AddToDictionaryHdl, MenuButton* );
    DECL_LINK( LanguageSelectHdl, SvxLanguageBox* );
    DECL_LINK( DialogUndoHdl, SpellUndoAction_Impl* );

    DECL_STATIC_LINK( SpellDialog, InitHdl, SpellDialog * );

    void            StartSpellOptDlg_Impl();
    void            InitUserDicts();
    void            UpdateBoxes_Impl();
    void            Init_Impl();
    void            SpellContinue_Impl(bool UseSavedSentence = false);
    void            LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}

    void            SetSelectedLang_Impl( LanguageType nLang );
    LanguageType    GetSelectedLang_Impl() const;

    /** Retrieves the next sentence.
     */
    bool            GetNextSentence_Impl(bool bUseSavedSentence);
    /** Corrects all errors that have been selected to be changed always
     */
    bool            ApplyChangeAllList_Impl(SpellPortions& rSentence, bool& bHasReplaced);

protected:
    virtual void    Paint( const Rectangle& rRect );
    virtual long    Notify( NotifyEvent& rNEvt );

public:
    SpellDialog(
        svx::SpellDialogChildWindow* pChildWindow,
        Window * pParent,
        SfxBindings* pBindings);
    ~SpellDialog();

    void            SetLanguage( sal_uInt16 nLang );
    virtual sal_Bool    Close();

    void            Invalidate();
};
} //namespace svx

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: svdhlpln.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 13:10:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include "svdhlpln.hxx"

#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif

#ifndef _OUTDEV_HXX //autogen
#include <vcl/outdev.hxx>
#endif

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif

#ifndef _SV_LINEINFO_HXX
#include <vcl/lineinfo.hxx>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////

Pointer SdrHelpLine::GetPointer() const
{
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : return Pointer(POINTER_ESIZE);
        case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE);
        default                    : return Pointer(POINTER_MOVE);
    } // switch
}

// #i27493#
// Helper method to draw a hor or ver two-colored dashed line
void SdrHelpLine::ImpDrawDashedTwoColorLine(OutputDevice& rOut, sal_Int32 nStart, sal_Int32 nEnd, sal_Int32 nFixPos,
    sal_Int32 nStepWidth, Color aColA, Color aColB, sal_Bool bHorizontal) const
{
    for(sal_Int32 a(nStart), b(0L); a < nEnd; a += nStepWidth, b++)
    {
        rOut.SetLineColor((b % 2) ? aColA : aColB);
        sal_Int32 nNextPos(a + nStepWidth - 1L);
        if(nNextPos > nEnd)
            nNextPos = nEnd;
        if(bHorizontal)
            rOut.DrawLine(Point(a, nFixPos), Point(nNextPos, nFixPos));
        else
            rOut.DrawLine(Point(nFixPos, a), Point(nFixPos, nNextPos));
    }
}

void SdrHelpLine::Draw(OutputDevice& rOut, const Point& rOfs) const
{
    // #i27493# New implementation for 8. Will be replaced later when we have overlays.
    Point aPnt(rOut.LogicToPixel(aPos + rOfs));
    const sal_Int32 xPos(aPnt.X());
    const sal_Int32 yPos(aPnt.Y());
    const sal_Bool bOldMapModeWasEnabled(rOut.IsMapModeEnabled());
    const Size aOutSizePixel(rOut.GetOutputSizePixel());
    rOut.EnableMapMode(sal_False);

    switch(eKind)
    {
        case SDRHELPLINE_VERTICAL :
        {
            ImpDrawDashedTwoColorLine(rOut, 0L, aOutSizePixel.Height(),
                xPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_False);
            break;
        }

        case SDRHELPLINE_HORIZONTAL :
        {
            ImpDrawDashedTwoColorLine(rOut, 0L, aOutSizePixel.Width(),
                yPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_True);
            break;
        }

        case SDRHELPLINE_POINT :
        {
            ImpDrawDashedTwoColorLine(rOut, xPos - SDRHELPLINE_POINT_PIXELSIZE, xPos + SDRHELPLINE_POINT_PIXELSIZE,
                yPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_True);
            ImpDrawDashedTwoColorLine(rOut, yPos - SDRHELPLINE_POINT_PIXELSIZE, yPos + SDRHELPLINE_POINT_PIXELSIZE,
                xPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_False);
            break;
        }
    }

    rOut.EnableMapMode(bOldMapModeWasEnabled);
}

FASTBOOL SdrHelpLine::IsHit(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
{
    Size a1Pix(rOut.PixelToLogic(Size(1,1)));
    FASTBOOL bXHit=rPnt.X()>=aPos.X()-nTolLog && rPnt.X()<=aPos.X()+nTolLog+a1Pix.Width();
    FASTBOOL bYHit=rPnt.Y()>=aPos.Y()-nTolLog && rPnt.Y()<=aPos.Y()+nTolLog+a1Pix.Height();
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : return bXHit;
        case SDRHELPLINE_HORIZONTAL: return bYHit;
        case SDRHELPLINE_POINT: {
            if (bXHit || bYHit) {
                Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
                return rPnt.X()>=aPos.X()-aRad.Width() && rPnt.X()<=aPos.X()+aRad.Width()+a1Pix.Width() &&
                       rPnt.Y()>=aPos.Y()-aRad.Height() && rPnt.Y()<=aPos.Y()+aRad.Height()+a1Pix.Height();
            }
        } break;
    } // switch
    return FALSE;
}

Rectangle SdrHelpLine::GetBoundRect(const OutputDevice& rOut) const
{
    Rectangle aRet(aPos,aPos);
    Point aOfs(rOut.GetMapMode().GetOrigin());
    Size aSiz(rOut.GetOutputSize());
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : aRet.Top()=-aOfs.Y(); aRet.Bottom()=-aOfs.Y()+aSiz.Height(); break;
        case SDRHELPLINE_HORIZONTAL: aRet.Left()=-aOfs.X(); aRet.Right()=-aOfs.X()+aSiz.Width();  break;
        case SDRHELPLINE_POINT     : {
            Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
            aRet.Left()  -=aRad.Width();
            aRet.Right() +=aRad.Width();
            aRet.Top()   -=aRad.Height();
            aRet.Bottom()+=aRad.Height();
        } break;
    } // switch
    return aRet;
}

bool SdrHelpLine::IsVisibleEqual( const SdrHelpLine& rHelpLine, const OutputDevice& rOut ) const
{
    if( eKind == rHelpLine.eKind)
    {
        Point aPt1(rOut.LogicToPixel(aPos)), aPt2(rOut.LogicToPixel(rHelpLine.aPos));
        switch( eKind )
        {
            case SDRHELPLINE_POINT:
                return aPt1 == aPt2;
            case SDRHELPLINE_VERTICAL:
                return aPt1.X() == aPt2.X();
            case SDRHELPLINE_HORIZONTAL:
                return aPt1.Y() == aPt2.Y();
        }
    }
    return false;
}

//BFS01SvStream& operator<<(SvStream& rOut, const SdrHelpLine& rHL)
//BFS01{
//BFS01 SdrIOHeader aHead(rOut,STREAM_WRITE,SdrIOHlpLID);
//BFS01 rOut<<UINT16(rHL.eKind);
//BFS01 rOut<<rHL.aPos;
//BFS01 return rOut;
//BFS01}

//BFS01SvStream& operator>>(SvStream& rIn, SdrHelpLine& rHL)
//BFS01{
//BFS01 SdrIOHeader aHead(rIn,STREAM_READ);
//BFS01 UINT16 nDum;
//BFS01 rIn>>nDum;
//BFS01 rHL.eKind=(SdrHelpLineKind)nDum;
//BFS01 rIn>>rHL.aPos;
//BFS01 return rIn;
//BFS01}

void SdrHelpLineList::Clear()
{
    USHORT nAnz=GetCount();
    for (USHORT i=0; i<nAnz; i++) {
        delete GetObject(i);
    }
    aList.Clear();
}

void SdrHelpLineList::operator=(const SdrHelpLineList& rSrcList)
{
    Clear();
    USHORT nAnz=rSrcList.GetCount();
    for (USHORT i=0; i<nAnz; i++) {
        Insert(rSrcList[i]);
    }
}

bool SdrHelpLineList::operator==(const SdrHelpLineList& rSrcList) const
{
    FASTBOOL bEqual=FALSE;
    USHORT nAnz=GetCount();
    if (nAnz==rSrcList.GetCount()) {
        bEqual=TRUE;
        for (USHORT i=0; i<nAnz && bEqual; i++) {
            if (*GetObject(i)!=*rSrcList.GetObject(i)) {
                bEqual=FALSE;
            }
        }
    }
    return bEqual;
}

void SdrHelpLineList::DrawAll(OutputDevice& rOut, const Point& rOfs) const
{

    sal_uInt16 nAnz = GetCount();
    sal_uInt16 i,j;
    SdrHelpLine *pHL, *pHL2;

    for(i=0; i<nAnz; i++)
    {
        pHL = GetObject(i);

        // check if we already drawn a help line like this one
        if( pHL )
        {
            for(j=0;j<i;j++)
            {
                pHL2 = GetObject(j);
                if( pHL2 && pHL->IsVisibleEqual( *pHL2, rOut) )
                {
                    pHL = NULL;
                    break;
                }
            }
        }

        if( pHL )
            pHL->Draw(rOut,rOfs);
    }
}

USHORT SdrHelpLineList::HitTest(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
{
    USHORT nAnz=GetCount();
    for (USHORT i=nAnz; i>0;) {
        i--;
        if (GetObject(i)->IsHit(rPnt,nTolLog,rOut)) return i;
    }
    return SDRHELPLINE_NOTFOUND;
}

//BFS01SvStream& operator<<(SvStream& rOut, const SdrHelpLineList& rHLL)
//BFS01{
//BFS01 SdrIOHeader aHead(rOut,STREAM_WRITE,SdrIOHLstID);
//BFS01 USHORT nAnz=rHLL.GetCount();
//BFS01 rOut<<nAnz;
//BFS01 for (USHORT i=0; i<nAnz; i++) {
//BFS01     rOut<<rHLL[i];
//BFS01 }
//BFS01 return rOut;
//BFS01}

//BFS01SvStream& operator>>(SvStream& rIn, SdrHelpLineList& rHLL)
//BFS01{
//BFS01 SdrIOHeader aHead(rIn,STREAM_READ);
//BFS01 rHLL.Clear();
//BFS01 USHORT nAnz;
//BFS01 rIn>>nAnz;
//BFS01 for (USHORT i=0; i<nAnz; i++) {
//BFS01     SdrHelpLine* pHL=new SdrHelpLine;
//BFS01     rIn>>*pHL;
//BFS01     rHLL.aList.Insert(pHL,CONTAINER_APPEND);
//BFS01 }
//BFS01 return rIn;
//BFS01}

// eof
<commit_msg>INTEGRATION: CWS aw024 (1.8.140); FILE MERGED 2006/11/10 03:43:22 aw 1.8.140.5: RESYNC: (1.12-1.13); FILE MERGED 2006/09/21 19:27:45 aw 1.8.140.4: RESYNC: (1.11-1.12); FILE MERGED 2006/07/04 13:15:06 aw 1.8.140.3: RESYNC: (1.9-1.10); FILE MERGED 2005/09/18 05:03:28 aw 1.8.140.2: RESYNC: (1.8-1.9); FILE MERGED 2004/12/23 16:52:45 aw 1.8.140.1: #i39525<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: svdhlpln.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 13:42:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include "svdhlpln.hxx"

#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif

#ifndef _OUTDEV_HXX //autogen
#include <vcl/outdev.hxx>
#endif

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif

#ifndef _SV_LINEINFO_HXX
#include <vcl/lineinfo.hxx>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////

Pointer SdrHelpLine::GetPointer() const
{
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : return Pointer(POINTER_ESIZE);
        case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE);
        default                    : return Pointer(POINTER_MOVE);
    } // switch
}

// #i27493#
// Helper method to draw a hor or ver two-colored dashed line
void SdrHelpLine::ImpDrawDashedTwoColorLine(OutputDevice& rOut, sal_Int32 nStart, sal_Int32 nEnd, sal_Int32 nFixPos,
    sal_Int32 nStepWidth, Color aColA, Color aColB, sal_Bool bHorizontal) const
{
    for(sal_Int32 a(nStart), b(0L); a < nEnd; a += nStepWidth, b++)
    {
        rOut.SetLineColor((b % 2) ? aColA : aColB);
        sal_Int32 nNextPos(a + nStepWidth - 1L);
        if(nNextPos > nEnd)
            nNextPos = nEnd;
        if(bHorizontal)
            rOut.DrawLine(Point(a, nFixPos), Point(nNextPos, nFixPos));
        else
            rOut.DrawLine(Point(nFixPos, a), Point(nFixPos, nNextPos));
    }
}

void SdrHelpLine::Draw(OutputDevice& rOut, const Point& rOfs) const
{
    // #i27493# New implementation for 8. Will be replaced later when we have overlays.
    Point aPnt(rOut.LogicToPixel(aPos + rOfs));
    const sal_Int32 xPos(aPnt.X());
    const sal_Int32 yPos(aPnt.Y());
    const sal_Bool bOldMapModeWasEnabled(rOut.IsMapModeEnabled());
    const Size aOutSizePixel(rOut.GetOutputSizePixel());
    rOut.EnableMapMode(sal_False);

    switch(eKind)
    {
        case SDRHELPLINE_VERTICAL :
        {
            ImpDrawDashedTwoColorLine(rOut, 0L, aOutSizePixel.Height(),
                xPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_False);
            break;
        }

        case SDRHELPLINE_HORIZONTAL :
        {
            ImpDrawDashedTwoColorLine(rOut, 0L, aOutSizePixel.Width(),
                yPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_True);
            break;
        }

        case SDRHELPLINE_POINT :
        {
            ImpDrawDashedTwoColorLine(rOut, xPos - SDRHELPLINE_POINT_PIXELSIZE, xPos + SDRHELPLINE_POINT_PIXELSIZE,
                yPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_True);
            ImpDrawDashedTwoColorLine(rOut, yPos - SDRHELPLINE_POINT_PIXELSIZE, yPos + SDRHELPLINE_POINT_PIXELSIZE,
                xPos, 4L , Color(COL_BLACK), Color(COL_WHITE), sal_False);
            break;
        }
    }

    rOut.EnableMapMode(bOldMapModeWasEnabled);
}

FASTBOOL SdrHelpLine::IsHit(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
{
    Size a1Pix(rOut.PixelToLogic(Size(1,1)));
    FASTBOOL bXHit=rPnt.X()>=aPos.X()-nTolLog && rPnt.X()<=aPos.X()+nTolLog+a1Pix.Width();
    FASTBOOL bYHit=rPnt.Y()>=aPos.Y()-nTolLog && rPnt.Y()<=aPos.Y()+nTolLog+a1Pix.Height();
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : return bXHit;
        case SDRHELPLINE_HORIZONTAL: return bYHit;
        case SDRHELPLINE_POINT: {
            if (bXHit || bYHit) {
                Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
                return rPnt.X()>=aPos.X()-aRad.Width() && rPnt.X()<=aPos.X()+aRad.Width()+a1Pix.Width() &&
                       rPnt.Y()>=aPos.Y()-aRad.Height() && rPnt.Y()<=aPos.Y()+aRad.Height()+a1Pix.Height();
            }
        } break;
    } // switch
    return FALSE;
}

Rectangle SdrHelpLine::GetBoundRect(const OutputDevice& rOut) const
{
    Rectangle aRet(aPos,aPos);
    Point aOfs(rOut.GetMapMode().GetOrigin());
    Size aSiz(rOut.GetOutputSize());
    switch (eKind) {
        case SDRHELPLINE_VERTICAL  : aRet.Top()=-aOfs.Y(); aRet.Bottom()=-aOfs.Y()+aSiz.Height(); break;
        case SDRHELPLINE_HORIZONTAL: aRet.Left()=-aOfs.X(); aRet.Right()=-aOfs.X()+aSiz.Width();  break;
        case SDRHELPLINE_POINT     : {
            Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
            aRet.Left()  -=aRad.Width();
            aRet.Right() +=aRad.Width();
            aRet.Top()   -=aRad.Height();
            aRet.Bottom()+=aRad.Height();
        } break;
    } // switch
    return aRet;
}

bool SdrHelpLine::IsVisibleEqual( const SdrHelpLine& rHelpLine, const OutputDevice& rOut ) const
{
    if( eKind == rHelpLine.eKind)
    {
        Point aPt1(rOut.LogicToPixel(aPos)), aPt2(rOut.LogicToPixel(rHelpLine.aPos));
        switch( eKind )
        {
            case SDRHELPLINE_POINT:
                return aPt1 == aPt2;
            case SDRHELPLINE_VERTICAL:
                return aPt1.X() == aPt2.X();
            case SDRHELPLINE_HORIZONTAL:
                return aPt1.Y() == aPt2.Y();
        }
    }
    return false;
}

void SdrHelpLineList::Clear()
{
    USHORT nAnz=GetCount();
    for (USHORT i=0; i<nAnz; i++) {
        delete GetObject(i);
    }
    aList.Clear();
}

void SdrHelpLineList::operator=(const SdrHelpLineList& rSrcList)
{
    Clear();
    USHORT nAnz=rSrcList.GetCount();
    for (USHORT i=0; i<nAnz; i++) {
        Insert(rSrcList[i]);
    }
}

bool SdrHelpLineList::operator==(const SdrHelpLineList& rSrcList) const
{
    FASTBOOL bEqual=FALSE;
    USHORT nAnz=GetCount();
    if (nAnz==rSrcList.GetCount()) {
        bEqual=TRUE;
        for (USHORT i=0; i<nAnz && bEqual; i++) {
            if (*GetObject(i)!=*rSrcList.GetObject(i)) {
                bEqual=FALSE;
            }
        }
    }
    return bEqual;
}

void SdrHelpLineList::DrawAll(OutputDevice& rOut, const Point& rOfs) const
{

    sal_uInt16 nAnz = GetCount();
    sal_uInt16 i,j;
    SdrHelpLine *pHL, *pHL2;

    for(i=0; i<nAnz; i++)
    {
        pHL = GetObject(i);

        // check if we already drawn a help line like this one
        if( pHL )
        {
            for(j=0;j<i;j++)
            {
                pHL2 = GetObject(j);
                if( pHL2 && pHL->IsVisibleEqual( *pHL2, rOut) )
                {
                    pHL = NULL;
                    break;
                }
            }
        }

        if( pHL )
            pHL->Draw(rOut,rOfs);
    }
}

USHORT SdrHelpLineList::HitTest(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
{
    USHORT nAnz=GetCount();
    for (USHORT i=nAnz; i>0;) {
        i--;
        if (GetObject(i)->IsHit(rPnt,nTolLog,rOut)) return i;
    }
    return SDRHELPLINE_NOTFOUND;
}

// eof
<|endoftext|>


<commit_before>#include "output_test.h"
#include "../src/check.h" // NOTE: check.h is for internal use only!
#include "../src/re.h" // NOTE: re.h is for internal use only
#include <memory>
#include <map>
#include <iostream>
#include <sstream>

// ========================================================================= //
// ------------------------------ Internals -------------------------------- //
// ========================================================================= //
namespace internal { namespace {

using TestCaseList = std::vector<TestCase>;

// Use a vector because the order elements are added matters during iteration.
// std::map/unordered_map don't guarantee that.
// For example:
//  SetSubstitutions({{"%HelloWorld", "Hello"}, {"%Hello", "Hi"}});
//     Substitute("%HelloWorld") // Always expands to Hello.
using SubMap = std::vector<std::pair<std::string, std::string>>;

TestCaseList& GetTestCaseList(TestCaseID ID) {
    // Uses function-local statics to ensure initialization occurs
    // before first use.
    static TestCaseList lists[TC_NumID];
    return lists[ID];
}

SubMap& GetSubstitutions() {
    // Don't use 'dec_re' from header because it may not yet be initialized.
    static std::string dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?";
    static SubMap map = {
        {"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"},
        {"%int", "[ ]*[0-9]+"},
        {" %s ", "[ ]+"},
        {"%time", "[ ]*[0-9]{1,5} ns"},
        {"%console_report", "[ ]*[0-9]{1,5} ns [ ]*[0-9]{1,5} ns [ ]*[0-9]+"},
        {"%csv_report", "[0-9]+," + dec_re + "," + dec_re + ",ns,,,,,"}
    };
    return map;
}

std::string PerformSubstitutions(std::string source) {
    SubMap const& subs = GetSubstitutions();
    using SizeT = std::string::size_type;
    for (auto const& KV : subs) {
        SizeT pos;
        SizeT next_start = 0;
        while ((pos = source.find(KV.first, next_start)) != std::string::npos) {
            next_start = pos + KV.second.size();
            source.replace(pos, KV.first.size(), KV.second);
        }
    }
    return source;
}

void CheckCase(std::stringstream& remaining_output, TestCase const& TC,
               TestCaseList const& not_checks)
{
    std::string first_line;
    bool on_first = true;
    std::string line;
    while (remaining_output.eof() == false) {
        CHECK(remaining_output.good());
        std::getline(remaining_output, line);
        if (on_first) {
            first_line = line;
            on_first = false;
        }
        for (auto& NC : not_checks) {
            CHECK(!NC.regex->Match(line)) << "Unexpected match for line \""
                                          << line << "\" for MR_Not regex \""
                                          << NC.regex_str << "\"";
        }
        if (TC.regex->Match(line)) return;
        CHECK(TC.match_rule != MR_Next) << "Expected line \"" << line
                                     << "\" to match regex \"" << TC.regex_str << "\"";
    }
    CHECK(remaining_output.eof() == false)
        << "End of output reached before match for regex \"" << TC.regex_str
        << "\" was found"
        << "\n    actual regex string \"" << TC.substituted_regex << "\""
        << "\n    started matching near: " << first_line;
}

void CheckCases(TestCaseList const& checks, std::stringstream& output) {
    std::vector<TestCase> not_checks;
    for (size_t i=0; i < checks.size(); ++i) {
        const auto& TC = checks[i];
        if (TC.match_rule == MR_Not) {
            not_checks.push_back(TC);
            continue;
        }
        CheckCase(output, TC, not_checks);
        not_checks.clear();
    }
}

class TestReporter : public benchmark::BenchmarkReporter {
public:
  TestReporter(std::vector<benchmark::BenchmarkReporter*> reps)
      : reporters_(reps)  {}

  virtual bool ReportContext(const Context& context) {
    bool last_ret = false;
    bool first = true;
    for (auto rep : reporters_) {
      bool new_ret = rep->ReportContext(context);
      CHECK(first || new_ret == last_ret)
          << "Reports return different values for ReportContext";
      first = false;
      last_ret = new_ret;
    }
    return last_ret;
  }

  void ReportRuns(const std::vector<Run>& report)
    { for (auto rep : reporters_) rep->ReportRuns(report); }
  void Finalize() { for (auto rep : reporters_) rep->Finalize(); }

private:
  std::vector<benchmark::BenchmarkReporter*> reporters_;
};

}} // end namespace internal

// ========================================================================= //
// -------------------------- Public API Definitions------------------------ //
// ========================================================================= //

TestCase::TestCase(std::string re, int rule)
    : regex_str(std::move(re)), match_rule(rule),
      substituted_regex(internal::PerformSubstitutions(regex_str)),
      regex(std::make_shared<benchmark::Regex>())
{
    std::string err_str;
    regex->Init(substituted_regex, &err_str);
    CHECK(err_str.empty())
        << "Could not construct regex \"" << substituted_regex << "\""
        << "\n    originally \"" << regex_str << "\""
        << "\n    got error: " << err_str;
}

int AddCases(TestCaseID ID, std::initializer_list<TestCase> il) {
    auto& L = internal::GetTestCaseList(ID);
    L.insert(L.end(), il);
    return 0;
}

int SetSubstitutions(std::initializer_list<std::pair<std::string, std::string>> il) {
    auto& subs = internal::GetSubstitutions();
    for (auto const& KV : il) {
        bool exists = false;
        for (auto& EKV : subs) {
            if (EKV.first == KV.first) {
                EKV.second = KV.second;
                exists = true;
                break;
            }
        }
        if (!exists) subs.push_back(KV);
    }
    return 0;
}

void RunOutputTests(int argc, char* argv[]) {
  using internal::GetTestCaseList;
  benchmark::Initialize(&argc, argv);
  benchmark::ConsoleReporter CR(benchmark::ConsoleReporter::OO_None);
  benchmark::JSONReporter JR;
  benchmark::CSVReporter CSVR;
  struct ReporterTest {
    const char* name;
    std::vector<TestCase>& output_cases;
    std::vector<TestCase>& error_cases;
    benchmark::BenchmarkReporter& reporter;
    std::stringstream out_stream;
    std::stringstream err_stream;

    ReporterTest(const char* n,
                 std::vector<TestCase>& out_tc,
                 std::vector<TestCase>& err_tc,
                 benchmark::BenchmarkReporter& br)
        : name(n), output_cases(out_tc), error_cases(err_tc), reporter(br) {
        reporter.SetOutputStream(&out_stream);
        reporter.SetErrorStream(&err_stream);
    }
  } TestCases[] = {
      {"ConsoleReporter", GetTestCaseList(TC_ConsoleOut),
                          GetTestCaseList(TC_ConsoleErr), CR},
      {"JSONReporter",    GetTestCaseList(TC_JSONOut),
                          GetTestCaseList(TC_JSONErr), JR},
      {"CSVReporter",     GetTestCaseList(TC_CSVOut),
                          GetTestCaseList(TC_CSVErr), CSVR},
  };

  // Create the test reporter and run the benchmarks.
  std::cout << "Running benchmarks...\n";
  internal::TestReporter test_rep({&CR, &JR, &CSVR});
  benchmark::RunSpecifiedBenchmarks(&test_rep);

  for (auto& rep_test : TestCases) {
      std::string msg = std::string("\nTesting ") + rep_test.name + " Output\n";
      std::string banner(msg.size() - 1, '-');
      std::cout << banner << msg << banner << "\n";

      std::cerr << rep_test.err_stream.str();
      std::cout << rep_test.out_stream.str();

      internal::CheckCases(rep_test.error_cases,rep_test.err_stream);
      internal::CheckCases(rep_test.output_cases, rep_test.out_stream);

      std::cout << "\n";
  }
}

<commit_msg>Improve diagnostic output for output tests.<commit_after>#include "output_test.h"
#include "../src/check.h" // NOTE: check.h is for internal use only!
#include "../src/re.h" // NOTE: re.h is for internal use only
#include <memory>
#include <map>
#include <iostream>
#include <sstream>

// ========================================================================= //
// ------------------------------ Internals -------------------------------- //
// ========================================================================= //
namespace internal { namespace {

using TestCaseList = std::vector<TestCase>;

// Use a vector because the order elements are added matters during iteration.
// std::map/unordered_map don't guarantee that.
// For example:
//  SetSubstitutions({{"%HelloWorld", "Hello"}, {"%Hello", "Hi"}});
//     Substitute("%HelloWorld") // Always expands to Hello.
using SubMap = std::vector<std::pair<std::string, std::string>>;

TestCaseList& GetTestCaseList(TestCaseID ID) {
    // Uses function-local statics to ensure initialization occurs
    // before first use.
    static TestCaseList lists[TC_NumID];
    return lists[ID];
}

SubMap& GetSubstitutions() {
    // Don't use 'dec_re' from header because it may not yet be initialized.
    static std::string dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?";
    static SubMap map = {
        {"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"},
        {"%int", "[ ]*[0-9]+"},
        {" %s ", "[ ]+"},
        {"%time", "[ ]*[0-9]{1,5} ns"},
        {"%console_report", "[ ]*[0-9]{1,5} ns [ ]*[0-9]{1,5} ns [ ]*[0-9]+"},
        {"%csv_report", "[0-9]+," + dec_re + "," + dec_re + ",ns,,,,,"}
    };
    return map;
}

std::string PerformSubstitutions(std::string source) {
    SubMap const& subs = GetSubstitutions();
    using SizeT = std::string::size_type;
    for (auto const& KV : subs) {
        SizeT pos;
        SizeT next_start = 0;
        while ((pos = source.find(KV.first, next_start)) != std::string::npos) {
            next_start = pos + KV.second.size();
            source.replace(pos, KV.first.size(), KV.second);
        }
    }
    return source;
}

void CheckCase(std::stringstream& remaining_output, TestCase const& TC,
               TestCaseList const& not_checks)
{
    std::string first_line;
    bool on_first = true;
    std::string line;
    while (remaining_output.eof() == false) {
        CHECK(remaining_output.good());
        std::getline(remaining_output, line);
        if (on_first) {
            first_line = line;
            on_first = false;
        }
        for (auto& NC : not_checks) {
            CHECK(!NC.regex->Match(line))
                << "Unexpected match for line \"" << line
                << "\" for MR_Not regex \"" << NC.regex_str << "\""
                << "\n    actual regex string \"" << TC.substituted_regex << "\""
                << "\n    started matching near: " << first_line;
        }
        if (TC.regex->Match(line)) return;
        CHECK(TC.match_rule != MR_Next)
            << "Expected line \"" << line << "\" to match regex \"" << TC.regex_str << "\""
            << "\n    actual regex string \"" << TC.substituted_regex << "\""
            << "\n    started matching near: " << first_line;
    }
    CHECK(remaining_output.eof() == false)
        << "End of output reached before match for regex \"" << TC.regex_str
        << "\" was found"
        << "\n    actual regex string \"" << TC.substituted_regex << "\""
        << "\n    started matching near: " << first_line;
}

void CheckCases(TestCaseList const& checks, std::stringstream& output) {
    std::vector<TestCase> not_checks;
    for (size_t i=0; i < checks.size(); ++i) {
        const auto& TC = checks[i];
        if (TC.match_rule == MR_Not) {
            not_checks.push_back(TC);
            continue;
        }
        CheckCase(output, TC, not_checks);
        not_checks.clear();
    }
}

class TestReporter : public benchmark::BenchmarkReporter {
public:
  TestReporter(std::vector<benchmark::BenchmarkReporter*> reps)
      : reporters_(reps)  {}

  virtual bool ReportContext(const Context& context) {
    bool last_ret = false;
    bool first = true;
    for (auto rep : reporters_) {
      bool new_ret = rep->ReportContext(context);
      CHECK(first || new_ret == last_ret)
          << "Reports return different values for ReportContext";
      first = false;
      last_ret = new_ret;
    }
    return last_ret;
  }

  void ReportRuns(const std::vector<Run>& report)
    { for (auto rep : reporters_) rep->ReportRuns(report); }
  void Finalize() { for (auto rep : reporters_) rep->Finalize(); }

private:
  std::vector<benchmark::BenchmarkReporter*> reporters_;
};

}} // end namespace internal

// ========================================================================= //
// -------------------------- Public API Definitions------------------------ //
// ========================================================================= //

TestCase::TestCase(std::string re, int rule)
    : regex_str(std::move(re)), match_rule(rule),
      substituted_regex(internal::PerformSubstitutions(regex_str)),
      regex(std::make_shared<benchmark::Regex>())
{
    std::string err_str;
    regex->Init(substituted_regex, &err_str);
    CHECK(err_str.empty())
        << "Could not construct regex \"" << substituted_regex << "\""
        << "\n    originally \"" << regex_str << "\""
        << "\n    got error: " << err_str;
}

int AddCases(TestCaseID ID, std::initializer_list<TestCase> il) {
    auto& L = internal::GetTestCaseList(ID);
    L.insert(L.end(), il);
    return 0;
}

int SetSubstitutions(std::initializer_list<std::pair<std::string, std::string>> il) {
    auto& subs = internal::GetSubstitutions();
    for (auto const& KV : il) {
        bool exists = false;
        for (auto& EKV : subs) {
            if (EKV.first == KV.first) {
                EKV.second = KV.second;
                exists = true;
                break;
            }
        }
        if (!exists) subs.push_back(KV);
    }
    return 0;
}

void RunOutputTests(int argc, char* argv[]) {
  using internal::GetTestCaseList;
  benchmark::Initialize(&argc, argv);
  benchmark::ConsoleReporter CR(benchmark::ConsoleReporter::OO_None);
  benchmark::JSONReporter JR;
  benchmark::CSVReporter CSVR;
  struct ReporterTest {
    const char* name;
    std::vector<TestCase>& output_cases;
    std::vector<TestCase>& error_cases;
    benchmark::BenchmarkReporter& reporter;
    std::stringstream out_stream;
    std::stringstream err_stream;

    ReporterTest(const char* n,
                 std::vector<TestCase>& out_tc,
                 std::vector<TestCase>& err_tc,
                 benchmark::BenchmarkReporter& br)
        : name(n), output_cases(out_tc), error_cases(err_tc), reporter(br) {
        reporter.SetOutputStream(&out_stream);
        reporter.SetErrorStream(&err_stream);
    }
  } TestCases[] = {
      {"ConsoleReporter", GetTestCaseList(TC_ConsoleOut),
                          GetTestCaseList(TC_ConsoleErr), CR},
      {"JSONReporter",    GetTestCaseList(TC_JSONOut),
                          GetTestCaseList(TC_JSONErr), JR},
      {"CSVReporter",     GetTestCaseList(TC_CSVOut),
                          GetTestCaseList(TC_CSVErr), CSVR},
  };

  // Create the test reporter and run the benchmarks.
  std::cout << "Running benchmarks...\n";
  internal::TestReporter test_rep({&CR, &JR, &CSVR});
  benchmark::RunSpecifiedBenchmarks(&test_rep);

  for (auto& rep_test : TestCases) {
      std::string msg = std::string("\nTesting ") + rep_test.name + " Output\n";
      std::string banner(msg.size() - 1, '-');
      std::cout << banner << msg << banner << "\n";

      std::cerr << rep_test.err_stream.str();
      std::cout << rep_test.out_stream.str();

      internal::CheckCases(rep_test.error_cases,rep_test.err_stream);
      internal::CheckCases(rep_test.output_cases, rep_test.out_stream);

      std::cout << "\n";
  }
}

<|endoftext|>