Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_TwoDimWriter.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_Writer.h"\r
9 #include "include/BC_CommonBitMatrix.h"\r
10 #include "include/BC_TwoDimWriter.h"\r
11 CBC_TwoDimWriter::CBC_TwoDimWriter()\r
12 {\r
13     m_iCorrectLevel             = 1;\r
14     m_bFixedSize                = TRUE;\r
15     m_output = NULL;\r
16 }\r
17 CBC_TwoDimWriter::~CBC_TwoDimWriter()\r
18 {\r
19     if (m_output != NULL) {\r
20         delete m_output;\r
21         m_output = NULL;\r
22     }\r
23 }\r
24 void CBC_TwoDimWriter::RenderDeviceResult(CFX_RenderDevice* device, const CFX_Matrix* matrix)\r
25 {\r
26     CFX_GraphStateData stateData;\r
27     CFX_PathData path;\r
28     path.AppendRect(0, 0, (FX_FLOAT)m_Width, (FX_FLOAT)m_Height);\r
29     device->DrawPath(&path, matrix, &stateData, m_backgroundColor, m_backgroundColor, FXFILL_ALTERNATE);\r
30     FX_INT32 leftPos = 0;\r
31     FX_INT32 topPos = 0;\r
32     if ( m_bFixedSize) {\r
33         leftPos = (m_Width - m_output->GetWidth()) / 2;\r
34         topPos = (m_Height - m_output->GetHeight()) / 2;\r
35     }\r
36     CFX_Matrix matri = *matrix;\r
37     if (m_Width < m_output->GetWidth() && m_Height < m_output->GetHeight()) {\r
38         CFX_Matrix matriScale((FX_FLOAT)m_Width / (FX_FLOAT)m_output->GetWidth(), 0.0, 0.0, (FX_FLOAT)m_Height / (FX_FLOAT)m_output->GetHeight(), 0.0, 0.0);\r
39         matriScale.Concat(*matrix);\r
40         matri = matriScale;\r
41     }\r
42     for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {\r
43         for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {\r
44             CFX_PathData rect;\r
45             rect.AppendRect((FX_FLOAT)leftPos + x, (FX_FLOAT)topPos + y, (FX_FLOAT)(leftPos + x + 1), (FX_FLOAT)(topPos + y + 1));\r
46             CFX_GraphStateData stateData;\r
47             if(m_output->Get(x, y)) {\r
48                 device->DrawPath(&rect, &matri, &stateData, m_barColor, 0, FXFILL_WINDING);\r
49             }\r
50         }\r
51     }\r
52 }\r
53 void CBC_TwoDimWriter::RenderBitmapResult(CFX_DIBitmap *&pOutBitmap, FX_INT32& e)\r
54 {\r
55     if (m_bFixedSize) {\r
56         pOutBitmap = CreateDIBitmap(m_Width, m_Height);\r
57     } else {\r
58         pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight());\r
59     }\r
60     if (!pOutBitmap) {\r
61         e = BCExceptionFailToCreateBitmap;\r
62         return;\r
63     }\r
64     pOutBitmap->Clear(m_backgroundColor);\r
65     FX_INT32 leftPos = 0;\r
66     FX_INT32 topPos = 0;\r
67     if ( m_bFixedSize) {\r
68         leftPos = (m_Width - m_output->GetWidth()) / 2;\r
69         topPos = (m_Height - m_output->GetHeight()) / 2;\r
70     }\r
71     for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {\r
72         for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {\r
73             if (m_output->Get(x, y)) {\r
74                 pOutBitmap->SetPixel(leftPos + x, topPos + y, m_barColor);\r
75             }\r
76         }\r
77     }\r
78     if (!m_bFixedSize) {\r
79         CFX_DIBitmap * pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height);\r
80         if (pOutBitmap) {\r
81             delete pOutBitmap;\r
82         }\r
83         pOutBitmap = pStretchBitmap;\r
84     }\r
85 }\r
86 void CBC_TwoDimWriter::RenderResult(FX_BYTE *code, FX_INT32 codeWidth, FX_INT32 codeHeight, FX_INT32 &e)\r
87 {\r
88     FX_INT32 inputWidth = codeWidth;\r
89     FX_INT32 inputHeight = codeHeight;\r
90     FX_INT32 tempWidth = inputWidth + (1 << 1);\r
91     FX_INT32 tempHeight = inputHeight + (1 << 1);\r
92     FX_FLOAT moduleHSize = (FX_FLOAT)FX_MIN(m_ModuleWidth, m_ModuleHeight);\r
93     if (moduleHSize > 8) {\r
94         moduleHSize = 8;\r
95     } else if (moduleHSize < 1) {\r
96         moduleHSize = 1;\r
97     }\r
98     FX_INT32 outputWidth = (FX_INT32)FX_MAX(tempWidth * moduleHSize, tempWidth);\r
99     FX_INT32 outputHeight = (FX_INT32)FX_MAX(tempHeight * moduleHSize, tempHeight);\r
100     FX_INT32 multiX = 1;\r
101     FX_INT32 multiY = 1;\r
102     if (m_bFixedSize) {\r
103         if (m_Width < outputWidth || m_Height < outputHeight) {\r
104             e = BCExceptionBitmapSizeError;\r
105             return;\r
106         }\r
107     } else {\r
108         if (m_Width > outputWidth || m_Height > outputHeight) {\r
109             outputWidth = (FX_INT32)(outputWidth * ceil ( (FX_FLOAT)m_Width / (FX_FLOAT)outputWidth));\r
110             outputHeight = (FX_INT32)(outputHeight * ceil ( (FX_FLOAT)m_Height / (FX_FLOAT)outputHeight));\r
111         }\r
112     }\r
113     multiX = (FX_INT32)ceil((FX_FLOAT)outputWidth / (FX_FLOAT)tempWidth);\r
114     multiY = (FX_INT32)ceil((FX_FLOAT)outputHeight / (FX_FLOAT) tempHeight);\r
115     if (m_bFixedSize) {\r
116         multiX = FX_MIN(multiX, multiY);\r
117         multiY = multiX;\r
118     }\r
119     FX_INT32 leftPadding = (outputWidth - (inputWidth * multiX)) / 2;\r
120     FX_INT32 topPadding = (outputHeight - (inputHeight * multiY)) / 2;\r
121     if (leftPadding < 0) {\r
122         leftPadding = 0;\r
123     }\r
124     if (topPadding < 0) {\r
125         topPadding = 0;\r
126     }\r
127     m_output = FX_NEW CBC_CommonBitMatrix;\r
128     m_output->Init(outputWidth, outputHeight);\r
129     for (FX_INT32 inputY = 0, outputY = topPadding; (inputY < inputHeight) && (outputY < outputHeight - multiY); inputY++, outputY += multiY) {\r
130         for (FX_INT32 inputX = 0, outputX = leftPadding; (inputX < inputWidth) && (outputX < outputWidth - multiX); inputX++, outputX += multiX) {\r
131             if (code[inputX + inputY * inputWidth] == 1) {\r
132                 m_output->SetRegion(outputX, outputY, multiX, multiY, e);\r
133                 BC_EXCEPTION_CHECK_ReturnVoid(e);\r
134             }\r
135         }\r
136     }\r
137 }\r