Subversion Repositories Kolibri OS

Rev

Rev 7781 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*========================================================
  2. =                                                        =
  3. =                        STYLE                           =
  4. =                                                        =
  5. ========================================================*/
  6. #define HTML_PADDING_X 8;
  7. #define HTML_PADDING_Y 5;
  8.  
  9. struct _style {
  10.         bool bold, underlined, italic, strike;
  11.         bool h1, h2, h3, h4, h5, h6;
  12.         bool a;
  13.         bool pre;
  14.         bool ignore;
  15.         bool body;
  16.         dword color;
  17.         void clear();
  18. };
  19.  
  20. void _style::clear()
  21. {
  22.         bold=underlined=italic=strike=0;
  23.         h1=h2=h3=h4=h5=h6=0;
  24.         a=0;
  25.         pre=0;
  26.         ignore=0;
  27.         color=0;
  28.         body=0;
  29. }
  30.  
  31. /*========================================================
  32. =                                                        =
  33. =                         TAG                            =
  34. =                                                        =
  35. ========================================================*/
  36. struct _tag {
  37.         dword start;
  38.         dword end;
  39.         dword name;
  40.  
  41.         bool opens;
  42.  
  43.         dword attribute;
  44.         dword value;
  45.  
  46.         void parse();
  47.         int nameis();
  48. };
  49.  
  50. void _tag::parse()
  51. {
  52.         dword START = start;
  53.  
  54.         calc(1); //WTF
  55.  
  56.         if (ESBYTE[START]=='/') {
  57.                 START++;
  58.                 opens = false;
  59.         } else opens = true;
  60.  
  61.         name = START;
  62.        
  63.         while ( (START < end) && (!__isWhite(ESBYTE[START])) ) {
  64.                 START++;
  65.         }
  66.         if (START!=end) ESBYTE[START] = '\0';
  67.         START++;
  68.  
  69.         strlwr(name);
  70.  
  71.         start = START;
  72. }
  73.  
  74. int _tag::nameis(dword _in_tag_name)
  75. {
  76.         if (name) && (streq(_in_tag_name, name)) return true;
  77.         return false;
  78. }
  79.  
  80. /*========================================================
  81. =                                                        =
  82. =                         DRAW                           =
  83. =                                                        =
  84. ========================================================*/
  85. struct _draw
  86. {
  87.         dword x;
  88.         dword y;
  89.         void init();
  90.         void line_break();
  91. };
  92.  
  93. void _draw::init()
  94. {
  95.         x = HTML_PADDING_X;
  96.         y = HTML_PADDING_Y;
  97. }
  98. void _draw::line_break()
  99. {
  100.         y+= list.item_h;
  101.         x = HTML_PADDING_X;    
  102. }
  103.  
  104. /*========================================================
  105. =                                                        =
  106. =                         BUF                            =
  107. =                                                        =
  108. ========================================================*/
  109. struct _buf
  110. {
  111.         dword pointer;
  112.         dword len;
  113.         dword start;
  114.         dword end;
  115.         void init();
  116. };
  117.  
  118. void _buf::init(dword _buf_pointer, _buf_len)
  119. {
  120.         pointer = _buf_pointer;
  121.         len = _buf_len;
  122.         start = malloc(len);
  123.         end = start + len;
  124.         strlcpy(start, pointer, len);  
  125. }
  126.  
  127. /*========================================================
  128. =                                                        =
  129. =                         TEXT                           =
  130. =                                                        =
  131. ========================================================*/
  132. struct _text {
  133.         int size_pt_change;
  134.         dword start;
  135.         dword end;
  136.  
  137.         dword width;
  138. };
  139.  
  140. /*========================================================
  141. =                                                        =
  142. =                         DOM                            =
  143. =                                                        =
  144. ========================================================*/
  145. struct _dom
  146. {
  147.         _tag tag;
  148.         _style style;
  149.         _draw draw;
  150.         _buf buf;
  151.         _text text;
  152.         _canvas canvas;
  153.         void init();
  154.         void apply_text();
  155.         void set_style();
  156.         void parse();
  157. };
  158.  
  159. void _dom::init()
  160. {
  161.         style.clear();
  162.         draw.init();
  163.         buf.init(io.buffer_data, strlen(io.buffer_data));
  164. }
  165.  
  166. void _dom::set_style()
  167. {
  168.         if (tag.nameis("body")) style.body = tag.opens;
  169.         if (tag.nameis("b")) style.bold = tag.opens;
  170.         if (tag.nameis("i")) style.italic = tag.opens;
  171.         if (tag.nameis("s")) style.strike = tag.opens;
  172.         if (tag.nameis("pre")) style.pre = tag.opens;
  173.         if (tag.nameis("style")) style.ignore = tag.opens;
  174.         if (tag.nameis("a"))  {
  175.                 style.a = tag.opens;
  176.                 if (tag.opens) style.color=0x0000FF; else style.color=0;
  177.         }
  178.        
  179.         if (tag.nameis("br"))
  180.                 || (tag.nameis("p"))
  181.                 || (tag.nameis("div"))
  182.                 || (tag.nameis("tr")) {
  183.                 draw.line_break();
  184.                 return;
  185.         }
  186.  
  187.         if (tag.nameis("li")) && (tag.opens) {
  188.                 draw.line_break();
  189.                 return;
  190.         }
  191.  
  192.         if (tag.nameis("td")) && (tag.opens) {
  193.                 draw.line_break();
  194.                 return;
  195.         }
  196.  
  197.         /*
  198.         if (tag.nameis("title")) {
  199.                 strcpy(#title, text.start);
  200.                 strcat(#title, " - Aelia");
  201.                 DrawTitle(#title);
  202.         }
  203.  
  204.         if      (tag.nameis("h1")) || (tag.nameis("/h1")) ||
  205.                 (tag.nameis("h2")) || (tag.nameis("/h2")) ||
  206.                 (tag.nameis("h3")) || (tag.nameis("/h3")) {
  207.                 if (tag.nameis("h1")) {
  208.                         text.size_pt_change = 8;
  209.                 } else if (tag.nameis("/h1")) {
  210.                         text.size_pt_change = -8;
  211.                 } else if (tag.nameis("h2")) {
  212.                         text.size_pt_change = 6;
  213.                 } else if (tag.nameis("/h2")) {
  214.                         text.size_pt_change = -6;
  215.                 } else if (tag.nameis("h3")) {
  216.                         text.size_pt_change = 4;
  217.                 } else if (tag.nameis("/h3")) {
  218.                         text.size_pt_change = -4;
  219.                 }
  220.                 kfont.size.pt += text.size_pt_change;
  221.                 get_label_symbols_size();
  222.                 if (text.size_pt_change > 0) {
  223.                         draw.y+= list.item_h;//что если будет очень длинная строка в теге?
  224.                 } else {//коммент выше и коммент ниже связаны
  225.                         draw.y+= list.item_h - text.size_pt_change;//не очень понятна логика этого места
  226.                         text.size_pt_change = 0;
  227.                 }
  228.                 draw.x = HTML_PADDING_X;
  229.                 return;                                
  230.         }
  231.         */
  232. }
  233.  
  234. void _dom::apply_text(dword _intext)
  235. {
  236.         int label_w;
  237.         int textlen = strlen(_intext);
  238.         dword curline = malloc(textlen);
  239.  
  240.         if (!textlen) || (!style.body) return;
  241.  
  242.         do {
  243.                 strlcpy(curline, _intext, textlen);
  244.                 label_w = kfont.get_label_width(curline);
  245.                 textlen--;
  246.         } while (label_w > list.w - draw.x - 10) && (textlen);
  247.  
  248.         kfont.bold = style.bold;
  249.  
  250.         if (kfont.size.height) {
  251.                 canvas.write_text(draw.x, draw.y, style.color, curline);
  252.                 if (style.a) {
  253.                         canvas.draw_hor_line(draw.x, draw.y + list.item_h-2,
  254.                                 kfont.get_label_width(curline), style.color);
  255.                         link.add(draw.x, draw.y, kfont.get_label_width(curline),
  256.                                 list.item_h, curline, "http://kolibrios.org");
  257.                 }              
  258.         }
  259.         draw.x += label_w;
  260.         strcpy(curline, _intext + textlen);
  261.  
  262.         if (textlen) && (textlen < strlen(_intext)-1) {
  263.                 draw.x = 0;
  264.                 draw.y += list.item_h;
  265.                 apply_text(_intext + textlen);
  266.         }
  267. }
  268.  
  269. void _dom::parse()
  270. {
  271.         dword i;
  272.         init();
  273.  
  274.         text.start = buf.start;
  275.         tag.start = buf.start;
  276.         for ( i=buf.start; i<buf.end; i++ )
  277.         {
  278.                 if (ESBYTE[i]=='<') {
  279.                         tag.start = i+1;
  280.                         text.end = i-1;
  281.                         ESBYTE[i] = '\0';
  282.                         apply_text(text.start);
  283.                 }
  284.                 if (ESBYTE[i]=='>') {
  285.                         tag.end = i-1;
  286.                         text.start = i+1;
  287.                         ESBYTE[i] = '\0';
  288.                         tag.parse();
  289.                         set_style();
  290.                 }
  291.         }
  292.  
  293.         free(buf.start);
  294.         if (!kfont.size.height) {
  295.                 list.count = draw.y/list.item_h+3;
  296.                 if (list.count < list.visible) list.count = list.visible;
  297.                 kfont.size.height = list.count+5*list.item_h;
  298.                 kfont.raw_size = 0;
  299.                 parse();
  300.         }
  301. }
  302.  
  303.  
  304.  
  305. /*========================================================
  306. =                                                        =
  307. =                       PREPARE                          =
  308. =                                                        =
  309. ========================================================*/
  310. void PreparePage()
  311. {
  312.         _dom dom;
  313.  
  314.         strcpy(#title, history.current()+strrchr(history.current(),'/'));
  315.         ChangeCharset(encoding, "CP866", io.buffer_data);
  316.         link.clear();
  317.  
  318.         kfont.size.height = 0;
  319.  
  320.         dom.parse();
  321.  
  322.         kfont.ApplySmooth();
  323.  
  324.         DrawPage();
  325. }
  326.