vstyleparser.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include "vstyleparser.h"
  2. #include <QFont>
  3. #include <QFontDatabase>
  4. #include <QPalette>
  5. #include <QTextEdit>
  6. #include <QColor>
  7. #include <QBrush>
  8. #include <QVector>
  9. #include <QtDebug>
  10. #include <QStringList>
  11. VStyleParser::VStyleParser()
  12. {
  13. markdownStyles = NULL;
  14. }
  15. VStyleParser::~VStyleParser()
  16. {
  17. if (markdownStyles) {
  18. pmh_free_style_collection(markdownStyles);
  19. }
  20. }
  21. QColor VStyleParser::QColorFromPmhAttr(pmh_attr_argb_color *attr) const
  22. {
  23. return QColor(attr->red, attr->green, attr->blue, attr->alpha);
  24. }
  25. QBrush VStyleParser::QBrushFromPmhAttr(pmh_attr_argb_color *attr) const
  26. {
  27. return QBrush(QColorFromPmhAttr(attr));
  28. }
  29. void markdownStyleErrorCB(char *errMsg, int lineNr, void *context)
  30. {
  31. (void)context;
  32. qDebug() << "parser error:" << errMsg << lineNr;
  33. }
  34. QTextCharFormat VStyleParser::QTextCharFormatFromAttrs(pmh_style_attribute *attrs,
  35. const QFont &baseFont) const
  36. {
  37. QTextCharFormat format;
  38. while (attrs) {
  39. switch (attrs->type) {
  40. case pmh_attr_type_foreground_color:
  41. format.setForeground(QBrushFromPmhAttr(attrs->value->argb_color));
  42. break;
  43. case pmh_attr_type_background_color:
  44. format.setBackground(QBrushFromPmhAttr(attrs->value->argb_color));
  45. break;
  46. case pmh_attr_type_font_size_pt:
  47. {
  48. pmh_attr_font_size *fontSize = attrs->value->font_size;
  49. int ptSize = fontSize->size_pt;
  50. if (fontSize->is_relative) {
  51. int basePtSize = baseFont.pointSize();
  52. if (basePtSize == -1) {
  53. // In pixel. Use default font configuration.
  54. basePtSize = 11;
  55. }
  56. ptSize += basePtSize;
  57. }
  58. if (ptSize > 0) {
  59. format.setFontPointSize(ptSize);
  60. }
  61. break;
  62. }
  63. case pmh_attr_type_font_family:
  64. {
  65. QString familyList(attrs->value->font_family);
  66. QString finalFamily = filterAvailableFontFamily(familyList);
  67. if (!finalFamily.isEmpty()) {
  68. format.setFontFamily(finalFamily);
  69. }
  70. break;
  71. }
  72. case pmh_attr_type_font_style:
  73. {
  74. pmh_attr_font_styles *fontStyle = attrs->value->font_styles;
  75. if (fontStyle->italic) {
  76. format.setFontItalic(true);
  77. }
  78. if (fontStyle->bold) {
  79. format.setFontWeight(QFont::Bold);
  80. }
  81. if (fontStyle->underlined) {
  82. format.setFontUnderline(true);
  83. }
  84. break;
  85. }
  86. default:
  87. qWarning() << "warning: unimplemented format attr type:" << attrs->type;
  88. break;
  89. }
  90. attrs = attrs->next;
  91. }
  92. return format;
  93. }
  94. void VStyleParser::parseMarkdownStyle(const QString &styleStr)
  95. {
  96. if (markdownStyles) {
  97. pmh_free_style_collection(markdownStyles);
  98. }
  99. markdownStyles = pmh_parse_styles(styleStr.toLocal8Bit().data(),
  100. &markdownStyleErrorCB, this);
  101. }
  102. QVector<HighlightingStyle> VStyleParser::fetchMarkdownStyles(const QFont &baseFont) const
  103. {
  104. QVector<HighlightingStyle> styles(pmh_NUM_LANG_TYPES);
  105. for (int i = 0; i < pmh_NUM_LANG_TYPES; ++i) {
  106. pmh_style_attribute *attr = markdownStyles->element_styles[i];
  107. if (!attr) {
  108. continue;
  109. }
  110. styles[i].type = attr->lang_element_type;
  111. styles[i].format = QTextCharFormatFromAttrs(attr, baseFont);
  112. }
  113. return styles;
  114. }
  115. void VStyleParser::fetchMarkdownEditorStyles(QPalette &palette, QFont &font) const
  116. {
  117. // editor
  118. pmh_style_attribute *editorStyles = markdownStyles->editor_styles;
  119. while (editorStyles) {
  120. switch (editorStyles->type) {
  121. case pmh_attr_type_foreground_color:
  122. palette.setColor(QPalette::Text,
  123. QColorFromPmhAttr(editorStyles->value->argb_color));
  124. break;
  125. case pmh_attr_type_background_color:
  126. palette.setColor(QPalette::Base,
  127. QColorFromPmhAttr(editorStyles->value->argb_color));
  128. break;
  129. case pmh_attr_type_font_family:
  130. {
  131. QString familyList(editorStyles->value->font_family);
  132. QString finalFamily = filterAvailableFontFamily(familyList);
  133. if (!finalFamily.isEmpty()) {
  134. font.setFamily(finalFamily);
  135. }
  136. break;
  137. }
  138. default:
  139. qWarning() << "warning: unimplemented editor attr type:" << editorStyles->type;
  140. }
  141. editorStyles = editorStyles->next;
  142. }
  143. // editor-current-line
  144. pmh_style_attribute *curLineStyles = markdownStyles->editor_current_line_styles;
  145. if (curLineStyles) {
  146. qDebug() << "editor-current-line style is not supported";
  147. }
  148. // editor-selection
  149. pmh_style_attribute *selStyles = markdownStyles->editor_selection_styles;
  150. while (selStyles) {
  151. switch (selStyles->type) {
  152. case pmh_attr_type_foreground_color:
  153. palette.setColor(QPalette::HighlightedText,
  154. QColorFromPmhAttr(selStyles->value->argb_color));
  155. break;
  156. case pmh_attr_type_background_color:
  157. palette.setColor(QPalette::Highlight,
  158. QColorFromPmhAttr(selStyles->value->argb_color));
  159. break;
  160. default:
  161. qWarning() << "warning: unimplemented selection attr type:" << selStyles->type;
  162. }
  163. selStyles = selStyles->next;
  164. }
  165. }
  166. // @familyList is a comma separated string
  167. QString VStyleParser::filterAvailableFontFamily(const QString &familyList) const
  168. {
  169. QStringList families = familyList.split(',', QString::SkipEmptyParts);
  170. QStringList availFamilies = QFontDatabase().families();
  171. qDebug() << "family:" << familyList;
  172. for (int i = 0; i < families.size(); ++i) {
  173. QString family = families[i].trimmed().toLower();
  174. for (int j = 0; j < availFamilies.size(); ++j) {
  175. QString availFamily = availFamilies[j];
  176. availFamily.remove(QRegExp("\\[.*\\]"));
  177. if (family == availFamily.trimmed().toLower()) {
  178. qDebug() << "matched family:" << availFamilies[j];
  179. return availFamilies[j];
  180. }
  181. }
  182. }
  183. return QString();
  184. }