00001 #include <qapplication.h>
00002
00003 #include "mythcontext.h"
00004 #include "mythfontproperties.h"
00005 #include "mythmainwindow.h"
00006
00007
00008 #include "uitypes.h"
00009
00010 MythFontProperties::MythFontProperties() :
00011 m_color(QColor(Qt::white)), m_hasShadow(false), m_shadowAlpha(255),
00012 m_hasOutline(false), m_outlineAlpha(255), m_bFreeze(false)
00013 {
00014 CalcHash();
00015 }
00016
00017 void MythFontProperties::SetFace(const QFont &face)
00018 {
00019 m_face = face;
00020 CalcHash();
00021 }
00022
00023 void MythFontProperties::SetColor(const QColor &color)
00024 {
00025 m_color = color;
00026 CalcHash();
00027 }
00028
00029 void MythFontProperties::SetShadow(bool on, const QPoint &offset,
00030 const QColor &color, int alpha)
00031 {
00032 m_hasShadow = on;
00033 m_shadowOffset = offset;
00034 m_shadowColor = color;
00035 m_shadowAlpha = alpha;
00036 CalcHash();
00037 }
00038
00039 void MythFontProperties::SetOutline(bool on, const QColor &color,
00040 int size, int alpha)
00041 {
00042 m_hasOutline = on;
00043 m_outlineColor = color;
00044 m_outlineSize = size;
00045 m_outlineAlpha = alpha;
00046 CalcHash();
00047 }
00048
00049 void MythFontProperties::GetShadow(QPoint &offset, QColor &color, int &alpha) const
00050 {
00051 offset = m_shadowOffset;
00052 color = m_shadowColor;
00053 alpha = m_shadowAlpha;
00054 }
00055
00056 void MythFontProperties::GetOutline(QColor &color, int &size, int &alpha) const
00057 {
00058 color = m_outlineColor;
00059 size = m_outlineSize;
00060 alpha = m_outlineAlpha;
00061 }
00062
00063 void MythFontProperties::CalcHash(void)
00064 {
00065 if (m_bFreeze)
00066 return;
00067
00068 m_hash = QString("%1%2%3%4").arg(m_face.toString())
00069 .arg(m_color.name()).arg(m_hasShadow).arg(m_hasOutline);
00070
00071 if (m_hasShadow)
00072 m_hash += QString("%1%2%3%4").arg(m_shadowOffset.x())
00073 .arg(m_shadowOffset.y()).arg(m_shadowColor.name())
00074 .arg(m_shadowAlpha);
00075
00076 if (m_hasOutline)
00077 m_hash += QString("%1%2%3").arg(m_outlineColor.name())
00078 .arg(m_outlineSize).arg(m_outlineAlpha);
00079 }
00080
00081 void MythFontProperties::Freeze(void)
00082 {
00083 m_bFreeze = true;
00084 }
00085
00086 void MythFontProperties::Unfreeze(void)
00087 {
00088 m_bFreeze = false;
00089 CalcHash();
00090 }
00091
00092 MythFontProperties *MythFontProperties::ParseFromXml(QDomElement &element,
00093 bool addToGlobal)
00094 {
00095
00096 QString fontSizeType = gContext->GetSetting("ThemeFontSizeType", "default");
00097
00098 bool fromBase = false;
00099 MythFontProperties *newFont = new MythFontProperties();
00100 newFont->Freeze();
00101
00102 QString name = element.attribute("name", "");
00103 if (name.isNull() || name.isEmpty())
00104 {
00105 VERBOSE(VB_IMPORTANT, "Font needs a name");
00106 return NULL;
00107 }
00108
00109 if (addToGlobal && GetGlobalFontMap()->Contains(name))
00110 {
00111 VERBOSE(VB_IMPORTANT, QString("Error, already have a "
00112 "global font called: %1").arg(name));
00113 return NULL;
00114 }
00115
00116 QString base = element.attribute("base", "");
00117 if (!base.isNull() && !base.isEmpty())
00118 {
00119 MythFontProperties *tmp = GetGlobalFontMap()->GetFont(base);
00120 if (!tmp)
00121 {
00122 VERBOSE(VB_IMPORTANT,
00123 QString("Specified base font '%1' does not "
00124 "exist for font %2").arg(base).arg(name));
00125 return NULL;
00126 }
00127
00128 *newFont = *tmp;
00129 fromBase = true;
00130 }
00131
00132 int size, sizeSmall, sizeBig;
00133 size = sizeSmall = sizeBig = -1;
00134
00135 QString face = element.attribute("face", "");
00136 if (face.isNull() || face.isEmpty())
00137 {
00138 if (!fromBase)
00139 {
00140 VERBOSE(VB_IMPORTANT, "Font needs a face");
00141 return NULL;
00142 }
00143 }
00144 else
00145 {
00146 newFont->m_face.setFamily(face);
00147 if (!newFont->m_face.exactMatch())
00148 {
00149 QFont tmp = QApplication::font();
00150 newFont->m_face.setFamily(QFontInfo(tmp).family());
00151 }
00152 }
00153
00154 QString hint = element.attribute("stylehint", "");
00155 if (!hint.isNull() && !hint.isEmpty())
00156 {
00157 newFont->m_face.setStyleHint((QFont::StyleHint)hint.toInt());
00158 }
00159
00160 for (QDomNode child = element.firstChild(); !child.isNull();
00161 child = child.nextSibling())
00162 {
00163 QDomElement info = child.toElement();
00164 if (!info.isNull())
00165 {
00166 if (info.tagName() == "size")
00167 {
00168 size = getFirstText(info).toInt();
00169 }
00170 else if (info.tagName() == "size:small")
00171 {
00172 sizeSmall = getFirstText(info).toInt();
00173 }
00174 else if (info.tagName() == "size:big")
00175 {
00176 sizeBig = getFirstText(info).toInt();
00177 }
00178 else if (info.tagName() == "color")
00179 {
00180 newFont->m_color = QColor(getFirstText(info));
00181 }
00182 else if (info.tagName() == "dropcolor" ||
00183 info.tagName() == "shadowcolor")
00184 {
00185 newFont->m_shadowColor = QColor(getFirstText(info));
00186 }
00187 else if (info.tagName() == "shadow" ||
00188 info.tagName() == "shadowoffset")
00189 {
00190 newFont->m_hasShadow = true;
00191 newFont->m_shadowOffset = parsePoint(info);
00192 }
00193 else if (info.tagName() == "shadowalpha")
00194 {
00195 newFont->m_shadowAlpha = getFirstText(info).toInt();
00196 }
00197 else if (info.tagName() == "outlinecolor")
00198 {
00199 newFont->m_outlineColor = QColor(getFirstText(info));
00200 }
00201 else if (info.tagName() == "outlinesize")
00202 {
00203 newFont->m_hasOutline = true;
00204 newFont->m_outlineSize = getFirstText(info).toInt();
00205 }
00206 else if (info.tagName() == "outlinealpha")
00207 {
00208 newFont->m_outlineAlpha = getFirstText(info).toInt();
00209 }
00210 else if (info.tagName() == "bold")
00211 {
00212 newFont->m_face.setBold(parseBool(info));
00213 }
00214 else if (info.tagName() == "italics")
00215 {
00216 newFont->m_face.setItalic(parseBool(info));
00217 }
00218 else if (info.tagName() == "underline")
00219 {
00220 newFont->m_face.setUnderline(parseBool(info));
00221 }
00222 else
00223 {
00224 VERBOSE(VB_IMPORTANT, QString("Unknown tag %1 in font")
00225 .arg(info.tagName()));
00226 return NULL;
00227 }
00228 }
00229 }
00230
00231 if (sizeSmall > 0 && fontSizeType == "small")
00232 {
00233 size = sizeSmall;
00234 }
00235 else if (sizeBig > 0 && fontSizeType == "big")
00236 {
00237 size = sizeBig;
00238 }
00239
00240 if (size <= 0 && !fromBase)
00241 {
00242 VERBOSE(VB_IMPORTANT, "Error, font size must be > 0");
00243 return NULL;
00244 }
00245 else if (size > 0)
00246 newFont->m_face.setPointSize(GetMythMainWindow()->NormalizeFontSize(size));
00247
00248 newFont->Unfreeze();
00249
00250 if (addToGlobal)
00251 {
00252 GetGlobalFontMap()->AddFont(name, newFont);
00253 }
00254
00255 return newFont;
00256 }
00257
00258 static FontMap *gFontMap = NULL;
00259
00260
00261 extern QMap<QString, fontProp> globalFontMap;
00262
00263 MythFontProperties *FontMap::GetFont(const QString &text)
00264 {
00265 if (text.isEmpty())
00266 return NULL;
00267
00268 if (m_FontMap.contains(text))
00269 return &(m_FontMap[text]);
00270 return NULL;
00271 }
00272
00273 bool FontMap::AddFont(const QString &text, MythFontProperties *font)
00274 {
00275 if (!font || text.isEmpty())
00276 return false;
00277
00278 if (m_FontMap.contains(text))
00279 {
00280 VERBOSE(VB_IMPORTANT, QString("Already have a font: %1").arg(text));
00281 return false;
00282 }
00283
00284 m_FontMap[text] = *font;
00285
00286 {
00287
00288 fontProp oldf;
00289
00290 oldf.face = font->m_face;
00291 oldf.color = font->m_color;
00292 if (font->m_hasShadow)
00293 {
00294 oldf.dropColor = font->m_shadowColor;
00295 oldf.shadowOffset = font->m_shadowOffset;
00296 }
00297
00298 globalFontMap[text] = oldf;
00299 }
00300
00301 return true;
00302 }
00303
00304 bool FontMap::Contains(const QString &text)
00305 {
00306 return m_FontMap.contains(text);
00307 }
00308
00309 void FontMap::Clear(void)
00310 {
00311 m_FontMap.clear();
00312
00313
00314 globalFontMap.clear();
00315 }
00316
00317 FontMap *FontMap::GetGlobalFontMap(void)
00318 {
00319 if (!gFontMap)
00320 gFontMap = new FontMap();
00321 return gFontMap;
00322 }
00323
00324 FontMap *GetGlobalFontMap(void)
00325 {
00326 return FontMap::GetGlobalFontMap();
00327 }
00328