Hlavní navigace

Pohled pod kapotu JVM – práce s TTF fonty v knihovně SDLJava (dokončení)

Pavel Tišnovský

V dnešní části seriálu o programovacím jazyku Java i o virtuálním stroji tohoto jazyka dokončíme popis práce s TTF fonty v knihovně SDLJava. Kromě vykreslování textu je totiž mnohdy nutné nastavit styl vykreslování a popř. zjistit základní charakteristiky použitého fontu, zejména výšku jednotlivých textových řádků.

Obsah

1. Pohled pod kapotu JVM – práce s TTF fonty v knihovně SDLJava (dokončení)

2. Volba stylu vykreslování textu

3. Demonstrační příklad SDLTest44: vykreslení textu čtyřmi různými styly

4. Výška textu a doporučená vzdálenost mezi obrazovými řádky

5. Demonstrační příklad SDLTest45: vykreslení několika řádků textu

6. Získání informací o dalších základních charakteristikách vybraného fontu

7. Demonstrační příklad SDLTest46: výpis dalších charakteristik vybraného fontu

8. Repositář se zdrojovými kódy všech tří dnešních demonstračních příkladů

9. Odkazy na Internetu

1. Pohled pod kapotu JVM – práce s TTF fonty v knihovně SDLJava (dokončení)

V předchozí části tohoto seriálu jsme se seznámili se způsobem vykreslování textů s využitím knihovny SDLJava. Připomeňme si, že texty se v této knihovně vykreslují do samostatných bitmap, které je nutné s využitím metody sdljava.video.SDLSurface.blit­Surface() přenést na obrazovku (resp. přesněji řečeno na plochu odpovídající přednímu či zadnímu bufferu, v závislosti na nastavení double bufferingu). Tvary znaků jsou získány z externích TTF fontů – původní obrys jednotlivých znaků je automaticky převeden do rastrové podoby (rasterizace) a následně vykreslen do zmíněné bitmapy. Při vykreslování textů si vývojář může zvolit mezi trojicí renderovacích metod, které se od sebe liší v kvalitě výsledku a taktéž v náročnosti renderingu a paměťové náročnosti:

# Metoda Stručný popis metody
1 SDLTrueTypeFont.renderTextSolid() vytvoření bitmapy s 8bpp, pozadí znaků je průhledné
2 SDLTrueTypeFont.renderTextShaded() vytvoření bitmapy s 8bpp, pozadí znaků má zvolenou barvu
3 SDLTrueTypeFont.renderTextBlended() vytvoření bitmapy s 32bpp, využívá se zde antialiasing

