summaryrefslogtreecommitdiff
path: root/Client/Source/GUI/TextMeshGenerator.cpp
blob: 766a9b06b2d65a59ba9efe5dadac03b46bc35de1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "TextMeshGenerator.h"

// ¼ÆËãÒ»¸ö¹þÏ£Öµ
static uint32_t GetStrHash(const UnicodeString& str)
{
    if (str.length == 0)
        return 0;

    int len = str.length; 
    uint32_t hash = (uint32_t)len; // seed 
    size_t step = (len >> 5) + 1;
    for (int l = len; l >= step; l -= step)
    {
        unsigned short unicode = str.str[l - 1];
        unsigned char hicode = *((unsigned char*)&unicode);
        unsigned char locode = *(((unsigned char*)&unicode) + 1);
        hash = hash ^ ((hash << 5) + (hash >> 2) + hicode + locode);
    }
    return hash;
}

const UITextMesh* TextMeshGenerator::GetTextMesh(
    const UnicodeString& str
    , Font* font
    , int pixelSize
    , int lineHeight
    , Color32 col32
    , ETextAnchor anchor
    , ETextAlignment alignment
    , bool wordwrap
    , float preferred
){
    uint32_t hash = GetStrHash(str);
    UITextMeshList* tm = NULL;
    bool hasHash = m_TextMeshes.count(hash);
    if (hasHash)
    {
        tm = m_TextMeshes[hash];
        while (tm)
        {
            UITextMesh* mesh = tm->mesh;
            if (mesh->GetFont() != font
                || mesh->GetPixelSize() != pixelSize
                || mesh->GetLineHeight() != lineHeight
                || mesh->GetAnchor() != anchor
                || mesh->GetAlignment() != alignment
                || mesh->GetWordwrap() != wordwrap
                || mesh->GetPreferred() != preferred
                || mesh->GetColor() != col32
            ){
                tm = tm->next;
                continue;
            }
            const UnicodeString& content = mesh->GetContent();
            if (content.length != str.length)
            {
                tm = tm->next;
                continue;
            }
            if (memcmp(str.str, content.str, sizeof(character::Unicode) * str.length) == 0)
            {
                return tm->mesh;
            }
            tm = tm->next;
        }
    }
    tm = new UITextMeshList();
    try {
        tm->mesh = new UITextMesh(str, font, pixelSize, lineHeight, col32, anchor, alignment, wordwrap, preferred);
        log_info("Text", "New UITextMesh");
    }
    catch(TextMeshException& e) 
    {
        delete tm;
        throw;
    }
    if (hasHash)
    {
        UITextMeshList* list = m_TextMeshes[hash];
        tm->next = list; 
        m_TextMeshes[hash] = tm;
    }
    else
    {
        tm->next = NULL;
        m_TextMeshes.insert(std::pair<uint32_t, UITextMeshList*>(hash, tm));
    }
    return tm->mesh;
}