Browse Source

Improved parser and renderer

pull/1/head
gyroninja 5 years ago
parent
commit
8963dee746
  1. 8
      src/graphics/opengl/Window.cpp
  2. 14
      src/graphics/opengl/components/TextComponent.cpp
  3. 1
      src/graphics/opengl/components/TextComponent.h
  4. 38
      src/html/HTMLParser.cpp
  5. 2
      src/html/HTMLParser.h
  6. 6
      src/html/Node.h
  7. 15
      src/html/TagNode.cpp
  8. 5
      src/html/TagNode.h
  9. 36
      src/html/TextNode.cpp
  10. 3
      src/html/TextNode.h
  11. 10
      src/html/elements/H1Element.cpp
  12. 2
      src/html/elements/H1Element.h
  13. 10
      src/html/elements/H2Element.cpp
  14. 2
      src/html/elements/H2Element.h
  15. 10
      src/html/elements/H3Element.cpp
  16. 2
      src/html/elements/H3Element.h
  17. 10
      src/html/elements/LIElement.cpp
  18. 2
      src/html/elements/LIElement.h
  19. 10
      src/html/elements/PElement.cpp
  20. 2
      src/html/elements/PElement.h
  21. 8
      src/html/elements/SPANElement.cpp
  22. 2
      src/html/elements/SPANElement.h

8
src/graphics/opengl/Window.cpp

