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"
9extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
10IFX_BidiChar* IFX_BidiChar::Create()
11{
12    return FX_NEW CFX_BidiChar;
13}
14CFX_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}
24FX_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}
64FX_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}
72FX_INT32 CFX_BidiChar::GetBidiInfo(FX_INT32 &iStart, FX_INT32 &iCount)
73{
74    iStart = m_iLastStart;
75    iCount = m_iLastCount;
76    return m_iLastBidi;
77}
78void 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