Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #ifndef CORE_FXCRT_FX_BIDI_H_
      8 #define CORE_FXCRT_FX_BIDI_H_
      9 
     10 #include <memory>
     11 #include <vector>
     12 
     13 #include "core/fxcrt/fx_string.h"
     14 #include "core/fxcrt/fx_system.h"
     15 
     16 #ifdef PDF_ENABLE_XFA
     17 #include "core/fxcrt/cfx_char.h"
     18 #endif  // PDF_ENABLE_XFA
     19 
     20 // Processes characters and group them into segments based on text direction.
     21 class CFX_BidiChar {
     22  public:
     23   enum Direction { NEUTRAL, LEFT, RIGHT };
     24   struct Segment {
     25     int32_t start;        // Start position.
     26     int32_t count;        // Character count.
     27     Direction direction;  // Segment direction.
     28   };
     29 
     30   CFX_BidiChar();
     31 
     32   // Append a character and classify it as left, right, or neutral.
     33   // Returns true if the character has a different direction than the
     34   // existing direction to indicate there is a segment to process.
     35   bool AppendChar(wchar_t wch);
     36 
     37   // Call this after the last character has been appended. AppendChar()
     38   // must not be called after this.
     39   // Returns true if there is still a segment to process.
     40   bool EndChar();
     41 
     42   // Call after a change in direction is indicated by the above to get
     43   // information about the segment to process.
     44   Segment GetSegmentInfo() const { return m_LastSegment; }
     45 
     46  private:
     47   void StartNewSegment(CFX_BidiChar::Direction direction);
     48 
     49   Segment m_CurrentSegment;
     50   Segment m_LastSegment;
     51 };
     52 
     53 class CFX_BidiString {
     54  public:
     55   using const_iterator = std::vector<CFX_BidiChar::Segment>::const_iterator;
     56 
     57   explicit CFX_BidiString(const WideString& str);
     58   ~CFX_BidiString();
     59 
     60   // Overall direction is always LEFT or RIGHT, never NEUTRAL.
     61   CFX_BidiChar::Direction OverallDirection() const {
     62     return m_eOverallDirection;
     63   }
     64 
     65   // Force the overall direction to be R2L regardless of what was detected.
     66   void SetOverallDirectionRight();
     67 
     68   wchar_t CharAt(size_t x) const { return m_Str[x]; }
     69   const_iterator begin() const { return m_Order.begin(); }
     70   const_iterator end() const { return m_Order.end(); }
     71 
     72  private:
     73   const WideString m_Str;
     74   std::unique_ptr<CFX_BidiChar> m_pBidiChar;
     75   std::vector<CFX_BidiChar::Segment> m_Order;
     76   CFX_BidiChar::Direction m_eOverallDirection;
     77 };
     78 
     79 #if PDF_ENABLE_XFA
     80 void FX_BidiLine(std::vector<CFX_Char>* chars, size_t iCount);
     81 #endif  // PDF_ENABLE_XFA
     82 
     83 #endif  // CORE_FXCRT_FX_BIDI_H_
     84