@ -161,12 +161,12 @@ void Window::setDOM(const std::shared_ptr<Node> rootNode) { @@ -161,12 +161,12 @@ void Window::setDOM(const std::shared_ptr<Node> rootNode) {
}
void Window::drawNode(const std::shared_ptr<Node> node) {
if (node->nodeType == NodeType::TAG) {
TagNode *tagNode = dynamic_cast<TagNode*>(node.get());
std::unique_ptr<Component> component = tagNode->render(*tagNode, y, windowWidth, windowHeight);
if (node->nodeType == NodeType::TEXT) {
TextNode *textNode = dynamic_cast<TextNode*>(node.get());
std::unique_ptr<Component> component = textNode->render(*textNode, y, windowWidth, windowHeight);
if (component) {
components.push_back(tagNode->render(*tagNode, y, windowWidth, windowHeight));
y -= component->height;
components.push_back(std::move(component));
}
}
for (std::shared_ptr<Node> child : node->children) {

14
src/graphics/opengl/components/TextComponent.cpp

@ -7,7 +7,9 @@ TextComponent::TextComponent(const std::string &text, const int x, const int y, @@ -7,7 +7,9 @@ TextComponent::TextComponent(const std::string &text, const int x, const int y,
this->fontSize = fontSize;
this->bold = bold;
rasterize(text, x, y, fontSize, bold, windowWidth, windowHeight);
htmlDecode(this->text);
rasterize(this->text, x, y, fontSize, bold, windowWidth, windowHeight);
for (int i = 0; i < glyphVertices.size(); i++) {
const Glyph &glyph = glyphs[i];
@ -119,3 +121,13 @@ void TextComponent::pointToViewport(float &x, float &y, const int windowWidth, c @@ -119,3 +121,13 @@ void TextComponent::pointToViewport(float &x, float &y, const int windowWidth, c
x = ((x / windowWidth) * 2) - 1;
y = ((y / windowHeight) * 2) - 1;
}
void TextComponent::htmlDecode(std::string &str) {
size_t found = 0;
while ((found = str.find("&", found)) != std::string::npos) {
if (str.substr(found, 4) == "&gt;") {
str.replace(found, 4, ">");
}
found++;
}
}

1
src/graphics/opengl/components/TextComponent.h

@ -34,6 +34,7 @@ public: @@ -34,6 +34,7 @@ public:
void render();
void resize(const int x, const int y, const int windowWidth, const int windowHeight);
void pointToViewport(float &x, float &y, const int windowWidth, const int windowHeight) const;
void htmlDecode(std::string &str);
};
#endif

38
src/html/HTMLParser.cpp

@ -49,6 +49,17 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const { @@ -49,6 +49,17 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const {
currentNode = currentNode->parent;
state = 1;
}
else if (
(html[cursor + 1] == 'h' && html[cursor + 2] == 'r') ||
(html[cursor + 1] == 'b' && html[cursor + 2] == 'r') ||
(html[cursor + 1] == 'w' && html[cursor + 2] == 'b' && html[cursor + 3] == 'r') ||
(html[cursor + 1] == 'i' && html[cursor + 2] == 'm' && html[cursor + 3] == 'g') ||
(html[cursor + 1] == 'l' && html[cursor + 2] == 'i' && html[cursor + 3] == 'n' && html[cursor + 4] == 'k') ||
(html[cursor + 1] == 'm' && html[cursor + 2] == 'e' && html[cursor + 3] == 't' && html[cursor + 4] == 'a') ||
(html[cursor + 1] == 'i' && html[cursor + 2] == 'n' && html[cursor + 3] == 'p' && html[cursor + 4] == 'u' && html[cursor + 5] == 't')
) {
state = 1;
}
else {
std::shared_ptr<TagNode> tagNode = std::make_shared<TagNode>();
currentNode->children.push_back(tagNode);
@ -66,6 +77,7 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const { @@ -66,6 +77,7 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const {
starts.push_back(cursor);
state = 3;
}
cursor--;
}
else if (state == 1) { // Skip Over Element
if (html[cursor] == '>') {
@ -77,15 +89,16 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const { @@ -77,15 +89,16 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const {
const int start = starts.back();
starts.pop_back();
std::string element = html.substr(start, cursor - start + 1);
parseTag(element, dynamic_cast<TagNode*>(currentNode.get()));
parseTag(element, *dynamic_cast<TagNode*>(currentNode.get()));
state = 0;
}
}
else if (state == 3) { // Text
if (html[cursor + 1] == '<' && html[cursor + 2] == '/') {
if (html[cursor + 1] == '<') {
const int start = starts.back();
starts.pop_back();
dynamic_cast<TextNode*>(currentNode.get())->text = html.substr(start, cursor - start + 1);
currentNode = currentNode->parent;
state = 0;
}
}
@ -95,7 +108,7 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const { @@ -95,7 +108,7 @@ std::shared_ptr<Node> HTMLParser::parse(const std::string &html) const {
return rootNode;
}
void HTMLParser::parseTag(const std::string &element, TagNode* tagNode) const {
void HTMLParser::parseTag(const std::string &element, TagNode &tagNode) const {
int cursor;
int start = 1; // skip first <
int state = 0;
@ -103,7 +116,7 @@ void HTMLParser::parseTag(const std::string &element, TagNode* tagNode) const { @@ -103,7 +116,7 @@ void HTMLParser::parseTag(const std::string &element, TagNode* tagNode) const {
for (cursor = 0; cursor < element.length(); cursor++) {
if (state == 0) {
if (element[cursor] == ' ' || element[cursor] == '>') {
tagNode->tag = element.substr(start, cursor - start);
tagNode.tag = element.substr(start, cursor - start);
start = cursor + 1;
state = 1;
}
@ -118,14 +131,25 @@ void HTMLParser::parseTag(const std::string &element, TagNode* tagNode) const { @@ -118,14 +131,25 @@ void HTMLParser::parseTag(const std::string &element, TagNode* tagNode) const {
}
}
else if (state == 2) {
if (element[cursor] == '\"') {
if (element[cursor] == '"') {
start = cursor + 1;
state = 3;
}
else if (element[cursor] == '\'') {
start = cursor + 1;
state = 4;
}
}
else if (state == 3) {
if (element[cursor] == '\"') {
tagNode->properties.insert(std::pair<std::string, std::string>(propertyKey, element.substr(start, cursor - start)));
if (element[cursor] == '"') {
tagNode.properties.insert(std::pair<std::string, std::string>(propertyKey, element.substr(start, cursor - start)));
start = cursor + 1;
state = 1;
}
}
else if (state == 4) {
if (element[cursor] == '\'') {
tagNode.properties.insert(std::pair<std::string, std::string>(propertyKey, element.substr(start, cursor - start)));
start = cursor + 1;
state = 1;
}

2
src/html/HTMLParser.h

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
class HTMLParser {
public:
std::shared_ptr<Node> parse(const std::string &html) const;
void parseTag(const std::string &element, TagNode* tagNode) const;
void parseTag(const std::string &element, TagNode &tagNode) const;
};
#endif

6
src/html/Node.h

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
#ifndef NODE_H
#define NODE_H
#include "../graphics/opengl/components/Component.h"
#include <memory>
#include <vector>
@ -19,4 +20,9 @@ public: @@ -19,4 +20,9 @@ public:
std::vector<std::shared_ptr<Node>> children;
};
struct Element {
std::string tag;
std::function<std::unique_ptr<Component>(const Node &node, int y, int windowWidth, int windowHeight)> render;
};
#endif

15
src/html/TagNode.cpp

@ -1,27 +1,14 @@ @@ -1,27 +1,14 @@
#include "TagNode.h"
#include "elements/H1Element.h"
#include "elements/H2Element.h"
#include "elements/H3Element.h"
#include "elements/LIElement.h"
#include "elements/PElement.h"
#include "elements/SPANElement.h"
const Element TagNode::elements[] = {
{"h1", &H1Element::render},
{"h2", &H2Element::render},
{"h3", &H3Element::render},
{"li", &LIElement::render},
{"p", &PElement::render},
{"span", &SPANElement::render}
};
TagNode::TagNode() : Node(NodeType::TAG) {
}
std::unique_ptr<Component> TagNode::render(const Node &node, int y, int windowWidth, int windowHeight) {
for (Element element : elements) {
if (tag == element.tag) {
if (element.tag == tag) {
return element.render(node, y, windowWidth, windowHeight);
}
}

5
src/html/TagNode.h

@ -5,11 +5,6 @@ @@ -5,11 +5,6 @@
#include "../graphics/opengl/components/Component.h"
#include <map>
struct Element {
std::string tag;
std::function<std::unique_ptr<Component>(const Node &node, int y, int windowWidth, int windowHeight)> render;
};
class TagNode : public Node {
private:
static const Element elements[];

36
src/html/TextNode.cpp

@ -1,5 +1,37 @@ @@ -1,5 +1,37 @@
#include "TextNode.h"
#include "TagNode.h"
#include "elements/BLOCKQUOTEElement.h"
#include "elements/H1Element.h"
#include "elements/H2Element.h"
#include "elements/H3Element.h"
#include "elements/LIElement.h"
#include "elements/PElement.h"
#include "elements/SPANElement.h"
TextNode::TextNode() : Node(NodeType::TEXT) {
const Element TextNode::elements[] = {
{"blockquote", &BLOCKQUOTEElement::render},
{"h1", &H1Element::render},
{"h2", &H2Element::render},
{"h3", &H3Element::render},
{"li", &LIElement::render},
{"p", &PElement::render},
{"span", &SPANElement::render}
};
}
TextNode::TextNode() : Node(NodeType::TEXT) {
}
#include <iostream>
std::unique_ptr<Component> TextNode::render(const Node &node, int y, int windowWidth, int windowHeight) {
// std::cout << "BOOP: " << text << std::endl;
TagNode *tagNode = dynamic_cast<TagNode*>(node.parent.get());
if (tagNode) {
for (Element element : elements) {
// std::cout << element.tag << " vs " << tagNode->tag << std::endl;
if (element.tag == tagNode->tag) {
// std::cout << "BLIP" << std::endl;
return element.render(node, y, windowWidth, windowHeight);
}
}
}
return nullptr;
}

3
src/html/TextNode.h

@ -5,8 +5,11 @@ @@ -5,8 +5,11 @@
#include <map>
class TextNode : public Node {
private:
static const Element elements[];
public:
TextNode();
std::unique_ptr<Component> render(const Node &node, int y, int windowWidth, int windowHeight);
std::string text;
};

10
src/html/elements/H1Element.cpp

@ -1,13 +1,5 @@ @@ -1,13 +1,5 @@
#include "H1Element.h"
#include "../TextNode.h"
#include <iostream>
std::unique_ptr<Component> H1Element::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>(textNode->text, 0, y, 24, true, windowWidth, windowHeight);
}
}
return nullptr;
return std::make_unique<TextComponent>(static_cast<const TextNode&>(node).text, 0, y, 24, true, windowWidth, windowHeight);
}

2
src/html/elements/H1Element.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class H1Element {
public:

10
src/html/elements/H2Element.cpp

@ -1,13 +1,5 @@ @@ -1,13 +1,5 @@
#include "H2Element.h"
#include "../TextNode.h"
#include <iostream>
std::unique_ptr<Component> H2Element::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>(textNode->text, 0, y, 18, true, windowWidth, windowHeight);
}
}
return nullptr;
return std::make_unique<TextComponent>(static_cast<const TextNode&>(node).text, 0, y, 18, true, windowWidth, windowHeight);
}

2
src/html/elements/H2Element.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class H2Element {
public:

10
src/html/elements/H3Element.cpp

@ -1,13 +1,5 @@ @@ -1,13 +1,5 @@
#include "H3Element.h"
#include "../TextNode.h"
#include <iostream>
std::unique_ptr<Component> H3Element::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>(textNode->text, 0, y, 14, true, windowWidth, windowHeight); // Should be 14.04pt
}
}
return nullptr;
return std::make_unique<TextComponent>(static_cast<const TextNode&>(node).text, 0, y, 14, true, windowWidth, windowHeight); // Should be 14.04pt
}

2
src/html/elements/H3Element.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class H3Element {
public:

10
src/html/elements/LIElement.cpp

@ -1,13 +1,5 @@ @@ -1,13 +1,5 @@
#include "LIElement.h"
#include "../TextNode.h"
#include <iostream>
std::unique_ptr<Component> LIElement::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>("" + textNode->text, 0, y, 12, false, windowWidth, windowHeight);
}
}
return nullptr;
return std::make_unique<TextComponent>("" + static_cast<const TextNode&>(node).text, 0, y, 12, false, windowWidth, windowHeight);
}

2
src/html/elements/LIElement.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class LIElement {
public:

10
src/html/elements/PElement.cpp

@ -1,13 +1,5 @@ @@ -1,13 +1,5 @@
#include "PElement.h"
#include "../TextNode.h"
#include <iostream>
std::unique_ptr<Component> PElement::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>(textNode->text, 0, y, 12, false, windowWidth, windowHeight);
}
}
return nullptr;
return std::make_unique<TextComponent>(static_cast<const TextNode&>(node).text, 0, y, 12, false, windowWidth, windowHeight);
}

2
src/html/elements/PElement.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class PElement {
public:

8
src/html/elements/SPANElement.cpp

@ -1,12 +1,8 @@ @@ -1,12 +1,8 @@
#include "SPANElement.h"
#include "../TextNode.h"
std::unique_ptr<Component> SPANElement::render(const Node &node, int y, int windowWidth, int windowHeight) {
if (!node.children.empty()) {
TextNode *textNode = dynamic_cast<TextNode*>(node.children[0].get());
if (textNode) {
return std::make_unique<TextComponent>(textNode->text, 0, y, 12, false, windowWidth, windowHeight);
}
if (node.parent->children.size() == 1) {
return std::make_unique<TextComponent>(static_cast<const TextNode&>(node).text, 0, y, 12, false, windowWidth, windowHeight);
}
return nullptr;
}

2
src/html/elements/SPANElement.h

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
#include "../../graphics/opengl/components/Component.h"
#include "../../graphics/opengl/components/TextComponent.h"
#include "../Node.h"
#include "../TextNode.h"
class SPANElement {
public:

Loading…
Cancel
Save