Dnes téma vykreslování textů s využitím knihovny SDLJava dokončíme – popíšeme si, jakým způsobem je možné nastavit styl vykreslovaných textů a jak lze zjistit základní informace o metrikách použitého fontu. To je poměrně důležité v případě, že se má například vykreslit víceřádkové menu či nápověda. Možnosti knihovny SDLJava sice v této oblasti nejsou na tak propracované úrovni, jako je tomu například v knihovně AWT (viz popis třídy java.awt.FontMatrics, nicméně to ani není cílem knihovny SDLJava. V SDLJava nejsou podporovány ani další složitější manipulace s fonty (práce s ligaturami, umístění znaků se subpixelovou přesností, psaní zprava doleva atd.), což by však při tvorbě her nemělo příliš vadit.

2. Volba stylu vykreslování textu

Minule jsme si taktéž řekli a na čtveřici demonstračních příkladů i prakticky ukázali, že font typu TTF se do spuštěné aplikace může načíst s využitím metody sdljava.ttf.SDLTTF.openFon­t(jméno_souboru_s_fontem, velikost_písma_v_bodech). Pokud tato metoda nevyhodí výjimku (což se může stát v mnoha případech, například pokud není font nalezen), vrátí instanci třídy sdljava.ttf.SDLTrueTypeFont. Tato třída kromě výše zmíněné trojice metod určených pro rasterizaci textu obsahuje mj. i metodu nazvanou sdljava.ttf.SDLTrueTypeFon­t.setFontStyle(), jenž je určena pro změnu řezu písma, tloušťky písmových tahů (duktu) popř. pro zapnutí podtrhávání celého textu. Metoda setFontStyle() akceptuje teoreticky libovolnou kombinaci čtyř celočíselných konstant vypsaných v následující tabulce:

# Parametr metody SDLTrueTypeFont.setFontStyle Význam parametru
1 TTF_STYLE_NORMAL základní řez písma
2 TTF_STYLE_ITALIC kurzíva (ať již pravá či nepravá)
3 TTF_STYLE_BOLD polotučné písmo
4 TTF_STYLE_UNDERLINE podtržení celého textu (ne pouze jednotlivých znaků)

Současná verze knihovny SDLJava však obsahuje prozatím neopravenou chybu způsobující, že při použití některých kombinací (polotučné písmo+kurzíva) může při vykreslování textů dojít k pádu celého virtuálního stroje Javy. Z tohoto důvodu je bezpečnější se tomuto způsobu úpravy řezu písma vyhnout a používat každou ze zmíněných konstant samostatně, tj. bez kombinace s dalšími třemi konstantami.

Obrázek 1: Různé řezy a styly textů vykreslených demonstračním příkladem SDLTest44.

3. Demonstrační příklad SDLTest44: vykreslení textu čtyřmi různými styly

Způsob změny stylu vykreslovaných textů je ukázán v dnešním prvním demonstračním příkladu, který je nazván SDLTest44. Po spuštění tohoto příkladu je načten vybraný font (příslušný soubor „freesans.ttf“ by měl být uložen v aktuálním adresáři) a následně se na obrazovku vypíšou čtyři řádky s textem – první řádek je vykreslen základním řezem písma, druhý řádek pravou či nepravou kurzívou, třetí řádek polotučným písmem a konečně řádek čtvrtý je podtržený). Ještě před vykreslením všech čtyř textových řádků je do bufferu vykreslen rastrový obrázek, takže lze snadno demonstrovat výpočet průhlednosti těch pixelů, které nepřísluší do žádného znaku. Demonstrační příklad samozřejmě podporuje použití libovolného fontu typu TTF, postačuje pouze příslušný font překopírovat do aktuálního adresáře a změnit hodnotu konstanty FONT_NAME. Následuje výpis zdrojového kódu celého demonstračního příkladu SDLTest44:

import sdljava.SDLMain;
import sdljava.SDLException;
 
import sdljava.event.SDLEvent;
import sdljava.event.SDLKeyboardEvent;
import sdljava.event.SDLKey;
import sdljava.event.SDLQuitEvent;
 
import sdljava.video.SDLColor;
import sdljava.video.SDLRect;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import sdljava.ttf.SDLTTF;
import sdljava.ttf.SDLTrueTypeFont;
 
import sdljava.x.swig.SDLPressedState;
 
 
 
/**
 * Ctyricaty ctvrty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Ukazka vyuziti zakladnich moznosti tridy sdljava.ttf.SDLTTF:
 * zmena stylu fontu.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest44 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 640;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Jmeno souboru s fontem.
     */
    private static final String FONT_NAME = "freesans.ttf";
    //private static final String FONT_NAME = "mcgf.ttf";
    //private static final String FONT_NAME = "aescr5b.ttf";
 
    /**
     * Velikost pisma udavana v bodech.
     */
    private static final int FONT_SIZE = 72;
 
    /**
     * Barvy vykresleneho textu.
     */
    private static final SDLColor[] FONT_COLORS = new SDLColor[] {
        new SDLColor(255,  95,  95),
        new SDLColor(255, 255,  95),
        new SDLColor(95,  255,  95),
        new SDLColor(95,   95, 255)
    };
 
    /**
     * Styly vykresleneho textu.
     */
    private static final int[] FONT_STYLES = new int[] {
        SDLTrueTypeFont.TTF_STYLE_NORMAL,
        SDLTrueTypeFont.TTF_STYLE_ITALIC,
        SDLTrueTypeFont.TTF_STYLE_BOLD,
        SDLTrueTypeFont.TTF_STYLE_UNDERLINE,
    };
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                return;
            }
 
            // stisk ci pusteni klavesy
            if (event instanceof SDLKeyboardEvent) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawBitmap(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
 
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
 
    }
 
    /**
     * Vykresleni bitmapy s textem na obrazovku (do okna aplikace).
     * 
     * @param screen
     *            framebuffer
     * @param font
     *            font pouzity pri vykreslovani
     */
    private static void drawOnScreen(SDLSurface screen, SDLTrueTypeFont font, SDLSurface bitmap) throws SDLException {
        // vykresleni podkladove bitmapy s obrazkem
        drawBitmap(screen, bitmap);
 
        // vykresleni textu s vyuzitim ctyr ruznych barev a stylu
        for (int i = 0; i < FONT_COLORS.length; i++) {
            // nastaveni stylu pisma
            font.setFontStyle(FONT_STYLES[i]);
 
            // vykreslit text do samostatne bitmapy
            SDLSurface textBitmap = font.renderTextSolid("www.root.cz", FONT_COLORS[i]);
 
            // vypocitat umisteni bitmapy na obrazovce.
            SDLRect rect = computePositionOnScreen(screen, textBitmap);
            rect.y += (i-2) * 70;
 
            // provest operaci typu BitBLT
            textBitmap.blitSurface(screen, rect);
        }
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa s pismem, ktera se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth)>>1;
        final int y = (screenHeight - bitmapHeight)>>1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Spusteni ctyricateho ctvrteho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace subsystemu SDL_ttf
            SDLTTF.init();
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            final SDLSurface screen = initVideo();
 
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
 
            // instance tridy SDLTrueTypeFont nese jiz zpracovane informace fontu
            // vybrane velikosti
            final SDLTrueTypeFont font = SDLTTF.openFont(FONT_NAME, FONT_SIZE);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, font, bitmap);
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                // uvolneni prostredku vyuzivanych subsytemem SDL_ttf.
                SDLTTF.quit();
            }
            catch (SDLException e) {
                e.printStackTrace();
            }
 
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

