simple http download ok by nginx upstream proxy
authoryu.dongliang <18588496441@163.com>
Wed, 6 Nov 2024 15:02:23 +0000 (23:02 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 6 Nov 2024 15:02:23 +0000 (23:02 +0800)
13 files changed:
examples/nginx.html [new file with mode: 0644]
html/abc_html.c
html/abc_io_http.c
html/abc_obj.h
net/ngx_http_abc.h
net/ngx_http_abc_module.c
ui/abc_layout.c
ui/abc_layout_a.c
ui/abc_layout_form.c
ui/abc_layout_h1.c
ui/abc_layout_img.c
ui/abc_layout_input.c
ui/abc_layout_label.c

diff --git a/examples/nginx.html b/examples/nginx.html
new file mode 100644 (file)
index 0000000..79cd51e
--- /dev/null
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>Welcome to nginx!</title>
+</head>
+<body>
+<h1>Welcome to nginx!</h1>
+<p>If you see this page, the nginx web server is successfully installed and
+working. Further configuration is required.</p>
+
+<p>For online documentation and support please refer to
+<a href="http://nginx.org/">nginx.org</a><br>
+Commercial support is available at
+<a href="http://nginx.com/">nginx.com</a></p>
+
+<p>Thank you for using nginx.</p>
+</body>
+</html>
index 82afe9384dfb9cc7da27570fe711aa6092d7f100..3f3485983c8b948a436cfa4661c70c738d247566 100644 (file)
@@ -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;
index 8e291601e27b12a8a4ef09585ff47c9af8007c50..d62afd5000e0d144fbd4c21d4982ac809eced81c 100644 (file)
@@ -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);
                        }
index d3de45764359b16e61105f3cdb655694a81435e8..ac7b04ca69b2801537f4edc0aeb97590568ebc36 100644 (file)
@@ -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
 
index 01aabf804d5b197577d746be444115af4eb96451..e7bce377068559c95a885130b09bddbedc2e96de 100644 (file)
@@ -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
index 2040d5143a52cddd41301adad5f8571edcd3fdde..14ad489edb6b842c2eb0cf30667e72f20ffcab48 100644 (file)
@@ -2,24 +2,15 @@
 #include <ngx_core.h>
 #include <ngx_http.h>
 #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("<html><head><title>hello</title></head><body><h1>hello world</h1></body></html>");
+       ngx_str_t    type = ngx_string("text/html");
+       ngx_str_t    body = ngx_string("<html><head><title>hello</title></head><body><h1>hello world</h1></body></html>");
 
        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 =
index 7332b456708d2d13cfb650ac5a3a26e1b83184e8..0918e106cd55cb5b6f2d9f7877431fc1f494f7a7 100644 (file)
@@ -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);
index e7f66f34a989276ce0c97eed34aac3f6fd28a5f1..16358932917d684824a171bf34acc90c8e440e79 100644 (file)
@@ -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);
index 9b7d25fba74616b16fc7fe625858045970068eee..6023fdb3b28a9f776598620174b778e61f1100a6 100644 (file)
@@ -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;
 
index 6033f38fc0db0c9906cfbb7759d625d8aa61a934..2242bf88bcb4194e09adcbd5ec8e7332b8f2aba6 100644 (file)
@@ -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;
 
index 57442718b9cd27132dbfbee87af1e4b14a92efd0..4e6a814cc1d3ca9e60cd8b41d07c52f80abb47d7 100644 (file)
@@ -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;
index b08bdfe159bc3415842434b2d4764e618d4ea972..eb34e5935f3234c3096301d842073b1d45dab115 100644 (file)
@@ -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;
 
index 7a7aa83dcaafa34a6e3d7103236cfcdee704879d..53a51818f62cb38d510f627f1bff266fbcce3119 100644 (file)
@@ -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;