Page 1 of 1

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

Posted: 03 Sep 2006, 00:26
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

Posted: 03 Sep 2006, 00:37
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)

Posted: 04 Sep 2006, 18:17
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ě)

Posted: 08 Sep 2006, 13:53
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?

Posted: 08 Sep 2006, 14:27
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

Posted: 08 Sep 2006, 20:14
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?

Posted: 08 Sep 2006, 23:06
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)

Posted: 09 Sep 2006, 08:56
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

Posted: 09 Sep 2006, 14:26
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.

Posted: 09 Oct 2006, 18:16
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í.

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

Posted: 26 Apr 2009, 18:38
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 15113 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};