HEX Viewer a špatně spočtená šířka systémových znaků (v px)

Hlášení chyb a problémů programu Altap Salamander. Buďte, prosím, ve svých popisech co nejpodrobnější a vytvořte pro každý incident nový příspěvek. Nevkládejte programem generovaná hlášení o pádu programu, pošlete je e-mailem.
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

HEX Viewer a špatně spočtená šířka systémových znaků (v px)

Post by zarevak »

Dobrý den,
v Internal Vieweru se spačtně počítá šířka systémových (0x00 - 0x 1F) znaků. Mám nastavený font "8 pt. Fixedsys" (kódovaní: Central Europe), který by měl mít všechny znaky stejně široké, což však z nějakého důvodu není pravda. Zvláště je chyba viditelná v HEX zobrazení (projevuje se i v textovém zobrazení) a při označování myší - označený text je jinak veliký než neoznačený a celé to pak divně skáče.
Asi lepší předvést na obrázku:
Image
- řádek 01D0 je datově stejný jako 01E0, ale jen z části označný -> konec označení by měl být v textu pod sebou, ale v řádku 01D0 je bvíce vpravo
- řádky 0270 - 02790 neobsahují systémové znaky a jsou zobrazeny správně
- ostatní řádky jsou zobrazeny v různé šířce závisle na obsahu řádku (jak označené, tak neoznačené (u nich to není tak viditelné - ale řádek 03B0 jasně obsahuje sekvenci íľ, která je pod znakem J z řádku 03A0 ))

Poznámky:
- Tato chyba mne trápí už docela dlouho.... :(
- Mám Anglické Windows XP SP2 se zapnutou češtinou jako jazykem pro ne-UNICODE programy; jestli si dobře vzpomínám, tak se tato chyba na českých Windows XP nevyskytuje
- Fonty "8pt. MS Sans Serif" ani "8pt. MS Shell Dlg" (podle vlákna Písmo) v nabídce fontů v nastavení nemám
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Ještě dodatek: Při změně fontu z otevřeného Internal Vieweru (menu: Options>Configuration...) se neaktualizuje výška řádku a pokud je font nižší, tak se vzniklý prostor mezi řádky nepřekresluje... (při zavření Vieweru a jeho znovu otevření je již vše ok)
User avatar
Mem
Posts: 202
Joined: 08 Mar 2006, 15:07
Contact:

Post by Mem »

To bude ale nějaký problém u vás, hexview v internal vieweru používám dost často a už od starších verzí SS a toto jsem ještě nikdy neviděl (teď v SS RC 1 jsem si speciálně otevřel binární data a v pohodě)
Jan Rysavy
ALTAP Staff
ALTAP Staff
Posts: 5231
Joined: 08 Dec 2005, 06:34
Location: Novy Bor, Czech Republic
Contact:

Post by Jan Rysavy »

Zvláštní jsou ty semigrafické znaky, které jsou příčinou problému. Vypadají, jako by nepocházely z Fixedsys fontu. Můžete prosím spustit Character Map z Windows, zvolit Fixedsys font a mrknout se, zda tam takové znaky jsou?
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Dobrý den,
zkoušel jsem si s tím ještě chvíli pohrát a stejnou chybu to dělá u všech fontů. Osobně jsem přešel na Micorosftí Consolas font, protože podporuje ClearType, vypadá dobře :) a dělá chyby jen ve znacích 0x00-0x1F.
Znak 0x0C dokonce mění tvar! (podle toho jak je označené okolí)

Co mne přijde zajímavé je:
- že znaky 0x00-0x1F mení šířku podle toho, zda jsou označené nebo ne
- znak 0x0C (při použití Consolas) mění svůj tvar - jestli to není nějaký problém s UNICODE a návazností znaků či něco takového :?

BTW: O fontu Consolas (font určený pro vývojáře a s podporou ClearType) více na:
- VSEditor's WebLog: New Font for the Visual Studio 2005 Editor
- Powertoys WebLog: Consolas - a New Font for the Visual Studio 2005 Editor
- Ke stažení na Microsoft Download Center
User avatar
Mem
Posts: 202
Joined: 08 Mar 2006, 15:07
Contact:

Post by Mem »

zarevak: Stejnou chybu vám to dělá u všech fontů v Internal Vieweru SS, nebo všude v systému? A ten charmap jste tedy zkoušel?
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Johohó!! Podařilo se mi "rozbít" čistou instalaci Anglických Windows XP Pro SP2 do stejného stavu jako mám já ;-)
Nejdrív jsem podezíral nastavení pro ne-UNICODE programy, ale to se ukázalo jako v pořádku. Problém dělá až nainstalování podpory pro Asijské a komplexní jazyky (konkrétně která ze 2 možností nevím). Viz obrázek:
Image
[dialog Regional and Language Options je dosputný přímo z Control Panel]

