vstyleparser.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. }
  71. break;
  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. QPalette VStyleParser::fetchMarkdownEditorStyles(const QPalette &basePalette) const
  116. {
  117. QPalette palette(basePalette);
  118. // editor
  119. pmh_style_attribute *editorStyles = markdownStyles->editor_styles;
  120. while (editorStyles) {
  121. switch (editorStyles->type) {
  122. case pmh_attr_type_foreground_color:
  123. palette.setColor(QPalette::Text,
  124. QColorFromPmhAttr(editorStyles->value->argb_color));
  125. break;
  126. case pmh_attr_type_background_color:
  127. palette.setColor(QPalette::Base,
  128. QColorFromPmhAttr(editorStyles->value->argb_color));
  129. break;
  130. default:
  131. qWarning() << "warning: unimplemented editor attr type:" << editorStyles->type;
  132. }
  133. editorStyles = editorStyles->next;
  134. }
  135. // editor-current-line
  136. pmh_style_attribute *curLineStyles = markdownStyles->editor_current_line_styles;
  137. if (curLineStyles) {
  138. qDebug() << "editor-current-line style is not supported";
  139. }
  140. // editor-selection
  141. pmh_style_attribute *selStyles = markdownStyles->editor_selection_styles;
  142. while (selStyles) {
  143. switch (selStyles->type) {
  144. case pmh_attr_type_foreground_color:
  145. palette.setColor(QPalette::HighlightedText,
  146. QColorFromPmhAttr(selStyles->value->argb_color));
  147. break;
  148. case pmh_attr_type_background_color:
  149. palette.setColor(QPalette::Highlight,
  150. QColorFromPmhAttr(selStyles->value->argb_color));
  151. break;
  152. default:
  153. qWarning() << "warning: unimplemented selection attr type:" << selStyles->type;
  154. }
  155. selStyles = selStyles->next;
  156. }
  157. return palette;
  158. }
  159. // @familyList is a comma separated string
  160. QString VStyleParser::filterAvailableFontFamily(const QString &familyList) const
  161. {
  162. QStringList families = familyList.split(',', QString::SkipEmptyParts);
  163. QStringList availFamilies = QFontDatabase().families();
  164. qDebug() << "family:" << familyList;
  165. for (int i = 0; i < families.size(); ++i) {
  166. QString family = families[i].trimmed().toLower();
  167. for (int j = 0; j < availFamilies.size(); ++j) {
  168. QString availFamily = availFamilies[j];
  169. availFamily.remove(QRegExp("\\[.*\\]"));
  170. if (family == availFamily.trimmed().toLower()) {
  171. qDebug() << "matched family:" << availFamilies[j];
  172. return availFamilies[j];
  173. }
  174. }
  175. }
  176. return QString();
  177. }