From 6a36e53e311d17a94e1fb6817eca20afe2b8d4c2 Mon Sep 17 00:00:00 2001
From: "yu.dongliang" <18588496441@163.com>
Date: Wed, 6 Nov 2024 23:02:23 +0800
Subject: [PATCH] simple http download ok by nginx upstream proxy
---
examples/nginx.html | 17 ++
html/abc_html.c | 52 +++---
html/abc_io_http.c | 17 +-
html/abc_obj.h | 2 +
net/ngx_http_abc.h | 8 +
net/ngx_http_abc_module.c | 329 +++++++++++++++++++++++++++++++++++---
ui/abc_layout.c | 65 +++++---
ui/abc_layout_a.c | 6 +-
ui/abc_layout_form.c | 4 +-
ui/abc_layout_h1.c | 4 +-
ui/abc_layout_img.c | 4 +-
ui/abc_layout_input.c | 4 +-
ui/abc_layout_label.c | 4 +-
13 files changed, 434 insertions(+), 82 deletions(-)
create mode 100644 examples/nginx.html
diff --git a/examples/nginx.html b/examples/nginx.html
new file mode 100644
index 0000000..79cd51e
--- /dev/null
+++ b/examples/nginx.html
@@ -0,0 +1,17 @@
+
+
+Welcome to nginx!
+
+
+Welcome to nginx!
+If you see this page, the nginx web server is successfully installed and
+working. Further configuration is required.
+
+For online documentation and support please refer to
+nginx.org
+Commercial support is available at
+nginx.com
+
+Thank you for using nginx.
+
+
diff --git a/html/abc_html.c b/html/abc_html.c
index 82afe93..3f34859 100644
--- a/html/abc_html.c
+++ b/html/abc_html.c
@@ -57,8 +57,10 @@ static char* img_keys[] = {"img", "å¾ç", NULL};
static char* title_keys[] = {"title", "æ é¢", NULL};
static char* input_keys[] = {"input", "è¾å
¥", NULL};
static char* label_keys[] = {"label", "æ ç¾", NULL};
+static char* center_keys[] = {"center", "å±
ä¸", NULL};
static char* br_keys[] = {"br", "æ¢è¡", NULL};
+static char* hr_keys[] = {"hr", "æ é¢æ¢è¡", NULL};
static char* h1_keys[] = {"h1", "æ é¢1", NULL};
static char* h2_keys[] = {"h2", "æ é¢2", NULL};
static char* h3_keys[] = {"h3", "æ é¢3", NULL};
@@ -156,29 +158,31 @@ static html_attr_t form_attrs[] =
static html_label_t html_labels[] =
{
- {html_keys, ABC_HTML, 0, NULL, ABC_HTML_FLAG_CLOSE},
- {title_keys, ABC_HTML_TITLE, 0, NULL, ABC_HTML_FLAG_CLOSE},
- {head_keys, ABC_HTML_HEAD, 0, NULL, ABC_HTML_FLAG_CLOSE},
- {body_keys, ABC_HTML_BODY, 0, NULL, ABC_HTML_FLAG_CLOSE},
-
- {div_keys, ABC_HTML_DIV, 0, NULL, ABC_HTML_FLAG_CLOSE},
-
- {h1_keys, ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE},
- {h2_keys, ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE},
- {h3_keys, ABC_HTML_H3, abc_number_of(h3_attrs), h3_attrs, ABC_HTML_FLAG_CLOSE},
- {h4_keys, ABC_HTML_H4, abc_number_of(h4_attrs), h4_attrs, ABC_HTML_FLAG_CLOSE},
- {h5_keys, ABC_HTML_H5, abc_number_of(h5_attrs), h5_attrs, ABC_HTML_FLAG_CLOSE},
- {h6_keys, ABC_HTML_H6, abc_number_of(h6_attrs), h6_attrs, ABC_HTML_FLAG_CLOSE},
-
- {p_keys, ABC_HTML_P, abc_number_of(p_attrs), p_attrs, ABC_HTML_FLAG_CLOSE},
- {br_keys, ABC_HTML_BR, 0, NULL, ABC_HTML_FLAG_OPEN},
-
- {a_keys, ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE},
- {img_keys, ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE},
-
- {form_keys, ABC_HTML_FORM, abc_number_of(form_attrs), form_attrs, ABC_HTML_FLAG_CLOSE},
- {input_keys, ABC_HTML_INPUT, abc_number_of(input_attrs), input_attrs, ABC_HTML_FLAG_OPEN},
- {label_keys, ABC_HTML_LABEL, abc_number_of(label_attrs), label_attrs, ABC_HTML_FLAG_CLOSE},
+ {html_keys, ABC_HTML, 0, NULL, ABC_HTML_FLAG_CLOSE},
+ {title_keys, ABC_HTML_TITLE, 0, NULL, ABC_HTML_FLAG_CLOSE},
+ {head_keys, ABC_HTML_HEAD, 0, NULL, ABC_HTML_FLAG_CLOSE},
+ {body_keys, ABC_HTML_BODY, 0, NULL, ABC_HTML_FLAG_CLOSE},
+
+ {div_keys, ABC_HTML_DIV, 0, NULL, ABC_HTML_FLAG_CLOSE},
+
+ {h1_keys, ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE},
+ {h2_keys, ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE},
+ {h3_keys, ABC_HTML_H3, abc_number_of(h3_attrs), h3_attrs, ABC_HTML_FLAG_CLOSE},
+ {h4_keys, ABC_HTML_H4, abc_number_of(h4_attrs), h4_attrs, ABC_HTML_FLAG_CLOSE},
+ {h5_keys, ABC_HTML_H5, abc_number_of(h5_attrs), h5_attrs, ABC_HTML_FLAG_CLOSE},
+ {h6_keys, ABC_HTML_H6, abc_number_of(h6_attrs), h6_attrs, ABC_HTML_FLAG_CLOSE},
+
+ {p_keys, ABC_HTML_P, abc_number_of(p_attrs), p_attrs, ABC_HTML_FLAG_CLOSE},
+ {br_keys, ABC_HTML_BR, 0, NULL, ABC_HTML_FLAG_OPEN},
+ {hr_keys, ABC_HTML_HR, 0, NULL, ABC_HTML_FLAG_OPEN},
+
+ {a_keys, ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE},
+ {img_keys, ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE},
+
+ {form_keys, ABC_HTML_FORM, abc_number_of(form_attrs), form_attrs, ABC_HTML_FLAG_CLOSE},
+ {input_keys, ABC_HTML_INPUT, abc_number_of(input_attrs), input_attrs, ABC_HTML_FLAG_OPEN},
+ {label_keys, ABC_HTML_LABEL, abc_number_of(label_attrs), label_attrs, ABC_HTML_FLAG_CLOSE},
+ {center_keys, ABC_HTML_CENTER, 0, NULL, ABC_HTML_FLAG_CLOSE},
};
static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
@@ -776,7 +780,7 @@ int abc_html_parse(abc_html_t* html)
return 0;
}
- if ('\n' == c->c) {
+ if ('\n' == c->c || '\r' == c->c) {
html->n_lines++;
html->pos = 0;
continue;
diff --git a/html/abc_io_http.c b/html/abc_io_http.c
index 8e29160..d62afd5 100644
--- a/html/abc_io_http.c
+++ b/html/abc_io_http.c
@@ -77,6 +77,11 @@ static void* http_thread(void* arg)
scf_loge("\n");
goto error;
+
+ } else if (0 == ret) {
+ scf_loge("\n");
+ usleep(500 * 1000);
+ continue;
}
pthread_mutex_lock(&http->mutex);
@@ -100,8 +105,16 @@ static void* http_thread(void* arg)
}
}
- if (http->content_length >= http->rbuf->len - http->rpos)
- html->download = 1;
+ if (http->rpos > 0) {
+ if (http->content_length >= 0) {
+ if (http->content_length == http->rbuf->len - http->rpos) {
+ html->download = 1;
+
+ scf_logi("http response: %s\n", http->rbuf->data);
+ }
+ } else {
+ }
+ }
pthread_mutex_unlock(&http->mutex);
}
diff --git a/html/abc_obj.h b/html/abc_obj.h
index d3de457..ac7b04c 100644
--- a/html/abc_obj.h
+++ b/html/abc_obj.h
@@ -27,6 +27,7 @@ enum abc_objs
// 11
ABC_HTML_P,
ABC_HTML_BR,
+ ABC_HTML_HR,
ABC_HTML_A,
ABC_HTML_A_HREF,
@@ -37,6 +38,7 @@ enum abc_objs
ABC_HTML_FORM,
ABC_HTML_LABEL,
ABC_HTML_INPUT,
+ ABC_HTML_CENTER,
ABC_HTML_NB, // total HTML objects
diff --git a/net/ngx_http_abc.h b/net/ngx_http_abc.h
index 01aabf8..e7bce37 100644
--- a/net/ngx_http_abc.h
+++ b/net/ngx_http_abc.h
@@ -7,4 +7,12 @@
extern ngx_module_t ngx_http_abc_module;
+typedef struct {
+ ngx_http_upstream_conf_t upstream;
+} ngx_http_abc_conf_t;
+
+typedef struct {
+ ngx_http_status_t status;
+} ngx_http_abc_ctx_t;
+
#endif
diff --git a/net/ngx_http_abc_module.c b/net/ngx_http_abc_module.c
index 2040d51..14ad489 100644
--- a/net/ngx_http_abc_module.c
+++ b/net/ngx_http_abc_module.c
@@ -2,24 +2,15 @@
#include
#include
#include "ngx_http_abc.h"
-
-static ngx_int_t ngx_http_abc_handler(ngx_http_request_t *r)
+#if 0
+static void ngx_http_abc_body_handler(ngx_http_request_t *r)
{
- printf("%s(),%d\n", __func__, __LINE__);
-
ngx_chain_t out;
ngx_buf_t* b;
ngx_int_t rc;
- if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_POST)))
- return NGX_HTTP_NOT_ALLOWED;
-
- rc = ngx_http_discard_request_body(r);
- if (NGX_OK != rc)
- return rc;
-
- ngx_str_t type = ngx_string("text/html");
- ngx_str_t body = ngx_string("hellohello world
");
+ ngx_str_t type = ngx_string("text/html");
+ ngx_str_t body = ngx_string("hellohello world
");
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = body.len;
@@ -29,12 +20,16 @@ static ngx_int_t ngx_http_abc_handler(ngx_http_request_t *r)
printf("%s(),%d, rc: %ld\n", __func__, __LINE__, rc);
- if (NGX_ERROR == rc || rc > NGX_OK || r->header_only)
- return rc;
+ if (NGX_ERROR == rc || rc > NGX_OK || r->header_only) {
+ ngx_http_finalize_request(r, rc);
+ return;
+ }
b = ngx_create_temp_buf(r->pool, body.len);
- if (!b)
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ if (!b) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
ngx_memcpy(b->pos, body.data, body.len);
@@ -44,7 +39,243 @@ static ngx_int_t ngx_http_abc_handler(ngx_http_request_t *r)
out.buf = b;
out.next = NULL;
- return ngx_http_output_filter(r, &out);
+ rc = ngx_http_output_filter(r, &out);
+
+ ngx_http_finalize_request(r, rc);
+}
+#endif
+static ngx_int_t abc_upstream_create_request(ngx_http_request_t *r)
+{
+ printf("%s(),%d\n", __func__, __LINE__);
+ ngx_buf_t* b;
+ size_t len;
+
+ len = strlen("GET ") + r->uri.len + strlen(" HTTP/1.1\r\n");
+ len += strlen("Host: localhost\r\n");
+ len += strlen("User-Agent: nginx/1.20.0\r\n");
+ len += strlen("Accept: */*\r\n");
+ len += strlen("Connection: close\r\n\r\n");
+
+ b = ngx_create_temp_buf(r->pool, len);
+ if (!b)
+ return NGX_ERROR;
+
+ b->last = b->pos + len;
+
+ printf("%s(),%d, len: %ld\n", __func__, __LINE__, len);
+
+ ngx_snprintf(b->pos, len, "GET %V HTTP/1.1\r\nHost: localhost\r\nUser-Agent: nginx/1.20.0\r\nAccept: */*\r\nConnection: close\r\n\r\n", &r->uri);
+
+ r->upstream->request_bufs = ngx_alloc_chain_link(r->pool);
+ if (!r->upstream->request_bufs)
+ return NGX_ERROR;
+
+ r->upstream->request_bufs->buf = b;
+ r->upstream->request_bufs->next = NULL;
+
+ r->upstream->request_sent = 0;
+ r->upstream->header_sent = 0;
+ r->header_hash = 1;
+
+ return NGX_OK;
+}
+
+static ngx_int_t abc_upstream_process_header(ngx_http_request_t *r)
+{
+ printf("%s(),%d\n", __func__, __LINE__);
+
+ ngx_http_upstream_main_conf_t* umcf;
+ ngx_http_upstream_header_t* uh;
+ ngx_http_upstream_t* u;
+ ngx_table_elt_t* h;
+ ngx_int_t rc;
+
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
+
+ u = r->upstream;
+
+ while (1) {
+ rc = ngx_http_parse_header_line(r, &u->buffer, 1);
+
+ if (NGX_OK == rc) {
+ h = ngx_list_push(&u->headers_in.headers);
+ if (!h)
+ return NGX_ERROR;
+
+ h->hash = r->header_hash;
+ h->key.len = r->header_name_end - r->header_name_start;
+ h->value.len = r->header_end - r->header_start;
+
+ h->key.data = ngx_pcalloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len);
+ if (!h->key.data)
+ return NGX_ERROR;
+
+ h->value.data = h->key.data + h->key.len + 1;
+ h->lowcase_key = h->value.data + h->value.len + 1;
+
+ ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
+ ngx_memcpy(h->value.data, r->header_start, h->value.len);
+ ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
+
+ uint8_t buf[1024] = {0};
+ ngx_snprintf(buf, 1023, "%V: %V\n", &h->key, &h->value);
+ printf("%s(),%d, %s\n", __func__, __LINE__, buf);
+
+ uh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len);
+ if (uh && uh->handler(r, h, uh->offset) != NGX_OK)
+ return NGX_ERROR;
+
+ } else if (NGX_HTTP_PARSE_HEADER_DONE == rc) {
+
+ if (!u->headers_in.server) {
+
+ h = ngx_list_push(&u->headers_in.headers);
+ if (!h)
+ return NGX_ERROR;
+
+ h->hash = ngx_hash_key((u_char*)"server", 6);
+
+ ngx_str_set (&h->key, "Server");
+ ngx_str_null(&h->value);
+ h->lowcase_key = (u_char*)"server";
+ }
+
+ if (!u->headers_in.date) {
+
+ h = ngx_list_push(&u->headers_in.headers);
+ if (!h)
+ return NGX_ERROR;
+
+ h->hash = ngx_hash_key((u_char*)"date", 4);
+
+ ngx_str_set (&h->key, "Date");
+ ngx_str_null(&h->value);
+ h->lowcase_key = (u_char*)"date";
+ }
+
+ printf("%s(),%d, done\n", __func__, __LINE__);
+ return NGX_OK;
+
+ } else if (NGX_AGAIN == rc)
+ return NGX_AGAIN;
+ else
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ }
+}
+
+static ngx_int_t abc_upstream_process_status(ngx_http_request_t *r)
+{
+ ngx_http_upstream_t* u;
+ ngx_http_abc_ctx_t* ctx;
+ ngx_int_t rc;
+ size_t len;
+
+ printf("%s(),%d\n", __func__, __LINE__);
+ ctx = ngx_http_get_module_ctx(r, ngx_http_abc_module);
+ if (!ctx)
+ return NGX_ERROR;
+
+ u = r->upstream;
+
+ rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);
+ if (NGX_AGAIN == rc)
+ return rc;
+
+ if (NGX_ERROR == rc)
+ return rc;
+
+ if (u->state)
+ u->state->status = ctx->status.code;
+
+ u->headers_in.status_n = ctx->status.code;
+
+ len = ctx->status.end - ctx->status.start;
+
+ u->headers_in.status_line.len = len;
+ u->headers_in.status_line.data = ngx_palloc(r->pool, len);
+ if (!u->headers_in.status_line.data)
+ return NGX_ERROR;
+
+ ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);
+
+ u->process_header = abc_upstream_process_header;
+
+ printf("%s(),%d, code: %ld\n", __func__, __LINE__, ctx->status.code);
+ return abc_upstream_process_header(r);
+}
+
+static void abc_upstream_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+ printf("%s(),%d\n\n", __func__, __LINE__);
+}
+
+static ngx_int_t ngx_http_abc_handler(ngx_http_request_t *r)
+{
+ printf("%s(),%d\n", __func__, __LINE__);
+
+ ngx_http_upstream_t* u;
+ ngx_http_abc_conf_t* abcf;
+ ngx_http_abc_ctx_t* ctx;
+ ngx_int_t rc;
+
+ if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_POST)))
+ return NGX_HTTP_NOT_ALLOWED;
+
+ r->request_body_in_file_only = 1;
+
+// rc = ngx_http_read_client_request_body(r, ngx_http_abc_body_handler);
+ rc = ngx_http_discard_request_body(r);
+ if (rc != NGX_OK)
+ return rc;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_abc_module);
+ if (!ctx) {
+ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_abc_ctx_t));
+ if (!ctx)
+ return NGX_ERROR;
+
+ ngx_http_set_ctx(r, ctx, ngx_http_abc_module);
+ } else {
+ ctx->status.code = 0;
+ ctx->status.count = 0;
+ ctx->status.start = NULL;
+ ctx->status.end = NULL;
+ }
+
+ if (ngx_http_upstream_create(r) != NGX_OK)
+ return NGX_ERROR;
+
+ u = r->upstream;
+ abcf = ngx_http_get_module_loc_conf(r, ngx_http_abc_module);
+
+ u->conf = &abcf->upstream;
+ u->buffering = abcf->upstream.buffering;
+
+ u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
+ if (!u->resolved)
+ return NGX_ERROR;
+
+ ngx_str_t host = ngx_string("localhost");
+
+ u->resolved->host.len = host.len;
+ u->resolved->host.data = ngx_palloc(r->pool, host.len);
+ if (!u->resolved->host.data)
+ return NGX_ERROR;
+
+ ngx_memcpy(u->resolved->host.data, host.data, host.len);
+
+ u->resolved->port = 80;
+
+ u->create_request = abc_upstream_create_request;
+ u->process_header = abc_upstream_process_status;
+ u->finalize_request = abc_upstream_finalize_request;
+
+ r->main->count++;
+
+ ngx_http_upstream_init(r);
+
+ printf("%s(),%d, subrequest_in_memory: %d\n", __func__, __LINE__, r->subrequest_in_memory);
+ return NGX_DONE;
}
static char* ngx_http_abc(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
@@ -73,6 +304,64 @@ static ngx_command_t ngx_http_abc_commands[] =
ngx_null_command
};
+static void* ngx_http_abc_create_loc_conf(ngx_conf_t *cf)
+{
+ ngx_http_abc_conf_t* abcf;
+
+ abcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_abc_conf_t));
+ if (!abcf)
+ return NULL;
+
+ abcf->upstream.connect_timeout = 60 * 1000;
+ abcf->upstream.send_timeout = 60 * 1000;
+ abcf->upstream.read_timeout = 60 * 1000;
+
+ abcf->upstream.store_access = 0666;
+ abcf->upstream.buffering = 0;
+ abcf->upstream.bufs.num = 8;
+ abcf->upstream.bufs.size = ngx_pagesize;
+ abcf->upstream.buffer_size = ngx_pagesize;
+
+ abcf->upstream.busy_buffers_size = 2 * ngx_pagesize;
+ abcf->upstream.temp_file_write_size = 2 * ngx_pagesize;
+ abcf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
+
+ abcf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
+ abcf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
+ return abcf;
+}
+
+static ngx_str_t ngx_http_proxy_hide_headers[] =
+{
+ ngx_string("Date"),
+ ngx_string("Server"),
+ ngx_string("X-Pad"),
+ ngx_string("X-Accel-Expires"),
+ ngx_string("X-Accel-Redirect"),
+ ngx_string("X-Accel-Limit-Rate"),
+ ngx_string("X-Accel-Buffering"),
+ ngx_string("X-Accel-Charset"),
+ ngx_null_string
+};
+
+static char* ngx_http_abc_merge_loc_conf(ngx_conf_t *cf, void *prev, void *conf)
+{
+ ngx_http_abc_conf_t* ccf = conf;
+ ngx_http_abc_conf_t* pcf = prev;
+
+ ngx_hash_init_t hash;
+
+ hash.max_size = 100;
+ hash.bucket_size = 1024;
+ hash.name = "proxy_headers_hash";
+
+ if (ngx_http_upstream_hide_headers_hash(cf, &ccf->upstream, &pcf->upstream, ngx_http_proxy_hide_headers, &hash) != NGX_OK)
+ return NGX_CONF_ERROR;
+
+ return NGX_CONF_OK;
+}
+
static ngx_http_module_t ngx_http_abc_module_ctx =
{
NULL, /* pre configuration */
@@ -84,8 +373,8 @@ static ngx_http_module_t ngx_http_abc_module_ctx =
NULL,
NULL,
- NULL,
- NULL,
+ ngx_http_abc_create_loc_conf,
+ ngx_http_abc_merge_loc_conf,
};
ngx_module_t ngx_http_abc_module =
diff --git a/ui/abc_layout.c b/ui/abc_layout.c
index 7332b45..0918e10 100644
--- a/ui/abc_layout.c
+++ b/ui/abc_layout.c
@@ -64,20 +64,17 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
if (width <= 0 || height <= 0)
return -EINVAL;
- int x = 4;
- int y = 4;
+ int x = root->x + 4;
+ int y = root->y + 4;
int h = 0;
- int __w = 0;
- int __h = 0;
+ int X = 0;
+ int Y = 0;
for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
child = scf_list_data(l, abc_obj_t, list);
- int ret = abc_layout_root(NULL, child, width, height);
- if (ret < 0)
- return ret;
-
+ int ret;
switch (child->type) {
case ABC_HTML_H1:
@@ -86,19 +83,31 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
case ABC_HTML_H4:
case ABC_HTML_H5:
case ABC_HTML_H6:
- case ABC_HTML_BR:
- child->x = 4;
+ child->x = root->x + 4;
child->y = y + h;
- x = 4;
+ ret = abc_layout_root(NULL, child, width, height);
+ if (ret < 0)
+ return ret;
+
+ x = root->x + 4;
y = child->y + child->h;
h = 0;
break;
+ case ABC_HTML_BR:
+ x = root->x + 4;
+ y += h;
+ h = 0;
default:
- if (child->w + x < width) {
- child->x = x;
- child->y = y;
+ child->x = x;
+ child->y = y;
+
+ ret = abc_layout_root(NULL, child, width, height);
+ if (ret < 0)
+ return ret;
+
+ if (x + child->w < width) {
if (h < child->h)
h = child->h;
@@ -107,34 +116,44 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
} else {
y += h;
- child->x = 4;
+ child->x = root->x + 4;
child->y = y;
+ ret = abc_layout_root(NULL, child, width, height);
+ if (ret < 0)
+ return ret;
+
h = child->h;
x = child->x + child->w;
}
+
+ if (ABC_HTML_P == child->type && ABC_HTML_P != root->type) {
+ x = root->x + 4;
+ y += h;
+ h = 0;
+ }
break;
};
if (child->keys)
scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->keys[0], child->x, child->y, child->w, child->h);
- if (__w < child->x + child->w)
- __w = child->x + child->w;
+ if (X < child->x + child->w)
+ X = child->x + child->w;
- if (__h < child->y + child->h)
- __h = child->y + child->h;
+ if (Y < child->y + child->h)
+ Y = child->y + child->h;
}
int ret = abc_layout_obj(NULL, root, width, height);
if (ret < 0)
return ret;
- if (root->w < __w)
- root->w = __w;
+ if (root->w < X - root->x)
+ root->w = X - root->x;
- if (root->h < __h)
- root->h = __h;
+ if (root->h < Y - root->y)
+ root->h = Y - root->y;
if (root->keys)
scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->keys[0], root->x, root->y, root->w, root->h);
diff --git a/ui/abc_layout_a.c b/ui/abc_layout_a.c
index e7f66f3..1635893 100644
--- a/ui/abc_layout_a.c
+++ b/ui/abc_layout_a.c
@@ -33,15 +33,15 @@ int abc_layout_a(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
cairo_text_extents(cr, obj->text->data, &extents);
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = extents.width + extents.x_bearing;
obj->h = extents.height + extents.height / 2;
obj->w = (obj->w + 3) & ~0x3;
obj->h = (obj->h + 3) & ~0x3;
- scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
+ scf_logi("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
obj->text->data, obj->w, obj->h,
extents.x_bearing, extents.y_bearing, extents.width, extents.height,
extents.x_advance, extents.y_advance);
diff --git a/ui/abc_layout_form.c b/ui/abc_layout_form.c
index 9b7d25f..6023fdb 100644
--- a/ui/abc_layout_form.c
+++ b/ui/abc_layout_form.c
@@ -24,8 +24,8 @@ int abc_layout_form(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, obj->text->data, &extents);
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = extents.width + extents.x_bearing;
obj->h = extents.height + extents.height / 2;
diff --git a/ui/abc_layout_h1.c b/ui/abc_layout_h1.c
index 6033f38..2242bf8 100644
--- a/ui/abc_layout_h1.c
+++ b/ui/abc_layout_h1.c
@@ -24,8 +24,8 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, obj->text->data, &extents);
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = extents.width + extents.x_bearing;
obj->h = extents.height + extents.height / 2;
diff --git a/ui/abc_layout_img.c b/ui/abc_layout_img.c
index 5744271..4e6a814 100644
--- a/ui/abc_layout_img.c
+++ b/ui/abc_layout_img.c
@@ -22,8 +22,8 @@ int abc_layout_img(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
};
}
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = (obj->w + 3) & ~0x3;
obj->h = (obj->h + 3) & ~0x3;
diff --git a/ui/abc_layout_input.c b/ui/abc_layout_input.c
index b08bdfe..eb34e59 100644
--- a/ui/abc_layout_input.c
+++ b/ui/abc_layout_input.c
@@ -35,8 +35,8 @@ int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, text, &extents);
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = extents.width + extents.x_bearing;
obj->h = extents.height;
diff --git a/ui/abc_layout_label.c b/ui/abc_layout_label.c
index 7a7aa83..53a5181 100644
--- a/ui/abc_layout_label.c
+++ b/ui/abc_layout_label.c
@@ -24,8 +24,8 @@ int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, obj->text->data, &extents);
- obj->x = 4;
- obj->y = 4;
+// obj->x = 4;
+// obj->y = 4;
obj->w = extents.width + extents.x_bearing;
obj->h = extents.height;
--
2.25.1