Thread View: pl.comp.lang.c
5 messages
5 total messages
Started by Marcin Zielinski
Wed, 18 Feb 1998 07:33
Edytor tekstu
Author: Marcin Zielinski
Date: Wed, 18 Feb 1998 07:33
Date: Wed, 18 Feb 1998 07:33
137 lines
6074 bytes
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
Author: Perfect Drug
Date: Wed, 18 Feb 1998 13:25
Date: Wed, 18 Feb 1998 13:25
5 lines
940 bytes
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
Author: Piotr Kaminski
Date: Wed, 18 Feb 1998 21:22
Date: Wed, 18 Feb 1998 21:22
25 lines
1704 bytes
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
Author: Jacek Sikora
Date: Thu, 19 Feb 1998 08:51
Date: Thu, 19 Feb 1998 08:51
12 lines
1363 bytes
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
Author: Marcin Zielinski
Date: Thu, 19 Feb 1998 14:39
Date: Thu, 19 Feb 1998 14:39
17 lines
1365 bytes
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