Obrázek 2: Různé řezy a styly textů vykreslených demonstračním příkladem SDLTest44.

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest44.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest44.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest44

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest44

4. Výška textu a doporučená vzdálenost mezi obrazovými řádky

Při pohledu na zdrojový kód demonstračního příkladu SDLTest44 je možné si všimnout způsobu výpočtu umístění bitmapy s textem na obrazovku:

// vykreslit text do samostatne bitmapy
SDLSurface textBitmap = font.renderTextSolid("www.root.cz", FONT_COLORS[i]);
 
// vypocitat umisteni bitmapy na obrazovce.
SDLRect rect = computePositionOnScreen(screen, textBitmap);
rect.y += (i-2) * 70;

V žádném případě se nejedná o nijak čitelný výpočet, ovšem jeho největším záporem je to, že není přesný a navíc nebude pracovat korektně ve chvíli, kdy se změní velikost fontu, tj. v našem příkladu konkrétně hodnota konstanty FONT_SIZE. Jeden z problémů spočívá v tom, že se velikost textu určuje v typografických bodech, zatímco pozice bitmapy na obrazovce se udává v pixelech. Ovšem třída SDLTrueTypeFont obsahuje i metody, které dokážou na základě metrik uložených v souboru s fontem získat výšku řádků, popř. doporučovanou vzdálenost mezi obrazovými řádky. Důležité je, že tyto údaje již jsou skutečně uváděny v pixelech, takže je lze využít pro přesné polohování textů na obrazovce:

# Metoda Význam
1 SDLTrueTypeFont.fontHeight() Maximální výška znaku, který se může ve fontu vyskytnout
2 SDLTrueTypeFont.fontLineSkip() Doporučená vertikální vzdálenost mezi po sobě jdoucími textovými řádky

Hodnoty vrácené metodami fontHeight()fontLineSkip() se od sebe budou lišit, protože mezi jednotlivými po sobě jdoucími textovými řádky by měl být alespoň minimální volný prostor, například o velikosti jeden či dva pixely (obrazové řádky). Při snaze o vykreslení co největšího množství řádků na obrazovku je však v naprosté většině případů možné použít i hodnotu vrácenou funkcí fontHeight(), protože je jen málo pravděpodobné, že dojde k dotyku dvou znaků pod sebou (horní znak by musel mít dolní dotažnici a spodní znak by například musel být kapitálkou).

Obrázek 3: Čtyři textové řádky (písmo velikosti 72) vykreslené demonstračním příkladem SDLTest45.

5. Demonstrační příklad SDLTest45: vykreslení několika řádků textu

Použití metody SDLTrueTypeFont.fontHeight() je ukázáno v dnešním druhém demonstračním příkladu nazvaném SDLTest45. I v tomto příkladu se na obrazovku vytisknou čtyři řádky textu, ovšem s korektně spočítanou vzdáleností mezi jednotlivými textovými řádky. Samotný výpočet probíhá velmi jednoduše v metodě drawOnScreen:

