🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #1618

Edytor tekstu

#1618
From: Marcin Zielinski
Date: Wed, 18 Feb 1998 07:33
137 lines
6074 bytes
Mam problem z napisaniem edytora tekstu.

Mój edytor ma wczytywać dane z pliku HTML i wyświetlać na ekranie tekst, w
którym zaznaczone by były znaczniki tego języka. Ja już próbowałem i
przedstawię Ci moje rozwiązanie, które jest dobre, ale przy dokumentach
mających długie linie (po 600 znaków) strasznie szwankuje szybkość rysowania
tekstu. Poza małą prędkością mój algorytm nie radzi sobie z np: łamaniem
lini kodu HTML tzn. jeśli na przykład mamy taki fragment kodu HTML:

<body
background="ala.gif">

to zostanie podświetlone tylko słowo body, a reszta będzie traktowana jak
zwykły tekst.
Napisałem już kawałek programu wyświetlającego ten tekst, dlatego poniżej
przedstawię Ci to co udało mi się zrobić.
(Program pisany jest w Visual C++)

Zdefiniowałem klasę CHTMLEditorDoc, w której dodałem zmienną CStringArray
lines przechowywującą linie tekstu.

Zdefiniowałem również klasę CHTMLEditorView, odpowiedzialną, za wyświetlanie
tekstu w okienku. (dziedziczy ona po klasie CScrollView), a o to dodane
przezemnie funkcje i składowe:

const fs_FormatChar = 0x10;
const fs_Normal  = 0x11;

class CFranekView : public CScrollView
{
public: // Funkcje obslugi slow kluczowych
 static CObArray *keyWords; // Keywords - slowa kluczowe, ktore np: beda
podswietlane
static CKeyWord *FindKeyWord(char *keyWord); // Odszukuje slowo kluczowe
protected: // create from serialization only
// Zmienne mające za zadanie przyśpieszyć rysowanie na ekranie. Funkcja
OnDraw rysuje tylko tyle ile jest
// widziane na ekranie
 int charsVisible; // ilość znaków widzianych
 int linesVisible; // ilość lini widzianych

public:
 int topLine, bottomLine; // Numer gornej i dolnej widocznej na ekranie lini

protected:
 CFont *font; // Czcionka, którą ma być wyświetlany tekst
private:
 CSize fontSize; // Rozmiary czcionki. Potrzebne by dokładnie pozycjonować
kursor w czasie edycji
 int FindChar(LPCSTR text, char c, int start); // Funkcja przyśpieszająca
wyszukiwanie znaków
 void DrawLine(CDC *pDC, CPoint pos, LPCSTR str); // funkcja rysuje na dane
pozycji tekst z parametru str
 CString FormatString(LPCSTR string);
    .
    .
    .
    .
};
W tej klasie znajduje się również funkcja OnDraw(CDC *pDC), którą
zaimplementowałem tak:

 CFranekDoc* pDoc = GetDocument(); // Pobiera wskaznik do dokumentu
 ASSERT_VALID(pDoc); // Dodane przez VC++
 pDC->SetBkMode(TRANSPARENT);
 for (int i = topLine; i < bottomLine; i++)
 {
  CString line; // Linia, ktora jest poddawana obrobce

  if (i > pDoc->lines.GetSize() - 1) break; // Zabezpieczenie przed wyjsciem
poza zakres tablicy lines
  line = ((CLine *)pDoc->lines[i])->lineText; // Kopiuje linie, ktora ma byc
rysowana
  CString formatedString = ""; // Linia sformatowana, dla funkcji DrawLine
  BOOL section = FALSE; // Informacja o tym, że jest teraz sekcja HTML
  int j = 0;
  int lineLength = line.GetLength(); // Za zadanie ma przyśpieszyć funkcję
  while (j < lineLength)
  {
   if (line[j] == '<')  // Czy znacznik HTML
   {
    section = TRUE; // Zaczyna się sekcja HTML
    formatedString += line.Left(j) + FS_RESTORE; // Do tekstu formatowanego
kopiuje cały tekst wcześniejszy, który nie jest tekstem HTML'a
    int k = lineLength - j;
    if (k > 0)
     line = line.Right(k); // Obcina linie do znaku <
    else
     line = ""; // Jezeli dlugość pozostałej linii jest 0
    lineLength = line.GetLength();
    j = 0;
   } else
    if ((line[j] == '>') & (section)) // Jezeli znak kończący sekcję
    {
     formatedString += FormatString(line.Left(j + 1)); // Wywołuje funckcję
formatującą , która zwraca tekst sformatowany
     line = line.Right(line.GetLength() - j - 1); // Obcina znowu linie, bo
już
     lineLength = line.GetLength();
     section = FALSE;
     j = 0;
    };
   j++;
  };
  formatedString += line + FS_RESTORE; // FS_RESTORE mówi, że tekst po tym
znaczniku ma być rysowany
// czcionką domyślną
  DrawLine(pDC, CPoint(0, i), formatedString); // Rysuje linie na ekranie
 };

Funkcja FormatString szuka słów, jeśli okaże się, że dane słowo jest słowem
HTML'a to wstawia znaczniki formatowania przed danym słowem. Format
znaczników jest taki:
znak fs_FormatChar (mówiący, że dalej zaczyna się informacja o czcionce)
jeśli po tym znaczniku znajduje się znacznik fs_Normal to przywracana jest
czcionka domyślna, jeśli nie to po kolei zapisywane są bajty: pogrubienie,
pochyłość, oraz na końcu trzy składowe koloru powiększone o 1 (by nie było
znaku końca łancucha dla np: koloru 0x000000).

Funkcja DrawLine przeszukuje tekst z parametru str i gdy znajdzie znak
fs_FormatChar ustawia odpowiednią czcionkę. Gdy znajdzie znak fs_FormatChar,
a po nim znak fs_Normal to rysuje tekst do tych dwóch znaków i ustawia
domyślną czcionkę.

Algorytm jest nawet sprawny, gdyby nie to, że musi on tyle razy przeszukiwać
dane łańcuchy. Nawet wstawki w assemblerze nie rozwiązuję tego problemu.
Ponieważ nie za dobże potrafię tłumaczyć co mi chodzi po głowie, dlatego
jeśli czegoś nie będziesz wiedział napisz do mnie.

Proszę o pomoc, za którą z góry dziękuję.
------------------------------------------
Marcin Zielinski
e-mail: zielu1@polbox.com
e-mail: zielu1@friko3.onet.pl
http://free.polbox.pl/z/zielu1
http://friko3.onet.pl/wa/zielu1
------------------------------------------
Technical Details
Message-ID: <34ea8f4a.0@news.tpnet.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.tpnet.pl!ppp-cst6.warszawa.tpnet.pl

Show Full Headers
Complete Article Headers
From: "Marcin Zielinski" <zielu1@friko3.onet.pl>
Newsgroups: pl.comp.lang.c
Subject: Edytor tekstu
Date: Wed, 18 Feb 1998 08:33:18 +0100
Lines: 139
X-Newsreader: Microsoft Outlook Express 4.71.1712.3
X-MimeOLE: Produced By Microsoft MimeOLE V4.71.1712.3
NNTP-Posting-Host: ppp-cst6.warszawa.tpnet.pl
Message-ID: <34ea8f4a.0@news.tpnet.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.tpnet.pl!ppp-cst6.warszawa.tpnet.pl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit