Merge "Move TypefaceUtils and ViewUtils to utils package"
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 017df34..be40c9d 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -112,32 +112,23 @@
         mIsUsed = true;
         mIsCachedForNextSuggestion = false;
         mDicNodeProperties.init(
-                NOT_A_DICT_POS, 0 /* flags */, rootGroupPos, NOT_A_DICT_POS /* attributesPos */,
+                NOT_A_DICT_POS, rootGroupPos, NOT_A_DICT_POS /* attributesPos */,
                 NOT_A_CODE_POINT /* nodeCodePoint */, NOT_A_PROBABILITY /* probability */,
-                false /* isTerminal */, true /* hasChildren */, 0 /* depth */,
-                0 /* terminalDepth */);
+                false /* isTerminal */, true /* hasChildren */,
+                false /* isBlacklistedOrNotAWord */, 0 /* depth */, 0 /* terminalDepth */);
         mDicNodeState.init(prevWordNodePos);
         PROF_NODE_RESET(mProfiler);
     }
 
-    void initAsPassingChild(DicNode *parentNode) {
-        mIsUsed = true;
-        mIsCachedForNextSuggestion = parentNode->mIsCachedForNextSuggestion;
-        const int c = parentNode->getNodeTypedCodePoint();
-        mDicNodeProperties.init(&parentNode->mDicNodeProperties, c);
-        mDicNodeState.init(&parentNode->mDicNodeState);
-        PROF_NODE_COPY(&parentNode->mProfiler, mProfiler);
-    }
-
     // Init for root with previous word
     void initAsRootWithPreviousWord(DicNode *dicNode, const int rootGroupPos) {
         mIsUsed = true;
         mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
         mDicNodeProperties.init(
-                NOT_A_DICT_POS,  0 /* flags */, rootGroupPos, NOT_A_DICT_POS /* attributesPos */,
+                NOT_A_DICT_POS, rootGroupPos, NOT_A_DICT_POS /* attributesPos */,
                 NOT_A_CODE_POINT /* nodeCodePoint */, NOT_A_PROBABILITY /* probability */,
-                false /* isTerminal */, true /* hasChildren */, 0 /* depth */,
-                0 /* terminalDepth */);
+                false /* isTerminal */, true /* hasChildren */,
+                false /* isBlacklistedOrNotAWord */,  0 /* depth */, 0 /* terminalDepth */);
         // TODO: Move to dicNodeState?
         mDicNodeState.mDicNodeStateOutput.init(); // reset for next word
         mDicNodeState.mDicNodeStateInput.init(
@@ -157,18 +148,27 @@
         PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
     }
 
-    // TODO: minimize arguments by looking binary_format
-    void initAsChild(DicNode *dicNode, const int pos, const uint8_t flags, const int childrenPos,
+    void initAsPassingChild(DicNode *parentNode) {
+        mIsUsed = true;
+        mIsCachedForNextSuggestion = parentNode->mIsCachedForNextSuggestion;
+        const int c = parentNode->getNodeTypedCodePoint();
+        mDicNodeProperties.init(&parentNode->mDicNodeProperties, c);
+        mDicNodeState.init(&parentNode->mDicNodeState);
+        PROF_NODE_COPY(&parentNode->mProfiler, mProfiler);
+    }
+
+    void initAsChild(DicNode *dicNode, const int pos, const int childrenPos,
             const int attributesPos, const int probability, const bool isTerminal,
-            const bool hasChildren, const uint16_t mergedNodeCodePointCount,
-            const int *const mergedNodeCodePoints) {
+            const bool hasChildren, const bool isBlacklistedOrNotAWord,
+            const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) {
         mIsUsed = true;
         uint16_t newDepth = static_cast<uint16_t>(dicNode->getNodeCodePointCount() + 1);
         mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
         const uint16_t newLeavingDepth = static_cast<uint16_t>(
                 dicNode->mDicNodeProperties.getLeavingDepth() + mergedNodeCodePointCount);
-        mDicNodeProperties.init(pos, flags, childrenPos, attributesPos, mergedNodeCodePoints[0],
-                probability, isTerminal, hasChildren, newDepth, newLeavingDepth);
+        mDicNodeProperties.init(pos, childrenPos, attributesPos, mergedNodeCodePoints[0],
+                probability, isTerminal, hasChildren, isBlacklistedOrNotAWord, newDepth,
+                newLeavingDepth);
         mDicNodeState.init(&dicNode->mDicNodeState, mergedNodeCodePointCount,
                 mergedNodeCodePoints);
         PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
@@ -216,7 +216,7 @@
     }
 
     bool isImpossibleBigramWord() const {
-        if (mDicNodeProperties.hasBlacklistedOrNotAWordFlag()) {
+        if (isBlacklistedOrNotAWord()) {
             return true;
         }
         const int prevWordLen = mDicNodeState.mDicNodeStatePrevWord.getPrevWordLength()
@@ -463,8 +463,8 @@
         return mDicNodeState.mDicNodeStateScoring.isExactMatch();
     }
 
-    uint8_t getFlags() const {
-        return mDicNodeProperties.getFlags();
+    bool isBlacklistedOrNotAWord() const {
+        return mDicNodeProperties.isBlacklistedOrNotAWord();
     }
 
     int getAttributesPos() const {
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_properties.h b/native/jni/src/suggest/core/dicnode/dic_node_properties.h
index 7e8aa49..d98000d 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_properties.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node_properties.h
@@ -20,7 +20,6 @@
 #include <stdint.h>
 
 #include "defines.h"
-#include "suggest/core/dictionary/binary_format.h"
 
 namespace latinime {
 
@@ -32,24 +31,25 @@
 class DicNodeProperties {
  public:
     AK_FORCE_INLINE DicNodeProperties()
-            : mPos(0), mFlags(0), mChildrenPos(0), mAttributesPos(0), mProbability(0),
-              mNodeCodePoint(0), mDepth(0), mLeavingDepth(0), mIsTerminal(false),
-              mHasChildren(false) {}
+            : mPos(0), mChildrenPos(0), mAttributesPos(0), mProbability(0),
+              mNodeCodePoint(0), mIsTerminal(false), mHasChildren(false),
+              mIsBlacklistedOrNotAWord(false), mDepth(0), mLeavingDepth(0) {}
 
     virtual ~DicNodeProperties() {}
 
     // Should be called only once per DicNode is initialized.
-    void init(const int pos, const uint8_t flags, const int childrenPos, const int attributesPos,
+    void init(const int pos, const int childrenPos, const int attributesPos,
             const int nodeCodePoint, const int probability, const bool isTerminal,
-            const bool hasChildren, const uint16_t depth, const uint16_t leavingDepth) {
+            const bool hasChildren, const bool isBlacklistedOrNotAWord,
+            const uint16_t depth, const uint16_t leavingDepth) {
         mPos = pos;
-        mFlags = flags;
         mChildrenPos = childrenPos;
         mAttributesPos = attributesPos;
         mNodeCodePoint = nodeCodePoint;
         mProbability = probability;
         mIsTerminal = isTerminal;
         mHasChildren = hasChildren;
+        mIsBlacklistedOrNotAWord = isBlacklistedOrNotAWord;
         mDepth = depth;
         mLeavingDepth = leavingDepth;
     }
@@ -57,13 +57,13 @@
     // Init for copy
     void init(const DicNodeProperties *const nodeProp) {
         mPos = nodeProp->mPos;
-        mFlags = nodeProp->mFlags;
         mChildrenPos = nodeProp->mChildrenPos;
         mAttributesPos = nodeProp->mAttributesPos;
         mNodeCodePoint = nodeProp->mNodeCodePoint;
         mProbability = nodeProp->mProbability;
         mIsTerminal = nodeProp->mIsTerminal;
         mHasChildren = nodeProp->mHasChildren;
+        mIsBlacklistedOrNotAWord = nodeProp->mIsBlacklistedOrNotAWord;
         mDepth = nodeProp->mDepth;
         mLeavingDepth = nodeProp->mLeavingDepth;
     }
@@ -71,13 +71,13 @@
     // Init as passing child
     void init(const DicNodeProperties *const nodeProp, const int codePoint) {
         mPos = nodeProp->mPos;
-        mFlags = nodeProp->mFlags;
         mChildrenPos = nodeProp->mChildrenPos;
         mAttributesPos = nodeProp->mAttributesPos;
         mNodeCodePoint = codePoint; // Overwrite the node char of a passing child
         mProbability = nodeProp->mProbability;
         mIsTerminal = nodeProp->mIsTerminal;
         mHasChildren = nodeProp->mHasChildren;
+        mIsBlacklistedOrNotAWord = nodeProp->mIsBlacklistedOrNotAWord;
         mDepth = nodeProp->mDepth + 1; // Increment the depth of a passing child
         mLeavingDepth = nodeProp->mLeavingDepth;
     }
@@ -86,10 +86,6 @@
         return mPos;
     }
 
-    uint8_t getFlags() const {
-        return mFlags;
-    }
-
     int getChildrenPos() const {
         return mChildrenPos;
     }
@@ -123,8 +119,8 @@
         return mHasChildren || mDepth != mLeavingDepth;
     }
 
-    bool hasBlacklistedOrNotAWordFlag() const {
-        return BinaryFormat::hasBlacklistedOrNotAWordFlag(mFlags);
+    bool isBlacklistedOrNotAWord() const {
+        return mIsBlacklistedOrNotAWord;
     }
 
  private:
@@ -132,15 +128,15 @@
     // Use a default copy constructor and an assign operator because shallow copies are ok
     // for this class
     int mPos;
-    uint8_t mFlags;
     int mChildrenPos;
     int mAttributesPos;
     int mProbability;
     int mNodeCodePoint;
-    uint16_t mDepth;
-    uint16_t mLeavingDepth;
     bool mIsTerminal;
     bool mHasChildren;
+    bool mIsBlacklistedOrNotAWord;
+    uint16_t mDepth;
+    uint16_t mLeavingDepth;
 };
 } // namespace latinime
 #endif // LATINIME_DIC_NODE_PROPERTIES_H
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
index c7c8d2a..6c7f666 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
@@ -78,6 +78,7 @@
     const bool isTerminal = (0 != (BinaryFormat::FLAG_IS_TERMINAL & flags));
     const bool hasChildren = BinaryFormat::hasChildrenInFlags(flags);
     const bool hasShortcuts = (0 != (BinaryFormat::FLAG_HAS_SHORTCUT_TARGETS & flags));
+    const bool isBlacklistedOrNotAWord = BinaryFormat::hasBlacklistedOrNotAWordFlag(flags);
 
     int codePoint = BinaryFormat::getCodePointAndForwardPointer(
             binaryDictionaryInfo->getDictRoot(), &pos);
@@ -111,8 +112,9 @@
     if (childrenFilter->isFilteredOut(mergedNodeCodePoints[0])) {
         return siblingPos;
     }
-    childDicNodes->pushLeavingChild(dicNode, nextPos, flags, childrenPos, attributesPos,
-            probability, isTerminal, hasChildren, mergedNodeCodePointCount, mergedNodeCodePoints);
+    childDicNodes->pushLeavingChild(dicNode, nextPos, childrenPos, attributesPos,
+            probability, isTerminal, hasChildren, isBlacklistedOrNotAWord,
+            mergedNodeCodePointCount, mergedNodeCodePoints);
     return siblingPos;
 }
 
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_vector.h b/native/jni/src/suggest/core/dicnode/dic_node_vector.h
index 9641cc1..5ac4eea 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_vector.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node_vector.h
@@ -62,14 +62,15 @@
         mDicNodes.back().initAsPassingChild(dicNode);
     }
 
-    void pushLeavingChild(DicNode *dicNode, const int pos, const uint8_t flags,
-            const int childrenPos, const int attributesPos, const int probability,
-            const bool isTerminal, const bool hasChildren, const uint16_t mergedNodeCodePointCount,
-            const int *const mergedNodeCodePoints) {
+    void pushLeavingChild(DicNode *dicNode, const int pos, const int childrenPos,
+            const int attributesPos, const int probability, const bool isTerminal,
+            const bool hasChildren, const bool isBlacklistedOrNotAWord,
+            const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) {
         ASSERT(!mLock);
         mDicNodes.push_back(mEmptyNode);
-        mDicNodes.back().initAsChild(dicNode, pos, flags, childrenPos, attributesPos, probability,
-                isTerminal, hasChildren, mergedNodeCodePointCount, mergedNodeCodePoints);
+        mDicNodes.back().initAsChild(dicNode, pos, childrenPos, attributesPos, probability,
+                isTerminal, hasChildren, isBlacklistedOrNotAWord, mergedNodeCodePointCount,
+                mergedNodeCodePoints);
     }
 
     DicNode *operator[](const int id) {
diff --git a/native/jni/src/suggest/core/dictionary/terminal_attributes.h b/native/jni/src/suggest/core/dictionary/terminal_attributes.h
index a8520b1..0da6504 100644
--- a/native/jni/src/suggest/core/dictionary/terminal_attributes.h
+++ b/native/jni/src/suggest/core/dictionary/terminal_attributes.h
@@ -21,7 +21,6 @@
 
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/binary_dictionary_terminal_attributes_reading_utils.h"
-#include "suggest/core/dictionary/binary_format.h"
 
 namespace latinime {
 
@@ -71,13 +70,12 @@
     };
 
     TerminalAttributes(const BinaryDictionaryInfo *const binaryDictionaryInfo,
-            const uint8_t nodeFlags, const int shortcutPos)
-            : mBinaryDictionaryInfo(binaryDictionaryInfo),
-              mNodeFlags(nodeFlags), mShortcutListSizePos(shortcutPos) {}
+            const int shortcutPos)
+            : mBinaryDictionaryInfo(binaryDictionaryInfo), mShortcutListSizePos(shortcutPos) {}
 
     inline ShortcutIterator getShortcutIterator() const {
         int shortcutPos = mShortcutListSizePos;
-        const bool hasShortcutList = 0 != (mNodeFlags & BinaryFormat::FLAG_HAS_SHORTCUT_TARGETS);
+        const bool hasShortcutList = shortcutPos != NOT_A_DICT_POS;
         if (hasShortcutList) {
             BinaryDictionaryTerminalAttributesReadingUtils::getShortcutListSizeAndForwardPointer(
                     mBinaryDictionaryInfo, &shortcutPos);
@@ -86,14 +84,9 @@
         return ShortcutIterator(mBinaryDictionaryInfo, shortcutPos, hasShortcutList);
     }
 
-    bool isBlacklistedOrNotAWord() const {
-        return BinaryFormat::hasBlacklistedOrNotAWordFlag(mNodeFlags);
-    }
-
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(TerminalAttributes);
     const BinaryDictionaryInfo *const mBinaryDictionaryInfo;
-    const uint8_t mNodeFlags;
     const int mShortcutListSizePos;
 };
 } // namespace latinime
diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp
index 9a0f10c..6e9aff5 100644
--- a/native/jni/src/suggest/core/suggest.cpp
+++ b/native/jni/src/suggest/core/suggest.cpp
@@ -173,8 +173,6 @@
                 terminalIndex, doubleLetterTerminalIndex, doubleLetterLevel);
         const float compoundDistance = terminalDicNode->getCompoundDistance(languageWeight)
                 + doubleLetterCost;
-        const TerminalAttributes terminalAttributes(traverseSession->getBinaryDictionaryInfo(),
-                terminalDicNode->getFlags(), terminalDicNode->getAttributesPos());
         const bool isPossiblyOffensiveWord = terminalDicNode->getProbability() <= 0;
         const bool isExactMatch = terminalDicNode->isExactMatch();
         const bool isFirstCharUppercase = terminalDicNode->isFirstCharUppercase();
@@ -187,7 +185,7 @@
                 | (isSafeExactMatch ? Dictionary::KIND_FLAG_EXACT_MATCH : 0);
 
         // Entries that are blacklisted or do not represent a word should not be output.
-        const bool isValidWord = !terminalAttributes.isBlacklistedOrNotAWord();
+        const bool isValidWord = !terminalDicNode->isBlacklistedOrNotAWord();
 
         // Increase output score of top typing suggestion to ensure autocorrection.
         // TODO: Better integration with java side autocorrection logic.
@@ -233,6 +231,8 @@
         }
 
         if (!terminalDicNode->hasMultipleWords()) {
+            const TerminalAttributes terminalAttributes(traverseSession->getBinaryDictionaryInfo(),
+                    terminalDicNode->getAttributesPos());
             // Shortcut is not supported for multiple words suggestions.
             // TODO: Check shortcuts during traversal for multiple words suggestions.
             const bool sameAsTyped = TRAVERSAL->sameAsTyped(traverseSession, terminalDicNode);