xref: /aosp_15_r20/external/pdfium/fxbarcode/oned/BC_OneDimWriter.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker // Original code is licensed as follows:
7*3ac0a46fSAndroid Build Coastguard Worker /*
8*3ac0a46fSAndroid Build Coastguard Worker  * Copyright 2011 ZXing authors
9*3ac0a46fSAndroid Build Coastguard Worker  *
10*3ac0a46fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
11*3ac0a46fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
12*3ac0a46fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
13*3ac0a46fSAndroid Build Coastguard Worker  *
14*3ac0a46fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
15*3ac0a46fSAndroid Build Coastguard Worker  *
16*3ac0a46fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
17*3ac0a46fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
18*3ac0a46fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19*3ac0a46fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
20*3ac0a46fSAndroid Build Coastguard Worker  * limitations under the License.
21*3ac0a46fSAndroid Build Coastguard Worker  */
22*3ac0a46fSAndroid Build Coastguard Worker 
23*3ac0a46fSAndroid Build Coastguard Worker #include "fxbarcode/oned/BC_OneDimWriter.h"
24*3ac0a46fSAndroid Build Coastguard Worker 
25*3ac0a46fSAndroid Build Coastguard Worker #include <math.h>
26*3ac0a46fSAndroid Build Coastguard Worker 
27*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
28*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
29*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
30*3ac0a46fSAndroid Build Coastguard Worker 
31*3ac0a46fSAndroid Build Coastguard Worker #include "build/build_config.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_defaultrenderdevice.h"
33*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_fillrenderoptions.h"
34*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_font.h"
35*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_graphstatedata.h"
36*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_path.h"
37*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_renderdevice.h"
38*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_unicodeencodingex.h"
39*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/text_char_pos.h"
40*3ac0a46fSAndroid Build Coastguard Worker #include "fxbarcode/BC_Writer.h"
41*3ac0a46fSAndroid Build Coastguard Worker 
42*3ac0a46fSAndroid Build Coastguard Worker // static
HasValidContentSize(WideStringView contents)43*3ac0a46fSAndroid Build Coastguard Worker bool CBC_OneDimWriter::HasValidContentSize(WideStringView contents) {
44*3ac0a46fSAndroid Build Coastguard Worker   // Limit the size of 1D barcodes. Typical 1D barcodes are short so this should
45*3ac0a46fSAndroid Build Coastguard Worker   // be sufficient for most use cases.
46*3ac0a46fSAndroid Build Coastguard Worker   static constexpr size_t kMaxInputLengthBytes = 8192;
47*3ac0a46fSAndroid Build Coastguard Worker 
48*3ac0a46fSAndroid Build Coastguard Worker   size_t size = contents.GetLength();
49*3ac0a46fSAndroid Build Coastguard Worker   return size > 0 && size <= kMaxInputLengthBytes;
50*3ac0a46fSAndroid Build Coastguard Worker }
51*3ac0a46fSAndroid Build Coastguard Worker 
52*3ac0a46fSAndroid Build Coastguard Worker CBC_OneDimWriter::CBC_OneDimWriter() = default;
53*3ac0a46fSAndroid Build Coastguard Worker 
54*3ac0a46fSAndroid Build Coastguard Worker CBC_OneDimWriter::~CBC_OneDimWriter() = default;
55*3ac0a46fSAndroid Build Coastguard Worker 
SetPrintChecksum(bool checksum)56*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetPrintChecksum(bool checksum) {
57*3ac0a46fSAndroid Build Coastguard Worker   m_bPrintChecksum = checksum;
58*3ac0a46fSAndroid Build Coastguard Worker }
59*3ac0a46fSAndroid Build Coastguard Worker 
SetDataLength(int32_t length)60*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetDataLength(int32_t length) {
61*3ac0a46fSAndroid Build Coastguard Worker   m_iDataLenth = length;
62*3ac0a46fSAndroid Build Coastguard Worker }
63*3ac0a46fSAndroid Build Coastguard Worker 
SetCalcChecksum(bool state)64*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetCalcChecksum(bool state) {
65*3ac0a46fSAndroid Build Coastguard Worker   m_bCalcChecksum = state;
66*3ac0a46fSAndroid Build Coastguard Worker }
67*3ac0a46fSAndroid Build Coastguard Worker 
SetFont(CFX_Font * cFont)68*3ac0a46fSAndroid Build Coastguard Worker bool CBC_OneDimWriter::SetFont(CFX_Font* cFont) {
69*3ac0a46fSAndroid Build Coastguard Worker   if (!cFont)
70*3ac0a46fSAndroid Build Coastguard Worker     return false;
71*3ac0a46fSAndroid Build Coastguard Worker 
72*3ac0a46fSAndroid Build Coastguard Worker   m_pFont = cFont;
73*3ac0a46fSAndroid Build Coastguard Worker   return true;
74*3ac0a46fSAndroid Build Coastguard Worker }
75*3ac0a46fSAndroid Build Coastguard Worker 
SetFontSize(float size)76*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetFontSize(float size) {
77*3ac0a46fSAndroid Build Coastguard Worker   m_fFontSize = size;
78*3ac0a46fSAndroid Build Coastguard Worker }
79*3ac0a46fSAndroid Build Coastguard Worker 
SetFontStyle(int32_t style)80*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetFontStyle(int32_t style) {
81*3ac0a46fSAndroid Build Coastguard Worker   m_iFontStyle = style;
82*3ac0a46fSAndroid Build Coastguard Worker }
83*3ac0a46fSAndroid Build Coastguard Worker 
SetFontColor(FX_ARGB color)84*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::SetFontColor(FX_ARGB color) {
85*3ac0a46fSAndroid Build Coastguard Worker   m_fontColor = color;
86*3ac0a46fSAndroid Build Coastguard Worker }
87*3ac0a46fSAndroid Build Coastguard Worker 
AppendPattern(pdfium::span<uint8_t> target,pdfium::span<const uint8_t> pattern,bool startColor)88*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<uint8_t> CBC_OneDimWriter::AppendPattern(
89*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<uint8_t> target,
90*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<const uint8_t> pattern,
91*3ac0a46fSAndroid Build Coastguard Worker     bool startColor) {
92*3ac0a46fSAndroid Build Coastguard Worker   bool color = startColor;
93*3ac0a46fSAndroid Build Coastguard Worker   size_t added = 0;
94*3ac0a46fSAndroid Build Coastguard Worker   size_t pos = 0;
95*3ac0a46fSAndroid Build Coastguard Worker   for (const int8_t pattern_value : pattern) {
96*3ac0a46fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < pattern_value; ++i)
97*3ac0a46fSAndroid Build Coastguard Worker       target[pos++] = color ? 1 : 0;
98*3ac0a46fSAndroid Build Coastguard Worker     added += pattern_value;
99*3ac0a46fSAndroid Build Coastguard Worker     color = !color;
100*3ac0a46fSAndroid Build Coastguard Worker   }
101*3ac0a46fSAndroid Build Coastguard Worker   return target.subspan(added);
102*3ac0a46fSAndroid Build Coastguard Worker }
103*3ac0a46fSAndroid Build Coastguard Worker 
CalcTextInfo(const ByteString & text,TextCharPos * charPos,CFX_Font * cFont,float geWidth,int32_t fontSize,float & charsLen)104*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::CalcTextInfo(const ByteString& text,
105*3ac0a46fSAndroid Build Coastguard Worker                                     TextCharPos* charPos,
106*3ac0a46fSAndroid Build Coastguard Worker                                     CFX_Font* cFont,
107*3ac0a46fSAndroid Build Coastguard Worker                                     float geWidth,
108*3ac0a46fSAndroid Build Coastguard Worker                                     int32_t fontSize,
109*3ac0a46fSAndroid Build Coastguard Worker                                     float& charsLen) {
110*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<CFX_UnicodeEncodingEx> encoding =
111*3ac0a46fSAndroid Build Coastguard Worker       FX_CreateFontEncodingEx(cFont);
112*3ac0a46fSAndroid Build Coastguard Worker 
113*3ac0a46fSAndroid Build Coastguard Worker   const size_t length = text.GetLength();
114*3ac0a46fSAndroid Build Coastguard Worker   std::vector<uint32_t> charcodes(length);
115*3ac0a46fSAndroid Build Coastguard Worker   float charWidth = 0;
116*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < length; ++i) {
117*3ac0a46fSAndroid Build Coastguard Worker     charcodes[i] = encoding->CharCodeFromUnicode(text[i]);
118*3ac0a46fSAndroid Build Coastguard Worker     int32_t glyph_code = encoding->GlyphFromCharCode(charcodes[i]);
119*3ac0a46fSAndroid Build Coastguard Worker     int glyph_value = cFont->GetGlyphWidth(glyph_code);
120*3ac0a46fSAndroid Build Coastguard Worker     float temp = glyph_value * fontSize / 1000.0;
121*3ac0a46fSAndroid Build Coastguard Worker     charWidth += temp;
122*3ac0a46fSAndroid Build Coastguard Worker   }
123*3ac0a46fSAndroid Build Coastguard Worker   charsLen = charWidth;
124*3ac0a46fSAndroid Build Coastguard Worker   float leftPositon = (float)(geWidth - charsLen) / 2.0f;
125*3ac0a46fSAndroid Build Coastguard Worker   if (leftPositon < 0 && geWidth == 0) {
126*3ac0a46fSAndroid Build Coastguard Worker     leftPositon = 0;
127*3ac0a46fSAndroid Build Coastguard Worker   }
128*3ac0a46fSAndroid Build Coastguard Worker   float penX = 0.0;
129*3ac0a46fSAndroid Build Coastguard Worker   float penY = (float)abs(cFont->GetDescent()) * (float)fontSize / 1000.0f;
130*3ac0a46fSAndroid Build Coastguard Worker   float left = leftPositon;
131*3ac0a46fSAndroid Build Coastguard Worker   float top = 0.0;
132*3ac0a46fSAndroid Build Coastguard Worker   charPos[0].m_Origin = CFX_PointF(penX + left, penY + top);
133*3ac0a46fSAndroid Build Coastguard Worker   charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charcodes[0]);
134*3ac0a46fSAndroid Build Coastguard Worker   charPos[0].m_FontCharWidth = cFont->GetGlyphWidth(charPos[0].m_GlyphIndex);
135*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
136*3ac0a46fSAndroid Build Coastguard Worker   charPos[0].m_ExtGID = charPos[0].m_GlyphIndex;
137*3ac0a46fSAndroid Build Coastguard Worker #endif
138*3ac0a46fSAndroid Build Coastguard Worker   penX += (float)(charPos[0].m_FontCharWidth) * (float)fontSize / 1000.0f;
139*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 1; i < length; i++) {
140*3ac0a46fSAndroid Build Coastguard Worker     charPos[i].m_Origin = CFX_PointF(penX + left, penY + top);
141*3ac0a46fSAndroid Build Coastguard Worker     charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charcodes[i]);
142*3ac0a46fSAndroid Build Coastguard Worker     charPos[i].m_FontCharWidth = cFont->GetGlyphWidth(charPos[i].m_GlyphIndex);
143*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
144*3ac0a46fSAndroid Build Coastguard Worker     charPos[i].m_ExtGID = charPos[i].m_GlyphIndex;
145*3ac0a46fSAndroid Build Coastguard Worker #endif
146*3ac0a46fSAndroid Build Coastguard Worker     penX += (float)(charPos[i].m_FontCharWidth) * (float)fontSize / 1000.0f;
147*3ac0a46fSAndroid Build Coastguard Worker   }
148*3ac0a46fSAndroid Build Coastguard Worker }
149*3ac0a46fSAndroid Build Coastguard Worker 
ShowDeviceChars(CFX_RenderDevice * device,const CFX_Matrix & matrix,const ByteString str,float geWidth,TextCharPos * pCharPos,float locX,float locY,int32_t barWidth)150*3ac0a46fSAndroid Build Coastguard Worker void CBC_OneDimWriter::ShowDeviceChars(CFX_RenderDevice* device,
151*3ac0a46fSAndroid Build Coastguard Worker                                        const CFX_Matrix& matrix,
152*3ac0a46fSAndroid Build Coastguard Worker                                        const ByteString str,
153*3ac0a46fSAndroid Build Coastguard Worker                                        float geWidth,
154*3ac0a46fSAndroid Build Coastguard Worker                                        TextCharPos* pCharPos,
155*3ac0a46fSAndroid Build Coastguard Worker                                        float locX,
156*3ac0a46fSAndroid Build Coastguard Worker                                        float locY,
157*3ac0a46fSAndroid Build Coastguard Worker                                        int32_t barWidth) {
158*3ac0a46fSAndroid Build Coastguard Worker   int32_t iFontSize = static_cast<int32_t>(fabs(m_fFontSize));
159*3ac0a46fSAndroid Build Coastguard Worker   int32_t iTextHeight = iFontSize + 1;
160*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rect((float)locX, (float)locY, (float)(locX + geWidth),
161*3ac0a46fSAndroid Build Coastguard Worker                      (float)(locY + iTextHeight));
162*3ac0a46fSAndroid Build Coastguard Worker   if (geWidth != m_Width) {
163*3ac0a46fSAndroid Build Coastguard Worker     rect.right -= 1;
164*3ac0a46fSAndroid Build Coastguard Worker   }
165*3ac0a46fSAndroid Build Coastguard Worker   FX_RECT re = matrix.TransformRect(rect).GetOuterRect();
166*3ac0a46fSAndroid Build Coastguard Worker   device->FillRect(re, kBackgroundColor);
167*3ac0a46fSAndroid Build Coastguard Worker   CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, (float)locX,
168*3ac0a46fSAndroid Build Coastguard Worker                            (float)(locY + iFontSize));
169*3ac0a46fSAndroid Build Coastguard Worker   affine_matrix.Concat(matrix);
170*3ac0a46fSAndroid Build Coastguard Worker   device->DrawNormalText(pdfium::make_span(pCharPos, str.GetLength()), m_pFont,
171*3ac0a46fSAndroid Build Coastguard Worker                          static_cast<float>(iFontSize), affine_matrix,
172*3ac0a46fSAndroid Build Coastguard Worker                          m_fontColor, GetTextRenderOptions());
173*3ac0a46fSAndroid Build Coastguard Worker }
174*3ac0a46fSAndroid Build Coastguard Worker 
ShowChars(WideStringView contents,CFX_RenderDevice * device,const CFX_Matrix & matrix,int32_t barWidth)175*3ac0a46fSAndroid Build Coastguard Worker bool CBC_OneDimWriter::ShowChars(WideStringView contents,
176*3ac0a46fSAndroid Build Coastguard Worker                                  CFX_RenderDevice* device,
177*3ac0a46fSAndroid Build Coastguard Worker                                  const CFX_Matrix& matrix,
178*3ac0a46fSAndroid Build Coastguard Worker                                  int32_t barWidth) {
179*3ac0a46fSAndroid Build Coastguard Worker   if (!device || !m_pFont)
180*3ac0a46fSAndroid Build Coastguard Worker     return false;
181*3ac0a46fSAndroid Build Coastguard Worker 
182*3ac0a46fSAndroid Build Coastguard Worker   ByteString str = FX_UTF8Encode(contents);
183*3ac0a46fSAndroid Build Coastguard Worker   std::vector<TextCharPos> charpos(str.GetLength());
184*3ac0a46fSAndroid Build Coastguard Worker   float charsLen = 0;
185*3ac0a46fSAndroid Build Coastguard Worker   float geWidth = 0;
186*3ac0a46fSAndroid Build Coastguard Worker   if (m_locTextLoc == BC_TEXT_LOC::kAboveEmbed ||
187*3ac0a46fSAndroid Build Coastguard Worker       m_locTextLoc == BC_TEXT_LOC::kBelowEmbed) {
188*3ac0a46fSAndroid Build Coastguard Worker     geWidth = 0;
189*3ac0a46fSAndroid Build Coastguard Worker   } else if (m_locTextLoc == BC_TEXT_LOC::kAbove ||
190*3ac0a46fSAndroid Build Coastguard Worker              m_locTextLoc == BC_TEXT_LOC::kBelow) {
191*3ac0a46fSAndroid Build Coastguard Worker     geWidth = (float)barWidth;
192*3ac0a46fSAndroid Build Coastguard Worker   }
193*3ac0a46fSAndroid Build Coastguard Worker   int32_t iFontSize = static_cast<int32_t>(fabs(m_fFontSize));
194*3ac0a46fSAndroid Build Coastguard Worker   int32_t iTextHeight = iFontSize + 1;
195*3ac0a46fSAndroid Build Coastguard Worker   CalcTextInfo(str, charpos.data(), m_pFont, geWidth, iFontSize, charsLen);
196*3ac0a46fSAndroid Build Coastguard Worker   if (charsLen < 1)
197*3ac0a46fSAndroid Build Coastguard Worker     return true;
198*3ac0a46fSAndroid Build Coastguard Worker 
199*3ac0a46fSAndroid Build Coastguard Worker   int32_t locX = 0;
200*3ac0a46fSAndroid Build Coastguard Worker   int32_t locY = 0;
201*3ac0a46fSAndroid Build Coastguard Worker   switch (m_locTextLoc) {
202*3ac0a46fSAndroid Build Coastguard Worker     case BC_TEXT_LOC::kAboveEmbed:
203*3ac0a46fSAndroid Build Coastguard Worker       locX = static_cast<int32_t>(barWidth - charsLen) / 2;
204*3ac0a46fSAndroid Build Coastguard Worker       locY = 0;
205*3ac0a46fSAndroid Build Coastguard Worker       geWidth = charsLen;
206*3ac0a46fSAndroid Build Coastguard Worker       break;
207*3ac0a46fSAndroid Build Coastguard Worker     case BC_TEXT_LOC::kAbove:
208*3ac0a46fSAndroid Build Coastguard Worker       locX = 0;
209*3ac0a46fSAndroid Build Coastguard Worker       locY = 0;
210*3ac0a46fSAndroid Build Coastguard Worker       geWidth = (float)barWidth;
211*3ac0a46fSAndroid Build Coastguard Worker       break;
212*3ac0a46fSAndroid Build Coastguard Worker     case BC_TEXT_LOC::kBelowEmbed:
213*3ac0a46fSAndroid Build Coastguard Worker       locX = static_cast<int32_t>(barWidth - charsLen) / 2;
214*3ac0a46fSAndroid Build Coastguard Worker       locY = m_Height - iTextHeight;
215*3ac0a46fSAndroid Build Coastguard Worker       geWidth = charsLen;
216*3ac0a46fSAndroid Build Coastguard Worker       break;
217*3ac0a46fSAndroid Build Coastguard Worker     case BC_TEXT_LOC::kBelow:
218*3ac0a46fSAndroid Build Coastguard Worker     default:
219*3ac0a46fSAndroid Build Coastguard Worker       locX = 0;
220*3ac0a46fSAndroid Build Coastguard Worker       locY = m_Height - iTextHeight;
221*3ac0a46fSAndroid Build Coastguard Worker       geWidth = (float)barWidth;
222*3ac0a46fSAndroid Build Coastguard Worker       break;
223*3ac0a46fSAndroid Build Coastguard Worker   }
224*3ac0a46fSAndroid Build Coastguard Worker   ShowDeviceChars(device, matrix, str, geWidth, charpos.data(), (float)locX,
225*3ac0a46fSAndroid Build Coastguard Worker                   (float)locY, barWidth);
226*3ac0a46fSAndroid Build Coastguard Worker   return true;
227*3ac0a46fSAndroid Build Coastguard Worker }
228*3ac0a46fSAndroid Build Coastguard Worker 
RenderDeviceResult(CFX_RenderDevice * device,const CFX_Matrix & matrix,WideStringView contents)229*3ac0a46fSAndroid Build Coastguard Worker bool CBC_OneDimWriter::RenderDeviceResult(CFX_RenderDevice* device,
230*3ac0a46fSAndroid Build Coastguard Worker                                           const CFX_Matrix& matrix,
231*3ac0a46fSAndroid Build Coastguard Worker                                           WideStringView contents) {
232*3ac0a46fSAndroid Build Coastguard Worker   if (m_output.empty())
233*3ac0a46fSAndroid Build Coastguard Worker     return false;
234*3ac0a46fSAndroid Build Coastguard Worker 
235*3ac0a46fSAndroid Build Coastguard Worker   CFX_GraphStateData stateData;
236*3ac0a46fSAndroid Build Coastguard Worker   CFX_Path path;
237*3ac0a46fSAndroid Build Coastguard Worker   path.AppendRect(0, 0, static_cast<float>(m_Width),
238*3ac0a46fSAndroid Build Coastguard Worker                   static_cast<float>(m_Height));
239*3ac0a46fSAndroid Build Coastguard Worker   device->DrawPath(path, &matrix, &stateData, kBackgroundColor,
240*3ac0a46fSAndroid Build Coastguard Worker                    kBackgroundColor, CFX_FillRenderOptions::EvenOddOptions());
241*3ac0a46fSAndroid Build Coastguard Worker   CFX_Matrix scaledMatrix(m_outputHScale, 0.0, 0.0,
242*3ac0a46fSAndroid Build Coastguard Worker                           static_cast<float>(m_Height), 0.0, 0.0);
243*3ac0a46fSAndroid Build Coastguard Worker   scaledMatrix.Concat(matrix);
244*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& rect : m_output) {
245*3ac0a46fSAndroid Build Coastguard Worker     CFX_GraphStateData data;
246*3ac0a46fSAndroid Build Coastguard Worker     device->DrawPath(rect, &scaledMatrix, &data, kBarColor, 0,
247*3ac0a46fSAndroid Build Coastguard Worker                      CFX_FillRenderOptions::WindingOptions());
248*3ac0a46fSAndroid Build Coastguard Worker   }
249*3ac0a46fSAndroid Build Coastguard Worker 
250*3ac0a46fSAndroid Build Coastguard Worker   return m_locTextLoc == BC_TEXT_LOC::kNone || !contents.Contains(' ') ||
251*3ac0a46fSAndroid Build Coastguard Worker          ShowChars(contents, device, matrix, m_barWidth);
252*3ac0a46fSAndroid Build Coastguard Worker }
253*3ac0a46fSAndroid Build Coastguard Worker 
RenderResult(WideStringView contents,pdfium::span<const uint8_t> code)254*3ac0a46fSAndroid Build Coastguard Worker bool CBC_OneDimWriter::RenderResult(WideStringView contents,
255*3ac0a46fSAndroid Build Coastguard Worker                                     pdfium::span<const uint8_t> code) {
256*3ac0a46fSAndroid Build Coastguard Worker   if (code.empty())
257*3ac0a46fSAndroid Build Coastguard Worker     return false;
258*3ac0a46fSAndroid Build Coastguard Worker 
259*3ac0a46fSAndroid Build Coastguard Worker   m_ModuleHeight = std::max(m_ModuleHeight, 20);
260*3ac0a46fSAndroid Build Coastguard Worker   const size_t original_codelength = code.size();
261*3ac0a46fSAndroid Build Coastguard Worker   const int32_t leftPadding = m_bLeftPadding ? 7 : 0;
262*3ac0a46fSAndroid Build Coastguard Worker   const int32_t rightPadding = m_bRightPadding ? 7 : 0;
263*3ac0a46fSAndroid Build Coastguard Worker   const size_t codelength = code.size() + leftPadding + rightPadding;
264*3ac0a46fSAndroid Build Coastguard Worker   m_outputHScale =
265*3ac0a46fSAndroid Build Coastguard Worker       m_Width > 0 ? static_cast<float>(m_Width) / static_cast<float>(codelength)
266*3ac0a46fSAndroid Build Coastguard Worker                   : 1.0;
267*3ac0a46fSAndroid Build Coastguard Worker   m_barWidth = m_Width;
268*3ac0a46fSAndroid Build Coastguard Worker 
269*3ac0a46fSAndroid Build Coastguard Worker   m_output.clear();
270*3ac0a46fSAndroid Build Coastguard Worker   m_output.reserve(original_codelength);
271*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < original_codelength; ++i) {
272*3ac0a46fSAndroid Build Coastguard Worker     if (code[i] != 1)
273*3ac0a46fSAndroid Build Coastguard Worker       continue;
274*3ac0a46fSAndroid Build Coastguard Worker 
275*3ac0a46fSAndroid Build Coastguard Worker     size_t output_index = i + leftPadding;
276*3ac0a46fSAndroid Build Coastguard Worker     if (output_index >= codelength)
277*3ac0a46fSAndroid Build Coastguard Worker       return true;
278*3ac0a46fSAndroid Build Coastguard Worker 
279*3ac0a46fSAndroid Build Coastguard Worker     m_output.emplace_back();
280*3ac0a46fSAndroid Build Coastguard Worker     m_output.back().AppendRect(output_index, 0.0f, output_index + 1, 1.0f);
281*3ac0a46fSAndroid Build Coastguard Worker   }
282*3ac0a46fSAndroid Build Coastguard Worker   return true;
283*3ac0a46fSAndroid Build Coastguard Worker }
284