Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: core/src/fxcrt/fx_bidi.cpp

Issue 1682983002: Make fx_bidi sane. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Stray class decl. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/include/fxcrt/fx_bidi.h" 7 #include "core/include/fxcrt/fx_bidi.h"
8 #include "core/include/fxcrt/fx_ucd.h" 8 #include "core/include/fxcrt/fx_ucd.h"
9 9
10 CFX_BidiChar::CFX_BidiChar() 10 #include <algorithm>
11 : m_iCurStart(0),
12 m_iCurCount(0),
13 m_CurBidi(NEUTRAL),
14 m_iLastStart(0),
15 m_iLastCount(0),
16 m_LastBidi(NEUTRAL) {
17 }
18
19 CFX_BidiChar::~CFX_BidiChar() {
20 }
21 11
22 bool CFX_BidiChar::AppendChar(FX_WCHAR wch) { 12 bool CFX_BidiChar::AppendChar(FX_WCHAR wch) {
23 FX_DWORD dwProps = FX_GetUnicodeProperties(wch); 13 FX_DWORD dwProps = FX_GetUnicodeProperties(wch);
24 int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS; 14 int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
25 Direction bidi = NEUTRAL; 15 Direction direction = NEUTRAL;
26 switch (iBidiCls) { 16 switch (iBidiCls) {
27 case FX_BIDICLASS_L: 17 case FX_BIDICLASS_L:
28 case FX_BIDICLASS_AN: 18 case FX_BIDICLASS_AN:
29 case FX_BIDICLASS_EN: 19 case FX_BIDICLASS_EN:
30 bidi = LEFT; 20 direction = LEFT;
31 break; 21 break;
32 case FX_BIDICLASS_R: 22 case FX_BIDICLASS_R:
33 case FX_BIDICLASS_AL: 23 case FX_BIDICLASS_AL:
34 bidi = RIGHT; 24 direction = RIGHT;
35 break; 25 break;
36 } 26 }
37 27
38 bool bRet = (bidi != m_CurBidi); 28 bool bChangeDirection = (direction != m_CurrentSegment.direction);
39 if (bRet) { 29 if (bChangeDirection)
40 SaveCurrentStateToLastState(); 30 StartNewSegment(direction);
41 m_CurBidi = bidi; 31
42 } 32 m_CurrentSegment.count++;
43 m_iCurCount++; 33 return bChangeDirection;
44 return bRet;
45 } 34 }
46 35
47 bool CFX_BidiChar::EndChar() { 36 bool CFX_BidiChar::EndChar() {
48 SaveCurrentStateToLastState(); 37 StartNewSegment(NEUTRAL);
49 return m_iLastCount > 0; 38 return m_LastSegment.count > 0;
50 } 39 }
51 40
52 CFX_BidiChar::Direction CFX_BidiChar::GetBidiInfo(int32_t* iStart, 41 void CFX_BidiChar::StartNewSegment(CFX_BidiChar::Direction direction) {
53 int32_t* iCount) const { 42 m_LastSegment = m_CurrentSegment;
54 if (iStart) 43 m_CurrentSegment.start += m_CurrentSegment.count;
55 *iStart = m_iLastStart; 44 m_CurrentSegment.count = 0;
56 if (iCount) 45 m_CurrentSegment.direction = direction;
57 *iCount = m_iLastCount;
58 return m_LastBidi;
59 } 46 }
60 47
61 void CFX_BidiChar::SaveCurrentStateToLastState() { 48 CFX_BidiString::CFX_BidiString(const CFX_WideString& str)
62 m_LastBidi = m_CurBidi; 49 : m_Str(str),
63 m_iLastStart = m_iCurStart; 50 m_pBidiChar(new CFX_BidiChar),
64 m_iCurStart = m_iCurCount; 51 m_eOverallDirection(CFX_BidiChar::LEFT) {
65 m_iLastCount = m_iCurCount - m_iLastStart; 52 size_t nR2L = 0;
53 size_t nL2R = 0;
54 for (int i = 0; i < m_Str.GetLength(); ++i) {
55 if (m_pBidiChar->AppendChar(m_Str.GetAt(i))) {
56 m_Order.push_back(m_pBidiChar->GetSegmentInfo());
57 if (m_Order.back().direction == CFX_BidiChar::RIGHT)
58 nR2L++;
59 else if (m_Order.back().direction == CFX_BidiChar::LEFT)
60 nL2R++;
61 }
62 }
63 if (m_pBidiChar->EndChar()) {
64 m_Order.push_back(m_pBidiChar->GetSegmentInfo());
65 if (m_Order.back().direction == CFX_BidiChar::RIGHT)
Lei Zhang 2016/02/12 00:46:43 Maybe just push into |m_Order| and calculate |nR2L
Tom Sepez 2016/02/12 17:54:33 That's really clean.
66 nR2L++;
67 else if (m_Order.back().direction == CFX_BidiChar::LEFT)
68 nL2R++;
69 }
70 if (nR2L > 0 && nR2L >= nL2R)
71 SetOverallDirection(CFX_BidiChar::RIGHT);
66 } 72 }
73
74 void CFX_BidiString::SetOverallDirection(CFX_BidiChar::Direction eDirection) {
75 ASSERT(eDirection != CFX_BidiChar::NEUTRAL);
76 if (eDirection != m_eOverallDirection) {
77 std::reverse(m_Order.begin(), m_Order.end());
Tom Sepez 2016/02/11 18:25:58 Note: this is the key idea. Rather than forcing ou
Lei Zhang 2016/02/12 00:46:43 SGTM
78 m_eOverallDirection = eDirection;
79 }
80 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698