/**
 * Vykresleni bitmapy s textem na obrazovku (do okna aplikace).
 * 
 * @param screen
 *            framebuffer
 * @param font
 *            font pouzity pri vykreslovani
 */
private static void drawOnScreen(SDLSurface screen, SDLTrueTypeFont font, SDLSurface bitmap) throws SDLException {
    // vykresleni podkladove bitmapy s obrazkem
    drawBitmap(screen, bitmap);
 
    // vypocitat umisteni bitmapy s textem na obrazovce.
    SDLRect rect = new SDLRect(100, 10);
 
    // vykresleni textu s vyuzitim ctyr ruznych barev
    for (int i = 0; i < FONT_COLORS.length; i++) {
        // vykreslit text do samostatne bitmapy
        SDLSurface textBitmap = font.renderTextSolid("www.root.cz", FONT_COLORS[i]);
 
        // presun na dalsi "radek"
        rect.y += font.fontHeight();
 
        // provest operaci typu BitBLT
        textBitmap.blitSurface(screen, rect);
    }
 
    // nutno volat i v pripade, ze neni pouzit double buffering
    screen.updateRect();
    screen.flip();
}

Následuje výpis úplného zdrojového kódu tohoto demonstračního příkladu:

import sdljava.SDLMain;
import sdljava.SDLException;
 
import sdljava.event.SDLEvent;
import sdljava.event.SDLKeyboardEvent;
import sdljava.event.SDLKey;
import sdljava.event.SDLQuitEvent;
 
import sdljava.video.SDLColor;
import sdljava.video.SDLRect;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import sdljava.ttf.SDLTTF;
import sdljava.ttf.SDLTrueTypeFont;
 
import sdljava.x.swig.SDLPressedState;
 
 
 
/**
 * Ctyricaty paty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Ukazka vyuziti zakladnich moznosti tridy sdljava.ttf.SDLTTF:
 * vyuziti metriky fontu pri zjistovani vysky textoveho radku.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest45 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 640;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Jmeno souboru s fontem.
     */
    private static final String FONT_NAME = "freesans.ttf";
    //private static final String FONT_NAME = "mcgf.ttf";
    //private static final String FONT_NAME = "aescr5b.ttf";
 
    /**
     * Velikost pisma udavana v bodech.
     */
    private static final int FONT_SIZE = 72;
 
    /**
     * Barvy vykresleneho textu.
     */
    private static final SDLColor[] FONT_COLORS = new SDLColor[] {
        new SDLColor(255,  95,  95),
        new SDLColor(255, 255,  95),
        new SDLColor(95,  255,  95),
        new SDLColor(95,   95, 255)
    };
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                return;
            }
 
            // stisk ci pusteni klavesy
            if (event instanceof SDLKeyboardEvent) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawBitmap(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
 
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
 
    }
 
    /**
     * Vykresleni bitmapy s textem na obrazovku (do okna aplikace).
     * 
     * @param screen
     *            framebuffer
     * @param font
     *            font pouzity pri vykreslovani
     */
    private static void drawOnScreen(SDLSurface screen, SDLTrueTypeFont font, SDLSurface bitmap) throws SDLException {
        // vykresleni podkladove bitmapy s obrazkem
        drawBitmap(screen, bitmap);
 
        // vypocitat umisteni bitmapy s textem na obrazovce.
        SDLRect rect = new SDLRect(100, 10);
 
        // vykresleni textu s vyuzitim ctyr ruznych barev
        for (int i = 0; i < FONT_COLORS.length; i++) {
            // vykreslit text do samostatne bitmapy
            SDLSurface textBitmap = font.renderTextSolid("www.root.cz", FONT_COLORS[i]);
 
            // presun na dalsi "radek"
            rect.y += font.fontHeight();
 
            // provest operaci typu BitBLT
            textBitmap.blitSurface(screen, rect);
        }
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa s pismem, ktera se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth)>>1;
        final int y = (screenHeight - bitmapHeight)>>1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Spusteni ctyricateho pateho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace subsystemu SDL_ttf
            SDLTTF.init();
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            final SDLSurface screen = initVideo();
 
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
 
            // instance tridy SDLTrueTypeFont nese jiz zpracovane informace fontu
            // vybrane velikosti
            final SDLTrueTypeFont font = SDLTTF.openFont(FONT_NAME, FONT_SIZE);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, font, bitmap);
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                // uvolneni prostredku vyuzivanych subsytemem SDL_ttf.
                SDLTTF.quit();
            }
            catch (SDLException e) {
                e.printStackTrace();
            }
 
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

