Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_PDF417Writer.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "barcode.h"\r
8 #include "include/BC_TwoDimWriter.h"\r
9 #include "include/BC_PDF417Compaction.h"\r
10 #include "include/BC_PDF417.h"\r
11 #include "include/BC_PDF417BarcodeMatrix.h"\r
12 #include "include/BC_CommonBitArray.h"\r
13 #include "include/BC_CommonBitMatrix.h"\r
14 #include "include/BC_PDF417Writer.h"\r
15 CBC_PDF417Writer::CBC_PDF417Writer()\r
16 {\r
17     m_bFixedSize = FALSE;\r
18 }\r
19 CBC_PDF417Writer::~CBC_PDF417Writer()\r
20 {\r
21     m_bTruncated = TRUE;\r
22 }\r
23 FX_BOOL CBC_PDF417Writer:: SetErrorCorrectionLevel(FX_INT32 level)\r
24 {\r
25     if (level < 0 || level > 8) {\r
26         return FALSE;\r
27     }\r
28     m_iCorrectLevel = level;\r
29     return TRUE;\r
30 }\r
31 void CBC_PDF417Writer::SetTruncated(FX_BOOL truncated)\r
32 {\r
33     m_bTruncated = truncated;\r
34 }\r
35 FX_BYTE* CBC_PDF417Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)\r
36 {\r
37     if ( format != BCFORMAT_PDF_417) {\r
38         return NULL;\r
39     }\r
40     CFX_WideString encodeContents = contents.UTF8Decode();\r
41     return Encode(encodeContents, outWidth, outHeight, e );\r
42 }\r
43 FX_BYTE* CBC_PDF417Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)\r
44 {\r
45     return NULL;\r
46 }\r
47 FX_BYTE* CBC_PDF417Writer::Encode(const CFX_WideString &contents, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)\r
48 {\r
49     CBC_PDF417 encoder;\r
50     FX_INT32 col = (m_Width / m_ModuleWidth - 69) / 17;\r
51     FX_INT32 row = m_Height / (m_ModuleWidth * 20);\r
52     if (row >= 3 && row <= 90 && col >= 1 && col <= 30) {\r
53         encoder.setDimensions(col, col, row, row);\r
54     } else if (col >= 1 && col <= 30) {\r
55         encoder.setDimensions(col, col, 90, 3);\r
56     } else if (row >= 3 && row <= 90) {\r
57         encoder.setDimensions(30, 1, row, row);\r
58     }\r
59     encoder.generateBarcodeLogic(contents, m_iCorrectLevel, e);\r
60     BC_EXCEPTION_CHECK_ReturnValue(e,  NULL);\r
61     FX_INT32 lineThickness = 2;\r
62     FX_INT32 aspectRatio = 4;\r
63     CBC_BarcodeMatrix* barcodeMatrix = encoder.getBarcodeMatrix();\r
64     CFX_ByteArray originalScale;\r
65     originalScale.Copy(barcodeMatrix->getScaledMatrix(lineThickness, aspectRatio * lineThickness));\r
66     FX_INT32 width = outWidth;\r
67     FX_INT32 height = outHeight;\r
68     outWidth = barcodeMatrix->getWidth();\r
69     outHeight = barcodeMatrix->getHeight();\r
70     FX_BOOL rotated = FALSE;\r
71     if ((height > width) ^ (outWidth < outHeight)) {\r
72         rotateArray(originalScale, outHeight, outWidth);\r
73         rotated = TRUE;\r
74         FX_INT32 temp = outHeight;\r
75         outHeight = outWidth;\r
76         outWidth = temp;\r
77     }\r
78     FX_INT32 scaleX = width / outWidth;\r
79     FX_INT32 scaleY = height / outHeight;\r
80     FX_INT32 scale;\r
81     if (scaleX < scaleY) {\r
82         scale = scaleX;\r
83     } else {\r
84         scale = scaleY;\r
85     }\r
86     if (scale > 1) {\r
87         originalScale.RemoveAll();\r
88         originalScale.Copy(barcodeMatrix->getScaledMatrix(scale * lineThickness, scale * aspectRatio * lineThickness));\r
89         if (rotated) {\r
90             rotateArray(originalScale, outHeight, outWidth);\r
91             FX_INT32 temp = outHeight;\r
92             outHeight = outWidth;\r
93             outWidth = temp;\r
94         }\r
95     }\r
96     FX_BYTE* result = (FX_BYTE*)FX_Alloc(FX_BYTE, outHeight * outWidth);\r
97     FXSYS_memcpy32(result, originalScale.GetData(), outHeight * outWidth);\r
98     return result;\r
99 }\r
100 void CBC_PDF417Writer::rotateArray(CFX_ByteArray& bitarray, FX_INT32 height, FX_INT32 width)\r
101 {\r
102     CFX_ByteArray temp;\r
103     temp.Copy(bitarray);\r
104     for (FX_INT32 ii = 0; ii < height; ii++) {\r
105         FX_INT32 inverseii = height - ii - 1;\r
106         for (FX_INT32 jj = 0; jj < width; jj++) {\r
107             bitarray[jj * height + inverseii] = temp[ii * width + jj];\r
108         }\r
109     }\r
110 }\r