]> Shamusworld >> Repos - architektonas/blob - src/base/rs_fontlist.cpp
35590c27c9fda3295e413074f7cd694942db0e4c
[architektonas] / src / base / rs_fontlist.cpp
1 // rs_fontlist.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/27/2010  Added this text. :-)
13 //
14
15 #include "rs_fontlist.h"
16
17 #include "rs_font.h"
18 #include "rs_entity.h"
19 #include "rs_system.h"
20
21 //[DONE] #warning "!!! NEED TO FIX ITERATORS IN THIS CLASS !!!"
22
23 RS_FontList * RS_FontList::uniqueInstance = NULL;
24
25 /**
26  * Default constructor.
27  */
28 RS_FontList::RS_FontList(): fontIterator(fonts)
29 {
30 //Dealt with here...
31 //#warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
32 //      fonts.setAutoDelete(true);
33         //fontListListeners.setAutoDelete(false);
34 }
35
36 /*static*/ RS_FontList * RS_FontList::instance()
37 {
38         if (uniqueInstance == NULL)
39                 uniqueInstance = new RS_FontList();
40
41         return uniqueInstance;
42 }
43
44 RS_FontList::~RS_FontList()
45 {
46         clearFonts();
47 }
48
49 /**
50  * Initializes the font list by creating empty RS_Font
51  * objects, one for each font that could be found.
52  */
53 void RS_FontList::init()
54 {
55         RS_DEBUG->print("RS_FontList::initFonts");
56
57         QStringList list = RS_SYSTEM->getFontList();
58 //      Q3Dict<char> added; //used to remeber added fonts (avoid duplication)
59         QMultiHash<QString, char *> added; //used to remeber added fonts (avoid duplication)
60
61         for(QStringList::Iterator it=list.begin(); it!=list.end(); ++it)
62         {
63                 RS_DEBUG->print("font: %s:", (*it).toLatin1().data());
64 //printf("RS_FontList::init(): font: %s:\n", (*it).toLatin1().data());
65
66                 QFileInfo fi(*it);
67
68 //              if (!added[fi.baseName()])
69                 if (added.value(fi.baseName()) == 0)
70                 {
71                         RS_Font * font = new RS_Font(fi.baseName());
72                         fonts.append(font);
73                         added.insert(fi.baseName(), (char *)1);
74                 }
75
76                 RS_DEBUG->print("base: %s", fi.baseName().toLatin1().data());
77         }
78 }
79
80 /**
81  * Removes all fonts in the fontlist.
82  */
83 void RS_FontList::clearFonts()
84 {
85 //      fonts.clear();
86         while (!fonts.isEmpty())
87                 delete fonts.takeFirst();
88 }
89
90 int RS_FontList::countFonts()
91 {
92         return fonts.count();
93 }
94
95 /**
96  * Removes a font from the list.
97  * Listeners are notified after the font was removed from
98  * the list but before it gets deleted.
99  */
100 void RS_FontList::removeFont(RS_Font * font)
101 {
102         RS_DEBUG->print("RS_FontList::removeFont()");
103
104         // here the font is removed from the list but not deleted
105 //      fonts.remove(font);
106         // Here we have to delete this ourselves, because there is no AutoDelete
107         // for QLists
108         int i = fonts.indexOf(font);
109
110         if (i != -1)
111                 delete fonts.takeAt(i);
112
113         //for (uint i=0; i<fontListListeners.count(); ++i) {
114         //    RS_FontListListener* l = fontListListeners.at(i);
115         //    l->fontRemoved(font);
116         //}
117 }
118
119 /**
120  * @return Pointer to the font with the given name or
121  * \p NULL if no such font was found. The font will be loaded into
122  * memory if it's not already.
123  */
124 RS_Font * RS_FontList::requestFont(const QString & name)
125 {
126         RS_DEBUG->print("RS_FontList::requestFont %s",  name.toLatin1().data());
127
128         QString name2 = name.toLower();
129         RS_Font * foundFont = NULL;
130
131         // QCad 1 compatibility:
132         if (name2.contains('#') && name2.contains('_'))
133 //              name2 = name2.left(name2.find('_'));
134                 name2 = name2.left(name2.indexOf('_'));
135         else if (name2.contains('#'))
136 //              name2 = name2.left(name2.find('#'));
137                 name2 = name2.left(name2.indexOf('#'));
138
139         RS_DEBUG->print("name2: %s", name2.toLatin1().data());
140
141         // Search our list of available fonts:
142 //      for(RS_Font * f=fonts.first(); f!=NULL; f=fonts.next())
143         for(int i=0; i<fonts.size(); i++)
144         {
145                 RS_Font * f = fonts[i];
146
147                 if (f->getFileName() == name2)
148                 {
149                         // Make sure this font is loaded into memory:
150                         f->loadFont();
151                         foundFont = f;
152                         break;
153                 }
154         }
155
156         if (foundFont == NULL && name != "standard")
157                 foundFont = requestFont("standard");
158
159         return foundFont;
160 }
161
162 //! @return First font of the list.
163 RS_Font * RS_FontList::firstFont()
164 {
165 //      return fonts.first();
166 //      fontIterator.toFront();
167 //      return fontIterator.next();
168
169         fontIterator = fonts;
170         return (fontIterator.hasNext() ? fontIterator.next() : NULL);
171 }
172
173 /**
174  * @return Next font from the list after
175  * calling firstFont() or nextFont().
176  */
177 RS_Font * RS_FontList::nextFont()
178 {
179 //      return fonts.next();
180 //      return fontIterator.next();
181         return (fontIterator.hasNext() ? fontIterator.next() : NULL);
182 }
183
184 /**
185  * Dumps the fonts to stdout.
186  */
187 std::ostream & operator<<(std::ostream & os, RS_FontList & l)
188 {
189         os << "Fontlist: \n";
190
191         for(RS_Font * f=l.firstFont(); f!=NULL; f=l.nextFont())
192                 os << *f << "\n";
193
194         return os;
195 }