🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

5 total messages Started by Marcin Zielinski Wed, 18 Feb 1998 07:33
Edytor tekstu
#1618
Author: 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
------------------------------------------
Re: Edytor tekstu
#1619
Author: Perfect Drug
Date: Wed, 18 Feb 1998 13:25
5 lines
940 bytes
Sprobuj zaczac uzywac takich narzedzi jak LEX, a znikna Twoje problemy
zwiazane z analiza leksykalna tekstow. Dodatkowo, jesli dorzucisz do tego
YACCA to bedziesz mogl tez sobie sprawdzac poprawnosc skladniowa danych
wejsciowych...
banita :)
Re: Edytor tekstu
#1620
Author: Piotr Kaminski
Date: Wed, 18 Feb 1998 21:22
25 lines
1704 bytes
On Wed, 18 Feb 1998 08:33:18 +0100, "Marcin Zielinski"
<zielu1@friko3.onet.pl> arranged ASCII characters in a pattern:

>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:
>

Nasunelo mi sie pare uwag:

1) korzystasz z CStringList/Array -> Twój edytor obsłuży tylko do
maxint linii. Każdy CString ma do MAXINT znaków (sorki, jeśli źle
mówię - mam stare informacje, może w nowszych wydaniach VC++ (tzn. 32
- bit) jest to inaczej.

2) Piszesz, że korzystasz z czcionki domyślnej - ja radzę
dc.SelectStockObject(ANSI_FIXED_FONT), wtedy każda literka ma
identyczną szerokość i może po ludzku przesuwać kursor.

Pozdrawiam, Piotr
Re: Edytor tekstu
#1622
Author: Jacek Sikora
Date: Thu, 19 Feb 1998 08:51
12 lines
1363 bytes
Na pierwszy rzut oka nasuwajš mi się dwie uwagi:
1. Pliku HTML nie powinieneś parsować w funkcji OnDraw - bo wtedy wielokrotnie
niepotrzebnie przetwarzasz tš samš linię. Może poza CStringArray w której
trzymasz zwykły tekst powinieneś mieć drugš tablicę w której trzymasz
przetworzone linie tekstu (z dodanymi znacznikami)?; podczas edycji na bieżšco
modyfikujesz obie tablice, a w OnDraw tylko wyświetlasz widoczne linie funkcjš
DrawLine.
2. Operacje na CString takie jak Left, Right sš dosyć kosztowne - chyba stšd
twoje problemy przy długich liniach - powinieneś się zastosować nad tym czy i
jak można je wyeliminować - może z wykorzystaniem starych dobrych (char*) ?.
Powodzenia,
Jacek
Re: Edytor tekstu
#1621
Author: Marcin Zielinski
Date: Thu, 19 Feb 1998 14:39
17 lines
1365 bytes
Dzięki za pomoc !!!!

Właśnie zaimplementowałem tak linie by przechowywały one również inforamacje
o czcionce i kolorach fragmentów. Rzeczywiście funkcja rysowania działa
teraz bardzo szybko.
Jeśli chodzi o klasę CStringArray to w wersji 32 bitowej radzi sobie nawet z
plikiem wielkości dwóch mega, ale i tak wątpie żeby ktoś taki plik edytował.

Dzięki jeszcze raz !!! Może ktoś wie jak sobie poradzić z HTML'em
"połamanym" na różne linie ? Bo jak narazie nie mam pomysłu.
------------------------------------------
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
------------------------------------------
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads