|
@@ -67,18 +67,6 @@ typedef struct {
|
|
|
size_t size, allocated;
|
|
|
} buffer_t;
|
|
|
|
|
|
-#define FLAG_BOLD (1 << 0)
|
|
|
-#define FLAG_STRIKE (1 << 1)
|
|
|
-#define FLAG_ITALIC (1 << 2)
|
|
|
-#define FLAG_TT (1 << 3)
|
|
|
-
|
|
|
-typedef struct _node_t {
|
|
|
- uint_t flags;
|
|
|
- buffer_t *buffer;
|
|
|
-
|
|
|
- struct _node_t *next;
|
|
|
-} node_t;
|
|
|
-
|
|
|
void *malloc_protected(size_t z) {
|
|
|
void *p;
|
|
|
|
|
@@ -139,128 +127,89 @@ void buffer_append_data(buffer_t *buffer, unsigned char *data, size_t data_lengt
|
|
|
}
|
|
|
|
|
|
#define BUFFER_APPEND(b, s) buffer_append_data(b, s, strlen(s))
|
|
|
-#define BUFFER_CONCAT(b1, b2) buffer_append_data(b1, (b2)->data, (b2)->size);
|
|
|
-
|
|
|
-node_t *new_node() {
|
|
|
- node_t *node;
|
|
|
-
|
|
|
- node = malloc_protected(sizeof(node_t));
|
|
|
-
|
|
|
- node->flags = 0;
|
|
|
- node->buffer = new_buffer();
|
|
|
- node->next = NULL;
|
|
|
-
|
|
|
- return node;
|
|
|
+#define BUFFER_CONCAT(b1, b2) {\
|
|
|
+ buffer_append_data(b2, "\0", 1);\
|
|
|
+ preprocess_text(b1, b2->data);\
|
|
|
}
|
|
|
|
|
|
-void free_node(node_t *node) {
|
|
|
- if (node->next)
|
|
|
- free_node(node->next);
|
|
|
-
|
|
|
- free_buffer(node->buffer);
|
|
|
- free(node);
|
|
|
-}
|
|
|
-
|
|
|
-#define SET(flag) {\
|
|
|
- if (tail->flags & FLAG_##flag) {\
|
|
|
- tail = tail->next = new_node();\
|
|
|
- continue;\
|
|
|
- }\
|
|
|
- uint_t flags = tail->flags;\
|
|
|
- tail = tail->next = new_node();\
|
|
|
- tail->flags = flags | FLAG_##flag;\
|
|
|
-}
|
|
|
-
|
|
|
-void preprocess_text(buffer_t *buffer, char *text) {
|
|
|
- uint_t state;
|
|
|
- node_t *head;
|
|
|
- node_t *tail;
|
|
|
-
|
|
|
- head = tail = new_node();
|
|
|
-
|
|
|
- for (size_t i = 0; i < strlen(text); i++) {
|
|
|
- unsigned char c, nc;
|
|
|
-
|
|
|
- c = text[i];
|
|
|
- nc = text[i+1];
|
|
|
-
|
|
|
- if (c == '`') {
|
|
|
- SET(TT);
|
|
|
- } else if (c == '*' && nc == '*') {
|
|
|
- i++;
|
|
|
+void buffer_append_escaped(buffer_t *buffer, char c) {
|
|
|
+ switch (c) {
|
|
|
+ case '<':
|
|
|
+ BUFFER_APPEND(buffer, "<");
|
|
|
|
|
|
- SET(BOLD);
|
|
|
- } else if (c == '~' && nc == '~') {
|
|
|
- i++;
|
|
|
+ return;
|
|
|
|
|
|
- SET(STRIKE);
|
|
|
- } else if (c == '_' && nc == '_') {
|
|
|
- i++;
|
|
|
+ case '>':
|
|
|
+ BUFFER_APPEND(buffer, ">");
|
|
|
|
|
|
- SET(ITALIC);
|
|
|
- } else {
|
|
|
- switch (c) {
|
|
|
- case '<':
|
|
|
- BUFFER_APPEND(tail->buffer, "<");
|
|
|
+ return;
|
|
|
|
|
|
- continue;
|
|
|
+ case '&':
|
|
|
+ BUFFER_APPEND(buffer, "&");
|
|
|
|
|
|
- case '>':
|
|
|
- BUFFER_APPEND(tail->buffer, ">");
|
|
|
+ return;
|
|
|
|
|
|
- continue;
|
|
|
+ case '"':
|
|
|
+ BUFFER_APPEND(buffer, """);
|
|
|
|
|
|
- case '&':
|
|
|
- BUFFER_APPEND(tail->buffer, "&");
|
|
|
+ return;
|
|
|
|
|
|
- continue;
|
|
|
+ case '\'':
|
|
|
+ BUFFER_APPEND(buffer, "'");
|
|
|
|
|
|
- case '"':
|
|
|
- BUFFER_APPEND(tail->buffer, """);
|
|
|
-
|
|
|
- continue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- case '\'':
|
|
|
- BUFFER_APPEND(tail->buffer, "'");
|
|
|
+ buffer_append_data(buffer, &c, 1);
|
|
|
+}
|
|
|
|
|
|
- continue;
|
|
|
- }
|
|
|
+#define SET(s,tag) do {\
|
|
|
+ buffer_t *temp_buffer;\
|
|
|
+ uint_t k;\
|
|
|
+ temp_buffer = new_buffer();\
|
|
|
+ k = strlen(s);\
|
|
|
+ i += k;\
|
|
|
+ while (text[i]) {\
|
|
|
+ if (strncmp(&text[i], s, k) == 0) {\
|
|
|
+ i += k-1;\
|
|
|
+ buffer_append_data(buffer, "<", 1);\
|
|
|
+ BUFFER_APPEND(buffer, tag);\
|
|
|
+ buffer_append_data(buffer, ">", 1);\
|
|
|
+ BUFFER_CONCAT(buffer, temp_buffer);\
|
|
|
+ buffer_append_data(buffer, "</", 2);\
|
|
|
+ BUFFER_APPEND(buffer, tag);\
|
|
|
+ buffer_append_data(buffer, ">", 1);\
|
|
|
+ free_buffer(temp_buffer);\
|
|
|
+ goto escape;\
|
|
|
+ }\
|
|
|
+ buffer_append_escaped(temp_buffer, text[i]);\
|
|
|
+ i++;\
|
|
|
+ }\
|
|
|
+ i--;\
|
|
|
+ BUFFER_APPEND(buffer, s);\
|
|
|
+ BUFFER_CONCAT(buffer, temp_buffer);\
|
|
|
+ free_buffer(temp_buffer);\
|
|
|
+} while(0)
|
|
|
|
|
|
- buffer_append_data(tail->buffer, &c, 1);
|
|
|
- }
|
|
|
- }
|
|
|
+void preprocess_text(buffer_t *buffer, char *text) {
|
|
|
+ for (size_t i = 0; text[i]; i++) {
|
|
|
+ unsigned char c, nc;
|
|
|
|
|
|
- if (tail->flags) {
|
|
|
- tail->flags = 0;
|
|
|
- }
|
|
|
+ c = text[i];
|
|
|
+ nc = text[i+1];
|
|
|
|
|
|
- node_t *start = head;
|
|
|
-
|
|
|
- while (head) {
|
|
|
- if (head->flags & FLAG_BOLD)
|
|
|
- BUFFER_APPEND(buffer, "<b>");
|
|
|
- if (head->flags & FLAG_STRIKE)
|
|
|
- BUFFER_APPEND(buffer, "<s>");
|
|
|
- if (head->flags & FLAG_ITALIC)
|
|
|
- BUFFER_APPEND(buffer, "<i>");
|
|
|
- if (head->flags & FLAG_TT)
|
|
|
- BUFFER_APPEND(buffer, "<tt>");
|
|
|
-
|
|
|
- BUFFER_CONCAT(buffer, head->buffer);
|
|
|
-
|
|
|
- if (head->flags & FLAG_TT)
|
|
|
- BUFFER_APPEND(buffer, "</tt>");
|
|
|
- if (head->flags & FLAG_ITALIC)
|
|
|
- BUFFER_APPEND(buffer, "</i>");
|
|
|
- if (head->flags & FLAG_STRIKE)
|
|
|
- BUFFER_APPEND(buffer, "</s>");
|
|
|
- if (head->flags & FLAG_BOLD)
|
|
|
- BUFFER_APPEND(buffer, "</b>");
|
|
|
-
|
|
|
- head = head->next;
|
|
|
+ if (c == '`')
|
|
|
+ SET("`", "tt");
|
|
|
+ else if (c == '*' && nc == '*')
|
|
|
+ SET("**", "b");
|
|
|
+ else if (c == '_' && nc == '_')
|
|
|
+ SET("__", "i");
|
|
|
+ else if (c == '~' && nc == '~')
|
|
|
+ SET("~~", "s");
|
|
|
+ else
|
|
|
+ buffer_append_escaped(buffer, c);
|
|
|
+escape:;
|
|
|
}
|
|
|
-
|
|
|
- free_node(start);
|
|
|
}
|
|
|
|
|
|
text_t *new_text(cairo_t *cr, char *s, int size, int weight, int preprocess) {
|
|
@@ -384,7 +333,7 @@ void paste_image(cairo_t *cr, uint_t x, uint_t y, char *path) {
|
|
|
cairo_surface_destroy(surface);
|
|
|
}
|
|
|
|
|
|
-void fit(cairo_surface_t **surface, uint_t width, uint_t height) {
|
|
|
+void contain(cairo_surface_t **surface, uint_t width, uint_t height) {
|
|
|
uint_t image_width, image_height;
|
|
|
uint_t new_width, new_height;
|
|
|
double image_ratio, new_ratio;
|
|
@@ -528,7 +477,7 @@ main() {
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
|
- fit(&surface, 512, 512);
|
|
|
+ contain(&surface, 512, 512);
|
|
|
cairo_surface_write_to_png(surface, output_path->data);
|
|
|
|
|
|
free_buffer(output_path);
|