Obrázek 4: Čtyři textové řádky (písmo velikosti 10) vykreslené demonstračním příkladem SDLTest45.

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest45.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest45.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest45

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest45

6. Získání informací o dalších základních charakteristikách vybraného fontu

Ve třídě SDLTrueTypeFont najdeme kromě již popsaných metod fontHeight()fontLineSkip() i další dvě metody nazvané fontAscent()fontDescent() popisující přesněji metriku vybraného fontu, resp. parametry písmové osnovy. První z těchto metod vrací vzdálenost (udávanou v pixelech) mezi akcentovou dotažnicí (sem dosahují nejvyšší akcenty) a základní dotažnicí, tj. základem písmové osnovy (nejnižší místo, kam zasahují tvary kapitálek). Druhá metoda se jmenuje fontDescent() a vrací vzdálenost mezi základní dotažnicí a dolní dotažnicí, tj. spodní hranicí minusek g, j, p, q a y (tato hodnota je záporná):

# Metoda Význam
1 SDLTrueTypeFont.fontHeight() Maximální výška znaku, který se může ve fontu vyskytnout
2 SDLTrueTypeFont.fontLineSkip() Doporučená vertikální vzdálenost mezi po sobě jdoucími textovými řádky
3 SDLTrueTypeFont.fontAscent() Vrací vzdálenost mezi akcentovou dotažnicí a základní dotažnicí
4 SDLTrueTypeFont.fontDescent() Vrací vzdálenost mezi základní dotažnicí a dolní dotažnicí

Obrázek 5: Základní informace o načteném fontu.

Obrázek 6: Základní informace o načteném fontu (odlišná velikost písma).

7. Demonstrační příklad SDLTest46: výpis dalších charakteristik vybraného fontu

Všechny informace získané z načteného a inicializovaného fontu vypisuje do svého okna dnešní třetí a současně i poslední demonstrační příklad nazvaný SDLTest46. Výpis jména vlastnosti i její hodnoty je implementován v metodě drawText(), v níž se pro přesun vykreslování na další řádek používá hodnota získaná metodou SDLTrueTypeFont.fontLineSkip():

/**
 * Vykresleni textu na obrazovku.
 *
 * @param screen
 *            framebuffer
 * @param font
 *            font pouzity pri vykreslovani
 * @param property
 *            text, ktery ma byt vypsany na obrazovku (vlastnost)
 * @param value
 *            text, ktery ma byt vypsany na obrazovku (hodnota vlastnosti)
 */
private static void drawText(SDLSurface screen, SDLTrueTypeFont font, String property, int value) throws SDLException {
    // vykreslit text do samostatne bitmapy
    SDLSurface textBitmap1 = font.renderTextSolid(property, FONT_COLORS[0]);
    SDLSurface textBitmap2 = font.renderTextSolid(Integer.toString(value), FONT_COLORS[1]);
 
    // provest operaci typu BitBLT
    textBitmap1.blitSurface(screen, rect1);
    textBitmap2.blitSurface(screen, rect2);
 
    // presun na dalsi "radek"
    rect1.y += font.fontLineSkip();
    rect2.y += font.fontLineSkip();
}

Výpis zdrojového kódu demonstračního příkladu SDLTest46:

import sdljava.SDLMain;
import sdljava.SDLException;
 
import sdljava.event.SDLEvent;
import sdljava.event.SDLKeyboardEvent;
import sdljava.event.SDLKey;
import sdljava.event.SDLQuitEvent;
 
import sdljava.video.SDLColor;
import sdljava.video.SDLRect;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import sdljava.ttf.SDLTTF;
import sdljava.ttf.SDLTrueTypeFont;
 
import sdljava.x.swig.SDLPressedState;
 
 
 
/**
 * Ctyricaty sesty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Ukazka vyuziti zakladnich moznosti tridy sdljava.ttf.SDLTTF:
 * vypis informaci o vlastnostech zvoleneho fontu.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest46 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 640;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Jmeno souboru s fontem.
     */
    private static final String FONT_NAME = "freesans.ttf";
    //private static final String FONT_NAME = "mcgf.ttf";
    //private static final String FONT_NAME = "aescr5b.ttf";
 
    /**
     * Velikost pisma udavana v bodech.
     */
    private static final int FONT_SIZE = 24;
 
    /**
     * Barvy vykresleneho textu.
     */
    private static final SDLColor[] FONT_COLORS = new SDLColor[] {
        new SDLColor(255,  95,  95),
        new SDLColor(255, 255,  95),
    };
 
    /**
     * Umisteni bitmapy s textem na obrazovce.
     */
    private static SDLRect rect1 = new SDLRect(50, 10);
    private static SDLRect rect2 = new SDLRect(350, 10);
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                return;
            }
 
            // stisk ci pusteni klavesy
            if (event instanceof SDLKeyboardEvent) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni textu na obrazovku.
     *
     * @param screen
     *            framebuffer
     * @param font
     *            font pouzity pri vykreslovani
     * @param property
     *            text, ktery ma byt vypsany na obrazovku (vlastnost)
     * @param value
     *            text, ktery ma byt vypsany na obrazovku (hodnota vlastnosti)
     */
    private static void drawText(SDLSurface screen, SDLTrueTypeFont font, String property, int value) throws SDLException {
        // vykreslit text do samostatne bitmapy
        SDLSurface textBitmap1 = font.renderTextSolid(property, FONT_COLORS[0]);
        SDLSurface textBitmap2 = font.renderTextSolid(Integer.toString(value), FONT_COLORS[1]);
 
        // provest operaci typu BitBLT
        textBitmap1.blitSurface(screen, rect1);
        textBitmap2.blitSurface(screen, rect2);
 
        // presun na dalsi "radek"
        rect1.y += font.fontLineSkip();
        rect2.y += font.fontLineSkip();
    }
 
    /**
     * Vykresleni bitmapy s textem na obrazovku (do okna aplikace).
     * 
     * @param screen
     *            framebuffer
     * @param font
     *            font pouzity pri vykreslovani
     */
    private static void drawOnScreen(SDLSurface screen, SDLTrueTypeFont font) throws SDLException {
        // vypis vsech vlastnosti fontu
        drawText(screen, font, "Font size (points):  ", font.getPTSize());
        drawText(screen, font, "Max. height (pixels):", font.fontHeight());
        drawText(screen, font, "Ascent (points):     ", font.fontAscent());
        drawText(screen, font, "Descent (points):    ", font.fontDescent());
        drawText(screen, font, "Line skip (points):  ", font.fontLineSkip());
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Spusteni ctyricateho sesteho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace subsystemu SDL_ttf
            SDLTTF.init();
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            final SDLSurface screen = initVideo();
 
            // instance tridy SDLTrueTypeFont nese jiz zpracovane informace fontu
            // vybrane velikosti
            final SDLTrueTypeFont font = SDLTTF.openFont(FONT_NAME, FONT_SIZE);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, font);
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                // uvolneni prostredku vyuzivanych subsytemem SDL_ttf.
                SDLTTF.quit();
            }
            catch (SDLException e) {
                e.printStackTrace();
            }
 
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

Obrázek 7: Základní informace o načteném fontu (odlišná velikost písma).

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest46.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest46.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest46

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest46

8. Repositář se zdrojovými kódy všech tří dnešních demonstračních příkladů

Všechny tři dnes popsané demonstrační příklady byly společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženy do Mercurial repositáře dostupného na adrese http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozích několika dílech tohoto seriálu, i ke dnešním příkladům jsou přiloženy skripty využitelné pro jejich překlad a spuštění. Navíc byly přidány i skripty využitelné ve Windows:

# Zdrojový soubor/skript Umístění souboru v repositáři
1 SDLTest44.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44.ja­va
2 SDLTest44_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_com­pile.sh
3 SDLTest44_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_com­pile_sys.sh
4 SDLTest44_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_run­.sh
5 SDLTest44_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_run_sys­.sh
6 SDLTest44_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_com­pile.bat
7 SDLTest44_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest44/SDLTest44_run­.bat
     
8 SDLTest45.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45.ja­va
9 SDLTest45_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_com­pile.sh
10 SDLTest45_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_com­pile_sys.sh
11 SDLTest45_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_run­.sh
12 SDLTest45_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_run_sys­.sh
13 SDLTest45_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_com­pile.bat
14 SDLTest45_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest45/SDLTest45_run­.bat
     
15 SDLTest46.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46.ja­va
16 SDLTest46_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_com­pile.sh
17 SDLTest46_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_com­pile_sys.sh
18 SDLTest46_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_run­.sh
19 SDLTest46_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_run_sys­.sh
20 SDLTest46_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_com­pile.bat
21 SDLTest46_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c016f8c41232/sdlja­va/SDLTest46/SDLTest46_run­.bat