BTW: Tato chyba (špatná šířka systémových (0x00 - 0x1F) znaků) se projevuje i v Notepadu, ale při označení se text ani šířka znaků nemění (jen některé znaky jsou stabilně užší)

K CharMap: CharMap zobrazuje znaky 0x21 a výše a problémy dělají znaky právě z rozsahu 0x00-0x1F (0x20 je normální mezera)
User avatar
Mem
Posts: 202
Joined: 08 Mar 2006, 15:07
Contact:

Post by Mem »

zarevak wrote:K CharMap: CharMap zobrazuje znaky 0x21 a výše a problémy dělají znaky právě z rozsahu 0x00-0x1F (0x20 je normální mezera)
Aha, znaky od 0x00 umí zobrazit třeba BabelMap (http://www.babelstone.co.uk/Software/BabelMap.html), resp. nemá tam jejich grafické symboly ale prázdné rámečky, ale je vidět, že pro různé fonty jsou ty rámečky různě široké (např. právě poloviční v porovnání s ostatními písmeny), možná to má souvislost
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

S těmi rámečky máte částečně pravdu: dokud jsem na těch druhých Windows neměl nainstalovánu tu podporu pro komplikované jazyky, tak jsem měl v SS taky rámečky (přesněji: standardní znak fontu pro fontem nepodporovaný znak). Po instalaci té podpory komplikovaných jazyků však mám místo rámečků prázdno (toto osobně preferuji, protože znak 0x00 je NULL a tedy vlastně nic ;-) )
Myslím, že z těch dvou políček se konkrétně jedná o podporu pro Asijské jazyky, protože podporu pro komplexní jazyky jsem instaloval až teprve nedávno a problém se vyskytoval už předtím.

Ještě mne napadá, jestli s tím nějak nesouvisí třetí záložka výše zmíněného dialogu, kde se nastavují (spíše jen instalují) převodní tabulky pro různá kódování - třeba je některá tabulka špatně nebo se špatně vybere...

Jak již jsem řekl, tak nepevnou šířkou znaku trpí i Notepad (s fontem Lucida Console; konkrétně třeba znak 0x01). To bych nějak přežil :wink: . Zaráží mne však, že označený znak má v SS jinou šířku než neoznačený (či se špatně počítá šřka okolních znaků) - toto chování (celý text pak v SS při postupném označování různě poskakuje) je pro mne mnohem větším problémem.
Jan Rysavy
ALTAP Staff
ALTAP Staff
Posts: 5231
Joined: 08 Dec 2005, 06:34
Location: Novy Bor, Czech Republic
Contact:

Post by Jan Rysavy »

Děkujeme za velice přesné dohledání příčiny problému! Koukali jsme na možné řešení a bohužel jsme nic nevymysleli.

Pro programátory: problém je v tom, že funkce DrawText a TextOut v tomto režimu (zapnuté checkboxy) zobrazují text v multibyte kódování. Neznáme způsob, jak jim v tomto zabránit. Mohli bychom na základě znalosti escape sekvencí se je snažit během vykreslování nahrazovat například mezerou, ale to nepovažujeme za čisté řešení.
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Re: HEX Viewer a špatně spočtená šířka systémových znaků (v px)

Post by zarevak »

Juchů! Našel jsem cestu, jak zobrazit HEX mód správně a možná ještě k tomu trochu zrychlit jeho kreslení 8)

Řešením je použíti funkce ExtTextOut() a jejího parametru lpDX ;)
Krásný a zarovnaný výsledek
Krásný a zarovnaný výsledek
ExtTextOut.png (5.13 KiB) Viewed 15096 times
Informace:
- ExtTextOut Function (Windows)
- KB71230: INFO: ExtTextOut() Instead of TextOut() to Improve Performance
- Win32 Tips and Tricks - Filling areas with a solid colour - o použití ExtTextOut() místo FillRect()

Velmi hrubý kód:

Code: Select all

SIZE sz;
GetTextExtentPoint32(hdc, TEXT("W"), 1, &sz); //získání šířky
int dx[] = { sz.cx, sz.cx, sz.cx, sz.cx, 
             sz.cx, sz.cx, sz.cx, sz.cx, 
             sz.cx, sz.cx, sz.cx, sz.cx, 
             sz.cx, sz.cx, sz.cx, sz.cx, 
             sz.cx, sz.cx, sz.cx, sz.cx, sz.cx}; //alespoň tolik, kolik bude kreslených znaků
ExtTextOut(hdc, 0, 0, 0, NULL, TEXT("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"), 16, dx); //funguje!!!
//porovnání s TextOut:
TextOut(hdc, 0, 20, TEXT("0123456789ABCDEF"), 16);                                                                //srovnání se standardním způsobem
TextOut(hdc, 0, 40, TEXT("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"), 16);                //nefunguje
Jiné zjištění šířky znaku:

Code: Select all

TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
int dx[] = { tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, 
             tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, 
             tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, 
             tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, 
             tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth, tm.tmAveCharWidth};
Post Reply