1 /*
2 * Copyright 2016 Nu-book Inc.
3 * Copyright 2016 ZXing authors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 
18 #include "PDFBoundingBox.h"
19 
20 #include <algorithm>
21 
22 namespace ZXing {
23 namespace Pdf417 {
24 
BoundingBox()25 BoundingBox::BoundingBox() {
26 	_imgWidth = _imgHeight = _minX = _maxX = _minY = _maxY = 0;
27 }
28 
29 bool
Create(int imgWidth,int imgHeight,const Nullable<ResultPoint> & topLeft,const Nullable<ResultPoint> & bottomLeft,const Nullable<ResultPoint> & topRight,const Nullable<ResultPoint> & bottomRight,BoundingBox & result)30 BoundingBox::Create(int imgWidth, int imgHeight, const Nullable<ResultPoint>& topLeft, const Nullable<ResultPoint>& bottomLeft, const Nullable<ResultPoint>& topRight, const Nullable<ResultPoint>& bottomRight, BoundingBox& result)
31 {
32 	if ((topLeft == nullptr && topRight == nullptr) ||
33 		(bottomLeft == nullptr && bottomRight == nullptr) ||
34 		(topLeft != nullptr && bottomLeft == nullptr) ||
35 		(topRight != nullptr && bottomRight == nullptr)) {
36 		return false;
37 	}
38 	result._imgWidth = imgWidth;
39 	result._imgHeight = imgHeight;
40 	result._topLeft = topLeft;
41 	result._bottomLeft = bottomLeft;
42 	result._topRight = topRight;
43 	result._bottomRight = bottomRight;
44 	result.calculateMinMaxValues();
45 	return true;
46 }
47 
48 void
calculateMinMaxValues()49 BoundingBox::calculateMinMaxValues()
50 {
51 	if (_topLeft == nullptr) {
52 		_topLeft = ResultPoint(0.f, _topRight.value().y());
53 		_bottomLeft = ResultPoint(0.f, _bottomRight.value().y());
54 	}
55 	else if (_topRight == nullptr) {
56 		_topRight = ResultPoint(static_cast<float>(_imgWidth - 1), _topLeft.value().y());
57 		_bottomRight = ResultPoint(static_cast<float>(_imgHeight - 1), _bottomLeft.value().y());
58 	}
59 
60 	_minX = static_cast<int>(std::min(_topLeft.value().x(), _bottomLeft.value().x()));
61 	_maxX = static_cast<int>(std::max(_topRight.value().x(), _bottomRight.value().x()));
62 	_minY = static_cast<int>(std::min(_topLeft.value().y(), _topRight.value().y()));
63 	_maxY = static_cast<int>(std::max(_bottomLeft.value().y(), _bottomRight.value().y()));
64 }
65 
66 bool
Merge(const Nullable<BoundingBox> & leftBox,const Nullable<BoundingBox> & rightBox,Nullable<BoundingBox> & result)67 BoundingBox::Merge(const Nullable<BoundingBox>& leftBox, const Nullable<BoundingBox>& rightBox, Nullable<BoundingBox>& result)
68 {
69 	if (leftBox == nullptr) {
70 		result = rightBox;
71 		return true;
72 	}
73 	if (rightBox == nullptr) {
74 		result = leftBox;
75 		return true;
76 	}
77 	BoundingBox box;
78 	if (Create(leftBox.value()._imgWidth, leftBox.value()._imgHeight, leftBox.value()._topLeft, leftBox.value()._bottomLeft, rightBox.value()._topRight, rightBox.value()._bottomRight, box)) {
79 		result = box;
80 		return true;
81 	}
82 	return false;
83 }
84 
85 bool
AddMissingRows(const BoundingBox & box,int missingStartRows,int missingEndRows,bool isLeft,BoundingBox & result)86 BoundingBox::AddMissingRows(const BoundingBox& box, int missingStartRows, int missingEndRows, bool isLeft, BoundingBox& result)
87 {
88 	auto newTopLeft = box._topLeft;
89 	auto newBottomLeft = box._bottomLeft;
90 	auto newTopRight = box._topRight;
91 	auto newBottomRight = box._bottomRight;
92 
93 	if (missingStartRows > 0) {
94 		auto top = isLeft ? box._topLeft : box._topRight;
95 		int newMinY = static_cast<int>(top.value().y()) - missingStartRows;
96 		if (newMinY < 0) {
97 			newMinY = 0;
98 		}
99 		ResultPoint newTop(top.value().x(), static_cast<float>(newMinY));
100 		if (isLeft) {
101 			newTopLeft = newTop;
102 		}
103 		else {
104 			newTopRight = newTop;
105 		}
106 	}
107 
108 	if (missingEndRows > 0) {
109 		auto bottom = isLeft ? box._bottomLeft : box._bottomRight;
110 		int newMaxY = (int)bottom.value().y() + missingEndRows;
111 		if (newMaxY >= box._imgHeight) {
112 			newMaxY = box._imgHeight - 1;
113 		}
114 		ResultPoint newBottom(bottom.value().x(), static_cast<float>(newMaxY));
115 		if (isLeft) {
116 			newBottomLeft = newBottom;
117 		}
118 		else {
119 			newBottomRight = newBottom;
120 		}
121 	}
122 
123 	return Create(box._imgWidth, box._imgHeight, newTopLeft, newBottomLeft, newTopRight, newBottomRight, result);
124 }
125 
126 } // Pdf417
127 } // ZXing
128