9. Odkazy na Internetu

  1. SDLJava: package sdljava.ttf
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/pac­kage-summary.html#package_description
  2. SDLJava: class sdljava.ttf.SDLTTF
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTTF­.html
  3. SDLJava: class sdljava.ttf.SDLTrueTypeFont
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTru­eTypeFont.html
  4. SDL_ttf Documentation
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/
  5. SDL_ttf 2.0 (není prozatím součástí SDLJava)
    http://www.libsdl.org/pro­jects/SDL_ttf/
  6. SDL_ttf doc
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/SDL_ttf_fra­me.html
  7. SDL 1.2 Documentation: SDL_Surface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html
  8. SDL 1.2 Documentation: SDL_PixelFormat
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html
  9. SDL 1.2 Documentation: SDL_LockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html
  10. SDL 1.2 Documentation: SDL_UnlockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html
  11. SDL 1.2 Documentation: SDL_LoadBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html
  12. SDL 1.2 Documentation: SDL_SaveBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html
  13. SDL 1.2 Documentation: SDL_BlitSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html
  14. SDL 1.2 Documentation: SDL_VideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html
  15. SDL 1.2 Documentation: SDL_GetVideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html
  16. glDrawArrays
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArrays­.xml
  17. glDrawElements
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­ts.xml
  18. glDrawArraysInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArraysIn­stanced.xml
  19. glDrawElementsInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­tsInstanced.xml
  20. Root.cz: Seriál Grafická knihovna OpenGL
    http://www.root.cz/serialy/graficka-knihovna-opengl/
  21. Root.cz: Seriál Tvorba přenositelných grafických aplikací využívajících knihovnu GLUT
    http://www.root.cz/serialy/tvorba-prenositelnych-grafickych-aplikaci-vyuzivajicich-knihovnu-glut/
  22. Best Practices for Working with Vertex Data
    https://developer.apple.com/li­brary/ios/documentation/3ddra­wing/conceptual/opengles_pro­grammingguide/Techniquesfor­WorkingwithVertexData/Techni­quesforWorkingwithVertexDa­ta.html
  23. Class BufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/i­mage/BufferStrategy.html
  24. Class Graphics
    http://docs.oracle.com/ja­vase/1.5.0/docs/api/java/aw­t/Graphics.html
  25. Double Buffering and Page Flipping
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/doublebuf.html
  26. BufferStrategy and BufferCapabilities
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/bufferstrategy.html
  27. Java:Tutorials:Double Buffering
    http://content.gpwiki.org/in­dex.php/Java:Tutorials:Dou­ble_Buffering
  28. Double buffer in standard Java AWT
    http://www.codeproject.com/Ar­ticles/2136/Double-buffer-in-standard-Java-AWT
  29. Java 2D: Hardware Accelerating – Part 1 – Volatile Images
    http://www.javalobby.org/fo­rums/thread.jspa?threadID=16840&tstar­t=0
  30. Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
    http://www.javalobby.org/ja­va/forums/t16867.html
  31. How does paintComponent work?
    http://stackoverflow.com/qu­estions/15544549/how-does-paintcomponent-work
  32. A Swing Architecture Overview
    http://www.oracle.com/technet­work/java/architecture-142923.html
  33. Class javax.swing.JComponent
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html
  34. Class java.awt.Component
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html
  35. Class java.awt.Component.BltBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.BltBufferStrategy.html
  36. Class java.awt.Component.FlipBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.FlipBufferStrategy­.html
  37. Metoda java.awt.Component.isDoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html#isDoubleBuffe­red()
  38. Metoda javax.swing.JComponent.is­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#isDouble­Buffered()
  39. Metoda javax.swing.JComponent.set­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#setDouble­Buffered(boolean)
  40. Javadoc – třída GraphicsDevice
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsDevice.html
  41. Javadoc – třída GraphicsEnvironment
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsEnvironment.html
  42. Javadoc – třída GraphicsConfiguration
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsConfiguration.html
  43. Javadoc – třída DisplayMode
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Dis­playMode.html
  44. Lesson: Full-Screen Exclusive Mode API
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/
  45. Full-Screen Exclusive Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/exclusivemode.html
  46. Display Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/displaymode.html
  47. Using the Full-Screen Exclusive Mode API in Java
    http://www.developer.com/ja­va/other/article.php/3609776/U­sing-the-Full-Screen-Exclusive-Mode-API-in-Java.htm
  48. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mobilefish.com/tu­torials/java/java_quickgu­ide_jvm_instruction_set.html
  49. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  50. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  51. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  52. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  53. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  54. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  55. GC safe-point (or safepoint) and safe-region
    http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html
  56. Safepoints in HotSpot JVM
    http://blog.ragozin.info/2012/10/sa­fepoints-in-hotspot-jvm.html
  57. Java theory and practice: Synchronization optimizations in Mustang
    http://www.ibm.com/develo­perworks/java/library/j-jtp10185/
  58. How to build hsdis
    http://hg.openjdk.java.net/jdk7/hot­spot/hotspot/file/tip/src/sha­re/tools/hsdis/README
  59. Java SE 6 Performance White Paper
    http://www.oracle.com/technet­work/java/6-performance-137236.html
  60. Lukas Stadler's Blog
    http://classparser.blogspot­.cz/2010/03/hsdis-i386dll.html
  61. How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
    http://dropzone.nfshost.com/hsdis.htm
  62. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  63. The Java Virtual Machine Specification: 3.14. Synchronization
    http://docs.oracle.com/ja­vase/specs/jvms/se7/html/jvms-3.html#jvms-3.14
  64. The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
  65. The Java Virtual Machine Specification: 17.4. Memory Model
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.4
  66. The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.7
  67. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  68. ASM Home page
    http://asm.ow2.org/
  69. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2.org/users.html
  70. ObjectWeb ASM (Wikipedia)
    http://en.wikipedia.org/wi­ki/ObjectWeb_ASM
  71. Java Bytecode BCEL vs ASM
    http://james.onegoodcooki­e.com/2005/10/26/java-bytecode-bcel-vs-asm/
  72. BCEL Home page
    http://commons.apache.org/bcel/
  73. Byte Code Engineering Library (před verzí 5.0)
    http://bcel.sourceforge.net/
  74. Byte Code Engineering Library (verze >= 5.0)
    http://commons.apache.org/pro­per/commons-bcel/
  75. BCEL Manual
    http://commons.apache.org/bcel/ma­nual.html
  76. Byte Code Engineering Library (Wikipedia)
    http://en.wikipedia.org/wiki/BCEL
  77. BCEL Tutorial
    http://www.smfsupport.com/sup­port/java/bcel-tutorial!/
  78. Bytecode Engineering
    http://book.chinaunix.net/spe­cial/ebook/Core_Java2_Volu­me2AF/0131118269/ch13lev1sec6­.html
  79. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2.org/eclipse/index.html
  80. Javassist
    http://www.jboss.org/javassist/
  81. Byteman
    http://www.jboss.org/byteman
  82. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ibm.com/develo­perworks/java/library/j-dyn0414/
  83. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/VMSpec­TOC.doc.html
  84. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  85. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  86. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.die.net/man/1/javap-java-1.6.0-openjdk
  87. Using javap
    http://www.idevelopment.in­fo/data/Programming/java/mis­cellaneous_java/Using_javap­.html
  88. Examine class files with the javap command
    http://www.techrepublic.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  89. aspectj (Eclipse)
    http://www.eclipse.org/aspectj/
  90. Aspect-oriented programming (Wikipedia)
    http://en.wikipedia.org/wi­ki/Aspect_oriented_program­ming
  91. AspectJ (Wikipedia)
    http://en.wikipedia.org/wiki/AspectJ
  92. EMMA: a free Java code coverage tool
    http://emma.sourceforge.net/
  93. Cobertura
    http://cobertura.sourceforge.net/
  94. jclasslib bytecode viewer
    http://www.ej-technologies.com/products/jclas­slib/overview.html
Našli jste v článku chybu?
120na80.cz: Rovnátka, která nejsou vidět

Rovnátka, která nejsou vidět

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

DigiZone.cz: SES zajistí HD pro M7 Group

SES zajistí HD pro M7 Group

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Lupa.cz: Levný tarif pro Brno nebude, je to kartel

Levný tarif pro Brno nebude, je to kartel

DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Měšec.cz: Za palivo zaplatíte mobilem (TEST)

Za palivo zaplatíte mobilem (TEST)

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Lupa.cz: Obchod budoucnosti je bez front, košíků i pokladen

Obchod budoucnosti je bez front, košíků i pokladen