Subversion Repositories Kolibri OS

Rev

Rev 7291 | 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. dword line_break;
  142. byte char_holder;
  143.  
  144. if (ESBYTE[buf.pos]==0x0A) {
  145.         if (style.pre) {
  146.                 draw.line_break();
  147.                 continue;
  148.         }
  149. }
  150.  
  151. while (get_label_len(text.start) + draw.x + 30 > list.w)
  152. {
  153.         for (line_break=tag.start-1; line_break>text.start; line_break--;)
  154.         {
  155.                 char_holder = ESBYTE[line_break]; //set line end
  156.                 ESBYTE[line_break] = '\0';
  157.                 if (get_label_len(text.start) + draw.x + 30 <= list.w) break;
  158.                 ESBYTE[line_break] = char_holder; //restore line
  159.         }
  160.         if (draw_on) {
  161.                 if (style.a) {
  162.                         link.add(draw.x,draw.y + size_pt_change,get_label_len(text.start),list.item_h,text.start," ");
  163.                         label_draw_bar(draw.x, draw.y+kfont.size.pt+1, get_label_len(text.start), style.color);
  164.                 }
  165.                 WriteTextIntoBuf(draw.x, draw.y, style.color, text.start);
  166.         }
  167.         draw.x+=char_width[' '];
  168.         ESBYTE[line_break] = char_holder; //restore line
  169.         text.start = line_break;
  170.         draw.line_break();
  171. }
  172. if (draw_on) {
  173.         if (style.a) {
  174.                 link.add(draw.x,draw.y + size_pt_change,get_label_len(text.start),list.item_h,text.start," "); 
  175.                 label_draw_bar(draw.x, draw.y+kfont.size.pt+1, get_label_len(text.start), style.color);
  176.         }
  177.         WriteTextIntoBuf(draw.x, draw.y, style.color, text.start);
  178. }
  179. draw.x += char_width[' '];
  180. draw.x += get_label_len(text.start);
  181. */
  182.  
  183.  
  184. /*========================================================
  185. =                                                        =
  186. =                         DOM                            =
  187. =                                                        =
  188. ========================================================*/
  189. struct _dom
  190. {
  191.         _tag tag;
  192.         _style style;
  193.         _draw draw;
  194.         _buf buf;
  195.         _text text;
  196.         _canvas canvas;
  197.         void init();
  198.         void apply_text();
  199.         void set_style();
  200.         void parse();
  201. };
  202.  
  203. void _dom::init()
  204. {
  205.         style.clear();
  206.         draw.init();
  207.         buf.init(io.buffer_data, strlen(io.buffer_data));
  208. }
  209.  
  210. void _dom::set_style()
  211. {
  212.         if (tag.nameis("body")) style.body = tag.opens;
  213.         if (tag.nameis("b")) style.bold = tag.opens;
  214.         if (tag.nameis("i")) style.italic = tag.opens;
  215.         if (tag.nameis("s")) style.strike = tag.opens;
  216.         if (tag.nameis("pre")) style.pre = tag.opens;
  217.         if (tag.nameis("style")) style.ignore = tag.opens;
  218.         if (tag.nameis("a"))  {
  219.                 style.a = tag.opens;
  220.                 if (tag.opens) style.color=0x0000FF; else style.color=0;
  221.         }
  222.        
  223.         if (tag.nameis("br"))
  224.                 || (tag.nameis("p"))
  225.                 || (tag.nameis("div"))
  226.                 || (tag.nameis("tr")) {
  227.                 draw.line_break();
  228.                 return;
  229.         }
  230.  
  231.         if (tag.nameis("li")) && (tag.opens) {
  232.                 draw.line_break();
  233.                 return;
  234.         }
  235.  
  236.         if (tag.nameis("td")) && (tag.opens) {
  237.                 draw.line_break();
  238.                 return;
  239.         }
  240.  
  241.         /*
  242.         if (tag.nameis("title")) {
  243.                 strcpy(#title, text.start);
  244.                 strcat(#title, " - Aelia");
  245.                 DrawTitle(#title);
  246.         }
  247.  
  248.         if      (tag.nameis("h1")) || (tag.nameis("/h1")) ||
  249.                 (tag.nameis("h2")) || (tag.nameis("/h2")) ||
  250.                 (tag.nameis("h3")) || (tag.nameis("/h3")) {
  251.                 if (tag.nameis("h1")) {
  252.                         text.size_pt_change = 8;
  253.                 } else if (tag.nameis("/h1")) {
  254.                         text.size_pt_change = -8;
  255.                 } else if (tag.nameis("h2")) {
  256.                         text.size_pt_change = 6;
  257.                 } else if (tag.nameis("/h2")) {
  258.                         text.size_pt_change = -6;
  259.                 } else if (tag.nameis("h3")) {
  260.                         text.size_pt_change = 4;
  261.                 } else if (tag.nameis("/h3")) {
  262.                         text.size_pt_change = -4;
  263.                 }
  264.                 kfont.size.pt += text.size_pt_change;
  265.                 get_label_symbols_size();
  266.                 if (text.size_pt_change > 0) {
  267.                         draw.y+= list.item_h;//что если будет очень длинная строка в теге?
  268.                 } else {//коммент выше и коммент ниже связаны
  269.                         draw.y+= list.item_h - text.size_pt_change;//не очень понятна логика этого места
  270.                         text.size_pt_change = 0;
  271.                 }
  272.                 draw.x = HTML_PADDING_X;
  273.                 return;                                
  274.         }
  275.         */
  276. }
  277.  
  278. void _dom::apply_text()
  279. {
  280.         if (kfont.size.height) && (style.body) {
  281.                 kfont.bold = style.bold;
  282.                 canvas.write_text(draw.x, draw.y, style.color, text.start);
  283.                 if (style.a) {
  284.                         canvas.draw_hor_line(draw.x, draw.y + list.item_h-2, kfont.get_label_width(text.start), style.color);
  285.                         link.add(draw.x, draw.y, kfont.get_label_width(text.start), list.item_h, text.start, "http://kolibrios.org");
  286.                 }
  287.         }
  288. }
  289.  
  290. void _dom::parse()
  291. {
  292.         dword i;
  293.         init();
  294.  
  295.         text.start = buf.start;
  296.         tag.start = buf.start;
  297.         for ( i=buf.start; i<buf.end; i++ )
  298.         {
  299.                 if (ESBYTE[i]=='<') {
  300.                         tag.start = i+1;
  301.                         text.end = i-1;
  302.                         ESBYTE[i] = '\0';
  303.                         apply_text();
  304.                 }
  305.                 if (ESBYTE[i]=='>') {
  306.                         tag.end = i-1;
  307.                         text.start = i+1;
  308.                         ESBYTE[i] = '\0';
  309.                         tag.parse();
  310.                         set_style();
  311.                 }
  312.         }
  313.  
  314.         free(buf.start);
  315.         if (!kfont.size.height) {
  316.                 list.count = draw.y/list.item_h+3;
  317.                 if (list.count < list.visible) list.count = list.visible;
  318.                 kfont.size.height = list.count+5*list.item_h;
  319.                 kfont.raw_size = 0;
  320.                 parse();
  321.         }
  322. }
  323.  
  324.  
  325.  
  326. /*========================================================
  327. =                                                        =
  328. =                       PREPARE                          =
  329. =                                                        =
  330. ========================================================*/
  331. void PreparePage()
  332. {
  333.         _dom dom;
  334.  
  335.         strcpy(#title, history.current()+strrchr(history.current(),'/'));
  336.         ChangeCharset(charsets[encoding], "CP866", io.buffer_data);
  337.         link.clear();
  338.  
  339.         kfont.size.height = 0;
  340.  
  341.         if ( strstri(io.buffer_data, "<html") == -1 ) ParseTxt(); else dom.parse();
  342.  
  343.         kfont.ApplySmooth();
  344.  
  345.         DrawPage();
  346. }
  347.  
  348. void ParseTxt()
  349. {
  350. _canvas canvas;
  351. byte ch, zeroch=0;
  352. dword bufoff, buflen, line_start, srch_pos;
  353. int stroka_y=5, line_length=0;
  354.  
  355.         line_start=io.buffer_data;
  356.         buflen = strlen(io.buffer_data) + io.buffer_data;
  357.         for (bufoff=io.buffer_data; bufoff<buflen; bufoff++)
  358.         {
  359.                 ch = ESBYTE[bufoff];
  360.                 line_length += kfont_char_width[ch];
  361.                 if (line_length>=list.w-30) || (ch==10) {
  362.                         srch_pos = bufoff;
  363.                         loop()
  364.                         {
  365.                                 if (__isWhite(ESBYTE[srch_pos])) { bufoff=srch_pos+1; break; } //normal word-break
  366.                                 if (srch_pos == line_start) break; //no white space found in whole line
  367.                                 srch_pos--;
  368.                         }
  369.                         if (kfont.size.height) {
  370.                                 ESBYTE[bufoff] >< zeroch; //set line end
  371.                                 canvas.write_text(8, stroka_y, 0x000000, line_start);
  372.                                 ESBYTE[bufoff] >< zeroch; //restore line
  373.                         }
  374.                         stroka_y += list.item_h;
  375.                         line_start = bufoff;
  376.                         line_length = 0;
  377.                 }
  378.         }
  379.         if (!kfont.size.height) {
  380.                 list.count = stroka_y/list.item_h+3;
  381.                 if (list.count < list.visible) list.count = list.visible;
  382.                 kfont.size.height = list.count+5*list.item_h;
  383.                 kfont.raw_size = 0;
  384.                 ParseTxt();
  385.         }
  386.         else canvas.write_text(8, stroka_y, 0x000000, line_start);
  387. }