2006. március 23., csütörtök

Simple HTML parsing and painting


Problem/Question/Abstract:

How to do simple HTML parsing and painting

Answer:

This morning a friend asked me how to do a simple HTML parsing. He wanted to implement a hint box with formatting possibilities.

So I developed a very simple procedure which draws the contents of a string to a rectangle on a canvas. It only understands the HTML tags b, i and u, and it moves to the next line when it finds a new line code. (This is not HTML conform, but in this case really useful)

The parsing itself is extremely simple, but you need to work  with pointers and not with strings since they make it more difficult to get each individual character.

The following procedure is just a little example. If you need HTML editing/painting please try out WPTools.

// Draw simple HTML text to any canvas
// 3/16/2000 by Julian Ziersch, http://www.ziersch.com/
// Products: WPTools, WPReporter, WPForm
// wPDF: PDF Export for WPTools

procedure DrawHTML(r: TRect; aCanvas: TCanvas; const text: string);
var
  p: PChar;
  c: Char;
  x, y, w, wc, hc: Integer;
  code: string;
begin
  p := PChar(text);
  x := r.Left;
  y := r.Top;
  hc := aCanvas.TextHeight('Ag');
  if p <> nil then
    while p^ <> #0 do
    begin
      c := p^;
      if c = '<' then
      begin
        code := '';
        inc(p);
        while (p^ <> '>') and (p^ <> #0) do
        begin
          code := code + uppercase(p^);
          inc(p);
        end;
        if code = 'B' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style + [fsBold]
        else if code = 'I' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style + [fsItalic]
        else if code = 'U' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style + [fsUnderline]
        else if code = '/B' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style - [fsBold]
        else if code = '/I' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style - [fsItalic]
        else if code = '/U' then
          aCanvas.Font.Style :=
            aCanvas.Font.Style - [fsUnderline];
      end
      else if c = #10 then
      begin
        x := r.Left;
        inc(y, hc);
      end
      else if c >= #32 then
      begin
        wc := aCanvas.TextWidth(c);
        if x + wc > r.Right then
        begin
          x := r.Left;
          inc(y, hc);
        end;
        if y + hc < r.Bottom then
          aCanvas.TextOut(x, y, c);
        inc(x, wc);
      end;
      if p^ > #0 then
        inc(p);
    end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése