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 #include "../../include/fxcrt/fx_ext.h"
8 #include "fx_arabic.h"
9 extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
Create()10 IFX_BidiChar* IFX_BidiChar::Create()
11 {
12     return new CFX_BidiChar;
13 }
CFX_BidiChar()14 CFX_BidiChar::CFX_BidiChar()
15     : m_bSeparateNeutral(TRUE)
16     , m_iCurStart(0)
17     , m_iCurCount(0)
18     , m_iCurBidi(0)
19     , m_iLastBidi(0)
20     , m_iLastStart(0)
21     , m_iLastCount(0)
22 {
23 }
AppendChar(FX_WCHAR wch)24 FX_BOOL CFX_BidiChar::AppendChar(FX_WCHAR wch)
25 {
26     FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
27     FX_INT32 iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
28     FX_INT32 iContext = 0;
29     switch (iBidiCls) {
30         case FX_BIDICLASS_L:
31         case FX_BIDICLASS_AN:
32         case FX_BIDICLASS_EN:
33             iContext = 1;
34             break;
35         case FX_BIDICLASS_R:
36         case FX_BIDICLASS_AL:
37             iContext = 2;
38             break;
39     }
40     FX_BOOL bRet = FALSE;
41     if (iContext != m_iCurBidi) {
42         if (m_bSeparateNeutral) {
43             bRet = TRUE;
44         } else {
45             if (m_iCurBidi == 0) {
46                 bRet = (m_iCurCount > 0);
47             } else {
48                 bRet = (iContext != 0);
49             }
50         }
51         if (bRet) {
52             m_iLastBidi = m_iCurBidi;
53             m_iLastStart = m_iCurStart;
54             m_iCurStart = m_iCurCount;
55             m_iLastCount = m_iCurCount - m_iLastStart;
56         }
57         if (m_bSeparateNeutral || iContext != 0) {
58             m_iCurBidi = iContext;
59         }
60     }
61     m_iCurCount ++;
62     return bRet;
63 }
EndChar()64 FX_BOOL CFX_BidiChar::EndChar()
65 {
66     m_iLastBidi = m_iCurBidi;
67     m_iLastStart = m_iCurStart;
68     m_iCurStart = m_iCurCount;
69     m_iLastCount = m_iCurCount - m_iLastStart;
70     return m_iLastCount > 0;
71 }
GetBidiInfo(FX_INT32 & iStart,FX_INT32 & iCount)72 FX_INT32 CFX_BidiChar::GetBidiInfo(FX_INT32 &iStart, FX_INT32 &iCount)
73 {
74     iStart = m_iLastStart;
75     iCount = m_iLastCount;
76     return m_iLastBidi;
77 }
Reset()78 void CFX_BidiChar::Reset()
79 {
80     m_iCurStart = 0;
81     m_iCurCount = 0;
82     m_iCurBidi = 0;
83     m_iLastBidi = 0;
84     m_iLastStart = 0;
85     m_iLastCount = 0;
86 }
87