Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_UtilRSS.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_UtilRSS.h"\r
9 CBC_UtilRSS::CBC_UtilRSS()\r
10 {\r
11 }\r
12 CBC_UtilRSS::~CBC_UtilRSS()\r
13 {\r
14 }\r
15 CFX_Int32Array *CBC_UtilRSS::GetRssWidths(FX_INT32 val, FX_INT32 n, FX_INT32 elements, FX_INT32 maxWidth, FX_BOOL noNarrow)\r
16 {\r
17     CFX_Int32Array *iTemp =  FX_NEW CFX_Int32Array;\r
18     iTemp->SetSize(elements);\r
19     CBC_AutoPtr<CFX_Int32Array > widths(iTemp);\r
20     FX_INT32 bar;\r
21     FX_INT32 narrowMask = 0;\r
22     for (bar = 0; bar < elements - 1; bar++) {\r
23         narrowMask |= (1 << bar);\r
24         FX_INT32 elmWidth = 1;\r
25         FX_INT32 subVal;\r
26         while (TRUE) {\r
27             subVal = Combins(n - elmWidth - 1, elements - bar - 2);\r
28             if (noNarrow && (narrowMask == 0) &&\r
29                     (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\r
30                 subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2);\r
31             }\r
32             if (elements - bar - 1 > 1) {\r
33                 FX_INT32 lessVal = 0;\r
34                 for (FX_INT32 mxwElement = n - elmWidth - (elements - bar - 2);\r
35                         mxwElement > maxWidth;\r
36                         mxwElement--) {\r
37                     lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3);\r
38                 }\r
39                 subVal -= lessVal * (elements - 1 - bar);\r
40             } else if (n - elmWidth > maxWidth) {\r
41                 subVal--;\r
42             }\r
43             val -= subVal;\r
44             if (val < 0) {\r
45                 break;\r
46             }\r
47             elmWidth++;\r
48             narrowMask &= ~(1 << bar);\r
49         }\r
50         val += subVal;\r
51         n -= elmWidth;\r
52         (*widths)[bar] = elmWidth;\r
53     }\r
54     (*widths)[bar] = n;\r
55     return widths.release();\r
56 }\r
57 FX_INT32 CBC_UtilRSS::GetRSSvalue(CFX_Int32Array &widths, FX_INT32 maxWidth, FX_BOOL noNarrow)\r
58 {\r
59     FX_INT32 elements = widths.GetSize();\r
60     FX_INT32 n = 0;\r
61     for (FX_INT32 i = 0; i < elements; i++) {\r
62         n += widths[i];\r
63     }\r
64     FX_INT32 val = 0;\r
65     FX_INT32 narrowMask = 0;\r
66     for (FX_INT32 bar = 0; bar < elements - 1; bar++) {\r
67         FX_INT32 elmWidth;\r
68         for (elmWidth = 1, narrowMask |= (1 << bar);\r
69                 elmWidth < widths[bar];\r
70                 elmWidth++, narrowMask &= ~(1 << bar)) {\r
71             FX_INT32 subVal = Combins(n - elmWidth - 1, elements - bar - 2);\r
72             if (noNarrow && (narrowMask == 0) &&\r
73                     (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\r
74                 subVal -= Combins(n - elmWidth - (elements - bar),\r
75                                   elements - bar - 2);\r
76             }\r
77             if (elements - bar - 1 > 1) {\r
78                 FX_INT32 lessVal = 0;\r
79                 for (FX_INT32 mxwElement = n - elmWidth - (elements - bar - 2);\r
80                         mxwElement > maxWidth; mxwElement--) {\r
81                     lessVal += Combins(n - elmWidth - mxwElement - 1,\r
82                                        elements - bar - 3);\r
83                 }\r
84                 subVal -= lessVal * (elements - 1 - bar);\r
85             } else if (n - elmWidth > maxWidth) {\r
86                 subVal--;\r
87             }\r
88             val += subVal;\r
89         }\r
90         n -= elmWidth;\r
91     }\r
92     return val;\r
93 }\r
94 FX_INT32 CBC_UtilRSS::Combins(FX_INT32 n, FX_INT32 r)\r
95 {\r
96     FX_INT32 maxDenom;\r
97     FX_INT32 minDenom;\r
98     if (n - r > r) {\r
99         minDenom = r;\r
100         maxDenom = n - r;\r
101     } else {\r
102         minDenom = n - r;\r
103         maxDenom = r;\r
104     }\r
105     FX_INT32 val = 1;\r
106     FX_INT32 j = 1;\r
107     for (FX_INT32 i = n; i > maxDenom; i--) {\r
108         val *= i;\r
109         if (j <= minDenom) {\r
110             val /= j;\r
111             j++;\r
112         }\r
113     }\r
114     while (j <= minDenom) {\r
115         val /= j;\r
116         j++;\r
117     }\r
118     return val;\r
119 }\r
120 CFX_Int32Array *CBC_UtilRSS::Elements(CFX_Int32Array &eDist, FX_INT32 N, FX_INT32 K)\r
121 {\r
122     CFX_Int32Array *widths = FX_NEW CFX_Int32Array;\r
123     widths->SetSize(eDist.GetSize() + 2);\r
124     FX_INT32 twoK = K << 1;\r
125     (*widths)[0] = 1;\r
126     FX_INT32 i;\r
127     FX_INT32 minEven = 10;\r
128     FX_INT32 barSum = 1;\r
129     for (i = 1; i < twoK - 2; i += 2) {\r
130         (*widths)[i] = eDist[i - 1] - (*widths)[i - 1];\r
131         (*widths)[i + 1] = eDist[i] - (*widths)[i];\r
132         barSum += (*widths)[i] + (*widths)[i + 1];\r
133         if ((*widths)[i] < minEven) {\r
134             minEven = (*widths)[i];\r
135         }\r
136     }\r
137     (*widths)[twoK - 1] = N - barSum;\r
138     if ((*widths)[twoK - 1] < minEven) {\r
139         minEven = (*widths)[twoK - 1];\r
140     }\r
141     if (minEven > 1) {\r
142         for (i = 0; i < twoK; i += 2) {\r
143             (*widths)[i] += minEven - 1;\r
144             (*widths)[i + 1] -= minEven - 1;\r
145         }\r
146     }\r
147     return widths;\r
148 }\r